diff options
Diffstat (limited to 'openpicc')
-rw-r--r-- | openpicc/application/cmd.c | 17 | ||||
-rw-r--r-- | openpicc/application/main.c | 66 | ||||
-rw-r--r-- | openpicc/application/pio_irq.c | 19 | ||||
-rw-r--r-- | openpicc/application/pio_irq.h | 1 | ||||
-rw-r--r-- | openpicc/application/pll.c | 2 | ||||
-rw-r--r-- | openpicc/application/ssc_picc.c | 315 | ||||
-rw-r--r-- | openpicc/application/ssc_picc.h | 23 | ||||
-rw-r--r-- | openpicc/application/tc_cdiv_sync.c | 8 | ||||
-rw-r--r-- | openpicc/application/tc_fdt.c | 17 | ||||
-rw-r--r-- | openpicc/os/boot/Cstartup_SAM7.c | 3 |
10 files changed, 323 insertions, 148 deletions
diff --git a/openpicc/application/cmd.c b/openpicc/application/cmd.c index 4ba149f..1e7b552 100644 --- a/openpicc/application/cmd.c +++ b/openpicc/application/cmd.c @@ -193,6 +193,13 @@ void prvExecCommand(u_int32_t cmd, portCHAR *args) { DumpStringToUSB("cdiv_sync enabled \n\r"); } break; + case 'D': + i=atoiEx(args, &args); + tc_cdiv_set_divider(i); + DumpStringToUSB("tc_cdiv set to "); + DumpUIntToUSB(i); + DumpStringToUSB("\n\r"); + break; case 'P': print_pio(); break; @@ -236,6 +243,15 @@ void prvExecCommand(u_int32_t cmd, portCHAR *args) { DumpStringToUSB(" * current field strength: "); DumpUIntToUSB(adc_get_field_strength()); DumpStringToUSB("\n\r"); + DumpStringToUSB(" * SSC RX overflows: "); + DumpUIntToUSB(ssc_get_overflows()); + DumpStringToUSB("\n\r"); + DumpStringToUSB(" * SSC free buffers: "); + DumpUIntToUSB(ssc_count_free()); + DumpStringToUSB("\n\r"); + DumpStringToUSB(" * SSC status: "); + DumpUIntToUSB(AT91C_BASE_SSC->SSC_SR); + DumpStringToUSB("\n\r"); DumpStringToUSB( " *\n\r" " *****************************************************\n\r" @@ -296,6 +312,7 @@ void prvExecCommand(u_int32_t cmd, portCHAR *args) { " * z 0/1- enable or disable tc_cdiv_sync\n\r" " * ! - reset tc_cdiv_sync\n\r" " * q - start rx\n\r" + " * d div- set tc_cdiv divider value 16, 32, 64, ...\n\r" " * 9 - reset CPU\n\r" " * ?,h - display this help screen\n\r" " *\n\r" diff --git a/openpicc/application/main.c b/openpicc/application/main.c index fd776ec..e13c793 100644 --- a/openpicc/application/main.c +++ b/openpicc/application/main.c @@ -74,8 +74,10 @@ static inline void prvSetupHardware (void) 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); disabled_green = 1; @@ -83,6 +85,57 @@ void vApplicationIdleHook(void) usb_print_flush(); } +void vMainTestSSCRXConsumer (void *pvParameters) +{ + int i, dumped; + static int pktcount=0; + unsigned int j; + u_int32_t *tmp; + (void)pvParameters; + while(1) { + ssc_dma_buffer_t* buffer; + if(xQueueReceive(ssc_rx_queue, &buffer, portMAX_DELAY)) { + portENTER_CRITICAL(); + buffer->state = PROCESSING; + portEXIT_CRITICAL(); + /*vLedBlinkGreen(); + for(i=0; i<buffer->len*8; i++) { + vLedSetGreen( buffer->data[i/8] & (1<<(i%8)) ); + } + vLedBlinkGreen();*/ + //i = usb_print_set_default_flush(0); + + tmp = (u_int32_t*)buffer->data; + dumped = 0; + for(i = buffer->len / sizeof(*tmp); i >= 0 ; i--) { + if( *tmp != 0x00000000 ) { + if(dumped == 0) { + DumpUIntToUSB(buffer->len); + DumpStringToUSB(", "); + DumpUIntToUSB(pktcount++); + DumpStringToUSB(": "); + } else { + DumpStringToUSB(" "); + } + dumped = 1; + for(j=0; j<sizeof(*tmp)*8; j++) { + usb_print_char_f( (((*tmp) >> j) & 0x1) ? '1' : '_' , 0); + } + usb_print_flush(); + //DumpBufferToUSB((char*)(tmp), sizeof(*tmp)); + } + tmp++; + } + if(dumped) DumpStringToUSB("\n\r"); + + //usb_print_set_default_flush(i); + portENTER_CRITICAL(); + buffer->state = FREE; + portEXIT_CRITICAL(); + } + } +} + /**********************************************************************/ int main (void) { @@ -99,9 +152,20 @@ int main (void) pll_init(); tc_cdiv_init(); + tc_cdiv_set_divider(16); tc_fdt_init(); +#if 0 ssc_tx_init(); - //ssc_rx_init(); +#else + AT91F_PIO_CfgInput(AT91C_BASE_PIOA, OPENPICC_MOD_PWM); + AT91F_PIO_CfgPeriph(AT91C_BASE_PIOA, OPENPICC_MOD_SSC | + OPENPICC_SSC_DATA | OPENPICC_SSC_DATA | + AT91C_PIO_PA15, 0); +#endif + ssc_rx_init(); + + xTaskCreate (vMainTestSSCRXConsumer, (signed portCHAR *) "SSC_CONSUMER", TASK_USB_STACK, + NULL, TASK_USB_PRIORITY, NULL); xTaskCreate (vUSBCDCTask, (signed portCHAR *) "USB", TASK_USB_STACK, NULL, TASK_USB_PRIORITY, NULL); diff --git a/openpicc/application/pio_irq.c b/openpicc/application/pio_irq.c index 5a82a85..648a561 100644 --- a/openpicc/application/pio_irq.c +++ b/openpicc/application/pio_irq.c @@ -85,15 +85,12 @@ void __ramfunc __pio_irq_demux(u_int32_t pio) } /* regular interrupt handler, in case fast forcing for PIOA disabled */ -static void pio_irq_demux_inner(void) +static void pio_irq_demux(void) __attribute__ ((naked)); +static void pio_irq_demux(void) { + portSAVE_CONTEXT(); u_int32_t pio = AT91F_PIO_GetInterruptStatus(AT91C_BASE_PIOA); __pio_irq_demux(pio); -} -static void pio_irq_demux_outer(void) __attribute__ ((naked)); -static void pio_irq_demux_outer(void) { - portSAVE_CONTEXT(); - pio_irq_demux_inner(); portRESTORE_CONTEXT(); } @@ -144,11 +141,19 @@ void pio_irq_unregister(u_int32_t pio) pirqs.handlers[num] = NULL; } +static int initialized = 0; +void pio_irq_init_once(void) +{ + if(!initialized) pio_irq_init(); +} + void pio_irq_init(void) { + initialized = 1; AT91F_PIOA_CfgPMC(); AT91F_AIC_ConfigureIt(AT91C_ID_PIOA, OPENPICC_IRQ_PRIO_PIO, - AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL, &pio_irq_demux_outer); + AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL, &pio_irq_demux); AT91F_AIC_EnableIt(AT91C_ID_PIOA); + (void)pio_irq_demux; // FIXME NO IRQ } diff --git a/openpicc/application/pio_irq.h b/openpicc/application/pio_irq.h index ecb6fef..98a4b63 100644 --- a/openpicc/application/pio_irq.h +++ b/openpicc/application/pio_irq.h @@ -12,5 +12,6 @@ extern long pio_irq_get_count(void); extern int pio_irq_register(u_int32_t pio, irq_handler_t *func); extern void pio_irq_unregister(u_int32_t pio); extern void pio_irq_init(void); +extern void pio_irq_init_once(void); #endif diff --git a/openpicc/application/pll.c b/openpicc/application/pll.c index b9aa495..62236ae 100644 --- a/openpicc/application/pll.c +++ b/openpicc/application/pll.c @@ -42,7 +42,7 @@ static void pll_lock_change_cb(u_int32_t pio) { (void)pio; DEBUGPCRF("PLL LOCK: %d", pll_is_locked()); -#if 1 +#if 0 vLedSetRed(pll_is_locked()); #endif } diff --git a/openpicc/application/ssc_picc.c b/openpicc/application/ssc_picc.c index f1eeef4..176af88 100644 --- a/openpicc/application/ssc_picc.c +++ b/openpicc/application/ssc_picc.c @@ -31,9 +31,12 @@ #include <lib_AT91SAM7.h> #include <FreeRTOS.h> -//#include <os/usb_handler.h> +#include "queue.h" +#include "task.h" + #include "dbgu.h" #include "led.h" +#include "cmd.h" #include "board.h" #include "openpicc.h" @@ -41,6 +44,8 @@ #include "tc_cdiv_sync.h" #include "tc_fdt.h" +#include "usb_print.h" + //#define DEBUG_SSC_REFILL /* definitions for four-times oversampling */ @@ -50,8 +55,29 @@ static const AT91PS_SSC ssc = AT91C_BASE_SSC; static AT91PS_PDC rx_pdc; +static ssc_dma_buffer_t dma_buffers[SSC_DMA_BUFFER_COUNT]; +xQueueHandle ssc_rx_queue = NULL; + +#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, + ssc_dma_buffer_state_t newstate) +{ + ssc_dma_buffer_t* result = NULL; + int i=0; + for(i=0; i<SSC_DMA_BUFFER_COUNT; i++) { + if(dma_buffers[i].state == oldstate) { + result = &dma_buffers[i]; + result->state = newstate; + break; + } + } + return result; +} + struct ssc_state { - struct req_ctx *rx_ctx[2]; + ssc_dma_buffer_t* buffer[2]; enum ssc_mode mode; }; static struct ssc_state ssc_state; @@ -129,7 +155,9 @@ void ssc_rx_mode_set(enum ssc_mode ssc_mode) //ssc->SSC_RFMR = AT91C_SSC_MSBF | (data_len-1) & 0x1f | ssc->SSC_RFMR = ((data_len-1) & 0x1f) | (((num_data-1) & 0x0f) << 8) | - (((sync_len-1) & 0x0f) << 16); + (((sync_len-1) & 0x0f) << 16) + //| AT91C_SSC_MSBF + ; ssc->SSC_RCMR = AT91C_SSC_CKS_RK | AT91C_SSC_CKO_NONE | (0x2 << 6) | AT91C_SSC_CKI | start_cond; @@ -137,8 +165,11 @@ void ssc_rx_mode_set(enum ssc_mode ssc_mode) AT91F_PDC_EnableRx(rx_pdc); /* 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); +#endif out_set_mode: ssc_state.mode = ssc_mode; } @@ -176,7 +207,9 @@ static void ssc_tx_mode_set(enum ssc_mode ssc_mode) (((sync_len-1) & 0x0f) << 16); ssc->SSC_TCMR = AT91C_SSC_CKS_RK | AT91C_SSC_CKO_NONE | start_cond; +#ifdef TEST_WHETHER_NOT_ENABLING_IT_HELPS AT91F_SSC_EnableIt(ssc, AT91C_SSC_TXSYN); +#endif AT91F_SSC_EnableTx(AT91C_BASE_SSC); #if 0 /* Enable RX interrupts */ @@ -208,108 +241,129 @@ static void ssc_tx_mode_set(enum ssc_mode ssc_mode) #define DEBUGR(x, args ...) #endif +static volatile portBASE_TYPE overflows; +portBASE_TYPE ssc_get_overflows(void) { + return overflows; +} + +int ssc_count_free(void) { + int i,free = 0; + for(i=0; i<SSC_DMA_BUFFER_COUNT; i++) { + if(dma_buffers[i].state == FREE) free++; + } + return free; +} + static int __ramfunc __ssc_rx_refill(int secondary) { - (void)secondary; -// FIXME -/* struct req_ctx *rctx; - - rctx = req_ctx_find_get(1, RCTX_STATE_FREE, RCTX_STATE_SSC_RX_BUSY); - if (!rctx) { + ssc_dma_buffer_t *buffer; + + buffer = ssc_find_dma_buffer(FREE, PENDING); + if (!buffer) { DEBUGP("no_rctx_for_refill! "); + overflows++; return -1; } - init_opcdhdr(rctx); + //init_opcdhdr(buffer); DEBUGR("filling SSC RX%u dma ctx: %u (len=%u) ", secondary, - req_ctx_num(rctx), rctx->size); - rctx->tot_len = ssc_dmasize[ssc_state.mode]*4 + - sizeof(struct openpcd_hdr); + req_ctx_num(buffer), buffer->size); + buffer->len = ssc_dmasize[ssc_state.mode]*4; if (secondary) { - AT91F_PDC_SetNextRx(rx_pdc, rctx->data+MAX_HDRSIZE, + AT91F_PDC_SetNextRx(rx_pdc, buffer->data, ssc_dmasize[ssc_state.mode]); - ssc_state.rx_ctx[1] = rctx; + ssc_state.buffer[1] = buffer; } else { - AT91F_PDC_SetRx(rx_pdc, rctx->data+MAX_HDRSIZE, + AT91F_PDC_SetRx(rx_pdc, buffer->data, ssc_dmasize[ssc_state.mode]); - ssc_state.rx_ctx[0] = rctx; + ssc_state.buffer[0] = buffer; } -*/ - tc_cdiv_sync_reset(); + + //tc_cdiv_sync_reset(); return 0; } -#if 0 -static char dmabuf1[512]; -static char dmabuf2[512]; - -/* Try to refill RX dma descriptors. Return values: - * 0) no dma descriptors empty - * 1) filled next/secondary descriptor - * 2) filled both primary and secondary descriptor - * -1) no free request contexts to use - * -2) only one free request context, but two free descriptors - */ -static int8_t ssc_rx_refill(void) +#define ISO14443A_FDT_SHORT_1 1236 +#define ISO14443A_FDT_SHORT_0 1172 + +static void __ramfunc ssc_irq_short_inner(void) __attribute__ ((naked)); +static void __ramfunc ssc_irq_short_inner(void) { - struct req_ctx *rctx; - DEBUGR("refill "); -#if 1 - rctx = req_ctx_find_get(1, RCTX_STATE_FREE, RCTX_STATE_SSC_RX_BUSY); - DEBUGP("SSC_SR=0x%08x ", ssc->SSC_SR); - if (AT91F_PDC_IsRxEmpty(rx_pdc)) { - DEBUGR("filling primary SSC RX dma ctx: %u (len=%u) ", - req_ctx_num(rctx), rctx->size); - rctx->tot_len = rctx->size; - AT91F_PDC_SetRx(rx_pdc, rctx->data+MAX_HDRSIZE, - (rctx->size-MAX_HDRSIZE)>>2); - ssc_state.rx_ctx[0] = rctx; - - /* If primary is empty, secondary must be empty, too */ - rctx = req_ctx_find_get(1, RCTX_STATE_FREE, - RCTX_STATE_SSC_RX_BUSY); - if (!rctx) { - DEBUGPCRF("no rctx for secondary refill!"); - return -2; + portENTER_SWITCHING_ISR(); + portBASE_TYPE task_woken = pdFALSE; + static volatile int i = 0, flush; + vLedSetRed(1); + u_int32_t ssc_sr = ssc->SSC_SR; + (void)ssc_sr; + + i++; + flush = usb_print_set_default_flush(0); + DumpStringToUSB("b "); + DumpUIntToUSB(ssc_sr); + DumpStringToUSB("\t"); + DumpUIntToUSB(ssc_count_free()); + DumpStringToUSB("\t"); + DumpUIntToUSB(ssc->SSC_IMR); + DumpStringToUSB("\n\r"); + + + if (ssc_sr & AT91C_SSC_ENDRX) { + //ssc_rx_stop(); + /*if(i>10000) { + AT91F_AIC_DisableIt(AT91C_ID_SSC); + DumpStringToUSB("SSC IRQ Disabled\n\r"); + }*/ + + ssc_state.buffer[0]->state = FULL; + vLedSetGreen(1); + task_woken = xQueueSendFromISR(ssc_rx_queue, &ssc_state.buffer[0], task_woken); + DumpStringToUSB("Sent "); + DumpUIntToUSB((int)ssc_state.buffer[0]); + DumpStringToUSB("\n\r"); + vLedSetGreen(0); + ssc_state.buffer[0] = ssc_state.buffer[1]; + ssc_state.buffer[1] = NULL; + if(__ssc_rx_refill(1) == -1) { + AT91F_AIC_DisableIt(AT91C_ID_SSC); + DumpStringToUSB("SSC IRQ Disabled\n\r"); } - init_opcdhdr(rctx); - } - - if (AT91F_PDC_IsNextRxEmpty(rx_pdc)) { - DEBUGR("filling secondary SSC RX dma ctx: %u (len=%u) ", - req_ctx_num(rctx), rctx->size); - rctx->tot_len = rctx->size; - AT91F_PDC_SetNextRx(rx_pdc, rctx->data+MAX_HDRSIZE, - (rctx->size-MAX_HDRSIZE)>2); - ssc_state.rx_ctx[1] = rctx; - return 2; - } else { - /* we were unable to fill*/ - DEBUGPCRF("prim/secnd DMA busy, can't refill"); - req_ctx_put(rctx); - return 0; + + DumpStringToUSB("a "); + DumpUIntToUSB(ssc->SSC_SR); + DumpStringToUSB("\t"); + DumpUIntToUSB(ssc_count_free()); + DumpStringToUSB("\n\r"); } -#else - if (AT91F_PDC_IsRxEmpty(rx_pdc)) - AT91F_PDC_SetRx(rx_pdc, dmabuf1, sizeof(dmabuf1)>>2); - if (AT91F_PDC_IsNextRxEmpty(rx_pdc)) - AT91F_PDC_SetNextRx(rx_pdc, dmabuf2, sizeof(dmabuf2)>>2); - else - DEBUGPCRF("prim/secnd DMA busy, can't refill"); -#endif + usb_print_string(task_woken?"SSC: Task woken\n\r":""); + usb_print_set_default_flush(flush); + + AT91F_AIC_ClearIt(AT91C_ID_SSC); + AT91F_AIC_AcknowledgeIt(); + + vLedSetRed(0); + portEXIT_SWITCHING_ISR(task_woken); } -#endif - -#define ISO14443A_FDT_SHORT_1 1236 -#define ISO14443A_FDT_SHORT_0 1172 +/*static void __ramfunc ssc_irq_short_outer(void) __attribute__ ((naked)); +static void __ramfunc ssc_irq_short_outer(void) { + portSAVE_CONTEXT(); + ssc_irq_short_inner(); + portRESTORE_CONTEXT(); +}*/ -static void __ramfunc ssc_irq_inner(void) +static void __ramfunc ssc_irq(void) __attribute__ ((naked)); +static void __ramfunc ssc_irq(void) { + portENTER_SWITCHING_ISR(); + vLedSetRed(1); + portBASE_TYPE task_woken = pdFALSE; + +#ifdef TEST_WHETHER_THIS_INTERRUPT_WORKS_AT_ALL u_int32_t ssc_sr = ssc->SSC_SR; -// int i, *tmp, emptyframe = 0; + int i, emptyframe = 0; + u_int32_t *tmp; DEBUGP("ssc_sr=0x%08x, mode=%u: ", ssc_sr, ssc_state.mode); - + if (ssc_sr & AT91C_SSC_ENDRX) { #if 1 /* in a one-shot sample, we don't want to keep @@ -343,43 +397,53 @@ static void __ramfunc ssc_irq_inner(void) #endif /* Ignore empty frames */ if (ssc_state.mode == SSC_MODE_CONTINUOUS) { -// FIXME -// tmp = (u_int32_t*)ssc_state.rx_ctx[0]->data + MAX_HDRSIZE; -// emptyframe = 1; -// for(i = (ssc_state.rx_ctx[0]->size-MAX_HDRSIZE) / 4 - 8/*WTF?*/; i > 0; i--) { -// if( *tmp++ != 0xFFFFFFFF ) { -// DEBUGPCR("NONEMPTY(%08x, %i): %08x", tmp, i, *(tmp-1)); -// emptyframe = 0; -// break; -// } else { -// //DEBUGPCR("DUNNO(%08x, %i): %08x", tmp, i, tmp[i]); -// } -// } + tmp = (u_int32_t*)ssc_state.buffer[0]->data; + emptyframe = 1; + for(i = (ssc_state.buffer[0]->len) / 4 - 8/*WTF?*/; i > 0; i--) { + if( *tmp++ != 0xFFFFFFFF ) { + DEBUGPCR("NONEMPTY(%08x, %i): %08x", tmp, i, *(tmp-1)); + emptyframe = 0; + break; + } else { + //DEBUGPCR("DUNNO(%08x, %i): %08x", tmp, i, tmp[i]); + } + } } //DEBUGP("Sending primary RCTX(%u, len=%u) ", req_ctx_num(ssc_state.rx_ctx[0]), ssc_state.rx_ctx[0]->tot_len); /* Mark primary RCTX as ready to send for usb */ -// if(!emptyframe) { -// FIXME -// DEBUGP("NONEMPTY"); -// req_ctx_set_state(ssc_state.rx_ctx[0], -// RCTX_STATE_UDP_EP2_PENDING); -// //RCTX_STATE_FREE); -// } else { -// DEBUGP("EMPTY"); -// req_ctx_put(ssc_state.rx_ctx[0]); -// } + if(!emptyframe) { + //unsigned int i; + DEBUGP("NONEMPTY"); + //gaportENTER_CRITICAL(); + 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(); + ssc_state.buffer[0]->state = FREE; + //gaportEXIT_CRITICAL(); + } /* second buffer gets propagated to primary */ - ssc_state.rx_ctx[0] = ssc_state.rx_ctx[1]; - ssc_state.rx_ctx[1] = NULL; + ssc_state.buffer[0] = ssc_state.buffer[1]; + ssc_state.buffer[1] = NULL; if (ssc_sr & AT91C_SSC_RXBUFF) { -// DEBUGP("RXBUFF! "); -// if (ssc_state.rx_ctx[0]) { -// //DEBUGP("Sending secondary RCTX(%u, len=%u) ", req_ctx_num(ssc_state.rx_ctx[0]), ssc_state.rx_ctx[0]->tot_len); -// req_ctx_set_state(ssc_state.rx_ctx[0], -// RCTX_STATE_UDP_EP2_PENDING); -// //RCTX_STATE_FREE); -// } +// 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 | @@ -409,8 +473,6 @@ static void __ramfunc ssc_irq_inner(void) if (ssc_sr & AT91C_SSC_TXSYN) DEBUGP("TXSYN "); -#if 0 - led_toggle(1); switch (ssc_state.mode) { case SSC_MODE_14443A_SHORT: @@ -443,13 +505,10 @@ static void __ramfunc ssc_irq_inner(void) #endif DEBUGPCR("I"); AT91F_AIC_ClearIt(AT91C_ID_SSC); -} - -static void __ramfunc ssc_irq_outer(void) __attribute__ ((naked)); -static void __ramfunc ssc_irq_outer(void) { - portSAVE_CONTEXT(); - ssc_irq_inner(); - portRESTORE_CONTEXT(); + AT91F_AIC_AcknowledgeIt(); + + vLedSetRed(0); + portEXIT_SWITCHING_ISR(task_woken); } void ssc_print(void) @@ -463,8 +522,10 @@ void ssc_print(void) void ssc_rx_unthrottle(void) { +#ifdef TEST_WHETHER_NOT_ENABLING_IT_HELPS AT91F_SSC_EnableIt(ssc, AT91C_SSC_ENDRX | AT91C_SSC_CP0 | AT91C_SSC_RXBUFF | AT91C_SSC_OVRUN); +#endif } void ssc_rx_start(void) @@ -472,8 +533,10 @@ void ssc_rx_start(void) //DEBUGPCRF("starting SSC RX\n"); /* Enable Reception */ +#ifdef TEST_WHETHER_NOT_ENABLING_IT_HELPS AT91F_SSC_EnableIt(ssc, AT91C_SSC_ENDRX | AT91C_SSC_CP0 | AT91C_SSC_RXBUFF | AT91C_SSC_OVRUN); +#endif AT91F_SSC_EnableRx(AT91C_BASE_SSC); /* Clear the flipflop */ @@ -527,6 +590,9 @@ void ssc_rx_init(void) { tc_cdiv_sync_init(); tc_cdiv_sync_enable(); + + if(ssc_rx_queue == NULL) + ssc_rx_queue = xQueueCreate(10, sizeof(ssc_state.buffer[0])); rx_pdc = (AT91PS_PDC) &(ssc->SSC_RPR); @@ -542,7 +608,8 @@ void ssc_rx_init(void) AT91F_AIC_ConfigureIt(AT91C_ID_SSC, OPENPICC_IRQ_PRIO_SSC, - AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL, (THandler)&ssc_irq_outer); + AT91C_AIC_SRCTYPE_INT_POSITIVE_EDGE, (THandler)&ssc_irq); + (void)ssc_irq_short_inner; // FIXME SHORT IRQ IMPLEMENTATION /* don't divide clock inside SSC, we do that in tc_cdiv */ ssc->SSC_CMR = 0; @@ -555,10 +622,10 @@ void ssc_rx_init(void) ssc->SSC_RFMR = 31 | AT91C_SSC_MSBF | (14 << 8); #endif + ssc_rx_mode_set(SSC_MODE_NONE); + __ssc_rx_refill(0); __ssc_rx_refill(1); - - ssc_rx_mode_set(SSC_MODE_NONE); #if 0 AT91F_PDC_EnableRx(rx_pdc); diff --git a/openpicc/application/ssc_picc.h b/openpicc/application/ssc_picc.h index 0ba15d0..34bdc18 100644 --- a/openpicc/application/ssc_picc.h +++ b/openpicc/application/ssc_picc.h @@ -1,6 +1,8 @@ #ifndef _SSC_H #define _SSC_H +#include "queue.h" + extern void ssc_rx_start(void); extern void ssc_rx_stop(void); @@ -23,4 +25,25 @@ enum ssc_mode { extern void ssc_rx_mode_set(enum ssc_mode ssc_mode); +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 + +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) */ +} ssc_dma_buffer_state_t; + +typedef struct { + volatile ssc_dma_buffer_state_t state; + u_int32_t len; /* Length of the content */ + u_int8_t data[SSC_DMA_BUFFER_SIZE]; +} ssc_dma_buffer_t; + +extern xQueueHandle ssc_rx_queue; + #endif diff --git a/openpicc/application/tc_cdiv_sync.c b/openpicc/application/tc_cdiv_sync.c index 45c65b6..422fe44 100644 --- a/openpicc/application/tc_cdiv_sync.c +++ b/openpicc/application/tc_cdiv_sync.c @@ -24,7 +24,7 @@ static void pio_data_change(u_int32_t pio) *AT91C_TC0_CV); } else DEBUGPCR(""); - vLedSetGreen(0); + //vLedSetGreen(0); } void tc_cdiv_sync_reset(void) @@ -34,7 +34,7 @@ void tc_cdiv_sync_reset(void) (void)tmp; volatile int i; DEBUGPCRF("CDIV_SYNC_FLOP"); - vLedSetGreen(1); + //vLedSetGreen(1); /* reset the hardware flipflop */ AT91F_PIO_ClearOutput(AT91C_BASE_PIOA, @@ -63,6 +63,7 @@ void tc_cdiv_sync_enable(void) extern void (*fiq_handler)(void); void tc_cdiv_sync_init(void) { + pio_irq_init_once(); DEBUGPCRF("initializing"); enabled = 0; @@ -72,8 +73,7 @@ void tc_cdiv_sync_init(void) AT91F_PIO_CfgOutput(AT91C_BASE_PIOA, OPENPICC_PIO_SSC_DATA_CONTROL); pio_irq_register(OPENPICC_PIO_FRAME, &pio_data_change); - AT91F_AIC_EnableIt(AT91C_ID_PIOA); - vLedSetGreen(0); + //vLedSetGreen(0); tc_cdiv_sync_disable(); } diff --git a/openpicc/application/tc_fdt.c b/openpicc/application/tc_fdt.c index 179ea98..d8dbfd5 100644 --- a/openpicc/application/tc_fdt.c +++ b/openpicc/application/tc_fdt.c @@ -55,9 +55,11 @@ void tc_frame_end_set(u_int16_t count) tcfdt->TC_RB = count; } -static void tc_fdt_irq_inner(void) +static void tc_fdt_irq(void) __attribute__ ((naked)); +static void tc_fdt_irq(void) { - vLedSetGreen(1); + portSAVE_CONTEXT(); + //vLedSetGreen(1); u_int32_t sr = tcfdt->TC_SR; DEBUGP("tc_fdt_irq: TC2_SR=0x%08x TC2_CV=0x%08x ", sr, tcfdt->TC_CV); @@ -82,13 +84,7 @@ static void tc_fdt_irq_inner(void) } DEBUGPCR(""); AT91F_AIC_AcknowledgeIt(); - vLedSetGreen(0); -} - -static void tc_fdt_irq_outer(void) __attribute__ ((naked)); -static void tc_fdt_irq_outer(void) { - portSAVE_CONTEXT(); - tc_fdt_irq_inner(); + //vLedSetGreen(0); portRESTORE_CONTEXT(); } @@ -130,8 +126,9 @@ void tc_fdt_init(void) AT91F_AIC_ConfigureIt(AT91C_ID_TC2, OPENPCD_IRQ_PRIO_TC_FDT, - AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL, &tc_fdt_irq_outer); + AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL, &tc_fdt_irq); AT91F_AIC_EnableIt(AT91C_ID_TC2); + (void)tc_fdt_irq;// FIXME NO IRQ tcfdt->TC_IER = AT91C_TC_CPAS | AT91C_TC_CPBS | AT91C_TC_CPCS | AT91C_TC_ETRGS; diff --git a/openpicc/os/boot/Cstartup_SAM7.c b/openpicc/os/boot/Cstartup_SAM7.c index 450a95e..72c9917 100644 --- a/openpicc/os/boot/Cstartup_SAM7.c +++ b/openpicc/os/boot/Cstartup_SAM7.c @@ -34,7 +34,8 @@ 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 = (0x80 << 16) | AT91C_WDTC_WDRSTEN | 0x80; + AT91C_BASE_WDTC->WDTC_WDMR = (0x480 << 16) | AT91C_WDTC_WDRSTEN | 0x480; + //AT91C_BASE_WDTC->WDTC_WDMR = 0x8000; //* Set MCK at 47 923 200 // 1 Enabling the Main Oscillator: |