From 202b56a42c5e6a171ee43b469be48525d0e8e350 Mon Sep 17 00:00:00 2001 From: henryk Date: Wed, 12 Dec 2007 01:50:14 +0000 Subject: Add new miller decoder (not working yet) Vastly improve timing through CPU cycle counting. Jitter is now like 40ns (the SSC_DATA edge detection fuzziness) in 2 main clusters 4 CPU cycles (83ns) apart, plus an occasional glitch adding 4 CPU cycles in either direction git-svn-id: https://svn.openpcd.org:2342/trunk@385 6dc7ffe9-61d6-0310-9af1-9938baff3ed1 --- openpicc/application/iso14443_layer3a.c | 27 ++++--- openpicc/application/iso14443_layer3a.h | 30 ++++---- openpicc/application/iso14443a_manchester.c | 1 + openpicc/application/iso14443a_miller.c | 112 ++++++++++++++++++++++++++++ openpicc/application/iso14443a_miller.h | 6 ++ openpicc/application/tc_fdt.c | 12 +-- openpicc/application/tc_fdt.h | 2 +- 7 files changed, 156 insertions(+), 34 deletions(-) create mode 100644 openpicc/application/iso14443a_miller.c create mode 100644 openpicc/application/iso14443a_miller.h (limited to 'openpicc/application') diff --git a/openpicc/application/iso14443_layer3a.c b/openpicc/application/iso14443_layer3a.c index 0b5ceaf..35152db 100644 --- a/openpicc/application/iso14443_layer3a.c +++ b/openpicc/application/iso14443_layer3a.c @@ -37,13 +37,14 @@ #include "load_modulation.h" #include "decoder.h" #include "iso14443a_manchester.h" +#include "iso14443a_miller.h" #include "led.h" static enum ISO14443_STATES state = STARTING_UP; const iso14443_frame ATQA_FRAME = { TYPE_A, {{STANDARD_FRAME, PARITY}}, - 2, + 2, 0, 0, {4, 0}, {} @@ -85,11 +86,11 @@ const iso14443_frame NULL_FRAME = { void iso14443_transmit(ssc_dma_tx_buffer_t *buf, int fdt, int div) { tc_cdiv_set_divider(div); - if(fdt == ISO14443A_TRANSMIT_AT_NEXT_INTERVAL_0 || - fdt == ISO14443A_TRANSMIT_AT_NEXT_INTERVAL_1) { - /* FIXME Implement */ - return; - } + if(fdt == ISO14443A_TRANSMIT_AT_NEXT_INTERVAL_0) { + fdt = tc_fdt_get_next_slot(ISO14443A_FDT_SHORT_0, ISO14443A_FDT_SLOTLEN); + } else if (fdt == ISO14443A_TRANSMIT_AT_NEXT_INTERVAL_1) { + fdt = tc_fdt_get_next_slot(ISO14443A_FDT_SHORT_1, ISO14443A_FDT_SLOTLEN); + } ssc_tx_fiq_fdt_cdiv = fdt -3*div -1; tc_fdt_set(ssc_tx_fiq_fdt_cdiv -MAX_TF_FIQ_ENTRY_DELAY -MAX_TF_FIQ_OVERHEAD); ssc_tx_fiq_fdt_ssc = fdt -div +1; @@ -162,7 +163,7 @@ static int prefill_buffer(ssc_dma_tx_buffer_t *dest, const iso14443_frame *src) } -static u_int8_t received_buffer[256]; +static iso14443_frame received_frame; static void enable_reception(enum ssc_mode mode) { tc_fdt_set(0xff00); @@ -307,6 +308,12 @@ void iso14443_layer3a_state_machine (void *pvParameters) LAYER3_DEBUG(", woke up to send ATQA\n\r"); atqa_sent = 0; } + if(1) { + DumpStringToUSB("Decoded: "); + iso14443a_decode_miller(&received_frame, buffer->data, buffer->len); + DumpBufferToUSB((char*)received_frame.data, 100); + DumpStringToUSB("\n\r"); + } /* For debugging, wait 1ms, then wait for another frame * Normally we'd go to anticol from here*/ vTaskDelay(portTICK_RATE_MS); @@ -320,12 +327,12 @@ void iso14443_layer3a_state_machine (void *pvParameters) break; case ACTIVE: case ACTIVE_STAR: - if(0) { +#if 0 DumpStringToUSB("Decoded: "); decoder_decode(DECODER_MILLER, (const char*)buffer->data, buffer->len, received_buffer); DumpBufferToUSB((char*)received_buffer, 100); DumpStringToUSB("\n\r"); - } +#endif /* Wait for another frame */ if(0) { ssc_rx_mode_set(SSC_MODE_14443A_STANDARD); @@ -336,7 +343,7 @@ void iso14443_layer3a_state_machine (void *pvParameters) if(prefill_buffer(&ssc_tx_buffer, &NULL_FRAME)) { usb_print_string_f("Sending response ...",0); ssc_tx_buffer.state = PROCESSING; - iso14443_transmit(&ssc_tx_buffer, 1, 8); + iso14443_transmit(&ssc_tx_buffer, ISO14443A_TRANSMIT_AT_NEXT_INTERVAL_1, 8); while( ssc_tx_buffer.state != FREE ) { vTaskDelay(portTICK_RATE_MS); } diff --git a/openpicc/application/iso14443_layer3a.h b/openpicc/application/iso14443_layer3a.h index 495ca2e..26a8a2d 100644 --- a/openpicc/application/iso14443_layer3a.h +++ b/openpicc/application/iso14443_layer3a.h @@ -16,21 +16,6 @@ enum ISO14443_STATES { }; /******************** RX ************************************/ -/* Magic delay, don't know where it comes from */ -#define MAGIC_OFFSET -32 -/* Delay from modulation till detection in SSC_DATA */ -#define DETECTION_DELAY 11 -/* See fdt_timinig.dia for these values */ -#define MAX_TF_FIQ_ENTRY_DELAY 16 -#define MAX_TF_FIQ_OVERHEAD 75 /* guesstimate */ -extern volatile int fdt_offset; -/* standard derived magic values */ -#define ISO14443A_FDT_SLOTLEN 128 -#define ISO14443A_FDT_OFFSET_1 84 -#define ISO14443A_FDT_OFFSET_0 20 -#define ISO14443A_FDT_SHORT_1 (ISO14443A_FDT_SLOTLEN*9 + ISO14443A_FDT_OFFSET_1 +fdt_offset +MAGIC_OFFSET -DETECTION_DELAY) -#define ISO14443A_FDT_SHORT_0 (ISO14443A_FDT_SLOTLEN*9 + ISO14443A_FDT_OFFSET_0 +fdt_offset +MAGIC_OFFSET -DETECTION_DELAY) - #ifdef FOUR_TIMES_OVERSAMPLING /* definitions for four-times oversampling */ /* Sample values for the REQA and WUPA short frames */ @@ -82,6 +67,21 @@ extern volatile int fdt_offset; #endif /******************** TX ************************************/ +/* Magic delay, don't know where it comes from */ +#define MAGIC_OFFSET -32 +/* Delay from modulation till detection in SSC_DATA */ +#define DETECTION_DELAY 11 +/* See fdt_timinig.dia for these values */ +#define MAX_TF_FIQ_ENTRY_DELAY 16 +#define MAX_TF_FIQ_OVERHEAD 75 /* guesstimate */ +extern volatile int fdt_offset; +/* standard derived magic values */ +#define ISO14443A_FDT_SLOTLEN 128 +#define ISO14443A_FDT_OFFSET_1 84 +#define ISO14443A_FDT_OFFSET_0 20 +#define ISO14443A_FDT_SHORT_1 (ISO14443A_FDT_SLOTLEN*9 + ISO14443A_FDT_OFFSET_1 +fdt_offset +MAGIC_OFFSET -DETECTION_DELAY) +#define ISO14443A_FDT_SHORT_0 (ISO14443A_FDT_SLOTLEN*9 + ISO14443A_FDT_OFFSET_0 +fdt_offset +MAGIC_OFFSET -DETECTION_DELAY) + /* in bytes, not counting parity */ #define MAXIMUM_FRAME_SIZE 256 diff --git a/openpicc/application/iso14443a_manchester.c b/openpicc/application/iso14443a_manchester.c index be4de21..4093d57 100644 --- a/openpicc/application/iso14443a_manchester.c +++ b/openpicc/application/iso14443a_manchester.c @@ -1,5 +1,6 @@ /* ISO14443A Manchester encoder for OpenPICC * (C) 2006 by Harald Welte + * (C) 2007 by Henryk Plötz * * 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 diff --git a/openpicc/application/iso14443a_miller.c b/openpicc/application/iso14443a_miller.c new file mode 100644 index 0000000..deb9a8a --- /dev/null +++ b/openpicc/application/iso14443a_miller.c @@ -0,0 +1,112 @@ +/* ISO14443A Manchester encoder for OpenPICC + * (C) 2007 by Henryk Plötz + * + * 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; either version 2 of the License, or + * (at your option) any later version. + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include +#include + +#include + +#include "iso14443_layer3a.h" +#include "usb_print.h" +#include "cmd.h" + +#ifdef FOUR_TIMES_OVERSAMPLING +#define OVERSAMPLING_RATE 4 + +/* definitions for four-times oversampling */ +#define SEQ_X 0x4 +#define SEQ_Y 0x0 +#define SEQ_Z 0x1 +#else +#define OVERSAMPLING_RATE 2 +#define SEQ_X 0x2 +#define SEQ_Y 0x0 +#define SEQ_Z 0x1 +#endif + +enum miller_sequence { + SEQUENCE_X, + SEQUENCE_Y, + SEQUENCE_Z, +}; + +#define BIT_ENDMARKER -1 + +int iso14443a_decode_miller(iso14443_frame *frame, + const u_int8_t *sample_buf, const u_int16_t sample_buf_len) +{ + signed int i, j, bit = 0, last_bit = 0; + enum miller_sequence current_seq; + unsigned int bitpos = 0; + + memset(frame, 0, sizeof(frame)); + frame->type = TYPE_A; + frame->parameters.a.parity = GIVEN_PARITY; + + for(i=0; i>(j*OVERSAMPLING_RATE)) & ~(~0 << OVERSAMPLING_RATE); + switch(sample) { + case SEQ_X: current_seq = SEQUENCE_X; break; + case SEQ_Y: current_seq = SEQUENCE_Y; break; + case SEQ_Z: current_seq = SEQUENCE_Z; break; + default: current_seq = SEQUENCE_Y; + } + + switch(current_seq) { + case SEQ_X: + DumpStringToUSB("X"); + bit = 1; break; + case SEQ_Y: /* Fall-through to SEQ_Z */ + DumpStringToUSB("Y"); + if(last_bit == 0) { + bit = BIT_ENDMARKER; + break; + } + case SEQ_Z: + DumpStringToUSB("Z"); + bit = 0; break; + } + + switch(bit) { + case BIT_ENDMARKER: + bitpos--; + break; + case 0: /* Fall-through */ + case 1: { + int bytepos = bitpos/9; + if(bitpos % 9 == 8) { /* Parity bit */ + frame->parity[ bytepos/8 ] |= (bit<<(bytepos%8)); + } else { + frame->data[ bytepos ] |= (bit<<(bitpos%9)); + } + } + } + + last_bit = bit; + bitpos++; + } + } + + frame->numbytes = bitpos/9; + frame->numbits = bitpos%9; + DumpStringToUSB("\n\r"); + + return 0; +} diff --git a/openpicc/application/iso14443a_miller.h b/openpicc/application/iso14443a_miller.h new file mode 100644 index 0000000..dbd7f85 --- /dev/null +++ b/openpicc/application/iso14443a_miller.h @@ -0,0 +1,6 @@ +#ifndef ISO14443A_MILLER_H_ +#define ISO14443A_MILLER_H_ + +extern int iso14443a_decode_miller(iso14443_frame *frame, const u_int8_t *sample_buf, const u_int16_t sample_buf_len); + +#endif /*ISO14443A_MILLER_H_*/ diff --git a/openpicc/application/tc_fdt.c b/openpicc/application/tc_fdt.c index 7413e11..2a306ef 100644 --- a/openpicc/application/tc_fdt.c +++ b/openpicc/application/tc_fdt.c @@ -50,16 +50,12 @@ void tc_fdt_set(u_int16_t count) tcfdt->TC_RA = count; } -void __ramfunc tc_fdt_set_to_next_slot(int last_bit) +int tc_fdt_get_next_slot(int reference_time, int slotlen) { - int reference_time; - if(last_bit == 0) reference_time = ISO14443A_FDT_OFFSET_0; - else reference_time = ISO14443A_FDT_OFFSET_1; - - if(tcfdt->TC_SR & AT91C_TC_CLKSTA) + /*if(tcfdt->TC_SR & AT91C_TC_CLKSTA) while(tcfdt->TC_CV != 0xFFFF && (tcfdt->TC_CV - reference_time) % 128 != 0); - tcfdt->TC_CCR = AT91C_TC_SWTRG; - tc_fdt_set(2*128); + tcfdt->TC_CCR = AT91C_TC_SWTRG;*/ + return tcfdt->TC_CV + (slotlen-((tcfdt->TC_CV - reference_time) % slotlen)) + 3*slotlen; } diff --git a/openpicc/application/tc_fdt.h b/openpicc/application/tc_fdt.h index 28e7e7e..6e89f51 100644 --- a/openpicc/application/tc_fdt.h +++ b/openpicc/application/tc_fdt.h @@ -5,6 +5,6 @@ extern void tc_fdt_init(void); extern void tc_fdt_set(u_int16_t count); -extern void __ramfunc tc_fdt_set_to_next_slot(int last_bit); +extern int tc_fdt_get_next_slot(int reference_time, int slotlen); #endif -- cgit v1.2.3