From f7a420f2387b0bb660df08954d4bf35a66937203 Mon Sep 17 00:00:00 2001 From: henryk Date: Fri, 14 Mar 2008 18:29:28 +0000 Subject: Faked anticollision working now. During stress test (OpenPCD reqa firmware in anticol mode performing one cycle every 70ms) there were 52 late frames in 15992. git-svn-id: https://svn.openpcd.org:2342/trunk@454 6dc7ffe9-61d6-0310-9af1-9938baff3ed1 --- openpicc/Makefile | 4 +- openpicc/application/iso14443.h | 1 + openpicc/application/iso14443_layer2a.c | 14 +++++-- openpicc/application/iso14443a_diffmiller.c | 16 ++++++-- openpicc/application/iso14443a_pretender.c | 63 ++++++++++++++++------------- openpicc/application/main.c | 6 +-- openpicc/application/ssc.c | 2 + 7 files changed, 67 insertions(+), 39 deletions(-) (limited to 'openpicc') diff --git a/openpicc/Makefile b/openpicc/Makefile index b4270ab..e11eae5 100644 --- a/openpicc/Makefile +++ b/openpicc/Makefile @@ -110,9 +110,9 @@ ARM_SRC= \ os/core/MemMang/heap_2.c \ os/usb/USB-CDC.c \ os/usb/USBIsr.c \ - application/iso14443_sniffer.c \ + application/iso14443a_pretender.c \ +# application/iso14443_sniffer.c \ # application/tc_sniffer.c \ -# application/iso14443a_pretender.c \ # application/iso14443_layer3a.c # diff --git a/openpicc/application/iso14443.h b/openpicc/application/iso14443.h index a2d7458..e2418ca 100644 --- a/openpicc/application/iso14443.h +++ b/openpicc/application/iso14443.h @@ -80,6 +80,7 @@ typedef enum { FRAME_PENDING, /* Frame is currently filled by Rx */ FRAME_FULL, /* Frame has been filled by Rx */ FRAME_PROCESSING,/* The frame is currently processed by the consumer */ + FRAME_PREFILLED, /* The frame has been prefilled for later usage (only used for TX) */ } iso14443_frame_state_t; diff --git a/openpicc/application/iso14443_layer2a.c b/openpicc/application/iso14443_layer2a.c index 65d5d6a..2288eaa 100644 --- a/openpicc/application/iso14443_layer2a.c +++ b/openpicc/application/iso14443_layer2a.c @@ -132,7 +132,8 @@ int iso14443_transmit(ssc_dma_tx_buffer_t *buffer, unsigned int fdt, u_int8_t as clock_switch(CLOCK_SELECT_CARRIER); ssc_set_gate(0); tc_fdt_set(fdt); - tc_cdiv_set_divider(8); // FIXME Magic hardcoded number + // We'll keep the divider at 8 + //tc_cdiv_set_divider(8); // FIXME Magic hardcoded number if(!async) { /* FIXME Implement */ @@ -184,6 +185,11 @@ u_int8_t iso14443_get_fast_receive(void) static void iso14443_ssc_callback(ssc_callback_reason reason, void *data) { + if( reason == SSC_CALLBACK_SETUP ) { + // We'll keep the divider at 8 + tc_cdiv_set_divider(8); // FIXME Magic hardcoded number + } + if(reason == SSC_CALLBACK_RX_FRAME_BEGIN) { /* Busy loop for the frame end */ int *end_asserted = data, i=0; @@ -217,7 +223,8 @@ static void iso14443_ssc_callback(ssc_callback_reason reason, void *data) clock_switch(CLOCK_SELECT_CARRIER); ssc_set_gate(1); tc_fdt_set(0xff00); - tc_cdiv_set_divider(RX_DIVIDER); + // We'll keep the divider at 8 + //tc_cdiv_set_divider(RX_DIVIDER); tc_cdiv_sync_reset(); #if 1 int old=usb_print_set_default_flush(0); @@ -243,7 +250,8 @@ static void iso14443_tc_recv_callback(tc_recv_callback_reason reason, void *data clock_switch(CLOCK_SELECT_CARRIER); ssc_set_gate(1); tc_fdt_set(0xff00); - tc_cdiv_set_divider(RX_DIVIDER); + // We'll keep the divider at 8 + //tc_cdiv_set_divider(RX_DIVIDER); tc_cdiv_sync_reset(); } } diff --git a/openpicc/application/iso14443a_diffmiller.c b/openpicc/application/iso14443a_diffmiller.c index d73bf95..a36ea6b 100644 --- a/openpicc/application/iso14443a_diffmiller.c +++ b/openpicc/application/iso14443a_diffmiller.c @@ -101,6 +101,7 @@ struct diffmiller_state { u_int32_t counter; u_int16_t byte,crc; u_int8_t parity; + u_int8_t last_data_bit; struct { u_int8_t in_frame:1; u_int8_t frame_finished:1; @@ -155,7 +156,7 @@ static inline void append_to_frame(struct diffmiller_state *const state, } -static inline void end_frame(struct diffmiller_state * const state, const u_int32_t counter) +static inline void end_frame(struct diffmiller_state * const state, const u_int32_t counter, const int last_data_bit) { if(state->frame != NULL) { if(counter > 0) { @@ -167,6 +168,11 @@ static inline void end_frame(struct diffmiller_state * const state, const u_int3 else state->frame->parameters.a.crc = CRC_ERROR; + if(last_data_bit) + state->frame->parameters.a.last_bit = ISO14443A_LAST_BIT_1; + else + state->frame->parameters.a.last_bit = ISO14443A_LAST_BIT_0; + state->flags.frame_finished = 1; } } @@ -175,6 +181,7 @@ static inline void end_frame(struct diffmiller_state * const state, const u_int3 //#define PRINT_BIT(a) usb_print_string_f(a,0) #define DO_BIT_0 { \ + last_data_bit = 0; \ if(++counter==9) { \ append_to_frame(state, state->byte, 0, 8); \ counter=state->byte=state->parity=0; \ @@ -183,6 +190,7 @@ static inline void end_frame(struct diffmiller_state * const state, const u_int3 } #define DO_BIT_1 { \ + last_data_bit = 1; \ if(counter<8) { \ state->byte |= (1<parity ^= 1; \ @@ -218,7 +226,7 @@ static inline void end_frame(struct diffmiller_state * const state, const u_int3 in_frame = 0; \ } else { \ if(last_bit == BIT_0) { \ - end_frame(state, counter); \ + end_frame(state, counter, last_data_bit); \ PRINT_BIT(" EOF\n"); \ last_bit = BIT_EOF; \ in_frame = 0; \ @@ -255,6 +263,7 @@ int iso14443a_decode_diffmiller(struct diffmiller_state * const state, iso14443_ int in_frame = state->flags.in_frame; int error = state->flags.error; int counter = state->counter; + int last_data_bit = state->last_data_bit; for(; *offset < buflen; ) { int delta; @@ -324,6 +333,7 @@ int iso14443a_decode_diffmiller(struct diffmiller_state * const state, iso14443_ state->old_state = old_state; state->last_bit = last_bit; state->counter = counter; + state->last_data_bit = last_data_bit; state->flags.in_frame = in_frame; state->flags.error = error; @@ -338,7 +348,7 @@ int iso14443a_diffmiller_assert_frame_ended(struct diffmiller_state * const stat if(state->frame != NULL && state->frame != frame) return -EINVAL; state->frame = frame; - end_frame(state, state->counter); + end_frame(state, state->counter, state->last_data_bit); PRINT_BIT(" EOF2\n"); state->flags.in_frame = 0; diff --git a/openpicc/application/iso14443a_pretender.c b/openpicc/application/iso14443a_pretender.c index 03fb12d..c6f54cc 100644 --- a/openpicc/application/iso14443a_pretender.c +++ b/openpicc/application/iso14443a_pretender.c @@ -42,6 +42,7 @@ extern volatile int fdt_offset; static const iso14443_frame ATQA_FRAME = { TYPE_A, + FRAME_PREFILLED, {{STANDARD_FRAME, PARITY, ISO14443A_LAST_BIT_NONE, CRC_UNCALCULATED}}, 2, 0, 0, @@ -51,6 +52,7 @@ static const iso14443_frame ATQA_FRAME = { static const iso14443_frame UID_FRAME = { TYPE_A, + FRAME_PREFILLED, {{STANDARD_FRAME, PARITY, ISO14443A_LAST_BIT_NONE, CRC_UNCALCULATED}}, 5, 0, 0, @@ -60,6 +62,7 @@ static const iso14443_frame UID_FRAME = { static const iso14443_frame ATS_FRAME = { TYPE_A, + FRAME_PREFILLED, {{STANDARD_FRAME, PARITY, ISO14443A_LAST_BIT_NONE, CRC_UNCALCULATED}}, 3, 0, 0, @@ -69,6 +72,7 @@ static const iso14443_frame ATS_FRAME = { static const iso14443_frame NONCE_FRAME = { TYPE_A, + FRAME_PREFILLED, {{STANDARD_FRAME, PARITY, ISO14443A_LAST_BIT_NONE, CRC_UNCALCULATED}}, 4, 0, 0, @@ -79,10 +83,11 @@ static const iso14443_frame NONCE_FRAME = { #define FRAME_SIZE(bytes) (2* (1+(9*bytes)+1) ) #define SIZED_BUFFER(bytes) struct { int len; u_int8_t data[FRAME_SIZE(bytes)]; } +#define BYTES_AND_BITS(bytes,bits) (bytes*9+bits) static ssc_dma_tx_buffer_t ATQA_BUFFER, UID_BUFFER, ATS_BUFFER, NONCE_BUFFER; -static void fast_receive_callback(ssc_dma_rx_buffer_t *buffer, u_int8_t in_irq) +static void fast_receive_callback(ssc_dma_rx_buffer_t *buffer, iso14443_frame *frame, u_int8_t in_irq) { (void)buffer; (void)in_irq; unsigned int buffy=0; @@ -91,24 +96,30 @@ static void fast_receive_callback(ssc_dma_rx_buffer_t *buffer, u_int8_t in_irq) ssc_dma_tx_buffer_t *tx_buffer=NULL; int fdt = 0; - switch(buffer->len_transfers) { - case 3: case 4: /* REQA (7 bits) */ - //case 7: case 8: case 9: - case 11: + switch(frame->parameters.a.last_bit) { + case ISO14443A_LAST_BIT_0: + fdt = 20; + break; + case ISO14443A_LAST_BIT_1: + fdt = 84; + break; + case ISO14443A_LAST_BIT_NONE: + fdt = 0; + break; + } + + switch(BYTES_AND_BITS(frame->numbytes,frame->numbits)) { + case BYTES_AND_BITS(0, 7): /* REQA (7 bits) */ tx_buffer = &ATQA_BUFFER; - fdt = 1172; + fdt += 9*128; break; - case 6: case 7: /* ANTICOL (2 bytes) */ - case 8: case 9: + case BYTES_AND_BITS(2, 0): /* ANTICOL (2 bytes) */ tx_buffer = &UID_BUFFER; - fdt = 1172; - case 21: case 22: /* SELECT (9 bytes) */ - tx_buffer = &ATS_BUFFER; - fdt = 1172; + fdt += 9*128; break; - case 577: - usb_print_string_f("f", 0); - buffy=(unsigned int)buffer; + case BYTES_AND_BITS(9, 0): /* SELECT (9 bytes) */ + tx_buffer = &ATS_BUFFER; + fdt += 9*128; break; } @@ -116,7 +127,6 @@ static void fast_receive_callback(ssc_dma_rx_buffer_t *buffer, u_int8_t in_irq) //fdt += 3*128; fdt += fdt_offset; - if(tx_buffer != NULL) { tx_buffer->state = SSC_FULL; if( iso14443_transmit(tx_buffer, fdt, 1, 0) < 0) { @@ -208,28 +218,25 @@ prefill_failed: #define DETECTED_MIFARE 4 while(true) { - ssc_dma_rx_buffer_t *buffer = 0; - res = iso14443_receive(fast_receive_callback, &buffer, 1000 * portTICK_RATE_MS); + iso14443_frame *frame = 0; + res = iso14443_receive(fast_receive_callback, &frame, 1000 * portTICK_RATE_MS); if(res >= 0) { - DumpUIntToUSB(buffer->len_transfers); - DumpStringToUSB("\n\r"); - - switch(buffer->len_transfers) { - case 3: case 4: /* REQA (7 bits) */ + switch(BYTES_AND_BITS(frame->numbytes, frame->numbits) ) { + case BYTES_AND_BITS(0, 7): /* REQA (7 bits) */ current_detected |= DETECTED_14443A_3; break; - case 6: case 7: /* ANTICOL (2 bytes) */ - case 22: /* SELECT (9 bytes) */ + case BYTES_AND_BITS(2, 0): /* ANTICOL (2 bytes) */ + case BYTES_AND_BITS(9, 0): /* SELECT (9 bytes) */ current_detected |= DETECTED_14443A_3; break; - case 10: case 11: /* AUTH1A (or any other four byte frame) */ - case 19: case 20: /* AUTH2 (8 bytes) */ + case BYTES_AND_BITS(4, 0): /* AUTH1A (or any other four byte frame) */ + case BYTES_AND_BITS(8, 0): /* AUTH2 (8 bytes) */ current_detected |= DETECTED_MIFARE; break; } portENTER_CRITICAL(); - buffer->state = SSC_FREE; + frame->state = FRAME_FREE; portEXIT_CRITICAL(); } else { if(res != -ETIMEDOUT) { diff --git a/openpicc/application/main.c b/openpicc/application/main.c index a082933..d9b0ad5 100644 --- a/openpicc/application/main.c +++ b/openpicc/application/main.c @@ -211,10 +211,10 @@ int main (void) NULL, TASK_USB_PRIORITY, NULL); /*xTaskCreate (iso14443_layer3a_state_machine, (signed portCHAR *) "ISO14443A-3", TASK_ISO_STACK, NULL, TASK_ISO_PRIORITY, NULL);*/ - xTaskCreate (iso14443_sniffer, (signed portCHAR *) "ISO14443-SNIFF", TASK_ISO_STACK, - NULL, TASK_ISO_PRIORITY, NULL); - /*xTaskCreate (iso14443a_pretender, (signed portCHAR *) "ISO14443A-PRETEND", TASK_ISO_STACK, + /*xTaskCreate (iso14443_sniffer, (signed portCHAR *) "ISO14443-SNIFF", TASK_ISO_STACK, NULL, TASK_ISO_PRIORITY, NULL);*/ + xTaskCreate (iso14443a_pretender, (signed portCHAR *) "ISO14443A-PRETEND", TASK_ISO_STACK, + NULL, TASK_ISO_PRIORITY, NULL); /*xTaskCreate (tc_sniffer, (signed portCHAR *) "RFID-SNIFFER", TASK_ISO_STACK, NULL, TASK_ISO_PRIORITY, NULL);*/ diff --git a/openpicc/application/ssc.c b/openpicc/application/ssc.c index 9f30400..78f2960 100644 --- a/openpicc/application/ssc.c +++ b/openpicc/application/ssc.c @@ -234,7 +234,9 @@ static int __ramfunc _ssc_tx_irq(u_int32_t sr, portBASE_TYPE task_woken) /* Also set SSC mode to continous * FIXME BUG: This will somehow drop some samples or something on the SSC*/ + vLedSetGreen(0); sh->ssc->SSC_TCMR = (sh->ssc->SSC_TCMR & ~AT91C_SSC_START) | AT91C_SSC_START_CONTINOUS; + vLedSetGreen(1); if(sh->callback) sh->callback(SSC_CALLBACK_TX_FRAME_BEGIN, NULL); -- cgit v1.2.3