mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-21 22:03:42 -07:00
Merge pull request #1627 from lnv42/iso15rawSlowAnd2SC
[iso15] Add support for recieving slow and/or dual subcarriers answers from any raw commands
This commit is contained in:
commit
bda8062bff
5 changed files with 437 additions and 370 deletions
|
@ -1264,7 +1264,7 @@ static bool iclass_send_cmd_with_retries(uint8_t *cmd, size_t cmdsize, uint8_t *
|
||||||
return true;
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1296,7 +1296,7 @@ static bool select_iclass_tag_ex(picopass_hdr_t *hdr, bool use_credit_key, uint3
|
||||||
// wakeup
|
// wakeup
|
||||||
uint32_t start_time = GetCountSspClk();
|
uint32_t start_time = GetCountSspClk();
|
||||||
iclass_send_as_reader(act_all, 1, &start_time, eof_time);
|
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)
|
if (len < 0)
|
||||||
return false;
|
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);
|
iclass_send_as_reader(identify, 1, &start_time, eof_time);
|
||||||
|
|
||||||
// expect a 10-byte response here, 8 byte anticollision-CSN and 2 byte CRC
|
// 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)
|
if (len != 10)
|
||||||
return false;
|
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);
|
iclass_send_as_reader(select, sizeof(select), &start_time, eof_time);
|
||||||
|
|
||||||
// expect a 10-byte response here, 8 byte CSN and 2 byte CRC
|
// 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)
|
if (len != 10)
|
||||||
return false;
|
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);
|
iclass_send_as_reader(read_conf, sizeof(read_conf), &start_time, eof_time);
|
||||||
|
|
||||||
// expect a 8-byte response here
|
// 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)
|
if (len != 10)
|
||||||
return false;
|
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);
|
iclass_send_as_reader(read_aia, sizeof(read_aia), &start_time, eof_time);
|
||||||
|
|
||||||
// expect a 10-byte response here
|
// 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)
|
if (len != 10)
|
||||||
return false;
|
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);
|
iclass_send_as_reader(read_check_cc, sizeof(read_check_cc), &start_time, eof_time);
|
||||||
|
|
||||||
// expect a 8-byte response here
|
// 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)
|
if (len != 8)
|
||||||
return false;
|
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);
|
iclass_send_as_reader(read_aia, sizeof(read_aia), &start_time, eof_time);
|
||||||
|
|
||||||
// expect a 10-byte response here
|
// 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)
|
if (len != 10)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -1870,7 +1870,7 @@ void iClass_WriteBlock(uint8_t *msg) {
|
||||||
return;
|
return;
|
||||||
} else {
|
} 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;
|
res = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -647,23 +647,346 @@ static void DecodeTagInit(DecodeTag_t *tag, uint8_t *data, uint16_t max_len) {
|
||||||
DecodeTagReset(tag);
|
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
|
* 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;
|
int samples = 0, ret = 0;
|
||||||
|
|
||||||
// the Decoder data structure
|
// the Decoder data structure
|
||||||
DecodeTag_t dtm = { 0 };
|
DecodeTag_t dtm = { 0 };
|
||||||
DecodeTag_t *dt = &dtm;
|
DecodeTag_t *dt = &dtm;
|
||||||
|
|
||||||
|
DecodeTagFSK_t dtfm = { 0 };
|
||||||
|
DecodeTagFSK_t *dtf = &dtfm;
|
||||||
|
|
||||||
|
if (!fsk)
|
||||||
DecodeTagInit(dt, response, max_len);
|
DecodeTagInit(dt, response, max_len);
|
||||||
|
else
|
||||||
|
DecodeTagFSKInit(dtf, response, max_len);
|
||||||
|
|
||||||
// wait for last transfer to complete
|
// wait for last transfer to complete
|
||||||
while (!(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXEMPTY));
|
while (!(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXEMPTY));
|
||||||
|
|
||||||
// And put the FPGA in the appropriate mode
|
// 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.
|
// Setup and start DMA.
|
||||||
FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER);
|
FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER);
|
||||||
|
@ -719,7 +1042,8 @@ 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
|
||||||
|
|
||||||
|
@ -738,16 +1062,38 @@ int GetIso15693AnswerFromTag(uint8_t *response, uint16_t max_len, uint16_t timeo
|
||||||
ret = -3;
|
ret = -3;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (Handle15693FSKSamplesFromTag(tagdata >> 14, dtf, recv_speed)) {
|
||||||
|
|
||||||
|
*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();
|
FpgaDisableSscDma();
|
||||||
FpgaDisableTracing();
|
FpgaDisableTracing();
|
||||||
|
|
||||||
uint32_t sof_time = *eof_time
|
uint32_t sof_time = *eof_time - (32 * 16); // time for SOF transfer
|
||||||
- (dt->len * 8 * 8 * 16) // time for byte transfers
|
|
||||||
- (32 * 16) // time for SOF transfer
|
if (!fsk) {
|
||||||
- (dt->lastBit != SOF_PART2 ? (32 * 16) : 0); // time for EOF transfer
|
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) {
|
if (g_dbglevel >= DBG_EXTENDED) {
|
||||||
Dbprintf("samples = %d, ret = %d, Decoder: state = %d, lastBit = %d, len = %d, bitCount = %d, posCount = %d, maxlen = %u",
|
Dbprintf("samples = %d, ret = %d, Decoder: state = %d, lastBit = %d, len = %d, bitCount = %d, posCount = %d, maxlen = %u",
|
||||||
|
@ -762,14 +1108,37 @@ int GetIso15693AnswerFromTag(uint8_t *response, uint16_t max_len, uint16_t timeo
|
||||||
);
|
);
|
||||||
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) {
|
if (ret < 0) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!fsk) {
|
||||||
LogTrace_ISO15693(dt->output, dt->len, (sof_time * 4), (*eof_time * 4), NULL, false);
|
LogTrace_ISO15693(dt->output, dt->len, (sof_time * 4), (*eof_time * 4), NULL, false);
|
||||||
return dt->len;
|
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();
|
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) {
|
void SniffIso15693(uint8_t jam_search_len, uint8_t *jam_search_string, bool iclass) {
|
||||||
|
|
||||||
LEDsoff();
|
LEDsoff();
|
||||||
|
@ -1869,6 +1921,9 @@ int SendDataTag(uint8_t *send, int sendlen, bool init, bool speed_fast, uint8_t
|
||||||
start_time = GetCountSspClk();
|
start_time = GetCountSspClk();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool fsk = send[0] & ISO15_REQ_SUBCARRIER_TWO;
|
||||||
|
bool recv_speed = send[0] & ISO15_REQ_DATARATE_HIGH;
|
||||||
|
|
||||||
if (speed_fast) {
|
if (speed_fast) {
|
||||||
// high speed (1 out of 4)
|
// high speed (1 out of 4)
|
||||||
CodeIso15693AsReader(send, sendlen);
|
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
|
*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);
|
LogTrace_ISO15693(send, sendlen, (start_time * 4), (*eof_time * 4), NULL, true);
|
||||||
if (recv != NULL) {
|
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;
|
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();
|
CodeIso15693AsReaderEOF();
|
||||||
tosend_t *ts = get_tosend();
|
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;
|
int res = 0;
|
||||||
if (recv != NULL) {
|
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;
|
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);
|
reply_mix(CMD_ACK, recvlen, 0, 0, NULL, 0);
|
||||||
} else {
|
} 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
|
// send a single EOF to get the tag response
|
||||||
if (request_answer) {
|
if (request_answer) {
|
||||||
start_time = eof_time + DELAY_ISO15693_VICC_TO_VCD_READER;
|
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) {
|
if (recv) {
|
||||||
|
|
|
@ -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);
|
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);
|
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);
|
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 RecordRawAdcSamplesIso15693(void);
|
||||||
void AcquireRawAdcSamplesIso15693(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,
|
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);
|
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);
|
void SetTag15693Uid(const uint8_t *uid);
|
||||||
|
|
||||||
|
|
Binary file not shown.
|
@ -278,11 +278,20 @@ begin
|
||||||
corr_q_out <= {7'b1000000, after_hysteresis_prev};
|
corr_q_out <= {7'b1000000, after_hysteresis_prev};
|
||||||
end
|
end
|
||||||
else if (minor_mode == `FPGA_HF_READER_MODE_RECEIVE_AMPLITUDE)
|
else if (minor_mode == `FPGA_HF_READER_MODE_RECEIVE_AMPLITUDE)
|
||||||
|
begin
|
||||||
|
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
|
begin
|
||||||
// send amplitude
|
// send amplitude
|
||||||
corr_i_out <= {2'b00, corr_amplitude[13:8]};
|
corr_i_out <= {2'b00, corr_amplitude[13:8]};
|
||||||
corr_q_out <= corr_amplitude[7:0];
|
corr_q_out <= corr_amplitude[7:0];
|
||||||
end
|
end
|
||||||
|
end
|
||||||
else if (minor_mode == `FPGA_HF_READER_MODE_RECEIVE_IQ)
|
else if (minor_mode == `FPGA_HF_READER_MODE_RECEIVE_IQ)
|
||||||
begin
|
begin
|
||||||
// Send 8 bits of in phase tag signal
|
// Send 8 bits of in phase tag signal
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue