diff options
Diffstat (limited to 'openpicc')
| -rw-r--r-- | openpicc/application/iso14443_layer3a.c | 37 | ||||
| -rw-r--r-- | openpicc/application/iso14443_layer3a.h | 13 | ||||
| -rw-r--r-- | openpicc/application/ssc_picc.c | 15 | ||||
| -rw-r--r-- | openpicc/application/ssc_picc.h | 2 | ||||
| -rw-r--r-- | openpicc/application/tc_fdt.c | 4 | ||||
| -rw-r--r-- | openpicc/config/atmel-rom.ld | 8 | ||||
| -rw-r--r-- | openpicc/fdt_timing.dia | bin | 0 -> 2147 bytes | |||
| -rw-r--r-- | openpicc/os/boot/Cstartup_SAM7.c | 4 | ||||
| -rw-r--r-- | openpicc/os/boot/boot.s | 43 | 
9 files changed, 92 insertions, 34 deletions
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); diff --git a/openpicc/config/atmel-rom.ld b/openpicc/config/atmel-rom.ld index 9781d0c..447bd07 100644 --- a/openpicc/config/atmel-rom.ld +++ b/openpicc/config/atmel-rom.ld @@ -1,9 +1,9 @@  MEMORY   { -	boot    : ORIGIN = 0x00100000, LENGTH = 0x100 -	flash   : ORIGIN = 0x00100100, LENGTH = 256K - 0x100 -	vectors	: ORIGIN = 0x00200000, LENGTH = 0x100 -	ram	: ORIGIN = 0x00200100, LENGTH = 64K - 0x100 +	boot    : ORIGIN = 0x00100000, LENGTH = 0x200 +	flash   : ORIGIN = 0x00100200, LENGTH = 256K - 0x200 +	vectors	: ORIGIN = 0x00200000, LENGTH = 0x200 +	ram	: ORIGIN = 0x00200200, LENGTH = 64K - 0x200  }  __stack_end__ = 0x00200000 + 64K - 4; diff --git a/openpicc/fdt_timing.dia b/openpicc/fdt_timing.dia Binary files differnew file mode 100644 index 0000000..19fad5a --- /dev/null +++ b/openpicc/fdt_timing.dia diff --git a/openpicc/os/boot/Cstartup_SAM7.c b/openpicc/os/boot/Cstartup_SAM7.c index 5371794..b308856 100644 --- a/openpicc/os/boot/Cstartup_SAM7.c +++ b/openpicc/os/boot/Cstartup_SAM7.c @@ -68,8 +68,8 @@ void AT91F_LowLevelInit (void)      pPMC->PMC_MCKR |= AT91C_PMC_CSS_PLL_CLK;      while (!(pPMC->PMC_SR & AT91C_PMC_MCKRDY)); -    /* Copy first 0x100 bytes (IRQ vector table and FIQ) to RAM */ -    memcpy((void*)0x00200000, (void*)0x00100000, 0x100); +    /* Copy first 0x200 bytes (IRQ vector table and FIQ) to RAM */ +    memcpy((void*)0x00200000, (void*)0x00100000, 0x200);      /* Perform remap FIXME doesn't work*/      // AT91C_BASE_MC->MC_RCR = AT91C_MC_RCB;  } diff --git a/openpicc/os/boot/boot.s b/openpicc/os/boot/boot.s index 95bc130..0000479 100644 --- a/openpicc/os/boot/boot.s +++ b/openpicc/os/boot/boot.s @@ -5,6 +5,8 @@  	.extern AT91F_LowLevelInit  	.extern pio_irq_isr_value  	.extern ssc_tx_pending +	.extern ssc_tx_fiq_fdt_cdiv +	.extern ssc_tx_fiq_fdt_ssc  	.text  	.code 32 @@ -60,6 +62,7 @@  .equ PIOA_IDR,        0x44  .equ PIOA_ISR,        0x4c  .equ TC_CCR,          0x00 +.equ TC2_CV,          (0x80+0x10)  .equ AIC_EOICR,       (304)  .equ PIO_LED1,        (1 << 25)  .equ PIO_LED2,        (1 << 12) @@ -68,11 +71,6 @@  .equ PIO_SECONDARY_IRQ, 31  .equ PIO_SECONDARY_IRQ_BIT, (1 << PIO_SECONDARY_IRQ) -/* FIQ latency is approx 1us. At 13.56 MHz carrier frequency this means that  - * 13.56 cycles of the carrier have passed when the FIQ kicks in and this is - * the amount that CV0 should be loaded to. (Round up) */ -.equ TC0_FRAME_OFFSET, 9 -  start:  _start:  _mainCRTStartup: @@ -241,13 +239,38 @@ my_fiq_handler:                  ldrne   r11, =ssc_tx_pending                  ldrne   r8, [r11]                  tstne   r8, #0x01              /* Check whether a TX is pending */ +                beq     .no_ssc +                 +                mov   r8, #PIO_LED1 +                str   r8, [r10, #PIOA_SODR] /* disable LED */ +                 +                mov   r8, #0x00 +                str   r8, [r11]                /* Set ssc_tx_pending to 0 */ -                movne   r8, #0x00 -                strne   r8, [r11]                /* Set ssc_tx_pending to 0 */ +                ldr   r11, =ssc_tx_fiq_fdt_cdiv +                ldr   r11, [r11]               /* r11 == ssc_tx_fiq_fdt_cdiv */ + +.wait_for_fdt_cdiv:   +				ldr   r8, [r12, #TC2_CV] +				cmp   r8, r11 +				bmi   .wait_for_fdt_cdiv       /* spin while TC2.CV is less fdt_cdiv */ +				 +				str   r9, [r12, #TC_CCR]       /* SWTRG on TC0 */ +				 +                ldr   r11, =ssc_tx_fiq_fdt_ssc +                ldr   r11, [r11]               /* r11 == ssc_tx_fiq_fdt_ssc */ + +.wait_for_fdt_ssc: +				ldr   r8, [r12, #TC2_CV] +				cmp   r8, r11 +				bmi   .wait_for_fdt_ssc        /* spin while TC2.CV is less fdt_ssc */ +                 +                mov   r11, #PIO_LED1 +                str   r11, [r10, #PIOA_CODR] /* enable LED */ -                ldrne   r11, =AT91C_BASE_SSC -                movne   r8, #SSC_CR_TXEN -                strne   r8, [r11, #SSC_CR]       /* Write TXEN to SSC_CR, enables tx */  +                ldr   r11, =AT91C_BASE_SSC +                mov   r8, #SSC_CR_TXEN +                str   r8, [r11, #SSC_CR]       /* Write TXEN to SSC_CR, enables tx */   .no_ssc:                                 /* Trigger PIO_SECONDARY_IRQ */  | 
