summaryrefslogtreecommitdiff
path: root/openpicc
diff options
context:
space:
mode:
authorhenryk <henryk@6dc7ffe9-61d6-0310-9af1-9938baff3ed1>2007-12-15 20:56:57 +0000
committerhenryk <henryk@6dc7ffe9-61d6-0310-9af1-9938baff3ed1>2007-12-15 20:56:57 +0000
commit7c198cbff3872795661b6ded45662dc0a9ba6db9 (patch)
treee68615430e837cf6173db35e9d8cc6c29706fe3f /openpicc
parentca286b29ede8dece0661514dae381e05efe1badc (diff)
Record size of SSC RX DMA buffers in transfers, much clearer
Change miller decoder to take an RX DMA buffer in order to have access to the reception_mode member, much more versatile git-svn-id: https://svn.openpcd.org:2342/trunk@393 6dc7ffe9-61d6-0310-9af1-9938baff3ed1
Diffstat (limited to 'openpicc')
-rw-r--r--openpicc/application/iso14443_layer3a.c6
-rw-r--r--openpicc/application/iso14443a_miller.c24
-rw-r--r--openpicc/application/iso14443a_miller.h2
-rw-r--r--openpicc/application/main.c3
-rw-r--r--openpicc/application/ssc_picc.c70
-rw-r--r--openpicc/application/ssc_picc.h2
-rw-r--r--openpicc/application/usb_print.c2
7 files changed, 89 insertions, 20 deletions
diff --git a/openpicc/application/iso14443_layer3a.c b/openpicc/application/iso14443_layer3a.c
index cbff46f..57a3a99 100644
--- a/openpicc/application/iso14443_layer3a.c
+++ b/openpicc/application/iso14443_layer3a.c
@@ -307,11 +307,11 @@ void iso14443_layer3a_state_machine (void *pvParameters)
vLedBlinkGreen();
if(1) {
int i = usb_print_set_default_flush(0);
- DumpBufferToUSB((char*)buffer->data, (buffer->len+7)/8);
+ DumpBufferToUSB((char*)buffer->data, (buffer->len_transfers * buffer->reception_mode->transfersize_pdc)/8);
DumpStringToUSB(" Decoded: ");
- DumpUIntToUSB(buffer->len);
+ DumpUIntToUSB(buffer->len_transfers);
DumpStringToUSB(" ");
- iso14443a_decode_miller(&received_frame, buffer->data, (buffer->len+7)/8);
+ iso14443a_decode_miller(&received_frame, buffer);
DumpBufferToUSB((char*)received_frame.data, received_frame.numbytes + (received_frame.numbits+7)/8);
DumpStringToUSB(" ");
DumpUIntToUSB(received_frame.parameters.a.last_bit);
diff --git a/openpicc/application/iso14443a_miller.c b/openpicc/application/iso14443a_miller.c
index d7c24cd..a17a6e8 100644
--- a/openpicc/application/iso14443a_miller.c
+++ b/openpicc/application/iso14443a_miller.c
@@ -24,6 +24,7 @@
#include "iso14443_layer3a.h"
#include "usb_print.h"
+#include "ssc_picc.h"
#include "cmd.h"
#ifdef FOUR_TIMES_OVERSAMPLING
@@ -49,9 +50,10 @@ enum miller_sequence {
#define BIT_ENDMARKER -1
int iso14443a_decode_miller(iso14443_frame *frame,
- const u_int8_t *sample_buf, const u_int16_t sample_buf_len)
+ const ssc_dma_rx_buffer_t *buffer)
{
- signed int i, j, bit = 0, last_bit = -1, next_to_last_bit = 0;
+ u_int32_t i,j;
+ signed int bit = 0, last_bit = ISO14443A_LAST_BIT_NONE, next_to_last_bit = ISO14443A_LAST_BIT_NONE;
enum miller_sequence current_seq;
unsigned int bitpos = 0;
@@ -59,17 +61,23 @@ int iso14443a_decode_miller(iso14443_frame *frame,
frame->type = TYPE_A;
frame->parameters.a.parity = GIVEN_PARITY;
- for(i=0; i<sample_buf_len && bit != BIT_ENDMARKER; i++) {
+ for(i=0; i<buffer->len_transfers && bit != BIT_ENDMARKER; i++) {
+ u_int32_t sample = 0;
DumpStringToUSB(" ");
- DumpUIntToUSB(sample_buf[i]);
- for(j=0; j<(signed)(sizeof(sample_buf[0])*8)/OVERSAMPLING_RATE && bit != BIT_ENDMARKER; j++) {
+ switch(buffer->reception_mode->transfersize_pdc) {
+ case 8: sample = ((u_int8_t*)buffer->data)[i]; break;
+ case 16: sample = ((u_int16_t*)buffer->data)[i]; break;
+ case 32: sample = ((u_int32_t*)buffer->data)[i]; break;
+ }
+ DumpUIntToUSB(sample);
+ for(j=0; j<buffer->reception_mode->transfersize_ssc/OVERSAMPLING_RATE && bit != BIT_ENDMARKER; j++) {
DumpStringToUSB(".");
- int sample = (sample_buf[i]>>(j*OVERSAMPLING_RATE)) & ~(~0 << OVERSAMPLING_RATE);
- switch(sample) {
+ int bitsample = (sample>>(j*OVERSAMPLING_RATE)) & ~(~0 << OVERSAMPLING_RATE);
+ switch(bitsample) {
case SEQ_X: current_seq = SEQUENCE_X; DumpStringToUSB("X"); break;
case SEQ_Y: current_seq = SEQUENCE_Y; DumpStringToUSB("Y"); break;
case SEQ_Z: current_seq = SEQUENCE_Z; DumpStringToUSB("Z"); break;
- default: DumpUIntToUSB(sample); current_seq = SEQUENCE_Y;
+ default: DumpUIntToUSB(bitsample); current_seq = SEQUENCE_Y;
}
switch(current_seq) {
diff --git a/openpicc/application/iso14443a_miller.h b/openpicc/application/iso14443a_miller.h
index dbd7f85..be058d0 100644
--- a/openpicc/application/iso14443a_miller.h
+++ b/openpicc/application/iso14443a_miller.h
@@ -1,6 +1,6 @@
#ifndef ISO14443A_MILLER_H_
#define ISO14443A_MILLER_H_
-extern int iso14443a_decode_miller(iso14443_frame *frame, const u_int8_t *sample_buf, const u_int16_t sample_buf_len);
+extern int iso14443a_decode_miller(iso14443_frame *frame, const ssc_dma_rx_buffer_t *buffer);
#endif /*ISO14443A_MILLER_H_*/
diff --git a/openpicc/application/main.c b/openpicc/application/main.c
index 19407e6..38a08b5 100644
--- a/openpicc/application/main.c
+++ b/openpicc/application/main.c
@@ -85,6 +85,8 @@ void vApplicationIdleHook(void)
usb_print_flush();
}
+#if 0
+// Bitrotten
void main_help_print_buffer(ssc_dma_rx_buffer_t *buffer, int *pktcount)
{
ISO14443A_SHORT_TYPE *tmp = (ISO14443A_SHORT_TYPE*)buffer->data;
@@ -140,6 +142,7 @@ void vMainTestSSCRXConsumer (void *pvParameters)
}
}
}
+#endif
/* 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 */
diff --git a/openpicc/application/ssc_picc.c b/openpicc/application/ssc_picc.c
index 520098d..e2bc213 100644
--- a/openpicc/application/ssc_picc.c
+++ b/openpicc/application/ssc_picc.c
@@ -1,5 +1,6 @@
/* AT91SAM7 SSC controller routines for OpenPICC
* (C) 2006 by Harald Welte <hwelte@hmw-consulting.de>
+ * (C) 2007 Henryk Plötz <henryk@ploetzli.ch>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -154,7 +155,7 @@ static int __ramfunc __ssc_rx_load(int secondary)
}
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 * ssc_sizes[ssc_state.mode].transfers;
+ buffer->len_transfers = ssc_sizes[ssc_state.mode].transfers;
buffer->reception_mode = &ssc_sizes[ssc_state.mode];
if(ssc_state.buffer[secondary] != NULL) {
@@ -176,6 +177,21 @@ static int __ramfunc __ssc_rx_load(int secondary)
ssc_sizes[ssc_state.mode].transfers);
ssc_state.buffer[0] = buffer;
}
+
+ if(secondary) {int i=usb_print_set_default_flush(0);
+ DumpStringToUSB("{1:");
+ DumpUIntToUSB(rx_pdc->PDC_RNCR);
+ DumpStringToUSB(" ");
+ DumpUIntToUSB(rx_pdc->PDC_RNPR);
+ DumpStringToUSB("} ");
+ usb_print_set_default_flush(i);}
+ else {int i=usb_print_set_default_flush(0);
+ DumpStringToUSB("{0:");
+ DumpUIntToUSB(rx_pdc->PDC_RCR);
+ DumpStringToUSB(" ");
+ DumpUIntToUSB(rx_pdc->PDC_RPR);
+ DumpStringToUSB("} ");
+ usb_print_set_default_flush(i);}
return 0;
}
@@ -199,15 +215,40 @@ 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;
+ if(secondary) {int i=usb_print_set_default_flush(0);
+ DumpStringToUSB("(1:");
+ DumpUIntToUSB(rx_pdc->PDC_RNCR);
+ DumpStringToUSB(" ");
+ DumpUIntToUSB(rx_pdc->PDC_RNPR);
+ DumpStringToUSB(") ");
+ usb_print_set_default_flush(i);}
+ else {int i=usb_print_set_default_flush(0);
+ DumpStringToUSB("(0:");
+ DumpUIntToUSB(rx_pdc->PDC_RCR);
+ DumpStringToUSB(" ");
+ DumpUIntToUSB(rx_pdc->PDC_RPR);
+ DumpStringToUSB(") ");
+ usb_print_set_default_flush(i);}
+
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_int16_t elapsed_transfers = buffer->reception_mode->transfers - remaining_transfers;
+
+ /* BUG BUG BUG For some reason the RNCR is zero, even though there have been no transfers in the secondary
+ * buffer. For now just assume that secondary==1 && remaining_transfers==0 is a bug condition and actually
+ * means elapsed_transfers == 0. Of course this will fail should they second buffer really be completely full. */
+ if(secondary && remaining_transfers==0) {
+ remaining_transfers = buffer->reception_mode->transfers;
+ elapsed_transfers = 0;
+ }
+
u_int32_t elapsed_size = buffer->reception_mode->transfersize_pdc/8 * elapsed_transfers;
/* Consistency check */
if( next_transfer_location - elapsed_size != buffer->data ) {
int i=usb_print_set_default_flush(0);
- DumpStringToUSB("!!! "); DumpUIntToUSB((int)next_transfer_location); DumpStringToUSB(" ");
+ DumpStringToUSB("!!!"); DumpUIntToUSB(secondary); DumpStringToUSB(" ");
+ DumpUIntToUSB((int)next_transfer_location); DumpStringToUSB(" ");
DumpUIntToUSB(elapsed_size); DumpStringToUSB(" "); DumpUIntToUSB((int)buffer->data); DumpStringToUSB(" ");
usb_print_set_default_flush(i);
ssc_buffer_errors++;
@@ -221,7 +262,14 @@ static ssc_dma_rx_buffer_t* __ramfunc __ssc_rx_unload(int secondary)
} else {
AT91F_PDC_SetRx(rx_pdc, 0, 0);
}
- if(buffer->state == PENDING) buffer->state = FREE;
+ if(buffer->state == PENDING) {
+ buffer->len_transfers = elapsed_transfers;
+ if(elapsed_transfers > 0) {
+ buffer->state = FULL;
+ } else {
+ buffer->state = FREE;
+ }
+ }
ssc_state.buffer[secondary] = NULL;
return buffer;
@@ -439,7 +487,11 @@ static void __ramfunc ssc_irq(void)
vLedSetRed(1);
}
+ if(ssc_sr & AT91C_SSC_CP1) usb_print_string_f("CP1 ", 0);
+
if (ssc_sr & (AT91C_SSC_ENDRX | AT91C_SSC_CP1)) {
+#if 0
+// Bitrotten
/* Ignore empty frames */
if (ssc_state.mode == SSC_MODE_CONTINUOUS) {
/* This code section is probably bitrotten by now. */
@@ -455,6 +507,10 @@ static void __ramfunc ssc_irq(void)
}
}
}
+#else
+ (void)i;
+ (void)tmp;
+#endif
//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) {
@@ -472,10 +528,12 @@ static void __ramfunc ssc_irq(void)
}
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_sr & AT91C_SSC_ENDRX) {
+ /* second buffer gets propagated to primary */
+ ssc_state.buffer[0] = ssc_state.buffer[1];
+ ssc_state.buffer[1] = NULL;
+ }
if(ssc_state.mode == SSC_MODE_EDGE_ONE_SHOT || ssc_state.mode == SSC_MODE_14443A_SHORT
|| ssc_state.mode == SSC_MODE_14443A_STANDARD || (ssc_state.mode == SSC_MODE_14443A && ssc_sr & AT91C_SSC_CP1)) {
// Stop sampling here
diff --git a/openpicc/application/ssc_picc.h b/openpicc/application/ssc_picc.h
index 937cab5..b769fe7 100644
--- a/openpicc/application/ssc_picc.h
+++ b/openpicc/application/ssc_picc.h
@@ -74,7 +74,7 @@ typedef struct {
typedef struct {
volatile ssc_dma_buffer_state_t state;
- u_int32_t len; /* Length of the content, in samples */
+ u_int32_t len_transfers; /* Length of the content, in transfers */
const ssc_mode_def *reception_mode; /* Pointer to the SSC mode definition that the buffer has been loaded for (affects element size and count) */
u_int8_t data[SSC_RX_BUFFER_SIZE];
} ssc_dma_rx_buffer_t;
diff --git a/openpicc/application/usb_print.c b/openpicc/application/usb_print.c
index a01ae8b..ccde7de 100644
--- a/openpicc/application/usb_print.c
+++ b/openpicc/application/usb_print.c
@@ -25,7 +25,7 @@
#include "usb_print.h"
-#define BUFLEN 1024
+#define BUFLEN (2*1024)
static char ringbuffer[BUFLEN];
static int ringstart, ringstop;
personal git repositories of Harald Welte. Your mileage may vary