From 5cc0ed498f99d3b23c6f1b87a9a2fdcbb05dd1a9 Mon Sep 17 00:00:00 2001
From: henryk <henryk@6dc7ffe9-61d6-0310-9af1-9938baff3ed1>
Date: Wed, 21 Nov 2007 00:30:19 +0000
Subject: 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
---
 openpicc/application/cmd.c          |  17 ++
 openpicc/application/main.c         |  66 +++++++-
 openpicc/application/pio_irq.c      |  19 ++-
 openpicc/application/pio_irq.h      |   1 +
 openpicc/application/pll.c          |   2 +-
 openpicc/application/ssc_picc.c     | 315 ++++++++++++++++++++++--------------
 openpicc/application/ssc_picc.h     |  23 +++
 openpicc/application/tc_cdiv_sync.c |   8 +-
 openpicc/application/tc_fdt.c       |  17 +-
 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:
-- 
cgit v1.2.3