//-----------------------------------------------------------------------------
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;
}
//-----------------------------------------------------------------------------
// 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.
*/
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;
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
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;
++ }
++ }
++ }
++ }
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
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;
++ }
++ }
++ }
}
//=============================================================================
//=============================================================================
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;
/*
*/
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);
+ }
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
/*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;
++ }
++ }
++ }
}*/
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
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
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
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++;
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
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);
+ }
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
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++;
++ }
}
*/
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();
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();
++ }
}