From 7c198cbff3872795661b6ded45662dc0a9ba6db9 Mon Sep 17 00:00:00 2001 From: henryk Date: Sat, 15 Dec 2007 20:56:57 +0000 Subject: 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 --- openpicc/application/iso14443_layer3a.c | 6 +-- openpicc/application/iso14443a_miller.c | 24 +++++++---- openpicc/application/iso14443a_miller.h | 2 +- openpicc/application/main.c | 3 ++ openpicc/application/ssc_picc.c | 70 ++++++++++++++++++++++++++++++--- openpicc/application/ssc_picc.h | 2 +- openpicc/application/usb_print.c | 2 +- 7 files changed, 89 insertions(+), 20 deletions(-) (limited to 'openpicc') 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; ilen_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; jreception_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 + * (C) 2007 Henryk Plötz * * 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; -- cgit v1.2.3