//static void GetSamplesFor14443(int weTx, int n);
-#define DEMOD_TRACE_SIZE 4096
+/*#define DEMOD_TRACE_SIZE 4096
#define READER_TAG_BUFFER_SIZE 2048
#define TAG_READER_BUFFER_SIZE 2048
#define DEMOD_DMA_BUFFER_SIZE 1024
-
+*/
//=============================================================================
// An ISO 14443 Type B tag. We listen for commands from the reader, using
// a UART kind of thing that's implemented in software. When we get a
static int Handle14443UartBit(int bit)
{
switch(Uart.state) {
- case STATE_UNSYNCD:
+ case STATE_UNSYNCD:
LED_A_OFF();
if(!bit) {
// we went low, so this could be the beginning
// 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);
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SIMULATOR | FPGA_HF_SIMULATOR_NO_MODULATION);
// Now run a `software UART' on the stream of incoming samples.
int cmdsRecvd = 0;
+ FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
memset(receivedCmd, 0x44, 400);
CodeIso14443bAsTag(response1, sizeof(response1));
// Modulate BPSK
// Signal field is off with the appropriate LED
LED_D_OFF();
- FpgaWriteConfWord(
- FPGA_MAJOR_MODE_HF_SIMULATOR | FPGA_HF_SIMULATOR_MODULATE_BPSK);
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SIMULATOR | FPGA_HF_SIMULATOR_MODULATE_BPSK);
AT91C_BASE_SSC->SSC_THR = 0xff;
FpgaSetupSsc();
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 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;
+}
+
/*
- * 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
int max = 0;
int gotFrame = FALSE;
-//# define DMA_BUFFER_SIZE 8
- int8_t *dmaBuf;
-
int lastRxCounter;
- int8_t *upTo;
int ci, cq;
int samples = 0;
- // Clear out the state of the "UART" that receives from the tag.
- memset(BigBuf, 0x00, 400);
- Demod.output = (uint8_t *)BigBuf;
- Demod.len = 0;
- Demod.state = DEMOD_UNSYNCD;
-
- // And the UART that receives from the reader
- Uart.output = (((uint8_t *)BigBuf) + 1024);
- Uart.byteCntMax = 100;
- Uart.state = STATE_UNSYNCD;
+ DemodReset();
+ UartReset();
- // Setup for the DMA.
- dmaBuf = (int8_t *)(BigBuf + 32);
- upTo = dmaBuf;
- lastRxCounter = DEMOD_DMA_BUFFER_SIZE;
- FpgaSetupSscDma((uint8_t *)dmaBuf, DEMOD_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;
+ 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();
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))
+ while(((lastRxCounter-AT91C_BASE_PDC_SSC->PDC_RCR) & (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;
+ if(upTo - dmaBuf > DMA_BUFFER_SIZE) {
+ upTo -= DMA_BUFFER_SIZE;
AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) upTo;
- AT91C_BASE_PDC_SSC->PDC_RNCR = DEMOD_DMA_BUFFER_SIZE;
+ AT91C_BASE_PDC_SSC->PDC_RNCR = DMA_BUFFER_SIZE;
}
lastRxCounter -= 2;
if(lastRxCounter <= 0) {
- lastRxCounter += DEMOD_DMA_BUFFER_SIZE;
+ lastRxCounter += DMA_BUFFER_SIZE;
}
samples += 2;
}
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);
+ }
}
//-----------------------------------------------------------------------------
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);
+ }
+}
+
//-----------------------------------------------------------------------------
// Read a SRI512 ISO 14443 tag.
//
//-----------------------------------------------------------------------------
void ReadSTMemoryIso14443(uint32_t dwLast)
{
+ clear_trace();
+ set_tracing(TRUE);
+
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();
// First command: wake up the tag using the INITIATE command
uint8_t cmd1[] = { 0x06, 0x00, 0x97, 0x5b};
- CodeIso14443bAsReader(cmd1, sizeof(cmd1));
- TransmitFor14443();
+
+ CodeAndTransmit14443bAsReader(cmd1, sizeof(cmd1));
// LED_A_ON();
GetSamplesFor14443Demod(TRUE, 2000,TRUE);
// LED_A_OFF();
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();
+ CodeAndTransmit14443bAsReader(cmd1, sizeof(cmd1));
+
// LED_A_ON();
GetSamplesFor14443Demod(TRUE, 2000,TRUE);
// LED_A_OFF();
// 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();
+ CodeAndTransmit14443bAsReader(cmd1, 3); // Only first three bytes for this one
+
// LED_A_ON();
GetSamplesFor14443Demod(TRUE, 2000,TRUE);
// LED_A_OFF();
}
cmd1[1] = i;
ComputeCrc14443(CRC_14443_B, cmd1, 2, &cmd1[2], &cmd1[3]);
- CodeIso14443bAsReader(cmd1, sizeof(cmd1));
- TransmitFor14443();
+ CodeAndTransmit14443bAsReader(cmd1, sizeof(cmd1));
+
// LED_A_ON();
GetSamplesFor14443Demod(TRUE, 2000,TRUE);
// LED_A_OFF();
// response from the tag.
int triggered = TRUE;
- // The command (reader -> tag) that we're working on receiving.
- uint8_t *receivedCmd = (uint8_t *)(BigBuf) + DEMOD_TRACE_SIZE;
- // The response (tag -> reader) that we're working on receiving.
- uint8_t *receivedResponse = (uint8_t *)(BigBuf) + DEMOD_TRACE_SIZE + READER_TAG_BUFFER_SIZE;
+ FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
- // 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;
- int traceLen = 0;
+ clear_trace();
+ set_tracing(TRUE);
// The DMA buffer, used to stream samples from the FPGA.
- int8_t *dmaBuf = (int8_t *)(BigBuf) + DEMOD_TRACE_SIZE + READER_TAG_BUFFER_SIZE + TAG_READER_BUFFER_SIZE;
+ int8_t *dmaBuf = ((int8_t *)BigBuf) + DMA_BUFFER_OFFSET;
int lastRxCounter;
int8_t *upTo;
int ci, cq;
// information in the trace buffer.
int samples = 0;
- // Initialize the trace buffer
- memset(trace, 0x44, DEMOD_TRACE_SIZE);
-
- // 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;
+ DemodReset();
+ UartReset();
// Print some debug information about the buffer sizes
Dbprintf("Snooping buffers initialized:");
- Dbprintf(" Trace: %i bytes", DEMOD_TRACE_SIZE);
- 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);
+ Dbprintf(" Trace: %i bytes", TRACE_SIZE);
+ Dbprintf(" Reader -> tag: %i bytes", MAX_FRAME_SIZE);
+ Dbprintf(" tag -> Reader: %i bytes", MAX_FRAME_SIZE);
+ Dbprintf(" DMA: %i bytes", DMA_BUFFER_SIZE);
- // And put the FPGA in the appropriate mode
- // Signal field is off with the appropriate LED
- LED_D_OFF();
+ // 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);
// Setup for the DMA.
FpgaSetupSsc();
upTo = dmaBuf;
- lastRxCounter = DEMOD_DMA_BUFFER_SIZE;
- FpgaSetupSscDma((uint8_t *)dmaBuf, DEMOD_DMA_BUFFER_SIZE);
-
+ lastRxCounter = DMA_BUFFER_SIZE;
+ FpgaSetupSscDma((uint8_t *)dmaBuf, DMA_BUFFER_SIZE);
+ uint8_t parity[MAX_PARITY_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);
+ (DMA_BUFFER_SIZE-1);
if(behindBy > maxBehindBy) {
maxBehindBy = behindBy;
- if(behindBy > (DEMOD_DMA_BUFFER_SIZE-2)) { // TODO: understand whether we can increase/decrease as we want or not?
+ 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);
- goto done;
+ break;
}
}
if(behindBy < 2) continue;
cq = upTo[1];
upTo += 2;
lastRxCounter -= 2;
- if(upTo - dmaBuf > DEMOD_DMA_BUFFER_SIZE) {
- upTo -= DEMOD_DMA_BUFFER_SIZE;
- lastRxCounter += DEMOD_DMA_BUFFER_SIZE;
+ 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 = DEMOD_DMA_BUFFER_SIZE;
+ AT91C_BASE_PDC_SSC->PDC_RNCR = 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(triggered && tracing) {
+ GetParity(Uart.output, Uart.byteCnt, parity);
+ LogTrace(Uart.output,Uart.byteCnt,samples, samples,parity,TRUE);
+ }
+ /* 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)) {
- HANDLE_BIT_IF_BODY
- }
+ if(triggered && tracing) {
+ GetParity(Uart.output, Uart.byteCnt, parity);
+ LogTrace(Uart.output,Uart.byteCnt,samples, samples,parity,TRUE);
+ }
+ /* 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)) {
- // 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 > DEMOD_TRACE_SIZE) {
- DbpString("Reached trace limit");
- goto done;
- }
+ //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();
// And ready to receive another response.
- memset(&Demod, 0, sizeof(Demod));
- Demod.output = receivedResponse;
- Demod.state = DEMOD_UNSYNCD;
+ DemodReset();
}
- WDT_HIT();
+ WDT_HIT();
+
+ if(!tracing) {
+ DbpString("Reached trace limit");
+ break;
+ }
if(BUTTON_PRESS()) {
DbpString("cancelled");
- goto done;
+ break;
}
}
-
-done:
+ FpgaDisableSscDma();
LED_A_OFF();
LED_B_OFF();
LED_C_OFF();
- AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTDIS;
+ AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTDIS;
DbpString("Snoop statistics:");
- Dbprintf(" Max behind by: %i", maxBehindBy);
+ Dbprintf(" Max behind by: %i", maxBehindBy);
Dbprintf(" Uart State: %x", Uart.state);
Dbprintf(" Uart ByteCnt: %i", Uart.byteCnt);
Dbprintf(" Uart ByteCntMax: %i", Uart.byteCntMax);
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;
SpinDelay(200);
}
- CodeIso14443bAsReader(data, datalen);
- TransmitFor14443();
+ CodeAndTransmit14443bAsReader(data, datalen);
+
if(recv)
{
uint16_t iLen = MIN(Demod.len,USB_CMD_DATA_SIZE);