summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorhenryk <henryk@6dc7ffe9-61d6-0310-9af1-9938baff3ed1>2007-11-21 00:30:19 +0000
committerhenryk <henryk@6dc7ffe9-61d6-0310-9af1-9938baff3ed1>2007-11-21 00:30:19 +0000
commit5cc0ed498f99d3b23c6f1b87a9a2fdcbb05dd1a9 (patch)
treee0f681d5a7fc06f192abdac3961ab39e08f98592
parentac77f6b5c53c4f2afb97564d1d281c5fdc429409 (diff)
Checking in status quo: Can currently receive and print frames in ssc continuous mode (with new short and incomplete ssc irq handler: FIXME, either switch back to original handler (maybe fixing it
if necessary) or handle the missing cases in the new handler). Lots of debug statements still in there git-svn-id: https://svn.openpcd.org:2342/trunk@335 6dc7ffe9-61d6-0310-9af1-9938baff3ed1
-rw-r--r--openpicc/application/cmd.c17
-rw-r--r--openpicc/application/main.c66
-rw-r--r--openpicc/application/pio_irq.c19
-rw-r--r--openpicc/application/pio_irq.h1
-rw-r--r--openpicc/application/pll.c2
-rw-r--r--openpicc/application/ssc_picc.c315
-rw-r--r--openpicc/application/ssc_picc.h23
-rw-r--r--openpicc/application/tc_cdiv_sync.c8
-rw-r--r--openpicc/application/tc_fdt.c17
-rw-r--r--openpicc/os/boot/Cstartup_SAM7.c3
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:
personal git repositories of Harald Welte. Your mileage may vary