#define DELAY_READER_TO_ARM 8
#define DELAY_ARM_TO_READER 0
//SSP_CLK runs at 13.56MHz / 4 = 3,39MHz when acting as reader. All values should be multiples of 16
-#define DELAY_TAG_TO_ARM 32
#define DELAY_ARM_TO_TAG 16
+#define DELAY_TAG_TO_ARM 32
+//SSP_CLK runs at 13.56MHz / 4 = 3,39MHz when snooping. All values should be multiples of 16
+#define DELAY_TAG_TO_ARM_SNOOP 32
+#define DELAY_READER_TO_ARM_SNOOP 32
static int DEBUG = 0;
// EOF
ToSend[++ToSendMax] = 0x20; //0010 + 0000 padding
-
+
ToSendMax++;
}
void TransmitTo15693Tag(const uint8_t *cmd, int len, uint32_t *start_time) {
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER | FPGA_HF_READER_MODE_SEND_FULL_MOD);
-
+
+ if (*start_time < DELAY_ARM_TO_TAG) {
+ *start_time = DELAY_ARM_TO_TAG;
+ }
+
*start_time = (*start_time - DELAY_ARM_TO_TAG) & 0xfffffff0;
- while (GetCountSspClk() > *start_time) { // we may miss the intended time
- *start_time += 16; // next possible time
+ if (GetCountSspClk() > *start_time) { // we may miss the intended time
+ *start_time = (GetCountSspClk() + 16) & 0xfffffff0; // next possible time
}
-
while (GetCountSspClk() < *start_time)
/* wait */ ;
WDT_HIT();
}
LED_B_OFF();
-
+
*start_time = *start_time + DELAY_ARM_TO_TAG;
}
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SIMULATOR | FPGA_HF_SIMULATOR_MODULATE_424K);
uint32_t modulation_start_time = *start_time - DELAY_ARM_TO_READER + 3 * 8; // no need to transfer the unmodulated start of SOF
-
+
while (GetCountSspClk() > (modulation_start_time & 0xfffffff8) + 3) { // we will miss the intended time
if (slot_time) {
modulation_start_time += slot_time; // use next available slot
}
}
- while (GetCountSspClk() < (modulation_start_time & 0xfffffff8))
+ while (GetCountSspClk() < (modulation_start_time & 0xfffffff8))
/* wait */ ;
uint8_t shift_delay = modulation_start_time & 0x00000007;
} DecodeTag_t;
-static int inline __attribute__((always_inline)) Handle15693SamplesFromTag(uint16_t amplitude, DecodeTag_t *DecodeTag)
-{
+static int inline __attribute__((always_inline)) Handle15693SamplesFromTag(uint16_t amplitude, DecodeTag_t *DecodeTag) {
switch(DecodeTag->state) {
case STATE_TAG_SOF_LOW:
// waiting for a rising edge
if (amplitude > NOISE_THRESHOLD + DecodeTag->previous_amplitude) {
if (DecodeTag->posCount > 10) {
- DecodeTag->threshold_sof = amplitude - DecodeTag->previous_amplitude;
+ DecodeTag->threshold_sof = amplitude - DecodeTag->previous_amplitude; // to be divided by 2
DecodeTag->threshold_half = 0;
DecodeTag->state = STATE_TAG_SOF_RISING_EDGE;
} else {
break;
case STATE_TAG_SOF_RISING_EDGE:
- if (amplitude - DecodeTag->previous_amplitude > DecodeTag->threshold_sof) { // edge still rising
- if (amplitude - DecodeTag->threshold_sof > DecodeTag->threshold_sof) { // steeper edge, take this as time reference
+ if (amplitude > DecodeTag->threshold_sof + DecodeTag->previous_amplitude) { // edge still rising
+ if (amplitude > DecodeTag->threshold_sof + DecodeTag->threshold_sof) { // steeper edge, take this as time reference
DecodeTag->posCount = 1;
} else {
DecodeTag->posCount = 2;
// DecodeTag->posCount = 2;
DecodeTag->state = STATE_TAG_SOF_HIGH;
break;
-
+
case STATE_TAG_SOF_HIGH:
// waiting for 10 times high. Take average over the last 8
if (amplitude > DecodeTag->threshold_sof) {
}
} else { // high phase was too short
DecodeTag->posCount = 1;
- DecodeTag->previous_amplitude = MAX_PREVIOUS_AMPLITUDE;
+ DecodeTag->previous_amplitude = amplitude;
DecodeTag->state = STATE_TAG_SOF_LOW;
}
break;
DecodeTag->posCount = 2;
DecodeTag->state = STATE_TAG_RECEIVING_DATA;
// FpgaDisableTracing(); // DEBUGGING
- // Dbprintf("amplitude = %d, threshold_sof = %d, threshold_half/4 = %d, previous_amplitude = %d",
- // amplitude,
- // DecodeTag->threshold_sof,
+ // Dbprintf("amplitude = %d, threshold_sof = %d, threshold_half/4 = %d, previous_amplitude = %d",
+ // amplitude,
+ // DecodeTag->threshold_sof,
// DecodeTag->threshold_half/4,
// DecodeTag->previous_amplitude); // DEBUGGING
LED_C_ON();
DecodeTag->posCount++;
if (DecodeTag->posCount > 13) { // high phase too long
DecodeTag->posCount = 0;
- DecodeTag->previous_amplitude = MAX_PREVIOUS_AMPLITUDE;
+ DecodeTag->previous_amplitude = amplitude;
DecodeTag->state = STATE_TAG_SOF_LOW;
LED_C_OFF();
}
break;
case STATE_TAG_RECEIVING_DATA:
+ // FpgaDisableTracing(); // DEBUGGING
+ // Dbprintf("amplitude = %d, threshold_sof = %d, threshold_half/4 = %d, previous_amplitude = %d",
+ // amplitude,
+ // DecodeTag->threshold_sof,
+ // DecodeTag->threshold_half/4,
+ // DecodeTag->previous_amplitude); // DEBUGGING
if (DecodeTag->posCount == 1) {
DecodeTag->sum1 = 0;
DecodeTag->sum2 = 0;
DecodeTag->state = STATE_TAG_EOF;
} else {
DecodeTag->posCount = 0;
- DecodeTag->previous_amplitude = MAX_PREVIOUS_AMPLITUDE;
+ DecodeTag->previous_amplitude = amplitude;
DecodeTag->state = STATE_TAG_SOF_LOW;
LED_C_OFF();
}
// logic 0
if (DecodeTag->lastBit == SOF_PART1) { // incomplete SOF
DecodeTag->posCount = 0;
- DecodeTag->previous_amplitude = MAX_PREVIOUS_AMPLITUDE;
+ DecodeTag->previous_amplitude = amplitude;
DecodeTag->state = STATE_TAG_SOF_LOW;
LED_C_OFF();
} else {
if (DecodeTag->len > DecodeTag->max_len) {
// buffer overflow, give up
DecodeTag->posCount = 0;
- DecodeTag->previous_amplitude = MAX_PREVIOUS_AMPLITUDE;
+ DecodeTag->previous_amplitude = amplitude;
DecodeTag->state = STATE_TAG_SOF_LOW;
LED_C_OFF();
}
DecodeTag->state = STATE_TAG_EOF_TAIL;
} else {
DecodeTag->posCount = 0;
- DecodeTag->previous_amplitude = MAX_PREVIOUS_AMPLITUDE;
+ DecodeTag->previous_amplitude = amplitude;
DecodeTag->state = STATE_TAG_SOF_LOW;
LED_C_OFF();
}
return true;
} else {
DecodeTag->posCount = 0;
- DecodeTag->previous_amplitude = MAX_PREVIOUS_AMPLITUDE;
+ DecodeTag->previous_amplitude = amplitude;
DecodeTag->state = STATE_TAG_SOF_LOW;
LED_C_OFF();
}
}
-static void DecodeTagInit(DecodeTag_t *DecodeTag, uint8_t *data, uint16_t max_len)
-{
+static void DecodeTagInit(DecodeTag_t *DecodeTag, uint8_t *data, uint16_t max_len) {
DecodeTag->previous_amplitude = MAX_PREVIOUS_AMPLITUDE;
DecodeTag->posCount = 0;
DecodeTag->state = STATE_TAG_SOF_LOW;
}
-static void DecodeTagReset(DecodeTag_t *DecodeTag)
-{
+static void DecodeTagReset(DecodeTag_t *DecodeTag) {
DecodeTag->posCount = 0;
DecodeTag->state = STATE_TAG_SOF_LOW;
DecodeTag->previous_amplitude = MAX_PREVIOUS_AMPLITUDE;
samples++;
if (samples == 1) {
- // DMA has transferred the very first data
+ // DMA has transferred the very first data
dma_start_time = GetCountSspClk() & 0xfffffff0;
}
-
+
uint16_t tagdata = *upTo++;
if(upTo >= dmaBuf + ISO15693_DMA_BUFFER_SIZE) { // we have read all of the DMA buffer content.
upTo = dmaBuf; // start reading the circular buffer from the beginning
- if(behindBy > (9*ISO15693_DMA_BUFFER_SIZE/10)) {
+ if (behindBy > (9*ISO15693_DMA_BUFFER_SIZE/10)) {
Dbprintf("About to blow circular buffer - aborted! behindBy=%d", behindBy);
ret = -1;
break;
}
if (samples > timeout && DecodeTag.state < STATE_TAG_RECEIVING_DATA) {
- ret = -1; // timeout
+ ret = -1; // timeout
break;
}
- DecodeTag.len * 8 * 8 * 16 // time for byte transfers
- 32 * 16 // time for SOF transfer
- (DecodeTag.lastBit != SOF_PART2?32*16:0); // time for EOF transfer
-
+
if (DEBUG) Dbprintf("timing: sof_time = %d, eof_time = %d", sof_time, *eof_time);
-
+
LogTrace_ISO15693(DecodeTag.output, DecodeTag.len, sof_time*4, *eof_time*4, NULL, false);
return DecodeTag.len;
//-----------------------------------------------------------------------------
void AcquireRawAdcSamplesIso15693(void)
{
- LEDsoff();
LED_A_ON();
uint8_t *dest = BigBuf_get_addr();
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER);
+ LED_D_ON();
FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER);
SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
BuildIdentifyRequest();
// Give the tags time to energize
- LED_D_ON();
SpinDelay(100);
// Now send the command
}
-void SnoopIso15693(void)
-{
+void SnoopIso15693(void) {
+
LED_A_ON();
+
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
- BigBuf_free();
clear_trace();
set_tracing(true);
// The DMA buffer, used to stream samples from the FPGA
- uint16_t* dmaBuf = (uint16_t*)BigBuf_malloc(ISO15693_DMA_BUFFER_SIZE*sizeof(uint16_t));
- uint16_t *upTo;
+ uint16_t dmaBuf[ISO15693_DMA_BUFFER_SIZE];
// Count of samples received so far, so that we can include timing
// information in the trace buffer.
Dbprintf("Snoop started. Press PM3 Button to stop.");
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER | FPGA_HF_READER_MODE_SNOOP_AMPLITUDE);
+ LED_D_OFF();
SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
-
- // Setup for the DMA.
FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER);
- upTo = dmaBuf;
+ StartCountSspClk();
FpgaSetupSscDma((uint8_t*) dmaBuf, ISO15693_DMA_BUFFER_SIZE);
-
+
bool TagIsActive = false;
bool ReaderIsActive = false;
bool ExpectTagAnswer = false;
-
+ uint32_t dma_start_time = 0;
+ uint16_t *upTo = dmaBuf;
+
// And now we loop, receiving samples.
for(;;) {
uint16_t behindBy = ((uint16_t*)AT91C_BASE_PDC_SSC->PDC_RPR - upTo) & (ISO15693_DMA_BUFFER_SIZE-1);
if (behindBy == 0) continue;
+ samples++;
+ if (samples == 1) {
+ // DMA has transferred the very first data
+ dma_start_time = GetCountSspClk() & 0xfffffff0;
+ }
+
uint16_t snoopdata = *upTo++;
- if(upTo >= dmaBuf + ISO15693_DMA_BUFFER_SIZE) { // we have read all of the DMA buffer content.
+ if (upTo >= dmaBuf + ISO15693_DMA_BUFFER_SIZE) { // we have read all of the DMA buffer content.
upTo = dmaBuf; // start reading the circular buffer from the beginning
- if(behindBy > (9*ISO15693_DMA_BUFFER_SIZE/10)) {
+ if (behindBy > (9*ISO15693_DMA_BUFFER_SIZE/10)) {
Dbprintf("About to blow circular buffer - aborted! behindBy=%d, samples=%d", behindBy, samples);
break;
}
AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) dmaBuf; // refresh the DMA Next Buffer and
AT91C_BASE_PDC_SSC->PDC_RNCR = ISO15693_DMA_BUFFER_SIZE; // DMA Next Counter registers
WDT_HIT();
- if(BUTTON_PRESS()) {
+ if (BUTTON_PRESS()) {
DbpString("Snoop stopped.");
break;
}
}
}
- samples++;
if (!TagIsActive) { // no need to try decoding reader data if the tag is sending
if (Handle15693SampleFromReader(snoopdata & 0x02, &DecodeReader)) {
- FpgaDisableSscDma();
- ExpectTagAnswer = true;
- LogTrace_ISO15693(DecodeReader.output, DecodeReader.byteCount, samples*64, samples*64, NULL, true);
+ // FpgaDisableSscDma();
+ uint32_t eof_time = dma_start_time + samples*16 + 8 - DELAY_READER_TO_ARM_SNOOP; // end of EOF
+ if (DecodeReader.byteCount > 0) {
+ uint32_t sof_time = eof_time
+ - DecodeReader.byteCount * (DecodeReader.Coding==CODING_1_OUT_OF_4?128*16:2048*16) // time for byte transfers
+ - 32*16 // time for SOF transfer
+ - 16*16; // time for EOF transfer
+ LogTrace_ISO15693(DecodeReader.output, DecodeReader.byteCount, sof_time*4, eof_time*4, NULL, true);
+ }
/* And ready to receive another command. */
DecodeReaderReset(&DecodeReader);
/* And also reset the demod code, which might have been */
/* false-triggered by the commands from the reader. */
DecodeTagReset(&DecodeTag);
- upTo = dmaBuf;
- FpgaSetupSscDma((uint8_t*) dmaBuf, ISO15693_DMA_BUFFER_SIZE);
- }
- if (Handle15693SampleFromReader(snoopdata & 0x01, &DecodeReader)) {
- FpgaDisableSscDma();
+ ReaderIsActive = false;
ExpectTagAnswer = true;
- LogTrace_ISO15693(DecodeReader.output, DecodeReader.byteCount, samples*64, samples*64, NULL, true);
+ // upTo = dmaBuf;
+ // samples = 0;
+ // FpgaSetupSscDma((uint8_t*) dmaBuf, ISO15693_DMA_BUFFER_SIZE);
+ // continue;
+ } else if (Handle15693SampleFromReader(snoopdata & 0x01, &DecodeReader)) {
+ // FpgaDisableSscDma();
+ uint32_t eof_time = dma_start_time + samples*16 + 16 - DELAY_READER_TO_ARM_SNOOP; // end of EOF
+ if (DecodeReader.byteCount > 0) {
+ uint32_t sof_time = eof_time
+ - DecodeReader.byteCount * (DecodeReader.Coding==CODING_1_OUT_OF_4?128*16:2048*16) // time for byte transfers
+ - 32*16 // time for SOF transfer
+ - 16*16; // time for EOF transfer
+ LogTrace_ISO15693(DecodeReader.output, DecodeReader.byteCount, sof_time*4, eof_time*4, NULL, true);
+ }
/* And ready to receive another command. */
DecodeReaderReset(&DecodeReader);
/* And also reset the demod code, which might have been */
/* false-triggered by the commands from the reader. */
DecodeTagReset(&DecodeTag);
- upTo = dmaBuf;
- FpgaSetupSscDma((uint8_t*) dmaBuf, ISO15693_DMA_BUFFER_SIZE);
+ ReaderIsActive = false;
+ ExpectTagAnswer = true;
+ // upTo = dmaBuf;
+ // samples = 0;
+ // FpgaSetupSscDma((uint8_t*) dmaBuf, ISO15693_DMA_BUFFER_SIZE);
+ // continue;
+ } else {
+ ReaderIsActive = (DecodeReader.state >= STATE_READER_RECEIVE_DATA_1_OUT_OF_4);
}
- ReaderIsActive = (DecodeReader.state >= STATE_READER_AWAIT_2ND_RISING_EDGE_OF_SOF);
}
if (!ReaderIsActive && ExpectTagAnswer) { // no need to try decoding tag data if the reader is currently sending or no answer expected yet
if (Handle15693SamplesFromTag(snoopdata >> 2, &DecodeTag)) {
- FpgaDisableSscDma();
- //Use samples as a time measurement
- LogTrace_ISO15693(DecodeTag.output, DecodeTag.len, samples*64, samples*64, NULL, false);
+ // FpgaDisableSscDma();
+ uint32_t eof_time = dma_start_time + samples*16 - DELAY_TAG_TO_ARM_SNOOP; // end of EOF
+ if (DecodeTag.lastBit == SOF_PART2) {
+ eof_time -= 8*16; // needed 8 additional samples to confirm single SOF (iCLASS)
+ }
+ uint32_t sof_time = eof_time
+ - DecodeTag.len * 8 * 8 * 16 // time for byte transfers
+ - 32 * 16 // time for SOF transfer
+ - (DecodeTag.lastBit != SOF_PART2?32*16:0); // time for EOF transfer
+ LogTrace_ISO15693(DecodeTag.output, DecodeTag.len, sof_time*4, eof_time*4, NULL, false);
// And ready to receive another response.
DecodeTagReset(&DecodeTag);
DecodeReaderReset(&DecodeReader);
ExpectTagAnswer = false;
- upTo = dmaBuf;
- FpgaSetupSscDma((uint8_t*) dmaBuf, ISO15693_DMA_BUFFER_SIZE);
+ TagIsActive = false;
+ // upTo = dmaBuf;
+ // samples = 0;
+ // FpgaSetupSscDma((uint8_t*) dmaBuf, ISO15693_DMA_BUFFER_SIZE);
+ // continue;
+ } else {
+ TagIsActive = (DecodeTag.state >= STATE_TAG_RECEIVING_DATA);
}
- TagIsActive = (DecodeTag.state >= STATE_TAG_RECEIVING_DATA);
}
}
FpgaDisableSscDma();
- BigBuf_free();
LEDsoff();
// return: length of received data, or -1 for timeout
int SendDataTag(uint8_t *send, int sendlen, bool init, int speed, uint8_t *recv, uint16_t max_recv_len, uint32_t start_time, uint32_t *eof_time) {
- LED_A_ON();
- LED_B_OFF();
- LED_C_OFF();
-
if (init) {
Iso15693InitReader();
StartCountSspClk();
}
-
+
int answerLen = 0;
-
+
if (!speed) {
// low speed (1 out of 256)
CodeIso15693AsReader256(send, sendlen);
CodeIso15693AsReader(send, sendlen);
}
- if (start_time == 0) {
- start_time = GetCountSspClk();
- }
TransmitTo15693Tag(ToSend, ToSendMax, &start_time);
// Now wait for a response
if (recv != NULL) {
- answerLen = GetIso15693AnswerFromTag(recv, max_recv_len, DELAY_ISO15693_VCD_TO_VICC_READER * 2, eof_time);
+ answerLen = GetIso15693AnswerFromTag(recv, max_recv_len, ISO15693_READER_TIMEOUT, eof_time);
}
- LED_A_OFF();
-
return answerLen;
}
// Simulate an ISO15693 reader, perform anti-collision and then attempt to read a sector.
// all demodulation performed in arm rather than host. - greg
//---------------------------------------------------------------------------------------
-void ReaderIso15693(uint32_t parameter)
-{
- LEDsoff();
+void ReaderIso15693(uint32_t parameter) {
+
LED_A_ON();
set_tracing(true);
// Simulate an ISO15693 TAG.
// For Inventory command: print command and send Inventory Response with given UID
// TODO: interpret other reader commands and send appropriate response
-void SimTagIso15693(uint32_t parameter, uint8_t *uid)
-{
- LEDsoff();
+void SimTagIso15693(uint32_t parameter, uint8_t *uid) {
+
LED_A_ON();
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
}
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
- LEDsoff();
+ LED_D_OFF();
+ LED_A_OFF();
}
// (some manufactures offer a way to read the AFI, though)
void BruteforceIso15693Afi(uint32_t speed)
{
- LEDsoff();
LED_A_ON();
uint8_t data[6];
Dbprintf("AFI Bruteforcing done.");
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
- LEDsoff();
+ LED_D_OFF();
+ LED_A_OFF();
+
}
// Allows to directly send commands to the tag via the client
void DirectTag15693Command(uint32_t datalen, uint32_t speed, uint32_t recv, uint8_t data[]) {
+ LED_A_ON();
+
int recvlen = 0;
uint8_t recvbuf[ISO15693_MAX_RESPONSE_LENGTH];
uint32_t eof_time;
-
- LED_A_ON();
if (DEBUG) {
Dbprintf("SEND:");
//-----------------------------------------------------------------------------
// Set the UID to the tag (based on Iceman work).
-void SetTag15693Uid(uint8_t *uid)
-{
- uint8_t cmd[4][9] = {0x00};
+void SetTag15693Uid(uint8_t *uid) {
+
+ LED_A_ON();
+ uint8_t cmd[4][9] = {0x00};
uint16_t crc;
int recvlen = 0;
uint8_t recvbuf[ISO15693_MAX_RESPONSE_LENGTH];
uint32_t eof_time;
-
- LED_A_ON();
// Command 1 : 02213E00000000
cmd[0][0] = 0x02;
cmd_send(CMD_ACK, recvlen>ISO15693_MAX_RESPONSE_LENGTH?ISO15693_MAX_RESPONSE_LENGTH:recvlen, 0, 0, recvbuf, ISO15693_MAX_RESPONSE_LENGTH);
}
- LED_D_OFF();
-
LED_A_OFF();
}