From 3354f0d9d36ef171f5a3e3c43b9ddcf6f1844ea2 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 15 Jul 2020 15:16:35 +0200 Subject: [PATCH] unified static dma buffer as bigbuf_malloc, less pressure on stack size --- armsrc/BigBuf.c | 64 +++++++++++++--- armsrc/BigBuf.h | 14 +++- armsrc/iso14443a.c | 23 +++--- armsrc/iso14443b.c | 185 ++++++++++++++++++--------------------------- armsrc/iso15693.c | 83 ++++++++++---------- 5 files changed, 194 insertions(+), 175 deletions(-) diff --git a/armsrc/BigBuf.c b/armsrc/BigBuf.c index 7cb440d82..338206d6e 100644 --- a/armsrc/BigBuf.c +++ b/armsrc/BigBuf.c @@ -36,6 +36,33 @@ static uint32_t s_bigbuf_hi = 0; // pointer to the emulator memory. static uint8_t *emulator_memory = NULL; +//============================================================================= +// The ToSend buffer. +// A buffer where we can queue things up to be sent through the FPGA, for +// any purpose (fake tag, as reader, whatever). We go MSB first, since that +// is the order in which they go out on the wire. +//============================================================================= +static tosend_t toSend = { + .max = -1, + .bit = 8, + .buf = NULL +}; +//============================================================================= +// The dmaBuf 16bit buffer. +// A buffer where we recive IQ samples sent from the FPGA, for demodulating +//============================================================================= +static dmabuf16_t dma_16 = { + .size = DMA_BUFFER_SIZE, + .buf = NULL +}; +// dmaBuf 8bit buffer +static dmabuf8_t dma_8 = { + .size = DMA_BUFFER_SIZE, + .buf = NULL +}; + + + // trace related variables static uint32_t trace_len = 0; static bool tracing = true; @@ -106,6 +133,9 @@ void BigBuf_free(void) { s_bigbuf_hi = s_bigbuf_size; emulator_memory = NULL; // shouldn't this empty BigBuf also? + toSend.buf = NULL; + dma_16.buf = NULL; + dma_8.buf = NULL; } // free allocated chunks EXCEPT the emulator memory @@ -114,6 +144,10 @@ void BigBuf_free_keep_EM(void) { s_bigbuf_hi = emulator_memory - (uint8_t *)BigBuf; else s_bigbuf_hi = s_bigbuf_size; + + toSend.buf = NULL; + dma_16.buf = NULL; + dma_8.buf = NULL; } void BigBuf_print_status(void) { @@ -123,6 +157,10 @@ void BigBuf_print_status(void) { DbpString(_CYAN_("Tracing")); Dbprintf(" tracing ................%d", tracing); Dbprintf(" traceLen ...............%d", trace_len); + + Dbprintf(" dma8 memory.............%d", dma_8.buf - BigBuf_get_addr()); + Dbprintf(" dma16 memory............%d", (uint8_t*)dma_16.buf - BigBuf_get_addr()); + Dbprintf(" toSend memory...........%d", toSend.buf - BigBuf_get_addr() ); } // return the maximum trace length (i.e. the unallocated size of BigBuf) @@ -228,17 +266,6 @@ uint8_t emlSet(uint8_t *data, uint32_t offset, uint32_t length) { } -//============================================================================= -// The ToSend buffer. -// A buffer where we can queue things up to be sent through the FPGA, for -// any purpose (fake tag, as reader, whatever). We go MSB first, since that -// is the order in which they go out on the wire. -//============================================================================= -static tosend_t toSend = { - .max = -1, - .bit = 8, - .buf = NULL -}; // get the address of the ToSend buffer. Allocate part of Bigbuf for it, if not yet done tosend_t *get_tosend(void) { @@ -270,3 +297,18 @@ void tosend_stuffbit(int b) { toSend.bit = 0; } } + +dmabuf16_t *get_dma16(void) { + if (dma_16.buf == NULL) + dma_16.buf = (uint16_t*)BigBuf_malloc(DMA_BUFFER_SIZE); + + return &dma_16; +} + +dmabuf8_t *get_dma8(void) { + if (dma_8.buf == NULL) + dma_8.buf = BigBuf_malloc(DMA_BUFFER_SIZE); + + return &dma_8; +} + diff --git a/armsrc/BigBuf.h b/armsrc/BigBuf.h index 33c454226..2f381f36b 100644 --- a/armsrc/BigBuf.h +++ b/armsrc/BigBuf.h @@ -19,7 +19,7 @@ #define MAX_MIFARE_FRAME_SIZE 18 // biggest Mifare frame is answer to a read (one block = 16 Bytes) + 2 Bytes CRC #define MAX_MIFARE_PARITY_SIZE 3 // need 18 parity bits for the 18 Byte above. 3 Bytes are enough to store these #define CARD_MEMORY_SIZE 4096 -#define DMA_BUFFER_SIZE 128 +#define DMA_BUFFER_SIZE 256 // 8 data bits and 1 parity bit per payload byte, 1 correction bit, 1 SOC bit, 2 EOC bits #define TOSEND_BUFFER_SIZE (9 * MAX_FRAME_SIZE + 1 + 1 + 2) @@ -56,4 +56,16 @@ tosend_t *get_tosend(void); void tosend_reset(void); void tosend_stuffbit(int b); +typedef struct { + uint16_t size; + uint8_t *buf; +} dmabuf8_t; + +typedef struct { + uint16_t size; + uint16_t *buf; +} dmabuf16_t; + +dmabuf8_t *get_dma8(void); +dmabuf16_t *get_dma16(void); #endif /* __BIGBUF_H */ diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index bac3008f9..53d1f6814 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -585,10 +585,6 @@ void RAMFUNC SniffIso14443a(uint8_t param) { uint8_t *receivedResp = BigBuf_malloc(MAX_FRAME_SIZE); uint8_t *receivedRespPar = BigBuf_malloc(MAX_PARITY_SIZE); - // The DMA buffer, used to stream samples from the FPGA - uint8_t *dmaBuf = BigBuf_malloc(DMA_BUFFER_SIZE); - uint8_t *data = dmaBuf; - uint8_t previous_data = 0; int maxDataLen = 0, dataLen; bool TagIsActive = false; @@ -602,8 +598,12 @@ void RAMFUNC SniffIso14443a(uint8_t param) { DbpString("Starting to sniff"); + // The DMA buffer, used to stream samples from the FPGA + dmabuf8_t *dma = get_dma8(); + uint8_t *data = dma->buf; + // Setup and start DMA. - if (!FpgaSetupSscDma((uint8_t *) dmaBuf, DMA_BUFFER_SIZE)) { + if (!FpgaSetupSscDma((uint8_t *) dma->buf, DMA_BUFFER_SIZE)) { if (DBGLEVEL > 1) Dbprintf("FpgaSetupSscDma failed. Exiting"); return; } @@ -621,7 +621,7 @@ void RAMFUNC SniffIso14443a(uint8_t param) { WDT_HIT(); LED_A_ON(); - int register readBufDataP = data - dmaBuf; + int register readBufDataP = data - dma->buf; int register dmaBufDataP = DMA_BUFFER_SIZE - AT91C_BASE_PDC_SSC->PDC_RCR; if (readBufDataP <= dmaBufDataP) dataLen = dmaBufDataP - readBufDataP; @@ -640,13 +640,13 @@ void RAMFUNC SniffIso14443a(uint8_t param) { // primary buffer was stopped( <-- we lost data! if (!AT91C_BASE_PDC_SSC->PDC_RCR) { - AT91C_BASE_PDC_SSC->PDC_RPR = (uint32_t) dmaBuf; + AT91C_BASE_PDC_SSC->PDC_RPR = (uint32_t) dma->buf; AT91C_BASE_PDC_SSC->PDC_RCR = DMA_BUFFER_SIZE; Dbprintf("[-] RxEmpty ERROR | data length %d", dataLen); // temporary } // secondary buffer sets as primary, secondary buffer was stopped if (!AT91C_BASE_PDC_SSC->PDC_RNCR) { - AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) dmaBuf; + AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) dma->buf; AT91C_BASE_PDC_SSC->PDC_RNCR = DMA_BUFFER_SIZE; } @@ -710,16 +710,15 @@ void RAMFUNC SniffIso14443a(uint8_t param) { previous_data = *data; rx_samples++; data++; - if (data == dmaBuf + DMA_BUFFER_SIZE) { - data = dmaBuf; + if (data == dma->buf + DMA_BUFFER_SIZE) { + data = dma->buf; } } // end main loop FpgaDisableTracing(); if (DBGLEVEL >= DBG_ERROR) { - Dbprintf("maxDataLen=%d, Uart.state=%x, Uart.len=%d", maxDataLen, Uart.state, Uart.len); - Dbprintf("traceLen=" _YELLOW_("%d")", Uart.output[0]="_YELLOW_("%08x"), BigBuf_get_traceLen(), (uint32_t)Uart.output[0]); + Dbprintf("trace len = " _YELLOW_("%d"), BigBuf_get_traceLen()); } switch_off(); } diff --git a/armsrc/iso14443b.c b/armsrc/iso14443b.c index d9d08a966..e26ebb017 100644 --- a/armsrc/iso14443b.c +++ b/armsrc/iso14443b.c @@ -26,11 +26,8 @@ #include "ticks.h" -#ifndef ISO14443B_DMA_BUFFER_SIZE -# define ISO14443B_DMA_BUFFER_SIZE 128 -#endif #ifndef RECEIVE_MASK -# define RECEIVE_MASK (ISO14443B_DMA_BUFFER_SIZE-1) +# define RECEIVE_MASK (DMA_BUFFER_SIZE - 1) #endif #define RECEIVE_SAMPLES_TIMEOUT 64 @@ -480,13 +477,7 @@ static void TransmitFor14443b_AsTag(uint8_t *response, uint16_t len) { // Put byte into tx holding register as soon as it is ready if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) { - AT91C_BASE_SSC->SSC_THR = response[++i]; - } - - // Prevent rx holding register from overflowing - if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { - volatile uint32_t b = AT91C_BASE_SSC->SSC_RHR; - (void)b; + AT91C_BASE_SSC->SSC_THR = response[i++]; } } } @@ -702,40 +693,17 @@ void SimulateIso14443bTag(uint32_t pupi) { * false if we are still waiting for some more * */ -static RAMFUNC int Handle14443bTagSamplesDemod(int ci, int cq) { - int v = 0, myI = ABS(ci), myQ = ABS(cq); - -// The soft decision on the bit uses an estimate of just the -// quadrant of the reference angle, not the exact angle. -#define MAKE_SOFT_DECISION(void) { \ - if (Demod.sumI > 0) { \ - v = ci; \ - } else { \ - v = -ci; \ - } \ - if (Demod.sumQ > 0) { \ - v += cq; \ - } else { \ - v -= cq; \ - } \ - } +static RAMFUNC int Handle14443bTagSamplesDemod(uint16_t amplitude) { #define SUBCARRIER_DETECT_THRESHOLD 8 -//note: couldn't we just use MAX(ABS(ci),ABS(cq)) + (MIN(ABS(ci),ABS(cq))/2) from common.h - marshmellow -#define CHECK_FOR_SUBCARRIER(void) { v = MAX(myI, myQ) + (MIN(myI, myQ) >> 1); } - switch (Demod.state) { case DEMOD_UNSYNCD: - CHECK_FOR_SUBCARRIER(); - - // subcarrier detected - - if (v > SUBCARRIER_DETECT_THRESHOLD) { + if (amplitude > SUBCARRIER_DETECT_THRESHOLD) { Demod.state = DEMOD_PHASE_REF_TRAINING; - Demod.sumI = ci; - Demod.sumQ = cq; + Demod.sumI = amplitude; + Demod.sumQ = amplitude; Demod.posCount = 1; } break; @@ -743,13 +711,11 @@ static RAMFUNC int Handle14443bTagSamplesDemod(int ci, int cq) { case DEMOD_PHASE_REF_TRAINING: if (Demod.posCount < 8) { - CHECK_FOR_SUBCARRIER(); - - if (v > SUBCARRIER_DETECT_THRESHOLD) { + if (amplitude > SUBCARRIER_DETECT_THRESHOLD) { // set the reference phase (will code a logic '1') by averaging over 32 1/fs. // note: synchronization time > 80 1/fs - Demod.sumI += ci; - Demod.sumQ += cq; + Demod.sumI += amplitude; + Demod.sumQ += amplitude; Demod.posCount++; } else { // subcarrier lost @@ -762,9 +728,7 @@ static RAMFUNC int Handle14443bTagSamplesDemod(int ci, int cq) { case DEMOD_AWAITING_FALLING_EDGE_OF_SOF: - MAKE_SOFT_DECISION(); - - if (v < 0) { // logic '0' detected + if (amplitude == 0) { // logic '0' detected Demod.state = DEMOD_GOT_FALLING_EDGE_OF_SOF; Demod.posCount = 0; // start of SOF sequence } else { @@ -779,9 +743,7 @@ static RAMFUNC int Handle14443bTagSamplesDemod(int ci, int cq) { case DEMOD_GOT_FALLING_EDGE_OF_SOF: Demod.posCount++; - MAKE_SOFT_DECISION(); - - if (v > 0) { + if (amplitude > 0) { // low phase of SOF too short (< 9 etu). Note: spec is >= 10, but FPGA tends to "smear" edges if (Demod.posCount < 9 * 2) { Demod.state = DEMOD_UNSYNCD; @@ -804,9 +766,7 @@ static RAMFUNC int Handle14443bTagSamplesDemod(int ci, int cq) { case DEMOD_AWAITING_START_BIT: Demod.posCount++; - MAKE_SOFT_DECISION(); - - if (v > 0) { + if (amplitude > 0) { if (Demod.posCount > 6 * 2) { // max 19us between characters = 16 1/fs, max 3 etu after low phase of SOF = 24 1/fs LED_C_OFF(); if (Demod.bitCount == 0 && Demod.len == 0) { // received SOF only, this is valid for iClass/Picopass @@ -818,7 +778,7 @@ static RAMFUNC int Handle14443bTagSamplesDemod(int ci, int cq) { } else { // start bit detected Demod.bitCount = 0; Demod.posCount = 1; // this was the first half - Demod.thisBit = v; + Demod.thisBit = amplitude; Demod.shiftReg = 0; Demod.state = DEMOD_RECEIVING_DATA; } @@ -826,15 +786,13 @@ static RAMFUNC int Handle14443bTagSamplesDemod(int ci, int cq) { case DEMOD_RECEIVING_DATA: - MAKE_SOFT_DECISION(); - if (Demod.posCount == 0) { // first half of bit - Demod.thisBit = v; + Demod.thisBit = amplitude; Demod.posCount = 1; } else { // second half of bit - Demod.thisBit += v; + Demod.thisBit += amplitude; Demod.shiftReg >>= 1; // OR in a logic '1' @@ -882,64 +840,66 @@ static RAMFUNC int Handle14443bTagSamplesDemod(int ci, int cq) { * Demodulate the samples we received from the tag, also log to tracebuffer */ static int GetTagSamplesFor14443bDemod(int timeout) { - int ret = 0; - int maxBehindBy = 0; - int lastRxCounter, samples = 0; - int8_t ci, cq; - uint32_t time_0 = 0, time_stop = 0; + + int samples = 0, ret = 0; BigBuf_free(); - // The response (tag -> reader) that we're receiving. - uint8_t *receivedResponse = BigBuf_malloc(MAX_FRAME_SIZE); - - // The DMA buffer, used to stream samples from the FPGA - uint16_t *dmaBuf = (uint16_t*) BigBuf_malloc(ISO14443B_DMA_BUFFER_SIZE * sizeof(uint16_t)); // Set up the demodulator for tag -> reader responses. - Demod14bInit(receivedResponse); + Demod14bInit(BigBuf_malloc(MAX_FRAME_SIZE)); // wait for last transfer to complete while (!(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXEMPTY)) // Setup and start DMA. FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER); - if (FpgaSetupSscDma((uint8_t *) dmaBuf, ISO14443B_DMA_BUFFER_SIZE) == false) { + + // The DMA buffer, used to stream samples from the FPGA + dmabuf16_t *dma = get_dma16(); + if (FpgaSetupSscDma((uint8_t *) dma->buf, DMA_BUFFER_SIZE) == false) { if (DBGLEVEL > 1) Dbprintf("FpgaSetupSscDma failed. Exiting"); return -1; } - uint16_t *upTo = dmaBuf; - lastRxCounter = ISO14443B_DMA_BUFFER_SIZE; - // Signal field is ON with the appropriate LED: LED_D_ON(); + // And put the FPGA in the appropriate mode FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER | FPGA_HF_READER_SUBCARRIER_848_KHZ | FPGA_HF_READER_MODE_RECEIVE_IQ); +// uint32_t dma_start_time; + uint16_t *upTo = dma->buf; + for(;;) { - int behindBy = (lastRxCounter - AT91C_BASE_PDC_SSC->PDC_RCR) & (ISO14443B_DMA_BUFFER_SIZE-1); - if (behindBy > maxBehindBy) { - maxBehindBy = behindBy; - } + uint16_t behindBy = ((uint16_t*)AT91C_BASE_PDC_SSC->PDC_RPR - upTo) & (DMA_BUFFER_SIZE - 1); - if (behindBy < 1) continue; + if (behindBy == 0) continue; - ci = *upTo >> 8; - cq = *upTo; - upTo++; - lastRxCounter--; - if (upTo >= dmaBuf + ISO14443B_DMA_BUFFER_SIZE) { // we have read all of the DMA buffer content. - upTo = dmaBuf; // start reading the circular buffer from the beginning - lastRxCounter += ISO14443B_DMA_BUFFER_SIZE; - } - - if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_ENDRX)) { // DMA Counter Register had reached 0, already rotated. - AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) dmaBuf; // refresh the DMA Next Buffer and - AT91C_BASE_PDC_SSC->PDC_RNCR = ISO14443B_DMA_BUFFER_SIZE; // DMA Next Counter registers - } samples++; + /* + if (samples == 1) { + // DMA has transferred the very first data + dma_start_time = GetCountSspClk() & 0xfffffff0; + } + */ - if (Handle14443bTagSamplesDemod(ci, cq)) { + volatile uint16_t tagdata = *upTo++; + + if (upTo >= dma->buf + DMA_BUFFER_SIZE) { // we have read all of the DMA buffer content. + upTo = dma->buf; // start reading the circular buffer from the beginning + if (behindBy > (9 * DMA_BUFFER_SIZE / 10)) { + Dbprintf("About to blow circular buffer - aborted! behindBy=%d", behindBy); + ret = -1; + break; + } + } + + if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_ENDRX)) { // DMA Counter Register had reached 0, already rotated. + AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) dma->buf; // refresh the DMA Next Buffer and + AT91C_BASE_PDC_SSC->PDC_RNCR = DMA_BUFFER_SIZE; // DMA Next Counter registers + } + + if (Handle14443bTagSamplesDemod(tagdata)) { ret = Demod.len; break; } @@ -958,7 +918,7 @@ static int GetTagSamplesFor14443bDemod(int timeout) { } if (Demod.len > 0) { - LogTrace(Demod.output, Demod.len, time_0, time_stop, NULL, false); + LogTrace(Demod.output, Demod.len, 0, 0, NULL, false); } return ret; @@ -976,12 +936,14 @@ static void TransmitFor14443b_AsReader(void) { for (int c = 0; c < ts->max; c++) { uint8_t data = ts->buf[c]; + for (int i = 0; i < 8; i++) { uint16_t send_word = (data & 0x80) ? 0x0000 : 0xffff; while (!(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY))) ; AT91C_BASE_SSC->SSC_THR = send_word; + while (!(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY))) ; AT91C_BASE_SSC->SSC_THR = send_word; @@ -1388,7 +1350,7 @@ static void iso1444b_setup_sniff(void) { Dbprintf("[+] trace: %i bytes", BigBuf_max_traceLen()); Dbprintf("[+] reader -> tag: %i bytes", MAX_FRAME_SIZE); Dbprintf("[+] tag -> reader: %i bytes", MAX_FRAME_SIZE); - Dbprintf("[+] DMA: %i bytes", ISO14443B_DMA_BUFFER_SIZE); + Dbprintf("[+] DMA: %i bytes", DMA_BUFFER_SIZE); } // connect Demodulated Signal to ADC: @@ -1432,12 +1394,7 @@ void RAMFUNC SniffIso14443b(void) { bool TagIsActive = false; bool ReaderIsActive = false; - iso1444b_setup_sniff(); - - // The DMA buffer, used to stream samples from the FPGA - uint16_t *dmaBuf = (uint16_t*) BigBuf_malloc(ISO14443B_DMA_BUFFER_SIZE * sizeof(uint16_t)); - uint16_t *upTo = dmaBuf; - int lastRxCounter = ISO14443B_DMA_BUFFER_SIZE; + int lastRxCounter = DMA_BUFFER_SIZE; int8_t ci, cq; int maxBehindBy = 0; @@ -1445,8 +1402,14 @@ void RAMFUNC SniffIso14443b(void) { // information in the trace buffer. int samples = 0; + iso1444b_setup_sniff(); + + // The DMA buffer, used to stream samples from the FPGA + dmabuf16_t *dma = get_dma16(); + uint16_t *upTo = dma->buf; + // Setup and start DMA. - if (!FpgaSetupSscDma((uint8_t *) dmaBuf, ISO14443B_DMA_BUFFER_SIZE)) { + if (!FpgaSetupSscDma((uint8_t *) dma->buf, DMA_BUFFER_SIZE)) { if (DBGLEVEL > 1) Dbprintf("[!] FpgaSetupSscDma failed. Exiting"); BigBuf_free(); return; @@ -1458,29 +1421,31 @@ void RAMFUNC SniffIso14443b(void) { // loop and listen for(;;) { - int behindBy = (lastRxCounter - AT91C_BASE_PDC_SSC->PDC_RCR) & (ISO14443B_DMA_BUFFER_SIZE - 1); + int behindBy = (lastRxCounter - AT91C_BASE_PDC_SSC->PDC_RCR) & (DMA_BUFFER_SIZE - 1); if (behindBy > maxBehindBy) { maxBehindBy = behindBy; } - if (behindBy < 1) continue; + if (behindBy == 0) continue; ci = *upTo >> 8; cq = *upTo; + uint16_t tagdata = *upTo; + upTo++; lastRxCounter--; - if (upTo >= dmaBuf + ISO14443B_DMA_BUFFER_SIZE) { // we have read all of the DMA buffer content. - upTo = dmaBuf; // start reading the circular buffer from the beginning again - lastRxCounter += ISO14443B_DMA_BUFFER_SIZE; - if (behindBy > (9 * ISO14443B_DMA_BUFFER_SIZE / 10)) { + if (upTo >= dma->buf + DMA_BUFFER_SIZE) { // we have read all of the DMA buffer content. + upTo = dma->buf; // start reading the circular buffer from the beginning again + lastRxCounter += DMA_BUFFER_SIZE; + if (behindBy > (9 * DMA_BUFFER_SIZE / 10)) { Dbprintf("About to blow circular buffer - aborted! behindBy=%d", behindBy); break; } } - if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_ENDRX)) { // DMA Counter Register had reached 0, already rotated. - AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) dmaBuf; // refresh the DMA Next Buffer and - AT91C_BASE_PDC_SSC->PDC_RNCR = ISO14443B_DMA_BUFFER_SIZE; // DMA Next Counter registers + if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_ENDRX)) { // DMA Counter Register had reached 0, already rotated. + AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) dma->buf; // refresh the DMA Next Buffer and + AT91C_BASE_PDC_SSC->PDC_RNCR = DMA_BUFFER_SIZE; // DMA Next Counter registers WDT_HIT(); if (BUTTON_PRESS()) { @@ -1522,7 +1487,7 @@ void RAMFUNC SniffIso14443b(void) { // is this | 0x01 the error? & 0xfe in https://github.com/Proxmark/proxmark3/issues/103 // LSB is a fpga signal bit. - if (Handle14443bTagSamplesDemod(ci/2, cq/2) >= 0) { + if (Handle14443bTagSamplesDemod(tagdata) >= 0) { time_stop = GetCountSspClk() - time_0; LogTrace(Demod.output, Demod.len, time_start, time_stop, NULL, false); Uart14bReset(); diff --git a/armsrc/iso15693.c b/armsrc/iso15693.c index ff59d260a..36530f72b 100644 --- a/armsrc/iso15693.c +++ b/armsrc/iso15693.c @@ -91,7 +91,7 @@ /////////////////////////////////////////////////////////////////////// // buffers -#define ISO15693_DMA_BUFFER_SIZE 256 // must be a power of 2 +//#define ISO15693_DMA_BUFFER_SIZE 256 // must be a power of 2 #define ISO15693_MAX_RESPONSE_LENGTH 36 // allows read single block with the maximum block size of 256bits. Read multiple blocks not supported yet #define ISO15693_MAX_COMMAND_LENGTH 45 // allows write single block with the maximum block size of 256bits. Write multiple blocks not supported yet @@ -305,7 +305,7 @@ void TransmitTo15693Reader(const uint8_t *cmd, size_t len, uint32_t *start_time, uint8_t bits_to_shift = 0x00; uint8_t bits_to_send = 0x00; for (size_t c = 0; c < len; c++) { - for (int i = (c==0?4:7); i >= 0; i--) { + for (int i = (c == 0 ? 4 : 7); i >= 0; i--) { uint8_t cmd_bits = ((cmd[c] >> i) & 0x01) ? 0xff : 0x00; for (int j = 0; j < (slow ? 4 : 1); ) { if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) { @@ -406,7 +406,7 @@ static RAMFUNC int Handle15693SamplesFromTag(uint16_t amplitude, DecodeTag_t *De DecodeTag->threshold_sof = (amplitude - DecodeTag->previous_amplitude) / 2; } else { DecodeTag->posCount = 2; - DecodeTag->threshold_sof = DecodeTag->threshold_sof/2; + DecodeTag->threshold_sof = DecodeTag->threshold_sof / 2; } // DecodeTag->posCount = 2; DecodeTag->state = STATE_TAG_SOF_HIGH; @@ -621,7 +621,6 @@ static void DecodeTagReset(DecodeTag_t *DecodeTag) { int GetIso15693AnswerFromTag(uint8_t* response, uint16_t max_len, uint16_t timeout, uint32_t *eof_time) { int samples = 0, ret = 0; - uint16_t dmaBuf[ISO15693_DMA_BUFFER_SIZE] = {0}; // the Decoder data structure DecodeTag_t DecodeTag = { 0 }; @@ -635,13 +634,18 @@ int GetIso15693AnswerFromTag(uint8_t* response, uint16_t max_len, uint16_t timeo // Setup and start DMA. FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER); - FpgaSetupSscDma((uint8_t*) dmaBuf, ISO15693_DMA_BUFFER_SIZE); + + // The DMA buffer, used to stream samples from the FPGA + dmabuf16_t *dma = get_dma16(); + + FpgaSetupSscDma((uint8_t*) dma->buf, DMA_BUFFER_SIZE); + uint32_t dma_start_time = 0; - uint16_t *upTo = dmaBuf; + uint16_t *upTo = dma->buf; for(;;) { - uint16_t behindBy = ((uint16_t*)AT91C_BASE_PDC_SSC->PDC_RPR - upTo) & (ISO15693_DMA_BUFFER_SIZE-1); + uint16_t behindBy = ((uint16_t*)AT91C_BASE_PDC_SSC->PDC_RPR - upTo) & (DMA_BUFFER_SIZE - 1); if (behindBy == 0) continue; @@ -653,17 +657,17 @@ int GetIso15693AnswerFromTag(uint8_t* response, uint16_t max_len, uint16_t timeo volatile 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)) { + if (upTo >= dma->buf + DMA_BUFFER_SIZE) { // we have read all of the DMA buffer content. + upTo = dma->buf; // start reading the circular buffer from the beginning + if (behindBy > (9 * DMA_BUFFER_SIZE / 10)) { Dbprintf("About to blow circular buffer - aborted! behindBy=%d", behindBy); ret = -1; break; } } - if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_ENDRX)) { // DMA Counter Register had reached 0, already rotated. - AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) dmaBuf; // refresh the DMA Next Buffer and - AT91C_BASE_PDC_SSC->PDC_RNCR = ISO15693_DMA_BUFFER_SIZE; // DMA Next Counter registers + if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_ENDRX)) { // DMA Counter Register had reached 0, already rotated. + AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) dma->buf; // refresh the DMA Next Buffer and + AT91C_BASE_PDC_SSC->PDC_RNCR = DMA_BUFFER_SIZE; // DMA Next Counter registers } if (Handle15693SamplesFromTag(tagdata, &DecodeTag)) { @@ -1016,8 +1020,6 @@ int GetIso15693CommandFromReader(uint8_t *received, size_t max_len, uint32_t *eo int samples = 0; bool gotFrame = false; - uint8_t dmaBuf[ISO15693_DMA_BUFFER_SIZE] = {0}; - // the decoder data structure DecodeReader_t DecodeReader = {0}; DecodeReaderInit(&DecodeReader, received, max_len, 0, NULL); @@ -1036,25 +1038,26 @@ int GetIso15693CommandFromReader(uint8_t *received, size_t max_len, uint32_t *eo uint32_t dma_start_time = GetCountSspClk() & 0xfffffff8; // Setup and start DMA. - FpgaSetupSscDma(dmaBuf, ISO15693_DMA_BUFFER_SIZE); - uint8_t *upTo = dmaBuf; + dmabuf8_t *dma = get_dma8(); + FpgaSetupSscDma(dma->buf, DMA_BUFFER_SIZE); + uint8_t *upTo = dma->buf; for (;;) { - uint16_t behindBy = ((uint8_t*)AT91C_BASE_PDC_SSC->PDC_RPR - upTo) & (ISO15693_DMA_BUFFER_SIZE - 1); + uint16_t behindBy = ((uint8_t*)AT91C_BASE_PDC_SSC->PDC_RPR - upTo) & (DMA_BUFFER_SIZE - 1); if (behindBy == 0) continue; volatile uint8_t b = *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)) { + if (upTo >= dma->buf + DMA_BUFFER_SIZE) { // we have read all of the DMA buffer content. + upTo = dma->buf; // start reading the circular buffer from the beginning + if (behindBy > (9 * DMA_BUFFER_SIZE / 10)) { Dbprintf("About to blow circular buffer - aborted! behindBy %d", behindBy); break; } } if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_ENDRX)) { // DMA Counter Register had reached 0, already rotated. - AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) dmaBuf; // refresh the DMA Next Buffer and - AT91C_BASE_PDC_SSC->PDC_RNCR = ISO15693_DMA_BUFFER_SIZE; // DMA Next Counter registers + AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) dma->buf; // refresh the DMA Next Buffer and + AT91C_BASE_PDC_SSC->PDC_RNCR = DMA_BUFFER_SIZE; // DMA Next Counter registers } for (int i = 7; i >= 0; i--) { @@ -1146,12 +1149,8 @@ void SniffIso15693(uint8_t jam_search_len, uint8_t *jam_search_string) { clear_trace(); set_tracing(true); - - // The DMA buffer, used to stream samples from the FPGA - uint16_t dmaBuf[ISO15693_DMA_BUFFER_SIZE] = {0}; - + // Count of samples received so far, so that we can include timing - // information in the trace buffer. int samples = 0; DecodeTag_t DecodeTag = {0}; @@ -1168,29 +1167,32 @@ void SniffIso15693(uint8_t jam_search_len, uint8_t *jam_search_string) { Dbprintf(" Trace: %i bytes", BigBuf_max_traceLen()); Dbprintf(" Reader -> tag: %i bytes", ISO15693_MAX_COMMAND_LENGTH); Dbprintf(" tag -> Reader: %i bytes", ISO15693_MAX_RESPONSE_LENGTH); - Dbprintf(" DMA: %i bytes", ISO15693_DMA_BUFFER_SIZE * sizeof(uint16_t)); + Dbprintf(" DMA: %i bytes", DMA_BUFFER_SIZE * sizeof(uint16_t)); } Dbprintf("Sniff started. Press PM3 Button to stop."); FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER | FPGA_HF_READER_MODE_SNIFF_AMPLITUDE); LED_D_OFF(); + SetAdcMuxFor(GPIO_MUXSEL_HIPKD); FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER); StartCountSspClk(); - FpgaSetupSscDma((uint8_t*) dmaBuf, ISO15693_DMA_BUFFER_SIZE); + + // The DMA buffer, used to stream samples from the FPGA + dmabuf16_t *dma = get_dma16(); + FpgaSetupSscDma((uint8_t*)dma->buf, DMA_BUFFER_SIZE); + uint16_t *upTo = dma->buf; bool TagIsActive = false; bool ReaderIsActive = false; bool ExpectTagAnswer = false; uint32_t dma_start_time = 0; - uint16_t *upTo = dmaBuf; - uint16_t max_behindBy = 0; // And now we loop, receiving samples. for(;;) { - uint16_t behindBy = ((uint16_t*)AT91C_BASE_PDC_SSC->PDC_RPR - upTo) & (ISO15693_DMA_BUFFER_SIZE-1); + uint16_t behindBy = ((uint16_t*)AT91C_BASE_PDC_SSC->PDC_RPR - upTo) & (DMA_BUFFER_SIZE - 1); if (behindBy > max_behindBy) { max_behindBy = behindBy; } @@ -1204,17 +1206,16 @@ void SniffIso15693(uint8_t jam_search_len, uint8_t *jam_search_string) { } uint16_t sniffdata = *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)) { - + + if (upTo >= dma->buf + DMA_BUFFER_SIZE) { // we have read all of the DMA buffer content. + upTo = dma->buf; // start reading the circular buffer from the beginning + if (behindBy > (9 * DMA_BUFFER_SIZE / 10)) { Dbprintf("About to blow circular buffer - aborted! behindBy=%d, samples=%d", behindBy, samples); break; } - if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_ENDRX)) { // DMA Counter Register had reached 0, already rotated. - AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) dmaBuf; // refresh the DMA Next Buffer and - AT91C_BASE_PDC_SSC->PDC_RNCR = ISO15693_DMA_BUFFER_SIZE; // DMA Next Counter registers + if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_ENDRX)) { // DMA Counter Register had reached 0, already rotated. + AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) dma->buf; // refresh the DMA Next Buffer and + AT91C_BASE_PDC_SSC->PDC_RNCR = DMA_BUFFER_SIZE; // DMA Next Counter registers WDT_HIT(); if (BUTTON_PRESS()) { DbpString("Sniff stopped.");