summaryrefslogtreecommitdiff
path: root/openpicc/application
diff options
context:
space:
mode:
Diffstat (limited to 'openpicc/application')
-rw-r--r--openpicc/application/cmd.c3
-rw-r--r--openpicc/application/iso14443_layer3a.c143
-rw-r--r--openpicc/application/iso14443_layer3a.h18
-rw-r--r--openpicc/application/main.c22
-rw-r--r--openpicc/application/pio_irq.c10
-rw-r--r--openpicc/application/ssc_picc.c1
-rw-r--r--openpicc/application/ssc_picc.h1
-rw-r--r--openpicc/application/tc_cdiv_sync.c4
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);
personal git repositories of Harald Welte. Your mileage may vary