diff options
Diffstat (limited to 'openpicc')
| -rw-r--r-- | openpicc/Makefile | 1 | ||||
| -rw-r--r-- | openpicc/application/iso14443_layer3a.c | 27 | ||||
| -rw-r--r-- | openpicc/application/iso14443_layer3a.h | 30 | ||||
| -rw-r--r-- | openpicc/application/iso14443a_manchester.c | 1 | ||||
| -rw-r--r-- | openpicc/application/iso14443a_miller.c | 112 | ||||
| -rw-r--r-- | openpicc/application/iso14443a_miller.h | 6 | ||||
| -rw-r--r-- | openpicc/application/tc_fdt.c | 12 | ||||
| -rw-r--r-- | openpicc/application/tc_fdt.h | 2 | ||||
| -rw-r--r-- | openpicc/os/boot/boot.s | 31 | 
9 files changed, 187 insertions, 35 deletions
| diff --git a/openpicc/Makefile b/openpicc/Makefile index e35dc27..92a7351 100644 --- a/openpicc/Makefile +++ b/openpicc/Makefile @@ -90,6 +90,7 @@ ARM_SRC= \    application/usb_print.c \    application/iso14443_layer3a.c \    application/iso14443a_manchester.c \ +  application/iso14443a_miller.c \    application/load_modulation.c \    application/decoder_miller.c \    application/decoder_nrzl.c \ 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 <hwelte@hmw-consulting.de> + * (C) 2007 by 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  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 <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; 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 <openpicc.h> +#include <FreeRTOS.h> + +#include <string.h> + +#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<sample_buf_len && bit != BIT_ENDMARKER; i++) { +		for(j=0; j<(signed)(sizeof(sample_buf[0])*8)/OVERSAMPLING_RATE && bit != BIT_ENDMARKER; j++) { +			int sample = (sample_buf[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 diff --git a/openpicc/os/boot/boot.s b/openpicc/os/boot/boot.s index 0000479..c065a6d 100644 --- a/openpicc/os/boot/boot.s +++ b/openpicc/os/boot/boot.s @@ -250,10 +250,39 @@ my_fiq_handler:                  ldr   r11, =ssc_tx_fiq_fdt_cdiv                  ldr   r11, [r11]               /* r11 == ssc_tx_fiq_fdt_cdiv */ +/* Problem: LDR from the timer still takes too long and causes us to miss the exact time. + * Strategy: Spin on TC2 till we are very near the actual time. Then load the timer value, calculate + * the difference to the target, then do a countdown spin without reading the timer. + *  + * At 47.923200 MHz 7 processor cycles are 2 carrier cycles of the 13.56MHz carrier + */ + .equ SUB_TIME, 20 /* subtract 20 carrier cycles == 70 processor cycles */ + .equ ADD_TIME, (70-20) /* Add x processor cycles */ +  + 				mov r8, #SUB_TIME + 				sub r11, r11, r8               +  .wait_for_fdt_cdiv:    				ldr   r8, [r12, #TC2_CV]  				cmp   r8, r11 -				bmi   .wait_for_fdt_cdiv       /* spin while TC2.CV is less fdt_cdiv */ +				bmi   .wait_for_fdt_cdiv       /* spin while TC2.CV is less fdt_cdiv-SUB_TIM */ +				 +				ldr r8, [r12, #TC2_CV] +				sub r11, r11, r8               /* r11 == fdt_cdiv-SUB_TIME - TC2.CV */ +				 +				mov r8, #0x07 +				mul r11, r8, r11               /* r11 = r11 * 7 */ +				mov r11, r11, ASR #1           /* r11 = r11 / 2 */ +				 +				mov r8, #ADD_TIME +				add r11, r11, r8               /* r11 = r11 + ADD_TIME */ +				 +				mov r11, r11, ASR #2           /* r11 = r11 / 4   (4 is the number of cycles per loop run below) */ +				 +				mov r8, #1 +.wait_for_my_time: +				subs r11, r11, r8 +				bge .wait_for_my_time  				str   r9, [r12, #TC_CCR]       /* SWTRG on TC0 */ | 
