// 4sample
#define SEND4STUFFBIT(x) ToSendStuffBit(x);ToSendStuffBit(x);ToSendStuffBit(x);ToSendStuffBit(x);
+//#define SEND4STUFFBIT(x) ToSendStuffBit(x);
static void switch_off(void);
*
*/
- // ToSendStuffBit, 40 calls
- // 1 ETU = 1startbit, 1stopbit, 8databits == 10bits.
- // 1 ETU = 10 * 4 == 40 stuffbits ( ETU_TAG_BIT )
int i,j;
uint8_t b;
// Send SOF.
// 10-11 ETU * 4times samples ZEROS
for(i = 0; i < 10; i++) { SEND4STUFFBIT(0); }
+ //for(i = 0; i < 10; i++) { ToSendStuffBit(0); }
// 2-3 ETU * 4times samples ONES
for(i = 0; i < 3; i++) { SEND4STUFFBIT(1); }
+ //for(i = 0; i < 3; i++) { ToSendStuffBit(1); }
// data
for(i = 0; i < len; ++i) {
// Start bit
SEND4STUFFBIT(0);
+ //ToSendStuffBit(0);
// Data bits
b = cmd[i];
for(j = 0; j < 8; ++j) {
if(b & 1) {
SEND4STUFFBIT(1);
+ //ToSendStuffBit(1);
} else {
SEND4STUFFBIT(0);
+ //ToSendStuffBit(0);
}
b >>= 1;
}
// Stop bit
SEND4STUFFBIT(1);
+ //ToSendStuffBit(1);
// Extra Guard bit
// For PICC it ranges 0-18us (1etu = 9us)
SEND4STUFFBIT(1);
+ //ToSendStuffBit(1);
}
// Send EOF.
// 10-11 ETU * 4 sample rate = ZEROS
for(i = 0; i < 10; i++) { SEND4STUFFBIT(0); }
+ //for(i = 0; i < 10; i++) { ToSendStuffBit(0); }
// why this?
for(i = 0; i < 40; i++) { SEND4STUFFBIT(1); }
+ //for(i = 0; i < 40; i++) { ToSendStuffBit(1); }
// Convert from last byte pos to length
++ToSendMax;
// Signal field is off with the appropriate LED
LED_D_OFF();
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SIMULATOR | FPGA_HF_SIMULATOR_NO_MODULATION);
-
+
StartCountSspClk();
+ volatile uint8_t b;
+
+ // clear receiving shift register and holding register
+ // What does this loop do? Is it TR1?
+ for(uint8_t c = 0; c < 10;) {
+ if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
+ AT91C_BASE_SSC->SSC_THR = 0xFF;
+ ++c;
+ }
+ }
+
// Now run a `software UART' on the stream of incoming samples.
UartInit(received);
-
- uint8_t mask, b = 0;
+
+ b = 0;
+ uint8_t mask;
while( !BUTTON_PRESS() ) {
WDT_HIT();
return FALSE;
}
+void ClearFpgaShiftingRegisters(void){
+
+ volatile uint8_t b;
+
+ // clear receiving shift register and holding register
+ while(!(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY));
+
+ b = AT91C_BASE_SSC->SSC_RHR; (void) b;
+
+ while(!(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY));
+
+ b = AT91C_BASE_SSC->SSC_RHR; (void) b;
+
+
+ // wait for the FPGA to signal fdt_indicator == 1 (the FPGA is ready to queue new data in its delay line)
+ for (uint8_t j = 0; j < 5; j++) { // allow timeout - better late than never
+ while(!(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY));
+ if (AT91C_BASE_SSC->SSC_RHR) break;
+ }
+
+ // Clear TXRDY:
+ //AT91C_BASE_SSC->SSC_THR = 0xFF;
+}
+
+void WaitForFpgaDelayQueueIsEmpty( uint16_t delay ){
+ // Ensure that the FPGA Delay Queue is empty before we switch to TAGSIM_LISTEN again:
+ uint8_t fpga_queued_bits = delay >> 3; // twich /8 ?? >>3,
+ for (uint8_t i = 0; i <= fpga_queued_bits/8 + 1; ) {
+ if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
+ AT91C_BASE_SSC->SSC_THR = 0xFF;
+ i++;
+ }
+ }
+}
static void TransmitFor14443b_AsTag( uint8_t *response, uint16_t len) {
// Signal field is off with the appropriate LED
LED_D_OFF();
+ //uint16_t fpgasendQueueDelay = 0;
// Modulate BPSK
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SIMULATOR | FPGA_HF_SIMULATOR_MODULATE_BPSK);
- // 8 ETU / 8bits. 8/4= 2 etus.
- AT91C_BASE_SSC->SSC_THR = 0XFF;
-
+ ClearFpgaShiftingRegisters();
+
FpgaSetupSsc();
+ volatile uint32_t b;
// Transmit the response.
for(uint16_t i = 0; i < len;) {
if(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) {
- AT91C_BASE_SSC->SSC_THR = response[i];
- ++i;
+ AT91C_BASE_SSC->SSC_THR = response[++i];
}
+ if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
+ b = AT91C_BASE_SSC->SSC_RHR;
+ (void)b;
+ }
}
+
+ //WaitForFpgaDelayQueueIsEmpty(fpgasendQueueDelay);
+ AT91C_BASE_SSC->SSC_THR = 0xFF;
}
//-----------------------------------------------------------------------------
// Main loop of simulated tag: receive commands from reader, decide what
// ...PUPI/UID supplied from user. Adjust ATQB response accordingly
if ( pupi > 0 ) {
+ uint8_t len = sizeof(respATQB);
num_to_bytes(pupi, 4, respATQB+1);
- ComputeCrc14443(CRC_14443_B, respATQB, 12, respATQB+13, respATQB+14);
+ ComputeCrc14443(CRC_14443_B, respATQB, 12, &respATQB[len-2], &respATQB[len-1]);
}
// prepare "ATQB" tag answer (encoded):
// REQ or WUP request in ANY state
// WUP in HALTED state
if (len == 5 ) {
- if ( (receivedCmd[0] == ISO14443B_REQB && (receivedCmd[2] & 0x8)== 0x8 && cardSTATE != SIM_HALTED) ||
- (receivedCmd[0] == ISO14443B_REQB && (receivedCmd[2] & 0x8)== 0) ){
-
- TransmitFor14443b_AsTag( encodedATQB, encodedATQBLen );
- LogTrace(respATQB, sizeof(respATQB), 0, 0, NULL, FALSE);
+ if ( (receivedCmd[0] == ISO14443B_REQB && (receivedCmd[2] & 0x8)== 0x8 && cardSTATE == SIM_HALTED) ||
+ receivedCmd[0] == ISO14443B_REQB ){
+ LogTrace(receivedCmd, len, 0, 0, NULL, TRUE);
cardSTATE = SIM_SELECTING;
- continue;
}
}
case SIM_SELECTING: {
TransmitFor14443b_AsTag( encodedATQB, encodedATQBLen );
LogTrace(respATQB, sizeof(respATQB), 0, 0, NULL, FALSE);
- cardSTATE = SIM_IDLE;
+ cardSTATE = SIM_WORK;
break;
}
case SIM_HALTING: {
Demod.posCount = 0; // start of SOF sequence
} else {
// maximum length of TR1 = 200 1/fs
- if(Demod.posCount > 25*2) Demod.state = DEMOD_UNSYNCD;
+ if(Demod.posCount > 26*2) Demod.state = DEMOD_UNSYNCD;
}
++Demod.posCount;
break;
if(v > 0) {
// low phase of SOF too short (< 9 etu). Note: spec is >= 10, but FPGA tends to "smear" edges
- if(Demod.posCount < 9*2) {
+ if(Demod.posCount < 8*2) {
Demod.state = DEMOD_UNSYNCD;
} else {
LED_C_ON(); // Got SOF
}
} else {
// low phase of SOF too long (> 12 etu)
- if (Demod.posCount > 12*2) {
+ if (Demod.posCount > 14*2) {
Demod.state = DEMOD_UNSYNCD;
LED_C_OFF();
}
MAKE_SOFT_DECISION();
if (v > 0) {
- if(Demod.posCount > 3*2) { // max 19us between characters = 16 1/fs, max 3 etu after low phase of SOF = 24 1/fs
+ if(Demod.posCount > 2*2) { // max 19us between characters = 16 1/fs, max 3 etu after low phase of SOF = 24 1/fs
Demod.state = DEMOD_UNSYNCD;
LED_C_OFF();
}
// And put the FPGA in the appropriate mode
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR | FPGA_HF_READER_RX_XCORR_848_KHZ);
-
+
while( !BUTTON_PRESS() ) {
WDT_HIT();
//-----------------------------------------------------------------------------
static void TransmitFor14443b_AsReader(void) {
- FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_TX | FPGA_HF_READER_TX_SHALLOW_MOD);
- SpinDelay(20);
-
- int c;
// we could been in following mode:
// FPGA_MAJOR_MODE_HF_READER_RX_XCORR | FPGA_HF_READER_RX_XCORR_848_KHZ
// if its second call or more
+
+ // while(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
+ // AT91C_BASE_SSC->SSC_THR = 0XFF;
+ // }
+
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_TX | FPGA_HF_READER_TX_SHALLOW_MOD);
+ SpinDelay(40);
+ int c;
+ volatile uint32_t b;
+
// What does this loop do? Is it TR1?
- for(c = 0; c < 10;) {
+ // 0xFF = 8 bits of 1. 1 bit == 1Etu,..
+ // loop 10 * 8 = 80 ETU of delay, with a non modulated signal. why?
+ // 80*9 = 720us.
+ for(c = 0; c < 50;) {
if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
AT91C_BASE_SSC->SSC_THR = 0xFF;
++c;
}
+ if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
+ b = AT91C_BASE_SSC->SSC_RHR;
+ (void)b;
+ }
}
-
+
// Send frame loop
for(c = 0; c < ToSendMax;) {
if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
- AT91C_BASE_SSC->SSC_THR = ToSend[c];
- ++c;
+ AT91C_BASE_SSC->SSC_THR = ToSend[c++];
}
+ if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
+ b = AT91C_BASE_SSC->SSC_RHR;
+ (void)b;
+ }
}
+ //WaitForFpgaDelayQueueIsEmpty(delay);
+ // We should wait here for the FPGA to send all bits.
WDT_HIT();
}
*
* 1 ETU == 1 BIT!
* TR0 - 8 ETUS minimum.
+ *
+ * QUESTION: how long is a 1 or 0 in pulses in the xcorr_848 mode?
+ * 1 "stuffbit" = 1ETU (9us)
*/
int i;
uint8_t b;
// Transition time. TR0 - guard time
// 8ETUS minum?
// Per specification, Subcarrier must be stopped no later than 2 ETUs after EOF.
- for(i = 0; i < 40 ; ++i) ToSendStuffBit(1);
+ // I'm guessing this is for the FPGA to be able to send all bits before we switch to listening mode
+ for(i = 0; i < 32 ; ++i) ToSendStuffBit(1);
// TR1 - Synchronization time
// Convert from last character reference to length
return 3;
// CID
- if (card) card->cid = Demod.output[0];
-
- uint8_t fwt = card->atqb[6]>>4;
- if ( fwt < 16 ){
- uint32_t fwt_time = (302 << fwt);
- iso14b_set_timeout( fwt_time);
+ if (card) {
+ card->cid = Demod.output[0];
+ uint8_t fwt = card->atqb[6] >> 4;
+ if ( fwt < 16 ){
+ uint32_t fwt_time = (302 << fwt);
+ iso14b_set_timeout( fwt_time);
+ }
}
// reset PCB block number
pcb_blocknum = 0;
Dbprintf(" Trace length: %i", BigBuf_get_traceLen());
// free mem refs.
- if ( dmaBuf ) dmaBuf = NULL;
if ( upTo ) upTo = NULL;
+
// Uart.byteCntMax should be set with ATQB value..
}