fix cotag memory bugs. was off-by-one

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

View file

@ -27,6 +27,7 @@
#include "protocols.h"
#include "pmflash.h"
#include "flashmem.h" // persistence on flash
#include "appmain.h" // print stack
/*
Notes about EM4xxx timings.
@ -2611,44 +2612,53 @@ void Cotag(uint32_t arg0) {
LED_A_ON();
LFSetupFPGAForADC(LF_FREQ2DIV(132), true);
LFSetupFPGAForADC(LF_DIVISOR_125, true);
//clear buffer now so it does not interfere with timing later
BigBuf_free();
BigBuf_Clear_ext(false);
//send COTAG start pulse
/*
ON(740) OFF(2035)
ON(3330) OFF(2035)
ON(740) OFF(2035)
ON(1000)
*/
ON(740) OFF(2035)
ON(3330) OFF(2035)
ON(740) OFF(2035)
ON(1000)
/*
ON(800) OFF(2200)
ON(3600) OFF(2200)
ON(800) OFF(2200)
ON(3400)
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, LF_FREQ2DIV(125));
*/
switch (rawsignal) {
case 0:
case 0: {
doCotagAcquisition();
reply_ng(CMD_LF_COTAG_READ, PM3_SUCCESS, NULL, 0);
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;
}
case 2: {
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;
}
}
// Turn the field off
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off
reply_ng(CMD_LF_COTAG_READ, PM3_SUCCESS, NULL, 0);
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
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.
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.
FpgaSetupSsc(FPGA_MAJOR_MODE_LF_READER);
// start a 1.5ticks is 1us
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) {
// 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
if ((checked == 4000) && (trigger_threshold > 0)) {
if ((checked >= 4000) && (trigger_threshold > 0)) {
if (data_available()) {
checked = -1;
break;
@ -479,27 +479,23 @@ void doT55x7Acquisition(size_t sample_size) {
**/
#define COTAG_T1 384
#define COTAG_T2 (COTAG_T1>>1)
#define COTAG_ONE_THRESHOLD 128+5
#define COTAG_ZERO_THRESHOLD 128-5
#define COTAG_T2 (COTAG_T1 >> 1)
#define COTAG_ONE_THRESHOLD 127+5
#define COTAG_ZERO_THRESHOLD 127-5
#ifndef COTAG_BITS
#define COTAG_BITS 264
#endif
void doCotagAcquisition() {
void doCotagAcquisition(void) {
uint8_t *dest = BigBuf_get_addr();
uint16_t bufsize = BigBuf_max_traceLen();
uint8_t *dest = BigBuf_malloc(bufsize);
dest[0] = 0;
uint8_t firsthigh = 0, firstlow = 0;
bool firsthigh = false, firstlow = false;
uint16_t i = 0, noise_counter = 0;
if (DBGLEVEL >= DBG_DEBUG) {
Dbprintf("doCotagAcquisition - after init");
print_stack_usage();
}
while ((i < bufsize) && (noise_counter < (COTAG_T1 << 1))) {
while ((i < bufsize) && (noise_counter < COTAG_T1 << 1)) {
if (BUTTON_PRESS())
break;
@ -507,93 +503,79 @@ void doCotagAcquisition() {
WDT_HIT();
if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) {
volatile uint8_t sample = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
// find first peak
if (!firsthigh) {
if (firsthigh == false) {
if (sample < COTAG_ONE_THRESHOLD) {
noise_counter++;
continue;
}
noise_counter = 0;
firsthigh = 1;
firsthigh = true;
}
if (!firstlow) {
if (firstlow == false) {
if (sample > COTAG_ZERO_THRESHOLD) {
noise_counter++;
continue;
}
noise_counter = 0;
firstlow = 1;
firstlow = true;
}
++i;
if (sample > COTAG_ONE_THRESHOLD)
dest[i] = 255;
else if (sample < COTAG_ZERO_THRESHOLD)
dest[i] = 0;
else
dest[i] = dest[i - 1];
if (++i < bufsize) {
if (sample > COTAG_ONE_THRESHOLD) {
dest[i] = 255;
} else if (sample < COTAG_ZERO_THRESHOLD) {
dest[i] = 0;
} else {
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
removeSignalOffset(dest, bufsize);
printSamples();
computeSignalProperties(dest, bufsize);
printSamples();
removeSignalOffset(dest, i);
computeSignalProperties(dest, i);
}
uint32_t doCotagAcquisitionManchester(void) {
uint8_t *dest = BigBuf_get_addr();
uint16_t bufsize = MIN(COTAG_BITS, BigBuf_max_traceLen());
uint16_t doCotagAcquisitionManchester(uint8_t *dest, uint16_t destlen) {
if (dest == NULL)
return 0;
dest[0] = 0;
uint8_t firsthigh = 0, firstlow = 0;
bool firsthigh = false, firstlow = false;
uint8_t curr = 0, prev = 0;
uint16_t sample_counter = 0, period = 0;
uint16_t noise_counter = 0;
uint16_t i = 0;
uint16_t period = 0;
if (DBGLEVEL >= DBG_DEBUG) {
Dbprintf("doCotagAcquisitionManchester - after init");
print_stack_usage();
}
while ((sample_counter < bufsize) && (noise_counter < (COTAG_T1 << 1))) {
if (BUTTON_PRESS())
break;
while ((i < destlen) && BUTTON_PRESS() == false) {
WDT_HIT();
if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) {
LED_D_ON();
}
if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) {
volatile uint8_t sample = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
// find first peak
if (!firsthigh) {
if (firsthigh == false) {
if (sample < COTAG_ONE_THRESHOLD) {
noise_counter++;
continue;
}
noise_counter = 0;
firsthigh = 1;
firsthigh = true;
}
if (!firstlow) {
if (firstlow == false) {
if (sample > COTAG_ZERO_THRESHOLD) {
noise_counter++;
continue;
}
noise_counter = 0;
firstlow = 1;
firstlow = true;
}
// set sample 255, 0, or previous
@ -613,10 +595,11 @@ uint32_t doCotagAcquisitionManchester(void) {
continue;
}
dest[sample_counter] = curr;
++sample_counter;
dest[i] = curr;
++i;
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
**/
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

View file

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