Play with transfer sizes
Enhance timing by removing debugging code Pending rewrite of SSC RX IRQ code git-svn-id: https://svn.openpcd.org:2342/trunk@397 6dc7ffe9-61d6-0310-9af1-9938baff3ed1
This commit is contained in:
parent
a2c6b650bf
commit
f89811486c
|
@ -61,6 +61,8 @@ const iso14443_frame NULL_FRAME = {
|
|||
{}
|
||||
};
|
||||
|
||||
const u_int8_t ISO14443A_SHORT_FRAME_REQA[ISO14443A_SHORT_FRAME_COMPARE_LENGTH] = _ISO14443A_SHORT_FRAME_REQA;
|
||||
const u_int8_t ISO14443A_SHORT_FRAME_WUPA[ISO14443A_SHORT_FRAME_COMPARE_LENGTH] = _ISO14443A_SHORT_FRAME_WUPA;
|
||||
|
||||
#define PLL_LOCK_HYSTERESIS portTICK_RATE_MS*5
|
||||
|
||||
|
@ -106,6 +108,28 @@ void iso14443_transmit(ssc_dma_tx_buffer_t *buf, int fdt, int div)
|
|||
ssc_tx_start(buf);
|
||||
}
|
||||
|
||||
static void _is_reqa_or_wupa(enum ssc_mode ssc_mode, u_int8_t* samples, int *is_reqa, int *is_wupa)
|
||||
{
|
||||
if(ssc_mode == SSC_MODE_14443A_SHORT) {
|
||||
*is_reqa = *is_wupa = 0;
|
||||
ISO14443A_SHORT_TYPE sample = *(ISO14443A_SHORT_TYPE*)samples;
|
||||
if(sample == REQA) {
|
||||
*is_reqa = 1;
|
||||
} else if(sample == WUPA) {
|
||||
*is_wupa = 1;
|
||||
}
|
||||
} else if(ssc_mode == SSC_MODE_14443A) {
|
||||
int i;
|
||||
*is_reqa = *is_wupa = 1;
|
||||
for(i=0; i<ISO14443A_SHORT_FRAME_COMPARE_LENGTH; i++) {
|
||||
if(samples[i] != ISO14443A_SHORT_FRAME_REQA[i]) is_reqa = 0;
|
||||
if(samples[i] != ISO14443A_SHORT_FRAME_WUPA[i]) is_wupa = 0;
|
||||
}
|
||||
} else {
|
||||
*is_reqa = *is_wupa = 0;
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
|
@ -113,13 +137,15 @@ 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 || ssc_mode == SSC_MODE_14443A) && samples) {
|
||||
ISO14443A_SHORT_TYPE sample = *(ISO14443A_SHORT_TYPE*)samples;
|
||||
portBASE_TYPE send_atqa = 0;
|
||||
if(sample == REQA) {
|
||||
int is_reqa, is_wupa;
|
||||
_is_reqa_or_wupa(ssc_mode, samples, &is_reqa, &is_wupa);
|
||||
portBASE_TYPE send_atqa = is_reqa || is_wupa;
|
||||
|
||||
if(is_reqa) {
|
||||
fdt = ISO14443A_FDT_SHORT_0;
|
||||
if(state == IDLE)
|
||||
send_atqa = 1;
|
||||
} else if(sample == WUPA) {
|
||||
} else if(is_wupa) {
|
||||
fdt = ISO14443A_FDT_SHORT_1;
|
||||
if(state == IDLE || state == HALT)
|
||||
send_atqa = 1;
|
||||
|
@ -316,7 +342,11 @@ void iso14443_layer3a_state_machine (void *pvParameters)
|
|||
DumpStringToUSB("] ");
|
||||
DumpBufferToUSB((char*)buffer->data, (buffer->len_transfers * buffer->reception_mode->transfersize_pdc)/8);
|
||||
DumpStringToUSB(" Decoded: ");
|
||||
vLedBlinkGreen();
|
||||
vLedSetGreen(1);
|
||||
iso14443a_decode_miller(&received_frame, buffer);
|
||||
vLedBlinkGreen();
|
||||
vLedSetGreen(0);
|
||||
DumpBufferToUSB((char*)received_frame.data, received_frame.numbytes + (received_frame.numbits+7)/8);
|
||||
DumpStringToUSB(" ");
|
||||
DumpUIntToUSB(received_frame.parameters.a.last_bit);
|
||||
|
@ -324,13 +354,16 @@ void iso14443_layer3a_state_machine (void *pvParameters)
|
|||
usb_print_set_default_flush(i);
|
||||
}
|
||||
|
||||
int is_reqa=0, is_wupa=0;
|
||||
switch(state) {
|
||||
case IDLE:
|
||||
case HALT:
|
||||
if(first_sample == WUPA || (state==IDLE && first_sample==REQA)) {
|
||||
if(buffer->data) _is_reqa_or_wupa(buffer->reception_mode->mode, buffer->data, &is_reqa, &is_wupa);
|
||||
|
||||
if(is_wupa || (state==IDLE && is_reqa)) {
|
||||
/* Need to transmit ATQA */
|
||||
LAYER3_DEBUG("Received ");
|
||||
LAYER3_DEBUG(first_sample == WUPA ? "WUPA" : "REQA");
|
||||
LAYER3_DEBUG(is_wupa ? "WUPA" : "REQA");
|
||||
if(atqa_sent) {
|
||||
LAYER3_DEBUG(", woke up to send ATQA\n\r");
|
||||
atqa_sent = 0;
|
||||
|
@ -358,7 +391,11 @@ void iso14443_layer3a_state_machine (void *pvParameters)
|
|||
if(prefill_buffer(&ssc_tx_buffer, &NULL_FRAME)) {
|
||||
usb_print_string_f("Sending response ...",0);
|
||||
ssc_tx_buffer.state = PROCESSING;
|
||||
iso14443_transmit(&ssc_tx_buffer, ISO14443A_TRANSMIT_AT_NEXT_INTERVAL_1, 8);
|
||||
iso14443_transmit(&ssc_tx_buffer,
|
||||
received_frame.parameters.a.last_bit==ISO14443A_LAST_BIT_0 ?
|
||||
ISO14443A_TRANSMIT_AT_NEXT_INTERVAL_0 :
|
||||
ISO14443A_TRANSMIT_AT_NEXT_INTERVAL_1,
|
||||
8);
|
||||
while( ssc_tx_buffer.state != FREE ) {
|
||||
vTaskDelay(portTICK_RATE_MS);
|
||||
}
|
||||
|
|
|
@ -42,18 +42,30 @@ enum ISO14443_STATES {
|
|||
/* definitions for two-times oversampling */
|
||||
#define ISO14443A_SAMPLE_LEN 2
|
||||
|
||||
/* For SSC_MODE_ISO14443A_SHORT */
|
||||
#define ISO14443A_SHORT_LEN 18
|
||||
#define REQA 0x4929
|
||||
#define WUPA 0x2249
|
||||
|
||||
#define ISO14443A_SOF_SAMPLE 0x01
|
||||
#define ISO14443A_SOF_LEN 2
|
||||
#define ISO14443A_SHORT_LEN 18
|
||||
|
||||
#define ISO14443A_EOF_SAMPLE 0x00
|
||||
#define ISO14443A_EOF_LEN 5
|
||||
|
||||
/* For SSC_MODE_ISO14443A */
|
||||
#define ISO14443A_SHORT_FRAME_COMPARE_LENGTH 2
|
||||
#define _ISO14443A_SHORT_FRAME_REQA { 0x29, 0x49 }
|
||||
#define _ISO14443A_SHORT_FRAME_WUPA { 0x49, 0x22 }
|
||||
// FIXME not correct. This should be compare_length == 3 (which is 9 at 4 per compare), but this
|
||||
// needs enhanced ssc irq code to transfer the last read (incomplete) data from the ssc holding
|
||||
// register to the buffer
|
||||
|
||||
#endif
|
||||
|
||||
extern const u_int8_t ISO14443A_SHORT_FRAME_REQA[ISO14443A_SHORT_FRAME_COMPARE_LENGTH];
|
||||
extern const u_int8_t ISO14443A_SHORT_FRAME_WUPA[ISO14443A_SHORT_FRAME_COMPARE_LENGTH];
|
||||
|
||||
/* A short frame should be received in one single SSC transfer */
|
||||
#if (ISO14443A_SHORT_LEN <= 8)
|
||||
/* SSC transfer size in bits */
|
||||
|
|
|
@ -56,6 +56,7 @@
|
|||
#define DEBUGR(x, args ...)
|
||||
#endif
|
||||
|
||||
#define DEBUG_LOAD_AND_UNLOAD 0
|
||||
|
||||
static const AT91PS_SSC ssc = AT91C_BASE_SSC;
|
||||
static AT91PS_PDC rx_pdc;
|
||||
|
@ -79,7 +80,10 @@ static const ssc_mode_def ssc_sizes[] = {
|
|||
/* 14443A Standard Frame: FIXME 16 transfers of 32 bits (maximum number), resulting in 512 samples */
|
||||
[SSC_MODE_14443A_STANDARD] = {SSC_MODE_14443A_STANDARD, 32, 32, 16},
|
||||
/* 14443A Frame, don't care if standard or short */
|
||||
[SSC_MODE_14443A] = {SSC_MODE_14443A, ISO14443A_SAMPLE_LEN, 8, ISO14443A_MAX_RX_FRAME_SIZE_IN_BITS},
|
||||
[SSC_MODE_14443A] = {SSC_MODE_14443A,
|
||||
4 * ISO14443A_SAMPLE_LEN, // transfersize_ssc
|
||||
4 * ISO14443A_SAMPLE_LEN <= 8 ? 8 : 16, // transfersize_pdc
|
||||
ISO14443A_MAX_RX_FRAME_SIZE_IN_BITS},
|
||||
[SSC_MODE_14443B] = {SSC_MODE_14443B, 32, 32, 16}, /* 64 bytes */
|
||||
[SSC_MODE_EDGE_ONE_SHOT] = {SSC_MODE_EDGE_ONE_SHOT, 32, 32, 16}, /* 64 bytes */
|
||||
[SSC_MODE_CONTINUOUS] = {SSC_MODE_CONTINUOUS, 32, 32, 511}, /* 2044 bytes */
|
||||
|
@ -178,6 +182,7 @@ static int __ramfunc __ssc_rx_load(int secondary)
|
|||
ssc_state.buffer[0] = buffer;
|
||||
}
|
||||
|
||||
if(DEBUG_LOAD_AND_UNLOAD) {
|
||||
if(secondary) {int i=usb_print_set_default_flush(0);
|
||||
DumpStringToUSB("{1:");
|
||||
DumpUIntToUSB(rx_pdc->PDC_RNCR);
|
||||
|
@ -192,6 +197,7 @@ static int __ramfunc __ssc_rx_load(int secondary)
|
|||
DumpUIntToUSB(rx_pdc->PDC_RPR);
|
||||
DumpStringToUSB("} ");
|
||||
usb_print_set_default_flush(i);}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -215,6 +221,7 @@ 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(DEBUG_LOAD_AND_UNLOAD) {
|
||||
if(secondary) {int i=usb_print_set_default_flush(0);
|
||||
DumpStringToUSB("(1:");
|
||||
DumpUIntToUSB(rx_pdc->PDC_RNCR);
|
||||
|
@ -229,6 +236,7 @@ static ssc_dma_rx_buffer_t* __ramfunc __ssc_rx_unload(int secondary)
|
|||
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);
|
||||
|
@ -264,6 +272,7 @@ static ssc_dma_rx_buffer_t* __ramfunc __ssc_rx_unload(int secondary)
|
|||
}
|
||||
if(buffer->state == PENDING || buffer->state==FULL) {
|
||||
buffer->len_transfers = elapsed_transfers;
|
||||
if(DEBUG_LOAD_AND_UNLOAD)
|
||||
{int i=usb_print_set_default_flush(0);
|
||||
DumpStringToUSB("<");
|
||||
DumpUIntToUSB((unsigned int)buffer);
|
||||
|
@ -329,7 +338,7 @@ void ssc_rx_mode_set(enum ssc_mode ssc_mode)
|
|||
sync_len = ISO14443A_EOF_LEN;
|
||||
ssc->SSC_RC0R = ISO14443A_SOF_SAMPLE << (ISO14443A_EOF_LEN-ISO14443A_SOF_LEN);
|
||||
ssc->SSC_RC1R = ISO14443A_EOF_SAMPLE;
|
||||
data_len = ISO14443A_SAMPLE_LEN;
|
||||
data_len = ssc_sizes[SSC_MODE_14443A].transfersize_ssc;
|
||||
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 */
|
||||
clock_gating = (0x0 << 6);
|
||||
|
|
Loading…
Reference in New Issue