From e2e37bea66206adefbb2fc97fcbfb71c1a3cfbe7 Mon Sep 17 00:00:00 2001 From: henryk Date: Fri, 14 Mar 2008 04:55:15 +0000 Subject: Add T/C based receiver code with integrated miller decoder Integrate T/C receiver into iso14443 layer 2a Add state field to iso14443_frame, rename ssc buffer state constants Sniffer seems to work with the new code git-svn-id: https://svn.openpcd.org:2342/trunk@452 6dc7ffe9-61d6-0310-9af1-9938baff3ed1 --- openpicc/application/iso14443_layer2a.c | 71 +++++++++++++++++++-------------- 1 file changed, 41 insertions(+), 30 deletions(-) (limited to 'openpicc/application/iso14443_layer2a.c') diff --git a/openpicc/application/iso14443_layer2a.c b/openpicc/application/iso14443_layer2a.c index 91df6b9..65d5d6a 100644 --- a/openpicc/application/iso14443_layer2a.c +++ b/openpicc/application/iso14443_layer2a.c @@ -44,6 +44,7 @@ #include "tc_fdt.h" #include "tc_cdiv.h" #include "tc_cdiv_sync.h" +#include "tc_recv.h" #include "load_modulation.h" #include "clock_switch.h" #include "pio_irq.h" @@ -58,6 +59,7 @@ static u_int8_t tx_pending=0; static u_int8_t rx_pending=0; static iso14443_receive_callback_t callback=NULL; static ssc_handle_t *ssc; +static tc_recv_handle_t th; #ifdef FOUR_TIMES_OVERSAMPLING #define RX_DIVIDER 32 @@ -65,10 +67,9 @@ static ssc_handle_t *ssc; #define RX_DIVIDER 64 #endif -int iso14443_receive(iso14443_receive_callback_t _callback, ssc_dma_rx_buffer_t **buffer, unsigned int timeout) +int iso14443_receive(iso14443_receive_callback_t _callback, iso14443_frame **frame, unsigned int timeout) { - ssc_dma_rx_buffer_t* _buffer = NULL; - int len; + iso14443_frame* _frame = NULL; if(rx_pending) { return -EALREADY; @@ -76,9 +77,9 @@ int iso14443_receive(iso14443_receive_callback_t _callback, ssc_dma_rx_buffer_t rx_pending=1; callback=_callback; - if(ssc_recv(ssc, &_buffer, timeout) == 0) { + if(tc_recv_receive(th, &_frame, timeout) == 0) { - if(_buffer == NULL) { + if(_frame == NULL) { /* Can this happen? */ rx_pending=0; callback=NULL; @@ -86,25 +87,23 @@ int iso14443_receive(iso14443_receive_callback_t _callback, ssc_dma_rx_buffer_t } portENTER_CRITICAL(); - _buffer->state = PROCESSING; + _frame->state = FRAME_PROCESSING; portEXIT_CRITICAL(); - len = _buffer->len_transfers; - if(callback != NULL && !fast_receive) { - callback(_buffer, 0); + callback(NULL, _frame, 0); } - if(buffer != NULL) *buffer = _buffer; + if(frame != NULL) *frame = _frame; else { portENTER_CRITICAL(); - _buffer->state = FREE; + _frame->state = FRAME_FREE; portEXIT_CRITICAL(); } rx_pending=0; callback=NULL; - return len; + return 0; } /* Note: There is the remote chance of a race condition probability here if @@ -185,7 +184,7 @@ u_int8_t iso14443_get_fast_receive(void) static void iso14443_ssc_callback(ssc_callback_reason reason, void *data) { - if(reason == CALLBACK_RX_FRAME_BEGIN) { + if(reason == SSC_CALLBACK_RX_FRAME_BEGIN) { /* Busy loop for the frame end */ int *end_asserted = data, i=0; for(i=0; i<96000; i++) @@ -197,20 +196,20 @@ static void iso14443_ssc_callback(ssc_callback_reason reason, void *data) return; } - if(reason == CALLBACK_TX_FRAME_ENDED) { + if(reason == SSC_CALLBACK_TX_FRAME_ENDED) { tx_pending = 0; } - if( reason == CALLBACK_RX_FRAME_ENDED && fast_receive ) { + if( reason == SSC_CALLBACK_RX_FRAME_ENDED && fast_receive ) { clock_switch(CLOCK_SELECT_CARRIER); /* A Tx might be coming up */ ssc_dma_rx_buffer_t *buffer = data; if(callback != NULL) - callback(buffer, 1); + callback(buffer, NULL, 1); } - if( (reason == CALLBACK_RX_FRAME_ENDED && !tx_pending) || reason == CALLBACK_RX_STARTING - || reason == CALLBACK_TX_FRAME_ENDED ) { + if( (reason == SSC_CALLBACK_RX_FRAME_ENDED && !tx_pending) || reason == SSC_CALLBACK_RX_STARTING + || reason == SSC_CALLBACK_TX_FRAME_ENDED ) { /* For regular SSC Rx we'd set the clock to // clock_switch(CLOCK_SELECT_PLL); * however, the SSC Rx code is going to go away (at least for 14443-A) @@ -226,16 +225,27 @@ static void iso14443_ssc_callback(ssc_callback_reason reason, void *data) usb_print_set_default_flush(old); #endif } - } -static portBASE_TYPE iso14443_rx_FRAME_cb(u_int32_t pio, portBASE_TYPE xTaskWoken) +static void iso14443_tc_recv_callback(tc_recv_callback_reason reason, void *data) { - (void)pio; - if(PRINT_DEBUG) usb_print_string_f("°", 0); // DEBUG OUTPUT - if(AT91F_PIO_IsInputSet(AT91C_BASE_PIOA, OPENPICC_PIO_FRAME)) - ssc_frame_started(); - return xTaskWoken; + if( reason == TC_RECV_CALLBACK_RX_FRAME_ENDED && fast_receive ) { + clock_switch(CLOCK_SELECT_CARRIER); /* A Tx might be coming up */ + + iso14443_frame *frame = data; + if(callback != NULL) + callback(NULL, frame, 1); + } + + if( (reason == TC_RECV_CALLBACK_RX_FRAME_ENDED && !tx_pending) || + reason == TC_RECV_CALLBACK_SETUP ) { + /* For T/C Rx we set the clock to */ + clock_switch(CLOCK_SELECT_CARRIER); + ssc_set_gate(1); + tc_fdt_set(0xff00); + tc_cdiv_set_divider(RX_DIVIDER); + tc_cdiv_sync_reset(); + } } int iso14443_layer2a_init(u_int8_t enable_fast_receive) @@ -251,14 +261,15 @@ int iso14443_layer2a_init(u_int8_t enable_fast_receive) iso14443_set_fast_receive(enable_fast_receive); pio_irq_init_once(); - if(pio_irq_register(OPENPICC_PIO_FRAME, &iso14443_rx_FRAME_cb) >= 0) { - if(PRINT_DEBUG) usb_print_string("FRAME irq registered\n\r"); // DEBUG OUTPUT - } - - ssc = ssc_open(1, 1, SSC_MODE_14443A, iso14443_ssc_callback); + ssc = ssc_open(0, 1, SSC_MODE_14443A, iso14443_ssc_callback); if(ssc == NULL) return -EIO; + if(tc_recv_init(&th, 0, iso14443_tc_recv_callback) < 0) { + ssc_close(ssc); + return -EIO; + } + load_mod_level(3); return 0; -- cgit v1.2.3