summaryrefslogtreecommitdiff
path: root/openpicc/application/iso14443_layer2a.c
diff options
context:
space:
mode:
Diffstat (limited to 'openpicc/application/iso14443_layer2a.c')
-rw-r--r--openpicc/application/iso14443_layer2a.c71
1 files changed, 41 insertions, 30 deletions
diff --git a/openpicc/application/iso14443_layer2a.c b/openpicc/application/iso14443_layer2a.c
index 91df6b9..65d5d6a 100644
--- a/openpicc/application/iso14443_layer2a.c
+++ b/openpicc/application/iso14443_layer2a.c
@@ -44,6 +44,7 @@
#include "tc_fdt.h"
#include "tc_cdiv.h"
#include "tc_cdiv_sync.h"
+#include "tc_recv.h"
#include "load_modulation.h"
#include "clock_switch.h"
#include "pio_irq.h"
@@ -58,6 +59,7 @@ static u_int8_t tx_pending=0;
static u_int8_t rx_pending=0;
static iso14443_receive_callback_t callback=NULL;
static ssc_handle_t *ssc;
+static tc_recv_handle_t th;
#ifdef FOUR_TIMES_OVERSAMPLING
#define RX_DIVIDER 32
@@ -65,10 +67,9 @@ static ssc_handle_t *ssc;
#define RX_DIVIDER 64
#endif
-int iso14443_receive(iso14443_receive_callback_t _callback, ssc_dma_rx_buffer_t **buffer, unsigned int timeout)
+int iso14443_receive(iso14443_receive_callback_t _callback, iso14443_frame **frame, unsigned int timeout)
{
- ssc_dma_rx_buffer_t* _buffer = NULL;
- int len;
+ iso14443_frame* _frame = NULL;
if(rx_pending) {
return -EALREADY;
@@ -76,9 +77,9 @@ int iso14443_receive(iso14443_receive_callback_t _callback, ssc_dma_rx_buffer_t
rx_pending=1;
callback=_callback;
- if(ssc_recv(ssc, &_buffer, timeout) == 0) {
+ if(tc_recv_receive(th, &_frame, timeout) == 0) {
- if(_buffer == NULL) {
+ if(_frame == NULL) {
/* Can this happen? */
rx_pending=0;
callback=NULL;
@@ -86,25 +87,23 @@ int iso14443_receive(iso14443_receive_callback_t _callback, ssc_dma_rx_buffer_t
}
portENTER_CRITICAL();
- _buffer->state = PROCESSING;
+ _frame->state = FRAME_PROCESSING;
portEXIT_CRITICAL();
- len = _buffer->len_transfers;
-
if(callback != NULL && !fast_receive) {
- callback(_buffer, 0);
+ callback(NULL, _frame, 0);
}
- if(buffer != NULL) *buffer = _buffer;
+ if(frame != NULL) *frame = _frame;
else {
portENTER_CRITICAL();
- _buffer->state = FREE;
+ _frame->state = FRAME_FREE;
portEXIT_CRITICAL();
}
rx_pending=0;
callback=NULL;
- return len;
+ return 0;
}
/* Note: There is the remote chance of a race condition probability here if
@@ -185,7 +184,7 @@ u_int8_t iso14443_get_fast_receive(void)
static void iso14443_ssc_callback(ssc_callback_reason reason, void *data)
{
- if(reason == CALLBACK_RX_FRAME_BEGIN) {
+ if(reason == SSC_CALLBACK_RX_FRAME_BEGIN) {
/* Busy loop for the frame end */
int *end_asserted = data, i=0;
for(i=0; i<96000; i++)
@@ -197,20 +196,20 @@ static void iso14443_ssc_callback(ssc_callback_reason reason, void *data)
return;
}
- if(reason == CALLBACK_TX_FRAME_ENDED) {
+ if(reason == SSC_CALLBACK_TX_FRAME_ENDED) {
tx_pending = 0;
}
- if( reason == CALLBACK_RX_FRAME_ENDED && fast_receive ) {
+ if( reason == SSC_CALLBACK_RX_FRAME_ENDED && fast_receive ) {
clock_switch(CLOCK_SELECT_CARRIER); /* A Tx might be coming up */
ssc_dma_rx_buffer_t *buffer = data;
if(callback != NULL)
- callback(buffer, 1);
+ callback(buffer, NULL, 1);
}
- if( (reason == CALLBACK_RX_FRAME_ENDED && !tx_pending) || reason == CALLBACK_RX_STARTING
- || reason == CALLBACK_TX_FRAME_ENDED ) {
+ if( (reason == SSC_CALLBACK_RX_FRAME_ENDED && !tx_pending) || reason == SSC_CALLBACK_RX_STARTING
+ || reason == SSC_CALLBACK_TX_FRAME_ENDED ) {
/* For regular SSC Rx we'd set the clock to
// clock_switch(CLOCK_SELECT_PLL);
* however, the SSC Rx code is going to go away (at least for 14443-A)
@@ -226,16 +225,27 @@ static void iso14443_ssc_callback(ssc_callback_reason reason, void *data)
usb_print_set_default_flush(old);
#endif
}
-
}
-static portBASE_TYPE iso14443_rx_FRAME_cb(u_int32_t pio, portBASE_TYPE xTaskWoken)
+static void iso14443_tc_recv_callback(tc_recv_callback_reason reason, void *data)
{
- (void)pio;
- if(PRINT_DEBUG) usb_print_string_f("°", 0); // DEBUG OUTPUT
- if(AT91F_PIO_IsInputSet(AT91C_BASE_PIOA, OPENPICC_PIO_FRAME))
- ssc_frame_started();
- return xTaskWoken;
+ if( reason == TC_RECV_CALLBACK_RX_FRAME_ENDED && fast_receive ) {
+ clock_switch(CLOCK_SELECT_CARRIER); /* A Tx might be coming up */
+
+ iso14443_frame *frame = data;
+ if(callback != NULL)
+ callback(NULL, frame, 1);
+ }
+
+ if( (reason == TC_RECV_CALLBACK_RX_FRAME_ENDED && !tx_pending) ||
+ reason == TC_RECV_CALLBACK_SETUP ) {
+ /* For T/C Rx we set the clock to */
+ clock_switch(CLOCK_SELECT_CARRIER);
+ ssc_set_gate(1);
+ tc_fdt_set(0xff00);
+ tc_cdiv_set_divider(RX_DIVIDER);
+ tc_cdiv_sync_reset();
+ }
}
int iso14443_layer2a_init(u_int8_t enable_fast_receive)
@@ -251,14 +261,15 @@ int iso14443_layer2a_init(u_int8_t enable_fast_receive)
iso14443_set_fast_receive(enable_fast_receive);
pio_irq_init_once();
- if(pio_irq_register(OPENPICC_PIO_FRAME, &iso14443_rx_FRAME_cb) >= 0) {
- if(PRINT_DEBUG) usb_print_string("FRAME irq registered\n\r"); // DEBUG OUTPUT
- }
-
- ssc = ssc_open(1, 1, SSC_MODE_14443A, iso14443_ssc_callback);
+ ssc = ssc_open(0, 1, SSC_MODE_14443A, iso14443_ssc_callback);
if(ssc == NULL)
return -EIO;
+ if(tc_recv_init(&th, 0, iso14443_tc_recv_callback) < 0) {
+ ssc_close(ssc);
+ return -EIO;
+ }
+
load_mod_level(3);
return 0;
personal git repositories of Harald Welte. Your mileage may vary