diff options
Diffstat (limited to 'openpicc/application')
-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 |
8 files changed, 264 insertions, 111 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 |