diff options
Diffstat (limited to 'openpicc')
| -rw-r--r-- | openpicc/application/cmd.c | 24 | ||||
| -rw-r--r-- | openpicc/application/decoder.h | 1 | ||||
| -rw-r--r-- | openpicc/application/iso14443_layer3a.c | 55 | ||||
| -rw-r--r-- | openpicc/application/iso14443_layer3a.h | 53 | ||||
| -rw-r--r-- | openpicc/application/iso14443a_manchester.c | 100 | ||||
| -rw-r--r-- | openpicc/application/main.c | 28 | ||||
| -rw-r--r-- | openpicc/application/ssc_picc.c | 95 | ||||
| -rw-r--r-- | openpicc/application/ssc_picc.h | 19 | ||||
| -rw-r--r-- | openpicc/os/boot/Cstartup_SAM7.c | 2 | 
9 files changed, 265 insertions, 112 deletions
diff --git a/openpicc/application/cmd.c b/openpicc/application/cmd.c index 6e5230e..8c06a3d 100644 --- a/openpicc/application/cmd.c +++ b/openpicc/application/cmd.c @@ -26,6 +26,10 @@ xTaskHandle xCmdRecvUsbTask;  xTaskHandle xFieldMeterTask;  xSemaphoreHandle xFieldMeterMutex; +#if ( configUSE_TRACE_FACILITY == 1 ) +static signed portCHAR pcWriteBuffer[512]; +#endif +  /* Whether to require a colon (':') be typed before long commands, similar to e.g. vi   * This makes a distinction between long commands and short commands: long commands may be   * longer than one character and/or accept optional parameters, short commands are only one @@ -262,11 +266,6 @@ void prvExecCommand(u_int32_t cmd, portCHAR *args) {  		    DumpStringToUSB(" * SSC_RCMR value: ");  		    DumpUIntToUSB(*AT91C_SSC_RCMR);  		    DumpStringToUSB("\n\r"); -		    DumpStringToUSB(" * is remapped?: "); -		    DumpStringToUSB( (*(int*)0x00100100 == *(int*)0x00000100) ? "no" : -		    	 ((*(int*)0x00200100 == *(int*)0x00000100) ? "yes" : "foo") -		    ); -		    DumpStringToUSB("\n\r");  		    DumpStringToUSB(  			" *\n\r"  			" *****************************************************\n\r" @@ -300,6 +299,14 @@ void prvExecCommand(u_int32_t cmd, portCHAR *args) {  		    break;  		case 'F':  		    startstop_field_meter(); +		    break; +#if ( configUSE_TRACE_FACILITY == 1 ) +		case 'T': +		    memset(pcWriteBuffer, 0, sizeof(pcWriteBuffer)); +		    vTaskList(pcWriteBuffer); +		    DumpStringToUSB((char*)pcWriteBuffer); +		    break; +#endif  		case 'Q':  		    ssc_rx_start();  		    while(0) { @@ -320,6 +327,9 @@ void prvExecCommand(u_int32_t cmd, portCHAR *args) {  			" *\n\r"  			" * s    - store transmitter settings\n\r"  			" * test - test critical sections\n\r" +#if ( configUSE_TRACE_FACILITY == 1 ) +			" * t    - print task list and stack usage\n\r" +#endif  			" * c    - print configuration\n\r"  			" * 0    - receive only mode\n\r"  			" * 1..4 - automatic transmit at selected power levels\n\r" @@ -479,12 +489,12 @@ portBASE_TYPE vCmdInit(void) {  		return 0;  	} -	if(xTaskCreate(vCmdRecvUsbCode, (signed portCHAR *)"CMDUSB", TASK_CMD_STACK, NULL,  +	if(xTaskCreate(vCmdRecvUsbCode, (signed portCHAR *)"CMDUSB", 128, NULL,   		TASK_CMD_PRIORITY, &xCmdRecvUsbTask) != pdPASS) {  		return 0;  	} -	if(xTaskCreate(vFieldMeter, (signed portCHAR *)"FIELD METER", TASK_CMD_STACK, NULL,  +	if(xTaskCreate(vFieldMeter, (signed portCHAR *)"FIELD METER", 128, NULL,   		TASK_CMD_PRIORITY, &xFieldMeterTask) != pdPASS) {  		return 0;  	} diff --git a/openpicc/application/decoder.h b/openpicc/application/decoder.h index bd25777..7892ea6 100644 --- a/openpicc/application/decoder.h +++ b/openpicc/application/decoder.h @@ -21,6 +21,7 @@ struct decoder_state {  extern int decoder_register(int algnum, struct decoder_algo *algo);  extern int decoder_decode(u_int8_t algo, const char *sample_buf,  		  	  int sample_buf_size, unsigned char *data_buf); +extern void decoder_init(void);  #define DECODER_MILLER		0  #define DECODER_NRZL		1 diff --git a/openpicc/application/iso14443_layer3a.c b/openpicc/application/iso14443_layer3a.c index 841ad14..2239655 100644 --- a/openpicc/application/iso14443_layer3a.c +++ b/openpicc/application/iso14443_layer3a.c @@ -34,20 +34,34 @@  #include "tc_cdiv_sync.h"  #include "usb_print.h"  #include "cmd.h" +#include "load_modulation.h" +#include "decoder.h" +#include "iso14443a_manchester.h" +#include "led.h"  static enum ISO14443_STATES state = STARTING_UP; +const iso14443_frame ATQA_FRAME = { +	TYPE_A, +	{{STANDARD_FRAME, NO_PARITY}}, +	2,  +	0, 0, +	{4, 0}, +	{} +}; + +  #define PLL_LOCK_HYSTERESIS portTICK_RATE_MS*5  #define LAYER3_DEBUG usb_print_string -extern void main_help_print_buffer(ssc_dma_buffer_t *buffer, int *pktcount); +extern void main_help_print_buffer(ssc_dma_rx_buffer_t *buffer, int *pktcount);  void iso14443_layer3a_state_machine (void *pvParameters)  {  	unsigned long int last_pll_lock = ~0;  	int pktcount=0;  	(void)pvParameters;  	while(1) { -		ssc_dma_buffer_t* buffer = NULL; +		ssc_dma_rx_buffer_t* buffer = NULL;  		portBASE_TYPE need_receive = 0, switch_on = 0;  		/* First let's see whether there is a reader */ @@ -97,7 +111,7 @@ void iso14443_layer3a_state_machine (void *pvParameters)  				tc_cdiv_set_divider(64);  #endif  				tc_fdt_init(); -#if 0 +#if 1  				ssc_tx_init();  #else  				AT91F_PIO_CfgInput(AT91C_BASE_PIOA, OPENPICC_MOD_PWM); @@ -107,6 +121,10 @@ void iso14443_layer3a_state_machine (void *pvParameters)  #endif  				ssc_rx_init(); +				load_mod_init(); +				load_mod_level(3); +				 +				  				state = POWERED_OFF;  				break;  			case POWERED_OFF: @@ -127,6 +145,7 @@ void iso14443_layer3a_state_machine (void *pvParameters)  		if(need_receive) {  			if(xQueueReceive(ssc_rx_queue, &buffer, portTICK_RATE_MS)) { +				vLedSetGreen(0);  				portENTER_CRITICAL();  				buffer->state = PROCESSING;  				portEXIT_CRITICAL(); @@ -145,6 +164,36 @@ void iso14443_layer3a_state_machine (void *pvParameters)  							LAYER3_DEBUG("Received ");  							LAYER3_DEBUG(first_sample == WUPA ? "WUPA" : "REQA");  							LAYER3_DEBUG(" waking up to send ATQA\n\r"); +							portENTER_CRITICAL(); +							if(ssc_tx_buffer.state != FREE) { +								portEXIT_CRITICAL(); +								/* Wait for another frame */ +								ssc_rx_mode_set(SSC_MODE_14443A_SHORT); +								ssc_rx_start(); +							} else { +								ssc_tx_buffer.state = PROCESSING; +								portEXIT_CRITICAL(); +								ssc_tx_buffer.len = sizeof(ssc_tx_buffer.data); +								unsigned int ret =  +									manchester_encode(ssc_tx_buffer.data, +										ssc_tx_buffer.len, +										&ATQA_FRAME); +								if(ret>0) { +									ssc_tx_buffer.len = ret; +									LAYER3_DEBUG("Buffer "); +									DumpUIntToUSB(ret); +									LAYER3_DEBUG(" "); +									DumpBufferToUSB((char*)ssc_tx_buffer.data, ssc_tx_buffer.len); +									LAYER3_DEBUG("\n\r"); +								} else { +									portENTER_CRITICAL(); +									ssc_tx_buffer.state = FREE; +									portEXIT_CRITICAL(); +									/* Wait for another frame */ +									ssc_rx_mode_set(SSC_MODE_14443A_SHORT); +									ssc_rx_start(); +								} +							}  						} else {  							/* Wait for another frame */  							ssc_rx_mode_set(SSC_MODE_14443A_SHORT); diff --git a/openpicc/application/iso14443_layer3a.h b/openpicc/application/iso14443_layer3a.h index 6f32dd5..142128e 100644 --- a/openpicc/application/iso14443_layer3a.h +++ b/openpicc/application/iso14443_layer3a.h @@ -15,6 +15,7 @@ enum ISO14443_STATES {  	ERROR,       /* Some unrecoverable error has occured */  }; +/******************** RX ************************************/  /* standard derived magic values */  #define ISO14443A_FDT_SHORT_1	1236  #define ISO14443A_FDT_SHORT_0	1172 @@ -30,6 +31,15 @@ enum ISO14443_STATES {  #define ISO14443A_SOF_LEN	4  /* Length in samples of a short frame */  #define ISO14443A_SHORT_LEN     32 +/* This is wrong: a short frame is 1 start bit, 7 data bits, 1 stop bit  + * followed by no modulation for one bit period. The start bit is 'eaten' in  + * SSC Compare 0, but the remaining 7+1+1 bit durations must be sampled and + * compared. At four times oversampling this would be 9*4=36 samples, which is  + * more than one SSC transfer. You'd have to use two transfers of 18 samples + * each and modify the comparison code accordingly.  + * Since four times oversampling doesn't work reliably anyway (every second + * sample is near an edge and might sample 0 or 1) this doesn't matter for now.*/ +#error Four times oversampling is broken, see comments in code   #else  /* definitions for two-times oversampling */ @@ -38,8 +48,49 @@ enum ISO14443_STATES {  #define ISO14443A_SOF_SAMPLE	0x01  #define ISO14443A_SOF_LEN	2 -#define ISO14443A_SHORT_LEN     16 +#define ISO14443A_SHORT_LEN     18  #endif +/* A short frame should be received in one single SSC transfer */ +#if (ISO14443A_SHORT_LEN <= 8) +/* SSC transfer size in bits */ +#define ISO14443A_SHORT_TRANSFER_SIZE 8 +#define ISO14443A_SHORT_TYPE u_int8_t + +#elif (ISO14443A_SHORT_LEN <= 16) +#define ISO14443A_SHORT_TRANSFER_SIZE 16 +#define ISO14443A_SHORT_TYPE u_int16_t + +#elif (ISO14443A_SHORT_LEN <= 32) +#define ISO14443A_SHORT_TRANSFER_SIZE 32 +#define ISO14443A_SHORT_TYPE u_int32_t + +#else +#error ISO14443A_SHORT_LEN defined too big +#endif + +/******************** TX ************************************/ +/* in bytes, not counting parity */ +#define MAXIMUM_FRAME_SIZE 256 + +typedef struct { +  enum { TYPE_A, TYPE_B } type; +  union { +  	struct { +  		enum { SHORT_FRAME, STANDARD_FRAME, AC_FRAME } format; +  		enum { PARITY, /* Calculate parity on the fly, ignore the parity field below */  +  		       GIVEN_PARITY, /* Use the parity bits from the parity field below */   +  		       NO_PARITY, /* Don't send any parity */ +  		} parity;  +  	} a; +  } parameters; +  u_int32_t numbytes; +  u_int8_t numbits, bit_offset; +  u_int8_t data[MAXIMUM_FRAME_SIZE]; +  u_int8_t parity[MAXIMUM_FRAME_SIZE]; /* Only the LSB of each byte is used */ +} iso14443_frame; + +extern const iso14443_frame ATQA_FRAME; +  #endif /*ISO14443_LAYER3A_H_*/ diff --git a/openpicc/application/iso14443a_manchester.c b/openpicc/application/iso14443a_manchester.c index efc4baf..eff5a31 100644 --- a/openpicc/application/iso14443a_manchester.c +++ b/openpicc/application/iso14443a_manchester.c @@ -25,7 +25,7 @@   * 		MSB first		LSB first	hex LSB first   * Sequence D	1010101000000000	0000000001010101	0x0055   * Sequence E	0000000010101010	0101010100000000	0x5500 - * Sequence F	1010101010101010	0101010101010101	0x5555 + * Sequence F	0000000000000000	0000000000000000	0x0000   *   * Logic 1	Sequence D   * Logic 0	Sequence E @@ -44,79 +44,93 @@  #define MANCHESTER_SEQ_D	0x0055  #define MANCHESTER_SEQ_E	0x5500 -#define MANCHESTER_SEQ_F	0x5555 +#define MANCHESTER_SEQ_F	0x0000  #include <errno.h>  #include <string.h>  #include "openpicc.h" +#include "iso14443_layer3a.h" +#include "iso14443a_manchester.h" -static u_int32_t manchester_sample_size(u_int8_t frame_bytelen) __attribute__((unused)); -static u_int32_t manchester_sample_size(u_int8_t frame_bytelen) -{ -	/* 16 bits (2 bytes) per bit => 16 bytes samples per data byte, -	 * plus 16bit (2 bytes) parity per data byte -	 * plus 16bit (2 bytes) SOF plus 16bit (2 bytes) EOF */ -	return (frame_bytelen*18) + 2 + 2; - -	/* this results in a maximum samples-per-frame size of 4612 bytes -	 * for a 256byte frame */ -} - -struct manch_enc_state { -	const char *data; -	char *samples; -	u_int16_t *samples16; +enum parity { +	PARITY_NONE, /* Don't add a parity bit */ +	ODD_PARITY, EVEN_PARITY, /* Calculate parity */ +	PARITY_0, PARITY_1 /* Set fixed parity */  }; -static void manchester_enc_byte(struct manch_enc_state *mencs, u_int8_t data) __attribute__((unused)); -static void manchester_enc_byte(struct manch_enc_state *mencs, u_int8_t data) +static void manchester_enc_byte(u_int16_t **s16, u_int8_t data, enum parity parity)  {  	int i;  	u_int8_t sum_1 = 0; +	u_int16_t *samples16 = *s16;  	/* append 8 sample blobs, one for each bit */  	for (i = 0; i < 8; i++) {  		if (data & (1 << i)) { -			*(mencs->samples16) = MANCHESTER_SEQ_D; +			*(samples16) = MANCHESTER_SEQ_D;  			sum_1++;  		} else { -			*(mencs->samples16) = MANCHESTER_SEQ_E; +			*(samples16) = MANCHESTER_SEQ_E; +		} +		samples16++; +	} +	if(parity != PARITY_NONE) { +		/* Append parity */ +		u_int8_t par=0; +		switch(parity) { +			case PARITY_NONE: break; +			case PARITY_0: par = 0; break; +			case PARITY_1: par = 1; break; +			case ODD_PARITY:  par = (sum_1 & 0x1) ? 0 : 1; break; +			case EVEN_PARITY: par = (sum_1 & 0x1) ? 1 : 0; break;  		} -		mencs->samples16++; +		if (par) +			*(samples16) = MANCHESTER_SEQ_D; +		else +			*(samples16) = MANCHESTER_SEQ_E; +		samples16++;  	} -	/* append odd parity */ -	if (sum_1 & 0x01) -		*(mencs->samples16) = MANCHESTER_SEQ_E; -	else -		*(mencs->samples16) = MANCHESTER_SEQ_D; -	mencs->samples16++; +	*s16 = samples16;  } -#if 0 -/* Broken? */ -int manchester_encode(char *sample_buf, u_int16_t sample_buf_len,  -		      const char *data, u_int8_t data_len) +int manchester_encode(u_int8_t *sample_buf, u_int16_t sample_buf_len,  +		      const iso14443_frame *frame)  { -	int i, enc_size; -	struct manch_enc_state mencs; - -	enc_size = manchester_sample_size(data_len); +	unsigned int i, enc_size; +	u_int16_t *samples16; +	 +	if(frame->type != TYPE_A) return -EINVAL; +	if(frame->parameters.a.format != STANDARD_FRAME) return -EINVAL; /* AC not implemented yet */ +	 +	/* One bit data is 16 bit/2 byte modulation data */ +	enc_size = 2*2 /* SOF and EOF */ +		+ frame->numbytes * 8 * 2 +		+ ((frame->parameters.a.parity != NO_PARITY) ? 1 : 0)*8*2;  	if (sample_buf_len < enc_size)  		return -EINVAL; +	 +	samples16 = (u_int16_t*)sample_buf;  	/* SOF */ -	*(mencs.samples16++) = MANCHESTER_SEQ_D; - -	for (i = 0; i < data_len; i++) -		manchester_enc_byte(&mencs, data[i]); +	*(samples16++) = MANCHESTER_SEQ_D; +	 +	if(frame->parameters.a.parity == NO_PARITY) +		for (i = 0; i < frame->numbytes; i++) +			manchester_enc_byte(&samples16, frame->data[i], PARITY_NONE); +	else if(frame->parameters.a.parity == GIVEN_PARITY) +		for (i = 0; i < frame->numbytes; i++) +			manchester_enc_byte(&samples16, frame->data[i], frame->parity[i]?PARITY_1:PARITY_0); +	else if(frame->parameters.a.parity == PARITY) +		for (i = 0; i < frame->numbytes; i++) +			manchester_enc_byte(&samples16, frame->data[i], ODD_PARITY);  	/* EOF */ -	*(mencs.samples16++) = MANCHESTER_SEQ_F; +	*(samples16++) = MANCHESTER_SEQ_F;  	return enc_size;  } -#endif +  #if 0  /* Broken? */  #define BPSK_SPEED_212	 diff --git a/openpicc/application/main.c b/openpicc/application/main.c index 48e9ab2..a093d70 100644 --- a/openpicc/application/main.c +++ b/openpicc/application/main.c @@ -48,6 +48,7 @@  #include "tc_fdt.h"  #include "usb_print.h"  #include "iso14443_layer3a.h" +#include "decoder.h"  /**********************************************************************/  static inline void prvSetupHardware (void) @@ -76,8 +77,6 @@ void vApplicationIdleHook(void)  {      static char disabled_green = 0;      //static int i=0; -    /* Restart watchdog, has been enabled in Cstartup_SAM7.c */ -    AT91F_WDTRestart(AT91C_BASE_WDTC);      //vLedSetGreen(i^=1);      if(!disabled_green) {      	//vLedSetGreen(0); @@ -86,9 +85,9 @@ void vApplicationIdleHook(void)      usb_print_flush();  } -void main_help_print_buffer(ssc_dma_buffer_t *buffer, int *pktcount) +void main_help_print_buffer(ssc_dma_rx_buffer_t *buffer, int *pktcount)  { -	u_int16_t *tmp = (u_int16_t*)buffer->data; +	ISO14443A_SHORT_TYPE *tmp = (ISO14443A_SHORT_TYPE*)buffer->data;  	int i, dumped = 0;  	unsigned int j;  	for(i = buffer->len / sizeof(*tmp); i >= 0 ; i--) { @@ -102,7 +101,7 @@ void main_help_print_buffer(ssc_dma_buffer_t *buffer, int *pktcount)  				DumpStringToUSB(" ");  			}  			dumped = 1; -			DumpUIntToUSB(i); +			DumpUIntToUSB(buffer->len / sizeof(*tmp) - i);  			DumpStringToUSB(": ");  			for(j=0; j<sizeof(*tmp)*8; j++) {  				usb_print_char_f( (((*tmp) >> j) & 0x1) ? '1' : '_' , 0); @@ -120,7 +119,7 @@ void vMainTestSSCRXConsumer (void *pvParameters)  	static int pktcount=0;  	(void)pvParameters;  	while(1) { -		ssc_dma_buffer_t* buffer; +		ssc_dma_rx_buffer_t* buffer;  		if(xQueueReceive(ssc_rx_queue, &buffer, portMAX_DELAY)) {  			portENTER_CRITICAL();  			buffer->state = PROCESSING; @@ -142,11 +141,25 @@ void vMainTestSSCRXConsumer (void *pvParameters)  	}  } +/* This task pings the watchdog even when the idle task is not running + * It should be started with a very high priority and will delay most of the time */ +void vMainWatchdogPinger (void *pvParameters) +{ +	(void)pvParameters; +     +	while(1) { +		/* Restart watchdog, has been enabled in Cstartup_SAM7.c */ +    		AT91F_WDTRestart(AT91C_BASE_WDTC); +    		vTaskDelay(500*portTICK_RATE_MS); +	} +} +  /**********************************************************************/  int main (void)  {      prvSetupHardware ();      usb_print_init(); +    decoder_init();      pio_irq_init(); @@ -165,6 +178,9 @@ int main (void)      vCmdInit(); +    xTaskCreate (vMainWatchdogPinger, (signed portCHAR *) "WDT PINGER", 64, +	NULL, TASK_ISO_PRIORITY -1, NULL); +	      //vLedSetGreen(1);      /* Remap RAM to addr 0 */ diff --git a/openpicc/application/ssc_picc.c b/openpicc/application/ssc_picc.c index e9fdbfb..19f028e 100644 --- a/openpicc/application/ssc_picc.c +++ b/openpicc/application/ssc_picc.c @@ -52,16 +52,18 @@  static const AT91PS_SSC ssc = AT91C_BASE_SSC;  static AT91PS_PDC rx_pdc; -static ssc_dma_buffer_t dma_buffers[SSC_DMA_BUFFER_COUNT]; +static ssc_dma_rx_buffer_t dma_buffers[SSC_DMA_BUFFER_COUNT];  xQueueHandle ssc_rx_queue = NULL; +ssc_dma_tx_buffer_t ssc_tx_buffer; +  #define TEST_WHETHER_NOT_ENABLING_IT_HELPS  #define TEST_WHETHER_THIS_INTERRUPT_WORKS_AT_ALL -static ssc_dma_buffer_t* __ramfunc ssc_find_dma_buffer(ssc_dma_buffer_state_t oldstate,  +static ssc_dma_rx_buffer_t* __ramfunc ssc_find_dma_buffer(ssc_dma_buffer_state_t oldstate,   	ssc_dma_buffer_state_t newstate)  { -	ssc_dma_buffer_t* result = NULL;  +	ssc_dma_rx_buffer_t* result = NULL;   	int i=0;  	for(i=0; i<SSC_DMA_BUFFER_COUNT; i++) {  		if(dma_buffers[i].state == oldstate) { @@ -74,18 +76,18 @@ static ssc_dma_buffer_t* __ramfunc ssc_find_dma_buffer(ssc_dma_buffer_state_t ol  }  struct ssc_state { -	ssc_dma_buffer_t* buffer[2]; +	ssc_dma_rx_buffer_t* buffer[2];  	enum ssc_mode mode;  };  static struct ssc_state ssc_state; -static const u_int16_t ssc_dmasize[] = { -	[SSC_MODE_NONE]			= 16, -	[SSC_MODE_14443A_SHORT]		= 16,	/* 64 bytes */ -	[SSC_MODE_14443A_STANDARD]	= 16,	/* 64 bytes */ -	[SSC_MODE_14443B]		= 16,	/* 64 bytes */ -	[SSC_MODE_EDGE_ONE_SHOT] 	= 16,	/* 64 bytes */ -	[SSC_MODE_CONTINUOUS]		= 511,	/* 2044 bytes */ +static const struct {u_int16_t bytes; u_int16_t transfers;} ssc_dmasize[] = { +	[SSC_MODE_NONE]			= {0, 0}, +	[SSC_MODE_14443A_SHORT]		= {ISO14443A_SHORT_TRANSFER_SIZE/8, 1},	/* 1 transfer of ISO14443A_SHORT_LEN bits */ +	[SSC_MODE_14443A_STANDARD]	= {16*4, 16},	/* 64 bytes */ +	[SSC_MODE_14443B]		= {16*4, 16},	/* 64 bytes */ +	[SSC_MODE_EDGE_ONE_SHOT] 	= {16*4, 16},	/* 64 bytes */ +	[SSC_MODE_CONTINUOUS]		= {511*4, 511},	/* 2044 bytes */  };  #define SSC_RX_IRQ_MASK	(AT91C_SSC_RXRDY | 	\ @@ -117,7 +119,7 @@ void ssc_rx_mode_set(enum ssc_mode ssc_mode)  		sync_len = ISO14443A_SOF_LEN;  		ssc->SSC_RC0R = ISO14443A_SOF_SAMPLE;  		data_len = ISO14443A_SHORT_LEN; -		num_data = 16; +		num_data = 2;  		break;  	case SSC_MODE_14443A_STANDARD:  		start_cond = AT91C_SSC_START_0; @@ -159,9 +161,9 @@ void ssc_rx_mode_set(enum ssc_mode ssc_mode)  	/* Enable RX interrupts */  #ifdef TEST_WHETHER_NOT_ENABLING_IT_HELPS - +/*  	AT91F_SSC_EnableIt(ssc, AT91C_SSC_OVRUN | AT91C_SSC_CP0 | -			   AT91C_SSC_ENDRX | AT91C_SSC_RXBUFF); +			   AT91C_SSC_ENDRX | AT91C_SSC_RXBUFF);*/  #endif  out_set_mode:  	ssc_state.mode = ssc_mode; @@ -249,7 +251,7 @@ int ssc_count_free(void) {  static int __ramfunc __ssc_rx_refill(int secondary)  { -	ssc_dma_buffer_t *buffer; +	ssc_dma_rx_buffer_t *buffer;  	buffer = ssc_find_dma_buffer(FREE, PENDING);  	if (!buffer) { @@ -260,14 +262,14 @@ static int __ramfunc __ssc_rx_refill(int secondary)  	//init_opcdhdr(buffer);  	DEBUGR("filling SSC RX%u dma ctx: %u (len=%u) ", secondary,  		req_ctx_num(buffer), buffer->size); -	buffer->len = ssc_dmasize[ssc_state.mode]*4; +	buffer->len = ssc_dmasize[ssc_state.mode].bytes;  	if (secondary) {  		AT91F_PDC_SetNextRx(rx_pdc, buffer->data, -				    ssc_dmasize[ssc_state.mode]); +				    ssc_dmasize[ssc_state.mode].transfers);  		ssc_state.buffer[1] = buffer;  	} else {  		AT91F_PDC_SetRx(rx_pdc, buffer->data, -				ssc_dmasize[ssc_state.mode]); +				ssc_dmasize[ssc_state.mode].transfers);  		ssc_state.buffer[0] = buffer;  	} @@ -360,9 +362,10 @@ static void __ramfunc ssc_irq(void)  		/* in a one-shot sample, we don't want to keep  		 * sampling further after having received the first  		 * packet.  */ -		if (ssc_state.mode == SSC_MODE_EDGE_ONE_SHOT) { +		if (ssc_state.mode == SSC_MODE_EDGE_ONE_SHOT || ssc_state.mode == SSC_MODE_14443A_SHORT) {  			DEBUGP("DISABLE_RX ");  			ssc_rx_stop(); +			vLedSetGreen(1);  		}  		//AT91F_SSC_DisableIt(AT91C_BASE_SSC, SSC_RX_IRQ_MASK);  #endif @@ -389,12 +392,6 @@ static void __ramfunc ssc_irq(void)  			ssc_state.buffer[0]->state = FULL;  			//gaportEXIT_CRITICAL();  			task_woken = xQueueSendFromISR(ssc_rx_queue, &ssc_state.buffer[0], task_woken); -			/*vLedBlinkRed(); -			vLedSetRed(1); for(i=0; i<50; i++) (void)i; vLedSetRed(0);  -			for(i=0; i<ssc_state.buffer[0]->len*8; i++) { -				vLedSetRed( ssc_state.buffer[0]->data[i/8] & (1<<(i%8)) ); -			} -			vLedBlinkRed();*/  		} else {  			DEBUGP("EMPTY");  			//gaportENTER_CRITICAL(); @@ -405,30 +402,28 @@ static void __ramfunc ssc_irq(void)  		/* second buffer gets propagated to primary */  		ssc_state.buffer[0] = ssc_state.buffer[1];  		ssc_state.buffer[1] = NULL; -		if (ssc_sr & AT91C_SSC_RXBUFF) { -// FIXME -			DEBUGP("RXBUFF! "); -			if (ssc_state.buffer[0]) { -				//DEBUGP("Sending secondary RCTX(%u, len=%u) ", req_ctx_num(ssc_state.rx_ctx[0]), ssc_state.rx_ctx[0]->tot_len); -				//gaportENTER_CRITICAL(); -				ssc_state.buffer[0]->state = FULL; -				//gaportEXIT_CRITICAL(); -				task_woken = xQueueSendFromISR(ssc_rx_queue, &ssc_state.buffer[0], task_woken); +		if(ssc_state.mode != SSC_MODE_14443A_SHORT) { +			if (ssc_sr & AT91C_SSC_RXBUFF) { +	// FIXME +				DEBUGP("RXBUFF! "); +				if (ssc_state.buffer[0]) { +					//DEBUGP("Sending secondary RCTX(%u, len=%u) ", req_ctx_num(ssc_state.rx_ctx[0]), ssc_state.rx_ctx[0]->tot_len); +					//gaportENTER_CRITICAL(); +					ssc_state.buffer[0]->state = FULL; +					//gaportEXIT_CRITICAL(); +					task_woken = xQueueSendFromISR(ssc_rx_queue, &ssc_state.buffer[0], task_woken); +				} +				if (__ssc_rx_refill(0) == -1) +					AT91F_SSC_DisableIt(ssc, AT91C_SSC_ENDRX | +							    AT91C_SSC_RXBUFF | +							    AT91C_SSC_OVRUN);  			} -			if (__ssc_rx_refill(0) == -1) +	 +			if (__ssc_rx_refill(1) == -1)  				AT91F_SSC_DisableIt(ssc, AT91C_SSC_ENDRX |  						    AT91C_SSC_RXBUFF |  						    AT91C_SSC_OVRUN); -		} - -		if (__ssc_rx_refill(1) == -1) -			AT91F_SSC_DisableIt(ssc, AT91C_SSC_ENDRX | -					    AT91C_SSC_RXBUFF | -					    AT91C_SSC_OVRUN); - -//		udp_refill_ep(2); -		 -		if(ssc_state.mode == SSC_MODE_14443A_SHORT) { +		} else {  			// Stop sampling here  			ssc_rx_stop();  		} @@ -503,8 +498,11 @@ void ssc_rx_unthrottle(void)  void ssc_rx_start(void)  { -	//DEBUGPCRF("starting SSC RX\n");	 - +	//DEBUGPCRF("starting SSC RX\n"); +	 +	__ssc_rx_refill(0); +	if(ssc_state.mode != SSC_MODE_14443A_SHORT) __ssc_rx_refill(1); +	  	/* Enable Reception */  #ifdef TEST_WHETHER_NOT_ENABLING_IT_HELPS  	AT91F_SSC_EnableIt(ssc, AT91C_SSC_ENDRX | AT91C_SSC_CP0 | @@ -596,9 +594,8 @@ void ssc_rx_init(void)  #endif  	ssc_rx_mode_set(SSC_MODE_NONE); +	ssc_state.buffer[0] = ssc_state.buffer[1] = NULL; -	__ssc_rx_refill(0); -	__ssc_rx_refill(1);  #if 0  	AT91F_PDC_EnableRx(rx_pdc); diff --git a/openpicc/application/ssc_picc.h b/openpicc/application/ssc_picc.h index 813ef33..db3cc00 100644 --- a/openpicc/application/ssc_picc.h +++ b/openpicc/application/ssc_picc.h @@ -2,6 +2,7 @@  #define _SSC_H  #include "queue.h" +#include "iso14443_layer3a.h"  extern void ssc_rx_start(void);  extern void ssc_rx_stop(void); @@ -29,7 +30,7 @@ extern portBASE_TYPE ssc_get_overflows(void);  extern int ssc_count_free(void);  #define SSC_DMA_BUFFER_SIZE 2048 -#define SSC_DMA_BUFFER_COUNT 10 +#define SSC_DMA_BUFFER_COUNT 4  typedef enum {  	FREE=0,    /* Buffer is free */ @@ -43,8 +44,22 @@ typedef struct {  	u_int32_t len;  /* Length of the content */  	enum ssc_mode reception_mode;  	u_int8_t data[SSC_DMA_BUFFER_SIZE]; -} ssc_dma_buffer_t; +} ssc_dma_rx_buffer_t;  extern xQueueHandle ssc_rx_queue; +/* in bytes, used for the sample buffer that holds the subcarrier modulation data at fc/8 = 1695 MHz */ +#define SSC_TX_BUFFER_SIZE ((MAXIMUM_FRAME_SIZE*( (8+1)*2 ) ) + 2 + 2) + +typedef struct { +	volatile ssc_dma_buffer_state_t state; +	u_int32_t len;  /* Length of the content */ +	u_int8_t data[SSC_TX_BUFFER_SIZE]; +} ssc_dma_tx_buffer_t; + +/* Declare one TX buffer. This means that only one buffer can ever be pending for sending. That's because + * this buffer must be huge (one frame of 256 bytes of subcarrier modulation data at  1695 MHz sample + * rate is approx 4k bytes). */ +extern ssc_dma_tx_buffer_t ssc_tx_buffer; +  #endif diff --git a/openpicc/os/boot/Cstartup_SAM7.c b/openpicc/os/boot/Cstartup_SAM7.c index 88af706..5371794 100644 --- a/openpicc/os/boot/Cstartup_SAM7.c +++ b/openpicc/os/boot/Cstartup_SAM7.c @@ -36,7 +36,7 @@ void AT91F_LowLevelInit (void)      AT91C_BASE_MC->MC_FMR = ((AT91C_MC_FMCN) & (75 << 16)) | AT91C_MC_FWS_1FWS;      //* Watchdog Enable -    AT91C_BASE_WDTC->WDTC_WDMR = (0x480 << 16) | AT91C_WDTC_WDRSTEN | 0x480; +    AT91C_BASE_WDTC->WDTC_WDMR = (0x180 << 16) | AT91C_WDTC_WDRSTEN | 0x180;      //AT91C_BASE_WDTC->WDTC_WDMR = 0x8000;      //* Set MCK at 47 923 200  | 
