}
// The function LogTrace() is also used by the iClass implementation in iClass.c
-int LogTrace(const uint8_t * btBytes, int iLen, int iSamples, uint32_t dwParity, int bReader)
+int RAMFUNC LogTrace(const uint8_t * btBytes, int iLen, int iSamples, uint32_t dwParity, int bReader)
{
// Return when trace is full
if (traceLen >= TRACE_SIZE) return FALSE;
// triggering so that we start recording at the point that the tag is moved
// near the reader.
//-----------------------------------------------------------------------------
-void RAMFUNC SnoopIso14443a(void)
-{
-// #define RECV_CMD_OFFSET 2032 // original (working as of 21/2/09) values
-// #define RECV_RES_OFFSET 2096 // original (working as of 21/2/09) values
-// #define DMA_BUFFER_OFFSET 2160 // original (working as of 21/2/09) values
-// #define DMA_BUFFER_SIZE 4096 // original (working as of 21/2/09) values
-// #define TRACE_SIZE 2000 // original (working as of 21/2/09) values
-
- // 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 = FALSE; // FALSE to wait first for card
-
- // The command (reader -> tag) that we're receiving.
+void RAMFUNC SnoopIso14443a(uint8_t param) {
+ // param:
+ // bit 0 - trigger from first card answer
+ // bit 1 - trigger from first reader 7-bit request
+
+ LEDsoff();
+ // init trace buffer
+ traceLen = 0;
+ memset(trace, 0x44, TRACE_SIZE);
+
+ // 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.
+ // triggered == FALSE -- to wait first for card
+ int triggered = !(param & 0x03);
+
+ // The command (reader -> tag) that we're receiving.
// The length of a received command will in most cases be no more than 18 bytes.
// So 32 should be enough!
- uint8_t *receivedCmd = (((uint8_t *)BigBuf) + RECV_CMD_OFFSET);
- // The response (tag -> reader) that we're receiving.
- uint8_t *receivedResponse = (((uint8_t *)BigBuf) + RECV_RES_OFFSET);
-
- // As we receive stuff, we copy it from receivedCmd or receivedResponse
- // into trace, along with its length and other annotations.
- //uint8_t *trace = (uint8_t *)BigBuf;
-
- traceLen = 0; // uncommented to fix ISSUE 15 - gerhard - jan2011
-
- // 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 smpl;
- int maxBehindBy = 0;
-
- // Count of samples received so far, so that we can include timing
- // information in the trace buffer.
- int samples = 0;
- int rsamples = 0;
-
- memset(trace, 0x44, TRACE_SIZE);
-
- // Set up the demodulator for tag -> reader responses.
- Demod.output = receivedResponse;
- Demod.len = 0;
- Demod.state = DEMOD_UNSYNCD;
-
- // Setup for the DMA.
- FpgaSetupSsc();
- upTo = dmaBuf;
- lastRxCounter = DMA_BUFFER_SIZE;
- FpgaSetupSscDma((uint8_t *)dmaBuf, DMA_BUFFER_SIZE);
-
- // And the reader -> tag commands
- memset(&Uart, 0, sizeof(Uart));
- Uart.output = receivedCmd;
- Uart.byteCntMax = 32; // was 100 (greg)////////////////////////////////////////////////////////////////////////
- Uart.state = STATE_UNSYNCD;
+ uint8_t *receivedCmd = (((uint8_t *)BigBuf) + RECV_CMD_OFFSET);
+ // The response (tag -> reader) that we're receiving.
+ uint8_t *receivedResponse = (((uint8_t *)BigBuf) + RECV_RES_OFFSET);
- // And put the FPGA in the appropriate mode
- // Signal field is off with the appropriate LED
- LED_D_OFF();
- FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_SNIFFER);
- SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
+ // As we receive stuff, we copy it from receivedCmd or receivedResponse
+ // into trace, along with its length and other annotations.
+ //uint8_t *trace = (uint8_t *)BigBuf;
+
+ // The DMA buffer, used to stream samples from the FPGA
+ int8_t *dmaBuf = ((int8_t *)BigBuf) + DMA_BUFFER_OFFSET;
+ int8_t *data = dmaBuf;
+ int maxDataLen = 0;
+ int dataLen = 0;
+ // Set up the demodulator for tag -> reader responses.
+ Demod.output = receivedResponse;
+ Demod.len = 0;
+ Demod.state = DEMOD_UNSYNCD;
- // And now we loop, receiving samples.
- for(;;) {
- LED_A_ON();
- WDT_HIT();
- int behindBy = (lastRxCounter - AT91C_BASE_PDC_SSC->PDC_RCR) &
- (DMA_BUFFER_SIZE-1);
- if(behindBy > maxBehindBy) {
- maxBehindBy = behindBy;
- if(behindBy > 400) {
- Dbprintf("blew circular buffer! behindBy=0x%x", behindBy);
- goto done;
- }
- }
- if(behindBy < 1) continue;
+ // Set up the demodulator for the reader -> tag commands
+ memset(&Uart, 0, sizeof(Uart));
+ Uart.output = receivedCmd;
+ Uart.byteCntMax = 32; // was 100 (greg)//////////////////
+ Uart.state = STATE_UNSYNCD;
- LED_A_OFF();
- smpl = upTo[0];
- upTo++;
- lastRxCounter -= 1;
- 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_RNCR = DMA_BUFFER_SIZE;
- }
+ // Setup for the DMA.
+ FpgaSetupSsc();
+ FpgaSetupSscDma((uint8_t *)dmaBuf, DMA_BUFFER_SIZE);
- samples += 4;
- if(MillerDecoding((smpl & 0xF0) >> 4)) {
- rsamples = samples - Uart.samples;
- LED_C_ON();
- if(triggered) {
- trace[traceLen++] = ((rsamples >> 0) & 0xff);
- trace[traceLen++] = ((rsamples >> 8) & 0xff);
- trace[traceLen++] = ((rsamples >> 16) & 0xff);
- trace[traceLen++] = ((rsamples >> 24) & 0xff);
- trace[traceLen++] = ((Uart.parityBits >> 0) & 0xff);
- trace[traceLen++] = ((Uart.parityBits >> 8) & 0xff);
- trace[traceLen++] = ((Uart.parityBits >> 16) & 0xff);
- trace[traceLen++] = ((Uart.parityBits >> 24) & 0xff);
- trace[traceLen++] = Uart.byteCnt;
- memcpy(trace+traceLen, receivedCmd, Uart.byteCnt);
- traceLen += Uart.byteCnt;
- if(traceLen > TRACE_SIZE) break;
- }
- /* And ready to receive another command. */
- Uart.state = STATE_UNSYNCD;
- /* And also reset the demod code, which might have been */
- /* false-triggered by the commands from the reader. */
- Demod.state = DEMOD_UNSYNCD;
- LED_B_OFF();
- }
+ // And put the FPGA in the appropriate mode
+ // Signal field is off with the appropriate LED
+ LED_D_OFF();
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_SNIFFER);
+ SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
- if(ManchesterDecoding(smpl & 0x0F)) {
- rsamples = samples - Demod.samples;
- LED_B_ON();
-
- // timestamp, as a count of samples
- trace[traceLen++] = ((rsamples >> 0) & 0xff);
- trace[traceLen++] = ((rsamples >> 8) & 0xff);
- trace[traceLen++] = ((rsamples >> 16) & 0xff);
- trace[traceLen++] = 0x80 | ((rsamples >> 24) & 0xff);
- trace[traceLen++] = ((Demod.parityBits >> 0) & 0xff);
- trace[traceLen++] = ((Demod.parityBits >> 8) & 0xff);
- trace[traceLen++] = ((Demod.parityBits >> 16) & 0xff);
- trace[traceLen++] = ((Demod.parityBits >> 24) & 0xff);
- // length
- trace[traceLen++] = Demod.len;
- memcpy(trace+traceLen, receivedResponse, Demod.len);
- traceLen += Demod.len;
- if(traceLen > TRACE_SIZE) break;
-
- triggered = TRUE;
-
- // And ready to receive another response.
- memset(&Demod, 0, sizeof(Demod));
- Demod.output = receivedResponse;
- Demod.state = DEMOD_UNSYNCD;
- LED_C_OFF();
- }
+ // Count of samples received so far, so that we can include timing
+ // information in the trace buffer.
+ rsamples = 0;
+ // And now we loop, receiving samples.
+ while(true) {
+ if(BUTTON_PRESS()) {
+ DbpString("cancelled by button");
+ goto done;
+ }
- if(BUTTON_PRESS()) {
- DbpString("cancelled_a");
- goto done;
- }
- }
+ LED_A_ON();
+ WDT_HIT();
- DbpString("COMMAND FINISHED");
+ int register readBufDataP = data - dmaBuf;
+ int register dmaBufDataP = DMA_BUFFER_SIZE - AT91C_BASE_PDC_SSC->PDC_RCR;
+ if (readBufDataP <= dmaBufDataP){
+ dataLen = dmaBufDataP - readBufDataP;
+ } else {
+ dataLen = DMA_BUFFER_SIZE - readBufDataP + dmaBufDataP + 1;
+ }
+ // test for length of buffer
+ if(dataLen > maxDataLen) {
+ maxDataLen = dataLen;
+ if(dataLen > 400) {
+ Dbprintf("blew circular buffer! dataLen=0x%x", dataLen);
+ goto done;
+ }
+ }
+ if(dataLen < 1) continue;
+
+ // primary buffer was stopped( <-- we lost data!
+ if (!AT91C_BASE_PDC_SSC->PDC_RCR) {
+ AT91C_BASE_PDC_SSC->PDC_RPR = (uint32_t) dmaBuf;
+ AT91C_BASE_PDC_SSC->PDC_RCR = DMA_BUFFER_SIZE;
+ Dbprintf("RxEmpty ERROR!!! %d", dataLen); // temporary
+ }
+ // secondary buffer sets as primary, secondary buffer was stopped
+ if (!AT91C_BASE_PDC_SSC->PDC_RNCR) {
+ AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) dmaBuf;
+ AT91C_BASE_PDC_SSC->PDC_RNCR = DMA_BUFFER_SIZE;
+ }
+
+ LED_A_OFF();
+
+ rsamples += 4;
+ if(MillerDecoding((data[0] & 0xF0) >> 4)) {
+ LED_C_ON();
+
+ // check - if there is a short 7bit request from reader
+ if ((!triggered) && (param & 0x02) && (Uart.byteCnt == 1) && (Uart.bitCnt = 9)) triggered = TRUE;
+
+ if(triggered) {
+ if (!LogTrace(receivedCmd, Uart.byteCnt, 0 - Uart.samples, Uart.parityBits, TRUE)) break;
+ }
+ /* And ready to receive another command. */
+ Uart.state = STATE_UNSYNCD;
+ /* And also reset the demod code, which might have been */
+ /* false-triggered by the commands from the reader. */
+ Demod.state = DEMOD_UNSYNCD;
+ LED_B_OFF();
+ }
+
+ if(ManchesterDecoding(data[0] & 0x0F)) {
+ LED_B_ON();
+
+ if (!LogTrace(receivedResponse, Demod.len, 0 - Demod.samples, Demod.parityBits, FALSE)) break;
+
+ if ((!triggered) && (param & 0x01)) triggered = TRUE;
+
+ // And ready to receive another response.
+ memset(&Demod, 0, sizeof(Demod));
+ Demod.output = receivedResponse;
+ Demod.state = DEMOD_UNSYNCD;
+ LED_C_OFF();
+ }
+
+ data++;
+ if(data > dmaBuf + DMA_BUFFER_SIZE) {
+ data = dmaBuf;
+ }
+ } // main cycle
+
+ DbpString("COMMAND FINISHED");
done:
- AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTDIS;
- Dbprintf("maxBehindBy=%x, Uart.state=%x, Uart.byteCnt=%x", maxBehindBy, Uart.state, Uart.byteCnt);
- Dbprintf("Uart.byteCntMax=%x, traceLen=%x, Uart.output[0]=%x", Uart.byteCntMax, traceLen, (int)Uart.output[0]);
- LED_A_OFF();
- LED_B_OFF();
- LED_C_OFF();
- LED_D_OFF();
+ AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTDIS;
+ Dbprintf("maxDataLen=%x, Uart.state=%x, Uart.byteCnt=%x", maxDataLen, Uart.state, Uart.byteCnt);
+ Dbprintf("Uart.byteCntMax=%x, traceLen=%x, Uart.output[0]=%08x", Uart.byteCntMax, traceLen, (int)Uart.output[0]);
+ LEDsoff();
}
//-----------------------------------------------------------------------------
// MIFARE sniffer.
//
//-----------------------------------------------------------------------------
-void RAMFUNC SniffMifare(void) {
+void RAMFUNC SniffMifare(uint8_t param) {
+ // param:
+ // bit 0 - trigger from first card answer
+ // bit 1 - trigger from first reader 7-bit request
+
LEDsoff();
// init trace buffer
traceLen = 0;
memset(trace, 0x44, TRACE_SIZE);
- // 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 = FALSE; // FALSE to wait first for card
-
// The command (reader -> tag) that we're receiving.
// The length of a received command will in most cases be no more than 18 bytes.
// So 32 should be enough!
// 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 smpl;
- int maxBehindBy = 0;
+ int8_t *data = dmaBuf;
+ int maxDataLen = 0;
+ int dataLen = 0;
+// data = dmaBuf;
// Set up the demodulator for tag -> reader responses.
Demod.output = receivedResponse;
// Setup for the DMA.
FpgaSetupSsc();
- upTo = dmaBuf;
- lastRxCounter = DMA_BUFFER_SIZE;
FpgaSetupSscDma((uint8_t *)dmaBuf, DMA_BUFFER_SIZE);
// And put the FPGA in the appropriate mode
rsamples = 0;
// And now we loop, receiving samples.
while(true) {
+ if(BUTTON_PRESS()) {
+ DbpString("cancelled by button");
+ goto done;
+ }
+
LED_A_ON();
WDT_HIT();
- int behindBy = (lastRxCounter - AT91C_BASE_PDC_SSC->PDC_RCR) &
- (DMA_BUFFER_SIZE-1);
- if(behindBy > maxBehindBy) {
- maxBehindBy = behindBy;
- if(behindBy > 400) {
- Dbprintf("blew circular buffer! behindBy=0x%x", behindBy);
+
+ int register readBufDataP = data - dmaBuf;
+ int register dmaBufDataP = DMA_BUFFER_SIZE - AT91C_BASE_PDC_SSC->PDC_RCR;
+ if (readBufDataP <= dmaBufDataP){
+ dataLen = dmaBufDataP - readBufDataP;
+ } else {
+ dataLen = DMA_BUFFER_SIZE - readBufDataP + dmaBufDataP + 1;
+ }
+ // test for length of buffer
+ if(dataLen > maxDataLen) {
+ maxDataLen = dataLen;
+ if(dataLen > 400) {
+ Dbprintf("blew circular buffer! dataLen=0x%x", dataLen);
goto done;
}
}
- if(behindBy < 1) continue;
+ if(dataLen < 1) continue;
- LED_A_OFF();
-
- smpl = upTo[0];
- upTo++;
- lastRxCounter -= 1;
- if(upTo - dmaBuf > DMA_BUFFER_SIZE) {
- upTo -= DMA_BUFFER_SIZE;
- lastRxCounter += DMA_BUFFER_SIZE;
- AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) upTo;
+ // primary buffer was stopped( <-- we lost data!
+ if (!AT91C_BASE_PDC_SSC->PDC_RCR) {
+ AT91C_BASE_PDC_SSC->PDC_RPR = (uint32_t) dmaBuf;
+ AT91C_BASE_PDC_SSC->PDC_RCR = DMA_BUFFER_SIZE;
+ Dbprintf("RxEmpty ERROR!!! %d", dataLen); // temporary
+ }
+ // secondary buffer sets as primary, secondary buffer was stopped
+ if (!AT91C_BASE_PDC_SSC->PDC_RNCR) {
+ AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) dmaBuf;
AT91C_BASE_PDC_SSC->PDC_RNCR = DMA_BUFFER_SIZE;
}
+
+ LED_A_OFF();
rsamples += 4;
- if(MillerDecoding((smpl & 0xF0) >> 4)) {
+ if(MillerDecoding((data[0] & 0xF0) >> 4)) {
LED_C_ON();
- if(triggered) {
- if (!LogTrace(receivedCmd, Uart.byteCnt, -1 * Uart.samples, Uart.parityBits, TRUE)) break;
+ // check - if there is a short 7bit request from reader
+ if ((Uart.byteCnt == 1) && (Uart.bitCnt = 9)) {
+
}
+ if (!LogTrace(receivedCmd, Uart.byteCnt, 0 - Uart.samples, Uart.parityBits, TRUE)) break;
+
/* And ready to receive another command. */
Uart.state = STATE_UNSYNCD;
/* And also reset the demod code, which might have been */
LED_B_OFF();
}
- if(ManchesterDecoding(smpl & 0x0F)) {
+ if(ManchesterDecoding(data[0] & 0x0F)) {
LED_B_ON();
- if (!LogTrace(receivedResponse, Demod.len, -1 * Demod.samples, Demod.parityBits, FALSE)) break;
-
- triggered = TRUE;
+ if (!LogTrace(receivedResponse, Demod.len, 0 - Demod.samples, Demod.parityBits, FALSE)) break;
// And ready to receive another response.
memset(&Demod, 0, sizeof(Demod));
LED_C_OFF();
}
- if(BUTTON_PRESS()) {
- DbpString("button cancelled");
- goto done;
+ data++;
+ if(data > dmaBuf + DMA_BUFFER_SIZE) {
+ data = dmaBuf;
}
} // main cycle
done:
AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTDIS;
- Dbprintf("maxBehindBy=%x, Uart.state=%x, Uart.byteCnt=%x", maxBehindBy, Uart.state, Uart.byteCnt);
+ Dbprintf("maxDataLen=%x, Uart.state=%x, Uart.byteCnt=%x", maxDataLen, Uart.state, Uart.byteCnt);
Dbprintf("Uart.byteCntMax=%x, traceLen=%x, Uart.output[0]=%x", Uart.byteCntMax, traceLen, (int)Uart.output[0]);
LEDsoff();
}
\ No newline at end of file