+
+//-----------------------------------------------------------------------------
+// The software UART that receives commands from the reader, and its state variables.
+//-----------------------------------------------------------------------------
+static struct {
+ enum {
+ STATE_UNSYNCD,
+ STATE_GOT_FALLING_EDGE_OF_SOF,
+ STATE_AWAITING_START_BIT,
+ STATE_RECEIVING_DATA
+ } state;
+ uint16_t shiftReg;
+ int bitCnt;
+ int byteCnt;
+ int byteCntMax;
+ int posCnt;
+ uint8_t *output;
+} Uart;
+
+static void UartReset() {
+ Uart.state = STATE_UNSYNCD;
+ Uart.shiftReg = 0;
+ Uart.bitCnt = 0;
+ Uart.byteCnt = 0;
+ Uart.byteCntMax = MAX_FRAME_SIZE;
+ Uart.posCnt = 0;
+}
+
+static void UartInit(uint8_t *data) {
+ Uart.output = data;
+ UartReset();
+// memset(Uart.output, 0x00, MAX_FRAME_SIZE);
+}
+
+//-----------------------------------------------------------------------------
+// The software Demod that receives commands from the tag, and its state variables.
+//-----------------------------------------------------------------------------
+static struct {
+ enum {
+ DEMOD_UNSYNCD,
+ DEMOD_PHASE_REF_TRAINING,
+ DEMOD_AWAITING_FALLING_EDGE_OF_SOF,
+ DEMOD_GOT_FALLING_EDGE_OF_SOF,
+ DEMOD_AWAITING_START_BIT,
+ DEMOD_RECEIVING_DATA
+ } state;
+ uint16_t bitCount;
+ int posCount;
+ int thisBit;
+/* this had been used to add RSSI (Received Signal Strength Indication) to traces. Currently not implemented.
+ int metric;
+ int metricN;
+*/
+ uint16_t shiftReg;
+ uint8_t *output;
+ uint16_t len;
+ int sumI;
+ int sumQ;
+ uint32_t startTime, endTime;
+} Demod;
+
+// Clear out the state of the "UART" that receives from the tag.
+static void DemodReset() {
+ Demod.state = DEMOD_UNSYNCD;
+ Demod.bitCount = 0;
+ Demod.posCount = 0;
+ Demod.thisBit = 0;
+ Demod.shiftReg = 0;
+ Demod.len = 0;
+ Demod.sumI = 0;
+ Demod.sumQ = 0;
+ Demod.startTime = 0;
+ Demod.endTime = 0;
+}
+
+static void DemodInit(uint8_t *data) {
+ Demod.output = data;
+ DemodReset();
+ // memset(Demod.output, 0x00, MAX_FRAME_SIZE);
+}
+
+
+/*
+* 9.4395 us = 1 ETU and clock is about 1.5 us
+* 13560000Hz
+* 1000ms/s
+* timeout in ETUs (time to transfer 1 bit, 9.4395 us)
+*
+* Formula to calculate FWT (in ETUs) by timeout (in ms):
+* fwt = 13560000 * 1000 / (8*16) * timeout;
+* Sample: 3sec == 3000ms
+* 13560000 * 1000 / (8*16) * 3000 ==
+* 13560000000 / 384000 = 35312 FWT
+* @param timeout is in frame wait time, fwt, measured in ETUs
+*/
+static void iso14b_set_timeout(uint32_t timeout) {
+ #define MAX_TIMEOUT 40542464 // 13560000Hz * 1000ms / (2^32-1) * (8*16)
+ if(timeout > MAX_TIMEOUT)
+ timeout = MAX_TIMEOUT;
+
+ iso14b_timeout = timeout;
+ if(MF_DBGLEVEL >= 3) Dbprintf("ISO14443B Timeout set to %ld fwt", iso14b_timeout);
+}
+static void iso14b_set_maxframesize(uint16_t size) {
+ if (size > 256)
+ size = MAX_FRAME_SIZE;
+
+ Uart.byteCntMax = size;
+ if(MF_DBGLEVEL >= 3) Dbprintf("ISO14443B Max frame size set to %d bytes", Uart.byteCntMax);
+}
+static void switch_off(void){
+ if (MF_DBGLEVEL > 3) Dbprintf("switch_off");
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
+ SpinDelay(100);
+ FpgaDisableSscDma();
+ set_tracing(FALSE);
+ LEDsoff();
+}
+
+void AppendCrc14443b(uint8_t* data, int len) {
+ ComputeCrc14443(CRC_14443_B, data, len, data+len, data+len+1);
+}
+