diff options
Diffstat (limited to 'openpicc/application')
-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 |
8 files changed, 180 insertions, 22 deletions
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); |