diff options
Diffstat (limited to 'openpicc')
| -rw-r--r-- | openpicc/Makefile | 5 | ||||
| -rw-r--r-- | openpicc/application/cmd.c | 4 | ||||
| -rw-r--r-- | openpicc/application/iso14443.h | 9 | ||||
| -rw-r--r-- | openpicc/application/iso14443_layer2a.c | 71 | ||||
| -rw-r--r-- | openpicc/application/iso14443_layer2a.h | 17 | ||||
| -rw-r--r-- | openpicc/application/iso14443_layer3a.c | 24 | ||||
| -rw-r--r-- | openpicc/application/iso14443_sniffer.c | 37 | ||||
| -rw-r--r-- | openpicc/application/iso14443a_diffmiller.c | 37 | ||||
| -rw-r--r-- | openpicc/application/iso14443a_diffmiller.h | 2 | ||||
| -rw-r--r-- | openpicc/application/iso14443a_pretender.c | 4 | ||||
| -rw-r--r-- | openpicc/application/main.c | 8 | ||||
| -rw-r--r-- | openpicc/application/openpicc.h | 1 | ||||
| -rw-r--r-- | openpicc/application/performance.c | 5 | ||||
| -rw-r--r-- | openpicc/application/ssc.c | 34 | ||||
| -rw-r--r-- | openpicc/application/ssc.h | 22 | ||||
| -rw-r--r-- | openpicc/application/ssc_buffer.h | 10 | ||||
| -rw-r--r-- | openpicc/application/tc_recv.c | 213 | ||||
| -rw-r--r-- | openpicc/application/tc_recv.h | 21 | ||||
| -rw-r--r-- | openpicc/application/tc_sniffer.c | 8 | 
19 files changed, 400 insertions, 132 deletions
diff --git a/openpicc/Makefile b/openpicc/Makefile index e70eab7..b4270ab 100644 --- a/openpicc/Makefile +++ b/openpicc/Makefile @@ -88,6 +88,7 @@ ARM_SRC= \    application/tc_cdiv_sync.c \    application/tc_fdt.c \    application/tc_cdiv.c \ +  application/tc_recv.c \    application/usb_print.c \    application/iso14443_layer2a.c \    application/iso14443a_manchester.c \ @@ -109,9 +110,9 @@ ARM_SRC= \    os/core/MemMang/heap_2.c \    os/usb/USB-CDC.c \    os/usb/USBIsr.c \ -  application/tc_sniffer.c \ +  application/iso14443_sniffer.c \ +#  application/tc_sniffer.c \  #  application/iso14443a_pretender.c \ -#  application/iso14443_sniffer.c \  #  application/iso14443_layer3a.c  # diff --git a/openpicc/application/cmd.c b/openpicc/application/cmd.c index 4d7d6b2..412a349 100644 --- a/openpicc/application/cmd.c +++ b/openpicc/application/cmd.c @@ -243,9 +243,9 @@ void prvExecCommand(u_int32_t cmd, portCHAR *args) {  		case 'P':  		    print_pio();  		    break; -		case 'R': +/*		case 'R':  			start_stop_sniffing(); -			break; +			break;*/  		case 'C':  		    DumpStringToUSB(  			" *****************************************************\n\r" diff --git a/openpicc/application/iso14443.h b/openpicc/application/iso14443.h index d3439d1..a2d7458 100644 --- a/openpicc/application/iso14443.h +++ b/openpicc/application/iso14443.h @@ -75,8 +75,17 @@  #define MAXIMUM_FRAME_SIZE 256  #define ISO14443A_MAX_RX_FRAME_SIZE_IN_BITS (MAXIMUM_FRAME_SIZE*9 +2) +typedef enum { +	FRAME_FREE=0,    /* Frame is free */ +	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 */ +} iso14443_frame_state_t; + +  typedef struct {    enum { TYPE_A, TYPE_B } type; +  iso14443_frame_state_t state;    union {    	struct {    		enum { SHORT_FRAME, STANDARD_FRAME, AC_FRAME } format; 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; diff --git a/openpicc/application/iso14443_layer2a.h b/openpicc/application/iso14443_layer2a.h index 858af81..a8874d0 100644 --- a/openpicc/application/iso14443_layer2a.h +++ b/openpicc/application/iso14443_layer2a.h @@ -4,36 +4,37 @@  #include "ssc_buffer.h"  /* Callback type for iso14443_receive(). - * Parameter buffer is being passed a pointer to an SSC Rx buffer structure that this receive happened - * on. You might want to pass this into iso14443a_decode_miller(). + * Parameter buffer is either being passed a pointer to an SSC Rx buffer structure that this  + * receive happened on, or a fully decoded iso14443_frame.  + * If it's an SSC buffer you might want to pass this into iso14443a_decode_miller().   * Parameter in_irq is true if the callback has been called while still in IRQ mode. It must then *NOT*   * perform any calls that might upset the IRQ processing. Especially it may not call into FreeRTOS or   * any parts of the applications that do.   */ -typedef void (*iso14443_receive_callback_t)(ssc_dma_rx_buffer_t *buffer, u_int8_t in_irq); +typedef void (*iso14443_receive_callback_t)(ssc_dma_rx_buffer_t *buffer, iso14443_frame *frame, u_int8_t in_irq);  /* Wait for and receive a frame. Parameters callback and buffer are optional. If you omit them you'll lose   * the received frame, obviously.   * Parameter callback is a callback function that will be called for each received frame and might   * then trigger a response. - * Parameter buffer is an output pointer to a pointer to an SSC Rx buffer structure containing the + * Parameter frame is an output pointer to a pointer to an ISO14443 frame structure containing the   * received frame.   * Parameter timeout gives an optional timeout for the receive operation after which the receive will   * be aborted. When timeout is 0 the receive will not time out.   * This call will block until a frame is received or an exception happens. Obviously it must not be run   * from IRQ context.   *  - * Warning: When you get a buffer from the function then its state is set to PROCESSING and you must  - * FREE it yourself. However, you MUST NOT free a buffer from the callback. + * Warning: When you get a frame from the function then its state is set to SSC_PROCESSING and you must  + * SSC_FREE it yourself. However, you MUST NOT free a buffer or a frame from the callback.   *    * Return values: - * >= 0        Frame received, return value is buffer length (yes, 0 is a valid buffer length) + * = 0         Frame received   * -ENETDOWN   PLL is not locked or PLL lock lost   * -ETIMEDOUT  Receive timed out without receiving anything (usually not regarded an error condition)   * -EBUSY      A Tx is currently running or pending; can't receive   * -EALREADY   There's already an iso14443_receive() invocation running   */ -extern int iso14443_receive(iso14443_receive_callback_t callback, ssc_dma_rx_buffer_t **buffer, unsigned int timeout); +extern int iso14443_receive(iso14443_receive_callback_t callback, iso14443_frame **frame, unsigned int timeout);  /*   * Transmit a frame. Starts transmitting fdt carrier cycles after the end of the received frame. diff --git a/openpicc/application/iso14443_layer3a.c b/openpicc/application/iso14443_layer3a.c index daac8dd..132038e 100644 --- a/openpicc/application/iso14443_layer3a.c +++ b/openpicc/application/iso14443_layer3a.c @@ -158,8 +158,8 @@ void __ramfunc iso14443_layer3a_irq_ext(u_int32_t ssc_sr, enum ssc_mode ssc_mode  		if(send_atqa) {  		vLedSetGreen(0); -			if(ssc_tx_buffer.state == PREFILLED && ssc_tx_buffer.source == &ATQA_FRAME) { -				ssc_tx_buffer.state = PROCESSING; +			if(ssc_tx_buffer.state == SSC_PREFILLED && ssc_tx_buffer.source == &ATQA_FRAME) { +				ssc_tx_buffer.state = SSC_PROCESSING;  				vLedSetGreen(1);  				iso14443_transmit(&ssc_tx_buffer, fdt, 8);  				atqa_sent = 1; @@ -174,8 +174,8 @@ void __ramfunc iso14443_layer3a_irq_ext(u_int32_t ssc_sr, enum ssc_mode ssc_mode  #define FALSE (0!=0)  static int prefill_buffer(ssc_dma_tx_buffer_t *dest, const iso14443_frame *src) {  	portENTER_CRITICAL(); -	if(dest->state == FREE) { -		dest->state = PROCESSING; +	if(dest->state == SSC_FREE) { +		dest->state = SSC_PROCESSING;  		portEXIT_CRITICAL();  		dest->source = (void*)src;  		dest->len = sizeof(ssc_tx_buffer.data); @@ -185,15 +185,15 @@ static int prefill_buffer(ssc_dma_tx_buffer_t *dest, const iso14443_frame *src)  		if(ret>0) {  			dest->len = ret;  			portENTER_CRITICAL(); -			dest->state = PREFILLED; +			dest->state = SSC_PREFILLED;  			portEXIT_CRITICAL();  		} else {  			portENTER_CRITICAL(); -			dest->state = FREE; +			dest->state = SSC_FREE;  			portEXIT_CRITICAL();  		}  		return ret > 0; -	} else if(dest->state == PREFILLED) { +	} else if(dest->state == SSC_PREFILLED) {  		portEXIT_CRITICAL();  		return dest->source == src;  	} else { @@ -325,7 +325,7 @@ void iso14443_layer3a_state_machine (void *pvParameters)  				vLedSetGreen(0);  				vLedBlinkGreen();  				portENTER_CRITICAL(); -				buffer->state = PROCESSING; +				buffer->state = SSC_PROCESSING;  				portEXIT_CRITICAL();  				u_int32_t first_sample = *(u_int32_t*)buffer->data; @@ -392,16 +392,16 @@ void iso14443_layer3a_state_machine (void *pvParameters)  								ssc_rx_start();  							} else {  								//vTaskDelay(portTICK_RATE_MS); -								if(ssc_tx_buffer.source == &ATQA_FRAME) ssc_tx_buffer.state = FREE; +								if(ssc_tx_buffer.source == &ATQA_FRAME) ssc_tx_buffer.state = SSC_FREE;  								if(prefill_buffer(&ssc_tx_buffer, &NULL_FRAME)) {  									usb_print_string_f("Sending response ...",0); -									ssc_tx_buffer.state = PROCESSING; +									ssc_tx_buffer.state = SSC_PROCESSING;  									iso14443_transmit(&ssc_tx_buffer,  										received_frame.parameters.a.last_bit==ISO14443A_LAST_BIT_0 ?  										ISO14443A_TRANSMIT_AT_NEXT_INTERVAL_0 :  										ISO14443A_TRANSMIT_AT_NEXT_INTERVAL_1,   									8); -									while( ssc_tx_buffer.state != FREE ) { +									while( ssc_tx_buffer.state != SSC_FREE ) {  										vTaskDelay(portTICK_RATE_MS);  									}  									usb_print_string("done\n\r"); @@ -415,7 +415,7 @@ void iso14443_layer3a_state_machine (void *pvParameters)  				}  				portENTER_CRITICAL(); -				buffer->state = FREE; +				buffer->state = SSC_FREE;  				portEXIT_CRITICAL();  			}  		} else vTaskDelay(portTICK_RATE_MS); diff --git a/openpicc/application/iso14443_sniffer.c b/openpicc/application/iso14443_sniffer.c index bc326b4..6d4a451 100644 --- a/openpicc/application/iso14443_sniffer.c +++ b/openpicc/application/iso14443_sniffer.c @@ -26,6 +26,7 @@  #include <board.h>  #include <task.h>  #include <errno.h> +#include <stdlib.h>  #include "openpicc.h"  #include "ssc_buffer.h" @@ -37,12 +38,11 @@  #include "cmd.h"  #include "led.h" -static iso14443_frame rx_frame; +static iso14443_frame *rx_frame;  void iso14443_sniffer (void *pvParameters)  {  	(void)pvParameters; -	(void)rx_frame;  	int res;  	/* Delay until USB print etc. are ready */ @@ -56,47 +56,30 @@ void iso14443_sniffer (void *pvParameters)  		}  	} while(res < 0); +	 +	//while(1) { static int i=0; vTaskDelay(10*portTICK_RATE_MS); vLedSetBrightness(LED_RED, abs(1000-i)); i=(i+8)%2000; } +		  	usb_print_string("Waiting for carrier. ");  	while(iso14443_wait_for_carrier(1000 * portTICK_RATE_MS) != 0) {  	}  	usb_print_string("Carrier detected.\n\r");  	while(true) { -		ssc_dma_rx_buffer_t *buffer = 0; -		res = iso14443_receive(NULL, &buffer, 20000 * portTICK_RATE_MS); +		res = iso14443_receive(NULL, &rx_frame, 20000 * portTICK_RATE_MS);  		if(res >= 0) { -#if 1  			DumpStringToUSB("\n\r");  			DumpTimeToUSB(xTaskGetTickCount());  			usb_print_string(": Frame received, consists of "); -			DumpUIntToUSB(res); -			usb_print_string(" transfers ("); -			DumpUIntToUSB(buffer->reception_mode->transfersize_ssc); -			usb_print_string(" bits from SSC each)\n\r                  "); -			if(buffer->len_transfers < 200) -				DumpBufferToUSB((char*)buffer->data, (buffer->len_transfers * buffer->reception_mode->transfersize_pdc)/8); -			else { -				DumpBufferToUSB((char*)buffer->data, (200 * buffer->reception_mode->transfersize_pdc)/8); -				usb_print_string("..."); -			} -			usb_print_string("\n\r                  "); -			iso14443a_decode_miller(&rx_frame, buffer); -			 -			usb_print_string("Decodes to "); -			DumpUIntToUSB(rx_frame.numbytes); +			DumpUIntToUSB(rx_frame->numbytes);  			usb_print_string(" bytes and "); -			DumpUIntToUSB(rx_frame.numbits); +			DumpUIntToUSB(rx_frame->numbits);  			usb_print_string(" bits:  "); -			DumpBufferToUSB((char*)rx_frame.data, rx_frame.numbytes + (rx_frame.numbits+7)/8 ); +			DumpBufferToUSB((char*)rx_frame->data, rx_frame->numbytes + (rx_frame->numbits+7)/8 );  			usb_print_string("\n\r"); -#else -			DumpUIntToUSB(buffer->len_transfers); -			DumpStringToUSB("\n\r"); -#endif  			portENTER_CRITICAL(); -			buffer->state = FREE; +			rx_frame->state = FRAME_FREE;  			portEXIT_CRITICAL();  		} else {  			if(res != -ETIMEDOUT) { diff --git a/openpicc/application/iso14443a_diffmiller.c b/openpicc/application/iso14443a_diffmiller.c index a5acfc8..d73bf95 100644 --- a/openpicc/application/iso14443a_diffmiller.c +++ b/openpicc/application/iso14443a_diffmiller.c @@ -124,6 +124,7 @@ inline void start_frame(struct diffmiller_state * const state)  	//memset(state->frame, 0, sizeof(*state->frame));  	memset(state->frame, 0, (u_int32_t)&(((iso14443_frame*)0)->data) );  	performance_set_checkpoint("start_frame after memset"); +	state->frame->state = FRAME_PENDING;  }  static inline void append_to_frame(struct diffmiller_state *const state, @@ -171,7 +172,7 @@ static inline void end_frame(struct diffmiller_state * const state, const u_int3  }  #define PRINT_BIT(a) if(0){(void)a;} -//#define PRINT_BIT(a) usb_print_string(a) +//#define PRINT_BIT(a) usb_print_string_f(a,0)  #define DO_BIT_0 { \  	if(++counter==9) { \ @@ -194,10 +195,10 @@ static inline void end_frame(struct diffmiller_state * const state, const u_int3  }  #define DO_SYMBOL_X \ +	PRINT_BIT("(X)"); \  	if(!in_frame) { \  		if(last_bit == BIT_0) DO_BIT_0; \  		error = 1; \ -		end_frame(state, counter); \  		PRINT_BIT(" ERROR\n"); \  		last_bit = BIT_ERROR; \  		in_frame = 0; \ @@ -208,10 +209,10 @@ static inline void end_frame(struct diffmiller_state * const state, const u_int3  	}  #define DO_SYMBOL_Y \ +	PRINT_BIT("(Y)"); \  	if(!in_frame) { \  		if(last_bit == BIT_0) DO_BIT_0; \  		error = 1; \ -		end_frame(state, counter); \  		PRINT_BIT(" ERROR\n"); \  		last_bit = BIT_ERROR; \  		in_frame = 0; \ @@ -227,6 +228,7 @@ static inline void end_frame(struct diffmiller_state * const state, const u_int3  	}  #define DO_SYMBOL_Z \ +	PRINT_BIT("(Z)"); \  	if(!in_frame) { \  		if(last_bit == BIT_0) DO_BIT_0; \  		counter = 0; \ @@ -308,11 +310,12 @@ int iso14443a_decode_diffmiller(struct diffmiller_state * const state, iso14443_  		if(state->flags.frame_finished)  {  			state->flags.frame_finished = 0; -			state->old_state = old_state; +			state->old_state = sym_y;  			state->last_bit = last_bit;  			state->counter = counter;  			state->flags.in_frame = in_frame;  			state->flags.error = error; +			state->frame = NULL;  			performance_set_checkpoint("frame finished");  			return 0;  		} @@ -327,6 +330,31 @@ int iso14443a_decode_diffmiller(struct diffmiller_state * const state, iso14443_  	return -EBUSY;  } +int iso14443a_diffmiller_assert_frame_ended(struct diffmiller_state * const state,  +		iso14443_frame * const frame) +{ +	if(state == NULL || !state->initialized) return -EINVAL; +	if(!state->flags.in_frame) return -EBUSY; +	if(state->frame != NULL && state->frame != frame) return -EINVAL; +	state->frame = frame; + +	end_frame(state, state->counter); +	PRINT_BIT(" EOF2\n"); +	state->flags.in_frame = 0; +	 +	if(state->flags.frame_finished)  { +		state->flags.frame_finished = 0; +		state->old_state = sym_y; +		state->last_bit = BIT_EOF; +		state->counter = 0; +		state->frame = NULL; +		performance_set_checkpoint("frame finished2"); +		return 0; +	} +	 +	return -EBUSY; +} +  struct diffmiller_state *iso14443a_init_diffmiller(int pauses_count)  {  	if(_state.initialized) return NULL; @@ -334,6 +362,7 @@ struct diffmiller_state *iso14443a_init_diffmiller(int pauses_count)  	state->initialized = 1;  	state->pauses_count = pauses_count;  	state->frame = NULL; +	state->old_state = sym_y;  	state->flags.frame_finished = 0;  	return state; diff --git a/openpicc/application/iso14443a_diffmiller.h b/openpicc/application/iso14443a_diffmiller.h index f5336d6..7dc9c55 100644 --- a/openpicc/application/iso14443a_diffmiller.h +++ b/openpicc/application/iso14443a_diffmiller.h @@ -7,6 +7,8 @@ struct diffmiller_state;  extern int iso14443a_decode_diffmiller(struct diffmiller_state *state, iso14443_frame *frame,   	const u_int32_t buffer[], unsigned int *offset, const unsigned int buflen); +extern int iso14443a_diffmiller_assert_frame_ended(struct diffmiller_state * const state,  +		iso14443_frame * const frame);  extern struct diffmiller_state *iso14443a_init_diffmiller(int pauses_count);  #endif /*ISO14443A_DIFFMILLER_H_*/ diff --git a/openpicc/application/iso14443a_pretender.c b/openpicc/application/iso14443a_pretender.c index 64112d1..03fb12d 100644 --- a/openpicc/application/iso14443a_pretender.c +++ b/openpicc/application/iso14443a_pretender.c @@ -118,7 +118,7 @@ static void fast_receive_callback(ssc_dma_rx_buffer_t *buffer, u_int8_t in_irq)  	if(tx_buffer != NULL) { -		tx_buffer->state = FULL; +		tx_buffer->state = SSC_FULL;  		if(	iso14443_transmit(tx_buffer, fdt, 1, 0) < 0) {  			usb_print_string_f("Tx failed ", 0);  		} @@ -229,7 +229,7 @@ prefill_failed:  			}  			portENTER_CRITICAL(); -			buffer->state = FREE; +			buffer->state = SSC_FREE;  			portEXIT_CRITICAL();  		} else {  			if(res != -ETIMEDOUT) { diff --git a/openpicc/application/main.c b/openpicc/application/main.c index 8babafe..a082933 100644 --- a/openpicc/application/main.c +++ b/openpicc/application/main.c @@ -211,12 +211,12 @@ 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 (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); +    /*xTaskCreate (tc_sniffer, (signed portCHAR *) "RFID-SNIFFER", TASK_ISO_STACK, +		 	NULL, TASK_ISO_PRIORITY, NULL);*/      xTaskCreate (vUSBCDCTask, (signed portCHAR *) "USB", TASK_USB_STACK, diff --git a/openpicc/application/openpicc.h b/openpicc/application/openpicc.h index b4d2b7a..17cb4ee 100644 --- a/openpicc/application/openpicc.h +++ b/openpicc/application/openpicc.h @@ -39,5 +39,6 @@ typedef int s_int32_t;  #define DA_BASELINE 200  #define DIV_ROUND_UP(a,b) ( (a+(b-1)) / b) +#define MIN(a, b) ((a)>(b)?(b):(a))  #endif/*__OPENPICC_H__*/ diff --git a/openpicc/application/performance.c b/openpicc/application/performance.c index cffd094..4515f18 100644 --- a/openpicc/application/performance.c +++ b/openpicc/application/performance.c @@ -33,6 +33,7 @@ static u_int32_t overruns = 0;  #define NUMBER_OF_CHECKPOINTS 20  static struct performance_checkpoint checkpoints[NUMBER_OF_CHECKPOINTS];  static int current_checkpoint; +static int running=0;  static void __ramfunc tc_perf_irq(void) __attribute__ ((naked));  static void __ramfunc tc_perf_irq(void) @@ -66,6 +67,7 @@ inline void performance_start(void)  	memset(checkpoints, 0, sizeof(checkpoints));  	current_checkpoint = 0;  	overruns = 0; +	running = 1;  	tc_perf->TC_CCR = AT91C_TC_SWTRG | AT91C_TC_CLKEN;  } @@ -82,6 +84,7 @@ inline perf_time_t performance_get(void)  inline perf_time_t performance_stop(void)  {  	perf_time_t result = performance_get(); +	running = 0;  	tc_perf->TC_CCR = AT91C_TC_CLKDIS;  	return result;  } @@ -105,6 +108,7 @@ perf_time_t performance_diff(perf_time_t a, perf_time_t b)  void performance_set_checkpoint(const char * const description)  { +	if(!running) return;  	if(current_checkpoint < NUMBER_OF_CHECKPOINTS) {  		perf_time_t time = performance_get();  		checkpoints[current_checkpoint++] = (struct performance_checkpoint){ @@ -116,6 +120,7 @@ void performance_set_checkpoint(const char * const description)  void performance_stop_report(void)  { +	if(!running) return;  	perf_time_t _now = performance_stop();  	struct performance_checkpoint now = {  			.time = _now, diff --git a/openpicc/application/ssc.c b/openpicc/application/ssc.c index e25d982..4da45ae 100644 --- a/openpicc/application/ssc.c +++ b/openpicc/application/ssc.c @@ -125,7 +125,7 @@ static int __ramfunc _ssc_rx_irq(u_int32_t orig_sr, int start_asserted, portBASE  		sh->ssc->SSC_RCMR = (orig_rcmr & (~AT91C_SSC_START)) | (AT91C_SSC_START_CONTINOUS);  		/* Receiving has started */  		if(sh->callback != NULL) { -			sh->callback(CALLBACK_RX_FRAME_BEGIN, &end_asserted); +			sh->callback(SSC_CALLBACK_RX_FRAME_BEGIN, &end_asserted);  			if(end_asserted)  				sr = orig_sr | _ssc.ssc->SSC_SR;  		} @@ -147,9 +147,9 @@ static int __ramfunc _ssc_rx_irq(u_int32_t orig_sr, int start_asserted, portBASE  		ssc_dma_rx_buffer_t *buffer = _unload_rx(sh);  		if(buffer != NULL) {  			if(sh->callback != NULL) -				sh->callback(CALLBACK_RX_FRAME_ENDED, buffer); +				sh->callback(SSC_CALLBACK_RX_FRAME_ENDED, buffer); -			if(buffer->state != FREE) { +			if(buffer->state != SSC_FREE) {  				task_woken = xQueueSendFromISR(sh->rx_queue, &buffer, task_woken);  			}  		} @@ -174,7 +174,7 @@ static int __ramfunc _ssc_rx_irq(u_int32_t orig_sr, int start_asserted, portBASE  		} else {  			sh->ssc->SSC_IDR = SSC_RX_IRQ_MASK;  			sh->rx_running = 0; -			sh->callback(CALLBACK_RX_STOPPED, sh); +			sh->callback(SSC_CALLBACK_RX_STOPPED, sh);  		}  	} @@ -202,7 +202,7 @@ static void __ramfunc _ssc_tx_end(ssc_handle_t *sh, int is_an_abort)  	AT91F_PDC_SetNextTx(sh->pdc, 0, 0);  	if(sh->tx_buffer) { -		sh->tx_buffer->state = FREE; +		sh->tx_buffer->state = SSC_FREE;  		sh->tx_running = 0;  	} @@ -213,9 +213,9 @@ static void __ramfunc _ssc_tx_end(ssc_handle_t *sh, int is_an_abort)  	if(sh->callback) {  		if(is_an_abort) -			sh->callback(CALLBACK_TX_FRAME_ABORTED, sh->tx_buffer); +			sh->callback(SSC_CALLBACK_TX_FRAME_ABORTED, sh->tx_buffer);  		else -			sh->callback(CALLBACK_TX_FRAME_ENDED, sh->tx_buffer); +			sh->callback(SSC_CALLBACK_TX_FRAME_ENDED, sh->tx_buffer);  	}  	sh->tx_buffer = NULL; @@ -236,7 +236,7 @@ static int __ramfunc _ssc_tx_irq(u_int32_t sr, portBASE_TYPE task_woken)  		sh->ssc->SSC_TCMR = (sh->ssc->SSC_TCMR & ~AT91C_SSC_START) | AT91C_SSC_START_CONTINOUS;  		if(sh->callback)  -			sh->callback(CALLBACK_TX_FRAME_BEGIN, NULL); +			sh->callback(SSC_CALLBACK_TX_FRAME_BEGIN, NULL);  	}  	if( sr & AT91C_SSC_TXEMPTY ) { @@ -297,7 +297,7 @@ static __ramfunc int _reload_rx(ssc_handle_t *sh)  		goto out;  	} -	ssc_dma_rx_buffer_t *buffer = _get_buffer(FREE, PENDING); +	ssc_dma_rx_buffer_t *buffer = _get_buffer(SSC_FREE, SSC_PENDING);  	if(buffer == NULL) {  		ssc_metrics[METRIC_RX_OVERFLOWS].value++; @@ -328,7 +328,7 @@ static __ramfunc ssc_dma_rx_buffer_t* _unload_rx(ssc_handle_t *sh)  		rcr = sh->pdc->PDC_RCR;  	AT91F_PDC_SetRx(sh->pdc, 0, 0);  	sh->rx_buffer[0] = NULL; -	buffer->state = FULL; +	buffer->state = SSC_FULL;  	if(rcr == 0) {  		buffer->flags.overflow = 1; @@ -357,7 +357,7 @@ static __ramfunc ssc_dma_rx_buffer_t* _unload_rx(ssc_handle_t *sh)  	if((buffer->len_transfers - rcr) != (rpr - (unsigned int)buffer->data)*(buffer->reception_mode->transfersize_pdc/8)) {  		ssc_metrics[METRIC_MANAGEMENT_ERRORS_3].value++; -		buffer->state = FREE; +		buffer->state = SSC_FREE;  		return NULL;  	} @@ -393,7 +393,7 @@ static void _ssc_start_rx(ssc_handle_t *sh)  		 AT91C_SSC_CP1 | AT91C_SSC_ENDRX;  	sh->rx_running = 1;  	if(sh->callback != NULL) -		sh->callback(CALLBACK_RX_STARTING, sh); +		sh->callback(SSC_CALLBACK_RX_STARTING, sh);  	// Actually enable reception  	int dummy = sh->ssc->SSC_RHR; (void)dummy; @@ -411,7 +411,7 @@ static void _ssc_stop_rx(ssc_handle_t *sh)  	sh->ssc->SSC_IDR = SSC_RX_IRQ_MASK;  	sh->rx_running = 0;  	if(sh->callback != NULL) -		sh->callback(CALLBACK_RX_STOPPED, sh); +		sh->callback(SSC_CALLBACK_RX_STOPPED, sh);  	taskEXIT_CRITICAL();  } @@ -556,7 +556,7 @@ static int _ssc_register_callback(ssc_handle_t *sh, ssc_callback_t _callback)  	if(sh->callback != NULL) return -EBUSY;  	sh->callback = _callback;  	if(sh->callback != NULL)  -		sh->callback(CALLBACK_SETUP, sh); +		sh->callback(SSC_CALLBACK_SETUP, sh);  	return 0;  } @@ -565,7 +565,7 @@ static int _ssc_unregister_callback(ssc_handle_t *sh, ssc_callback_t _callback)  	if(!sh) return -EINVAL;  	if(_callback == NULL || sh->callback == _callback) {  		if(sh->callback != NULL)  -			sh->callback(CALLBACK_TEARDOWN, sh); +			sh->callback(SSC_CALLBACK_TEARDOWN, sh);  		sh->callback = NULL;  	}  	return 0; @@ -686,7 +686,7 @@ int ssc_send(ssc_handle_t* sh, ssc_dma_tx_buffer_t *buffer)  	AT91F_PDC_SetTx(sh->pdc, buffer->data, num_data);  	AT91F_PDC_SetNextTx(sh->pdc, 0, 0); -	buffer->state = PENDING; +	buffer->state = SSC_PENDING;  	sh->ssc->SSC_IER = AT91C_SSC_TXEMPTY | AT91C_SSC_TXSYN;  	/* Enable DMA */ @@ -795,7 +795,7 @@ int ssc_get_metric(ssc_metric metric, char **description, int *value)  			_value = 0;  			int i;  			for(i=0; i < SSC_DMA_BUFFER_COUNT; i++) -				if(_rx_buffers[i].state == FREE) _value++; +				if(_rx_buffers[i].state == SSC_FREE) _value++;  			break;  		case METRIC_MANAGEMENT_ERRORS:  			_value = ssc_metrics[METRIC_MANAGEMENT_ERRORS_1].value + diff --git a/openpicc/application/ssc.h b/openpicc/application/ssc.h index 9edec64..e99d444 100644 --- a/openpicc/application/ssc.h +++ b/openpicc/application/ssc.h @@ -21,17 +21,17 @@ typedef enum {  extern int ssc_get_metric(ssc_metric metric, char **description, int *value);  typedef enum { -	CALLBACK_RX_STARTING,       // *data is ssh_handle_t *sh -	CALLBACK_RX_STOPPED,        // *data is ssh_handle_t *sh -	CALLBACK_RX_FRAME_BEGIN,    // *data is int *end_asserted -								//  may set *end_asserted = 1 to force tell the IRQ handler   -								//  that you have detected the end of reception -	CALLBACK_RX_FRAME_ENDED,    // *data is ssc_dma_rx_buffer *buffer -	CALLBACK_TX_FRAME_BEGIN, -	CALLBACK_TX_FRAME_ENDED, -	CALLBACK_TX_FRAME_ABORTED, -	CALLBACK_SETUP,             // *data is ssh_handle_t *sh -	CALLBACK_TEARDOWN,          // *data is ssh_handle_t *sh +	SSC_CALLBACK_RX_STARTING,       // *data is ssh_handle_t *sh +	SSC_CALLBACK_RX_STOPPED,        // *data is ssh_handle_t *sh +	SSC_CALLBACK_RX_FRAME_BEGIN,    // *data is int *end_asserted +									//  may set *end_asserted = 1 to force tell the IRQ handler   +									//  that you have detected the end of reception +	SSC_CALLBACK_RX_FRAME_ENDED,    // *data is ssc_dma_rx_buffer *buffer +	SSC_CALLBACK_TX_FRAME_BEGIN, +	SSC_CALLBACK_TX_FRAME_ENDED, +	SSC_CALLBACK_TX_FRAME_ABORTED, +	SSC_CALLBACK_SETUP,             // *data is ssh_handle_t *sh +	SSC_CALLBACK_TEARDOWN,          // *data is ssh_handle_t *sh  } ssc_callback_reason;  typedef void (*ssc_callback_t)(ssc_callback_reason reason, void *data); diff --git a/openpicc/application/ssc_buffer.h b/openpicc/application/ssc_buffer.h index 5365851..527ae46 100644 --- a/openpicc/application/ssc_buffer.h +++ b/openpicc/application/ssc_buffer.h @@ -15,11 +15,11 @@  #endif  typedef enum { -	FREE=0,    /* Buffer is free */ -	PENDING,   /* Buffer has been given to the DMA controller and is currently being filled */ -	FULL,      /* DMA controller signalled that the buffer is full */ -	PROCESSING,/* The buffer is currently processed by the consumer (e.g. decoder) */ -	PREFILLED, /* The buffer has been prefilled for later usage (only used for TX) */ +	SSC_FREE=0,    /* Buffer is free */ +	SSC_PENDING,   /* Buffer has been given to the DMA controller and is currently being filled */ +	SSC_FULL,      /* DMA controller signalled that the buffer is full */ +	SSC_PROCESSING,/* The buffer is currently processed by the consumer (e.g. decoder) */ +	SSC_PREFILLED, /* The buffer has been prefilled for later usage (only used for TX) */  } ssc_dma_buffer_state_t;  enum ssc_mode { diff --git a/openpicc/application/tc_recv.c b/openpicc/application/tc_recv.c new file mode 100644 index 0000000..fa6b510 --- /dev/null +++ b/openpicc/application/tc_recv.c @@ -0,0 +1,213 @@ +/*************************************************************** + * + * OpenPICC - ISO 14443 Layer 2 Type A  T/C based receiver code + * Implements a receiver using FDT Timer/Counter (TC2) and the + * FIQ to measure the number of carrier cycles between modulation + * pauses. + *  + * The timing measurements are given to the differential miller + * decoder on the fly to interleave reception and decoding. This + * means two things: a) The CPU will be held in an IRQ handler + * with IRQs disabled for the time of reception and b) The frame + * will already have been fully decoded to a iso14443_frame + * structure when reception ends. + *  + * Copyright 2008 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; version 2. + +    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., +    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +*/ + +#include <FreeRTOS.h> +#include <openpicc.h> +#include <errno.h> +#include <string.h> + +#include <task.h> +#include <queue.h> + +#include "tc_recv.h" + +#include "iso14443a_diffmiller.h" +#include "usb_print.h" +#include "pio_irq.h" +#include "led.h" +#include "cmd.h" + +struct tc_recv_handle { +	u_int8_t initialized; +	u_int8_t pauses_count; +	struct diffmiller_state *decoder; +	int current, next; +	tc_recv_callback_t callback; +	iso14443_frame *current_frame; +	xQueueHandle rx_queue; +}; + +static struct tc_recv_handle _tc; + +#define BUFSIZE 1024 +typedef struct { +	u_int32_t count; +	u_int32_t data[BUFSIZE]; +} fiq_buffer_t; +fiq_buffer_t fiq_buffers[2]; + +fiq_buffer_t *tc_sniffer_next_buffer_for_fiq = 0; + +iso14443_frame rx_frames[TC_RECV_NUMBER_OF_FRAME_BUFFERS]; + +#define REAL_FRAME_END 333  + +static int tc_recv_buffer_overruns = 0; + +static inline iso14443_frame *get_frame_buffer(tc_recv_handle_t th) +{ +	if(th->current_frame) return th->current_frame; +	unsigned int i; iso14443_frame *result; +	for(i=0; i<sizeof(rx_frames)/sizeof(rx_frames[0]); i++) { +		if(rx_frames[i].state == FRAME_FREE) { +			result = &rx_frames[i]; +			result->state = FRAME_PENDING; +			th->current_frame = result; +			return result; +		} +	} +	tc_recv_buffer_overruns++; +	return NULL; +} + +static portBASE_TYPE handle_frame(iso14443_frame *frame, portBASE_TYPE task_woken) +{ +	if(_tc.callback) _tc.callback(TC_RECV_CALLBACK_RX_FRAME_ENDED, frame); +	if(frame->state != FRAME_FREE) { +		task_woken = xQueueSendFromISR(_tc.rx_queue, &frame, task_woken); +	} +	_tc.current_frame = NULL; +	return task_woken; +} + +static portBASE_TYPE handle_buffer(u_int32_t data[], unsigned int count, portBASE_TYPE task_woken) +{ +	unsigned int offset = 0; +	while(offset < count) { +		iso14443_frame *rx_frame = get_frame_buffer(&_tc); +		if(rx_frame == NULL) return task_woken; +		int ret = iso14443a_decode_diffmiller(_tc.decoder, rx_frame, data, &offset, count); +		if(ret == 0) { +			task_woken = handle_frame(rx_frame, task_woken); +		} +	} +	return task_woken; +} + +static inline portBASE_TYPE flush_buffer(fiq_buffer_t *buffer, portBASE_TYPE task_woken) +{ +	if(buffer->count > 0) { +		if(buffer->count >= BUFSIZE) { +			usb_print_string_f("Warning: Possible buffer overrun detected\n\r",0); +			//overruns++; +		} +		buffer->count = MIN(buffer->count, BUFSIZE); +		task_woken = handle_buffer(buffer->data, buffer->count, task_woken); +		buffer->count = 0; +	} +	return task_woken; +} + +#define NEXT_BUFFER(a) ((a+1)%(sizeof(fiq_buffers)/sizeof(fiq_buffers[0]))) + +static portBASE_TYPE switch_buffers(portBASE_TYPE task_woken) +{ +	_tc.next = NEXT_BUFFER(_tc.current); +	task_woken = flush_buffer( &fiq_buffers[_tc.next] , task_woken); +	 +	tc_sniffer_next_buffer_for_fiq = &fiq_buffers[_tc.current=_tc.next]; +	return task_woken; +} + +static portBASE_TYPE tc_recv_irq(u_int32_t pio, portBASE_TYPE task_woken) +{ +	(void)pio; +	/* TODO There should be some emergency exit here to prevent the CPU from +	 * spinning in the IRQ for excessive amounts of time. (Maximum transmission +	 * time for 256 Byte frame is something like 21ms.) +	 */  +	while(*AT91C_TC2_CV <= REAL_FRAME_END ||  +			fiq_buffers[NEXT_BUFFER(_tc.current)].count > 0 ||  +			fiq_buffers[_tc.current].count > 0)  +		task_woken = switch_buffers(task_woken); +	 +	if(*AT91C_TC2_CV > REAL_FRAME_END) { +		iso14443_frame *rx_frame = get_frame_buffer(&_tc); +		if(rx_frame == NULL) return task_woken; +		int ret = iso14443a_diffmiller_assert_frame_ended(_tc.decoder, rx_frame); +		if(ret == 0) { +			task_woken = handle_frame(rx_frame, task_woken); +		} +	} +	return task_woken; +} + + +int tc_recv_init(tc_recv_handle_t *_th, int pauses_count, tc_recv_callback_t callback) +{ +	if(_tc.initialized) return -EBUSY; +	tc_recv_handle_t th = &_tc; +	 +	memset(fiq_buffers, 0, sizeof(fiq_buffers)); +	th->current = th->next = 0; +	 +	memset(rx_frames, 0, sizeof(rx_frames)); +	th->current_frame = NULL; +	 +	if(th->rx_queue == NULL) { +		th->rx_queue = xQueueCreate(TC_RECV_NUMBER_OF_FRAME_BUFFERS, sizeof(iso14443_frame*)); +		if(th->rx_queue == NULL) +			return -ENOMEM; +	} +	 +	th->pauses_count = pauses_count; +	th->decoder = iso14443a_init_diffmiller(th->pauses_count); +	if(!th->decoder) return -EBUSY; + +	// The change interrupt is going to be handled by the FIQ and our secondary IRQ handler  +	AT91F_PIO_CfgInput(AT91C_BASE_PIOA, OPENPICC_SSC_DATA); +	if( pio_irq_register(OPENPICC_SSC_DATA, &tc_recv_irq) < 0)  +		return -EBUSY; +	pio_irq_enable(OPENPICC_SSC_DATA); +	 +	th->initialized = 1; +	*_th = th; +	 +	th->callback = callback; +	if(th->callback) th->callback(TC_RECV_CALLBACK_SETUP, th); +	 +	return 0; +} + +int tc_recv_receive(tc_recv_handle_t th, iso14443_frame* *frame, unsigned int timeout) +{ +	if(th == NULL) return -EINVAL; +	if(!th->initialized) return -EINVAL; +	 +	if(xQueueReceive(th->rx_queue, frame, timeout)){ +		if(*frame != NULL) return 0; +		else return -EINTR; +	} +	 +	return -ETIMEDOUT; +} diff --git a/openpicc/application/tc_recv.h b/openpicc/application/tc_recv.h new file mode 100644 index 0000000..4f2392b --- /dev/null +++ b/openpicc/application/tc_recv.h @@ -0,0 +1,21 @@ +#ifndef TC_RECV_H_ +#define TC_RECV_H_ + +#include "iso14443.h" + +#define TC_RECV_NUMBER_OF_FRAME_BUFFERS 10 + +struct tc_recv_handle; +typedef struct tc_recv_handle *tc_recv_handle_t; + +typedef enum { +	TC_RECV_CALLBACK_RX_FRAME_ENDED,    // *data is iso14443_frame *frame +	TC_RECV_CALLBACK_SETUP,             // *data is tc_recv_handle_t th +	TC_RECV_CALLBACK_TEARDOWN,          // *data is tc_recv_handle_t th +} tc_recv_callback_reason; +typedef void (*tc_recv_callback_t)(tc_recv_callback_reason reason, void *data); + +extern int tc_recv_init(tc_recv_handle_t *th, int pauses_count, tc_recv_callback_t callback); +extern int tc_recv_receive(tc_recv_handle_t th, iso14443_frame* *frame, unsigned int timeout); + +#endif /*TC_RECV_H_*/ diff --git a/openpicc/application/tc_sniffer.c b/openpicc/application/tc_sniffer.c index 943a2ad..592b5a4 100644 --- a/openpicc/application/tc_sniffer.c +++ b/openpicc/application/tc_sniffer.c @@ -56,15 +56,7 @@ static xSemaphoreHandle data_semaphore;  struct diffmiller_state *decoder;  iso14443_frame rx_frame; -#define BUFSIZE 1024  #define WAIT_TICKS (20*portTICK_RATE_MS) -typedef struct { -	u_int32_t count; -	u_int32_t data[BUFSIZE]; -} fiq_buffer_t; -fiq_buffer_t fiq_buffers[2]; - -fiq_buffer_t *tc_sniffer_next_buffer_for_fiq = 0;  portBASE_TYPE currently_sniffing = 0;  enum { NONE, REQUEST_START, REQUEST_STOP } request_change = REQUEST_START;  | 
