Start reader sniffing right after card sniffing finished.

This fix the bug that the sniffing get wrong data when the time gap between card signal and reader signal is too small

(cherry picked from commit 573cb49)
This commit is contained in:
chenzitai
2018-08-15 22:48:22 +01:00
parent 7af4cc5ee1
commit 396cc21be1
2 changed files with 85 additions and 37 deletions
+1 -1
View File
@@ -96,7 +96,7 @@
#define Codec8Reg2 GPIOR2
#define Codec8Reg3 GPIOR3
#define CodecCount16Register1 (*((volatile uint16_t*) &GPIOR4)) /* GPIOR4 & GPIOR5 */
#define CodecCount16Register2 (*((volatile uint16_t*) &GPIOR6)) /* GPIOR4 & GPIOR5 */
#define CodecCount16Register2 (*((volatile uint16_t*) &GPIOR6)) /* GPIOR6 & GPIOR7 */
#define CodecPtrRegister1 (*((volatile uint8_t**) &GPIOR8))
#define CodecPtrRegister2 (*((volatile uint8_t**) &GPIORA))
#define CodecPtrRegister3 (*((volatile uint8_t**) &GPIORC))
@@ -43,6 +43,7 @@ enum RCTraffic TrafficSource;
static volatile struct {
volatile bool DemodFinished;
volatile bool RxDone;
volatile bool CardStarted; // If card have send the first bit
} Flags = { 0 };
static volatile uint16_t RxPendingSince;
@@ -52,7 +53,8 @@ typedef enum {
DEMOD_PARITY_BIT,
} StateType;
uint16_t DemodBitCount;
uint16_t ReaderBitCount;
uint16_t CardBitCount;
INLINE void CardSniffInit(void);
INLINE void CardSniffDeinit(void);
@@ -63,8 +65,8 @@ INLINE void CardSniffDeinit(void);
INLINE void ReaderSniffInit(void)
{
// PORTE.OUTSET = PIN3_bm;
LED_PORT.OUTCLR = LED_RED;
// Configure interrupt for demod
CODEC_DEMOD_IN_PORT.INTCTRL = PORT_INT1LVL_HI_gc;
@@ -95,6 +97,8 @@ INLINE void ReaderSniffInit(void)
}
INLINE void ReaderSniffDeInit(void)
{
// PORTE.OUTCLR = PIN3_bm;
/* Gracefully shutdown codec */
CODEC_DEMOD_IN_PORT.INT1MASK = 0;
CODEC_DEMOD_IN_PORT.INTCTRL = 0;
@@ -147,6 +151,8 @@ ISR(CODEC_TIMER_SAMPLING_CCD_VECT) {
// Shutdown the Reader->Card Sniffing,
// disable the sampling timer
PORTE.OUTSET = PIN3_bm;
CODEC_TIMER_SAMPLING.CTRLA = TC_CLKSEL_OFF_gc;
CODEC_TIMER_SAMPLING.INTFLAGS = TC0_CCDIF_bm;
CODEC_TIMER_SAMPLING.INTCTRLB = TC_CCDINTLVL_OFF_gc;
@@ -172,11 +178,18 @@ ISR(CODEC_TIMER_SAMPLING_CCD_VECT) {
/* Signal, that we have finished sampling */
Flags.DemodFinished = 1;
DemodBitCount = BitCount;
ReaderBitCount = BitCount;
// If we are have got data
// Start Card->Reader Sniffing without waiting for the complete of CodecTask
// Otherwise some bit will not be captured
CardSniffInit();
if (ReaderBitCount >= ISO14443A_MIN_BITS_PER_FRAME) {
CardSniffInit();
} else{
ReaderSniffInit();
}
PORTE.OUTCLR = PIN3_bm;
return;
}
@@ -249,6 +262,10 @@ ISR(CODEC_TIMER_SAMPLING_CCD_VECT) {
INLINE void CardSniffInit(void)
{
LED_PORT.OUTSET = LED_RED;
PORTE.OUTSET = PIN2_bm;
/* Initialize common peripherals and start listening
* for incoming data. */
@@ -268,6 +285,8 @@ 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;
@@ -301,14 +320,16 @@ INLINE void CardSniffInit(void)
ACA.AC0CTRL = AC_HSMODE_bm | AC_HYSMODE_NO_gc | AC_INTMODE_FALLING_gc | AC_INTLVL_HI_gc | AC_ENABLE_bm;
RxPendingSince = SystemGetSysTick();
PORTE.OUTSET = PIN3_bm;
Flags.CardStarted = false;
}
INLINE void CardSniffDeinit(void)
{
PORTE.OUTCLR = PIN3_bm;
PORTE.OUTCLR = PIN2_bm;
LED_PORT.OUTCLR = LED_RED;
CODEC_TIMER_LOADMOD.CTRLA = 0;
CODEC_TIMER_LOADMOD.INTCTRLB = 0;
@@ -320,7 +341,8 @@ INLINE void CardSniffDeinit(void)
ACA.AC0MUXCTRL = AC_MUXPOS_DAC_gc | AC_MUXNEG_PIN7_gc;
ACA.AC0CTRL = CODEC_AC_DEMOD_SETTINGS;
Flags.RxDone = false;
// Flags.RxDone = false;
// Flags.CardStarted = false;
}
@@ -341,6 +363,22 @@ INLINE void Insert1(void)
*CardBufferPtr++ = CardSampleR;
}
INLINE void TaskInsert0(void)
{
CardSampleR >>= 1;
if (++CardBitCount % 8)
return;
*CardBufferPtr++ = CardSampleR;
}
INLINE void TaskInsert1(void)
{
CardSampleR = (CardSampleR >> 1) | 0x80;
if (++CardBitCount % 8)
return;
*CardBufferPtr++ = CardSampleR;
}
// This interrupt find Card -> Reader SOC
ISR(ACA_AC0_vect) // this interrupt either finds the SOC or gets triggered before
{
@@ -348,7 +386,7 @@ ISR(ACA_AC0_vect) // this interrupt either finds the SOC or gets triggered befor
// enable the pause-finding timer
CODEC_TIMER_LOADMOD.CTRLD = TC_EVACT_RESTART_gc | TC_EVSEL_CH2_gc;
CODEC_TIMER_LOADMOD.CTRLA = TC_CLKSEL_DIV1_gc;
Flags.CardStarted = true;
}
// Decode the Card -> Reader signal
// according to the pause and modulated period
@@ -414,7 +452,13 @@ ISR(CODEC_TIMER_TIMESTAMPS_CCB_VECT) // EOC found
if (BitCount % 8) // copy the last byte, if there is an incomplete byte
CodecBuffer2[BitCount / 8] = CardSampleR >> (8 - (BitCount % 8));
CardBitCount = BitCount;
Flags.RxDone = true;
Flags.CardStarted = false;
CardSniffDeinit();
ReaderSniffInit();
}
@@ -424,7 +468,7 @@ ISR(CODEC_TIMER_TIMESTAMPS_CCB_VECT) // EOC found
void Sniff14443ACodecInit(void)
{
PORTE.DIRSET= PIN3_bm;
PORTE.DIRSET= PIN3_bm | PIN2_bm;
// Common Codec Register settings
CodecInitCommon();
// Enable demodulator power
@@ -433,6 +477,7 @@ void Sniff14443ACodecInit(void)
// Start with sniffing Reader->Card direction traffic
TrafficSource = TRAFFIC_READER;
ReaderSniffInit();
Flags.RxDone = false;
}
@@ -453,15 +498,15 @@ void Sniff14443ACodecTask(void)
Flags.DemodFinished = 0;
/* Reception finished. Process the received bytes */
if (DemodBitCount >= ISO14443A_MIN_BITS_PER_FRAME) {
LEDHook(LED_CODEC_RX, LED_PULSE);
if (ReaderBitCount >= ISO14443A_MIN_BITS_PER_FRAME) {
// LEDHook(LED_CODEC_RX, LED_PULSE);
TrafficSource = TRAFFIC_CARD;
return;
}
// Get nothing, Start sniff again
TrafficSource = TRAFFIC_READER;
ReaderSniffInit();
// ReaderSniffInit();
}
}
// Card->Reader Task
@@ -469,19 +514,19 @@ void Sniff14443ACodecTask(void)
{
// Receive finished
if (Flags.RxDone) {
if (Flags.RxDone && BitCount > 0) // decode the raw received data
if (Flags.RxDone && CardBitCount > 0) // decode the raw received data
{
if (BitCount < ISO14443A_RX_MINIMUM_BITCOUNT * 2) {
BitCount = 0;
if (CardBitCount < ISO14443A_RX_MINIMUM_BITCOUNT * 2) {
CardBitCount = 0;
}
else {
uint8_t TmpCodecBuffer[CODEC_BUFFER_SIZE];
memcpy(TmpCodecBuffer, CodecBuffer2, (BitCount + 7) / 8);
memcpy(TmpCodecBuffer, CodecBuffer2, (CardBitCount + 7) / 8);
CardBufferPtr = CodecBuffer2;
uint16_t BitCountTmp = 2, TotalBitCount = BitCount;
BitCount = 0;
uint16_t BitCountTmp = 2, TotalBitCount = CardBitCount;
CardBitCount = 0;
bool breakflag = false;
TmpCodecBuffer[0] >>= 2; // with this (and BitCountTmp = 2), the SOC is ignored
@@ -492,11 +537,11 @@ void Sniff14443ACodecTask(void)
TmpCodecBuffer[BitCountTmp / 8] >>= 2;
switch (Bit) {
case 0b10:
Insert1();
TaskInsert1();
break;
case 0b01:
Insert0();
TaskInsert0();
break;
case 0b00: // EOC
@@ -509,40 +554,43 @@ void Sniff14443ACodecTask(void)
}
BitCountTmp += 2;
}
if (BitCount % 8) // copy the last byte, if there is an incomplete byte
CodecBuffer2[BitCount / 8] = CardSampleR >> (8 - (BitCount % 8));
if (CardBitCount % 8) // copy the last byte, if there is an incomplete byte
CodecBuffer2[CardBitCount / 8] = CardSampleR >> (8 - (CardBitCount % 8));
// BitCount = removeParityBits(CodecBuffer, BitCount);
LEDHook(LED_CODEC_RX, LED_PULSE);
// BitCount = removeParityBits(CodecBuffer, CardBitCount);
// LEDHook(LED_CODEC_RX, LED_PULSE);
// Print log after a round finished
// Otherwise it will take too much cpu cycles
// then the card traffic sniffing may not start in time
LogEntry(LOG_INFO_CODEC_SNI_READER_DATA, CodecBuffer, (DemodBitCount+7)/8);
LogEntry(LOG_INFO_CODEC_SNI_CARD_DATA_W_PARITY, CodecBuffer2, (BitCount + 7) / 8);
LogEntry(LOG_INFO_CODEC_SNI_READER_DATA, CodecBuffer, (ReaderBitCount+7)/8);
LogEntry(LOG_INFO_CODEC_SNI_CARD_DATA_W_PARITY, CodecBuffer2, (CardBitCount + 7) / 8);
// Disable card sniffing and enable reader sniffing
CardSniffDeinit();
TrafficSource = TRAFFIC_READER;
ReaderSniffInit();
return;
// return;
}
}
// Once Rx Finished, Switch to Reader sniffing,
// No matter if getting data or not
// CardSniffDeinit();
// Disable card sniffing and enable reader sniffing
TrafficSource = TRAFFIC_READER;
// ReaderSniffInit();
Flags.RxDone = false;
/* Call application with received data */
BitCount = ApplicationProcess(CodecBuffer2, BitCount);
CardBitCount = ApplicationProcess(CodecBuffer2, CardBitCount);
}
else // Receive not finished yet, Continue waiting
{
// If Waiting for response time out
// Reset to reader sniffing
if ((SYSTICK_DIFF(RxPendingSince) > Reader_FWT + 1) ) {
Flags.RxDone = true;
if ((SYSTICK_DIFF(RxPendingSince) > Reader_FWT) && !Flags.CardStarted) {
Flags.RxDone = false;
// If Card sniffing started but no data get
// Then the codec must have sniffed some reader raffic
LogEntry(LOG_INFO_CODEC_SNI_READER_DATA, CodecBuffer, (DemodBitCount+7)/8);
LogEntry(LOG_INFO_CODEC_SNI_READER_DATA, CodecBuffer, (ReaderBitCount+7)/8);
// Disable card sniffing and enable reader sniffing
CardSniffDeinit();
TrafficSource = TRAFFIC_READER;