From ceb643380b02d0d8289e3ad75a495123414ace8c Mon Sep 17 00:00:00 2001 From: henryk Date: Sun, 9 Dec 2007 06:10:56 +0000 Subject: Prevent late frames by spinning in SSC CP0 IRQ till end of short frame reception Fix tc_cdiv_set_divider. again. Reverse the polarity! (of the ssc transmit clock) git-svn-id: https://svn.openpcd.org:2342/trunk@381 6dc7ffe9-61d6-0310-9af1-9938baff3ed1 --- openpicc/application/decoder_miller.c | 9 ++++++++- openpicc/application/ssc_picc.c | 18 +++++++++++++++++- openpicc/application/tc_cdiv.c | 11 +++++++---- openpicc/application/tc_cdiv.h | 4 ++-- openpicc/os/boot/boot.s | 10 +++++++++- 5 files changed, 43 insertions(+), 9 deletions(-) (limited to 'openpicc') diff --git a/openpicc/application/decoder_miller.c b/openpicc/application/decoder_miller.c index ca0a192..8f2aedb 100644 --- a/openpicc/application/decoder_miller.c +++ b/openpicc/application/decoder_miller.c @@ -46,14 +46,21 @@ #include "openpicc.h" #include "dbgu.h" #include "decoder.h" +#include "iso14443_layer3a.h" - +#ifdef FOUR_TIMES_OVERSAMPLING #define OVERSAMPLING_RATE 4 /* definitions for four-times oversampling */ #define SEQ_X 0x4 #define SEQ_Y 0x0 #define SEQ_Z 0x1 +#else +#define OVERSAMPLING_RATE 2 +#define SEQ_X 0x2 +#define SEQ_Y 0x0 +#define SEQ_Z 0x1 +#endif /* decode a single sampled bit */ static inline u_int8_t miller_decode_sampled_bit(u_int32_t sampled_bit) diff --git a/openpicc/application/ssc_picc.c b/openpicc/application/ssc_picc.c index 98f9e46..ce507fd 100644 --- a/openpicc/application/ssc_picc.c +++ b/openpicc/application/ssc_picc.c @@ -313,7 +313,7 @@ void ssc_tx_start(ssc_dma_tx_buffer_t *buf) ssc->SSC_TFMR = ((data_len-1) & 0x1f) | (((num_data-1) & 0x0f) << 8) | (((sync_len-1) & 0x0f) << 16); - ssc->SSC_TCMR = 0x01 | AT91C_SSC_CKO_NONE | start_cond; + ssc->SSC_TCMR = 0x01 | AT91C_SSC_CKO_NONE | AT91C_SSC_CKI | start_cond; AT91F_PDC_SetTx(tx_pdc, buf->data, num_data); AT91F_PDC_SetNextTx(tx_pdc, 0, 0); @@ -381,11 +381,27 @@ static void __ramfunc ssc_irq(void) portBASE_TYPE task_woken = pdFALSE; u_int32_t ssc_sr = ssc->SSC_SR; + u_int32_t orig_ssc_sr = ssc_sr; int i, emptyframe = 0; u_int32_t *tmp; ssc_dma_rx_buffer_t *inbuf=NULL; DEBUGP("ssc_sr=0x%08x, mode=%u: ", ssc_sr, ssc_state.mode); + if (ssc_sr & AT91C_SSC_CP0 && ssc_state.mode == SSC_MODE_14443A_SHORT) { + /* Short frame, busy loop till the frame is received completely to + * prevent a second irq entrance delay when the actual frame end + * irq is raised. (The scheduler masks interrupts for about 56us, + * which is too much for anticollision.) */ + int i = 0; + vLedBlinkRed(); + while( ! ((ssc_sr=ssc->SSC_SR) & AT91C_SSC_ENDRX) ) { + i++; + if(i > 9600) break; + } + ssc_sr |= orig_ssc_sr; + vLedSetRed(1); + } + if (ssc_sr & AT91C_SSC_ENDRX) { /* Ignore empty frames */ if (ssc_state.mode == SSC_MODE_CONTINUOUS) { diff --git a/openpicc/application/tc_cdiv.c b/openpicc/application/tc_cdiv.c index d389214..08b8efe 100644 --- a/openpicc/application/tc_cdiv.c +++ b/openpicc/application/tc_cdiv.c @@ -27,11 +27,12 @@ #include "openpicc.h" #include "tc_cdiv.h" +#include "led.h" AT91PS_TCB tcb = AT91C_BASE_TCB; /* set carrier divider to a specific */ -void tc_cdiv_set_divider(u_int16_t div) +void __ramfunc tc_cdiv_set_divider(u_int16_t div) { tcb->TCB_TC0.TC_RC = div; @@ -43,11 +44,13 @@ void tc_cdiv_set_divider(u_int16_t div) * In order to not lose phase information when doing that we'll busy wait till CV is * zero modulo the new RC.*/ /*tc_cdiv_phase_add(tcb->TCB_TC0.TC_RC-(tcb->TCB_TC0.TC_CV%tcb->TCB_TC0.TC_RC));*/ - if(tcb->TCB_TC0.TC_CV > div) while(tcb->TCB_TC0.TC_CV % div != 0); - tcb->TCB_TC0.TC_CCR = AT91C_TC_SWTRG; + if(tcb->TCB_TC0.TC_CV > div) { + while(tcb->TCB_TC0.TC_CV % div != 0); + tcb->TCB_TC0.TC_CCR = AT91C_TC_SWTRG; + } } -void tc_cdiv_phase_add(int16_t inc) +void __ramfunc tc_cdiv_phase_add(int16_t inc) { tcb->TCB_TC0.TC_RA = (tcb->TCB_TC0.TC_RA + inc) % tcb->TCB_TC0.TC_RC; tcb->TCB_TC0.TC_RB = (tcb->TCB_TC0.TC_RB + inc) % tcb->TCB_TC0.TC_RC; diff --git a/openpicc/application/tc_cdiv.h b/openpicc/application/tc_cdiv.h index 33ff5b9..04d8ed0 100644 --- a/openpicc/application/tc_cdiv.h +++ b/openpicc/application/tc_cdiv.h @@ -7,8 +7,8 @@ extern AT91PS_TCB tcb; -extern void tc_cdiv_phase_add(int16_t inc); -extern void tc_cdiv_set_divider(u_int16_t div); +extern void __ramfunc tc_cdiv_phase_add(int16_t inc); +extern void __ramfunc tc_cdiv_set_divider(u_int16_t div); static inline void tc_cdiv_phase_inc(void) { diff --git a/openpicc/os/boot/boot.s b/openpicc/os/boot/boot.s index e709b94..95bc130 100644 --- a/openpicc/os/boot/boot.s +++ b/openpicc/os/boot/boot.s @@ -52,6 +52,7 @@ .equ AT91C_TC_SWTRG, (1 << 2) .equ AT91C_TC_CLKEN, (1 << 0) .equ PIO_DATA, (1 << 27) +.equ PIO_FRAME, (1 << 20) .equ PIO_SSC_TF, (1 << 15) .equ PIOA_SODR, 0x30 .equ PIOA_CODR, 0x34 @@ -222,7 +223,14 @@ my_fiq_handler: movne r11, #PIO_DATA strne r11, [r10, #PIOA_IDR] /* disable further PIO_DATA FIQ */ - + beq .no_pio_data +/* .loop_high: + ldr r11, [r10, #PIOA_PDSR] + tst r11, #PIO_DATA + bne .loop_high + str r9, [r12, #TC_CCR] /* software trigger */ + +.no_pio_data: tst r8, #PIO_SSC_TF /* check for SSC Transmit Frame signal */ ldrne r11, [r10, #PIOA_PDSR] tstne r11, #PIO_SSC_TF /* check for SSC_TF == 1 */ -- cgit v1.2.3