diff --git a/armsrc/lfsampling.c b/armsrc/lfsampling.c index 96963d389..4b036d088 100644 --- a/armsrc/lfsampling.c +++ b/armsrc/lfsampling.c @@ -204,8 +204,9 @@ uint32_t DoAcquisition(uint8_t decimation, uint32_t bits_per_sample, bool averag dest[0], dest[1], dest[2], dest[3], dest[4], dest[5], dest[6], dest[7]); } - // Ensure that noise check is performed for any device-side processing - isNoise(dest, bufsize); + // Ensure that DC offset removal and noise check is performed for any device-side processing + removeSignalOffset(dest, bufsize); + computeSignalProperties(dest, bufsize); return data.numbits; } @@ -451,4 +452,4 @@ uint32_t doCotagAcquisitionManchester() { } } return sample_counter; -} \ No newline at end of file +} diff --git a/client/cmddata.c b/client/cmddata.c index ba3d61156..fc34f3e80 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -1393,15 +1393,13 @@ int CmdHide(const char *Cmd) { //zero mean GraphBuffer int CmdHpf(const char *Cmd) { - int i, accum = 0; - - for (i = 10; i < GraphTraceLen; ++i) - accum += GraphBuffer[i]; - - accum /= (GraphTraceLen - 10); - - for (i = 0; i < GraphTraceLen; ++i) - GraphBuffer[i] -= accum; + uint8_t bits[GraphTraceLen]; + size_t size = getFromGraphBuf(bits); + removeSignalOffset(bits, size); + // push it back to graph + setGraphBuf(bits, size); + // set signal properties low/high/mean/amplitude and is_noise detection + computeSignalProperties(bits, size); RepaintGraphWindow(); return 0; @@ -1471,12 +1469,11 @@ int getSamples(int n, bool silent) { GraphTraceLen = n; } - //ICEMAN todo uint8_t bits[GraphTraceLen]; size_t size = getFromGraphBuf(bits); - // set signal properties low/high/mean/amplitude and is_noice detection - isNoise(bits, size); - + // set signal properties low/high/mean/amplitude and is_noise detection + computeSignalProperties(bits, size); + setClockGrid(0, 0); DemodBufferLen = 0; RepaintGraphWindow(); @@ -1610,15 +1607,19 @@ int CmdLoad(const char *Cmd) { fclose(f); PrintAndLogEx(SUCCESS, "loaded %d samples", GraphTraceLen); + + uint8_t bits[GraphTraceLen]; + size_t size = getFromGraphBuf(bits); + // set signal properties low/high/mean/amplitude and is_noise detection + removeSignalOffset(bits, size); + // push it back to graph + setGraphBuf(bits, size); + // set signal properties low/high/mean/amplitude and is_noise detection + computeSignalProperties(bits, size); + setClockGrid(0,0); DemodBufferLen = 0; RepaintGraphWindow(); - - //ICEMAN todo - // set signal properties low/high/mean/amplitude and isnoice detection - uint8_t bits[GraphTraceLen]; - size_t size = getFromGraphBuf(bits); - isNoise(bits, size); return 0; } @@ -1683,11 +1684,11 @@ int CmdNorm(const char *Cmd) { } } - //ICEMAN todo - // set signal properties low/high/mean/amplitude and isnoice detection uint8_t bits[GraphTraceLen]; size_t size = getFromGraphBuf(bits); - isNoise(bits, size); + // set signal properties low/high/mean/amplitude and is_noise detection + computeSignalProperties(bits, size); + RepaintGraphWindow(); return 0; } @@ -1773,11 +1774,11 @@ int CmdDirectionalThreshold(const char *Cmd) { directionalThreshold(GraphBuffer, GraphBuffer, GraphTraceLen, up, down); - //ICEMAN todo // set signal properties low/high/mean/amplitude and isnoice detection uint8_t bits[GraphTraceLen]; size_t size = getFromGraphBuf(bits); - isNoise(bits, size); + // set signal properties low/high/mean/amplitude and is_noice detection + computeSignalProperties(bits, size); RepaintGraphWindow(); return 0; @@ -1805,11 +1806,10 @@ int CmdZerocrossings(const char *Cmd) { } } - //ICEMAN todo - // set signal properties low/high/mean/amplitude and isnoice detection uint8_t bits[GraphTraceLen]; size_t size = getFromGraphBuf(bits); - isNoise(bits, size); + // set signal properties low/high/mean/amplitude and is_noise detection + computeSignalProperties(bits, size); RepaintGraphWindow(); return 0; @@ -2063,13 +2063,11 @@ int CmdDataIIR(const char *Cmd){ //iceIIR_Butterworth(GraphBuffer, GraphTraceLen); iceSimple_Filter(GraphBuffer, GraphTraceLen, k); - //ICEMAN todo - // set signal properties low/high/mean/amplitude and isnoice detection uint8_t bits[GraphTraceLen]; size_t size = getFromGraphBuf(bits); - isNoise(bits, size); - - RepaintGraphWindow(); + // set signal properties low/high/mean/amplitude and is_noise detection + computeSignalProperties(bits, size); + RepaintGraphWindow(); return 0; } diff --git a/client/cmdlfem4x.c b/client/cmdlfem4x.c index 6d90e550f..8b9530957 100644 --- a/client/cmdlfem4x.c +++ b/client/cmdlfem4x.c @@ -800,7 +800,7 @@ int EM4x50Read(const char *Cmd, bool verbose) { uint8_t bits[MAX_GRAPH_TRACE_LEN] = {0}; size_t size = getFromGraphBuf(bits); - isNoise(bits, size); + computeSignalProperties(bits, size); signal_t *sp = getSignalProperties(); high = sp->high; @@ -999,9 +999,12 @@ bool downloadSamplesEM(){ PrintAndLogEx(WARNING, "command execution time out"); return false; } - setGraphBuf(got, sizeof(got)); - if (isNoise(got, sizeof(got))) { + setGraphBuf(got, sizeof(got)); + // set signal properties low/high/mean/amplitude and is_noise detection + computeSignalProperties(got, sizeof(got)); + RepaintGraphWindow(); + if (getSignalProperties()->isnoise) { PrintAndLogEx(DEBUG, "No tag found"); return false; } diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index ac92c119b..9a1e6cc71 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -1331,7 +1331,10 @@ bool AquireData( uint8_t page, uint8_t block, bool pwdmode, uint32_t password ) return false; } setGraphBuf(got, sizeof(got)); - return !isNoise(got, sizeof(got)); + // set signal properties low/high/mean/amplitude and is_noise detection + computeSignalProperties(got, sizeof(got)); + RepaintGraphWindow(); + return !getSignalProperties()->isnoise; } char * GetBitRateStr(uint32_t id, bool xmode) { diff --git a/client/comms.c b/client/comms.c index 5beaa0adb..f08c5f413 100644 --- a/client/comms.c +++ b/client/comms.c @@ -463,7 +463,7 @@ bool GetFromDevice(DeviceMemType_t memtype, uint8_t *dest, uint32_t bytes, uint3 return dl_it(dest, bytes, start_index, response, ms_timeout, show_warning, CMD_FLASHMEM_DOWNLOADED); } case SIM_MEM: { - //UsbCommand c = {CMD_DOWNLOAND_SIM_MEM, {start_index, bytes, 0}}; + //UsbCommand c = {CMD_DOWNLOAD_SIM_MEM, {start_index, bytes, 0}}; //SendCommand(&c); //return dl_it(dest, bytes, start_index, response, ms_timeout, show_warning, CMD_DOWNLOADED_SIMMEM); return false; diff --git a/common/lfdemod.c b/common/lfdemod.c index 1fd69d1b9..b9807ff8f 100644 --- a/common/lfdemod.c +++ b/common/lfdemod.c @@ -47,8 +47,7 @@ //********************************************************************************************** #define LOWEST_DEFAULT_CLOCK 32 #define FSK_PSK_THRESHOLD 123 -//might not be high enough for noisy environments -#define NOICE_AMPLITUDE_THRESHOLD 10 + //to allow debug print calls when used not on dev //void dummy(char *fmt, ...){} @@ -76,6 +75,7 @@ static void resetSignal(void) { signalprop.amplitude = 0; signalprop.isnoise = true; } + static void printSignal(void) { prnt("LF signal properties:"); prnt(" high..........%d", signalprop.high); @@ -83,94 +83,47 @@ static void printSignal(void) { prnt(" mean..........%d", signalprop.mean); prnt(" amplitude.....%d", signalprop.amplitude); prnt(" is Noise......%s", (signalprop.isnoise) ? "Yes" : "No"); - prnt(" THRESHOLD noice amplitude......%d" , NOICE_AMPLITUDE_THRESHOLD); + prnt(" THRESHOLD noise amplitude......%d" , NOISE_AMPLITUDE_THRESHOLD); } -// Function to compute mean for a series -// rounded to integer.. -uint32_t compute_mean_uint(uint8_t *in, size_t N) { - uint32_t mean = 0; - for (size_t i = 0; i < N; i++) - mean += in[i]; - - return mean / N; -} -// Function to compute mean for a series -// rounded to integer.. -int32_t compute_mean_int(int *in, size_t N) { - int32_t mean = 0; - for (size_t i = 0; i < N; i++) - mean += in[i]; - - return mean / (int)N; -} - -void zeromean(uint8_t* data, size_t size) { - - // zero mean data - int i, accum = 0; - for (i = 10; i < size; ++i) - accum += data[i] - 128; - accum /= (int)(size - 10); - - for (i = 0; i < size; ++i) { - if (accum > 0) { - data[i] = (data[i] >= accum)? data[i] - accum : 0; - } - if (accum < 0) { - data[i] = (255 - data[i] >= -accum)? data[i] - accum : 255; - } - } - // recompute signal characteristics: - isNoise(data, size); -} - -//test samples are not just noise -// By measuring mean and look at amplitude of signal from HIGH / LOW, we can detect noise -bool isNoise_int(int *bits, uint32_t size) { +void computeSignalProperties(uint8_t *samples, uint32_t size) { resetSignal(); - if ( bits == NULL || size < 100 ) return true; - - int32_t sum = 0; - for ( size_t i = 0; i < size; i++) { - if ( bits[i] < signalprop.low ) signalprop.low = bits[i]; - if ( bits[i] > signalprop.high ) signalprop.high = bits[i]; - sum += bits[i]; - } - // measure amplitude of signal - signalprop.mean = sum / (int)size; - signalprop.amplitude = ABS(signalprop.high - signalprop.mean); - signalprop.isnoise = signalprop.amplitude < NOICE_AMPLITUDE_THRESHOLD; - - if (g_debugMode) - printSignal(); - - return signalprop.isnoise; -} -//test samples are not just noise -// By measuring mean and look at amplitude of signal from HIGH / LOW, -// we can detect noise -bool isNoise(uint8_t *bits, uint32_t size) { - resetSignal(); - if ( bits == NULL || size < 100 ) return true; - uint32_t sum = 0; for ( uint32_t i = 0; i < size; i++) { - if ( bits[i] < signalprop.low ) signalprop.low = bits[i]; - if ( bits[i] > signalprop.high ) signalprop.high = bits[i]; - sum += bits[i]; + if ( samples[i] < signalprop.low ) signalprop.low = samples[i]; + if ( samples[i] > signalprop.high ) signalprop.high = samples[i]; + sum += samples[i]; } // measure amplitude of signal signalprop.mean = sum / size; signalprop.amplitude = signalprop.high - signalprop.mean; - signalprop.isnoise = signalprop.amplitude < NOICE_AMPLITUDE_THRESHOLD; - + // By measuring mean and look at amplitude of signal from HIGH / LOW, + // we can detect noise + signalprop.isnoise = signalprop.amplitude < NOISE_AMPLITUDE_THRESHOLD; + if (g_debugMode) printSignal(); +} - return signalprop.isnoise; +void removeSignalOffset(uint8_t *samples, uint32_t size) { + if ( samples == NULL || size < SIGNAL_MIN_SAMPLES ) return; + + int acc_off = 0; + for (uint32_t i = SIGNAL_IGNORE_FIRST_SAMPLES; i < size; i++) + acc_off += samples[i] - 128; + acc_off /= (int)(size - SIGNAL_IGNORE_FIRST_SAMPLES); + + // shift and saturate samples to center the mean + for ( uint32_t i = 0; i < size; i++) { + if (acc_off > 0) { + samples[i] = (samples[i] >= acc_off)? samples[i] - acc_off : 0; + } + if (acc_off < 0) { + samples[i] = (255 - samples[i] >= -acc_off)? samples[i] - acc_off : 255; + } + } } //by marshmellow @@ -1962,8 +1915,6 @@ int detectAWID(uint8_t *dest, size_t *size, int *waveStartIdx) { if (signalprop.isnoise) return -2; - zeromean(dest, *size); - // FSK2a demodulator clock 50, invert 1, fcHigh 10, fcLow 8 *size = fskdemod(dest, *size, 50, 1, 10, 8, waveStartIdx); //awid fsk2a @@ -2029,8 +1980,6 @@ int HIDdemodFSK(uint8_t *dest, size_t *size, uint32_t *hi2, uint32_t *hi, uint32 if (signalprop.isnoise) return -2; - zeromean(dest, *size); - // FSK demodulator fsk2a so invert and fc/10/8 *size = fskdemod(dest, *size, 50, 1, 10, 8, waveStartIdx); //hid fsk2a @@ -2090,8 +2039,6 @@ int detectIOProx(uint8_t *dest, size_t *size, int *waveStartIdx) { if (signalprop.isnoise) return -2; - zeromean(dest, *size); - // FSK demodulator RF/64, fsk2a so invert, and fc/10/8 *size = fskdemod(dest, *size, 64, 1, 10, 8, waveStartIdx); //io fsk2a diff --git a/common/lfdemod.h b/common/lfdemod.h index 43537b18b..a6542059e 100644 --- a/common/lfdemod.h +++ b/common/lfdemod.h @@ -20,6 +20,14 @@ #include // for bool #include "parity.h" // for parity test #include "util.h" // for ARRAYLEN + +//might not be high enough for noisy environments +#define NOISE_AMPLITUDE_THRESHOLD 10 +//ignore buffer with less than x samples +#define SIGNAL_MIN_SAMPLES 100 +//ignore first x samples of the buffer +#define SIGNAL_IGNORE_FIRST_SAMPLES 10 + //generic typedef struct { int low; @@ -28,14 +36,10 @@ typedef struct { int amplitude; bool isnoise; } signal_t; -extern signal_t* getSignalProperties(void); +signal_t* getSignalProperties(void); -extern uint32_t compute_mean_uint(uint8_t *in, size_t N); -extern int32_t compute_mean_int(int *in, size_t N); -bool isNoise_int(int *bits, uint32_t size); -bool isNoise(uint8_t *bits, uint32_t size); -extern void zeromean(uint8_t* data, size_t size); - +void computeSignalProperties(uint8_t *bits, uint32_t size); +void removeSignalOffset(uint8_t *samples, uint32_t size); void getNextLow(uint8_t *samples, size_t size, int low, size_t *i); void getNextHigh(uint8_t *samples, size_t size, int high, size_t *i); bool loadWaveCounters(uint8_t *samples, size_t size, int lowToLowWaveLen[], int highToLowWaveLen[], int *waveCnt, int *skip, int *minClk, int *high, int *low);