From d88d1207732a80156b5d2725b4c22869ef0b3d36 Mon Sep 17 00:00:00 2001 From: henryk Date: Tue, 11 Dec 2007 18:48:39 +0000 Subject: Several modifications to enable spinning until the correct phase is reached in tc_fdt (thereby taking the phase information from tc_fdt, resetting the phase in tc_cdiv) Still too much jitter (some bug in this code?) git-svn-id: https://svn.openpcd.org:2342/trunk@383 6dc7ffe9-61d6-0310-9af1-9938baff3ed1 --- openpicc/application/iso14443_layer3a.c | 37 ++++++++++++++++++++++++++------- openpicc/application/iso14443_layer3a.h | 13 ++++++------ openpicc/application/ssc_picc.c | 15 +++++++++++-- openpicc/application/ssc_picc.h | 2 ++ openpicc/application/tc_fdt.c | 4 ++-- 5 files changed, 53 insertions(+), 18 deletions(-) (limited to 'openpicc/application') diff --git a/openpicc/application/iso14443_layer3a.c b/openpicc/application/iso14443_layer3a.c index c4e02cd..0b5ceaf 100644 --- a/openpicc/application/iso14443_layer3a.c +++ b/openpicc/application/iso14443_layer3a.c @@ -74,20 +74,43 @@ const iso14443_frame NULL_FRAME = { #define INITIAL_FRAME NULL_FRAME #endif +#define ISO14443A_TRANSMIT_AT_NEXT_INTERVAL_0 -1 +#define ISO14443A_TRANSMIT_AT_NEXT_INTERVAL_1 -2 + +/* Transmit a frame in ISO14443A mode from buffer buf at fdt carrier cycles + * after the end of the last modulation pause from the PCD with a clock divisor + * of div. Set fdt to ISO14443A_TRANSMIT_AT_NEXT_INTERVAL_0 or _1 to have the + * transmission start at the next possible interval. Use _0 when the last bit + * from the PCD was a 0 and _1 when it was a 1. */ +void iso14443_transmit(ssc_dma_tx_buffer_t *buf, int fdt, int div) +{ + tc_cdiv_set_divider(div); + if(fdt == ISO14443A_TRANSMIT_AT_NEXT_INTERVAL_0 || + fdt == ISO14443A_TRANSMIT_AT_NEXT_INTERVAL_1) { + /* FIXME Implement */ + return; + } + ssc_tx_fiq_fdt_cdiv = fdt -3*div -1; + tc_fdt_set(ssc_tx_fiq_fdt_cdiv -MAX_TF_FIQ_ENTRY_DELAY -MAX_TF_FIQ_OVERHEAD); + ssc_tx_fiq_fdt_ssc = fdt -div +1; + ssc_tx_start(buf); +} + static int atqa_sent = 0; /* Running in ISR mode */ void __ramfunc iso14443_layer3a_irq_ext(u_int32_t ssc_sr, enum ssc_mode ssc_mode, u_int8_t* samples) { (void)ssc_sr; + int fdt; if(ssc_mode == SSC_MODE_14443A_SHORT && samples) { ISO14443A_SHORT_TYPE sample = *(ISO14443A_SHORT_TYPE*)samples; portBASE_TYPE send_atqa = 0; if(sample == REQA) { - tc_fdt_set(ISO14443A_FDT_SHORT_0); + fdt = ISO14443A_FDT_SHORT_0; if(state == IDLE) send_atqa = 1; } else if(sample == WUPA) { - tc_fdt_set(ISO14443A_FDT_SHORT_1); + fdt = ISO14443A_FDT_SHORT_1; if(state == IDLE || state == HALT) send_atqa = 1; } @@ -97,13 +120,13 @@ void __ramfunc iso14443_layer3a_irq_ext(u_int32_t ssc_sr, enum ssc_mode ssc_mode if(ssc_tx_buffer.state == PREFILLED && ssc_tx_buffer.source == &ATQA_FRAME) { ssc_tx_buffer.state = PROCESSING; vLedSetGreen(1); - tc_cdiv_set_divider(8); - ssc_tx_start(&ssc_tx_buffer); + iso14443_transmit(&ssc_tx_buffer, fdt, 8); atqa_sent = 1; vLedSetGreen(0); } vLedSetGreen(1); } + vLedSetGreen(0); } } @@ -142,7 +165,7 @@ static int prefill_buffer(ssc_dma_tx_buffer_t *dest, const iso14443_frame *src) static u_int8_t received_buffer[256]; static void enable_reception(enum ssc_mode mode) { - tc_fdt_set(ISO14443A_FDT_SHORT_0); + tc_fdt_set(0xff00); ssc_rx_mode_set(mode); #ifdef FOUR_TIMES_OVERSAMPLING tc_cdiv_set_divider(32); @@ -313,9 +336,7 @@ 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; - tc_cdiv_set_divider(8); - tc_fdt_set_to_next_slot(1); - ssc_tx_start(&ssc_tx_buffer); + iso14443_transmit(&ssc_tx_buffer, 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 0c2a909..b71c13f 100644 --- a/openpicc/application/iso14443_layer3a.h +++ b/openpicc/application/iso14443_layer3a.h @@ -16,17 +16,18 @@ enum ISO14443_STATES { }; /******************** RX ************************************/ -/* measured TF->FIQ->SSC TX start delay (~3.480us) in carrier cycles */ -#define TF_FIQ_SSC_DELAY 47 -//#define TF_FIQ_SSC_DELAY 40 -#define FALLING_EDGE_DETECTION_DELAY 12 +/* Magic delay, don't know where it comes from */ +#define MAGIC_DELAY -32 +/* See fdt_timinig.dia for these values */ +#define MAX_TF_FIQ_ENTRY_DELAY 16 +#define MAX_TF_FIQ_OVERHEAD 75 /* guesstimate */ extern volatile int fdt_offset; /* standard derived magic values */ #define ISO14443A_FDT_SLOTLEN 128 #define ISO14443A_FDT_OFFSET_1 84 #define ISO14443A_FDT_OFFSET_0 20 -#define ISO14443A_FDT_SHORT_1 (ISO14443A_FDT_SLOTLEN*9 + ISO14443A_FDT_OFFSET_1 -FALLING_EDGE_DETECTION_DELAY +fdt_offset -TF_FIQ_SSC_DELAY) -#define ISO14443A_FDT_SHORT_0 (ISO14443A_FDT_SLOTLEN*9 + ISO14443A_FDT_OFFSET_0 -FALLING_EDGE_DETECTION_DELAY +fdt_offset -TF_FIQ_SSC_DELAY) +#define ISO14443A_FDT_SHORT_1 (ISO14443A_FDT_SLOTLEN*9 + ISO14443A_FDT_OFFSET_1 +fdt_offset +MAGIC_DELAY) +#define ISO14443A_FDT_SHORT_0 (ISO14443A_FDT_SLOTLEN*9 + ISO14443A_FDT_OFFSET_0 +fdt_offset +MAGIC_DELAY) #ifdef FOUR_TIMES_OVERSAMPLING /* definitions for four-times oversampling */ diff --git a/openpicc/application/ssc_picc.c b/openpicc/application/ssc_picc.c index 10beaab..3da1dbe 100644 --- a/openpicc/application/ssc_picc.c +++ b/openpicc/application/ssc_picc.c @@ -302,6 +302,17 @@ out_set_mode: * by the fiq handler to see whether to start the transmitter. */ #define USE_SSC_TX_TF_WORKAROUND volatile u_int32_t ssc_tx_pending = 0; + +/* This is the time that the TF FIQ should spin until before SWTRG'ing the tc_cdiv. + * See fdt_timing.dia. Note: This means transmission is broken without USE_SSC_TX_TF_WORKAROUND */ +volatile u_int32_t ssc_tx_fiq_fdt_cdiv = 0; +/* This is the time that the TF FIQ should spin until before starting the SSC + * There must be enough time between these two! */ +volatile u_int32_t ssc_tx_fiq_fdt_ssc = 0; +#ifndef USE_SSC_TX_TF_WORKAROUND +#error Transmission is broken without USE_SSC_TX_TF_WORKAROUND, see comments in code +#endif + void ssc_tf_irq(u_int32_t pio); void ssc_tx_start(ssc_dma_tx_buffer_t *buf) { @@ -613,8 +624,8 @@ void ssc_rx_init(void) AT91F_SSC_EnableIt(ssc, AT91C_SSC_OVRUN | AT91C_SSC_ENDRX | AT91C_SSC_RXBUFF); #endif - /* FIXME: This is hardcoded for REQA 0x26 */ - tc_fdt_set(ISO14443A_FDT_SHORT_0); + /* Will be set to a real value some time later */ + tc_fdt_set(0xff00); AT91F_AIC_EnableIt(AT91C_ID_SSC); diff --git a/openpicc/application/ssc_picc.h b/openpicc/application/ssc_picc.h index df6da36..5eb1160 100644 --- a/openpicc/application/ssc_picc.h +++ b/openpicc/application/ssc_picc.h @@ -84,5 +84,7 @@ typedef struct { extern ssc_dma_tx_buffer_t ssc_tx_buffer; extern void ssc_tx_start(ssc_dma_tx_buffer_t *buf); +extern volatile u_int32_t ssc_tx_fiq_fdt_cdiv; +extern volatile u_int32_t ssc_tx_fiq_fdt_ssc; #endif diff --git a/openpicc/application/tc_fdt.c b/openpicc/application/tc_fdt.c index 6005125..7413e11 100644 --- a/openpicc/application/tc_fdt.c +++ b/openpicc/application/tc_fdt.c @@ -53,8 +53,8 @@ void tc_fdt_set(u_int16_t count) void __ramfunc tc_fdt_set_to_next_slot(int last_bit) { int reference_time; - if(last_bit == 0) reference_time = ISO14443A_FDT_OFFSET_0-FALLING_EDGE_DETECTION_DELAY; - else reference_time = ISO14443A_FDT_OFFSET_1-FALLING_EDGE_DETECTION_DELAY; + if(last_bit == 0) reference_time = ISO14443A_FDT_OFFSET_0; + else reference_time = ISO14443A_FDT_OFFSET_1; if(tcfdt->TC_SR & AT91C_TC_CLKSTA) while(tcfdt->TC_CV != 0xFFFF && (tcfdt->TC_CV - reference_time) % 128 != 0); -- cgit v1.2.3