From 5b7a3102608e452474775d204257b1b522b819cf Mon Sep 17 00:00:00 2001 From: henryk Date: Thu, 29 Nov 2007 20:34:20 +0000 Subject: Move to prefilling the transmit buffer for faster ATQA response git-svn-id: https://svn.openpcd.org:2342/trunk@359 6dc7ffe9-61d6-0310-9af1-9938baff3ed1 --- openpicc/application/iso14443_layer3a.c | 82 ++++++++++++++++++++------------- openpicc/application/ssc_picc.h | 4 +- 2 files changed, 53 insertions(+), 33 deletions(-) diff --git a/openpicc/application/iso14443_layer3a.c b/openpicc/application/iso14443_layer3a.c index de928ea..9150f1f 100644 --- a/openpicc/application/iso14443_layer3a.c +++ b/openpicc/application/iso14443_layer3a.c @@ -77,38 +77,58 @@ void __ramfunc iso14443_layer3a_irq_ext(u_int32_t ssc_sr, enum ssc_mode ssc_mode tc_fdt_set(ISO14443A_FDT_SHORT_0); if(state == IDLE) send_atqa = 1; - /* FIXME: prepare and configure ATQA response */ } else if(sample == WUPA) { tc_fdt_set(ISO14443A_FDT_SHORT_1); if(state == IDLE || state == HALT) send_atqa = 1; - /* FIXME: prepare and configure ATQA response */ } if(send_atqa) { vLedSetGreen(0); - if(ssc_tx_buffer.state == FREE) { + if(ssc_tx_buffer.state == PREFILLED && ssc_tx_buffer.source == &ATQA_FRAME) { ssc_tx_buffer.state = PROCESSING; - ssc_tx_buffer.len = sizeof(ssc_tx_buffer.data); - int ret = manchester_encode(ssc_tx_buffer.data, - ssc_tx_buffer.len, - &ATQA_FRAME); - if(ret>0) { - vLedSetGreen(1); - ssc_tx_buffer.len = ret; - tc_cdiv_set_divider(8); - ssc_tx_start(&ssc_tx_buffer); - vLedSetGreen(0); - - } else { - ssc_tx_buffer.state = FREE; - } + vLedSetGreen(1); + tc_cdiv_set_divider(8); + ssc_tx_start(&ssc_tx_buffer); + vLedSetGreen(0); } vLedSetGreen(1); } } } +#define FALSE (0!=0) +static int prefill_buffer(ssc_dma_tx_buffer_t *dest, const iso14443_frame *src) { + portENTER_CRITICAL(); + if(dest->state == FREE) { + dest->state = PROCESSING; + portEXIT_CRITICAL(); + dest->source = (void*)src; + dest->len = sizeof(ssc_tx_buffer.data); + int ret = manchester_encode(dest->data, + dest->len, + &ATQA_FRAME); + if(ret>0) { + dest->len = ret; + portENTER_CRITICAL(); + dest->state = PREFILLED; + portEXIT_CRITICAL(); + } else { + portENTER_CRITICAL(); + dest->state = FREE; + portEXIT_CRITICAL(); + } + return ret > 0; + } else if(dest->state == PREFILLED) { + portEXIT_CRITICAL(); + return dest->source == src; + } else { + portEXIT_CRITICAL(); + return FALSE; + } + +} + extern void main_help_print_buffer(ssc_dma_rx_buffer_t *buffer, int *pktcount); void iso14443_layer3a_state_machine (void *pvParameters) { @@ -172,15 +192,8 @@ void iso14443_layer3a_state_machine (void *pvParameters) #endif tc_fdt_init(); ssc_set_irq_extension((ssc_irq_ext_t)iso14443_layer3a_irq_ext); -#if 1 - ssc_tx_init(); -#else - AT91F_PIO_CfgInput(AT91C_BASE_PIOA, OPENPICC_MOD_PWM); - AT91F_PIO_CfgPeriph(AT91C_BASE_PIOA, OPENPICC_MOD_SSC | - OPENPICC_SSC_DATA | OPENPICC_SSC_DATA | - AT91C_PIO_PA15, 0); -#endif ssc_rx_init(); + ssc_tx_init(); load_mod_init(); load_mod_level(3); @@ -190,13 +203,18 @@ void iso14443_layer3a_state_machine (void *pvParameters) break; case POWERED_OFF: if(switch_on == 1) { - state=INITIAL_STATE; - if(INITIAL_STATE == IDLE) - ssc_rx_mode_set(SSC_MODE_14443A_SHORT); - else if(INITIAL_STATE == ACTIVE) - ssc_rx_mode_set(SSC_MODE_14443A_STANDARD); - else ssc_rx_mode_set(SSC_MODE_NONE); - ssc_rx_start(); + if(prefill_buffer(&ssc_tx_buffer, &ATQA_FRAME)) { + state=INITIAL_STATE; + if(INITIAL_STATE == IDLE) + ssc_rx_mode_set(SSC_MODE_14443A_SHORT); + else if(INITIAL_STATE == ACTIVE) + ssc_rx_mode_set(SSC_MODE_14443A_STANDARD); + else ssc_rx_mode_set(SSC_MODE_NONE); + ssc_rx_start(); + } else { + LAYER3_DEBUG("SSC TX overflow error, please debug"); + state=ERROR; + } continue; } break; diff --git a/openpicc/application/ssc_picc.h b/openpicc/application/ssc_picc.h index 9ba7ec8..671de7c 100644 --- a/openpicc/application/ssc_picc.h +++ b/openpicc/application/ssc_picc.h @@ -47,7 +47,8 @@ typedef enum { FREE=0, /* Buffer is free */ PENDING, /* Buffer has been given to the DMA controller and is currently being filled */ FULL, /* DMA controller signalled that the buffer is full */ - PROCESSING /* The buffer is currently processed by the consumer (e.g. decoder) */ + PROCESSING,/* The buffer is currently processed by the consumer (e.g. decoder) */ + PREFILLED, /* The buffer has been prefilled for later usage (only used for TX) */ } ssc_dma_buffer_state_t; typedef struct { @@ -65,6 +66,7 @@ extern xQueueHandle ssc_rx_queue; typedef struct { volatile ssc_dma_buffer_state_t state; u_int32_t len; /* Length of the content */ + void *source; /* Source pointer for a prefilled buffer; set to NULL if not used */ u_int8_t data[SSC_TX_BUFFER_SIZE]; } ssc_dma_tx_buffer_t; -- cgit v1.2.3