summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorhenryk <henryk@6dc7ffe9-61d6-0310-9af1-9938baff3ed1>2008-03-14 18:29:28 +0000
committerhenryk <henryk@6dc7ffe9-61d6-0310-9af1-9938baff3ed1>2008-03-14 18:29:28 +0000
commitf7a420f2387b0bb660df08954d4bf35a66937203 (patch)
tree43d7ca7aef351e23bde9081bf7f41433b71ed3b3
parentb7a11d3b34aebfc77addfcd2ef7803c38d4e1dcc (diff)
Faked anticollision working now. During stress test (OpenPCD reqa firmware in anticol mode performing one cycle every 70ms) there were 52 late frames in 15992.
git-svn-id: https://svn.openpcd.org:2342/trunk@454 6dc7ffe9-61d6-0310-9af1-9938baff3ed1
-rw-r--r--openpicc/Makefile4
-rw-r--r--openpicc/application/iso14443.h1
-rw-r--r--openpicc/application/iso14443_layer2a.c14
-rw-r--r--openpicc/application/iso14443a_diffmiller.c16
-rw-r--r--openpicc/application/iso14443a_pretender.c63
-rw-r--r--openpicc/application/main.c6
-rw-r--r--openpicc/application/ssc.c2
7 files changed, 67 insertions, 39 deletions
diff --git a/openpicc/Makefile b/openpicc/Makefile
index b4270ab..e11eae5 100644
--- a/openpicc/Makefile
+++ b/openpicc/Makefile
@@ -110,9 +110,9 @@ ARM_SRC= \
os/core/MemMang/heap_2.c \
os/usb/USB-CDC.c \
os/usb/USBIsr.c \
- application/iso14443_sniffer.c \
+ application/iso14443a_pretender.c \
+# application/iso14443_sniffer.c \
# application/tc_sniffer.c \
-# application/iso14443a_pretender.c \
# application/iso14443_layer3a.c
#
diff --git a/openpicc/application/iso14443.h b/openpicc/application/iso14443.h
index a2d7458..e2418ca 100644
--- a/openpicc/application/iso14443.h
+++ b/openpicc/application/iso14443.h
@@ -80,6 +80,7 @@ typedef enum {
FRAME_PENDING, /* Frame is currently filled by Rx */
FRAME_FULL, /* Frame has been filled by Rx */
FRAME_PROCESSING,/* The frame is currently processed by the consumer */
+ FRAME_PREFILLED, /* The frame has been prefilled for later usage (only used for TX) */
} iso14443_frame_state_t;
diff --git a/openpicc/application/iso14443_layer2a.c b/openpicc/application/iso14443_layer2a.c
index 65d5d6a..2288eaa 100644
--- a/openpicc/application/iso14443_layer2a.c
+++ b/openpicc/application/iso14443_layer2a.c
@@ -132,7 +132,8 @@ int iso14443_transmit(ssc_dma_tx_buffer_t *buffer, unsigned int fdt, u_int8_t as
clock_switch(CLOCK_SELECT_CARRIER);
ssc_set_gate(0);
tc_fdt_set(fdt);
- tc_cdiv_set_divider(8); // FIXME Magic hardcoded number
+ // We'll keep the divider at 8
+ //tc_cdiv_set_divider(8); // FIXME Magic hardcoded number
if(!async) {
/* FIXME Implement */
@@ -184,6 +185,11 @@ u_int8_t iso14443_get_fast_receive(void)
static void iso14443_ssc_callback(ssc_callback_reason reason, void *data)
{
+ if( reason == SSC_CALLBACK_SETUP ) {
+ // We'll keep the divider at 8
+ tc_cdiv_set_divider(8); // FIXME Magic hardcoded number
+ }
+
if(reason == SSC_CALLBACK_RX_FRAME_BEGIN) {
/* Busy loop for the frame end */
int *end_asserted = data, i=0;
@@ -217,7 +223,8 @@ static void iso14443_ssc_callback(ssc_callback_reason reason, void *data)
clock_switch(CLOCK_SELECT_CARRIER);
ssc_set_gate(1);
tc_fdt_set(0xff00);
- tc_cdiv_set_divider(RX_DIVIDER);
+ // We'll keep the divider at 8
+ //tc_cdiv_set_divider(RX_DIVIDER);
tc_cdiv_sync_reset();
#if 1
int old=usb_print_set_default_flush(0);
@@ -243,7 +250,8 @@ static void iso14443_tc_recv_callback(tc_recv_callback_reason reason, void *data
clock_switch(CLOCK_SELECT_CARRIER);
ssc_set_gate(1);
tc_fdt_set(0xff00);
- tc_cdiv_set_divider(RX_DIVIDER);
+ // We'll keep the divider at 8
+ //tc_cdiv_set_divider(RX_DIVIDER);
tc_cdiv_sync_reset();
}
}
diff --git a/openpicc/application/iso14443a_diffmiller.c b/openpicc/application/iso14443a_diffmiller.c
index d73bf95..a36ea6b 100644
--- a/openpicc/application/iso14443a_diffmiller.c
+++ b/openpicc/application/iso14443a_diffmiller.c
@@ -101,6 +101,7 @@ struct diffmiller_state {
u_int32_t counter;
u_int16_t byte,crc;
u_int8_t parity;
+ u_int8_t last_data_bit;
struct {
u_int8_t in_frame:1;
u_int8_t frame_finished:1;
@@ -155,7 +156,7 @@ static inline void append_to_frame(struct diffmiller_state *const state,
}
-static inline void end_frame(struct diffmiller_state * const state, const u_int32_t counter)
+static inline void end_frame(struct diffmiller_state * const state, const u_int32_t counter, const int last_data_bit)
{
if(state->frame != NULL) {
if(counter > 0) {
@@ -167,6 +168,11 @@ static inline void end_frame(struct diffmiller_state * const state, const u_int3
else
state->frame->parameters.a.crc = CRC_ERROR;
+ if(last_data_bit)
+ state->frame->parameters.a.last_bit = ISO14443A_LAST_BIT_1;
+ else
+ state->frame->parameters.a.last_bit = ISO14443A_LAST_BIT_0;
+
state->flags.frame_finished = 1;
}
}
@@ -175,6 +181,7 @@ static inline void end_frame(struct diffmiller_state * const state, const u_int3
//#define PRINT_BIT(a) usb_print_string_f(a,0)
#define DO_BIT_0 { \
+ last_data_bit = 0; \
if(++counter==9) { \
append_to_frame(state, state->byte, 0, 8); \
counter=state->byte=state->parity=0; \
@@ -183,6 +190,7 @@ static inline void end_frame(struct diffmiller_state * const state, const u_int3
}
#define DO_BIT_1 { \
+ last_data_bit = 1; \
if(counter<8) { \
state->byte |= (1<<counter); \
state->parity ^= 1; \
@@ -218,7 +226,7 @@ static inline void end_frame(struct diffmiller_state * const state, const u_int3
in_frame = 0; \
} else { \
if(last_bit == BIT_0) { \
- end_frame(state, counter); \
+ end_frame(state, counter, last_data_bit); \
PRINT_BIT(" EOF\n"); \
last_bit = BIT_EOF; \
in_frame = 0; \
@@ -255,6 +263,7 @@ int iso14443a_decode_diffmiller(struct diffmiller_state * const state, iso14443_
int in_frame = state->flags.in_frame;
int error = state->flags.error;
int counter = state->counter;
+ int last_data_bit = state->last_data_bit;
for(; *offset < buflen; ) {
int delta;
@@ -324,6 +333,7 @@ int iso14443a_decode_diffmiller(struct diffmiller_state * const state, iso14443_
state->old_state = old_state;
state->last_bit = last_bit;
state->counter = counter;
+ state->last_data_bit = last_data_bit;
state->flags.in_frame = in_frame;
state->flags.error = error;
@@ -338,7 +348,7 @@ int iso14443a_diffmiller_assert_frame_ended(struct diffmiller_state * const stat
if(state->frame != NULL && state->frame != frame) return -EINVAL;
state->frame = frame;
- end_frame(state, state->counter);
+ end_frame(state, state->counter, state->last_data_bit);
PRINT_BIT(" EOF2\n");
state->flags.in_frame = 0;
diff --git a/openpicc/application/iso14443a_pretender.c b/openpicc/application/iso14443a_pretender.c
index 03fb12d..c6f54cc 100644
--- a/openpicc/application/iso14443a_pretender.c
+++ b/openpicc/application/iso14443a_pretender.c
@@ -42,6 +42,7 @@ extern volatile int fdt_offset;
static const iso14443_frame ATQA_FRAME = {
TYPE_A,
+ FRAME_PREFILLED,
{{STANDARD_FRAME, PARITY, ISO14443A_LAST_BIT_NONE, CRC_UNCALCULATED}},
2,
0, 0,
@@ -51,6 +52,7 @@ static const iso14443_frame ATQA_FRAME = {
static const iso14443_frame UID_FRAME = {
TYPE_A,
+ FRAME_PREFILLED,
{{STANDARD_FRAME, PARITY, ISO14443A_LAST_BIT_NONE, CRC_UNCALCULATED}},
5,
0, 0,
@@ -60,6 +62,7 @@ static const iso14443_frame UID_FRAME = {
static const iso14443_frame ATS_FRAME = {
TYPE_A,
+ FRAME_PREFILLED,
{{STANDARD_FRAME, PARITY, ISO14443A_LAST_BIT_NONE, CRC_UNCALCULATED}},
3,
0, 0,
@@ -69,6 +72,7 @@ static const iso14443_frame ATS_FRAME = {
static const iso14443_frame NONCE_FRAME = {
TYPE_A,
+ FRAME_PREFILLED,
{{STANDARD_FRAME, PARITY, ISO14443A_LAST_BIT_NONE, CRC_UNCALCULATED}},
4,
0, 0,
@@ -79,10 +83,11 @@ static const iso14443_frame NONCE_FRAME = {
#define FRAME_SIZE(bytes) (2* (1+(9*bytes)+1) )
#define SIZED_BUFFER(bytes) struct { int len; u_int8_t data[FRAME_SIZE(bytes)]; }
+#define BYTES_AND_BITS(bytes,bits) (bytes*9+bits)
static ssc_dma_tx_buffer_t ATQA_BUFFER, UID_BUFFER, ATS_BUFFER, NONCE_BUFFER;
-static void fast_receive_callback(ssc_dma_rx_buffer_t *buffer, u_int8_t in_irq)
+static void fast_receive_callback(ssc_dma_rx_buffer_t *buffer, iso14443_frame *frame, u_int8_t in_irq)
{
(void)buffer; (void)in_irq;
unsigned int buffy=0;
@@ -91,24 +96,30 @@ static void fast_receive_callback(ssc_dma_rx_buffer_t *buffer, u_int8_t in_irq)
ssc_dma_tx_buffer_t *tx_buffer=NULL;
int fdt = 0;
- switch(buffer->len_transfers) {
- case 3: case 4: /* REQA (7 bits) */
- //case 7: case 8: case 9:
- case 11:
+ switch(frame->parameters.a.last_bit) {
+ case ISO14443A_LAST_BIT_0:
+ fdt = 20;
+ break;
+ case ISO14443A_LAST_BIT_1:
+ fdt = 84;
+ break;
+ case ISO14443A_LAST_BIT_NONE:
+ fdt = 0;
+ break;
+ }
+
+ switch(BYTES_AND_BITS(frame->numbytes,frame->numbits)) {
+ case BYTES_AND_BITS(0, 7): /* REQA (7 bits) */
tx_buffer = &ATQA_BUFFER;
- fdt = 1172;
+ fdt += 9*128;
break;
- case 6: case 7: /* ANTICOL (2 bytes) */
- case 8: case 9:
+ case BYTES_AND_BITS(2, 0): /* ANTICOL (2 bytes) */
tx_buffer = &UID_BUFFER;
- fdt = 1172;
- case 21: case 22: /* SELECT (9 bytes) */
- tx_buffer = &ATS_BUFFER;
- fdt = 1172;
+ fdt += 9*128;
break;
- case 577:
- usb_print_string_f("f", 0);
- buffy=(unsigned int)buffer;
+ case BYTES_AND_BITS(9, 0): /* SELECT (9 bytes) */
+ tx_buffer = &ATS_BUFFER;
+ fdt += 9*128;
break;
}
@@ -116,7 +127,6 @@ static void fast_receive_callback(ssc_dma_rx_buffer_t *buffer, u_int8_t in_irq)
//fdt += 3*128;
fdt += fdt_offset;
-
if(tx_buffer != NULL) {
tx_buffer->state = SSC_FULL;
if( iso14443_transmit(tx_buffer, fdt, 1, 0) < 0) {
@@ -208,28 +218,25 @@ prefill_failed:
#define DETECTED_MIFARE 4
while(true) {
- ssc_dma_rx_buffer_t *buffer = 0;
- res = iso14443_receive(fast_receive_callback, &buffer, 1000 * portTICK_RATE_MS);
+ iso14443_frame *frame = 0;
+ res = iso14443_receive(fast_receive_callback, &frame, 1000 * portTICK_RATE_MS);
if(res >= 0) {
- DumpUIntToUSB(buffer->len_transfers);
- DumpStringToUSB("\n\r");
-
- switch(buffer->len_transfers) {
- case 3: case 4: /* REQA (7 bits) */
+ switch(BYTES_AND_BITS(frame->numbytes, frame->numbits) ) {
+ case BYTES_AND_BITS(0, 7): /* REQA (7 bits) */
current_detected |= DETECTED_14443A_3;
break;
- case 6: case 7: /* ANTICOL (2 bytes) */
- case 22: /* SELECT (9 bytes) */
+ case BYTES_AND_BITS(2, 0): /* ANTICOL (2 bytes) */
+ case BYTES_AND_BITS(9, 0): /* SELECT (9 bytes) */
current_detected |= DETECTED_14443A_3;
break;
- case 10: case 11: /* AUTH1A (or any other four byte frame) */
- case 19: case 20: /* AUTH2 (8 bytes) */
+ case BYTES_AND_BITS(4, 0): /* AUTH1A (or any other four byte frame) */
+ case BYTES_AND_BITS(8, 0): /* AUTH2 (8 bytes) */
current_detected |= DETECTED_MIFARE;
break;
}
portENTER_CRITICAL();
- buffer->state = SSC_FREE;
+ frame->state = FRAME_FREE;
portEXIT_CRITICAL();
} else {
if(res != -ETIMEDOUT) {
diff --git a/openpicc/application/main.c b/openpicc/application/main.c
index a082933..d9b0ad5 100644
--- a/openpicc/application/main.c
+++ b/openpicc/application/main.c
@@ -211,10 +211,10 @@ int main (void)
NULL, TASK_USB_PRIORITY, NULL);
/*xTaskCreate (iso14443_layer3a_state_machine, (signed portCHAR *) "ISO14443A-3", TASK_ISO_STACK,
NULL, TASK_ISO_PRIORITY, NULL);*/
- xTaskCreate (iso14443_sniffer, (signed portCHAR *) "ISO14443-SNIFF", TASK_ISO_STACK,
- NULL, TASK_ISO_PRIORITY, NULL);
- /*xTaskCreate (iso14443a_pretender, (signed portCHAR *) "ISO14443A-PRETEND", TASK_ISO_STACK,
+ /*xTaskCreate (iso14443_sniffer, (signed portCHAR *) "ISO14443-SNIFF", TASK_ISO_STACK,
NULL, TASK_ISO_PRIORITY, NULL);*/
+ xTaskCreate (iso14443a_pretender, (signed portCHAR *) "ISO14443A-PRETEND", TASK_ISO_STACK,
+ NULL, TASK_ISO_PRIORITY, NULL);
/*xTaskCreate (tc_sniffer, (signed portCHAR *) "RFID-SNIFFER", TASK_ISO_STACK,
NULL, TASK_ISO_PRIORITY, NULL);*/
diff --git a/openpicc/application/ssc.c b/openpicc/application/ssc.c
index 9f30400..78f2960 100644
--- a/openpicc/application/ssc.c
+++ b/openpicc/application/ssc.c
@@ -234,7 +234,9 @@ static int __ramfunc _ssc_tx_irq(u_int32_t sr, portBASE_TYPE task_woken)
/* Also set SSC mode to continous
* FIXME BUG: This will somehow drop some samples or something on the SSC*/
+ vLedSetGreen(0);
sh->ssc->SSC_TCMR = (sh->ssc->SSC_TCMR & ~AT91C_SSC_START) | AT91C_SSC_START_CONTINOUS;
+ vLedSetGreen(1);
if(sh->callback)
sh->callback(SSC_CALLBACK_TX_FRAME_BEGIN, NULL);
personal git repositories of Harald Welte. Your mileage may vary