unified static dma buffer as bigbuf_malloc, less pressure on stack size

This commit is contained in:
iceman1001 2020-07-15 15:16:35 +02:00
commit 3354f0d9d3
5 changed files with 194 additions and 175 deletions

View file

@ -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;
}

View file

@ -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 */

View file

@ -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();
}

View file

@ -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();

View file

@ -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.");