[PCF7930] Refactoring & bugfix in READING

firs commit of a few to come.
First renames of variables, added a few comments to improve clarity.
Fixed types (int -> unitx_t , const, ...) - not all. still some to come

Fixed 2 conditions that did not work properly. Here some explanation:

  Imagine dest[i-1] = 255 and dest[i] = 0. THis would mean a clear falling edge.
  However, this code would not work, since dest[i] > lmax is not true.
  This condition only works if I have at least 1 sample between lmax and 255.
  Same for the other way around.
This commit is contained in:
tinooo 2025-02-10 22:41:01 +02:00 committed by Tino
commit 3a8dc89dca
2 changed files with 115 additions and 48 deletions

View file

@ -37,84 +37,147 @@ size_t DemodPCF7931(uint8_t **outBlocks, bool ledcontrol) {
uint8_t *dest = BigBuf_get_addr(); uint8_t *dest = BigBuf_get_addr();
int g_GraphTraceLen = BigBuf_max_traceLen(); int g_GraphTraceLen = BigBuf_max_traceLen();
// limit g_GraphTraceLen to a little more than 2 data frames.
// To make sure a complete dataframe is in the dataset.
if (g_GraphTraceLen > 18000) { if (g_GraphTraceLen > 18000) {
g_GraphTraceLen = 18000; g_GraphTraceLen = 18000;
} }
int i = 2, j, lastval, bitidx, half_switch; int i = 2, j, bitPos;
int clock = 64; uint8_t half_switch;
int tolerance = clock / 8;
uint16_t bitPosLastEdge;
uint16_t bitPosCurrentEdge;
uint8_t lastClockDuration; // used to store the duration of the last "clock", for decoding.
// clock may not be the correct term, maybe bit is better.
// The duration between two edges is meant
const uint8_t clock = 64;
const uint8_t tolerance = clock / 8;
const uint8_t _16T0 = clock/4;
const uint8_t _32T0 = clock/2;
const uint8_t _64T0 = clock;
int pmc, block_done; int pmc, block_done;
int lc, warnings = 0; int warnings = 0;
size_t num_blocks = 0; size_t num_blocks = 0;
int lmin = 64, lmax = 192; // int lmin = 64, lmax = 192; // used for some thresholds to identify high/low
uint8_t dir; uint8_t threshold = 30; // threshold to filter out noise, from an actual slope.
EdgeType expectedNextEdge = UNDEFINED; // direction in which the next slope is expected should go.
BigBuf_Clear_keep_EM(); BigBuf_Clear_keep_EM();
LFSetupFPGAForADC(LF_DIVISOR_125, true); LFSetupFPGAForADC(LF_DIVISOR_125, true);
DoAcquisition_default(0, true, ledcontrol); DoAcquisition_default(0, true, ledcontrol);
/* Find first local max/min */ // /* Find first local max/min */
if (dest[1] > dest[0]) { // if (dest[1] > dest[0]) {
while (i < g_GraphTraceLen) { // while (i < g_GraphTraceLen) {
if (!(dest[i] > dest[i - 1]) && dest[i] > lmax) { // // Todo: dont think that this condition is correct. same issue as below.
break; // if (!(dest[i] > dest[i - 1]) && dest[i] > lmax) {
} // break;
i++; // }
// i++;
// }
// dir = 0;
// } else {
// while (i < g_GraphTraceLen) {
// // Todo: dont think that this condition is correct. same issue as below.
// if (!(dest[i] < dest[i - 1]) && dest[i] < lmin) {
// break;
// }
// i++;
// }
// dir = 1;
// }
i = 1;
while (i < g_GraphTraceLen && expectedNextEdge==UNDEFINED) {
// find falling edge
if ((dest[i] + threshold) < dest[i-1]) {
expectedNextEdge = RISING; // current edge is falling, so next has to be rising
// find rising edge
} else if ((dest[i] - threshold) > dest[i-1]){
expectedNextEdge = FALLING; // current edge is rising, so next has to be falling
} }
dir = 0;
} else { i++;
while (i < g_GraphTraceLen) {
if (!(dest[i] < dest[i - 1]) && dest[i] < lmin) {
break;
}
i++;
}
dir = 1;
} }
lastval = i++; bitPosLastEdge = i++;
half_switch = 0; half_switch = 0;
pmc = 0; pmc = 0;
block_done = 0; block_done = 0;
for (bitidx = 0; i < g_GraphTraceLen; i++) { for (bitPos = 0; i < g_GraphTraceLen; i++) {
if ((dest[i - 1] > dest[i] && dir == 1 && dest[i] > lmax) || (dest[i - 1] < dest[i] && dir == 0 && dest[i] < lmin)) { // Todo: This condition is not working properly. It is failing, in case the samples are falling/rising RAPIDLY.
lc = i - lastval; // Imagine dest[i-1] = 255 and dest[i] = 0. THis would mean a clear falling edge.
lastval = i; // However, this code would not work, since dest[i] > lmax is not true.
// This condition only works if I have at least 1 sample between lmax and 255.
// Same for the other way around.
// if ((dest[i - 1] > dest[i] && dir == 1 && dest[i] > lmax) || (dest[i - 1] < dest[i] && dir == 0 && dest[i] < lmin)) {
if (bitPos%4 == 0){
//Dbprintf("dest[%d]: %d",i, dest[i]);
}
// condition is searching for the next slope, in the expected diretion.
if ( ((dest[i] + threshold) < dest[i-1] && expectedNextEdge == FALLING ) ||
((dest[i] - threshold) > dest[i-1] && expectedNextEdge == RISING )) {
expectedNextEdge = (expectedNextEdge == FALLING) ? RISING : FALLING; //toggle the next expected edge
//okay, next falling/rising edge found
bitPosCurrentEdge = i;
// Switch depending on lc length: lastClockDuration = bitPosCurrentEdge - bitPosLastEdge;
bitPosLastEdge = i;
// Switch depending on lastClockDuration length:
// Tolerance is 1/8 of clock rate (arbitrary) // Tolerance is 1/8 of clock rate (arbitrary)
if (ABS(lc - clock / 4) < tolerance) {
// 16T0 // 16T0
if ((i - pmc) == lc) { // 16T0 was previous one if (ABS(lastClockDuration - _16T0) < tolerance) {
if ((i - pmc) == lastClockDuration) { // 16T0 was previous one
// It's a PMC // It's a PMC
Dbprintf(_GREEN_("PMC 16T0 FOUND:") " at i: %d", i);
i += (128 + 127 + 16 + 32 + 33 + 16) - 1; i += (128 + 127 + 16 + 32 + 33 + 16) - 1;
lastval = i; bitPosLastEdge = i;
pmc = 0; pmc = 0;
block_done = 1; block_done = 1;
} else { } else {
pmc = i; pmc = i;
} }
} else if (ABS(lc - clock / 2) < tolerance) {
// 32TO // 32TO
if ((i - pmc) == lc) { // 16T0 was previous one } else if (ABS(lastClockDuration - _32T0) < tolerance) {
if ((i - pmc) == lastClockDuration) { // 16T0 was previous one
// It's a PMC ! // It's a PMC !
Dbprintf(_GREEN_("PMC 32T0 FOUND:") " at i: %d", i);
i += (128 + 127 + 16 + 32 + 33) - 1; i += (128 + 127 + 16 + 32 + 33) - 1;
lastval = i; bitPosLastEdge = i;
pmc = 0; pmc = 0;
block_done = 1; block_done = 1;
// if no pmc, then its a normal bit. Check if its the second time, the edge changed
// if yes, then the bit is 0
} else if (half_switch == 1) { } else if (half_switch == 1) {
bits[bitidx++] = 0; bits[bitPos++] = 0;
// reset the edge counter to 0
half_switch = 0; half_switch = 0;
// so it is the first time the edge changed. No bit value will be set here, bit if the
// edge changes again, it will be. see case above.
} else } else
half_switch++; half_switch++;
} else if (ABS(lc - clock) < tolerance) {
// 64TO // 64T0
bits[bitidx++] = 1; } else if (ABS(lastClockDuration - _64T0) < tolerance) {
bits[bitPos++] = 1;
// Error
} else { } else {
// Error
if (++warnings > 10) { if (++warnings > 10) {
if (g_dbglevel >= DBG_EXTENDED) { if (g_dbglevel >= DBG_EXTENDED) {
@ -126,7 +189,7 @@ size_t DemodPCF7931(uint8_t **outBlocks, bool ledcontrol) {
} }
if (block_done == 1) { if (block_done == 1) {
if (bitidx == 128) { if (bitPos == 128) {
for (j = 0; j < 16; ++j) { for (j = 0; j < 16; ++j) {
blocks[num_blocks][j] = blocks[num_blocks][j] =
128 * bits[j * 8 + 7] + 128 * bits[j * 8 + 7] +
@ -141,18 +204,15 @@ size_t DemodPCF7931(uint8_t **outBlocks, bool ledcontrol) {
} }
num_blocks++; num_blocks++;
} }
bitidx = 0; bitPos = 0;
block_done = 0; block_done = 0;
half_switch = 0; half_switch = 0;
} }
if (i < g_GraphTraceLen) {
dir = (dest[i - 1] > dest[i]) ? 0 : 1;
}
} }
if (bitidx == 255) { if (bitPos == 255) {
bitidx = 0; bitPos = 0;
} }
if (num_blocks == 4) { if (num_blocks == 4) {

View file

@ -18,6 +18,13 @@
#include "common.h" #include "common.h"
typedef enum{
UNDEFINED,
FALLING,
RISING
} EdgeType;
size_t DemodPCF7931(uint8_t **outBlocks, bool ledcontrol); size_t DemodPCF7931(uint8_t **outBlocks, bool ledcontrol);
bool IsBlock0PCF7931(uint8_t *block); bool IsBlock0PCF7931(uint8_t *block);
bool IsBlock1PCF7931(const uint8_t *block); bool IsBlock1PCF7931(const uint8_t *block);