summaryrefslogtreecommitdiff
path: root/openpicc/application
diff options
context:
space:
mode:
authorhenryk <henryk@6dc7ffe9-61d6-0310-9af1-9938baff3ed1>2007-12-05 15:36:56 +0000
committerhenryk <henryk@6dc7ffe9-61d6-0310-9af1-9938baff3ed1>2007-12-05 15:36:56 +0000
commitba63352b4b915e46bc44fbd98c6e0e837477005d (patch)
tree6d49eaab495d2fa9a8d8ebda9922b0ceeacac84f /openpicc/application
parent1cdcc383d801f6468e2937475be3b98af231f4cf (diff)
Revamp SSC buffer handling, should severely reduce buffer leakage
Switch SSC IRQ handling from edge triggered to level triggered. Somehow I was losing the ENDTX interrupt otherwise Modified ISO14443 code for testing to enable repeated REQA->ATQA cycles. Somehow only the first ATQA is correct, subsequent ATQAs are missing the first two bits. Need to debug git-svn-id: https://svn.openpcd.org:2342/trunk@373 6dc7ffe9-61d6-0310-9af1-9938baff3ed1
Diffstat (limited to 'openpicc/application')
-rw-r--r--openpicc/application/cmd.c3
-rw-r--r--openpicc/application/iso14443_layer3a.c67
-rw-r--r--openpicc/application/led.c2
-rw-r--r--openpicc/application/ssc_picc.c253
-rw-r--r--openpicc/application/ssc_picc.h4
5 files changed, 175 insertions, 154 deletions
diff --git a/openpicc/application/cmd.c b/openpicc/application/cmd.c
index b7169f1..776d5e5 100644
--- a/openpicc/application/cmd.c
+++ b/openpicc/application/cmd.c
@@ -281,6 +281,9 @@ void prvExecCommand(u_int32_t cmd, portCHAR *args) {
DumpStringToUSB(" * SSC_TCR value: ");
DumpUIntToUSB(*AT91C_SSC_TCR);
DumpStringToUSB("\n\r");
+ DumpStringToUSB(" * SSC_IMR value: ");
+ DumpUIntToUSB(*AT91C_SSC_IMR);
+ DumpStringToUSB("\n\r");
DumpStringToUSB(
" *\n\r"
" *****************************************************\n\r"
diff --git a/openpicc/application/iso14443_layer3a.c b/openpicc/application/iso14443_layer3a.c
index c7cd936..06857f2 100644
--- a/openpicc/application/iso14443_layer3a.c
+++ b/openpicc/application/iso14443_layer3a.c
@@ -66,6 +66,7 @@ const iso14443_frame NULL_FRAME = {
#define INITIAL_STATE IDLE
//#define INITIAL_STATE ACTIVE
+static int atqa_sent = 0;
/* Running in ISR mode */
void __ramfunc iso14443_layer3a_irq_ext(u_int32_t ssc_sr, enum ssc_mode ssc_mode, u_int8_t* samples)
{
@@ -90,6 +91,7 @@ void __ramfunc iso14443_layer3a_irq_ext(u_int32_t ssc_sr, enum ssc_mode ssc_mode
vLedSetGreen(1);
tc_cdiv_set_divider(8);
ssc_tx_start(&ssc_tx_buffer);
+ atqa_sent = 1;
vLedSetGreen(0);
}
vLedSetGreen(1);
@@ -182,11 +184,6 @@ void iso14443_layer3a_state_machine (void *pvParameters)
pll_init();
tc_cdiv_init();
-#ifdef FOUR_TIMES_OVERSAMPLING
- tc_cdiv_set_divider(32);
-#else
- tc_cdiv_set_divider(64);
-#endif
tc_fdt_init();
ssc_set_irq_extension((ssc_irq_ext_t)iso14443_layer3a_irq_ext);
ssc_rx_init();
@@ -216,6 +213,11 @@ void iso14443_layer3a_state_machine (void *pvParameters)
else if(INITIAL_STATE == ACTIVE)
ssc_rx_mode_set(SSC_MODE_14443A_STANDARD);
else ssc_rx_mode_set(SSC_MODE_NONE);
+#ifdef FOUR_TIMES_OVERSAMPLING
+ tc_cdiv_set_divider(32);
+#else
+ tc_cdiv_set_divider(64);
+#endif
ssc_rx_start();
} else {
LAYER3_DEBUG("SSC TX overflow error, please debug");
@@ -236,7 +238,7 @@ void iso14443_layer3a_state_machine (void *pvParameters)
}
if(need_receive) {
- if(xQueueReceive(ssc_rx_queue, &buffer, portTICK_RATE_MS)) {
+ if(xQueueReceive(ssc_rx_queue, &buffer, portTICK_RATE_MS) && buffer != NULL) {
vLedSetGreen(0);
portENTER_CRITICAL();
buffer->state = PROCESSING;
@@ -255,48 +257,29 @@ void iso14443_layer3a_state_machine (void *pvParameters)
/* Need to transmit ATQA */
LAYER3_DEBUG("Received ");
LAYER3_DEBUG(first_sample == WUPA ? "WUPA" : "REQA");
- LAYER3_DEBUG(" waking up to send ATQA\n\r");
- if(ssc_tx_buffer.state == PROCESSING) {
- LAYER3_DEBUG("Buffer ");
- DumpUIntToUSB(ssc_tx_buffer.len);
- LAYER3_DEBUG(" ");
- DumpBufferToUSB((char*)ssc_tx_buffer.data, ssc_tx_buffer.len);
- LAYER3_DEBUG("\n\r");
+ if(atqa_sent) {
+ LAYER3_DEBUG(", woke up to send ATQA\n\r");
+ atqa_sent = 0;
}
- /*portENTER_CRITICAL();
- if(ssc_tx_buffer.state != FREE) {
- portEXIT_CRITICAL();
- * Wait for another frame */ /*
+ /* For debugging, wait 1ms, then wait for another frame */
+ vTaskDelay(portTICK_RATE_MS);
+ if(prefill_buffer(&ssc_tx_buffer, &ATQA_FRAME)) {
ssc_rx_mode_set(SSC_MODE_14443A_SHORT);
+#ifdef FOUR_TIMES_OVERSAMPLING
+ tc_cdiv_set_divider(32);
+#else
+ tc_cdiv_set_divider(64);
+#endif
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;
- ssc_tx_start(&ssc_tx_buffer);
- 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);
+#ifdef FOUR_TIMES_OVERSAMPLING
+ tc_cdiv_set_divider(32);
+#else
+ tc_cdiv_set_divider(64);
+#endif
ssc_rx_start();
}
break;
diff --git a/openpicc/application/led.c b/openpicc/application/led.c
index 9b6861a..cab12b1 100644
--- a/openpicc/application/led.c
+++ b/openpicc/application/led.c
@@ -29,7 +29,7 @@
#include "led.h"
/**********************************************************************/
-#define BLINK_TIME 10
+#define BLINK_TIME 5
void vLedSetRed(bool_t on)
{
diff --git a/openpicc/application/ssc_picc.c b/openpicc/application/ssc_picc.c
index 99a4a2f..7e02ec6 100644
--- a/openpicc/application/ssc_picc.c
+++ b/openpicc/application/ssc_picc.c
@@ -48,17 +48,58 @@
#include "usb_print.h"
#include "iso14443_layer3a.h"
-//#define DEBUG_SSC_REFILL
+#define DEBUG_SSC_REFILL 1
+#ifdef DEBUG_SSC_REFILL
+#define DEBUGR(x, args ...) DEBUGPCRF(x, ## args)
+#else
+#define DEBUGR(x, args ...)
+#endif
+
static const AT91PS_SSC ssc = AT91C_BASE_SSC;
static AT91PS_PDC rx_pdc;
static AT91PS_PDC tx_pdc;
-static ssc_dma_rx_buffer_t dma_buffers[SSC_DMA_BUFFER_COUNT];
xQueueHandle ssc_rx_queue = NULL;
+struct ssc_state {
+ ssc_dma_rx_buffer_t* buffer[2];
+ enum ssc_mode mode;
+};
+static struct ssc_state ssc_state;
+
+/* Note: Only use 8, 16 or 32 for the transfersize. (These are the sizes used by the PDC and even though
+ * the SSC supports different sizes, all PDC tranfers will be either 8, 16 or 32, rounding up.) */
+static const struct {u_int16_t transfersize; u_int16_t transfers;} ssc_sizes[] = {
+ /* Undefined, no size set */
+ [SSC_MODE_NONE] = {0, 0},
+ /* 14443A Short Frame: 1 transfer of ISO14443A_SHORT_LEN bits */
+ [SSC_MODE_14443A_SHORT] = {ISO14443A_SHORT_TRANSFER_SIZE, 1},
+ /* 14443A Standard Frame: FIXME 16 transfers of 32 bits (maximum number), resulting in 512 samples */
+ [SSC_MODE_14443A_STANDARD] = {32, 16},
+ [SSC_MODE_14443B] = {32, 16}, /* 64 bytes */
+ [SSC_MODE_EDGE_ONE_SHOT] = {32, 16}, /* 64 bytes */
+ [SSC_MODE_CONTINUOUS] = {32, 511}, /* 2044 bytes */
+};
+
+/* ************** SSC BUFFER HANDLING *********************** */
+static ssc_dma_rx_buffer_t dma_buffers[SSC_DMA_BUFFER_COUNT];
ssc_dma_tx_buffer_t ssc_tx_buffer;
+static volatile int overflows;
+static volatile int ssc_buffer_errors;
+int ssc_get_overflows(void) {
+ return 1000*ssc_buffer_errors + 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 ssc_dma_rx_buffer_t* __ramfunc ssc_find_dma_buffer(ssc_dma_buffer_state_t oldstate,
ssc_dma_buffer_state_t newstate)
{
@@ -74,20 +115,88 @@ static ssc_dma_rx_buffer_t* __ramfunc ssc_find_dma_buffer(ssc_dma_buffer_state_t
return result;
}
-struct ssc_state {
- ssc_dma_rx_buffer_t* buffer[2];
- enum ssc_mode mode;
-};
-static struct ssc_state ssc_state;
-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}, /* 16 transfers of 32 bits (maximum number), resulting in 512 samples */
- [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 */
-};
+static int __ramfunc __ssc_rx_load(int secondary);
+static ssc_dma_rx_buffer_t* __ramfunc __ssc_rx_unload(int secondary);
+/*
+ * Find and load an RX buffer into the DMA controller, using the current SSC mode
+ */
+static int __ramfunc __ssc_rx_load(int secondary)
+{
+ ssc_dma_rx_buffer_t *buffer;
+
+ buffer = ssc_find_dma_buffer(FREE, PENDING);
+ if (!buffer) {
+ DEBUGP("no_rctx_for_refill! ");
+ overflows++;
+ return -1;
+ }
+ DEBUGR("filling SSC RX%u dma ctx: %u (len=%u) ", secondary,
+ req_ctx_num(buffer), buffer->size);
+ buffer->len = ssc_sizes[ssc_state.mode].transfersize * ssc_sizes[ssc_state.mode].transfers;
+
+ if(ssc_state.buffer[secondary] != NULL) {
+ /* This condition is not expected to happen and would probably indicate a bug
+ * of some sort. However, instead of leaking buffers we'll just pretend it to
+ * be free again. */
+ ssc_buffer_errors++;
+ if(ssc_state.buffer[secondary]->state == PENDING) {
+ ssc_state.buffer[secondary]->state = FREE;
+ }
+ }
+
+ if (secondary) {
+ AT91F_PDC_SetNextRx(rx_pdc, buffer->data,
+ ssc_sizes[ssc_state.mode].transfers);
+ ssc_state.buffer[1] = buffer;
+ } else {
+ AT91F_PDC_SetRx(rx_pdc, buffer->data,
+ ssc_sizes[ssc_state.mode].transfers);
+ ssc_state.buffer[0] = buffer;
+ }
+
+ return 0;
+}
+
+/*
+ * Take the RX buffer(s) from the DMA controller, e.g. to abort a currently executing receive process and
+ * either reclaim the buffer(s) (if no transfer have been done so far) or mark them as used, updating
+ * the length fields to match the number of transfers that have actually executed.
+ * Warning: When this function executes, the mapping in ssc_state is expected to match the mapping in
+ * the PDC (e.g. ssc_state[0] is the RX Buffer and ssc_state[1] is the Next RX Buffer). Do not use this
+ * function while the PDC transfer is enabled. Especially do not run it from the SSC RX IRQ.
+ */
+static int __ramfunc __ssc_tx_unload_all(ssc_dma_rx_buffer_t** primary, ssc_dma_rx_buffer_t** secondary)
+{
+ if(primary != NULL) *primary = __ssc_rx_unload(0); else __ssc_rx_unload(0);
+ if(secondary != NULL) *secondary = __ssc_rx_unload(1); else __ssc_rx_unload(1);
+ return 1;
+}
+static ssc_dma_rx_buffer_t* __ramfunc __ssc_rx_unload(int secondary)
+{
+ ssc_dma_rx_buffer_t *buffer = ssc_state.buffer[secondary];
+ if(buffer == NULL) return NULL;
+
+ u_int16_t remaining_transfers = (secondary ? rx_pdc->PDC_RNCR : rx_pdc->PDC_RCR);
+ u_int8_t* next_transfer_location = (u_int8_t*)(secondary ? rx_pdc->PDC_RNPR : rx_pdc->PDC_RPR);
+ u_int32_t remaining_size = ssc_sizes[buffer->reception_mode].transfersize * remaining_transfers;
+ /* Consistency check */
+ if( next_transfer_location - remaining_size != buffer->data ) {
+ ssc_buffer_errors++;
+ if(buffer->state == PENDING) buffer->state = FREE;
+ ssc_state.buffer[secondary] = NULL;
+ return NULL;
+ }
+
+ if(secondary) {
+ AT91F_PDC_SetNextRx(rx_pdc, 0, 0);
+ } else {
+ AT91F_PDC_SetRx(rx_pdc, 0, 0);
+ }
+ ssc_state.buffer[secondary] = NULL;
+
+ return buffer;
+}
#define SSC_RX_IRQ_MASK (AT91C_SSC_RXRDY | \
AT91C_SSC_OVRUN | \
@@ -200,9 +309,10 @@ void ssc_tx_start(ssc_dma_tx_buffer_t *buf)
ssc->SSC_TCMR = 0x01 | AT91C_SSC_CKO_NONE | start_cond;
AT91F_PDC_SetTx(tx_pdc, buf->data, num_data);
+ AT91F_PDC_SetNextTx(tx_pdc, 0, 0);
buf->state = PENDING;
- AT91F_SSC_EnableIt(ssc, AT91C_SSC_TXSYN | AT91C_SSC_ENDTX | AT91C_SSC_TXBUFE);
+ AT91F_SSC_EnableIt(ssc, AT91C_SSC_ENDTX);
/* Enable DMA */
AT91F_PDC_EnableTx(tx_pdc);
/* Start Transmission */
@@ -241,26 +351,6 @@ void ssc_tf_irq(u_int32_t pio) {
// rctx->tot_len = sizeof(opcd_ssc_hdr);
//}
-#define DEBUG_SSC_REFILL 1
-#ifdef DEBUG_SSC_REFILL
-#define DEBUGR(x, args ...) DEBUGPCRF(x, ## args)
-#else
-#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 ssc_irq_ext_t irq_extension = NULL;
ssc_irq_ext_t ssc_set_irq_extension(ssc_irq_ext_t ext_handler) {
ssc_irq_ext_t old = irq_extension;
@@ -268,35 +358,6 @@ ssc_irq_ext_t ssc_set_irq_extension(ssc_irq_ext_t ext_handler) {
return old;
}
-static int __ramfunc __ssc_rx_refill(int secondary)
-{
- ssc_dma_rx_buffer_t *buffer;
-
- buffer = ssc_find_dma_buffer(FREE, PENDING);
- if (!buffer) {
- DEBUGP("no_rctx_for_refill! ");
- overflows++;
- return -1;
- }
- //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].bytes;
- if (secondary) {
- AT91F_PDC_SetNextRx(rx_pdc, buffer->data,
- ssc_dmasize[ssc_state.mode].transfers);
- ssc_state.buffer[1] = buffer;
- } else {
- AT91F_PDC_SetRx(rx_pdc, buffer->data,
- ssc_dmasize[ssc_state.mode].transfers);
- ssc_state.buffer[0] = buffer;
- }
-
- //tc_cdiv_sync_reset();
-
- return 0;
-}
-
void __ramfunc ssc_rx_stop_frame_ended(void)
{
}
@@ -315,18 +376,6 @@ static void __ramfunc ssc_irq(void)
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
- * sampling further after having received the first
- * packet. */
- if (ssc_state.mode == SSC_MODE_EDGE_ONE_SHOT || ssc_state.mode == SSC_MODE_14443A_SHORT
- || ssc_state.mode == SSC_MODE_14443A_STANDARD) {
- DEBUGP("DISABLE_RX ");
- ssc_rx_stop();
- vLedSetGreen(1);
- }
- //AT91F_SSC_DisableIt(AT91C_BASE_SSC, SSC_RX_IRQ_MASK);
-#endif
/* Ignore empty frames */
if (ssc_state.mode == SSC_MODE_CONTINUOUS) {
tmp = (u_int32_t*)ssc_state.buffer[0]->data;
@@ -356,12 +405,14 @@ static void __ramfunc ssc_irq(void)
ssc_state.buffer[0]->state = FREE;
//gaportEXIT_CRITICAL();
}
+ vLedSetGreen(1);
/* second buffer gets propagated to primary */
inbuf = ssc_state.buffer[0];
ssc_state.buffer[0] = ssc_state.buffer[1];
ssc_state.buffer[1] = NULL;
- if(ssc_state.mode == SSC_MODE_14443A_SHORT) {
+ if(ssc_state.mode == SSC_MODE_EDGE_ONE_SHOT || ssc_state.mode == SSC_MODE_14443A_SHORT
+ || ssc_state.mode == SSC_MODE_14443A_SHORT) {
// Stop sampling here
ssc_rx_stop();
} else {
@@ -375,13 +426,13 @@ static void __ramfunc ssc_irq(void)
//gaportEXIT_CRITICAL();
task_woken = xQueueSendFromISR(ssc_rx_queue, &ssc_state.buffer[0], task_woken);
}
- if (__ssc_rx_refill(0) == -1)
+ if (__ssc_rx_load(0) == -1)
AT91F_SSC_DisableIt(ssc, AT91C_SSC_ENDRX |
AT91C_SSC_RXBUFF |
AT91C_SSC_OVRUN);
}
- if (__ssc_rx_refill(1) == -1)
+ if (__ssc_rx_load(1) == -1)
AT91F_SSC_DisableIt(ssc, AT91C_SSC_ENDRX |
AT91C_SSC_RXBUFF |
AT91C_SSC_OVRUN);
@@ -397,9 +448,14 @@ static void __ramfunc ssc_irq(void)
if (ssc_sr & AT91C_SSC_TXSYN)
DEBUGP("TXSYN ");
+ /* Why does this interrupt trigger _before_ even starting a transmission, but _not_ when the
+ * transmission actually finishes? */
if(ssc_sr & AT91C_SSC_ENDTX) {
- if(ssc_tx_buffer.state == PENDING)
+ //usb_print_string_f("ENDTX ", 0);
+ if(ssc_tx_buffer.state == PENDING) {
ssc_tx_buffer.state = FREE;
+ AT91F_SSC_DisableIt(ssc, SSC_TX_IRQ_MASK);
+ }
}
if(ssc_sr & AT91C_SSC_TXBUFE)
@@ -436,12 +492,13 @@ void ssc_rx_start(void)
{
//DEBUGPCRF("starting SSC RX\n");
- __ssc_rx_refill(0);
- if(ssc_state.mode != SSC_MODE_14443A_SHORT) __ssc_rx_refill(1);
+ __ssc_rx_load(0);
+ if(ssc_state.mode != SSC_MODE_14443A_SHORT) __ssc_rx_load(1);
/* Enable Reception */
AT91F_SSC_EnableIt(ssc, AT91C_SSC_ENDRX | AT91C_SSC_CP0 |
AT91C_SSC_RXBUFF | AT91C_SSC_OVRUN);
+ AT91F_PDC_EnableRx(rx_pdc);
AT91F_SSC_EnableRx(AT91C_BASE_SSC);
/* Clear the flipflop */
@@ -452,6 +509,9 @@ void ssc_rx_stop(void)
{
/* Disable reception */
AT91F_SSC_DisableRx(AT91C_BASE_SSC);
+ AT91F_PDC_DisableRx(rx_pdc);
+ __ssc_tx_unload_all(NULL, NULL);
+ AT91F_SSC_DisableIt(ssc, SSC_RX_IRQ_MASK);
}
void ssc_tx_init(void)
@@ -469,31 +529,6 @@ void ssc_tx_init(void)
tx_pdc = (AT91PS_PDC) &(ssc->SSC_RPR);
}
-//static int ssc_usb_in(struct req_ctx *rctx)
-//{
-// FIXME
-// struct openpcd_hdr *poh = (struct openpcd_hdr *) rctx->data;
-//
-// switch (poh->cmd) {
-// case OPENPCD_CMD_SSC_READ:
-// /* FIXME: allow host to specify mode */
-// ssc_rx_mode_set(SSC_MODE_EDGE_ONE_SHOT);
-// ssc_rx_start();
-// req_ctx_put(rctx);
-// return 0;
-// break;
-// case OPENPCD_CMD_SSC_WRITE:
-// /* FIXME: implement this */
-// //ssc_tx_start()
-// break;
-// default:
-// return USB_ERR(USB_ERR_CMD_UNKNOWN);
-// break;
-// }
-//
-// return (poh->flags & OPENPCD_FLAG_RESPOND) ? USB_RET_RESPOND : 0;
-//}
-
void ssc_rx_init(void)
{
tc_cdiv_sync_init();
@@ -516,7 +551,7 @@ void ssc_rx_init(void)
AT91F_AIC_ConfigureIt(AT91C_ID_SSC,
OPENPICC_IRQ_PRIO_SSC,
- AT91C_AIC_SRCTYPE_INT_POSITIVE_EDGE, (THandler)&ssc_irq);
+ AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL, (THandler)&ssc_irq);
/* don't divide clock inside SSC, we do that in tc_cdiv */
ssc->SSC_CMR = 0;
diff --git a/openpicc/application/ssc_picc.h b/openpicc/application/ssc_picc.h
index bd08a73..d141e44 100644
--- a/openpicc/application/ssc_picc.h
+++ b/openpicc/application/ssc_picc.h
@@ -38,7 +38,7 @@ typedef void (*ssc_irq_ext_t)(u_int32_t ssc_sr, enum ssc_mode ssc_mode, u_int8_t
* than acceptable for the synchronous responses (around 87us).*/
extern ssc_irq_ext_t ssc_set_irq_extension(ssc_irq_ext_t ext_handler);
-extern portBASE_TYPE ssc_get_overflows(void);
+extern int ssc_get_overflows(void);
extern int ssc_count_free(void);
#define SSC_DMA_BUFFER_SIZE 2048
@@ -55,7 +55,7 @@ typedef enum {
typedef struct {
volatile ssc_dma_buffer_state_t state;
u_int32_t len; /* Length of the content */
- enum ssc_mode reception_mode;
+ enum ssc_mode reception_mode; /* The SSC mode that the buffer has been loaded for (affects element size and count) */
u_int8_t data[SSC_DMA_BUFFER_SIZE];
} ssc_dma_rx_buffer_t;
personal git repositories of Harald Welte. Your mileage may vary