diff --git a/armsrc/Makefile.linux b/armsrc/Makefile.linux index 98c9c386..f0d9325a 100644 --- a/armsrc/Makefile.linux +++ b/armsrc/Makefile.linux @@ -31,11 +31,12 @@ OBJ = $(OBJDIR)/start.o \ $(OBJDIR)/appmain.o \ $(OBJDIR)/fpga.o \ $(OBJDIR)/iso15693.o \ - $(OBJDIR)/iso14443.o \ $(OBJDIR)/util.o - -OBJFAST = $(OBJDIR)/iso14443a.o +# To be compiled in ARM mode, not thumb mode: larger but faster +# Alleviates the 'blew circular buffer' issues somehow... +OBJFAST = $(OBJDIR)/iso14443.o \ + $(OBJDIR)/iso14443a.o OBJFPGA = $(OBJDIR)/fpgaimg.o diff --git a/armsrc/appmain.c b/armsrc/appmain.c index a0bb00d3..3cbe5c4f 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -8,8 +8,8 @@ #include #include "apps.h" -#include "fonts.h" #ifdef WITH_LCD +#include "fonts.h" #include "LCD.h" #endif @@ -657,10 +657,9 @@ void UsbPacketReceived(BYTE *packet, int len) break; case CMD_FPGA_MAJOR_MODE_OFF: // ## FPGA Control - LED_C_ON(); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); SpinDelay(200); - LED_C_OFF(); + LED_D_OFF(); // LED D indicates field ON or OFF break; case CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K: diff --git a/armsrc/iso14443.c b/armsrc/iso14443.c index 7271b9d0..311254d9 100644 --- a/armsrc/iso14443.c +++ b/armsrc/iso14443.c @@ -131,10 +131,20 @@ static struct { BYTE *output; } Uart; +/* Receive & handle a bit coming from the reader. + * + * LED handling: + * LED A -> ON once we have received the SOF and are expecting the rest. + * LED A -> OFF once we have received EOF or are in error state or unsynced + * + * Returns: true if we received a EOF + * false if we are still waiting for some more + */ static BOOL Handle14443UartBit(int bit) { switch(Uart.state) { case STATE_UNSYNCD: + LED_A_OFF(); if(!bit) { // we went low, so this could be the beginning // of an SOF @@ -154,6 +164,7 @@ static BOOL Handle14443UartBit(int bit) Uart.posCnt = 0; Uart.byteCnt = 0; Uart.state = STATE_AWAITING_START_BIT; + LED_A_ON(); // Indicate we got a valid SOF } else { // didn't stay down long enough // before going high, error @@ -186,6 +197,7 @@ static BOOL Handle14443UartBit(int bit) Uart.bitCnt = 0; Uart.shiftReg = 0; Uart.state = STATE_RECEIVING_DATA; + LED_A_ON(); // Indicate we're receiving } break; @@ -221,6 +233,7 @@ static BOOL Handle14443UartBit(int bit) } } else if(Uart.shiftReg == 0x000) { // this is an EOF byte + LED_A_OFF(); // Finished receiving return TRUE; } else { // this is an error @@ -245,6 +258,8 @@ static BOOL Handle14443UartBit(int bit) break; } + if (Uart.state == STATE_ERROR_WAIT) LED_A_OFF(); // Error + return FALSE; } @@ -264,6 +279,8 @@ static BOOL GetIso14443CommandFromReader(BYTE *received, int *len, int maxLen) // Set FPGA mode to "simulated ISO 14443 tag", no modulation (listen // only, since we are receiving, not transmitting). + // Signal field is off with the appropriate LED + LED_D_OFF(); FpgaWriteConfWord( FPGA_MAJOR_MODE_HF_SIMULATOR | FPGA_HF_SIMULATOR_NO_MODULATION); @@ -371,6 +388,8 @@ void SimulateIso14443Tag(void) if(respLen <= 0) continue; // Modulate BPSK + // Signal field is off with the appropriate LED + LED_D_OFF(); FpgaWriteConfWord( FPGA_MAJOR_MODE_HF_SIMULATOR | FPGA_HF_SIMULATOR_MODULATE_BPSK); SSC_TRANSMIT_HOLDING = 0xff; @@ -426,6 +445,17 @@ static struct { int sumQ; } Demod; +/* + * Handles reception of a bit from the tag + * + * LED handling: + * LED C -> ON once we have received the SOF and are expecting the rest. + * LED C -> OFF once we have received EOF or are unsynced + * + * Returns: true if we received a EOF + * false if we are still waiting for some more + * + */ static BOOL Handle14443SamplesDemod(int ci, int cq) { int v; @@ -498,6 +528,7 @@ static BOOL Handle14443SamplesDemod(int ci, int cq) if(Demod.posCount < 12) { Demod.state = DEMOD_UNSYNCD; } else { + LED_C_ON(); // Got SOF Demod.state = DEMOD_AWAITING_START_BIT; Demod.posCount = 0; Demod.len = 0; @@ -557,6 +588,7 @@ static BOOL Handle14443SamplesDemod(int ci, int cq) Demod.state = DEMOD_AWAITING_START_BIT; } else if(s == 0x000) { // This is EOF + LED_C_OFF(); return TRUE; Demod.state = DEMOD_UNSYNCD; } else { @@ -572,9 +604,16 @@ static BOOL Handle14443SamplesDemod(int ci, int cq) break; } + if (Demod.state == DEMOD_UNSYNCD) LED_C_OFF(); // Not synchronized... return FALSE; } +/* + * Demodulate the samples we received from the tag + * weTx: set to 'TRUE' if we behave like a reader + * set to 'FALSE' if we behave like a snooper + * quiet: set to 'TRUE' to disable debug output + */ static void GetSamplesFor14443Demod(BOOL weTx, int n, BOOL quiet) { int max = 0; @@ -607,6 +646,8 @@ static void GetSamplesFor14443Demod(BOOL weTx, int n, BOOL quiet) lastRxCounter = DMA_BUFFER_SIZE; FpgaSetupSscDma((BYTE *)dmaBuf, DMA_BUFFER_SIZE); + // Signal field is ON with the appropriate LED: + if (weTx) LED_D_ON(); else LED_D_OFF(); // And put the FPGA in the appropriate mode FpgaWriteConfWord( FPGA_MAJOR_MODE_HF_READER_RX_XCORR | FPGA_HF_READER_RX_XCORR_848_KHZ | @@ -616,7 +657,6 @@ static void GetSamplesFor14443Demod(BOOL weTx, int n, BOOL quiet) int behindBy = lastRxCounter - PDC_RX_COUNTER(SSC_BASE); if(behindBy > max) max = behindBy; - LED_D_ON(); while(((lastRxCounter-PDC_RX_COUNTER(SSC_BASE)) & (DMA_BUFFER_SIZE-1)) > 2) { @@ -642,7 +682,6 @@ static void GetSamplesFor14443Demod(BOOL weTx, int n, BOOL quiet) gotFrame = 1; } } - LED_D_OFF(); if(samples > 2000) { break; @@ -697,7 +736,11 @@ static void TransmitFor14443(void) SSC_TRANSMIT_HOLDING = 0xff; } - FpgaWriteConfWord( + // Signal field is ON with the appropriate Red LED + LED_D_ON(); + // Signal we are transmitting with the Green LED + LED_B_ON(); + FpgaWriteConfWord( FPGA_MAJOR_MODE_HF_READER_TX | FPGA_HF_READER_TX_SHALLOW_MOD); for(c = 0; c < 10;) { @@ -727,6 +770,7 @@ static void TransmitFor14443(void) } WDT_HIT(); } + LED_B_OFF(); // Finished sending } //----------------------------------------------------------------------------- @@ -797,28 +841,30 @@ void AcquireRawAdcSamplesIso14443(DWORD parameter) // Make sure that we start from off, since the tags are stateful; // confusing things will happen if we don't reset them between reads. - LED_D_OFF(); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + LED_D_OFF(); SpinDelay(200); SetAdcMuxFor(GPIO_MUXSEL_HIPKD); FpgaSetupSsc(); // Now give it time to spin up. + // Signal field is on with the appropriate LED + LED_D_ON(); FpgaWriteConfWord( FPGA_MAJOR_MODE_HF_READER_RX_XCORR | FPGA_HF_READER_RX_XCORR_848_KHZ); SpinDelay(200); CodeIso14443bAsReader(cmd1, sizeof(cmd1)); TransmitFor14443(); - LED_A_ON(); +// LED_A_ON(); GetSamplesFor14443Demod(TRUE, 2000, FALSE); - LED_A_OFF(); +// LED_A_OFF(); } //----------------------------------------------------------------------------- // Read a SRI512 ISO 14443 tag. -// +// // SRI512 tags are just simple memory tags, here we're looking at making a dump // of the contents of the memory. No anticollision algorithm is done, we assume // we have a single tag in the field. @@ -839,6 +885,8 @@ void ReadSRI512Iso14443(DWORD parameter) FpgaSetupSsc(); // Now give it time to spin up. + // Signal field is on with the appropriate LED + LED_D_ON(); FpgaWriteConfWord( FPGA_MAJOR_MODE_HF_READER_RX_XCORR | FPGA_HF_READER_RX_XCORR_848_KHZ); SpinDelay(200); @@ -847,9 +895,9 @@ void ReadSRI512Iso14443(DWORD parameter) BYTE cmd1[] = { 0x06, 0x00, 0x97, 0x5b}; CodeIso14443bAsReader(cmd1, sizeof(cmd1)); TransmitFor14443(); - LED_A_ON(); +// LED_A_ON(); GetSamplesFor14443Demod(TRUE, 2000,TRUE); - LED_A_OFF(); +// LED_A_OFF(); if (Demod.len == 0) { DbpString("No response from tag"); @@ -865,9 +913,9 @@ void ReadSRI512Iso14443(DWORD parameter) ComputeCrc14443(CRC_14443_B, cmd1, 2, &cmd1[2], &cmd1[3]); CodeIso14443bAsReader(cmd1, sizeof(cmd1)); TransmitFor14443(); - LED_A_ON(); +// LED_A_ON(); GetSamplesFor14443Demod(TRUE, 2000,TRUE); - LED_A_OFF(); +// LED_A_OFF(); if (Demod.len != 3) { DbpString("Expected 3 bytes from tag, got:"); DbpIntegers(Demod.len,0x0,0x0); @@ -891,9 +939,9 @@ void ReadSRI512Iso14443(DWORD parameter) ComputeCrc14443(CRC_14443_B, cmd1, 1 , &cmd1[1], &cmd1[2]); CodeIso14443bAsReader(cmd1, 3); // Only first three bytes for this one TransmitFor14443(); - LED_A_ON(); +// LED_A_ON(); GetSamplesFor14443Demod(TRUE, 2000,TRUE); - LED_A_OFF(); +// LED_A_OFF(); if (Demod.len != 10) { DbpString("Expected 10 bytes from tag, got:"); DbpIntegers(Demod.len,0x0,0x0); @@ -922,9 +970,9 @@ void ReadSRI512Iso14443(DWORD parameter) ComputeCrc14443(CRC_14443_B, cmd1, 2, &cmd1[2], &cmd1[3]); CodeIso14443bAsReader(cmd1, sizeof(cmd1)); TransmitFor14443(); - LED_A_ON(); +// LED_A_ON(); GetSamplesFor14443Demod(TRUE, 2000,TRUE); - LED_A_OFF(); +// LED_A_OFF(); if (Demod.len != 6) { // Check if we got an answer from the tag DbpString("Expected 6 bytes from tag, got less..."); return; @@ -957,6 +1005,13 @@ void ReadSRI512Iso14443(DWORD parameter) // triggering so that we start recording at the point that the tag is moved // near the reader. //----------------------------------------------------------------------------- +/* + * Memory usage for this function, (within BigBuf) + * 0-1023 : Demodulated samples receive (1024 bytes) + * 1024-1535 : Last Received command, 512 bytes (reader->tag) + * 1536-2047 : Last Received command, 512 bytes(tag->reader) + * 2048-2304 : DMA Buffer, 256 bytes (samples) + */ void SnoopIso14443(void) { // We won't start recording the frames that we acquire until we trigger; @@ -965,9 +1020,9 @@ void SnoopIso14443(void) BOOL triggered = FALSE; // The command (reader -> tag) that we're working on receiving. - BYTE *receivedCmd = (((BYTE *)BigBuf) + 1024); + BYTE *receivedCmd = (BYTE *)(BigBuf) + 1024; // The response (tag -> reader) that we're working on receiving. - BYTE *receivedResponse = (((BYTE *)BigBuf) + 1536); + BYTE *receivedResponse = (BYTE *)(BigBuf) + 1536; // As we receive stuff, we copy it from receivedCmd or receivedResponse // into trace, along with its length and other annotations. @@ -975,8 +1030,7 @@ void SnoopIso14443(void) int traceLen = 0; // The DMA buffer, used to stream samples from the FPGA. -//# define DMA_BUFFER_SIZE 256 - SBYTE *dmaBuf = ((SBYTE *)BigBuf) + 2048; + SBYTE *dmaBuf = (SBYTE *)(BigBuf) + 2048; int lastRxCounter; SBYTE *upTo; int ci, cq; @@ -986,7 +1040,8 @@ void SnoopIso14443(void) // information in the trace buffer. int samples = 0; - memset(trace, 0x44, 1000); + // Initialize the trace buffer + memset(trace, 0x44, 1024); // Set up the demodulator for tag -> reader responses. Demod.output = receivedResponse; @@ -1000,6 +1055,8 @@ void SnoopIso14443(void) Uart.state = STATE_UNSYNCD; // And put the FPGA in the appropriate mode + // Signal field is off with the appropriate LED + LED_D_OFF(); FpgaWriteConfWord( FPGA_MAJOR_MODE_HF_READER_RX_XCORR | FPGA_HF_READER_RX_XCORR_848_KHZ | FPGA_HF_READER_RX_XCORR_SNOOP); @@ -1010,17 +1067,15 @@ void SnoopIso14443(void) upTo = dmaBuf; lastRxCounter = DMA_BUFFER_SIZE; FpgaSetupSscDma((BYTE *)dmaBuf, DMA_BUFFER_SIZE); - - LED_A_ON(); - // And now we loop, receiving samples. for(;;) { - int behindBy = (lastRxCounter - PDC_RX_COUNTER(SSC_BASE)) & + int behindBy = (lastRxCounter - PDC_RX_COUNTER(SSC_BASE)) & (DMA_BUFFER_SIZE-1); if(behindBy > maxBehindBy) { maxBehindBy = behindBy; - if(behindBy > 100) { + if(behindBy > (DMA_BUFFER_SIZE-2)) { // TODO: understand whether we can increase/decrease as we want or not? DbpString("blew circular buffer!"); + DbpIntegers(behindBy,0,0); goto done; } } @@ -1033,7 +1088,7 @@ void SnoopIso14443(void) if(upTo - dmaBuf > DMA_BUFFER_SIZE) { upTo -= DMA_BUFFER_SIZE; lastRxCounter += DMA_BUFFER_SIZE; - PDC_RX_NEXT_POINTER(SSC_BASE) = (DWORD)upTo; + PDC_RX_NEXT_POINTER(SSC_BASE) = (DWORD) upTo; PDC_RX_NEXT_COUNTER(SSC_BASE) = DMA_BUFFER_SIZE; } @@ -1093,14 +1148,13 @@ void SnoopIso14443(void) if(traceLen > 1000) break; triggered = TRUE; - LED_A_OFF(); - LED_B_ON(); // And ready to receive another response. memset(&Demod, 0, sizeof(Demod)); Demod.output = receivedResponse; Demod.state = DEMOD_UNSYNCD; } + WDT_HIT(); if(BUTTON_PRESS()) { DbpString("cancelled"); @@ -1114,7 +1168,6 @@ void SnoopIso14443(void) DbpIntegers(Uart.byteCntMax, traceLen, 0x23); done: + LED_D_OFF(); PDC_CONTROL(SSC_BASE) = PDC_RX_DISABLE; - LED_A_OFF(); - LED_B_OFF(); } diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index 0957d051..c5557d39 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -516,8 +516,8 @@ void SnoopIso14443a(void) #define RECV_RES_OFFSET 3096 #define DMA_BUFFER_OFFSET 3160 #define DMA_BUFFER_SIZE 4096 - #define TRACE_LENGTH 3000 - + #define TRACE_LENGTH 3000 + // #define RECV_CMD_OFFSET 2032 // original (working as of 21/2/09) values // #define RECV_RES_OFFSET 2096 // original (working as of 21/2/09) values // #define DMA_BUFFER_OFFSET 2160 // original (working as of 21/2/09) values @@ -567,6 +567,8 @@ void SnoopIso14443a(void) Uart.state = STATE_UNSYNCD; // And put the FPGA in the appropriate mode + // Signal field is off with the appropriate LED + LED_D_OFF(); FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_SNIFFER); SetAdcMuxFor(GPIO_MUXSEL_HIPKD); @@ -841,6 +843,8 @@ static BOOL GetIso14443aCommandFromReader(BYTE *received, int *len, int maxLen) { // Set FPGA mode to "simulated ISO 14443 tag", no modulation (listen // only, since we are receiving, not transmitting). + // Signal field is off with the appropriate LED + LED_D_OFF(); FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_TAGSIM_LISTEN); // Now run a `software UART' on the stream of incoming samples. @@ -893,8 +897,8 @@ void SimulateIso14443aTag(int tagType, int TagUid) // my desfire static const BYTE response2[] = { 0x88, 0x04, 0x21, 0x3f, 0x4d }; // known uid - note cascade (0x88), 2nd byte (0x04) = NXP/Phillips - - + + // When reader selects us during cascade1 it will send cmd3 //BYTE response3[] = { 0x04, 0x00, 0x00 }; // SAK Select (cascade1) successful response (ULTRALITE) BYTE response3[] = { 0x24, 0x00, 0x00 }; // SAK Select (cascade1) successful response (DESFire) @@ -909,7 +913,7 @@ static const BYTE response2a[] = { 0x51, 0x48, 0x1d, 0x80, 0x84 }; // uid - cas //BYTE response3a[] = { 0x00, 0x00, 0x00 }; // SAK Select (cascade2) successful response (ULTRALITE) BYTE response3a[] = { 0x20, 0x00, 0x00 }; // SAK Select (cascade2) successful response (DESFire) ComputeCrc14443(CRC_14443_A, response3a, 1, &response3a[1], &response3a[2]); - + // When reader tries to authenticate // static const BYTE cmd5[] = { 0x60, 0x00, 0xf5, 0x7b }; static const BYTE response5[] = { 0x00, 0x00, 0x00, 0x00 }; // Very random tag nonce @@ -1434,8 +1438,10 @@ static BOOL GetIso14443aAnswerFromTag(BYTE *receivedResponse, int maxLen, int *s // buffer needs to be 512 bytes int c; - // Set FPGA mode to "simulated ISO 14443 tag", no modulation (listen + // Set FPGA mode to "reader listen mode", no modulation (listen // only, since we are receiving, not transmitting). + // Signal field is on with the appropriate LED + LED_D_ON(); FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_LISTEN); // Now get the answer from the card @@ -1528,7 +1534,7 @@ void ReaderIso14443a(DWORD parameter) int traceLen = 0; int rsamples = 0; - memset(trace, 0x44, 2000); // was 2000 - tied to oter size chnages + memset(trace, 0x44, 2000); // was 2000 - tied to oter size chnages // setting it to 3000 causes no tag responses to be detected (2900 is ok) // setting it to 1000 causes no tag responses to be detected @@ -1558,6 +1564,8 @@ void ReaderIso14443a(DWORD parameter) FpgaSetupSsc(); // Start from off (no field generated) + // Signal field is off with the appropriate LED + LED_D_OFF(); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); SpinDelay(200); @@ -1565,13 +1573,14 @@ void ReaderIso14443a(DWORD parameter) FpgaSetupSsc(); // Now give it time to spin up. + // Signal field is on with the appropriate LED + LED_D_ON(); FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD); SpinDelay(200); LED_A_ON(); LED_B_OFF(); LED_C_OFF(); - LED_D_OFF(); int samples = 0; int tsamples = 0; @@ -1684,7 +1693,7 @@ void ReaderIso14443a(DWORD parameter) traceLen += Demod.len; if(traceLen > TRACE_LENGTH) goto done; -// OK we have selected at least at cascade 1, lets see if first byte of UID was 0x88 in +// OK we have selected at least at cascade 1, lets see if first byte of UID was 0x88 in // which case we need to make a cascade 2 request and select - this is a long UID if (receivedAnswer[0] == 0x88) { @@ -1759,14 +1768,7 @@ void ReaderIso14443a(DWORD parameter) traceLen += Demod.len; if(traceLen > TRACE_LENGTH) goto done; - - - - - - } - - + } // Secondly compute the two CRC bytes at the end ComputeCrc14443(CRC_14443_A, cmd5, 2, &cmd5[2], &cmd5[3]); @@ -1809,7 +1811,6 @@ done: LED_A_OFF(); LED_B_OFF(); LED_C_OFF(); - LED_D_OFF(); DbpIntegers(rsamples, 0xCC, 0xCC); DbpString("ready.."); } diff --git a/winsrc/command.cpp b/winsrc/command.cpp index 9c4990a3..9599645d 100644 --- a/winsrc/command.cpp +++ b/winsrc/command.cpp @@ -805,7 +805,7 @@ static void CmdHi15demod(char *str) { // The sampling rate is 106.353 ksps/s, for T = 18.8 us - // SOF defined as + // SOF defined as // 1) Unmodulated time of 56.64us // 2) 24 pulses of 423.75khz // 3) logic '1' (unmodulated for 18.88us followed by 8 pulses of 423.75khz) @@ -833,7 +833,7 @@ static void CmdHi15demod(char *str) 1, 1, 1, 1 }; - // EOF defined as + // EOF defined as // 1) logic '0' (8 pulses of 423.75khz followed by unmodulated for 18.88us) // 2) 24 pulses of 423.75khz // 3) Unmodulated time of 56.64us @@ -1667,7 +1667,7 @@ static void Cmdmanchesterdemod(char *str) { BitStream[bitidx++]=GraphBuffer[i-1]; } else { // Error - PrintToScrollback("Warning: Manchester decode error for pulse width detection."); + PrintToScrollback("Warning: Manchester decode error for pulse width detection."); PrintToScrollback("(too many of those messages mean either the stream is not Manchester encoded, or clock is wrong)"); } } @@ -1909,6 +1909,7 @@ static struct { "hi14alist", CmdHi14alist,0, "list ISO 14443a history", // ## New list command "hiddemod", CmdHiddemod,1, "HID Prox Card II (not optimal)", "hidfskdemod", CmdHIDdemodFSK,0, "HID FSK demodulator", + "indalademod", CmdIndalademod,0, "demod samples for Indala", "askdemod", Cmdaskdemod,1, "Attempt to demodulate simple ASK tags", "hidsimtag", CmdHIDsimTAG,0, "HID tag simulator", "mandemod", Cmdmanchesterdemod,1, "Try a Manchester demodulation on a binary stream",