From 440a95fcf18a3504ec06b0e90a660b5f8e184cde Mon Sep 17 00:00:00 2001 From: henryk Date: Mon, 3 Mar 2008 20:56:30 +0000 Subject: Sending seems to be reliable now. Once in a while (about 1 in 20) there's an error condition that's not being recovered from, need to investigate git-svn-id: https://svn.openpcd.org:2342/trunk@438 6dc7ffe9-61d6-0310-9af1-9938baff3ed1 --- openpicc/application/cmd.c | 2 +- openpicc/application/iso14443_layer2a.c | 6 ++- openpicc/application/iso14443a_pretender.c | 61 ++++++++++++++++++++++++++---- openpicc/application/ssc.c | 8 ++-- 4 files changed, 63 insertions(+), 14 deletions(-) (limited to 'openpicc/application') diff --git a/openpicc/application/cmd.c b/openpicc/application/cmd.c index 878a991..47bbec5 100644 --- a/openpicc/application/cmd.c +++ b/openpicc/application/cmd.c @@ -28,7 +28,7 @@ xTaskHandle xCmdRecvUsbTask; xTaskHandle xFieldMeterTask; xSemaphoreHandle xFieldMeterMutex; -volatile int fdt_offset=0; +volatile int fdt_offset=-20; volatile int load_mod_level_set=3; #if ( configUSE_TRACE_FACILITY == 1 ) diff --git a/openpicc/application/iso14443_layer2a.c b/openpicc/application/iso14443_layer2a.c index d5e89cf..dc4a23e 100644 --- a/openpicc/application/iso14443_layer2a.c +++ b/openpicc/application/iso14443_layer2a.c @@ -199,7 +199,11 @@ static void iso14443_ssc_callback(ssc_callback_reason reason, void *data) if( (reason == CALLBACK_RX_FRAME_ENDED && !tx_pending) || reason == CALLBACK_RX_STARTING || reason == CALLBACK_TX_FRAME_ENDED ) { - ssc_select_clock(CLOCK_SELECT_PLL); + /* For regular SSC Rx we'd set the clock to + // ssc_select_clock(CLOCK_SELECT_PLL); + * however, the SSC Rx code is going to go away (at least for 14443-A) + * and switching clocks messes up the Tx timing, so we do a */ + ssc_select_clock(CLOCK_SELECT_CARRIER); ssc_set_gate(1); tc_fdt_set(0xff00); tc_cdiv_set_divider(RX_DIVIDER); diff --git a/openpicc/application/iso14443a_pretender.c b/openpicc/application/iso14443a_pretender.c index 6f62330..c2e37d5 100644 --- a/openpicc/application/iso14443a_pretender.c +++ b/openpicc/application/iso14443a_pretender.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include "openpicc.h" @@ -36,6 +37,7 @@ #include "iso14443a_manchester.h" #include "usb_print.h" #include "cmd.h" +extern volatile int fdt_offset; #include "led.h" static const iso14443_frame ATQA_FRAME = { @@ -47,6 +49,24 @@ static const iso14443_frame ATQA_FRAME = { {} }; +static const iso14443_frame LONG_FRAME = { + TYPE_A, + {{STANDARD_FRAME, PARITY, ISO14443A_LAST_BIT_NONE}}, + 40, + 0, 0, + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, }, + {} +}; + +#define FRAME_SIZE(bytes) (2* (1+(9*bytes)+1) ) +#define SIZED_BUFFER(bytes) struct { int len; u_int8_t data[FRAME_SIZE(bytes)]; } + +static SIZED_BUFFER(2) ATQA_BUFFER; +static SIZED_BUFFER(40) LONG_BUFFER; + static ssc_dma_tx_buffer_t tx_buffer; static void fast_receive_callback(ssc_dma_rx_buffer_t *buffer, u_int8_t in_irq) @@ -60,10 +80,11 @@ static void fast_receive_callback(ssc_dma_rx_buffer_t *buffer, u_int8_t in_irq) switch(buffer->len_transfers) { case 3: case 4: /* REQA (7 bits) */ + case 7: case 8: case 9: tx_frame = &ATQA_FRAME; fdt = 1172; break; - case 6: case 7: /* ANTICOL (2 bytes) */ + //case 6: case 7: /* ANTICOL (2 bytes) */ case 22: /* SELECT (9 bytes) */ break; @@ -74,15 +95,26 @@ static void fast_receive_callback(ssc_dma_rx_buffer_t *buffer, u_int8_t in_irq) } /* Add some extra room to the fdt for testing */ - fdt += 3*128; + //fdt += 3*128; + fdt += fdt_offset; + int ret = 0; if(tx_frame != NULL) { + tx_buffer.source = (void*)tx_frame; - tx_buffer.len = sizeof(tx_buffer.data); - ret = manchester_encode(tx_buffer.data, - tx_buffer.len, - tx_frame); + if(tx_frame == &ATQA_FRAME) { + memcpy(tx_buffer.data, ATQA_BUFFER.data, ATQA_BUFFER.len); + ret = tx_buffer.len = ATQA_BUFFER.len; + } else if(tx_frame == &LONG_FRAME) { + memcpy(tx_buffer.data, LONG_BUFFER.data, LONG_BUFFER.len); + ret = tx_buffer.len = LONG_BUFFER.len; + } else { + tx_buffer.len = sizeof(tx_buffer.data); + ret = manchester_encode(tx_buffer.data, + tx_buffer.len, + tx_frame); + } if(ret >= 0) { tx_buffer.state = FULL; tx_buffer.len = ret; @@ -129,6 +161,18 @@ void iso14443a_pretender (void *pvParameters) vTaskDelay(1*portTICK_RATE_MS); } + ATQA_BUFFER.len = manchester_encode(ATQA_BUFFER.data, sizeof(ATQA_BUFFER.data), &ATQA_FRAME); + LONG_BUFFER.len = manchester_encode(LONG_BUFFER.data, sizeof(LONG_BUFFER.data), &LONG_FRAME); + if(ATQA_BUFFER.len < 0 || LONG_BUFFER.len < 0) { + usb_print_string("Buffer prefilling failed\n\r"); + while(1) { + for(i=1000; i<=3000; i++) { + vLedSetBrightness(LED_GREEN, abs(1000-(i%2000))); + vTaskDelay(1*portTICK_RATE_MS); + } + } + } + do { res = iso14443_layer2a_init(1); if(res < 0) { @@ -206,7 +250,8 @@ void iso14443a_pretender (void *pvParameters) current_detected = 0; last_switched = xTaskGetTickCount(); } - + +#if 0 if(last_detected & (DETECTED_14443A_3 | DETECTED_14443A_4 | DETECTED_MIFARE)) { if(last_detected & DETECTED_MIFARE) { vLedSetGreen(0); @@ -222,6 +267,6 @@ void iso14443a_pretender (void *pvParameters) vLedSetGreen(0); vLedSetRed(0); } - +#endif } } diff --git a/openpicc/application/ssc.c b/openpicc/application/ssc.c index 5603256..50d416b 100644 --- a/openpicc/application/ssc.c +++ b/openpicc/application/ssc.c @@ -192,7 +192,7 @@ static int __ramfunc _ssc_tx_irq(u_int32_t sr, portBASE_TYPE task_woken) { ssc_handle_t *sh = &_ssc; - if( sr & AT91C_SSC_ENDTX ) { + if( sr & AT91C_SSC_TXEMPTY ) { /* Tx has ended */ AT91F_PDC_DisableTx(sh->pdc); AT91F_SSC_DisableTx(sh->ssc); @@ -656,16 +656,16 @@ int ssc_send(ssc_handle_t* sh, ssc_dma_tx_buffer_t *buffer) sh->ssc->SSC_TFMR = ((data_len-1) & 0x1f) | (((num_data_ssc-1) & 0x0f) << 8) | (((sync_len-1) & 0x0f) << 16); - sh->ssc->SSC_TCMR = 0x01 | AT91C_SSC_CKO_NONE | (AT91C_SSC_CKI&0) | start_cond; + sh->ssc->SSC_TCMR = 0x01 | AT91C_SSC_CKO_NONE | AT91C_SSC_CKI | start_cond; AT91F_PDC_SetTx(sh->pdc, buffer->data, num_data); AT91F_PDC_SetNextTx(sh->pdc, 0, 0); buffer->state = PENDING; - sh->ssc->SSC_IER = AT91C_SSC_ENDTX; + sh->ssc->SSC_IER = AT91C_SSC_TXEMPTY; /* Enable DMA */ + sh->ssc->SSC_THR = 0; AT91F_PDC_EnableTx(sh->pdc); - //AT91F_PDC_SetTx(sh->pdc, buffer->data, num_data); /* Disable Receiver, see comments in _ssc_rx_irq */ AT91F_SSC_DisableRx(sh->ssc); -- cgit v1.2.3