From f89811486cda3de0a28fbad1d9726d8c20a9b155 Mon Sep 17 00:00:00 2001 From: henryk Date: Wed, 19 Dec 2007 02:08:16 +0000 Subject: Play with transfer sizes Enhance timing by removing debugging code Pending rewrite of SSC RX IRQ code git-svn-id: https://svn.openpcd.org:2342/trunk@397 6dc7ffe9-61d6-0310-9af1-9938baff3ed1 --- openpicc/application/iso14443_layer3a.c | 51 ++++++++++++++++++++++++++++----- openpicc/application/iso14443_layer3a.h | 14 ++++++++- openpicc/application/ssc_picc.c | 13 +++++++-- 3 files changed, 68 insertions(+), 10 deletions(-) (limited to 'openpicc') diff --git a/openpicc/application/iso14443_layer3a.c b/openpicc/application/iso14443_layer3a.c index af0fc69..c1f7bce 100644 --- a/openpicc/application/iso14443_layer3a.c +++ b/openpicc/application/iso14443_layer3a.c @@ -61,6 +61,8 @@ const iso14443_frame NULL_FRAME = { {} }; +const u_int8_t ISO14443A_SHORT_FRAME_REQA[ISO14443A_SHORT_FRAME_COMPARE_LENGTH] = _ISO14443A_SHORT_FRAME_REQA; +const u_int8_t ISO14443A_SHORT_FRAME_WUPA[ISO14443A_SHORT_FRAME_COMPARE_LENGTH] = _ISO14443A_SHORT_FRAME_WUPA; #define PLL_LOCK_HYSTERESIS portTICK_RATE_MS*5 @@ -106,6 +108,28 @@ void iso14443_transmit(ssc_dma_tx_buffer_t *buf, int fdt, int div) ssc_tx_start(buf); } +static void _is_reqa_or_wupa(enum ssc_mode ssc_mode, u_int8_t* samples, int *is_reqa, int *is_wupa) +{ + if(ssc_mode == SSC_MODE_14443A_SHORT) { + *is_reqa = *is_wupa = 0; + ISO14443A_SHORT_TYPE sample = *(ISO14443A_SHORT_TYPE*)samples; + if(sample == REQA) { + *is_reqa = 1; + } else if(sample == WUPA) { + *is_wupa = 1; + } + } else if(ssc_mode == SSC_MODE_14443A) { + int i; + *is_reqa = *is_wupa = 1; + for(i=0; idata, (buffer->len_transfers * buffer->reception_mode->transfersize_pdc)/8); DumpStringToUSB(" Decoded: "); + vLedBlinkGreen(); + vLedSetGreen(1); iso14443a_decode_miller(&received_frame, buffer); + vLedBlinkGreen(); + vLedSetGreen(0); DumpBufferToUSB((char*)received_frame.data, received_frame.numbytes + (received_frame.numbits+7)/8); DumpStringToUSB(" "); DumpUIntToUSB(received_frame.parameters.a.last_bit); @@ -324,13 +354,16 @@ void iso14443_layer3a_state_machine (void *pvParameters) usb_print_set_default_flush(i); } + int is_reqa=0, is_wupa=0; switch(state) { case IDLE: case HALT: - if(first_sample == WUPA || (state==IDLE && first_sample==REQA)) { + if(buffer->data) _is_reqa_or_wupa(buffer->reception_mode->mode, buffer->data, &is_reqa, &is_wupa); + + if(is_wupa || (state==IDLE && is_reqa)) { /* Need to transmit ATQA */ LAYER3_DEBUG("Received "); - LAYER3_DEBUG(first_sample == WUPA ? "WUPA" : "REQA"); + LAYER3_DEBUG(is_wupa ? "WUPA" : "REQA"); if(atqa_sent) { LAYER3_DEBUG(", woke up to send ATQA\n\r"); atqa_sent = 0; @@ -358,7 +391,11 @@ void iso14443_layer3a_state_machine (void *pvParameters) if(prefill_buffer(&ssc_tx_buffer, &NULL_FRAME)) { usb_print_string_f("Sending response ...",0); ssc_tx_buffer.state = PROCESSING; - iso14443_transmit(&ssc_tx_buffer, ISO14443A_TRANSMIT_AT_NEXT_INTERVAL_1, 8); + iso14443_transmit(&ssc_tx_buffer, + received_frame.parameters.a.last_bit==ISO14443A_LAST_BIT_0 ? + ISO14443A_TRANSMIT_AT_NEXT_INTERVAL_0 : + ISO14443A_TRANSMIT_AT_NEXT_INTERVAL_1, + 8); while( ssc_tx_buffer.state != FREE ) { vTaskDelay(portTICK_RATE_MS); } diff --git a/openpicc/application/iso14443_layer3a.h b/openpicc/application/iso14443_layer3a.h index 8925249..42a37bc 100644 --- a/openpicc/application/iso14443_layer3a.h +++ b/openpicc/application/iso14443_layer3a.h @@ -42,18 +42,30 @@ enum ISO14443_STATES { /* definitions for two-times oversampling */ #define ISO14443A_SAMPLE_LEN 2 +/* For SSC_MODE_ISO14443A_SHORT */ +#define ISO14443A_SHORT_LEN 18 #define REQA 0x4929 #define WUPA 0x2249 #define ISO14443A_SOF_SAMPLE 0x01 #define ISO14443A_SOF_LEN 2 -#define ISO14443A_SHORT_LEN 18 #define ISO14443A_EOF_SAMPLE 0x00 #define ISO14443A_EOF_LEN 5 +/* For SSC_MODE_ISO14443A */ +#define ISO14443A_SHORT_FRAME_COMPARE_LENGTH 2 +#define _ISO14443A_SHORT_FRAME_REQA { 0x29, 0x49 } +#define _ISO14443A_SHORT_FRAME_WUPA { 0x49, 0x22 } +// FIXME not correct. This should be compare_length == 3 (which is 9 at 4 per compare), but this +// needs enhanced ssc irq code to transfer the last read (incomplete) data from the ssc holding +// register to the buffer + #endif +extern const u_int8_t ISO14443A_SHORT_FRAME_REQA[ISO14443A_SHORT_FRAME_COMPARE_LENGTH]; +extern const u_int8_t ISO14443A_SHORT_FRAME_WUPA[ISO14443A_SHORT_FRAME_COMPARE_LENGTH]; + /* A short frame should be received in one single SSC transfer */ #if (ISO14443A_SHORT_LEN <= 8) /* SSC transfer size in bits */ diff --git a/openpicc/application/ssc_picc.c b/openpicc/application/ssc_picc.c index e5d2085..79df04e 100644 --- a/openpicc/application/ssc_picc.c +++ b/openpicc/application/ssc_picc.c @@ -56,6 +56,7 @@ #define DEBUGR(x, args ...) #endif +#define DEBUG_LOAD_AND_UNLOAD 0 static const AT91PS_SSC ssc = AT91C_BASE_SSC; static AT91PS_PDC rx_pdc; @@ -79,7 +80,10 @@ static const ssc_mode_def ssc_sizes[] = { /* 14443A Standard Frame: FIXME 16 transfers of 32 bits (maximum number), resulting in 512 samples */ [SSC_MODE_14443A_STANDARD] = {SSC_MODE_14443A_STANDARD, 32, 32, 16}, /* 14443A Frame, don't care if standard or short */ - [SSC_MODE_14443A] = {SSC_MODE_14443A, ISO14443A_SAMPLE_LEN, 8, ISO14443A_MAX_RX_FRAME_SIZE_IN_BITS}, + [SSC_MODE_14443A] = {SSC_MODE_14443A, + 4 * ISO14443A_SAMPLE_LEN, // transfersize_ssc + 4 * ISO14443A_SAMPLE_LEN <= 8 ? 8 : 16, // transfersize_pdc + ISO14443A_MAX_RX_FRAME_SIZE_IN_BITS}, [SSC_MODE_14443B] = {SSC_MODE_14443B, 32, 32, 16}, /* 64 bytes */ [SSC_MODE_EDGE_ONE_SHOT] = {SSC_MODE_EDGE_ONE_SHOT, 32, 32, 16}, /* 64 bytes */ [SSC_MODE_CONTINUOUS] = {SSC_MODE_CONTINUOUS, 32, 32, 511}, /* 2044 bytes */ @@ -178,6 +182,7 @@ static int __ramfunc __ssc_rx_load(int secondary) ssc_state.buffer[0] = buffer; } + if(DEBUG_LOAD_AND_UNLOAD) { if(secondary) {int i=usb_print_set_default_flush(0); DumpStringToUSB("{1:"); DumpUIntToUSB(rx_pdc->PDC_RNCR); @@ -192,6 +197,7 @@ static int __ramfunc __ssc_rx_load(int secondary) DumpUIntToUSB(rx_pdc->PDC_RPR); DumpStringToUSB("} "); usb_print_set_default_flush(i);} + } return 0; } @@ -215,6 +221,7 @@ static ssc_dma_rx_buffer_t* __ramfunc __ssc_rx_unload(int secondary) ssc_dma_rx_buffer_t *buffer = ssc_state.buffer[secondary]; if(buffer == NULL) return NULL; + if(DEBUG_LOAD_AND_UNLOAD) { if(secondary) {int i=usb_print_set_default_flush(0); DumpStringToUSB("(1:"); DumpUIntToUSB(rx_pdc->PDC_RNCR); @@ -229,6 +236,7 @@ static ssc_dma_rx_buffer_t* __ramfunc __ssc_rx_unload(int secondary) DumpUIntToUSB(rx_pdc->PDC_RPR); DumpStringToUSB(") "); usb_print_set_default_flush(i);} + } u_int16_t remaining_transfers = (secondary ? rx_pdc->PDC_RNCR : rx_pdc->PDC_RCR); u_int8_t* next_transfer_location = (u_int8_t*)(secondary ? rx_pdc->PDC_RNPR : rx_pdc->PDC_RPR); @@ -264,6 +272,7 @@ static ssc_dma_rx_buffer_t* __ramfunc __ssc_rx_unload(int secondary) } if(buffer->state == PENDING || buffer->state==FULL) { buffer->len_transfers = elapsed_transfers; + if(DEBUG_LOAD_AND_UNLOAD) {int i=usb_print_set_default_flush(0); DumpStringToUSB("<"); DumpUIntToUSB((unsigned int)buffer); @@ -329,7 +338,7 @@ void ssc_rx_mode_set(enum ssc_mode ssc_mode) sync_len = ISO14443A_EOF_LEN; ssc->SSC_RC0R = ISO14443A_SOF_SAMPLE << (ISO14443A_EOF_LEN-ISO14443A_SOF_LEN); ssc->SSC_RC1R = ISO14443A_EOF_SAMPLE; - data_len = ISO14443A_SAMPLE_LEN; + data_len = ssc_sizes[SSC_MODE_14443A].transfersize_ssc; num_data = 16; /* Start with 16, then switch to continuous in the IRQ handler */ stop = 1; /* Actually the documentation indicates that setting STOP makes switching to continuous unnecessary */ clock_gating = (0x0 << 6); -- cgit v1.2.3