summaryrefslogtreecommitdiff
path: root/openpicc
diff options
context:
space:
mode:
authorhenryk <henryk@6dc7ffe9-61d6-0310-9af1-9938baff3ed1>2007-12-15 16:31:46 +0000
committerhenryk <henryk@6dc7ffe9-61d6-0310-9af1-9938baff3ed1>2007-12-15 16:31:46 +0000
commit91d960e6945a1bb8e70e41d62fbb3be93b16f989 (patch)
tree3c63f308eb33e979e7ae919c961c87abcf9bc30a /openpicc
parent86c7c1ea486d01cb6f0cbd5f3bd8ab91e643489b (diff)
Prepare generic ISO 14443A reception mode (no short/standard distinction), prerequisite for proper frame handling and anticol, doesn't work yet
git-svn-id: https://svn.openpcd.org:2342/trunk@390 6dc7ffe9-61d6-0310-9af1-9938baff3ed1
Diffstat (limited to 'openpicc')
-rw-r--r--openpicc/application/iso14443_layer3a.c22
-rw-r--r--openpicc/application/iso14443_layer3a.h7
-rw-r--r--openpicc/application/ssc_picc.c41
-rw-r--r--openpicc/application/ssc_picc.h6
4 files changed, 51 insertions, 25 deletions
diff --git a/openpicc/application/iso14443_layer3a.c b/openpicc/application/iso14443_layer3a.c
index b9ee0b9..e3ce769 100644
--- a/openpicc/application/iso14443_layer3a.c
+++ b/openpicc/application/iso14443_layer3a.c
@@ -75,6 +75,14 @@ const iso14443_frame NULL_FRAME = {
#define INITIAL_FRAME NULL_FRAME
#endif
+#if 1
+#define SHORT_MODE SSC_MODE_14443A_SHORT
+#define STANDARD_MODE SSC_MODE_14443A_STANDARD
+#else
+#define SHORT_MODE SSC_MODE_14443A
+#define STANDARD_MODE SSC_MODE_14443A
+#endif
+
#define ISO14443A_TRANSMIT_AT_NEXT_INTERVAL_0 -1
#define ISO14443A_TRANSMIT_AT_NEXT_INTERVAL_1 -2
@@ -104,7 +112,7 @@ void __ramfunc iso14443_layer3a_irq_ext(u_int32_t ssc_sr, enum ssc_mode ssc_mode
{
(void)ssc_sr;
int fdt;
- if(ssc_mode == SSC_MODE_14443A_SHORT && samples) {
+ if((ssc_mode == SSC_MODE_14443A_SHORT || ssc_mode == SSC_MODE_14443A) && samples) {
ISO14443A_SHORT_TYPE sample = *(ISO14443A_SHORT_TYPE*)samples;
portBASE_TYPE send_atqa = 0;
if(sample == REQA) {
@@ -259,9 +267,9 @@ void iso14443_layer3a_state_machine (void *pvParameters)
DumpStringToUSB("\n\r");
state=INITIAL_STATE;
if(INITIAL_STATE == IDLE)
- enable_reception(SSC_MODE_14443A_SHORT);
+ enable_reception(SHORT_MODE);
else if(INITIAL_STATE == ACTIVE)
- enable_reception(SSC_MODE_14443A_STANDARD);
+ enable_reception(STANDARD_MODE);
else enable_reception(SSC_MODE_NONE);
} else {
LAYER3_DEBUG("SSC TX overflow error, please debug");
@@ -324,18 +332,18 @@ void iso14443_layer3a_state_machine (void *pvParameters)
* Normally we'd go to anticol from here*/
vTaskDelay(portTICK_RATE_MS);
if(prefill_buffer(&ssc_tx_buffer, &ATQA_FRAME)) {
- enable_reception(SSC_MODE_14443A_SHORT);
+ enable_reception(SHORT_MODE);
}
} else {
/* Wait for another frame */
- enable_reception(SSC_MODE_14443A_SHORT);
+ enable_reception(SHORT_MODE);
}
break;
case ACTIVE:
case ACTIVE_STAR:
/* Wait for another frame */
if(0) {
- ssc_rx_mode_set(SSC_MODE_14443A_STANDARD);
+ ssc_rx_mode_set(STANDARD_MODE);
ssc_rx_start();
} else {
//vTaskDelay(portTICK_RATE_MS);
@@ -351,7 +359,7 @@ void iso14443_layer3a_state_machine (void *pvParameters)
usb_print_flush();
}
/* Wait for another frame */
- enable_reception(SSC_MODE_14443A_STANDARD);
+ enable_reception(STANDARD_MODE);
}
default:
break;
diff --git a/openpicc/application/iso14443_layer3a.h b/openpicc/application/iso14443_layer3a.h
index 26a8a2d..9b00ccb 100644
--- a/openpicc/application/iso14443_layer3a.h
+++ b/openpicc/application/iso14443_layer3a.h
@@ -18,6 +18,7 @@ enum ISO14443_STATES {
/******************** RX ************************************/
#ifdef FOUR_TIMES_OVERSAMPLING
/* definitions for four-times oversampling */
+#define ISO14443A_SAMPLE_LEN 4
/* Sample values for the REQA and WUPA short frames */
#define REQA 0x10410441
#define WUPA 0x04041041
@@ -39,6 +40,8 @@ enum ISO14443_STATES {
#else
/* definitions for two-times oversampling */
+#define ISO14443A_SAMPLE_LEN 2
+
#define REQA 0x4929
#define WUPA 0x2249
@@ -46,6 +49,9 @@ enum ISO14443_STATES {
#define ISO14443A_SOF_LEN 2
#define ISO14443A_SHORT_LEN 18
+#define ISO14443A_EOF_SAMPLE 0x00
+#define ISO14443A_EOF_LEN 4
+
#endif
/* A short frame should be received in one single SSC transfer */
@@ -66,6 +72,7 @@ enum ISO14443_STATES {
#error ISO14443A_SHORT_LEN defined too big
#endif
+#define ISO14443A_MAX_RX_FRAME_SIZE_IN_BITS (256*9 +2)
/******************** TX ************************************/
/* Magic delay, don't know where it comes from */
#define MAGIC_OFFSET -32
diff --git a/openpicc/application/ssc_picc.c b/openpicc/application/ssc_picc.c
index 721989f..09be1e5 100644
--- a/openpicc/application/ssc_picc.c
+++ b/openpicc/application/ssc_picc.c
@@ -76,7 +76,9 @@ static const ssc_mode_def ssc_sizes[] = {
/* 14443A Short Frame: 1 transfer of ISO14443A_SHORT_LEN bits */
[SSC_MODE_14443A_SHORT] = {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] = {SSC_MODE_14443A_STANDARD, 32, 4},
+ [SSC_MODE_14443A_STANDARD] = {SSC_MODE_14443A_STANDARD, 32, 16},
+ /* 14443A Frame, don't care if standard or short */
+ [SSC_MODE_14443A] = {SSC_MODE_14443A, ISO14443A_SAMPLE_LEN, ISO14443A_MAX_RX_FRAME_SIZE_IN_BITS},
[SSC_MODE_14443B] = {SSC_MODE_14443B, 32, 16}, /* 64 bytes */
[SSC_MODE_EDGE_ONE_SHOT] = {SSC_MODE_EDGE_ONE_SHOT, 32, 16}, /* 64 bytes */
[SSC_MODE_CONTINUOUS] = {SSC_MODE_CONTINUOUS, 32, 511}, /* 2044 bytes */
@@ -243,6 +245,7 @@ void ssc_rx_mode_set(enum ssc_mode ssc_mode)
{
u_int8_t data_len=0, num_data=0, sync_len=0;
u_int32_t start_cond=0;
+ u_int8_t stop = 0;
/* disable Rx and all Rx interrupt sources */
AT91F_SSC_DisableRx(AT91C_BASE_SSC);
@@ -263,6 +266,14 @@ void ssc_rx_mode_set(enum ssc_mode ssc_mode)
data_len = 32;
num_data = 16; /* FIXME */
break;
+ case SSC_MODE_14443A:
+ start_cond = AT91C_SSC_START_0;
+ sync_len = ISO14443A_SOF_LEN;
+ ssc->SSC_RC0R = ISO14443A_SOF_SAMPLE;
+ data_len = ISO14443A_SAMPLE_LEN;
+ num_data = 16; /* Start with 16, then switch to continuous in the IRQ handler */
+ stop = 1; /* Actually the documentation indicates that setting STOP makes switching to continuous unnecessary */
+ break;
case SSC_MODE_14443B:
/* start sampling at first falling data edge */
//start_cond =
@@ -289,7 +300,7 @@ void ssc_rx_mode_set(enum ssc_mode ssc_mode)
//| AT91C_SSC_MSBF
;
ssc->SSC_RCMR = AT91C_SSC_CKS_RK | AT91C_SSC_CKO_NONE |
- (0x2 << 6) | AT91C_SSC_CKI | start_cond;
+ (0x2 << 6) | AT91C_SSC_CKI | start_cond | (stop << 12);
/* Enable Rx DMA */
AT91F_PDC_EnableRx(rx_pdc);
@@ -384,16 +395,6 @@ void ssc_tf_irq(u_int32_t pio) {
#endif
-//static struct openpcd_hdr opcd_ssc_hdr = {
-// .cmd = OPENPCD_CMD_SSC_READ,
-//};
-
-//static inline void init_opcdhdr(struct req_ctx *rctx)
-//{
-// memcpy(rctx->data, &opcd_ssc_hdr, sizeof(opcd_ssc_hdr));
-// rctx->tot_len = sizeof(opcd_ssc_hdr);
-//}
-
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;
@@ -419,22 +420,26 @@ static void __ramfunc ssc_irq(void)
ssc_dma_rx_buffer_t *inbuf=NULL;
DEBUGP("ssc_sr=0x%08x, mode=%u: ", ssc_sr, ssc_state.mode);
- if (ssc_sr & AT91C_SSC_CP0 && ssc_state.mode == SSC_MODE_14443A_SHORT) {
+ if ((ssc_sr & AT91C_SSC_CP0) && (ssc_state.mode == SSC_MODE_14443A_SHORT || ssc_state.mode == SSC_MODE_14443A)) {
+ if(ssc_state.mode == SSC_MODE_14443A && ISO14443A_SOF_LEN != ISO14443A_EOF_LEN) {
+ /* Need to reprogram FSLEN */
+ ssc->SSC_RFMR = (ssc->SSC_RFMR & ~(0xf << 16)) | ( ((ISO14443A_EOF_LEN-1)&0xf) << 16 );
+ }
/* Short frame, busy loop till the frame is received completely to
* prevent a second irq entrance delay when the actual frame end
* irq is raised. (The scheduler masks interrupts for about 56us,
* which is too much for anticollision.) */
int i = 0;
vLedBlinkRed();
- while( ! ((ssc_sr=ssc->SSC_SR) & AT91C_SSC_ENDRX) ) {
+ while( ! ((ssc_sr=ssc->SSC_SR) & (AT91C_SSC_ENDRX | AT91C_SSC_CP1)) ) {
i++;
- if(i > 9600) break;
+ if(i > 9600) break; /* Break out, clearly this is not a short frame or a reception error happened */
}
ssc_sr |= orig_ssc_sr;
vLedSetRed(1);
}
- if (ssc_sr & AT91C_SSC_ENDRX) {
+ if (ssc_sr & (AT91C_SSC_ENDRX | AT91C_SSC_CP1)) {
/* Ignore empty frames */
if (ssc_state.mode == SSC_MODE_CONTINUOUS) {
/* This code section is probably bitrotten by now. */
@@ -472,7 +477,7 @@ static void __ramfunc ssc_irq(void)
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_STANDARD || (ssc_state.mode == SSC_MODE_14443A && ssc_sr & AT91C_SSC_CP1)) {
// Stop sampling here
ssc_rx_stop();
} else {
@@ -554,7 +559,7 @@ void ssc_rx_start(void)
if(ssc_state.mode != SSC_MODE_14443A_SHORT) __ssc_rx_load(1);
/* Enable Reception */
- AT91F_SSC_EnableIt(ssc, AT91C_SSC_ENDRX | AT91C_SSC_CP0 |
+ AT91F_SSC_EnableIt(ssc, AT91C_SSC_ENDRX | AT91C_SSC_CP0 | AT91C_SSC_CP1 |
AT91C_SSC_RXBUFF | AT91C_SSC_OVRUN);
AT91F_PDC_EnableRx(rx_pdc);
AT91F_SSC_EnableRx(AT91C_BASE_SSC);
diff --git a/openpicc/application/ssc_picc.h b/openpicc/application/ssc_picc.h
index a01b16d..9600bab 100644
--- a/openpicc/application/ssc_picc.h
+++ b/openpicc/application/ssc_picc.h
@@ -21,6 +21,7 @@ enum ssc_mode {
SSC_MODE_NONE,
SSC_MODE_14443A_SHORT,
SSC_MODE_14443A_STANDARD,
+ SSC_MODE_14443A,
SSC_MODE_14443B,
SSC_MODE_EDGE_ONE_SHOT,
SSC_MODE_CONTINUOUS,
@@ -51,6 +52,11 @@ extern int ssc_get_metric(ssc_metric metric);
#define SSC_RX_BUFFER_SIZE 2048
#define SSC_DMA_BUFFER_COUNT 4
+#if SSC_RX_BUFFER_SIZE < ISO14443A_MAX_RX_FRAME_SIZE_IN_BITS
+#undef SSC_RX_BUFFER_SIZE
+#define SSC_RX_BUFFER_SIZE ISO14443A_MAX_RX_FRAME_SIZE_IN_BITS
+#endif
+
typedef enum {
FREE=0, /* Buffer is free */
PENDING, /* Buffer has been given to the DMA controller and is currently being filled */
personal git repositories of Harald Welte. Your mileage may vary