From: Martin Holst Swende Date: Fri, 6 Feb 2015 07:41:02 +0000 (+0100) Subject: Merge branch 'master' into GenericTracing X-Git-Tag: v2.0.0-rc1~23^2~5 X-Git-Url: http://cvs.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/commitdiff_plain/7d5ebac99397fe7661760259377a4f222fdb92cb Merge branch 'master' into GenericTracing Conflicts: armsrc/iso14443.c armsrc/iso14443a.c client/cmdhf.c client/cmdhf14b.c --- 7d5ebac99397fe7661760259377a4f222fdb92cb diff --cc armsrc/iso14443.c index 1191c5bf,6a2e4d6a..92d05782 --- a/armsrc/iso14443.c +++ b/armsrc/iso14443.c @@@ -39,87 -39,87 +39,87 @@@ //----------------------------------------------------------------------------- static void CodeIso14443bAsTag(const uint8_t *cmd, int len) { -- int i; -- -- ToSendReset(); -- -- // Transmit a burst of ones, as the initial thing that lets the -- // reader get phase sync. This (TR1) must be > 80/fs, per spec, -- // but tag that I've tried (a Paypass) exceeds that by a fair bit, -- // so I will too. -- for(i = 0; i < 20; i++) { -- ToSendStuffBit(1); -- ToSendStuffBit(1); -- ToSendStuffBit(1); -- ToSendStuffBit(1); -- } -- -- // Send SOF. -- for(i = 0; i < 10; i++) { -- ToSendStuffBit(0); -- ToSendStuffBit(0); -- ToSendStuffBit(0); -- ToSendStuffBit(0); -- } -- for(i = 0; i < 2; i++) { -- ToSendStuffBit(1); -- ToSendStuffBit(1); -- ToSendStuffBit(1); -- ToSendStuffBit(1); -- } -- -- for(i = 0; i < len; i++) { -- int j; -- uint8_t b = cmd[i]; -- -- // Start bit -- ToSendStuffBit(0); -- ToSendStuffBit(0); -- ToSendStuffBit(0); -- ToSendStuffBit(0); -- -- // Data bits -- for(j = 0; j < 8; j++) { -- if(b & 1) { -- ToSendStuffBit(1); -- ToSendStuffBit(1); -- ToSendStuffBit(1); -- ToSendStuffBit(1); -- } else { -- ToSendStuffBit(0); -- ToSendStuffBit(0); -- ToSendStuffBit(0); -- ToSendStuffBit(0); -- } -- b >>= 1; -- } -- -- // Stop bit -- ToSendStuffBit(1); -- ToSendStuffBit(1); -- ToSendStuffBit(1); -- ToSendStuffBit(1); -- } -- -- // Send SOF. -- for(i = 0; i < 10; i++) { -- ToSendStuffBit(0); -- ToSendStuffBit(0); -- ToSendStuffBit(0); -- ToSendStuffBit(0); -- } -- for(i = 0; i < 10; i++) { -- ToSendStuffBit(1); -- ToSendStuffBit(1); -- ToSendStuffBit(1); -- ToSendStuffBit(1); -- } -- -- // Convert from last byte pos to length -- ToSendMax++; -- -- // Add a few more for slop -- ToSendMax += 2; ++ int i; ++ ++ ToSendReset(); ++ ++ // Transmit a burst of ones, as the initial thing that lets the ++ // reader get phase sync. This (TR1) must be > 80/fs, per spec, ++ // but tag that I've tried (a Paypass) exceeds that by a fair bit, ++ // so I will too. ++ for(i = 0; i < 20; i++) { ++ ToSendStuffBit(1); ++ ToSendStuffBit(1); ++ ToSendStuffBit(1); ++ ToSendStuffBit(1); ++ } ++ ++ // Send SOF. ++ for(i = 0; i < 10; i++) { ++ ToSendStuffBit(0); ++ ToSendStuffBit(0); ++ ToSendStuffBit(0); ++ ToSendStuffBit(0); ++ } ++ for(i = 0; i < 2; i++) { ++ ToSendStuffBit(1); ++ ToSendStuffBit(1); ++ ToSendStuffBit(1); ++ ToSendStuffBit(1); ++ } ++ ++ for(i = 0; i < len; i++) { ++ int j; ++ uint8_t b = cmd[i]; ++ ++ // Start bit ++ ToSendStuffBit(0); ++ ToSendStuffBit(0); ++ ToSendStuffBit(0); ++ ToSendStuffBit(0); ++ ++ // Data bits ++ for(j = 0; j < 8; j++) { ++ if(b & 1) { ++ ToSendStuffBit(1); ++ ToSendStuffBit(1); ++ ToSendStuffBit(1); ++ ToSendStuffBit(1); ++ } else { ++ ToSendStuffBit(0); ++ ToSendStuffBit(0); ++ ToSendStuffBit(0); ++ ToSendStuffBit(0); ++ } ++ b >>= 1; ++ } ++ ++ // Stop bit ++ ToSendStuffBit(1); ++ ToSendStuffBit(1); ++ ToSendStuffBit(1); ++ ToSendStuffBit(1); ++ } ++ ++ // Send SOF. ++ for(i = 0; i < 10; i++) { ++ ToSendStuffBit(0); ++ ToSendStuffBit(0); ++ ToSendStuffBit(0); ++ ToSendStuffBit(0); ++ } ++ for(i = 0; i < 10; i++) { ++ ToSendStuffBit(1); ++ ToSendStuffBit(1); ++ ToSendStuffBit(1); ++ ToSendStuffBit(1); ++ } ++ ++ // Convert from last byte pos to length ++ ToSendMax++; ++ ++ // Add a few more for slop ++ ToSendMax += 2; } //----------------------------------------------------------------------------- @@@ -127,19 -127,19 +127,19 @@@ // variables. //----------------------------------------------------------------------------- static struct { -- enum { -- STATE_UNSYNCD, -- STATE_GOT_FALLING_EDGE_OF_SOF, -- STATE_AWAITING_START_BIT, -- STATE_RECEIVING_DATA, -- STATE_ERROR_WAIT -- } state; -- uint16_t shiftReg; -- int bitCnt; -- int byteCnt; -- int byteCntMax; -- int posCnt; -- uint8_t *output; ++ enum { ++ STATE_UNSYNCD, ++ STATE_GOT_FALLING_EDGE_OF_SOF, ++ STATE_AWAITING_START_BIT, ++ STATE_RECEIVING_DATA, ++ STATE_ERROR_WAIT ++ } state; ++ uint16_t shiftReg; ++ int bitCnt; ++ int byteCnt; ++ int byteCntMax; ++ int posCnt; ++ uint8_t *output; } Uart; /* Receive & handle a bit coming from the reader. @@@ -153,126 -153,126 +153,126 @@@ */ static int 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 - Uart.state = STATE_GOT_FALLING_EDGE_OF_SOF; - Uart.posCnt = 0; - Uart.bitCnt = 0; - } - break; - - case STATE_GOT_FALLING_EDGE_OF_SOF: - Uart.posCnt++; - if(Uart.posCnt == 2) { - if(bit) { - if(Uart.bitCnt >= 10) { - // we've seen enough consecutive - // zeros that it's a valid SOF - 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 - Uart.state = STATE_ERROR_WAIT; - } - } else { - // do nothing, keep waiting - } - Uart.bitCnt++; - } - if(Uart.posCnt >= 4) Uart.posCnt = 0; - if(Uart.bitCnt > 14) { - // Give up if we see too many zeros without - // a one, too. - Uart.state = STATE_ERROR_WAIT; - } - break; - - case STATE_AWAITING_START_BIT: - Uart.posCnt++; - if(bit) { - if(Uart.posCnt > 25) { - // stayed high for too long between - // characters, error - Uart.state = STATE_ERROR_WAIT; - } - } else { - // falling edge, this starts the data byte - Uart.posCnt = 0; - Uart.bitCnt = 0; - Uart.shiftReg = 0; - Uart.state = STATE_RECEIVING_DATA; - LED_A_ON(); // Indicate we're receiving - } - break; - - case STATE_RECEIVING_DATA: - Uart.posCnt++; - if(Uart.posCnt == 2) { - // time to sample a bit - Uart.shiftReg >>= 1; - if(bit) { - Uart.shiftReg |= 0x200; - } - Uart.bitCnt++; - } - if(Uart.posCnt >= 4) { - Uart.posCnt = 0; - } - if(Uart.bitCnt == 10) { - if((Uart.shiftReg & 0x200) && !(Uart.shiftReg & 0x001)) - { - // this is a data byte, with correct - // start and stop bits - Uart.output[Uart.byteCnt] = (Uart.shiftReg >> 1) & 0xff; - Uart.byteCnt++; - - if(Uart.byteCnt >= Uart.byteCntMax) { - // Buffer overflowed, give up - Uart.posCnt = 0; - Uart.state = STATE_ERROR_WAIT; - } else { - // so get the next byte now - Uart.posCnt = 0; - Uart.state = STATE_AWAITING_START_BIT; - } - } else if(Uart.shiftReg == 0x000) { - // this is an EOF byte - LED_A_OFF(); // Finished receiving - return TRUE; - } else { - // this is an error - Uart.posCnt = 0; - Uart.state = STATE_ERROR_WAIT; - } - } - break; - - case STATE_ERROR_WAIT: - // We're all screwed up, so wait a little while - // for whatever went wrong to finish, and then - // start over. - Uart.posCnt++; - if(Uart.posCnt > 10) { - Uart.state = STATE_UNSYNCD; - } - break; - - default: - Uart.state = STATE_UNSYNCD; - break; - } - - // This row make the error blew circular buffer in hf 14b snoop - //if (Uart.state == STATE_ERROR_WAIT) LED_A_OFF(); // Error - - return FALSE; ++ switch(Uart.state) { + case STATE_UNSYNCD: - LED_A_OFF(); - if(!bit) { - // we went low, so this could be the beginning - // of an SOF - Uart.state = STATE_GOT_FALLING_EDGE_OF_SOF; - Uart.posCnt = 0; - Uart.bitCnt = 0; - } - break; - - case STATE_GOT_FALLING_EDGE_OF_SOF: - Uart.posCnt++; - if(Uart.posCnt == 2) { - if(bit) { - if(Uart.bitCnt >= 10) { - // we've seen enough consecutive - // zeros that it's a valid SOF - 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 - Uart.state = STATE_ERROR_WAIT; - } - } else { - // do nothing, keep waiting - } - Uart.bitCnt++; - } - if(Uart.posCnt >= 4) Uart.posCnt = 0; - if(Uart.bitCnt > 14) { - // Give up if we see too many zeros without - // a one, too. - Uart.state = STATE_ERROR_WAIT; - } - break; - - case STATE_AWAITING_START_BIT: - Uart.posCnt++; - if(bit) { - if(Uart.posCnt > 25) { - // stayed high for too long between - // characters, error - Uart.state = STATE_ERROR_WAIT; - } - } else { - // falling edge, this starts the data byte - Uart.posCnt = 0; - Uart.bitCnt = 0; - Uart.shiftReg = 0; - Uart.state = STATE_RECEIVING_DATA; - LED_A_ON(); // Indicate we're receiving - } - break; - - case STATE_RECEIVING_DATA: - Uart.posCnt++; - if(Uart.posCnt == 2) { - // time to sample a bit - Uart.shiftReg >>= 1; - if(bit) { - Uart.shiftReg |= 0x200; - } - Uart.bitCnt++; - } - if(Uart.posCnt >= 4) { - Uart.posCnt = 0; - } - if(Uart.bitCnt == 10) { - if((Uart.shiftReg & 0x200) && !(Uart.shiftReg & 0x001)) - { - // this is a data byte, with correct - // start and stop bits - Uart.output[Uart.byteCnt] = (Uart.shiftReg >> 1) & 0xff; - Uart.byteCnt++; - - if(Uart.byteCnt >= Uart.byteCntMax) { - // Buffer overflowed, give up - Uart.posCnt = 0; - Uart.state = STATE_ERROR_WAIT; - } else { - // so get the next byte now - Uart.posCnt = 0; - Uart.state = STATE_AWAITING_START_BIT; - } - } else if(Uart.shiftReg == 0x000) { - // this is an EOF byte - LED_A_OFF(); // Finished receiving - return TRUE; - } else { - // this is an error - Uart.posCnt = 0; - Uart.state = STATE_ERROR_WAIT; - } - } - break; - - case STATE_ERROR_WAIT: - // We're all screwed up, so wait a little while - // for whatever went wrong to finish, and then - // start over. - Uart.posCnt++; - if(Uart.posCnt > 10) { - Uart.state = STATE_UNSYNCD; - } - break; - - default: - Uart.state = STATE_UNSYNCD; - break; - } - - // This row make the error blew circular buffer in hf 14b snoop - //if (Uart.state == STATE_ERROR_WAIT) LED_A_OFF(); // Error - - return FALSE; ++ LED_A_OFF(); ++ if(!bit) { ++ // we went low, so this could be the beginning ++ // of an SOF ++ Uart.state = STATE_GOT_FALLING_EDGE_OF_SOF; ++ Uart.posCnt = 0; ++ Uart.bitCnt = 0; ++ } ++ break; ++ ++ case STATE_GOT_FALLING_EDGE_OF_SOF: ++ Uart.posCnt++; ++ if(Uart.posCnt == 2) { ++ if(bit) { ++ if(Uart.bitCnt >= 10) { ++ // we've seen enough consecutive ++ // zeros that it's a valid SOF ++ 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 ++ Uart.state = STATE_ERROR_WAIT; ++ } ++ } else { ++ // do nothing, keep waiting ++ } ++ Uart.bitCnt++; ++ } ++ if(Uart.posCnt >= 4) Uart.posCnt = 0; ++ if(Uart.bitCnt > 14) { ++ // Give up if we see too many zeros without ++ // a one, too. ++ Uart.state = STATE_ERROR_WAIT; ++ } ++ break; ++ ++ case STATE_AWAITING_START_BIT: ++ Uart.posCnt++; ++ if(bit) { ++ if(Uart.posCnt > 25) { ++ // stayed high for too long between ++ // characters, error ++ Uart.state = STATE_ERROR_WAIT; ++ } ++ } else { ++ // falling edge, this starts the data byte ++ Uart.posCnt = 0; ++ Uart.bitCnt = 0; ++ Uart.shiftReg = 0; ++ Uart.state = STATE_RECEIVING_DATA; ++ LED_A_ON(); // Indicate we're receiving ++ } ++ break; ++ ++ case STATE_RECEIVING_DATA: ++ Uart.posCnt++; ++ if(Uart.posCnt == 2) { ++ // time to sample a bit ++ Uart.shiftReg >>= 1; ++ if(bit) { ++ Uart.shiftReg |= 0x200; ++ } ++ Uart.bitCnt++; ++ } ++ if(Uart.posCnt >= 4) { ++ Uart.posCnt = 0; ++ } ++ if(Uart.bitCnt == 10) { ++ if((Uart.shiftReg & 0x200) && !(Uart.shiftReg & 0x001)) ++ { ++ // this is a data byte, with correct ++ // start and stop bits ++ Uart.output[Uart.byteCnt] = (Uart.shiftReg >> 1) & 0xff; ++ Uart.byteCnt++; ++ ++ if(Uart.byteCnt >= Uart.byteCntMax) { ++ // Buffer overflowed, give up ++ Uart.posCnt = 0; ++ Uart.state = STATE_ERROR_WAIT; ++ } else { ++ // so get the next byte now ++ Uart.posCnt = 0; ++ Uart.state = STATE_AWAITING_START_BIT; ++ } ++ } else if(Uart.shiftReg == 0x000) { ++ // this is an EOF byte ++ LED_A_OFF(); // Finished receiving ++ return TRUE; ++ } else { ++ // this is an error ++ Uart.posCnt = 0; ++ Uart.state = STATE_ERROR_WAIT; ++ } ++ } ++ break; ++ ++ case STATE_ERROR_WAIT: ++ // We're all screwed up, so wait a little while ++ // for whatever went wrong to finish, and then ++ // start over. ++ Uart.posCnt++; ++ if(Uart.posCnt > 10) { ++ Uart.state = STATE_UNSYNCD; ++ } ++ break; ++ ++ default: ++ Uart.state = STATE_UNSYNCD; ++ break; ++ } ++ ++ // This row make the error blew circular buffer in hf 14b snoop ++ //if (Uart.state == STATE_ERROR_WAIT) LED_A_OFF(); // Error ++ ++ return FALSE; } //----------------------------------------------------------------------------- @@@ -286,42 -286,42 +286,42 @@@ //----------------------------------------------------------------------------- static int GetIso14443CommandFromReader(uint8_t *received, int *len, int maxLen) { -- uint8_t mask; -- int i, bit; -- -- // 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); -- -- -- // Now run a `software UART' on the stream of incoming samples. -- Uart.output = received; -- Uart.byteCntMax = maxLen; -- Uart.state = STATE_UNSYNCD; -- -- for(;;) { -- WDT_HIT(); -- -- if(BUTTON_PRESS()) return FALSE; -- -- if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { -- AT91C_BASE_SSC->SSC_THR = 0x00; -- } -- if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { -- uint8_t b = (uint8_t)AT91C_BASE_SSC->SSC_RHR; -- -- mask = 0x80; -- for(i = 0; i < 8; i++, mask >>= 1) { -- bit = (b & mask); -- if(Handle14443UartBit(bit)) { -- *len = Uart.byteCnt; -- return TRUE; -- } -- } -- } -- } ++ uint8_t mask; ++ int i, bit; ++ ++ // 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); ++ ++ ++ // Now run a `software UART' on the stream of incoming samples. ++ Uart.output = received; ++ Uart.byteCntMax = maxLen; ++ Uart.state = STATE_UNSYNCD; ++ ++ for(;;) { ++ WDT_HIT(); ++ ++ if(BUTTON_PRESS()) return FALSE; ++ ++ if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { ++ AT91C_BASE_SSC->SSC_THR = 0x00; ++ } ++ if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { ++ uint8_t b = (uint8_t)AT91C_BASE_SSC->SSC_RHR; ++ ++ mask = 0x80; ++ for(i = 0; i < 8; i++, mask >>= 1) { ++ bit = (b & mask); ++ if(Handle14443UartBit(bit)) { ++ *len = Uart.byteCnt; ++ return TRUE; ++ } ++ } ++ } ++ } } //----------------------------------------------------------------------------- @@@ -330,99 -330,99 +330,99 @@@ //----------------------------------------------------------------------------- void SimulateIso14443Tag(void) { -- static const uint8_t cmd1[] = { 0x05, 0x00, 0x08, 0x39, 0x73 }; -- static const uint8_t response1[] = { -- 0x50, 0x82, 0x0d, 0xe1, 0x74, 0x20, 0x38, 0x19, 0x22, -- 0x00, 0x21, 0x85, 0x5e, 0xd7 -- }; ++ static const uint8_t cmd1[] = { 0x05, 0x00, 0x08, 0x39, 0x73 }; ++ static const uint8_t response1[] = { ++ 0x50, 0x82, 0x0d, 0xe1, 0x74, 0x20, 0x38, 0x19, 0x22, ++ 0x00, 0x21, 0x85, 0x5e, 0xd7 ++ }; -- uint8_t *resp; -- int respLen; ++ uint8_t *resp; ++ int respLen; - uint8_t *resp1 = (((uint8_t *)BigBuf) + 800); - uint8_t *resp1 = BigBuf_get_addr() + 800; -- int resp1Len; ++ uint8_t *resp1 = BigBuf_get_addr() + 800; ++ int resp1Len; - uint8_t *receivedCmd = (uint8_t *)BigBuf; - uint8_t *receivedCmd = BigBuf_get_addr(); -- int len; ++ uint8_t *receivedCmd = BigBuf_get_addr(); ++ int len; -- int i; ++ int i; -- int cmdsRecvd = 0; ++ int cmdsRecvd = 0; -- FpgaDownloadAndGo(FPGA_BITSTREAM_HF); -- memset(receivedCmd, 0x44, 400); ++ FpgaDownloadAndGo(FPGA_BITSTREAM_HF); ++ memset(receivedCmd, 0x44, 400); -- CodeIso14443bAsTag(response1, sizeof(response1)); -- memcpy(resp1, ToSend, ToSendMax); resp1Len = ToSendMax; ++ CodeIso14443bAsTag(response1, sizeof(response1)); ++ memcpy(resp1, ToSend, ToSendMax); resp1Len = ToSendMax; -- // We need to listen to the high-frequency, peak-detected path. -- SetAdcMuxFor(GPIO_MUXSEL_HIPKD); -- FpgaSetupSsc(); ++ // We need to listen to the high-frequency, peak-detected path. ++ SetAdcMuxFor(GPIO_MUXSEL_HIPKD); ++ FpgaSetupSsc(); -- cmdsRecvd = 0; ++ cmdsRecvd = 0; -- for(;;) { -- uint8_t b1, b2; ++ for(;;) { ++ uint8_t b1, b2; -- if(!GetIso14443CommandFromReader(receivedCmd, &len, 100)) { ++ if(!GetIso14443CommandFromReader(receivedCmd, &len, 100)) { Dbprintf("button pressed, received %d commands", cmdsRecvd); break; -- } -- -- // Good, look at the command now. -- -- if(len == sizeof(cmd1) && memcmp(receivedCmd, cmd1, len)==0) { -- resp = resp1; respLen = resp1Len; -- } else { -- Dbprintf("new cmd from reader: len=%d, cmdsRecvd=%d", len, cmdsRecvd); -- // And print whether the CRC fails, just for good measure -- ComputeCrc14443(CRC_14443_B, receivedCmd, len-2, &b1, &b2); -- if(b1 != receivedCmd[len-2] || b2 != receivedCmd[len-1]) { -- // Not so good, try again. -- DbpString("+++CRC fail"); -- } else { -- DbpString("CRC passes"); -- } -- break; -- } -- -- memset(receivedCmd, 0x44, 32); -- -- cmdsRecvd++; -- -- if(cmdsRecvd > 0x30) { -- DbpString("many commands later..."); -- break; -- } -- -- 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); -- AT91C_BASE_SSC->SSC_THR = 0xff; -- FpgaSetupSsc(); -- -- // Transmit the response. -- i = 0; -- for(;;) { -- if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { -- uint8_t b = resp[i]; -- -- AT91C_BASE_SSC->SSC_THR = b; -- -- i++; -- if(i > respLen) { -- break; -- } -- } -- if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { -- volatile uint8_t b = (uint8_t)AT91C_BASE_SSC->SSC_RHR; -- (void)b; -- } -- } -- } ++ } ++ ++ // Good, look at the command now. ++ ++ if(len == sizeof(cmd1) && memcmp(receivedCmd, cmd1, len)==0) { ++ resp = resp1; respLen = resp1Len; ++ } else { ++ Dbprintf("new cmd from reader: len=%d, cmdsRecvd=%d", len, cmdsRecvd); ++ // And print whether the CRC fails, just for good measure ++ ComputeCrc14443(CRC_14443_B, receivedCmd, len-2, &b1, &b2); ++ if(b1 != receivedCmd[len-2] || b2 != receivedCmd[len-1]) { ++ // Not so good, try again. ++ DbpString("+++CRC fail"); ++ } else { ++ DbpString("CRC passes"); ++ } ++ break; ++ } ++ ++ memset(receivedCmd, 0x44, 32); ++ ++ cmdsRecvd++; ++ ++ if(cmdsRecvd > 0x30) { ++ DbpString("many commands later..."); ++ break; ++ } ++ ++ 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); ++ AT91C_BASE_SSC->SSC_THR = 0xff; ++ FpgaSetupSsc(); ++ ++ // Transmit the response. ++ i = 0; ++ for(;;) { ++ if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { ++ uint8_t b = resp[i]; ++ ++ AT91C_BASE_SSC->SSC_THR = b; ++ ++ i++; ++ if(i > respLen) { ++ break; ++ } ++ } ++ if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { ++ volatile uint8_t b = (uint8_t)AT91C_BASE_SSC->SSC_RHR; ++ (void)b; ++ } ++ } ++ } } //============================================================================= @@@ -433,25 -433,25 +433,25 @@@ //============================================================================= static struct { -- enum { -- DEMOD_UNSYNCD, -- DEMOD_PHASE_REF_TRAINING, -- DEMOD_AWAITING_FALLING_EDGE_OF_SOF, -- DEMOD_GOT_FALLING_EDGE_OF_SOF, -- DEMOD_AWAITING_START_BIT, -- DEMOD_RECEIVING_DATA, -- DEMOD_ERROR_WAIT -- } state; -- int bitCount; -- int posCount; -- int thisBit; -- int metric; -- int metricN; -- uint16_t shiftReg; -- uint8_t *output; -- int len; -- int sumI; -- int sumQ; ++ enum { ++ DEMOD_UNSYNCD, ++ DEMOD_PHASE_REF_TRAINING, ++ DEMOD_AWAITING_FALLING_EDGE_OF_SOF, ++ DEMOD_GOT_FALLING_EDGE_OF_SOF, ++ DEMOD_AWAITING_START_BIT, ++ DEMOD_RECEIVING_DATA, ++ DEMOD_ERROR_WAIT ++ } state; ++ int bitCount; ++ int posCount; ++ int thisBit; ++ int metric; ++ int metricN; ++ uint16_t shiftReg; ++ uint8_t *output; ++ int len; ++ int sumI; ++ int sumQ; } Demod; /* @@@ -467,251 -467,238 +467,266 @@@ */ static RAMFUNC int Handle14443SamplesDemod(int ci, int cq) { -- int v; ++ int v; -- // The soft decision on the bit uses an estimate of just the -- // quadrant of the reference angle, not the exact angle. ++ // The soft decision on the bit uses an estimate of just the ++ // quadrant of the reference angle, not the exact angle. #define MAKE_SOFT_DECISION() { \ -- if(Demod.sumI > 0) { \ -- v = ci; \ -- } else { \ -- v = -ci; \ -- } \ -- if(Demod.sumQ > 0) { \ -- v += cq; \ -- } else { \ -- v -= cq; \ -- } \ -- } -- -- switch(Demod.state) { -- case DEMOD_UNSYNCD: -- v = ci; -- if(v < 0) v = -v; -- if(cq > 0) { -- v += cq; -- } else { -- v -= cq; -- } -- if(v > 40) { -- Demod.posCount = 0; -- Demod.state = DEMOD_PHASE_REF_TRAINING; -- Demod.sumI = 0; -- Demod.sumQ = 0; -- } -- break; -- -- case DEMOD_PHASE_REF_TRAINING: -- if(Demod.posCount < 8) { -- Demod.sumI += ci; -- Demod.sumQ += cq; -- } else if(Demod.posCount > 100) { -- // error, waited too long -- Demod.state = DEMOD_UNSYNCD; -- } else { -- MAKE_SOFT_DECISION(); -- if(v < 0) { -- Demod.state = DEMOD_AWAITING_FALLING_EDGE_OF_SOF; -- Demod.posCount = 0; -- } -- } -- Demod.posCount++; -- break; -- -- case DEMOD_AWAITING_FALLING_EDGE_OF_SOF: -- MAKE_SOFT_DECISION(); -- if(v < 0) { -- Demod.state = DEMOD_GOT_FALLING_EDGE_OF_SOF; -- Demod.posCount = 0; -- } else { -- if(Demod.posCount > 100) { -- Demod.state = DEMOD_UNSYNCD; -- } -- } -- Demod.posCount++; -- break; -- -- case DEMOD_GOT_FALLING_EDGE_OF_SOF: -- MAKE_SOFT_DECISION(); -- if(v > 0) { -- 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; -- Demod.metricN = 0; -- Demod.metric = 0; -- } -- } else { -- if(Demod.posCount > 100) { -- Demod.state = DEMOD_UNSYNCD; -- } -- } -- Demod.posCount++; -- break; -- -- case DEMOD_AWAITING_START_BIT: -- MAKE_SOFT_DECISION(); -- if(v > 0) { -- if(Demod.posCount > 10) { -- Demod.state = DEMOD_UNSYNCD; -- } -- } else { -- Demod.bitCount = 0; -- Demod.posCount = 1; -- Demod.thisBit = v; -- Demod.shiftReg = 0; -- Demod.state = DEMOD_RECEIVING_DATA; -- } -- break; -- -- case DEMOD_RECEIVING_DATA: -- MAKE_SOFT_DECISION(); -- if(Demod.posCount == 0) { -- Demod.thisBit = v; -- Demod.posCount = 1; -- } else { -- Demod.thisBit += v; -- -- if(Demod.thisBit > 0) { -- Demod.metric += Demod.thisBit; -- } else { -- Demod.metric -= Demod.thisBit; -- } -- (Demod.metricN)++; -- -- Demod.shiftReg >>= 1; -- if(Demod.thisBit > 0) { -- Demod.shiftReg |= 0x200; -- } -- -- Demod.bitCount++; -- if(Demod.bitCount == 10) { -- uint16_t s = Demod.shiftReg; -- if((s & 0x200) && !(s & 0x001)) { -- uint8_t b = (s >> 1); -- Demod.output[Demod.len] = b; -- Demod.len++; -- Demod.state = DEMOD_AWAITING_START_BIT; -- } else if(s == 0x000) { -- // This is EOF -- LED_C_OFF(); -- Demod.state = DEMOD_UNSYNCD; -- return TRUE; -- } else { -- Demod.state = DEMOD_UNSYNCD; -- } -- } -- Demod.posCount = 0; -- } -- break; -- -- default: -- Demod.state = DEMOD_UNSYNCD; -- break; -- } -- -- if (Demod.state == DEMOD_UNSYNCD) LED_C_OFF(); // Not synchronized... -- return FALSE; - } ++ if(Demod.sumI > 0) { \ ++ v = ci; \ ++ } else { \ ++ v = -ci; \ ++ } \ ++ if(Demod.sumQ > 0) { \ ++ v += cq; \ ++ } else { \ ++ v -= cq; \ ++ } \ ++ } + ++ switch(Demod.state) { ++ case DEMOD_UNSYNCD: ++ v = ci; ++ if(v < 0) v = -v; ++ if(cq > 0) { ++ v += cq; ++ } else { ++ v -= cq; ++ } ++ if(v > 40) { ++ Demod.posCount = 0; ++ Demod.state = DEMOD_PHASE_REF_TRAINING; ++ Demod.sumI = 0; ++ Demod.sumQ = 0; ++ } ++ break; ++ ++ case DEMOD_PHASE_REF_TRAINING: ++ if(Demod.posCount < 8) { ++ Demod.sumI += ci; ++ Demod.sumQ += cq; ++ } else if(Demod.posCount > 100) { ++ // error, waited too long ++ Demod.state = DEMOD_UNSYNCD; ++ } else { ++ MAKE_SOFT_DECISION(); ++ if(v < 0) { ++ Demod.state = DEMOD_AWAITING_FALLING_EDGE_OF_SOF; ++ Demod.posCount = 0; ++ } ++ } ++ Demod.posCount++; ++ break; ++ ++ case DEMOD_AWAITING_FALLING_EDGE_OF_SOF: ++ MAKE_SOFT_DECISION(); ++ if(v < 0) { ++ Demod.state = DEMOD_GOT_FALLING_EDGE_OF_SOF; ++ Demod.posCount = 0; ++ } else { ++ if(Demod.posCount > 100) { ++ Demod.state = DEMOD_UNSYNCD; ++ } ++ } ++ Demod.posCount++; ++ break; ++ ++ case DEMOD_GOT_FALLING_EDGE_OF_SOF: ++ MAKE_SOFT_DECISION(); ++ if(v > 0) { ++ 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; ++ Demod.metricN = 0; ++ Demod.metric = 0; ++ } ++ } else { ++ if(Demod.posCount > 100) { ++ Demod.state = DEMOD_UNSYNCD; ++ } ++ } ++ Demod.posCount++; ++ break; ++ ++ case DEMOD_AWAITING_START_BIT: ++ MAKE_SOFT_DECISION(); ++ if(v > 0) { ++ if(Demod.posCount > 10) { ++ Demod.state = DEMOD_UNSYNCD; ++ } ++ } else { ++ Demod.bitCount = 0; ++ Demod.posCount = 1; ++ Demod.thisBit = v; ++ Demod.shiftReg = 0; ++ Demod.state = DEMOD_RECEIVING_DATA; ++ } ++ break; ++ ++ case DEMOD_RECEIVING_DATA: ++ MAKE_SOFT_DECISION(); ++ if(Demod.posCount == 0) { ++ Demod.thisBit = v; ++ Demod.posCount = 1; ++ } else { ++ Demod.thisBit += v; ++ ++ if(Demod.thisBit > 0) { ++ Demod.metric += Demod.thisBit; ++ } else { ++ Demod.metric -= Demod.thisBit; ++ } ++ (Demod.metricN)++; ++ ++ Demod.shiftReg >>= 1; ++ if(Demod.thisBit > 0) { ++ Demod.shiftReg |= 0x200; ++ } ++ ++ Demod.bitCount++; ++ if(Demod.bitCount == 10) { ++ uint16_t s = Demod.shiftReg; ++ if((s & 0x200) && !(s & 0x001)) { ++ uint8_t b = (s >> 1); ++ Demod.output[Demod.len] = b; ++ Demod.len++; ++ Demod.state = DEMOD_AWAITING_START_BIT; ++ } else if(s == 0x000) { ++ // This is EOF ++ LED_C_OFF(); ++ Demod.state = DEMOD_UNSYNCD; ++ return TRUE; ++ } else { ++ Demod.state = DEMOD_UNSYNCD; ++ } ++ } ++ Demod.posCount = 0; ++ } ++ break; ++ ++ default: ++ Demod.state = DEMOD_UNSYNCD; ++ break; ++ } ++ ++ if (Demod.state == DEMOD_UNSYNCD) LED_C_OFF(); // Not synchronized... ++ return FALSE; ++} +static void DemodReset() +{ + // Clear out the state of the "UART" that receives from the tag. - Demod.output = ((uint8_t *)BigBuf) + RECV_RESP_OFFSET; + Demod.len = 0; + Demod.state = DEMOD_UNSYNCD; + memset(Demod.output, 0x00, MAX_FRAME_SIZE); - ++} ++static void DemodInit(uint8_t *data) ++{ ++ Demod.output = data; ++ DemodReset(); +} + +static void UartReset() +{ - // And the UART that receives from the reader - Uart.output = ((uint8_t *)BigBuf) + RECV_CMD_OFFSET; + Uart.byteCntMax = MAX_FRAME_SIZE; + Uart.state = STATE_UNSYNCD; + Uart.byteCnt = 0; + Uart.bitCnt = 0; +} ++static void UartInit(uint8_t *data) ++{ ++ Uart.output = data; ++ UartReset(); + } /* - * Demodulate the samples we received from the tag + * Demodulate the samples we received from the tag, also log to tracebuffer * 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(int weTx, int n, int quiet) { -- int max = 0; -- int gotFrame = FALSE; - -//# define DMA_BUFFER_SIZE 8 - uint8_t *dmaBuf; -- -- int lastRxCounter; - uint8_t *upTo; -- -- int ci, cq; - - int samples = 0; - - // Clear out the state of the "UART" that receives from the tag. - uint8_t *BigBuf = BigBuf_get_addr(); - memset(BigBuf, 0x00, 400); - Demod.output = BigBuf; - Demod.len = 0; - Demod.state = DEMOD_UNSYNCD; - - // And the UART that receives from the reader - Uart.output = BigBuf + 1024; - Uart.byteCntMax = 100; - Uart.state = STATE_UNSYNCD; - - // Setup for the DMA. - dmaBuf = BigBuf + 32; - upTo = dmaBuf; - lastRxCounter = DEMOD_DMA_BUFFER_SIZE; - FpgaSetupSscDma(dmaBuf, DEMOD_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 | - (weTx ? 0 : FPGA_HF_READER_RX_XCORR_SNOOP)); - - for(;;) { - int behindBy = lastRxCounter - AT91C_BASE_PDC_SSC->PDC_RCR; - if(behindBy > max) max = behindBy; - - while(((lastRxCounter-AT91C_BASE_PDC_SSC->PDC_RCR) & (DEMOD_DMA_BUFFER_SIZE-1)) - > 2) - { - ci = upTo[0]; - cq = upTo[1]; - upTo += 2; - if(upTo - dmaBuf > DEMOD_DMA_BUFFER_SIZE) { - upTo -= DEMOD_DMA_BUFFER_SIZE; - AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) upTo; - AT91C_BASE_PDC_SSC->PDC_RNCR = DEMOD_DMA_BUFFER_SIZE; - } - lastRxCounter -= 2; - if(lastRxCounter <= 0) { - lastRxCounter += DEMOD_DMA_BUFFER_SIZE; - } - - samples += 2; - - Handle14443UartBit(1); - Handle14443UartBit(1); - - if(Handle14443SamplesDemod(ci, cq)) { - gotFrame = 1; - } - } - - if(samples > 2000) { - break; - } - } - AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTDIS; - if (!quiet) Dbprintf("%x %x %x", max, gotFrame, Demod.len); ++ int max = 0; ++ int gotFrame = FALSE; ++ int lastRxCounter, ci, cq, samples = 0; ++ ++ // Allocate memory from BigBuf for some buffers ++ // free all previous allocations first ++ BigBuf_free(); ++ ++ // The command (reader -> tag) that we're receiving. ++ uint8_t *receivedCmd = BigBuf_malloc(MAX_FRAME_SIZE); ++ ++ // The response (tag -> reader) that we're receiving. ++ uint8_t *receivedResponse = BigBuf_malloc(MAX_FRAME_SIZE); ++ ++ // The DMA buffer, used to stream samples from the FPGA ++ uint8_t *dmaBuf = BigBuf_malloc(DMA_BUFFER_SIZE); + - int samples = 0; ++ // Set up the demodulator for tag -> reader responses. ++ DemodInit(receivedResponse); ++ // Set up the demodulator for the reader -> tag commands ++ UartInit(receivedCmd); + - DemodReset(); - UartReset(); ++ // Setup and start DMA. ++ FpgaSetupSscDma(dmaBuf, DMA_BUFFER_SIZE); + - // The DMA buffer, used to stream samples from the FPGA - int8_t *dmaBuf = ((int8_t *)BigBuf) + DMA_BUFFER_OFFSET; - int8_t *upTo= dmaBuf; ++ uint8_t *upTo= dmaBuf; + lastRxCounter = DMA_BUFFER_SIZE; - FpgaSetupSscDma((uint8_t *)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 | - (weTx ? 0 : FPGA_HF_READER_RX_XCORR_SNOOP)); ++ // 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 | ++ (weTx ? 0 : FPGA_HF_READER_RX_XCORR_SNOOP)); + - for(;;) { - int behindBy = lastRxCounter - AT91C_BASE_PDC_SSC->PDC_RCR; - if(behindBy > max) max = behindBy; ++ for(;;) { ++ int behindBy = lastRxCounter - AT91C_BASE_PDC_SSC->PDC_RCR; ++ if(behindBy > max) max = behindBy; + + while(((lastRxCounter-AT91C_BASE_PDC_SSC->PDC_RCR) & (DMA_BUFFER_SIZE-1)) - > 2) - { - ci = upTo[0]; - cq = upTo[1]; - upTo += 2; ++ > 2) ++ { ++ ci = upTo[0]; ++ cq = upTo[1]; ++ upTo += 2; + if(upTo - dmaBuf > DMA_BUFFER_SIZE) { + upTo -= DMA_BUFFER_SIZE; - AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) upTo; ++ AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) upTo; + AT91C_BASE_PDC_SSC->PDC_RNCR = DMA_BUFFER_SIZE; - } - lastRxCounter -= 2; - if(lastRxCounter <= 0) { ++ } ++ lastRxCounter -= 2; ++ if(lastRxCounter <= 0) { + lastRxCounter += DMA_BUFFER_SIZE; - } ++ } + - samples += 2; ++ samples += 2; + - Handle14443UartBit(1); - Handle14443UartBit(1); ++ Handle14443UartBit(1); ++ Handle14443UartBit(1); + - if(Handle14443SamplesDemod(ci, cq)) { - gotFrame = 1; - } - } ++ if(Handle14443SamplesDemod(ci, cq)) { ++ gotFrame = 1; ++ } ++ } + - if(samples > 2000) { - break; - } - } - AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTDIS; - if (!quiet) Dbprintf("%x %x %x", max, gotFrame, Demod.len); ++ if(samples > 2000) { ++ break; ++ } ++ } ++ AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTDIS; ++ if (!quiet) Dbprintf("%x %x %x", max, gotFrame, Demod.len); + //Tracing + if (tracing && Demod.len > 0) { + uint8_t parity[MAX_PARITY_SIZE]; + GetParity(Demod.output , Demod.len, parity); + LogTrace(Demod.output,Demod.len, 0, 0, parity, FALSE); + } } //----------------------------------------------------------------------------- @@@ -721,29 -708,29 +736,29 @@@ //----------------------------------------------------------------------------- /*static void GetSamplesFor14443(int weTx, int n) { -- uint8_t *dest = (uint8_t *)BigBuf; -- int c; -- -- FpgaWriteConfWord( -- FPGA_MAJOR_MODE_HF_READER_RX_XCORR | FPGA_HF_READER_RX_XCORR_848_KHZ | -- (weTx ? 0 : FPGA_HF_READER_RX_XCORR_SNOOP)); -- -- c = 0; -- for(;;) { -- if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { -- AT91C_BASE_SSC->SSC_THR = 0x43; -- } -- if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { -- int8_t b; -- b = (int8_t)AT91C_BASE_SSC->SSC_RHR; -- -- dest[c++] = (uint8_t)b; -- -- if(c >= n) { -- break; -- } -- } -- } ++ uint8_t *dest = (uint8_t *)BigBuf; ++ int c; ++ ++ FpgaWriteConfWord( ++ FPGA_MAJOR_MODE_HF_READER_RX_XCORR | FPGA_HF_READER_RX_XCORR_848_KHZ | ++ (weTx ? 0 : FPGA_HF_READER_RX_XCORR_SNOOP)); ++ ++ c = 0; ++ for(;;) { ++ if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { ++ AT91C_BASE_SSC->SSC_THR = 0x43; ++ } ++ if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { ++ int8_t b; ++ b = (int8_t)AT91C_BASE_SSC->SSC_RHR; ++ ++ dest[c++] = (uint8_t)b; ++ ++ if(c >= n) { ++ break; ++ } ++ } ++ } }*/ //----------------------------------------------------------------------------- @@@ -751,49 -738,49 +766,49 @@@ //----------------------------------------------------------------------------- static void TransmitFor14443(void) { -- int c; ++ int c; -- FpgaSetupSsc(); ++ FpgaSetupSsc(); -- while(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { -- AT91C_BASE_SSC->SSC_THR = 0xff; -- } ++ while(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { ++ AT91C_BASE_SSC->SSC_THR = 0xff; ++ } -- // Signal field is ON with the appropriate Red LED ++ // 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;) { -- if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { -- AT91C_BASE_SSC->SSC_THR = 0xff; -- c++; -- } -- if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { -- volatile uint32_t r = AT91C_BASE_SSC->SSC_RHR; -- (void)r; -- } -- WDT_HIT(); -- } -- -- c = 0; -- for(;;) { -- if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { -- AT91C_BASE_SSC->SSC_THR = ToSend[c]; -- c++; -- if(c >= ToSendMax) { -- break; -- } -- } -- if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { -- volatile uint32_t r = AT91C_BASE_SSC->SSC_RHR; -- (void)r; -- } -- WDT_HIT(); -- } -- LED_B_OFF(); // Finished sending ++ FPGA_MAJOR_MODE_HF_READER_TX | FPGA_HF_READER_TX_SHALLOW_MOD); ++ ++ for(c = 0; c < 10;) { ++ if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { ++ AT91C_BASE_SSC->SSC_THR = 0xff; ++ c++; ++ } ++ if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { ++ volatile uint32_t r = AT91C_BASE_SSC->SSC_RHR; ++ (void)r; ++ } ++ WDT_HIT(); ++ } ++ ++ c = 0; ++ for(;;) { ++ if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { ++ AT91C_BASE_SSC->SSC_THR = ToSend[c]; ++ c++; ++ if(c >= ToSendMax) { ++ break; ++ } ++ } ++ if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { ++ volatile uint32_t r = AT91C_BASE_SSC->SSC_RHR; ++ (void)r; ++ } ++ WDT_HIT(); ++ } ++ LED_B_OFF(); // Finished sending } //----------------------------------------------------------------------------- @@@ -802,54 -789,54 +817,54 @@@ //----------------------------------------------------------------------------- static void CodeIso14443bAsReader(const uint8_t *cmd, int len) { -- int i, j; -- uint8_t b; -- -- ToSendReset(); -- -- // Establish initial reference level -- for(i = 0; i < 40; i++) { -- ToSendStuffBit(1); -- } -- // Send SOF -- for(i = 0; i < 10; i++) { -- ToSendStuffBit(0); -- } -- -- for(i = 0; i < len; i++) { -- // Stop bits/EGT -- ToSendStuffBit(1); -- ToSendStuffBit(1); -- // Start bit -- ToSendStuffBit(0); -- // Data bits -- b = cmd[i]; -- for(j = 0; j < 8; j++) { -- if(b & 1) { -- ToSendStuffBit(1); -- } else { -- ToSendStuffBit(0); -- } -- b >>= 1; -- } -- } -- // Send EOF -- ToSendStuffBit(1); -- for(i = 0; i < 10; i++) { -- ToSendStuffBit(0); -- } -- for(i = 0; i < 8; i++) { -- ToSendStuffBit(1); -- } -- -- // And then a little more, to make sure that the last character makes -- // it out before we switch to rx mode. -- for(i = 0; i < 24; i++) { -- ToSendStuffBit(1); -- } -- -- // Convert from last character reference to length -- ToSendMax++; ++ int i, j; ++ uint8_t b; ++ ++ ToSendReset(); ++ ++ // Establish initial reference level ++ for(i = 0; i < 40; i++) { ++ ToSendStuffBit(1); ++ } ++ // Send SOF ++ for(i = 0; i < 10; i++) { ++ ToSendStuffBit(0); ++ } ++ ++ for(i = 0; i < len; i++) { ++ // Stop bits/EGT ++ ToSendStuffBit(1); ++ ToSendStuffBit(1); ++ // Start bit ++ ToSendStuffBit(0); ++ // Data bits ++ b = cmd[i]; ++ for(j = 0; j < 8; j++) { ++ if(b & 1) { ++ ToSendStuffBit(1); ++ } else { ++ ToSendStuffBit(0); ++ } ++ b >>= 1; ++ } ++ } ++ // Send EOF ++ ToSendStuffBit(1); ++ for(i = 0; i < 10; i++) { ++ ToSendStuffBit(0); ++ } ++ for(i = 0; i < 8; i++) { ++ ToSendStuffBit(1); ++ } ++ ++ // And then a little more, to make sure that the last character makes ++ // it out before we switch to rx mode. ++ for(i = 0; i < 24; i++) { ++ ToSendStuffBit(1); ++ } ++ ++ // Convert from last character reference to length ++ ToSendMax++; } //----------------------------------------------------------------------------- @@@ -862,23 -849,9 +877,23 @@@ //----------------------------------------------------------------------------- void AcquireRawAdcSamplesIso14443(uint32_t parameter) { -- uint8_t cmd1[] = { 0x05, 0x00, 0x08, 0x39, 0x73 }; ++ uint8_t cmd1[] = { 0x05, 0x00, 0x08, 0x39, 0x73 }; -- SendRawCommand14443B(sizeof(cmd1),1,1,cmd1); ++ SendRawCommand14443B(sizeof(cmd1),1,1,cmd1); +} + +/** + Convenience function to encode, transmit and trace iso 14443b comms + **/ +static void CodeAndTransmit14443bAsReader(const uint8_t *cmd, int len) +{ + CodeIso14443bAsReader(cmd, len); + TransmitFor14443(); + if (tracing) { + uint8_t parity[MAX_PARITY_SIZE]; + GetParity(cmd, len, parity); + LogTrace(cmd,len, 0, 0, parity, TRUE); + } } //----------------------------------------------------------------------------- @@@ -892,129 -865,126 +907,129 @@@ //----------------------------------------------------------------------------- void ReadSTMemoryIso14443(uint32_t dwLast) { - uint8_t i = 0x00; - - FpgaDownloadAndGo(FPGA_BITSTREAM_HF); - // 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); - 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); - - // First command: wake up the tag using the INITIATE command - uint8_t cmd1[] = { 0x06, 0x00, 0x97, 0x5b}; - CodeIso14443bAsReader(cmd1, sizeof(cmd1)); - TransmitFor14443(); + clear_trace(); + set_tracing(TRUE); + - uint8_t i = 0x00; ++ uint8_t i = 0x00; + - FpgaDownloadAndGo(FPGA_BITSTREAM_HF); - // 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); - SpinDelay(200); ++ FpgaDownloadAndGo(FPGA_BITSTREAM_HF); ++ // 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); ++ SpinDelay(200); + - SetAdcMuxFor(GPIO_MUXSEL_HIPKD); - FpgaSetupSsc(); ++ 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); ++ // 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); + - // First command: wake up the tag using the INITIATE command - uint8_t cmd1[] = { 0x06, 0x00, 0x97, 0x5b}; ++ // First command: wake up the tag using the INITIATE command ++ uint8_t cmd1[] = { 0x06, 0x00, 0x97, 0x5b}; + + CodeAndTransmit14443bAsReader(cmd1, sizeof(cmd1)); // LED_A_ON(); -- GetSamplesFor14443Demod(TRUE, 2000,TRUE); ++ GetSamplesFor14443Demod(TRUE, 2000,TRUE); // LED_A_OFF(); -- if (Demod.len == 0) { ++ if (Demod.len == 0) { DbpString("No response from tag"); return; -- } else { ++ } else { Dbprintf("Randomly generated UID from tag (+ 2 byte CRC): %x %x %x", Demod.output[0], Demod.output[1],Demod.output[2]); -- } -- // There is a response, SELECT the uid -- DbpString("Now SELECT tag:"); -- cmd1[0] = 0x0E; // 0x0E is SELECT -- cmd1[1] = Demod.output[0]; -- ComputeCrc14443(CRC_14443_B, cmd1, 2, &cmd1[2], &cmd1[3]); - CodeIso14443bAsReader(cmd1, sizeof(cmd1)); - TransmitFor14443(); ++ } ++ // There is a response, SELECT the uid ++ DbpString("Now SELECT tag:"); ++ cmd1[0] = 0x0E; // 0x0E is SELECT ++ cmd1[1] = Demod.output[0]; ++ ComputeCrc14443(CRC_14443_B, cmd1, 2, &cmd1[2], &cmd1[3]); + CodeAndTransmit14443bAsReader(cmd1, sizeof(cmd1)); + // LED_A_ON(); -- GetSamplesFor14443Demod(TRUE, 2000,TRUE); ++ GetSamplesFor14443Demod(TRUE, 2000,TRUE); // LED_A_OFF(); -- if (Demod.len != 3) { ++ if (Demod.len != 3) { Dbprintf("Expected 3 bytes from tag, got %d", Demod.len); return; -- } -- // Check the CRC of the answer: -- ComputeCrc14443(CRC_14443_B, Demod.output, 1 , &cmd1[2], &cmd1[3]); -- if(cmd1[2] != Demod.output[1] || cmd1[3] != Demod.output[2]) { ++ } ++ // Check the CRC of the answer: ++ ComputeCrc14443(CRC_14443_B, Demod.output, 1 , &cmd1[2], &cmd1[3]); ++ if(cmd1[2] != Demod.output[1] || cmd1[3] != Demod.output[2]) { DbpString("CRC Error reading select response."); return; -- } -- // Check response from the tag: should be the same UID as the command we just sent: -- if (cmd1[1] != Demod.output[0]) { ++ } ++ // Check response from the tag: should be the same UID as the command we just sent: ++ if (cmd1[1] != Demod.output[0]) { Dbprintf("Bad response to SELECT from Tag, aborting: %x %x", cmd1[1], Demod.output[0]); return; -- } -- // Tag is now selected, -- // First get the tag's UID: -- cmd1[0] = 0x0B; -- ComputeCrc14443(CRC_14443_B, cmd1, 1 , &cmd1[1], &cmd1[2]); - CodeIso14443bAsReader(cmd1, 3); // Only first three bytes for this one - TransmitFor14443(); ++ } ++ // Tag is now selected, ++ // First get the tag's UID: ++ cmd1[0] = 0x0B; ++ ComputeCrc14443(CRC_14443_B, cmd1, 1 , &cmd1[1], &cmd1[2]); + CodeAndTransmit14443bAsReader(cmd1, 3); // Only first three bytes for this one + // LED_A_ON(); -- GetSamplesFor14443Demod(TRUE, 2000,TRUE); ++ GetSamplesFor14443Demod(TRUE, 2000,TRUE); // LED_A_OFF(); -- if (Demod.len != 10) { ++ if (Demod.len != 10) { Dbprintf("Expected 10 bytes from tag, got %d", Demod.len); return; -- } -- // The check the CRC of the answer (use cmd1 as temporary variable): -- ComputeCrc14443(CRC_14443_B, Demod.output, 8, &cmd1[2], &cmd1[3]); -- if(cmd1[2] != Demod.output[8] || cmd1[3] != Demod.output[9]) { ++ } ++ // The check the CRC of the answer (use cmd1 as temporary variable): ++ ComputeCrc14443(CRC_14443_B, Demod.output, 8, &cmd1[2], &cmd1[3]); ++ if(cmd1[2] != Demod.output[8] || cmd1[3] != Demod.output[9]) { Dbprintf("CRC Error reading block! - Below: expected, got %x %x", (cmd1[2]<<8)+cmd1[3], (Demod.output[8]<<8)+Demod.output[9]); // Do not return;, let's go on... (we should retry, maybe ?) -- } -- Dbprintf("Tag UID (64 bits): %08x %08x", ++ } ++ Dbprintf("Tag UID (64 bits): %08x %08x", (Demod.output[7]<<24) + (Demod.output[6]<<16) + (Demod.output[5]<<8) + Demod.output[4], (Demod.output[3]<<24) + (Demod.output[2]<<16) + (Demod.output[1]<<8) + Demod.output[0]); -- // Now loop to read all 16 blocks, address from 0 to last block -- Dbprintf("Tag memory dump, block 0 to %d",dwLast); -- cmd1[0] = 0x08; -- i = 0x00; -- dwLast++; -- for (;;) { -- if (i == dwLast) { -- DbpString("System area block (0xff):"); -- i = 0xff; -- } -- cmd1[1] = i; -- ComputeCrc14443(CRC_14443_B, cmd1, 2, &cmd1[2], &cmd1[3]); - CodeIso14443bAsReader(cmd1, sizeof(cmd1)); - TransmitFor14443(); ++ // Now loop to read all 16 blocks, address from 0 to last block ++ Dbprintf("Tag memory dump, block 0 to %d",dwLast); ++ cmd1[0] = 0x08; ++ i = 0x00; ++ dwLast++; ++ for (;;) { ++ if (i == dwLast) { ++ DbpString("System area block (0xff):"); ++ i = 0xff; ++ } ++ cmd1[1] = i; ++ ComputeCrc14443(CRC_14443_B, cmd1, 2, &cmd1[2], &cmd1[3]); + CodeAndTransmit14443bAsReader(cmd1, sizeof(cmd1)); + // LED_A_ON(); -- GetSamplesFor14443Demod(TRUE, 2000,TRUE); ++ GetSamplesFor14443Demod(TRUE, 2000,TRUE); // LED_A_OFF(); -- if (Demod.len != 6) { // Check if we got an answer from the tag ++ if (Demod.len != 6) { // Check if we got an answer from the tag DbpString("Expected 6 bytes from tag, got less..."); return; -- } -- // The check the CRC of the answer (use cmd1 as temporary variable): -- ComputeCrc14443(CRC_14443_B, Demod.output, 4, &cmd1[2], &cmd1[3]); -- if(cmd1[2] != Demod.output[4] || cmd1[3] != Demod.output[5]) { ++ } ++ // The check the CRC of the answer (use cmd1 as temporary variable): ++ ComputeCrc14443(CRC_14443_B, Demod.output, 4, &cmd1[2], &cmd1[3]); ++ if(cmd1[2] != Demod.output[4] || cmd1[3] != Demod.output[5]) { Dbprintf("CRC Error reading block! - Below: expected, got %x %x", (cmd1[2]<<8)+cmd1[3], (Demod.output[4]<<8)+Demod.output[5]); // Do not return;, let's go on... (we should retry, maybe ?) -- } -- // Now print out the memory location: -- Dbprintf("Address=%x, Contents=%x, CRC=%x", i, ++ } ++ // Now print out the memory location: ++ Dbprintf("Address=%x, Contents=%x, CRC=%x", i, (Demod.output[3]<<24) + (Demod.output[2]<<16) + (Demod.output[1]<<8) + Demod.output[0], (Demod.output[4]<<8)+Demod.output[5]); -- if (i == 0xff) { ++ if (i == 0xff) { break; -- } -- i++; -- } ++ } ++ i++; ++ } } @@@ -1037,136 -1007,171 +1052,137 @@@ */ void RAMFUNC SnoopIso14443(void) { -- // We won't start recording the frames that we acquire until we trigger; -- // a good trigger condition to get started is probably when we see a -- // response from the tag. -- int triggered = TRUE; ++ // We won't start recording the frames that we acquire until we trigger; ++ // a good trigger condition to get started is probably when we see a ++ // response from the tag. ++ int triggered = TRUE; -- FpgaDownloadAndGo(FPGA_BITSTREAM_HF); ++ FpgaDownloadAndGo(FPGA_BITSTREAM_HF); + BigBuf_free(); - // The command (reader -> tag) that we're working on receiving. - uint8_t *receivedCmd = BigBuf_malloc(READER_TAG_BUFFER_SIZE); - // The response (tag -> reader) that we're working on receiving. - uint8_t *receivedResponse = BigBuf_malloc(TAG_READER_BUFFER_SIZE); - - // As we receive stuff, we copy it from receivedCmd or receivedResponse - // into trace, along with its length and other annotations. - uint8_t *trace = BigBuf_get_addr(); - traceLen = 0; - - // The DMA buffer, used to stream samples from the FPGA. - uint8_t *dmaBuf = BigBuf_malloc(DEMOD_DMA_BUFFER_SIZE); - int lastRxCounter; - uint8_t *upTo; - int ci, cq; - int maxBehindBy = 0; - - // Count of samples received so far, so that we can include timing - // information in the trace buffer. - int samples = 0; - - // Initialize the trace buffer - memset(trace, 0x44, BigBuf_max_traceLen()); - - // Set up the demodulator for tag -> reader responses. - Demod.output = receivedResponse; - Demod.len = 0; - Demod.state = DEMOD_UNSYNCD; - - // And the reader -> tag commands - memset(&Uart, 0, sizeof(Uart)); - Uart.output = receivedCmd; - Uart.byteCntMax = 100; - Uart.state = STATE_UNSYNCD; - - // Print some debug information about the buffer sizes - Dbprintf("Snooping buffers initialized:"); - Dbprintf(" Trace: %i bytes", BigBuf_max_traceLen()); - Dbprintf(" Reader -> tag: %i bytes", READER_TAG_BUFFER_SIZE); - Dbprintf(" tag -> Reader: %i bytes", TAG_READER_BUFFER_SIZE); - Dbprintf(" DMA: %i bytes", DEMOD_DMA_BUFFER_SIZE); - - // 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); - SetAdcMuxFor(GPIO_MUXSEL_HIPKD); - - // Setup for the DMA. - FpgaSetupSsc(); - upTo = dmaBuf; - lastRxCounter = DEMOD_DMA_BUFFER_SIZE; - FpgaSetupSscDma((uint8_t *)dmaBuf, DEMOD_DMA_BUFFER_SIZE); - - LED_A_ON(); - - // And now we loop, receiving samples. - for(;;) { - int behindBy = (lastRxCounter - AT91C_BASE_PDC_SSC->PDC_RCR) & - (DEMOD_DMA_BUFFER_SIZE-1); - if(behindBy > maxBehindBy) { - maxBehindBy = behindBy; - if(behindBy > (9*DEMOD_DMA_BUFFER_SIZE/10)) { // TODO: understand whether we can increase/decrease as we want or not? - Dbprintf("blew circular buffer! behindBy=0x%x", behindBy); - goto done; - } - } - if(behindBy < 2) continue; - - ci = upTo[0]; - cq = upTo[1]; - upTo += 2; - lastRxCounter -= 2; - if(upTo - dmaBuf > DEMOD_DMA_BUFFER_SIZE) { - upTo -= DEMOD_DMA_BUFFER_SIZE; - lastRxCounter += DEMOD_DMA_BUFFER_SIZE; - AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) upTo; - AT91C_BASE_PDC_SSC->PDC_RNCR = DEMOD_DMA_BUFFER_SIZE; - } - - samples += 2; - -#define HANDLE_BIT_IF_BODY \ - if(triggered) { \ - trace[traceLen++] = ((samples >> 0) & 0xff); \ - trace[traceLen++] = ((samples >> 8) & 0xff); \ - trace[traceLen++] = ((samples >> 16) & 0xff); \ - trace[traceLen++] = ((samples >> 24) & 0xff); \ - trace[traceLen++] = 0; \ - trace[traceLen++] = 0; \ - trace[traceLen++] = 0; \ - trace[traceLen++] = 0; \ - trace[traceLen++] = Uart.byteCnt; \ - memcpy(trace+traceLen, receivedCmd, Uart.byteCnt); \ - traceLen += Uart.byteCnt; \ - if(traceLen > 1000) break; \ - } \ - /* And ready to receive another command. */ \ - memset(&Uart, 0, sizeof(Uart)); \ - Uart.output = receivedCmd; \ - Uart.byteCntMax = 100; \ - Uart.state = STATE_UNSYNCD; \ - /* And also reset the demod code, which might have been */ \ - /* false-triggered by the commands from the reader. */ \ - memset(&Demod, 0, sizeof(Demod)); \ - Demod.output = receivedResponse; \ - Demod.state = DEMOD_UNSYNCD; \ - - if(Handle14443UartBit(ci & 1)) { - HANDLE_BIT_IF_BODY - } - if(Handle14443UartBit(cq & 1)) { - HANDLE_BIT_IF_BODY - } - - if(Handle14443SamplesDemod(ci, cq)) { - // timestamp, as a count of samples - trace[traceLen++] = ((samples >> 0) & 0xff); - trace[traceLen++] = ((samples >> 8) & 0xff); - trace[traceLen++] = ((samples >> 16) & 0xff); - trace[traceLen++] = 0x80 | ((samples >> 24) & 0xff); - // correlation metric (~signal strength estimate) - if(Demod.metricN != 0) { - Demod.metric /= Demod.metricN; - } - trace[traceLen++] = ((Demod.metric >> 0) & 0xff); - trace[traceLen++] = ((Demod.metric >> 8) & 0xff); - trace[traceLen++] = ((Demod.metric >> 16) & 0xff); - trace[traceLen++] = ((Demod.metric >> 24) & 0xff); - // length - trace[traceLen++] = Demod.len; - memcpy(trace+traceLen, receivedResponse, Demod.len); - traceLen += Demod.len; - if(traceLen > BigBuf_max_traceLen()) { - DbpString("Reached trace limit"); - goto done; - } - triggered = TRUE; - LED_A_OFF(); - LED_B_ON(); + clear_trace(); + set_tracing(TRUE); + - // The DMA buffer, used to stream samples from the FPGA. - int8_t *dmaBuf = ((int8_t *)BigBuf) + DMA_BUFFER_OFFSET; - int lastRxCounter; - int8_t *upTo; - int ci, cq; - int maxBehindBy = 0; - - // Count of samples received so far, so that we can include timing - // information in the trace buffer. - int samples = 0; - - DemodReset(); - UartReset(); - - // Print some debug information about the buffer sizes - Dbprintf("Snooping buffers initialized:"); - Dbprintf(" Trace: %i bytes", TRACE_SIZE); ++ // The DMA buffer, used to stream samples from the FPGA ++ uint8_t *dmaBuf = BigBuf_malloc(DMA_BUFFER_SIZE); ++ int lastRxCounter; ++ uint8_t *upTo; ++ int ci, cq; ++ int maxBehindBy = 0; ++ ++ // Count of samples received so far, so that we can include timing ++ // information in the trace buffer. ++ int samples = 0; + - // And ready to receive another response. - memset(&Demod, 0, sizeof(Demod)); - Demod.output = receivedResponse; - Demod.state = DEMOD_UNSYNCD; - } - WDT_HIT(); ++ DemodInit(BigBuf_malloc(MAX_FRAME_SIZE)); ++ UartInit(BigBuf_malloc(MAX_FRAME_SIZE)); + - if(BUTTON_PRESS()) { - DbpString("cancelled"); - goto done; - } - } ++ // Print some debug information about the buffer sizes ++ Dbprintf("Snooping buffers initialized:"); ++ Dbprintf(" Trace: %i bytes", BigBuf_max_traceLen()); + Dbprintf(" Reader -> tag: %i bytes", MAX_FRAME_SIZE); + Dbprintf(" tag -> Reader: %i bytes", MAX_FRAME_SIZE); + Dbprintf(" DMA: %i bytes", DMA_BUFFER_SIZE); -done: + // Signal field is off with the appropriate LED + 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 | - FPGA_HF_READER_RX_XCORR_SNOOP); - SetAdcMuxFor(GPIO_MUXSEL_HIPKD); - - // Setup for the DMA. - FpgaSetupSsc(); - upTo = dmaBuf; ++ FpgaWriteConfWord( ++ FPGA_MAJOR_MODE_HF_READER_RX_XCORR | FPGA_HF_READER_RX_XCORR_848_KHZ | ++ FPGA_HF_READER_RX_XCORR_SNOOP); ++ SetAdcMuxFor(GPIO_MUXSEL_HIPKD); ++ ++ // Setup for the DMA. ++ FpgaSetupSsc(); ++ upTo = dmaBuf; + lastRxCounter = DMA_BUFFER_SIZE; + FpgaSetupSscDma((uint8_t *)dmaBuf, DMA_BUFFER_SIZE); + uint8_t parity[MAX_PARITY_SIZE]; - LED_A_ON(); ++ LED_A_ON(); + - // And now we loop, receiving samples. - for(;;) { - int behindBy = (lastRxCounter - AT91C_BASE_PDC_SSC->PDC_RCR) & ++ // And now we loop, receiving samples. ++ for(;;) { ++ int behindBy = (lastRxCounter - AT91C_BASE_PDC_SSC->PDC_RCR) & + (DMA_BUFFER_SIZE-1); - if(behindBy > maxBehindBy) { - maxBehindBy = behindBy; - if(behindBy > (DMA_BUFFER_SIZE-2)) { // TODO: understand whether we can increase/decrease as we want or not? - Dbprintf("blew circular buffer! behindBy=0x%x", behindBy); ++ if(behindBy > maxBehindBy) { ++ maxBehindBy = behindBy; ++ if(behindBy > (9*DMA_BUFFER_SIZE/10)) { // TODO: understand whether we can increase/decrease as we want or not? ++ Dbprintf("blew circular buffer! behindBy=0x%x", behindBy); + break; - } - } - if(behindBy < 2) continue; - - ci = upTo[0]; - cq = upTo[1]; - upTo += 2; - lastRxCounter -= 2; ++ } ++ } ++ if(behindBy < 2) continue; ++ ++ ci = upTo[0]; ++ cq = upTo[1]; ++ upTo += 2; ++ lastRxCounter -= 2; + if(upTo - dmaBuf > DMA_BUFFER_SIZE) { + upTo -= DMA_BUFFER_SIZE; + lastRxCounter += DMA_BUFFER_SIZE; - AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) upTo; ++ AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) upTo; + AT91C_BASE_PDC_SSC->PDC_RNCR = DMA_BUFFER_SIZE; - } ++ } + - samples += 2; ++ samples += 2; + + if(Handle14443UartBit(ci & 1)) { + if(triggered && tracing) { + GetParity(Uart.output, Uart.byteCnt, parity); + LogTrace(Uart.output,Uart.byteCnt,samples, samples,parity,TRUE); + } + if(Uart.byteCnt==0) Dbprintf("[1] Error, Uart.byteCnt==0, Uart.bitCnt=%d", Uart.bitCnt); + + /* And ready to receive another command. */ + UartReset(); + /* And also reset the demod code, which might have been */ + /* false-triggered by the commands from the reader. */ + DemodReset(); + } - if(Handle14443UartBit(cq & 1)) { ++ if(Handle14443UartBit(cq & 1)) { + if(triggered && tracing) { + GetParity(Uart.output, Uart.byteCnt, parity); + LogTrace(Uart.output,Uart.byteCnt,samples, samples,parity,TRUE); + } + if(Uart.byteCnt==0) Dbprintf("[2] Error, Uart.byteCnt==0, Uart.bitCnt=%d", Uart.bitCnt); + + /* And ready to receive another command. */ + UartReset(); + /* And also reset the demod code, which might have been */ + /* false-triggered by the commands from the reader. */ + DemodReset(); + } + - if(Handle14443SamplesDemod(ci, cq)) { ++ if(Handle14443SamplesDemod(ci, cq)) { + + //Use samples as a time measurement + if(tracing) + { + uint8_t parity[MAX_PARITY_SIZE]; + GetParity(Demod.output, Demod.len, parity); + LogTrace(Demod.output,Demod.len,samples, samples,parity,FALSE); + } - triggered = TRUE; - LED_A_OFF(); - LED_B_ON(); ++ triggered = TRUE; ++ LED_A_OFF(); ++ LED_B_ON(); + - // And ready to receive another response. ++ // And ready to receive another response. + DemodReset(); - } ++ } + WDT_HIT(); + + if(!tracing) { + DbpString("Reached trace limit"); + break; + } + - if(BUTTON_PRESS()) { - DbpString("cancelled"); ++ if(BUTTON_PRESS()) { ++ DbpString("cancelled"); + break; - } - } ++ } ++ } + FpgaDisableSscDma(); LED_A_OFF(); LED_B_OFF(); LED_C_OFF(); @@@ -1194,41 -1199,41 +1210,41 @@@ void SendRawCommand14443B(uint32_t datalen, uint32_t recv,uint8_t powerfield, uint8_t data[]) { -- FpgaDownloadAndGo(FPGA_BITSTREAM_HF); -- if(!powerfield) -- { -- // Make sure that we start from off, since the tags are stateful; -- // confusing things will happen if we don't reset them between reads. -- FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); -- LED_D_OFF(); -- SpinDelay(200); -- } -- -- if(!GETBIT(GPIO_LED_D)) -- { -- 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(data, datalen); - TransmitFor14443(); - if(recv) - { - uint16_t iLen = MIN(Demod.len,USB_CMD_DATA_SIZE); - GetSamplesFor14443Demod(TRUE, 2000, TRUE); - cmd_send(CMD_ACK,iLen,0,0,Demod.output,iLen); - } - if(!powerfield) - { - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - LED_D_OFF(); -- } ++ FpgaDownloadAndGo(FPGA_BITSTREAM_HF); ++ if(!powerfield) ++ { ++ // Make sure that we start from off, since the tags are stateful; ++ // confusing things will happen if we don't reset them between reads. ++ FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); ++ LED_D_OFF(); ++ SpinDelay(200); ++ } ++ ++ if(!GETBIT(GPIO_LED_D)) ++ { ++ 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); ++ } + + CodeAndTransmit14443bAsReader(data, datalen); + - if(recv) - { - uint16_t iLen = MIN(Demod.len,USB_CMD_DATA_SIZE); - GetSamplesFor14443Demod(TRUE, 2000, TRUE); - cmd_send(CMD_ACK,iLen,0,0,Demod.output,iLen); - } - if(!powerfield) - { - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - LED_D_OFF(); - } ++ if(recv) ++ { ++ uint16_t iLen = MIN(Demod.len,USB_CMD_DATA_SIZE); ++ GetSamplesFor14443Demod(TRUE, 2000, TRUE); ++ cmd_send(CMD_ACK,iLen,0,0,Demod.output,iLen); ++ } ++ if(!powerfield) ++ { ++ FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); ++ LED_D_OFF(); ++ } } diff --cc armsrc/iso14443a.c index 54c1db40,b73495a3..336250ed --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@@ -145,7 -146,17 +145,8 @@@ void iso14a_set_trigger(bool enable) trigger = enable; } -void iso14a_clear_trace() { - uint8_t *trace = BigBuf_get_addr(); - uint16_t max_traceLen = BigBuf_max_traceLen(); - memset(trace, 0x44, max_traceLen); - traceLen = 0; -} -void iso14a_set_tracing(bool enable) { - tracing = enable; -} + void iso14a_set_timeout(uint32_t timeout) { iso14a_timeout = timeout; } @@@ -188,7 -199,63 +189,6 @@@ void AppendCrc14443a(uint8_t* data, in ComputeCrc14443(CRC_14443_A,data,len,data+len,data+len+1); } -// The function LogTrace() is also used by the iClass implementation in iClass.c -bool RAMFUNC LogTrace(const uint8_t *btBytes, uint16_t iLen, uint32_t timestamp_start, uint32_t timestamp_end, uint8_t *parity, bool readerToTag) -{ - if (!tracing) return FALSE; - - uint8_t *trace = BigBuf_get_addr(); - uint16_t num_paritybytes = (iLen-1)/8 + 1; // number of valid paritybytes in *parity - uint16_t duration = timestamp_end - timestamp_start; - - // Return when trace is full - uint16_t max_traceLen = BigBuf_max_traceLen(); - if (traceLen + sizeof(iLen) + sizeof(timestamp_start) + sizeof(duration) + num_paritybytes + iLen >= max_traceLen) { - tracing = FALSE; // don't trace any more - return FALSE; - } - - // Traceformat: - // 32 bits timestamp (little endian) - // 16 bits duration (little endian) - // 16 bits data length (little endian, Highest Bit used as readerToTag flag) - // y Bytes data - // x Bytes parity (one byte per 8 bytes data) - - // timestamp (start) - trace[traceLen++] = ((timestamp_start >> 0) & 0xff); - trace[traceLen++] = ((timestamp_start >> 8) & 0xff); - trace[traceLen++] = ((timestamp_start >> 16) & 0xff); - trace[traceLen++] = ((timestamp_start >> 24) & 0xff); - - // duration - trace[traceLen++] = ((duration >> 0) & 0xff); - trace[traceLen++] = ((duration >> 8) & 0xff); - - // data length - trace[traceLen++] = ((iLen >> 0) & 0xff); - trace[traceLen++] = ((iLen >> 8) & 0xff); - - // readerToTag flag - if (!readerToTag) { - trace[traceLen - 1] |= 0x80; - } - - // data bytes - if (btBytes != NULL && iLen != 0) { - memcpy(trace + traceLen, btBytes, iLen); - } - traceLen += iLen; - - // parity bytes - if (parity != NULL && iLen != 0) { - memcpy(trace + traceLen, parity, num_paritybytes); - } - traceLen += num_paritybytes; - - return TRUE; -} -- //============================================================================= // ISO 14443 Type A - Miller decoder //============================================================================= diff --cc armsrc/util.c index 38f41750,674f1b91..4948fce8 --- a/armsrc/util.c +++ b/armsrc/util.c @@@ -12,10 -12,7 +12,9 @@@ #include "util.h" #include "string.h" #include "apps.h" ++#include "BigBuf.h" - uint8_t *trace = (uint8_t *) BigBuf+TRACE_OFFSET; - int traceLen = 0; +int tracing = TRUE; void print_result(char *name, uint8_t *buf, size_t len) { @@@ -430,85 -427,5 +429,91 @@@ uint32_t RAMFUNC GetCountSspClk() return tmp_count; } } +void iso14a_clear_trace() { + clear_trace(); +} + +void iso14a_set_tracing(bool enable) { + set_tracing(enable); +} + +void clear_trace() { - memset(trace, 0x44, TRACE_SIZE); ++ uint8_t *trace = BigBuf_get_addr(); ++ uint16_t max_traceLen = BigBuf_max_traceLen(); ++ memset(trace, 0x44, max_traceLen); + traceLen = 0; +} + +void set_tracing(bool enable) { + tracing = enable; +} + +/** + This is a function to store traces. All protocols can use this generic tracer-function. + The traces produced by calling this function can be fetched on the client-side + by 'hf list raw', alternatively 'hf list ' for protocol-specific + annotation of commands/responses. + +**/ +bool RAMFUNC LogTrace(const uint8_t *btBytes, uint16_t iLen, uint32_t timestamp_start, uint32_t timestamp_end, uint8_t *parity, bool readerToTag) +{ + if (!tracing) return FALSE; + ++ uint8_t *trace = BigBuf_get_addr(); ++ + uint16_t num_paritybytes = (iLen-1)/8 + 1; // number of valid paritybytes in *parity + uint16_t duration = timestamp_end - timestamp_start; + // Return when trace is full - if (traceLen + sizeof(iLen) + sizeof(timestamp_start) + sizeof(duration) + num_paritybytes + iLen >= TRACE_SIZE) { ++ uint16_t max_traceLen = BigBuf_max_traceLen(); ++ ++ if (traceLen + sizeof(iLen) + sizeof(timestamp_start) + sizeof(duration) + num_paritybytes + iLen >= max_traceLen) { + tracing = FALSE; // don't trace any more + return FALSE; + } + // Traceformat: + // 32 bits timestamp (little endian) + // 16 bits duration (little endian) + // 16 bits data length (little endian, Highest Bit used as readerToTag flag) + // y Bytes data + // x Bytes parity (one byte per 8 bytes data) + + // timestamp (start) + trace[traceLen++] = ((timestamp_start >> 0) & 0xff); + trace[traceLen++] = ((timestamp_start >> 8) & 0xff); + trace[traceLen++] = ((timestamp_start >> 16) & 0xff); + trace[traceLen++] = ((timestamp_start >> 24) & 0xff); + + // duration + trace[traceLen++] = ((duration >> 0) & 0xff); + trace[traceLen++] = ((duration >> 8) & 0xff); + + // data length + trace[traceLen++] = ((iLen >> 0) & 0xff); + trace[traceLen++] = ((iLen >> 8) & 0xff); + + // readerToTag flag + if (!readerToTag) { + trace[traceLen - 1] |= 0x80; + } + + // data bytes + if (btBytes != NULL && iLen != 0) { + memcpy(trace + traceLen, btBytes, iLen); + } + traceLen += iLen; + + // parity bytes + if (parity != NULL && iLen != 0) { + memcpy(trace + traceLen, parity, num_paritybytes); + } + traceLen += num_paritybytes; + - if(traceLen +4 < TRACE_SIZE) ++ if(traceLen +4 < max_traceLen) + { //If it hadn't been cleared, for whatever reason.. + memset(trace+traceLen,0x44, 4); + } + + return TRUE; +} diff --cc client/cmdhf.c index 0f31da4d,a55c41b2..07a4aa49 --- a/client/cmdhf.c +++ b/client/cmdhf.c @@@ -449,9 -409,10 +448,9 @@@ uint16_t printTraceLine(uint16_t tracep } parity_len = (data_len-1)/8 + 1; - if (tracepos + data_len + parity_len >= TRACE_SIZE) { - return TRACE_SIZE; + if (tracepos + data_len + parity_len > traceLen) { + return traceLen; } - uint8_t *frame = trace + tracepos; tracepos += data_len; uint8_t *parityBytes = trace + tracepos; diff --cc client/cmdhf14b.c index 3aaf45fa,cf865875..525ffcc6 --- a/client/cmdhf14b.c +++ b/client/cmdhf14b.c @@@ -145,9 -145,97 +145,10 @@@ demodError int CmdHF14BList(const char *Cmd) { - uint8_t *got = malloc(USB_CMD_DATA_SIZE); - - // Query for the actual size of the trace - UsbCommand response; - GetFromBigBuf(got, USB_CMD_DATA_SIZE, 0); - WaitForResponse(CMD_ACK, &response); - uint16_t traceLen = response.arg[2]; - if (traceLen > USB_CMD_DATA_SIZE) { - uint8_t *p = realloc(got, traceLen); - if (p == NULL) { - PrintAndLog("Cannot allocate memory for trace"); - free(got); - return 2; - } - got = p; - GetFromBigBuf(got, traceLen, 0); - WaitForResponse(CMD_ACK,NULL); - } - PrintAndLog("recorded activity: (TraceLen = %d bytes)", traceLen); - PrintAndLog(" time :rssi: who bytes"); - PrintAndLog("---------+----+----+-----------"); - - int i = 0; - int prev = -1; - - for(;;) { - - if(i >= traceLen) { break; } - - bool isResponse; - int timestamp = *((uint32_t *)(got+i)); - if(timestamp & 0x80000000) { - timestamp &= 0x7fffffff; - isResponse = 1; - } else { - isResponse = 0; - } - int metric = *((uint32_t *)(got+i+4)); - - int len = got[i+8]; + PrintAndLog("Deprecated command, use 'hf list 14b' instead"); + - if(len > 100) { - break; - } - if(i + len >= traceLen) { - break; - } - - uint8_t *frame = (got+i+9); - - // Break and stick with current result if buffer was not completely full - if (frame[0] == 0x44 && frame[1] == 0x44 && frame[2] == 0x44 && frame[3] == 0x44) break; - - char line[1000] = ""; - int j; - for(j = 0; j < len; j++) { - sprintf(line+(j*3), "%02x ", frame[j]); - } - - char *crc; - if(len > 2) { - uint8_t b1, b2; - ComputeCrc14443(CRC_14443_B, frame, len-2, &b1, &b2); - if(b1 != frame[len-2] || b2 != frame[len-1]) { - crc = "**FAIL CRC**"; - } else { - crc = ""; - } - } else { - crc = "(SHORT)"; - } - - char metricString[100]; - if(isResponse) { - sprintf(metricString, "%3d", metric); - } else { - strcpy(metricString, " "); - } - - PrintAndLog(" +%7d: %s: %s %s %s", - (prev < 0 ? 0 : timestamp - prev), - metricString, - (isResponse ? "TAG" : " "), line, crc); - - prev = timestamp; - i += (len + 9); - } - free(got); - return 0; + return 0; } - int CmdHF14BRead(const char *Cmd) { UsbCommand c = {CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_14443, {strtol(Cmd, NULL, 0), 0, 0}};