summaryrefslogtreecommitdiff
path: root/openpicc/application/iso14443_layer3a.c
diff options
context:
space:
mode:
Diffstat (limited to 'openpicc/application/iso14443_layer3a.c')
-rw-r--r--openpicc/application/iso14443_layer3a.c92
1 files changed, 86 insertions, 6 deletions
diff --git a/openpicc/application/iso14443_layer3a.c b/openpicc/application/iso14443_layer3a.c
index 2239655..f2fe16e 100644
--- a/openpicc/application/iso14443_layer3a.c
+++ b/openpicc/application/iso14443_layer3a.c
@@ -49,11 +49,65 @@ const iso14443_frame ATQA_FRAME = {
{}
};
+const iso14443_frame NULL_FRAME = {
+ TYPE_A,
+ {{STANDARD_FRAME, PARITY}},
+ 4,
+ 0, 0,
+ {0, 0, 0, 0},
+ {}
+};
+
#define PLL_LOCK_HYSTERESIS portTICK_RATE_MS*5
#define LAYER3_DEBUG usb_print_string
+#define INITIAL_STATE IDLE
+//#define INITIAL_STATE ACTIVE
+
+/* 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;
+ 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);
+ if(state == IDLE)
+ send_atqa = 1;
+ /* FIXME: prepare and configure ATQA response */
+ } else if(sample == WUPA) {
+ tc_fdt_set(ISO14443A_FDT_SHORT_1);
+ if(state == IDLE || state == HALT)
+ send_atqa = 1;
+ /* FIXME: prepare and configure ATQA response */
+ }
+
+ if(send_atqa) {
+ vLedSetGreen(0);
+ if(ssc_tx_buffer.state == FREE) {
+ ssc_tx_buffer.state = PROCESSING;
+ ssc_tx_buffer.len = sizeof(ssc_tx_buffer.data);
+ int ret = manchester_encode(ssc_tx_buffer.data,
+ ssc_tx_buffer.len,
+ &ATQA_FRAME);
+ if(ret>0) {
+ vLedSetGreen(1);
+ ssc_tx_buffer.len = ret;
+ ssc_tx_start(&ssc_tx_buffer);
+ vLedSetGreen(0);
+
+ } else {
+ ssc_tx_buffer.state = FREE;
+ }
+ }
+ vLedSetGreen(1);
+ }
+ }
+}
+
extern void main_help_print_buffer(ssc_dma_rx_buffer_t *buffer, int *pktcount);
void iso14443_layer3a_state_machine (void *pvParameters)
{
@@ -64,6 +118,11 @@ void iso14443_layer3a_state_machine (void *pvParameters)
ssc_dma_rx_buffer_t* buffer = NULL;
portBASE_TYPE need_receive = 0, switch_on = 0;
+ if(ssc_get_overflows() > 0 && state != ERROR) {
+ LAYER3_DEBUG("SSC overflow error, please debug\n\r");
+ state = ERROR;
+ }
+
/* First let's see whether there is a reader */
switch(state) {
case STARTING_UP: /* Fall through */
@@ -111,6 +170,7 @@ void iso14443_layer3a_state_machine (void *pvParameters)
tc_cdiv_set_divider(64);
#endif
tc_fdt_init();
+ ssc_set_irq_extension((ssc_irq_ext_t)iso14443_layer3a_irq_ext);
#if 1
ssc_tx_init();
#else
@@ -129,8 +189,12 @@ void iso14443_layer3a_state_machine (void *pvParameters)
break;
case POWERED_OFF:
if(switch_on == 1) {
- state=IDLE;
- ssc_rx_mode_set(SSC_MODE_14443A_SHORT);
+ state=INITIAL_STATE;
+ if(INITIAL_STATE == IDLE)
+ ssc_rx_mode_set(SSC_MODE_14443A_SHORT);
+ else if(INITIAL_STATE == ACTIVE)
+ ssc_rx_mode_set(SSC_MODE_14443A_STANDARD);
+ else ssc_rx_mode_set(SSC_MODE_NONE);
ssc_rx_start();
continue;
}
@@ -139,6 +203,9 @@ void iso14443_layer3a_state_machine (void *pvParameters)
case HALT:
/* Wait for REQA or WUPA (HALT: only WUPA) */
need_receive = 1;
+ case ACTIVE:
+ case ACTIVE_STAR:
+ need_receive = 1;
default:
break;
}
@@ -164,10 +231,17 @@ void iso14443_layer3a_state_machine (void *pvParameters)
LAYER3_DEBUG("Received ");
LAYER3_DEBUG(first_sample == WUPA ? "WUPA" : "REQA");
LAYER3_DEBUG(" waking up to send ATQA\n\r");
- portENTER_CRITICAL();
+ if(ssc_tx_buffer.state == PROCESSING) {
+ LAYER3_DEBUG("Buffer ");
+ DumpUIntToUSB(ssc_tx_buffer.len);
+ LAYER3_DEBUG(" ");
+ DumpBufferToUSB((char*)ssc_tx_buffer.data, ssc_tx_buffer.len);
+ LAYER3_DEBUG("\n\r");
+ }
+ /*portENTER_CRITICAL();
if(ssc_tx_buffer.state != FREE) {
portEXIT_CRITICAL();
- /* Wait for another frame */
+ * Wait for another frame */ /*
ssc_rx_mode_set(SSC_MODE_14443A_SHORT);
ssc_rx_start();
} else {
@@ -180,6 +254,7 @@ void iso14443_layer3a_state_machine (void *pvParameters)
&ATQA_FRAME);
if(ret>0) {
ssc_tx_buffer.len = ret;
+ ssc_tx_start(&ssc_tx_buffer);
LAYER3_DEBUG("Buffer ");
DumpUIntToUSB(ret);
LAYER3_DEBUG(" ");
@@ -189,17 +264,22 @@ void iso14443_layer3a_state_machine (void *pvParameters)
portENTER_CRITICAL();
ssc_tx_buffer.state = FREE;
portEXIT_CRITICAL();
- /* Wait for another frame */
+ * Wait for another frame */ /*
ssc_rx_mode_set(SSC_MODE_14443A_SHORT);
ssc_rx_start();
}
- }
+ }*/
} else {
/* Wait for another frame */
ssc_rx_mode_set(SSC_MODE_14443A_SHORT);
ssc_rx_start();
}
break;
+ case ACTIVE:
+ case ACTIVE_STAR:
+ /* Wait for another frame */
+ ssc_rx_mode_set(SSC_MODE_14443A_STANDARD);
+ ssc_rx_start();
default:
break;
}
personal git repositories of Harald Welte. Your mileage may vary