From 86d47110a97f18ebbffd3ac8d7ed79e1ce3bacc1 Mon Sep 17 00:00:00 2001 From: chenzitai Date: Fri, 27 Jul 2018 01:46:12 +0100 Subject: [PATCH] Basic auto calibrate for sniffing mode. Started from the smallest threshold and when the first good threshold is obtained, stop. May also need to extend the TIMEOUT to make this work. Need the reader reading all the timing when sniffing in order to auto calibrate (cherry picked from commit 2c3d5f5) --- .../Chameleon-Mini/Application/Sniff14443A.c | 102 ++++++++++-------- .../Chameleon-Mini/Codec/SniffISO14443-2A.c | 2 - 2 files changed, 57 insertions(+), 47 deletions(-) diff --git a/Firmware/Chameleon-Mini/Application/Sniff14443A.c b/Firmware/Chameleon-Mini/Application/Sniff14443A.c index e652834..59f3ed7 100644 --- a/Firmware/Chameleon-Mini/Application/Sniff14443A.c +++ b/Firmware/Chameleon-Mini/Application/Sniff14443A.c @@ -11,7 +11,7 @@ extern bool checkParityBits(uint8_t * Buffer, uint16_t BitCount); Sniff14443Command Sniff14443CurrentCommand = Sniff14443_Do_Nothing; -bool selected = false; +//bool selected = false; static enum { STATE_IDLE, STATE_REQA, @@ -22,16 +22,21 @@ static enum { STATE_SAK, } SniffState = STATE_IDLE; +static uint16_t tmp_th = CODEC_THRESHOLD_CALIBRATE_MIN; +static uint8_t Thresholds[(CODEC_THRESHOLD_CALIBRATE_MAX - CODEC_THRESHOLD_CALIBRATE_MIN) / + CODEC_THRESHOLD_CALIBRATE_STEPS] = {0}; void Sniff14443AAppInit(void){ SniffState = STATE_REQA; - selected = false; + + tmp_th = CODEC_THRESHOLD_CALIBRATE_MIN; + CodecThresholdSet(tmp_th); } void Sniff14443AAppReset(void){ SniffState = STATE_IDLE; + Sniff14443CurrentCommand = Sniff14443_Do_Nothing; - selected = false; } // Currently APPTask and AppTick is not being used void Sniff14443AAppTask(void){/* Empty */} @@ -41,24 +46,31 @@ void Sniff14443AAppTimeout(void){ Sniff14443AAppReset(); } -void reset2REQA(void){ +INLINE void reset2REQA(void){ SniffState = STATE_REQA; LED_PORT.OUTCLR = LED_RED; - selected = false; - // TODO: Mark the current threshold as fail and continue + // Mark the current threshold as fail and continue + if(tmp_th < CODEC_THRESHOLD_CALIBRATE_MAX){ + Thresholds[(tmp_th - CODEC_THRESHOLD_CALIBRATE_MIN) / CODEC_THRESHOLD_CALIBRATE_STEPS] = 0; + tmp_th = CodecThresholdIncrement(); + } else{ + // mark finish + } } uint16_t Sniff14443AAppProcess(uint8_t* Buffer, uint16_t BitCount){ switch (Sniff14443CurrentCommand){ - case Sniff14443_Do_Nothing: + case Sniff14443_Do_Nothing: { return 0; - case Sniff14443_Autocalibrate: - switch (SniffState){ + } + case Sniff14443_Autocalibrate: { + + switch (SniffState) { case STATE_REQA: + LED_PORT.OUTCLR = LED_RED; // If received Reader REQA or WUPA if (TrafficSource == TRAFFIC_READER && - (Buffer[0] == 0x26 || Buffer[0] == 0x54)) - { + (Buffer[0] == 0x26 || Buffer[0] == 0x52)) { SniffState = STATE_ATQA; } else { // Stay in this state, do noting @@ -67,19 +79,18 @@ uint16_t Sniff14443AAppProcess(uint8_t* Buffer, uint16_t BitCount){ case STATE_ATQA: // ATQA: P RRRR XXXX P XXRX XXXX if (TrafficSource == TRAFFIC_CARD && - BitCount == 2*9 && - (Buffer[0] & 0x20) == 0x00 && // Bit6 RFU shall be 0 - (Buffer[1] & 0xE0) == 0x00 && // bit13-16 RFU shall be 0 - (Buffer[2] & 0x01) == 0x00 && - checkParityBits(Buffer, BitCount)) - { + BitCount == 2 * 9 && + (Buffer[0] & 0x20) == 0x00 && // Bit6 RFU shall be 0 + (Buffer[1] & 0xE0) == 0x00 && // bit13-16 RFU shall be 0 + (Buffer[2] & 0x01) == 0x00 && + checkParityBits(Buffer, BitCount)) { // Assume this is a good ATQA SniffState = STATE_ANTICOLLI; } else { // If not ATQA, but REQA, then stay on this state, // Reset to REQA, save the counter and reset the counter if (TrafficSource == TRAFFIC_READER && - (Buffer[0] == 0x26 || Buffer[0] == 0x54)) { + (Buffer[0] == 0x26 || Buffer[0] == 0x52)) { } else { // If not ATQA and not REQA then reset to REQA reset2REQA(); @@ -87,23 +98,21 @@ uint16_t Sniff14443AAppProcess(uint8_t* Buffer, uint16_t BitCount){ } break; case STATE_ANTICOLLI: - LED_PORT.OUTSET = LED_RED; // SEL: 93/95/97 - if(TrafficSource == TRAFFIC_READER && - BitCount == 2*8 && - (Buffer[0] & 0xf0) == 0x90 && - (Buffer[0] & 0x09) == 0x01) - { + if (TrafficSource == TRAFFIC_READER && + BitCount == 2 * 8 && + (Buffer[0] & 0xf0) == 0x90 && + (Buffer[0] & 0x09) == 0x01) { SniffState = STATE_UID; - } else{ + + } else { reset2REQA(); } break; case STATE_UID: - if(TrafficSource == TRAFFIC_CARD && - BitCount == 5*9 && - checkParityBits(Buffer, BitCount)) - { + if (TrafficSource == TRAFFIC_CARD && + BitCount == 5 * 9 && + checkParityBits(Buffer, BitCount)) { SniffState = STATE_SELECT; } else { reset2REQA(); @@ -113,36 +122,39 @@ uint16_t Sniff14443AAppProcess(uint8_t* Buffer, uint16_t BitCount){ // SELECT: 9 bytes, SEL = 93/95/97, NVB=70 if (TrafficSource == TRAFFIC_READER && - BitCount == 9*8 && - (Buffer[0] & 0xf0) == 0x90 && - (Buffer[0] & 0x09) == 0x01 && - Buffer[1] == 0x70) - { + BitCount == 9 * 8 && + (Buffer[0] & 0xf0) == 0x90 && + (Buffer[0] & 0x09) == 0x01 && + Buffer[1] == 0x70) { SniffState = STATE_SAK; - } else{ + } else { // Not valid, reset reset2REQA(); } break; case STATE_SAK: // SAK: 1Byte SAK + CRC - if(TrafficSource == TRAFFIC_CARD && - BitCount == 3*9 && - checkParityBits(Buffer, BitCount)) - { - if((Buffer[0] & 0x04) == 0x00){ + if (TrafficSource == TRAFFIC_CARD && + BitCount == 3 * 9 && + checkParityBits(Buffer, BitCount)) { + if ((Buffer[0] & 0x04) == 0x00) { // UID complete, success SELECTED, - // TODO: Mark the current threshold as success and continue + // Mark the current threshold as ok and finish // reset SniffState = STATE_REQA; - selected = true; - LED_PORT.OUTCLR = LED_RED; + LED_PORT.OUTSET = LED_RED; + Thresholds[(tmp_th - CODEC_THRESHOLD_CALIBRATE_MIN) / CODEC_THRESHOLD_CALIBRATE_STEPS] += 1; + CommandLinePendingTaskFinished(COMMAND_INFO_OK_WITH_TEXT_ID, NULL); + char tmpBuf[10]; + snprintf(tmpBuf, 10, "%4" PRIu16 ": ", tmp_th); + TerminalSendString(tmpBuf); + Sniff14443AAppReset(); } else { // UID not complete, goto ANTICOLLI SniffState = STATE_ANTICOLLI; } - } else{ + } else { reset2REQA(); } break; @@ -150,7 +162,7 @@ uint16_t Sniff14443AAppProcess(uint8_t* Buffer, uint16_t BitCount){ break; } break; - + } default: return 0; } diff --git a/Firmware/Chameleon-Mini/Codec/SniffISO14443-2A.c b/Firmware/Chameleon-Mini/Codec/SniffISO14443-2A.c index b58cc16..628eead 100644 --- a/Firmware/Chameleon-Mini/Codec/SniffISO14443-2A.c +++ b/Firmware/Chameleon-Mini/Codec/SniffISO14443-2A.c @@ -281,8 +281,6 @@ INLINE void CardSniffInit(void) * bit halves had modulations since the last pause. */ - DACB.CH0DATA = GlobalSettings.ActiveSettingPtr->ReaderThreshold; // real threshold voltage can be calculated with ch0data * Vref / 0xFFF - // Comparator ADC /* Configure and enable the analog comparator for finding pauses in the DEMOD signal. */ ACA.AC0CTRL = AC_HSMODE_bm | AC_HYSMODE_NO_gc | AC_INTMODE_FALLING_gc | AC_ENABLE_bm;