fix cotag memory bugs. was off-by-one

This commit is contained in:
iceman1001 2020-08-25 15:34:10 +02:00
commit 32c614db7b
4 changed files with 81 additions and 89 deletions

View file

@ -27,6 +27,7 @@
#include "protocols.h" #include "protocols.h"
#include "pmflash.h" #include "pmflash.h"
#include "flashmem.h" // persistence on flash #include "flashmem.h" // persistence on flash
#include "appmain.h" // print stack
/* /*
Notes about EM4xxx timings. Notes about EM4xxx timings.
@ -2611,44 +2612,53 @@ void Cotag(uint32_t arg0) {
LED_A_ON(); LED_A_ON();
LFSetupFPGAForADC(LF_FREQ2DIV(132), true); LFSetupFPGAForADC(LF_DIVISOR_125, true);
//clear buffer now so it does not interfere with timing later //clear buffer now so it does not interfere with timing later
BigBuf_free(); BigBuf_free();
BigBuf_Clear_ext(false); BigBuf_Clear_ext(false);
//send COTAG start pulse //send COTAG start pulse
/*
ON(740) OFF(2035) ON(740) OFF(2035)
ON(3330) OFF(2035) ON(3330) OFF(2035)
ON(740) OFF(2035) ON(740) OFF(2035)
ON(1000) ON(1000)
*/
/*
ON(800) OFF(2200) ON(800) OFF(2200)
ON(3600) OFF(2200) ON(3600) OFF(2200)
ON(800) OFF(2200) ON(800) OFF(2200)
ON(3400) ON(3400)
*/
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, LF_FREQ2DIV(125));
switch (rawsignal) { switch (rawsignal) {
case 0: case 0: {
doCotagAcquisition(); doCotagAcquisition();
reply_ng(CMD_LF_COTAG_READ, PM3_SUCCESS, NULL, 0);
break; break;
case 1: }
doCotagAcquisitionManchester(); case 1: {
uint8_t *dest = BigBuf_malloc(COTAG_BITS);
uint16_t bits = doCotagAcquisitionManchester(dest, COTAG_BITS);
reply_ng(CMD_LF_COTAG_READ, PM3_SUCCESS, dest, bits);
break; break;
}
case 2: { case 2: {
DoAcquisition_config(false, 0); DoAcquisition_config(false, 0);
reply_ng(CMD_LF_COTAG_READ, PM3_SUCCESS, NULL, 0);
break;
}
default: {
reply_ng(CMD_LF_COTAG_READ, PM3_SUCCESS, NULL, 0);
break; break;
} }
} }
// Turn the field off // Turn the field off
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
reply_ng(CMD_LF_COTAG_READ, PM3_SUCCESS, NULL, 0);
LEDsoff(); LEDsoff();
} }
/* /*

View file

@ -236,15 +236,15 @@ void LFSetupFPGAForADC(int divisor, bool reader_field) {
// Connect the A/D to the peak-detected low-frequency path. // Connect the A/D to the peak-detected low-frequency path.
SetAdcMuxFor(GPIO_MUXSEL_LOPKD); SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
// 50ms for the resonant antenna to settle.
if (reader_field)
SpinDelay(50);
// Now set up the SSC to get the ADC samples that are now streaming at us. // Now set up the SSC to get the ADC samples that are now streaming at us.
FpgaSetupSsc(FPGA_MAJOR_MODE_LF_READER); FpgaSetupSsc(FPGA_MAJOR_MODE_LF_READER);
// start a 1.5ticks is 1us // start a 1.5ticks is 1us
StartTicks(); StartTicks();
// 50ms for the resonant antenna to settle.
if (reader_field)
WaitMS(50);
} }
/** /**
@ -277,9 +277,9 @@ uint32_t DoAcquisition(uint8_t decimation, uint8_t bits_per_sample, bool avg, in
while (BUTTON_PRESS() == false) { while (BUTTON_PRESS() == false) {
// only every 1000th times, in order to save time when collecting samples. // only every 4000th times, in order to save time when collecting samples.
// interruptible only when logging not yet triggered // interruptible only when logging not yet triggered
if ((checked == 4000) && (trigger_threshold > 0)) { if ((checked >= 4000) && (trigger_threshold > 0)) {
if (data_available()) { if (data_available()) {
checked = -1; checked = -1;
break; break;
@ -480,26 +480,22 @@ void doT55x7Acquisition(size_t sample_size) {
#define COTAG_T1 384 #define COTAG_T1 384
#define COTAG_T2 (COTAG_T1 >> 1) #define COTAG_T2 (COTAG_T1 >> 1)
#define COTAG_ONE_THRESHOLD 128+5 #define COTAG_ONE_THRESHOLD 127+5
#define COTAG_ZERO_THRESHOLD 128-5 #define COTAG_ZERO_THRESHOLD 127-5
#ifndef COTAG_BITS #ifndef COTAG_BITS
#define COTAG_BITS 264 #define COTAG_BITS 264
#endif #endif
void doCotagAcquisition() { void doCotagAcquisition(void) {
uint8_t *dest = BigBuf_get_addr();
uint16_t bufsize = BigBuf_max_traceLen(); uint16_t bufsize = BigBuf_max_traceLen();
uint8_t *dest = BigBuf_malloc(bufsize);
dest[0] = 0; dest[0] = 0;
uint8_t firsthigh = 0, firstlow = 0;
bool firsthigh = false, firstlow = false;
uint16_t i = 0, noise_counter = 0; uint16_t i = 0, noise_counter = 0;
if (DBGLEVEL >= DBG_DEBUG) { while ((i < bufsize) && (noise_counter < COTAG_T1 << 1)) {
Dbprintf("doCotagAcquisition - after init");
print_stack_usage();
}
while ((i < bufsize) && (noise_counter < (COTAG_T1 << 1))) {
if (BUTTON_PRESS()) if (BUTTON_PRESS())
break; break;
@ -507,93 +503,79 @@ void doCotagAcquisition() {
WDT_HIT(); WDT_HIT();
if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) {
volatile uint8_t sample = (uint8_t)AT91C_BASE_SSC->SSC_RHR; volatile uint8_t sample = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
// find first peak // find first peak
if (!firsthigh) { if (firsthigh == false) {
if (sample < COTAG_ONE_THRESHOLD) { if (sample < COTAG_ONE_THRESHOLD) {
noise_counter++; noise_counter++;
continue; continue;
} }
noise_counter = 0; noise_counter = 0;
firsthigh = 1; firsthigh = true;
} }
if (!firstlow) {
if (firstlow == false) {
if (sample > COTAG_ZERO_THRESHOLD) { if (sample > COTAG_ZERO_THRESHOLD) {
noise_counter++; noise_counter++;
continue; continue;
} }
noise_counter = 0; noise_counter = 0;
firstlow = 1; firstlow = true;
} }
++i; if (++i < bufsize) {
if (sample > COTAG_ONE_THRESHOLD) {
if (sample > COTAG_ONE_THRESHOLD)
dest[i] = 255; dest[i] = 255;
else if (sample < COTAG_ZERO_THRESHOLD) } else if (sample < COTAG_ZERO_THRESHOLD) {
dest[i] = 0; dest[i] = 0;
else } else {
dest[i] = dest[i - 1]; dest[i] = dest[i - 1];
} }
} }
}
Dbprintf("doCotagAcquisition - %u high %u == 1 low %u == 1", i, firsthigh, firstlow); }
// Ensure that DC offset removal and noise check is performed for any device-side processing // Ensure that DC offset removal and noise check is performed for any device-side processing
removeSignalOffset(dest, bufsize); removeSignalOffset(dest, i);
printSamples(); computeSignalProperties(dest, i);
computeSignalProperties(dest, bufsize);
printSamples();
} }
uint32_t doCotagAcquisitionManchester(void) { uint16_t doCotagAcquisitionManchester(uint8_t *dest, uint16_t destlen) {
uint8_t *dest = BigBuf_get_addr(); if (dest == NULL)
uint16_t bufsize = MIN(COTAG_BITS, BigBuf_max_traceLen()); return 0;
dest[0] = 0; dest[0] = 0;
uint8_t firsthigh = 0, firstlow = 0;
bool firsthigh = false, firstlow = false;
uint8_t curr = 0, prev = 0; uint8_t curr = 0, prev = 0;
uint16_t sample_counter = 0, period = 0; uint16_t i = 0;
uint16_t noise_counter = 0; uint16_t period = 0;
if (DBGLEVEL >= DBG_DEBUG) { while ((i < destlen) && BUTTON_PRESS() == false) {
Dbprintf("doCotagAcquisitionManchester - after init");
print_stack_usage();
}
while ((sample_counter < bufsize) && (noise_counter < (COTAG_T1 << 1))) {
if (BUTTON_PRESS())
break;
WDT_HIT(); WDT_HIT();
if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) {
LED_D_ON();
}
if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) {
volatile uint8_t sample = (uint8_t)AT91C_BASE_SSC->SSC_RHR; volatile uint8_t sample = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
// find first peak // find first peak
if (!firsthigh) { if (firsthigh == false) {
if (sample < COTAG_ONE_THRESHOLD) { if (sample < COTAG_ONE_THRESHOLD) {
noise_counter++;
continue; continue;
} }
noise_counter = 0; firsthigh = true;
firsthigh = 1;
} }
if (!firstlow) { if (firstlow == false) {
if (sample > COTAG_ZERO_THRESHOLD) { if (sample > COTAG_ZERO_THRESHOLD) {
noise_counter++;
continue; continue;
} }
noise_counter = 0; firstlow = true;
firstlow = 1;
} }
// set sample 255, 0, or previous // set sample 255, 0, or previous
@ -613,10 +595,11 @@ uint32_t doCotagAcquisitionManchester(void) {
continue; continue;
} }
dest[sample_counter] = curr; dest[i] = curr;
++sample_counter; ++i;
period = COTAG_T1; period = COTAG_T1;
} }
} }
return sample_counter;
return i;
} }

View file

@ -22,7 +22,7 @@ typedef struct {
* and is Manchester?, we directly gather the manchester data into bigbuff * and is Manchester?, we directly gather the manchester data into bigbuff
**/ **/
void doCotagAcquisition(void); void doCotagAcquisition(void);
uint32_t doCotagAcquisitionManchester(void); uint16_t doCotagAcquisitionManchester(uint8_t *dest, uint16_t destlen);
/** /**
* acquisition of T55x7 LF signal. Similar to other LF, but adjusted with @marshmellows thresholds * acquisition of T55x7 LF signal. Similar to other LF, but adjusted with @marshmellows thresholds

View file

@ -84,9 +84,11 @@ static int CmdCOTAGRead(const char *Cmd) {
uint32_t rawsignal = 1; uint32_t rawsignal = 1;
sscanf(Cmd, "%u", &rawsignal); sscanf(Cmd, "%u", &rawsignal);
PacketResponseNG resp;
clearCommandBuffer(); clearCommandBuffer();
SendCommandMIX(CMD_LF_COTAG_READ, rawsignal, 0, 0, NULL, 0); SendCommandMIX(CMD_LF_COTAG_READ, rawsignal, 0, 0, NULL, 0);
if (!WaitForResponseTimeout(CMD_LF_COTAG_READ, NULL, 7000)) {
if (!WaitForResponseTimeout(CMD_LF_COTAG_READ, &resp, 7000)) {
PrintAndLogEx(WARNING, "command execution time out"); PrintAndLogEx(WARNING, "command execution time out");
return PM3_ETIMEOUT; return PM3_ETIMEOUT;
} }
@ -100,11 +102,8 @@ static int CmdCOTAGRead(const char *Cmd) {
break; break;
} }
case 1: { case 1: {
PrintAndLogEx(INFO, "ICE_:: bits %u", resp.length);
if (!GetFromDevice(BIG_BUF, DemodBuffer, COTAG_BITS, 0, NULL, 0, NULL, 1000, false)) { memcpy(DemodBuffer, resp.data.asBytes, COTAG_BITS);
PrintAndLogEx(WARNING, "timeout while waiting for reply.");
return PM3_ETIMEOUT;
}
DemodBufferLen = COTAG_BITS; DemodBufferLen = COTAG_BITS;
return CmdCOTAGDemod(""); return CmdCOTAGDemod("");
} }