diff options
| -rw-r--r-- | openpicc/Makefile | 1 | ||||
| -rw-r--r-- | openpicc/application/cmd.c | 3 | ||||
| -rw-r--r-- | openpicc/application/iso14443_layer3a.c | 143 | ||||
| -rw-r--r-- | openpicc/application/iso14443_layer3a.h | 18 | ||||
| -rw-r--r-- | openpicc/application/main.c | 22 | ||||
| -rw-r--r-- | openpicc/application/pio_irq.c | 10 | ||||
| -rw-r--r-- | openpicc/application/ssc_picc.c | 1 | ||||
| -rw-r--r-- | openpicc/application/ssc_picc.h | 1 | ||||
| -rw-r--r-- | openpicc/application/tc_cdiv_sync.c | 4 | ||||
| -rw-r--r-- | openpicc/config/atmel-rom.ld | 2 | ||||
| -rw-r--r-- | openpicc/config/board.h | 3 | ||||
| -rw-r--r-- | openpicc/os/boot/Cstartup_SAM7.c | 6 | ||||
| -rw-r--r-- | openpicc/os/boot/boot.s | 93 | 
13 files changed, 282 insertions, 25 deletions
| diff --git a/openpicc/Makefile b/openpicc/Makefile index f88f052..bea0f40 100644 --- a/openpicc/Makefile +++ b/openpicc/Makefile @@ -83,6 +83,7 @@ ARM_SRC= \    application/tc_fdt.c \    application/tc_cdiv.c \    application/usb_print.c \ +  application/iso14443_layer3a.c \    os/boot/Cstartup_SAM7.c \    os/core/list.c \    os/core/queue.c \ diff --git a/openpicc/application/cmd.c b/openpicc/application/cmd.c index 1e7b552..7b370db 100644 --- a/openpicc/application/cmd.c +++ b/openpicc/application/cmd.c @@ -422,8 +422,5 @@ portBASE_TYPE vCmdInit(void) {  		return 0;  	} -	ssc_rx_mode_set(SSC_MODE_CONTINUOUS); -	DumpStringToUSB("SSC mode set to continuous\n\r"); -	  	return 1;  } diff --git a/openpicc/application/iso14443_layer3a.c b/openpicc/application/iso14443_layer3a.c new file mode 100644 index 0000000..26a6115 --- /dev/null +++ b/openpicc/application/iso14443_layer3a.c @@ -0,0 +1,143 @@ +/*************************************************************** + * + * OpenPICC - ISO 14443 Layer 3 Type A state machine + * + * Copyright 2007 Henryk Plötz <henryk@ploetzli.ch> + * + *************************************************************** + +    This program is free software; you can redistribute it and/or modify +    it under the terms of the GNU General Public License as published by +    the Free Software Foundation; version 2. + +    This program is distributed in the hope that it will be useful, +    but WITHOUT ANY WARRANTY; without even the implied warranty of +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +    GNU General Public License for more details. + +    You should have received a copy of the GNU General Public License along +    with this program; if not, write to the Free Software Foundation, Inc., +    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +*/ + +#include <FreeRTOS.h> +#include <board.h> +#include <task.h> + +#include "openpicc.h" +#include "iso14443_layer3a.h" +#include "ssc_picc.h" +#include "pll.h" +#include "tc_fdt.h" +#include "tc_cdiv.h" +#include "tc_cdiv_sync.h" +#include "usb_print.h" +#include "cmd.h" + +static enum ISO14443_STATES state = STARTING_UP; +#define PLL_LOCK_HYSTERESIS portTICK_RATE_MS*5 + +#define LAYER3_DEBUG usb_print_string + +void iso14443_layer3a_state_machine (void *pvParameters) +{ +	unsigned long int last_pll_lock = ~0; +	(void)pvParameters; +	while(1) { +		ssc_dma_buffer_t* buffer = NULL; +		portBASE_TYPE need_receive = 0, switch_on = 0; +		 +		/* First let's see whether there is a reader */ +		switch(state) { +			case STARTING_UP: /* Fall through */ +			case ERROR: +				// do nothing here +				break; +			case POWERED_OFF: +				if(pll_is_locked()) { +					unsigned long int now = xTaskGetTickCount(); +					if(now - last_pll_lock > PLL_LOCK_HYSTERESIS) {  +						/* Go to idle when in POWERED_OFF and pll  +						 * was locked for at least  +						 * PLL_LOCK_HYSTERESIS ticks */ +						switch_on = 1; +						last_pll_lock = ~0; +						LAYER3_DEBUG("PLL locked, switching on \n\r"); +					} else last_pll_lock = now;  +				} else last_pll_lock = ~0; +				break; +			default: +				if(!pll_is_locked()) { +					unsigned long int now = xTaskGetTickCount(); +					if(now - last_pll_lock > PLL_LOCK_HYSTERESIS) { +						/* Power off when not powered off and pll +						 * was unlocked for at least  PLL_LOCK_HYSTERESIS +						 * ticks */ +						state = POWERED_OFF; +						ssc_rx_stop(); +						last_pll_lock = ~0; +						LAYER3_DEBUG("PLL lost lock, switching off \n\r"); +						continue;  +					} else last_pll_lock = now;  +				} else last_pll_lock = ~0; +				break; +		} +		 +		switch(state) { +			case STARTING_UP: +				pll_init(); +			     +				tc_cdiv_init(); +				tc_cdiv_set_divider(32); +				tc_fdt_init(); +#if 0 +				ssc_tx_init(); +#else +				AT91F_PIO_CfgInput(AT91C_BASE_PIOA, OPENPICC_MOD_PWM); +				AT91F_PIO_CfgPeriph(AT91C_BASE_PIOA, OPENPICC_MOD_SSC |  +						    OPENPICC_SSC_DATA | OPENPICC_SSC_DATA | +						    AT91C_PIO_PA15, 0); +#endif +				ssc_rx_init(); +				 +				state = POWERED_OFF; +				break; +			case POWERED_OFF: +				if(switch_on == 1) { +					state=IDLE; +					continue; +				} +				break; +			case IDLE: +			case HALT: +				/* Wait for REQA or WUPA (HALT: only WUPA) */ +				ssc_rx_mode_set(SSC_MODE_14443A_SHORT); +				ssc_rx_start(); +				need_receive = 1; +			default: +				break; +		} +		 +		if(need_receive) { +			if(xQueueReceive(ssc_rx_queue, &buffer, portTICK_RATE_MS)) { +				portENTER_CRITICAL(); +				buffer->state = PROCESSING; +				portEXIT_CRITICAL(); +				 +				switch(state) { +					case IDLE: +					case HALT: +						 +						break; +					default: +						break; +				} +				 +				portENTER_CRITICAL(); +				buffer->state = FREE; +				portEXIT_CRITICAL(); +			} +		} else vTaskDelay(portTICK_RATE_MS); +	} +} diff --git a/openpicc/application/iso14443_layer3a.h b/openpicc/application/iso14443_layer3a.h new file mode 100644 index 0000000..396ebe9 --- /dev/null +++ b/openpicc/application/iso14443_layer3a.h @@ -0,0 +1,18 @@ +#ifndef ISO14443_LAYER3A_H_ +#define ISO14443_LAYER3A_H_ + +extern void iso14443_layer3a_state_machine (void *pvParameters); + +enum ISO14443_STATES { +	STARTING_UP, /* Hardware has not been initialized, initialize hardware, go to power-off */ +	POWERED_OFF, /* Card not in field, wait for PLL lock */ +	IDLE,        /* Card in field and powered, wait for REQA or WUPA */ +	READY,       /* Perform anticollision, wait for select */ +	ACTIVE,      /* Selected */ +	HALT,        /* Card halted and powered, wait for WUPA */ +	READY_STAR,  /* Perform anticollision, wait for select */ +	ACTIVE_STAR, /* Selected */ +	ERROR,       /* Some unrecoverable error has occured */ +}; + +#endif /*ISO14443_LAYER3A_H_*/ diff --git a/openpicc/application/main.c b/openpicc/application/main.c index e13c793..0756d10 100644 --- a/openpicc/application/main.c +++ b/openpicc/application/main.c @@ -47,6 +47,7 @@  #include "tc_cdiv_sync.h"  #include "tc_fdt.h"  #include "usb_print.h" +#include "iso14443_layer3a.h"  /**********************************************************************/  static inline void prvSetupHardware (void) @@ -149,23 +150,10 @@ int main (void)      da_init();      adc_init(); -    pll_init(); -     -    tc_cdiv_init(); -    tc_cdiv_set_divider(16); -    tc_fdt_init(); -#if 0 -    ssc_tx_init(); -#else -	AT91F_PIO_CfgInput(AT91C_BASE_PIOA, OPENPICC_MOD_PWM); -	AT91F_PIO_CfgPeriph(AT91C_BASE_PIOA, OPENPICC_MOD_SSC |  -			    OPENPICC_SSC_DATA | OPENPICC_SSC_DATA | -			    AT91C_PIO_PA15, 0); -#endif -    ssc_rx_init(); - -    xTaskCreate (vMainTestSSCRXConsumer, (signed portCHAR *) "SSC_CONSUMER", TASK_USB_STACK, -	NULL, TASK_USB_PRIORITY, NULL); +    /*xTaskCreate (vMainTestSSCRXConsumer, (signed portCHAR *) "SSC_CONSUMER", TASK_USB_STACK, +	NULL, TASK_USB_PRIORITY, NULL);*/ +    xTaskCreate (iso14443_layer3a_state_machine, (signed portCHAR *) "ISO14443A-3", TASK_ISO_STACK, +	NULL, TASK_ISO_PRIORITY, NULL);      xTaskCreate (vUSBCDCTask, (signed portCHAR *) "USB", TASK_USB_STACK,  	NULL, TASK_USB_PRIORITY, NULL); diff --git a/openpicc/application/pio_irq.c b/openpicc/application/pio_irq.c index 648a561..73dbae5 100644 --- a/openpicc/application/pio_irq.c +++ b/openpicc/application/pio_irq.c @@ -147,13 +147,23 @@ void pio_irq_init_once(void)  	if(!initialized) pio_irq_init();  } +#define USE_FIQ +extern void fiq_handler(void);  void pio_irq_init(void)  {  	initialized = 1;  	AT91F_PIOA_CfgPMC(); +#ifdef USE_FIQ +        AT91F_AIC_ConfigureIt(AT91C_ID_FIQ, +                              //0, AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL, &cdsync_cb); +                              0, AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL, &fiq_handler); +        /* enable fast forcing for PIOA interrupt */ +        *AT91C_AIC_FFER = (1 << AT91C_ID_PIOA); +#else  	AT91F_AIC_ConfigureIt(AT91C_ID_PIOA,  			      OPENPICC_IRQ_PRIO_PIO,  			      AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL, &pio_irq_demux); +#endif  	AT91F_AIC_EnableIt(AT91C_ID_PIOA);  	(void)pio_irq_demux; // FIXME NO IRQ  } diff --git a/openpicc/application/ssc_picc.c b/openpicc/application/ssc_picc.c index 176af88..ac3b70f 100644 --- a/openpicc/application/ssc_picc.c +++ b/openpicc/application/ssc_picc.c @@ -315,6 +315,7 @@ static void __ramfunc ssc_irq_short_inner(void)  		}*/  		ssc_state.buffer[0]->state = FULL; +		ssc_state.buffer[0]->reception_mode = ssc_state.mode;  		vLedSetGreen(1);  		task_woken = xQueueSendFromISR(ssc_rx_queue, &ssc_state.buffer[0], task_woken);  		DumpStringToUSB("Sent "); diff --git a/openpicc/application/ssc_picc.h b/openpicc/application/ssc_picc.h index 34bdc18..813ef33 100644 --- a/openpicc/application/ssc_picc.h +++ b/openpicc/application/ssc_picc.h @@ -41,6 +41,7 @@ typedef enum {  typedef struct {  	volatile ssc_dma_buffer_state_t state;  	u_int32_t len;  /* Length of the content */ +	enum ssc_mode reception_mode;  	u_int8_t data[SSC_DMA_BUFFER_SIZE];  } ssc_dma_buffer_t; diff --git a/openpicc/application/tc_cdiv_sync.c b/openpicc/application/tc_cdiv_sync.c index 422fe44..0486f90 100644 --- a/openpicc/application/tc_cdiv_sync.c +++ b/openpicc/application/tc_cdiv_sync.c @@ -19,9 +19,11 @@ static void pio_data_change(u_int32_t pio)  	 * change the level is high, then it must have been a rising  	 * edge */  	if (*AT91C_PIOA_PDSR & OPENPICC_PIO_FRAME) { +		vLedSetGreen(1);  		*AT91C_TC0_CCR = AT91C_TC_SWTRG;  		DEBUGPCR("CDIV_SYNC_FLIP SWTRG CV=0x%08x",  			  *AT91C_TC0_CV); +		vLedSetGreen(0);  	} else  		DEBUGPCR("");  	//vLedSetGreen(0); @@ -60,7 +62,6 @@ void tc_cdiv_sync_enable(void)  	*AT91C_PIOA_IER = OPENPICC_PIO_FRAME;  } -extern void (*fiq_handler)(void);  void tc_cdiv_sync_init(void)  {  	pio_irq_init_once(); @@ -69,7 +70,6 @@ void tc_cdiv_sync_init(void)  	enabled = 0;  	AT91F_PIOA_CfgPMC(); -	  	AT91F_PIO_CfgOutput(AT91C_BASE_PIOA, OPENPICC_PIO_SSC_DATA_CONTROL);  	pio_irq_register(OPENPICC_PIO_FRAME, &pio_data_change); diff --git a/openpicc/config/atmel-rom.ld b/openpicc/config/atmel-rom.ld index 0a9a04d..8ea6c68 100644 --- a/openpicc/config/atmel-rom.ld +++ b/openpicc/config/atmel-rom.ld @@ -1,7 +1,7 @@  MEMORY   {  	flash	: ORIGIN = 0x00100000, LENGTH = 256K - 1K /* save 1K for environment on top of flash */ -	ram		: ORIGIN = 0x00200000, LENGTH = 64K +	ram		: ORIGIN = 0x00200028, LENGTH = 64K-28  }  __stack_end__ = 0x00200000 + 64K - 4; diff --git a/openpicc/config/board.h b/openpicc/config/board.h index c2f0e2e..18cfe9e 100644 --- a/openpicc/config/board.h +++ b/openpicc/config/board.h @@ -95,6 +95,9 @@  #define TASK_USB_PRIORITY	( tskIDLE_PRIORITY + 2 )  #define TASK_USB_STACK		( 512 ) +#define TASK_ISO_PRIORITY	( tskIDLE_PRIORITY + 3 ) +#define TASK_ISO_STACK		( 512 ) +  #define TASK_NRF_PRIORITY	( tskIDLE_PRIORITY + 3 )  #define TASK_NRF_STACK		( 512 ) diff --git a/openpicc/os/boot/Cstartup_SAM7.c b/openpicc/os/boot/Cstartup_SAM7.c index 72c9917..fdcafd3 100644 --- a/openpicc/os/boot/Cstartup_SAM7.c +++ b/openpicc/os/boot/Cstartup_SAM7.c @@ -26,6 +26,7 @@  //*----------------------------------------------------------------------------  void AT91F_LowLevelInit (void)  { +    char i=0;      AT91PS_PMC pPMC = AT91C_BASE_PMC;      //* Set flash wait state @@ -65,4 +66,9 @@ void AT91F_LowLevelInit (void)      pPMC->PMC_MCKR |= AT91C_PMC_CSS_PLL_CLK;      while (!(pPMC->PMC_SR & AT91C_PMC_MCKRDY)); +     +    /* Copy IRQ vector table to RAM */ +    for(i=0; i<0x24; i++) *((char*)(0x00200000)+i) = *((char*)(0x00100000)+i); +    /* 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 6bd5db2..cbd9be7 100644 --- a/openpicc/os/boot/boot.s +++ b/openpicc/os/boot/boot.s @@ -23,7 +23,7 @@  	/* Stack Sizes */      .set  UND_STACK_SIZE, 0x00000004      .set  ABT_STACK_SIZE, 0x00000004 -    .set  FIQ_STACK_SIZE, 0x00000004 +    .set  FIQ_STACK_SIZE, 0x00000400      .set  IRQ_STACK_SIZE, 0X00000400      .set  SVC_STACK_SIZE, 0x00000400 @@ -39,6 +39,20 @@      .equ  I_BIT, 0x80               /* when I bit is set, IRQ is disabled */      .equ  F_BIT, 0x40               /* when F bit is set, FIQ is disabled */ +.equ AT91C_BASE_AIC,  (0xFFFFF000) +.equ AT91C_BASE_PIOA, 0xFFFFF400 +.equ AT91C_BASE_TC0,  0xFFFA0000 +.equ AT91C_TC_SWTRG,  (1 << 2) +.equ PIO_DATA,        (1 << 27) +.equ PIOA_SODR,       0x30 +.equ PIOA_CODR,       0x34 +.equ PIOA_PDSR,       0x3c +.equ PIOA_IDR,        0x44 +.equ PIOA_ISR,        0x4c +.equ TC_CCR,          0x00 +.equ AIC_EOICR,       (304) +/*.equ PIO_LED1,        (1 << 25)*/ +.equ PIO_LED1,        (1 << 12)  start:  _start: @@ -55,6 +69,11 @@ _mainCRTStartup:      mov   sp, r0      sub   r0, r0, #ABT_STACK_SIZE      msr   CPSR_c, #MODE_FIQ|I_BIT|F_BIT /* FIQ Mode */ +    /* Preload registers for FIQ handler */ +    ldr     r10, =AT91C_BASE_PIOA +    ldr     r12, =AT91C_BASE_TC0 +    ldr     r8, =AT91C_BASE_AIC +    mov     r9, #AT91C_TC_SWTRG      mov   sp, r0      sub   r0, r0, #FIQ_STACK_SIZE      msr   CPSR_c, #MODE_IRQ|I_BIT|F_BIT /* IRQ Mode */ @@ -147,7 +166,7 @@ endless_loop:  	ldr   pc, _dabt						/* data abort - _dabt		*/  	nop									/* reserved					*/  	ldr   pc, [pc,#-0xF20]				/* IRQ - read the AIC		*/ -	ldr   pc, _fiq						/* FIQ - _fiq				*/ +	ldr   pc, [pc,#-0xF20]				/* FIQ - read the AIC		*/  _undf:  .word __undf                    /* undefined				*/  _swi:   .word swi_handler				/* SWI						*/ @@ -159,3 +178,73 @@ __undf: b     .                         /* undefined				*/  __pabt: b     .                         /* program abort			*/  __dabt: b     .                         /* data abort				*/  __fiq:  b     .                         /* FIQ						*/ + +/* Following is from openpcd/firmware/src/start/Cstartup_app.S */ +#define LED_TRIGGER +/*#define CALL_PIO_IRQ_DEMUX*/ +         +        .text +        .arm +        .section .fastrun, "ax" +         +        .global fiq_handler +        .func fiq_handler +fiq_handler: +                /* code that uses pre-initialized FIQ reg */ +                /* r8   AT91C_BASE_AIC (dfu init) +                   r9   AT91C_TC_SWTRG +                   r10  AT91C_BASE_PIOA +                   r11  tmp +                   r12  AT91C_BASE_TC0 +                   r13  stack +                   r14  lr +                 */ + +                ldr     r8, [r10, #PIOA_ISR] +                tst     r8, #PIO_DATA           /* check for PIO_DATA change */ +                ldrne   r11, [r10, #PIOA_PDSR] +                tstne   r11, #PIO_DATA          /* check for PIO_DATA == 1 */ +                strne   r9, [r12, #TC_CCR]      /* software trigger */ +#ifdef LED_TRIGGER +                movne   r11, #PIO_LED1 +                strne   r11, [r10, #PIOA_CODR] /* enable LED */ +#endif + +#if 1 +                movne   r11, #PIO_DATA +                strne   r11, [r10, #PIOA_IDR]   /* disable further PIO_DATA FIQ */ +#endif + +                /*- Mark the End of Interrupt on the AIC */ +                ldr     r11, =AT91C_BASE_AIC +                str     r11, [r11, #AIC_EOICR] + +#ifdef LED_TRIGGER +                mov     r11, #PIO_LED1 +                str     r11, [r10, #PIOA_SODR] /* disable LED */ +#endif + +#ifdef CALL_PIO_IRQ_DEMUX +                /* push r0, r1-r3, r12, r14 onto FIQ stack */ +                /*stmfd   sp!, { r0-r3, r12, lr} +                mov     r0, r8*/ + +                /* enable interrupts while handling demux */ +                /* enable interrupts while handling demux */ +                /* msr  CPSR_c, #F_BIT | ARM_MODE_SVC */ + +                /* Call C function, give PIOA_ISR as argument */ +                /*ldr     r11, =__pio_irq_demux +                mov     r14, pc +                bx      r11*/ + +                /* msr  CPSR_c, #I_BIT | F_BIT | ARM_MODE_FIQ */ +                /*ldmia   sp!, { r0-r3, r12, lr }*/ +#endif + +                /*- Restore the Program Counter using the LR_fiq directly in the PC */ +                subs        pc, lr, #4 + +        .size   fiq_handler, . - fiq_handler +        .endfunc +        .end | 
