diff --git a/armsrc/iclass.c b/armsrc/iclass.c index e261efc59..cabec62ca 100644 --- a/armsrc/iclass.c +++ b/armsrc/iclass.c @@ -1264,7 +1264,7 @@ static bool iclass_send_cmd_with_retries(uint8_t *cmd, size_t cmdsize, uint8_t * return true; } - if (expected_size == GetIso15693AnswerFromTag(resp, max_resp_size, timeout, eof_time)) { + if (expected_size == GetIso15693AnswerFromTag(resp, max_resp_size, timeout, eof_time, false, true)) { return true; } } @@ -1296,7 +1296,7 @@ static bool select_iclass_tag_ex(picopass_hdr_t *hdr, bool use_credit_key, uint3 // wakeup uint32_t start_time = GetCountSspClk(); iclass_send_as_reader(act_all, 1, &start_time, eof_time); - int len = GetIso15693AnswerFromTag(resp, sizeof(resp), ICLASS_READER_TIMEOUT_ACTALL, eof_time); + int len = GetIso15693AnswerFromTag(resp, sizeof(resp), ICLASS_READER_TIMEOUT_ACTALL, eof_time, false, true); if (len < 0) return false; @@ -1305,7 +1305,7 @@ static bool select_iclass_tag_ex(picopass_hdr_t *hdr, bool use_credit_key, uint3 iclass_send_as_reader(identify, 1, &start_time, eof_time); // expect a 10-byte response here, 8 byte anticollision-CSN and 2 byte CRC - len = GetIso15693AnswerFromTag(resp, sizeof(resp), ICLASS_READER_TIMEOUT_OTHERS, eof_time); + len = GetIso15693AnswerFromTag(resp, sizeof(resp), ICLASS_READER_TIMEOUT_OTHERS, eof_time, false, true); if (len != 10) return false; @@ -1317,7 +1317,7 @@ static bool select_iclass_tag_ex(picopass_hdr_t *hdr, bool use_credit_key, uint3 iclass_send_as_reader(select, sizeof(select), &start_time, eof_time); // expect a 10-byte response here, 8 byte CSN and 2 byte CRC - len = GetIso15693AnswerFromTag(resp, sizeof(resp), ICLASS_READER_TIMEOUT_OTHERS, eof_time); + len = GetIso15693AnswerFromTag(resp, sizeof(resp), ICLASS_READER_TIMEOUT_OTHERS, eof_time, false, true); if (len != 10) return false; @@ -1329,7 +1329,7 @@ static bool select_iclass_tag_ex(picopass_hdr_t *hdr, bool use_credit_key, uint3 iclass_send_as_reader(read_conf, sizeof(read_conf), &start_time, eof_time); // expect a 8-byte response here - len = GetIso15693AnswerFromTag(resp, sizeof(resp), ICLASS_READER_TIMEOUT_OTHERS, eof_time); + len = GetIso15693AnswerFromTag(resp, sizeof(resp), ICLASS_READER_TIMEOUT_OTHERS, eof_time, false, true); if (len != 10) return false; @@ -1347,7 +1347,7 @@ static bool select_iclass_tag_ex(picopass_hdr_t *hdr, bool use_credit_key, uint3 iclass_send_as_reader(read_aia, sizeof(read_aia), &start_time, eof_time); // expect a 10-byte response here - len = GetIso15693AnswerFromTag(resp, sizeof(resp), ICLASS_READER_TIMEOUT_OTHERS, eof_time); + len = GetIso15693AnswerFromTag(resp, sizeof(resp), ICLASS_READER_TIMEOUT_OTHERS, eof_time, false, true); if (len != 10) return false; @@ -1361,7 +1361,7 @@ static bool select_iclass_tag_ex(picopass_hdr_t *hdr, bool use_credit_key, uint3 iclass_send_as_reader(read_check_cc, sizeof(read_check_cc), &start_time, eof_time); // expect a 8-byte response here - len = GetIso15693AnswerFromTag(resp, sizeof(resp), ICLASS_READER_TIMEOUT_OTHERS, eof_time); + len = GetIso15693AnswerFromTag(resp, sizeof(resp), ICLASS_READER_TIMEOUT_OTHERS, eof_time, false, true); if (len != 8) return false; @@ -1383,7 +1383,7 @@ static bool select_iclass_tag_ex(picopass_hdr_t *hdr, bool use_credit_key, uint3 iclass_send_as_reader(read_aia, sizeof(read_aia), &start_time, eof_time); // expect a 10-byte response here - len = GetIso15693AnswerFromTag(resp, sizeof(resp), ICLASS_READER_TIMEOUT_OTHERS, eof_time); + len = GetIso15693AnswerFromTag(resp, sizeof(resp), ICLASS_READER_TIMEOUT_OTHERS, eof_time, false, true); if (len != 10) return false; @@ -1870,7 +1870,7 @@ void iClass_WriteBlock(uint8_t *msg) { return; } else { - if (GetIso15693AnswerFromTag(resp, sizeof(resp), ICLASS_READER_TIMEOUT_UPDATE, &eof_time) == 10) { + if (GetIso15693AnswerFromTag(resp, sizeof(resp), ICLASS_READER_TIMEOUT_UPDATE, &eof_time, false, true) == 10) { res = true; break; } diff --git a/armsrc/iso15693.c b/armsrc/iso15693.c index edf9aa100..adba61be6 100644 --- a/armsrc/iso15693.c +++ b/armsrc/iso15693.c @@ -647,23 +647,346 @@ static void DecodeTagInit(DecodeTag_t *tag, uint8_t *data, uint16_t max_len) { DecodeTagReset(tag); } +//============================================================================= +// An ISO 15693 decoder for tag responses in FSK (two subcarriers) mode. +// Subcarriers frequencies are 424kHz and 484kHz (fc/32 and fc/28), +// LED handling: +// LED C -> ON once we have received the SOF and are expecting the rest. +// LED C -> OFF once we have received EOF or are unsynced +// +// Returns: true if we received a EOF +// false if we are still waiting for some more +//============================================================================= +//#define DEBUG 1 +#define FREQ_IS_484(f) ((f & 1) == 1) //(f >= 26 && f <= 30) +#define FREQ_IS_424(f) ((f & 2) == 2) //(f >= 30 && f <= 34) +#define FREQ_IS_0(f) ((f & 3) == 0) // (f <= 24 || f >= 36) +#define SEOF_COUNT(c, s) ((s) ? (c >= 11 && c <= 13) : (c >= 45 && c <= 51)) +#define LOGIC_COUNT(c, s) ((s) ? (c >= 3 && c <= 6) : (c >= 14 && c <= 20)) +#define MAX_COUNT(c, s) ((s) ? (c >= 13) : (c >= 52)) + +typedef struct DecodeTagFSK { + enum { + STATE_FSK_ERROR, + STATE_FSK_BEFORE_SOF, + STATE_FSK_SOF_484, + STATE_FSK_SOF_424, + STATE_FSK_SOF_END_484, + STATE_FSK_SOF_END_424, + STATE_FSK_RECEIVING_DATA_484, + STATE_FSK_RECEIVING_DATA_424, + STATE_FSK_EOF + } state; + enum { + LOGIC0_PART1, + LOGIC1_PART1, + LOGIC0_PART2, + LOGIC1_PART2, + SOF + } lastBit; + uint8_t count; + uint8_t bitCount; + uint8_t shiftReg; + uint16_t len; + uint16_t max_len; + uint8_t *output; +} DecodeTagFSK_t; + +static void DecodeTagFSKReset(DecodeTagFSK_t *DecodeTag) { + DecodeTag->state = STATE_FSK_BEFORE_SOF; + DecodeTag->bitCount = 0; + DecodeTag->len = 0; + DecodeTag->shiftReg = 0; +} + +static void DecodeTagFSKInit(DecodeTagFSK_t *DecodeTag, uint8_t *data, uint16_t max_len) { + DecodeTag->output = data; + DecodeTag->max_len = max_len; + DecodeTagFSKReset(DecodeTag); +} + +// Performances of this function are crutial for stability +// as it is called in real time for every samples +static int RAMFUNC Handle15693FSKSamplesFromTag(uint8_t freq, DecodeTagFSK_t *DecodeTag, bool recv_speed) +{ + switch(DecodeTag->state) { + case STATE_FSK_BEFORE_SOF: + if (FREQ_IS_484(freq)) + { // possible SOF starting + DecodeTag->state = STATE_FSK_SOF_484; + DecodeTag->lastBit = LOGIC0_PART1; + DecodeTag->count = 1; + } + break; + + case STATE_FSK_SOF_484: + //DbpString("STATE_FSK_SOF_484"); + if (FREQ_IS_424(freq) && SEOF_COUNT(DecodeTag->count, recv_speed)) + { // SOF part1 continue at 424 + DecodeTag->state = STATE_FSK_SOF_424; + DecodeTag->count = 1; + } + else if (FREQ_IS_484(freq) && !MAX_COUNT(DecodeTag->count, recv_speed)) // still in SOF at 484 + { + DecodeTag->count++; + } + else // SOF failed, roll back + { + DecodeTag->state = STATE_FSK_BEFORE_SOF; + } + break; + + case STATE_FSK_SOF_424: + //DbpString("STATE_FSK_SOF_424"); + if (FREQ_IS_484(freq) && SEOF_COUNT(DecodeTag->count, recv_speed)) + { // SOF part 1 finished + DecodeTag->state = STATE_FSK_SOF_END_484; + DecodeTag->count = 1; + } + else if (FREQ_IS_424(freq) && !MAX_COUNT(DecodeTag->count, recv_speed)) // still in SOF at 424 + DecodeTag->count++; + else // SOF failed, roll back + { +#ifdef DEBUG + if (DEBUG) + Dbprintf("SOF_424 failed: freq=%d, count=%d, recv_speed=%d", freq, DecodeTag->count, recv_speed); +#endif + DecodeTag->state = STATE_FSK_BEFORE_SOF; + } + break; + + case STATE_FSK_SOF_END_484: + if (FREQ_IS_424(freq) && LOGIC_COUNT(DecodeTag->count, recv_speed)) + { + DecodeTag->state = STATE_FSK_SOF_END_424; + DecodeTag->count = 1; + } + else if (FREQ_IS_484(freq) && !MAX_COUNT(DecodeTag->count, recv_speed)) // still in SOF_END_484 + DecodeTag->count++; + else // SOF failed, roll back + { +#ifdef DEBUG + if (DEBUG) + Dbprintf("SOF_END_484 failed: freq=%d, count=%d, recv_speed=%d", freq, DecodeTag->count, recv_speed); +#endif + DecodeTag->state = STATE_FSK_BEFORE_SOF; + } + break; + case STATE_FSK_SOF_END_424: + if (FREQ_IS_484(freq) && LOGIC_COUNT(DecodeTag->count, recv_speed)) + { // SOF finished at 484 + DecodeTag->count = 1; + DecodeTag->lastBit = SOF; + DecodeTag->state = STATE_FSK_RECEIVING_DATA_484; + LED_C_ON(); + } + else if (FREQ_IS_424(freq) && LOGIC_COUNT(DecodeTag->count-2, recv_speed)) + { // SOF finished at 424 (wait count+2 to be sure that next freq is 424) + DecodeTag->count = 2; + DecodeTag->lastBit = SOF; + DecodeTag->state = STATE_FSK_RECEIVING_DATA_424; + LED_C_ON(); + } + else if (FREQ_IS_424(freq) && !MAX_COUNT(DecodeTag->count, recv_speed)) // still in SOF_END_424 + DecodeTag->count++; + else // SOF failed, roll back + { +#ifdef DEBUG + if (DEBUG) + Dbprintf("SOF_END_424 failed: freq=%d, count=%d, recv_speed=%d", freq, DecodeTag->count, recv_speed); +#endif + DecodeTag->state = STATE_FSK_BEFORE_SOF; + } + break; + + + case STATE_FSK_RECEIVING_DATA_424: + if (FREQ_IS_484(freq) && LOGIC_COUNT(DecodeTag->count, recv_speed)) + { + if (DecodeTag->lastBit == LOGIC1_PART1) + { // logic 1 finished, goto 484 + DecodeTag->lastBit = LOGIC1_PART2; + + DecodeTag->shiftReg >>= 1; + DecodeTag->shiftReg |= 0x80; + DecodeTag->bitCount++; + if (DecodeTag->bitCount == 8) { + DecodeTag->output[DecodeTag->len++] = DecodeTag->shiftReg; + if (DecodeTag->len > DecodeTag->max_len) { + // buffer overflow, give up + LED_C_OFF(); + return true; + } + DecodeTag->bitCount = 0; + DecodeTag->shiftReg = 0; + } + } + else + { // end of LOGIC0_PART1 + DecodeTag->lastBit = LOGIC0_PART1; + } + DecodeTag->count = 1; + DecodeTag->state = STATE_FSK_RECEIVING_DATA_484; + } + else if (FREQ_IS_424(freq) && LOGIC_COUNT(DecodeTag->count-2, recv_speed) && + DecodeTag->lastBit == LOGIC1_PART1) + { // logic 1 finished, stay in 484 + DecodeTag->lastBit = LOGIC1_PART2; + + DecodeTag->shiftReg >>= 1; + DecodeTag->shiftReg |= 0x80; + DecodeTag->bitCount++; + if (DecodeTag->bitCount == 8) { + DecodeTag->output[DecodeTag->len++] = DecodeTag->shiftReg; + if (DecodeTag->len > DecodeTag->max_len) { + // buffer overflow, give up + LED_C_OFF(); + return true; + } + DecodeTag->bitCount = 0; + DecodeTag->shiftReg = 0; + } + DecodeTag->count = 2; + } + else if (FREQ_IS_424(freq) && !MAX_COUNT(DecodeTag->count, recv_speed)) // still at 424 + DecodeTag->count++; + + else if (FREQ_IS_484(freq) && DecodeTag->lastBit == LOGIC0_PART2 && + SEOF_COUNT(DecodeTag->count, recv_speed)) + { // EOF has started +#ifdef DEBUG + if (DEBUG) + Dbprintf("RECEIVING_DATA_424->EOF: freq=%d, count=%d, recv_speed=%d, lastbit=%d, state=%d", freq, DecodeTag->count, recv_speed, DecodeTag->lastBit, DecodeTag->state); +#endif + DecodeTag->count = 1; + DecodeTag->state = STATE_FSK_EOF; + LED_C_OFF(); + } + else // error + { +#ifdef DEBUG + if (DEBUG) + Dbprintf("RECEIVING_DATA_424 error: freq=%d, count=%d, recv_speed=%d, lastbit=%d, state=%d", freq, DecodeTag->count, recv_speed, DecodeTag->lastBit, DecodeTag->state); +#endif + DecodeTag->state = STATE_FSK_ERROR; + LED_C_OFF(); + return true; + } + break; + + case STATE_FSK_RECEIVING_DATA_484: + if (FREQ_IS_424(freq) && LOGIC_COUNT(DecodeTag->count, recv_speed)) + { + if (DecodeTag->lastBit == LOGIC0_PART1) + { // logic 0 finished, goto 424 + DecodeTag->lastBit = LOGIC0_PART2; + + DecodeTag->shiftReg >>= 1; + DecodeTag->bitCount++; + if (DecodeTag->bitCount == 8) { + DecodeTag->output[DecodeTag->len++] = DecodeTag->shiftReg; + if (DecodeTag->len > DecodeTag->max_len) { + // buffer overflow, give up + LED_C_OFF(); + return true; + } + DecodeTag->bitCount = 0; + DecodeTag->shiftReg = 0; + } + } + else + { // end of LOGIC1_PART1 + DecodeTag->lastBit = LOGIC1_PART1; + } + DecodeTag->count = 1; + DecodeTag->state = STATE_FSK_RECEIVING_DATA_424; + } + else if (FREQ_IS_484(freq) && LOGIC_COUNT(DecodeTag->count-2, recv_speed) && + DecodeTag->lastBit == LOGIC0_PART1) + { // logic 0 finished, stay in 424 + DecodeTag->lastBit = LOGIC0_PART2; + + DecodeTag->shiftReg >>= 1; + DecodeTag->bitCount++; + if (DecodeTag->bitCount == 8) { + DecodeTag->output[DecodeTag->len++] = DecodeTag->shiftReg; + if (DecodeTag->len > DecodeTag->max_len) { + // buffer overflow, give up + LED_C_OFF(); + return true; + } + DecodeTag->bitCount = 0; + DecodeTag->shiftReg = 0; + } + DecodeTag->count = 2; + } + else if (FREQ_IS_484(freq) && !MAX_COUNT(DecodeTag->count, recv_speed)) // still at 484 + DecodeTag->count++; + else // error + { +#ifdef DEBUG + if (DEBUG) + Dbprintf("RECEIVING_DATA_484 error: freq=%d, count=%d, recv_speed=%d, lastbit=%d, state=%d", freq, DecodeTag->count, recv_speed, DecodeTag->lastBit, DecodeTag->state); +#endif + LED_C_OFF(); + DecodeTag->state = STATE_FSK_ERROR; + return true; + } + break; + + case STATE_FSK_EOF: + if (FREQ_IS_484(freq) && !MAX_COUNT(DecodeTag->count, recv_speed)) // still at 484 + { + DecodeTag->count++; + if (SEOF_COUNT(DecodeTag->count, recv_speed)) + return true; // end of the transmission + } + else // error + { +#ifdef DEBUG + if (DEBUG) + Dbprintf("EOF error: freq=%d, count=%d, recv_speed=%d", freq, DecodeTag->count, recv_speed); +#endif + DecodeTag->state = STATE_FSK_ERROR; + return true; + } + break; + case STATE_FSK_ERROR: + LED_C_OFF(); +#ifdef DEBUG + if (DEBUG) + Dbprintf("FSK error: freq=%d, count=%d, recv_speed=%d", freq, DecodeTag->count, recv_speed); +#endif + return true; // error + break; + } + return false; +} + /* * Receive and decode the tag response, also log to tracebuffer */ -int GetIso15693AnswerFromTag(uint8_t *response, uint16_t max_len, uint16_t timeout, uint32_t *eof_time) { +int GetIso15693AnswerFromTag(uint8_t *response, uint16_t max_len, uint16_t timeout, uint32_t *eof_time, bool fsk, bool recv_speed) { int samples = 0, ret = 0; // the Decoder data structure DecodeTag_t dtm = { 0 }; DecodeTag_t *dt = &dtm; - DecodeTagInit(dt, response, max_len); + + DecodeTagFSK_t dtfm = { 0 }; + DecodeTagFSK_t *dtf = &dtfm; + + if (!fsk) + DecodeTagInit(dt, response, max_len); + else + DecodeTagFSKInit(dtf, response, max_len); // wait for last transfer to complete while (!(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXEMPTY)); // And put the FPGA in the appropriate mode - FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER | FPGA_HF_READER_SUBCARRIER_424_KHZ | FPGA_HF_READER_MODE_RECEIVE_AMPLITUDE); + FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER | FPGA_HF_READER_2SUBCARRIERS_424_484_KHZ | FPGA_HF_READER_MODE_RECEIVE_AMPLITUDE); // Setup and start DMA. FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER); @@ -719,56 +1042,102 @@ int GetIso15693AnswerFromTag(uint8_t *response, uint16_t max_len, uint16_t timeo } } - if (Handle15693SamplesFromTag(tagdata, dt, true)) { + if (!fsk) { + if (Handle15693SamplesFromTag(tagdata & 0x3FFF, dt, recv_speed)) { - *eof_time = dma_start_time + (samples * 16) - DELAY_TAG_TO_ARM; // end of EOF + *eof_time = dma_start_time + (samples * 16) - DELAY_TAG_TO_ARM; // end of EOF - if (dt->lastBit == SOF_PART2) { - *eof_time -= (8 * 16); // needed 8 additional samples to confirm single SOF (iCLASS) + if (dt->lastBit == SOF_PART2) { + *eof_time -= (8 * 16); // needed 8 additional samples to confirm single SOF (iCLASS) + } + if (dt->len > dt->max_len) { + ret = -2; // buffer overflow + Dbprintf("overflow (%d > %d", dt->len, dt->max_len); + } + break; } - if (dt->len > dt->max_len) { - ret = -2; // buffer overflow - Dbprintf("overflow (%d > %d", dt->len, dt->max_len); + + // timeout + if (samples > timeout && dt->state < STATE_TAG_RECEIVING_DATA) { + ret = -3; + break; } - break; } + else { + if (Handle15693FSKSamplesFromTag(tagdata >> 14, dtf, recv_speed)) { - // timeout - if (samples > timeout && dt->state < STATE_TAG_RECEIVING_DATA) { - ret = -3; - break; + *eof_time = dma_start_time + (samples * 16) - DELAY_TAG_TO_ARM; // end of EOF + + if (dtf->lastBit == SOF) { + *eof_time -= (8 * 16); // needed 8 additional samples to confirm single SOF (iCLASS) + } + if (dtf->len > dtf->max_len) { + ret = -2; // buffer overflow + Dbprintf("overflow (%d > %d", dtf->len, dtf->max_len); + } + break; + } + + // timeout + if (samples > timeout && dtf->state < STATE_FSK_RECEIVING_DATA_484) { + ret = -3; + break; + } } - } FpgaDisableSscDma(); FpgaDisableTracing(); - uint32_t sof_time = *eof_time - - (dt->len * 8 * 8 * 16) // time for byte transfers - - (32 * 16) // time for SOF transfer - - (dt->lastBit != SOF_PART2 ? (32 * 16) : 0); // time for EOF transfer + uint32_t sof_time = *eof_time - (32 * 16); // time for SOF transfer - if (g_dbglevel >= DBG_EXTENDED) { - Dbprintf("samples = %d, ret = %d, Decoder: state = %d, lastBit = %d, len = %d, bitCount = %d, posCount = %d, maxlen = %u", - samples, - ret, - dt->state, - dt->lastBit, - dt->len, - dt->bitCount, - dt->posCount, - dt->max_len + if (!fsk) { + sof_time -= (dt->len * 8 * 8 * 16) // time for byte transfers + + (dt->lastBit != SOF_PART2 ? (32 * 16) : 0); // time for EOF transfer + + if (g_dbglevel >= DBG_EXTENDED) { + Dbprintf("samples = %d, ret = %d, Decoder: state = %d, lastBit = %d, len = %d, bitCount = %d, posCount = %d, maxlen = %u", + samples, + ret, + dt->state, + dt->lastBit, + dt->len, + dt->bitCount, + dt->posCount, + dt->max_len ); - Dbprintf("timing: sof_time = %d, eof_time = %d", (sof_time * 4), (*eof_time * 4)); + Dbprintf("timing: sof_time = %d, eof_time = %d", (sof_time * 4), (*eof_time * 4)); + } + } + else { + sof_time -= (dtf->len * 8 * 8 * 16) // time for byte transfers + + (dtf->lastBit != SOF ? (32 * 16) : 0); // time for EOF transfer + + if (g_dbglevel >= DBG_EXTENDED) { + Dbprintf("samples = %d, ret = %d, FSK Decoder: state = %d, lastBit = %d, len = %d, bitCount = %d, count = %d, maxlen = %u", + samples, + ret, + dtf->state, + dtf->lastBit, + dtf->len, + dtf->bitCount, + dtf->count, + dtf->max_len + ); + Dbprintf("timing: sof_time = %d, eof_time = %d", (sof_time * 4), (*eof_time * 4)); + } } if (ret < 0) { return ret; } - LogTrace_ISO15693(dt->output, dt->len, (sof_time * 4), (*eof_time * 4), NULL, false); - return dt->len; + if (!fsk) { + LogTrace_ISO15693(dt->output, dt->len, (sof_time * 4), (*eof_time * 4), NULL, false); + return dt->len; + } + LogTrace_ISO15693(dtf->output, dtf->len, (sof_time * 4), (*eof_time * 4), NULL, false); + return dtf->len; } @@ -1259,323 +1628,6 @@ void AcquireRawAdcSamplesIso15693(void) { LEDsoff(); } -//============================================================================= -// An ISO 15693 decoder for tag responses in FSK (two subcarriers) mode. -// Subcarriers frequencies are 424kHz and 484kHz (fc/32 and fc/28), -// LED handling: -// LED C -> ON once we have received the SOF and are expecting the rest. -// LED C -> OFF once we have received EOF or are unsynced -// -// Returns: true if we received a EOF -// false if we are still waiting for some more -//============================================================================= -//#define DEBUG 1 -#define FREQ_IS_484(f) ((f & 1) == 1) //(f >= 26 && f <= 30) -#define FREQ_IS_424(f) ((f & 2) == 2) //(f >= 30 && f <= 34) -#define FREQ_IS_0(f) ((f & 3) == 0) // (f <= 24 || f >= 36) -#define SEOF_COUNT(c, s) ((s) ? (c >= 11 && c <= 13) : (c >= 44 && c <= 52)) -#define LOGIC_COUNT(c, s) ((s) ? (c >= 3 && c <= 6) : (c >= 13 && c <= 21)) -#define MAX_COUNT(c, s) ((s) ? (c >= 13) : (c >= 52)) -#define MIN_COUNT(c, s) ((s) ? (c <= 2) : (c <= 4)) - -typedef struct DecodeTagFSK { - enum { - STATE_FSK_ERROR, - STATE_FSK_BEFORE_SOF, - STATE_FSK_SOF_484, - STATE_FSK_SOF_424, - STATE_FSK_SOF_END_484, - STATE_FSK_SOF_END_424, - STATE_FSK_RECEIVING_DATA_484, - STATE_FSK_RECEIVING_DATA_424, - STATE_FSK_EOF - } state; - enum { - LOGIC0_PART1, - LOGIC1_PART1, - LOGIC0_PART2, - LOGIC1_PART2, - SOF - } lastBit; - uint8_t count; - uint8_t bitCount; - uint8_t shiftReg; - uint16_t len; - uint16_t max_len; - uint8_t *output; -} DecodeTagFSK_t; - -static void DecodeTagFSKReset(DecodeTagFSK_t *DecodeTag) { - DecodeTag->state = STATE_FSK_BEFORE_SOF; - DecodeTag->bitCount = 0; - DecodeTag->len = 0; - DecodeTag->shiftReg = 0; -} - -static void DecodeTagFSKInit(DecodeTagFSK_t *DecodeTag, uint8_t *data, uint16_t max_len) { - DecodeTag->output = data; - DecodeTag->max_len = max_len; - DecodeTagFSKReset(DecodeTag); -} - -// Performances of this function are crutial for stability -// as it is called in real time for every samples -static int RAMFUNC Handle15693FSKSamplesFromTag(uint8_t freq, DecodeTagFSK_t *DecodeTag, bool recv_speed) -{ - switch(DecodeTag->state) { - case STATE_FSK_BEFORE_SOF: - if (FREQ_IS_484(freq)) - { // possible SOF starting - DecodeTag->state = STATE_FSK_SOF_484; - DecodeTag->lastBit = LOGIC0_PART1; - DecodeTag->count = 1; - } - break; - - case STATE_FSK_SOF_484: - //DbpString("STATE_FSK_SOF_484"); - if (FREQ_IS_424(freq) && SEOF_COUNT(DecodeTag->count, recv_speed)) - { // SOF part1 continue at 424 - DecodeTag->state = STATE_FSK_SOF_424; - DecodeTag->count = 1; - } - else if (FREQ_IS_484(freq) && !MAX_COUNT(DecodeTag->count, recv_speed)) // still in SOF at 484 - { - DecodeTag->count++; - } - else // SOF failed, roll back - { - DecodeTag->state = STATE_FSK_BEFORE_SOF; - } - break; - - case STATE_FSK_SOF_424: - //DbpString("STATE_FSK_SOF_424"); - if (FREQ_IS_484(freq) && SEOF_COUNT(DecodeTag->count, recv_speed)) - { // SOF part 1 finished - DecodeTag->state = STATE_FSK_SOF_END_484; - DecodeTag->count = 1; - } - else if (FREQ_IS_424(freq) && !MAX_COUNT(DecodeTag->count, recv_speed)) // still in SOF at 424 - DecodeTag->count++; - else // SOF failed, roll back - { -#ifdef DEBUG - if (DEBUG) - Dbprintf("SOF_424 failed: freq=%d, count=%d, recv_speed=%d", freq, DecodeTag->count, recv_speed); -#endif - DecodeTag->state = STATE_FSK_BEFORE_SOF; - } - break; - - case STATE_FSK_SOF_END_484: - if (FREQ_IS_424(freq) && LOGIC_COUNT(DecodeTag->count, recv_speed)) - { - DecodeTag->state = STATE_FSK_SOF_END_424; - DecodeTag->count = 1; - } - else if (FREQ_IS_484(freq) && !MAX_COUNT(DecodeTag->count, recv_speed)) // still in SOF_END_484 - DecodeTag->count++; - else // SOF failed, roll back - { -#ifdef DEBUG - if (DEBUG) - Dbprintf("SOF_END_484 failed: freq=%d, count=%d, recv_speed=%d", freq, DecodeTag->count, recv_speed); -#endif - DecodeTag->state = STATE_FSK_BEFORE_SOF; - } - break; - case STATE_FSK_SOF_END_424: - if (FREQ_IS_484(freq) && LOGIC_COUNT(DecodeTag->count, recv_speed)) - { // SOF finished at 484 - DecodeTag->count = 1; - DecodeTag->lastBit = SOF; - DecodeTag->state = STATE_FSK_RECEIVING_DATA_484; - LED_C_ON(); - } - else if (FREQ_IS_424(freq) && LOGIC_COUNT(DecodeTag->count-2, recv_speed)) - { // SOF finished at 424 (wait count+2 to be sure that next freq is 424) - DecodeTag->count = 2; - DecodeTag->lastBit = SOF; - DecodeTag->state = STATE_FSK_RECEIVING_DATA_424; - LED_C_ON(); - } - else if (FREQ_IS_424(freq) && !MAX_COUNT(DecodeTag->count, recv_speed)) // still in SOF_END_424 - DecodeTag->count++; - else // SOF failed, roll back - { -#ifdef DEBUG - if (DEBUG) - Dbprintf("SOF_END_424 failed: freq=%d, count=%d, recv_speed=%d", freq, DecodeTag->count, recv_speed); -#endif - DecodeTag->state = STATE_FSK_BEFORE_SOF; - } - break; - - - case STATE_FSK_RECEIVING_DATA_424: - if (FREQ_IS_484(freq) && LOGIC_COUNT(DecodeTag->count, recv_speed)) - { - if (DecodeTag->lastBit == LOGIC1_PART1) - { // logic 1 finished, goto 484 - DecodeTag->lastBit = LOGIC1_PART2; - - DecodeTag->shiftReg >>= 1; - DecodeTag->shiftReg |= 0x80; - DecodeTag->bitCount++; - if (DecodeTag->bitCount == 8) { - DecodeTag->output[DecodeTag->len++] = DecodeTag->shiftReg; - if (DecodeTag->len > DecodeTag->max_len) { - // buffer overflow, give up - LED_C_OFF(); - return true; - } - DecodeTag->bitCount = 0; - DecodeTag->shiftReg = 0; - } - } - else - { // end of LOGIC0_PART1 - DecodeTag->lastBit = LOGIC0_PART1; - } - DecodeTag->count = 1; - DecodeTag->state = STATE_FSK_RECEIVING_DATA_484; - } - else if (FREQ_IS_424(freq) && LOGIC_COUNT(DecodeTag->count-2, recv_speed) && - DecodeTag->lastBit == LOGIC1_PART1) - { // logic 1 finished, stay in 484 - DecodeTag->lastBit = LOGIC1_PART2; - - DecodeTag->shiftReg >>= 1; - DecodeTag->shiftReg |= 0x80; - DecodeTag->bitCount++; - if (DecodeTag->bitCount == 8) { - DecodeTag->output[DecodeTag->len++] = DecodeTag->shiftReg; - if (DecodeTag->len > DecodeTag->max_len) { - // buffer overflow, give up - LED_C_OFF(); - return true; - } - DecodeTag->bitCount = 0; - DecodeTag->shiftReg = 0; - } - DecodeTag->count = 2; - } - else if (FREQ_IS_424(freq) && !MAX_COUNT(DecodeTag->count, recv_speed)) // still at 424 - DecodeTag->count++; - - else if (FREQ_IS_484(freq) && DecodeTag->lastBit == LOGIC0_PART2 && - SEOF_COUNT(DecodeTag->count, recv_speed)) - { // EOF has started -#ifdef DEBUG - if (DEBUG) - Dbprintf("RECEIVING_DATA_424->EOF: freq=%d, count=%d, recv_speed=%d, lastbit=%d, state=%d", freq, DecodeTag->count, recv_speed, DecodeTag->lastBit, DecodeTag->state); -#endif - DecodeTag->count = 1; - DecodeTag->state = STATE_FSK_EOF; - LED_C_OFF(); - } - else // error - { -#ifdef DEBUG - if (DEBUG) - Dbprintf("RECEIVING_DATA_424 error: freq=%d, count=%d, recv_speed=%d, lastbit=%d, state=%d", freq, DecodeTag->count, recv_speed, DecodeTag->lastBit, DecodeTag->state); -#endif - DecodeTag->state = STATE_FSK_ERROR; - LED_C_OFF(); - return true; - } - break; - - case STATE_FSK_RECEIVING_DATA_484: - if (FREQ_IS_424(freq) && LOGIC_COUNT(DecodeTag->count, recv_speed)) - { - if (DecodeTag->lastBit == LOGIC0_PART1) - { // logic 0 finished, goto 424 - DecodeTag->lastBit = LOGIC0_PART2; - - DecodeTag->shiftReg >>= 1; - DecodeTag->bitCount++; - if (DecodeTag->bitCount == 8) { - DecodeTag->output[DecodeTag->len++] = DecodeTag->shiftReg; - if (DecodeTag->len > DecodeTag->max_len) { - // buffer overflow, give up - LED_C_OFF(); - return true; - } - DecodeTag->bitCount = 0; - DecodeTag->shiftReg = 0; - } - } - else - { // end of LOGIC1_PART1 - DecodeTag->lastBit = LOGIC1_PART1; - } - DecodeTag->count = 1; - DecodeTag->state = STATE_FSK_RECEIVING_DATA_424; - } - else if (FREQ_IS_484(freq) && LOGIC_COUNT(DecodeTag->count-2, recv_speed) && - DecodeTag->lastBit == LOGIC0_PART1) - { // logic 0 finished, stay in 424 - DecodeTag->lastBit = LOGIC0_PART2; - - DecodeTag->shiftReg >>= 1; - DecodeTag->bitCount++; - if (DecodeTag->bitCount == 8) { - DecodeTag->output[DecodeTag->len++] = DecodeTag->shiftReg; - if (DecodeTag->len > DecodeTag->max_len) { - // buffer overflow, give up - LED_C_OFF(); - return true; - } - DecodeTag->bitCount = 0; - DecodeTag->shiftReg = 0; - } - DecodeTag->count = 2; - } - else if (FREQ_IS_484(freq) && !MAX_COUNT(DecodeTag->count, recv_speed)) // still at 484 - DecodeTag->count++; - else // error - { -#ifdef DEBUG - if (DEBUG) - Dbprintf("RECEIVING_DATA_484 error: freq=%d, count=%d, recv_speed=%d, lastbit=%d, state=%d", freq, DecodeTag->count, recv_speed, DecodeTag->lastBit, DecodeTag->state); -#endif - LED_C_OFF(); - DecodeTag->state = STATE_FSK_ERROR; - return true; - } - break; - - case STATE_FSK_EOF: - if (FREQ_IS_484(freq) && !MAX_COUNT(DecodeTag->count, recv_speed)) // still at 484 - { - DecodeTag->count++; - if (SEOF_COUNT(DecodeTag->count, recv_speed)) - return true; // end of the transmission - } - else // error - { -#ifdef DEBUG - if (DEBUG) - Dbprintf("EOF error: freq=%d, count=%d, recv_speed=%d", freq, DecodeTag->count, recv_speed); -#endif - DecodeTag->state = STATE_FSK_ERROR; - return true; - } - break; - case STATE_FSK_ERROR: - LED_C_OFF(); -#ifdef DEBUG - if (DEBUG) - Dbprintf("FSK error: freq=%d, count=%d, recv_speed=%d", freq, DecodeTag->count, recv_speed); -#endif - return true; // error - break; - } - return false; -} - void SniffIso15693(uint8_t jam_search_len, uint8_t *jam_search_string, bool iclass) { LEDsoff(); @@ -1869,6 +1921,9 @@ int SendDataTag(uint8_t *send, int sendlen, bool init, bool speed_fast, uint8_t start_time = GetCountSspClk(); } + bool fsk = send[0] & ISO15_REQ_SUBCARRIER_TWO; + bool recv_speed = send[0] & ISO15_REQ_DATARATE_HIGH; + if (speed_fast) { // high speed (1 out of 4) CodeIso15693AsReader(send, sendlen); @@ -1889,13 +1944,13 @@ int SendDataTag(uint8_t *send, int sendlen, bool init, bool speed_fast, uint8_t *eof_time = start_time + 32 * ((8 * ts->max) - 4); // subtract the 4 padding bits after EOF LogTrace_ISO15693(send, sendlen, (start_time * 4), (*eof_time * 4), NULL, true); if (recv != NULL) { - res = GetIso15693AnswerFromTag(recv, max_recv_len, timeout, eof_time); + res = GetIso15693AnswerFromTag(recv, max_recv_len, timeout, eof_time, fsk, recv_speed); } } return res; } -int SendDataTagEOF(uint8_t *recv, uint16_t max_recv_len, uint32_t start_time, uint16_t timeout, uint32_t *eof_time) { +int SendDataTagEOF(uint8_t *recv, uint16_t max_recv_len, uint32_t start_time, uint16_t timeout, uint32_t *eof_time, bool fsk, bool recv_speed) { CodeIso15693AsReaderEOF(); tosend_t *ts = get_tosend(); @@ -1905,7 +1960,7 @@ int SendDataTagEOF(uint8_t *recv, uint16_t max_recv_len, uint32_t start_time, ui int res = 0; if (recv != NULL) { - res = GetIso15693AnswerFromTag(recv, max_recv_len, timeout, eof_time); + res = GetIso15693AnswerFromTag(recv, max_recv_len, timeout, eof_time, fsk, recv_speed); } return res; } @@ -2335,10 +2390,13 @@ void DirectTag15693Command(uint32_t datalen, uint32_t speed, uint32_t recv, uint reply_mix(CMD_ACK, recvlen, 0, 0, NULL, 0); } else { + bool fsk = data[0] & ISO15_REQ_SUBCARRIER_TWO; + bool recv_speed = data[0] & ISO15_REQ_DATARATE_HIGH; + // send a single EOF to get the tag response if (request_answer) { start_time = eof_time + DELAY_ISO15693_VICC_TO_VCD_READER; - recvlen = SendDataTagEOF((recv ? recvbuf : NULL), sizeof(recvbuf), start_time, ISO15693_READER_TIMEOUT, &eof_time); + recvlen = SendDataTagEOF((recv ? recvbuf : NULL), sizeof(recvbuf), start_time, ISO15693_READER_TIMEOUT, &eof_time, fsk, recv_speed); } if (recv) { diff --git a/armsrc/iso15693.h b/armsrc/iso15693.h index 31ca6e6c1..dbb3ff28b 100644 --- a/armsrc/iso15693.h +++ b/armsrc/iso15693.h @@ -41,7 +41,7 @@ void CodeIso15693AsTag(const uint8_t *cmd, size_t len); void TransmitTo15693Reader(const uint8_t *cmd, size_t len, uint32_t *start_time, uint32_t slot_time, bool slow); int GetIso15693CommandFromReader(uint8_t *received, size_t max_len, uint32_t *eof_time); void TransmitTo15693Tag(const uint8_t *cmd, int len, uint32_t *start_time); -int GetIso15693AnswerFromTag(uint8_t *response, uint16_t max_len, uint16_t timeout, uint32_t *eof_time); +int GetIso15693AnswerFromTag(uint8_t *response, uint16_t max_len, uint16_t timeout, uint32_t *eof_time, bool fsk, bool recv_speed); //void RecordRawAdcSamplesIso15693(void); void AcquireRawAdcSamplesIso15693(void); @@ -55,7 +55,7 @@ void SniffIso15693(uint8_t jam_search_len, uint8_t *jam_search_string, bool icla int SendDataTag(uint8_t *send, int sendlen, bool init, bool speed_fast, uint8_t *recv, uint16_t max_recv_len, uint32_t start_time, uint16_t timeout, uint32_t *eof_time); -int SendDataTagEOF(uint8_t *recv, uint16_t max_recv_len, uint32_t start_time, uint16_t timeout, uint32_t *eof_time); +int SendDataTagEOF(uint8_t *recv, uint16_t max_recv_len, uint32_t start_time, uint16_t timeout, uint32_t *eof_time, bool fsk, bool recv_speed); void SetTag15693Uid(const uint8_t *uid); diff --git a/fpga-xc2s30/fpga_hf_15.bit b/fpga-xc2s30/fpga_hf_15.bit index 678e746c4..c1ea7d070 100644 Binary files a/fpga-xc2s30/fpga_hf_15.bit and b/fpga-xc2s30/fpga_hf_15.bit differ diff --git a/fpga-xc2s30/hi_reader_15.v b/fpga-xc2s30/hi_reader_15.v index 28b8a7cae..357dc9e08 100644 --- a/fpga-xc2s30/hi_reader_15.v +++ b/fpga-xc2s30/hi_reader_15.v @@ -245,11 +245,11 @@ begin if (minor_mode == `FPGA_HF_READER_MODE_SNIFF_AMPLITUDE) begin if (subcarrier_frequency == `FPGA_HF_READER_2SUBCARRIERS_424_484_KHZ) - begin + begin // send amplitude + 2 bits fsk (2sc) signal + 2 bits reader signal corr_i_out <= corr_amplitude[13:6]; corr_q_out <= {corr_amplitude[5:2], fskout, after_hysteresis_prev_prev, after_hysteresis_prev}; - end + end else begin // send amplitude plus 2 bits reader signal @@ -279,9 +279,18 @@ begin end else if (minor_mode == `FPGA_HF_READER_MODE_RECEIVE_AMPLITUDE) begin - // send amplitude - corr_i_out <= {2'b00, corr_amplitude[13:8]}; - corr_q_out <= corr_amplitude[7:0]; + if (subcarrier_frequency == `FPGA_HF_READER_2SUBCARRIERS_424_484_KHZ) + begin + // send 2 bits fsk (2sc) signal + amplitude + corr_i_out <= {fskout, corr_amplitude[13:8]}; + corr_q_out <= corr_amplitude[7:0]; + end + else + begin + // send amplitude + corr_i_out <= {2'b00, corr_amplitude[13:8]}; + corr_q_out <= corr_amplitude[7:0]; + end end else if (minor_mode == `FPGA_HF_READER_MODE_RECEIVE_IQ) begin