+ DecodeTag->posCount++;
+ break;
+
+ case STATE_TAG_EOF:
+ if (DecodeTag->posCount == 1) {
+ DecodeTag->sum1 = 0;
+ DecodeTag->sum2 = 0;
+ }
+ if (DecodeTag->posCount <= 4) {
+ DecodeTag->sum1 += amplitude;
+ } else {
+ DecodeTag->sum2 += amplitude;
+ }
+ if (DecodeTag->posCount == 8) {
+ int32_t corr_1 = DecodeTag->sum2 - DecodeTag->sum1;
+ int32_t corr_0 = -corr_1;
+ int32_t corr_EOF = (DecodeTag->sum1 + DecodeTag->sum2) / 2;
+ if (corr_EOF > corr_0 || corr_1 > corr_0) {
+ DecodeTag->posCount = 0;
+ DecodeTag->state = STATE_TAG_SOF_LOW;
+ LED_C_OFF();
+ } else {
+ LED_C_OFF();
+ return true;
+ }
+ }
+ DecodeTag->posCount++;
+ break;
+
+ }
+
+ return false;
+}
+
+
+static void DecodeTagInit(DecodeTag_t *DecodeTag, uint8_t *data, uint16_t max_len)
+{
+ DecodeTag->posCount = 0;
+ DecodeTag->state = STATE_TAG_SOF_LOW;
+ DecodeTag->output = data;
+ DecodeTag->max_len = max_len;
+}
+
+
+static void DecodeTagReset(DecodeTag_t *DecodeTag)
+{
+ DecodeTag->posCount = 0;
+ DecodeTag->state = STATE_TAG_SOF_LOW;
+}
+
+
+/*
+ * Receive and decode the tag response, also log to tracebuffer
+ */
+static int GetIso15693AnswerFromTag(uint8_t* response, uint16_t max_len, int timeout)
+{
+ int samples = 0;
+ bool gotFrame = false;
+
+ uint16_t *dmaBuf = (uint16_t*)BigBuf_malloc(ISO15693_DMA_BUFFER_SIZE*sizeof(uint16_t));
+
+ // the Decoder data structure
+ DecodeTag_t DecodeTag = { 0 };
+ DecodeTagInit(&DecodeTag, response, max_len);
+
+ // wait for last transfer to complete
+ while (!(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXEMPTY));
+
+ // And put the FPGA in the appropriate mode
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER | FPGA_HF_READER_SUBCARRIER_424_KHZ | FPGA_HF_READER_MODE_RECEIVE_AMPLITUDE);
+
+ // Setup and start DMA.
+ FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER);
+ FpgaSetupSscDma((uint8_t*) dmaBuf, ISO15693_DMA_BUFFER_SIZE);
+ uint16_t *upTo = dmaBuf;
+
+ for(;;) {
+ uint16_t behindBy = ((uint16_t*)AT91C_BASE_PDC_SSC->PDC_RPR - upTo) & (ISO15693_DMA_BUFFER_SIZE-1);
+
+ if (behindBy == 0) continue;
+
+ uint16_t tagdata = *upTo++;
+
+ if(upTo >= dmaBuf + ISO15693_DMA_BUFFER_SIZE) { // we have read all of the DMA buffer content.
+ upTo = dmaBuf; // start reading the circular buffer from the beginning
+ if(behindBy > (9*ISO15693_DMA_BUFFER_SIZE/10)) {
+ Dbprintf("About to blow circular buffer - aborted! behindBy=%d", behindBy);