From 3a8dc89dca3294b0ed9c2458c0755c5262045e49 Mon Sep 17 00:00:00 2001 From: tinooo <34310283+tinooo@users.noreply.github.com> Date: Mon, 10 Feb 2025 22:41:01 +0200 Subject: [PATCH 01/12] [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. --- armsrc/pcf7931.c | 156 ++++++++++++++++++++++++++++++++--------------- armsrc/pcf7931.h | 7 +++ 2 files changed, 115 insertions(+), 48 deletions(-) diff --git a/armsrc/pcf7931.c b/armsrc/pcf7931.c index 2d56943af..67391d226 100644 --- a/armsrc/pcf7931.c +++ b/armsrc/pcf7931.c @@ -37,84 +37,147 @@ size_t DemodPCF7931(uint8_t **outBlocks, bool ledcontrol) { uint8_t *dest = BigBuf_get_addr(); 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) { g_GraphTraceLen = 18000; } - int i = 2, j, lastval, bitidx, half_switch; - int clock = 64; - int tolerance = clock / 8; + int i = 2, j, bitPos; + uint8_t half_switch; + + 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 lc, warnings = 0; + int warnings = 0; size_t num_blocks = 0; - int lmin = 64, lmax = 192; - uint8_t dir; + // int lmin = 64, lmax = 192; // used for some thresholds to identify high/low + 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(); LFSetupFPGAForADC(LF_DIVISOR_125, true); DoAcquisition_default(0, true, ledcontrol); - /* Find first local max/min */ - if (dest[1] > dest[0]) { - while (i < g_GraphTraceLen) { - if (!(dest[i] > dest[i - 1]) && dest[i] > lmax) { - break; - } - i++; + // /* Find first local max/min */ + // if (dest[1] > dest[0]) { + // while (i < g_GraphTraceLen) { + // // Todo: dont think that this condition is correct. same issue as below. + // if (!(dest[i] > dest[i - 1]) && dest[i] > lmax) { + // break; + // } + // 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 { - while (i < g_GraphTraceLen) { - if (!(dest[i] < dest[i - 1]) && dest[i] < lmin) { - break; - } - i++; - } - dir = 1; + + i++; } - lastval = i++; + bitPosLastEdge = i++; half_switch = 0; pmc = 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)) { - lc = i - lastval; - lastval = i; + // Todo: This condition is not working properly. It is failing, in case the samples are falling/rising RAPIDLY. + // 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. + // 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) - if (ABS(lc - clock / 4) < tolerance) { - // 16T0 - if ((i - pmc) == lc) { // 16T0 was previous one + + // 16T0 + if (ABS(lastClockDuration - _16T0) < tolerance) { + if ((i - pmc) == lastClockDuration) { // 16T0 was previous one // It's a PMC + Dbprintf(_GREEN_("PMC 16T0 FOUND:") " at i: %d", i); i += (128 + 127 + 16 + 32 + 33 + 16) - 1; - lastval = i; + bitPosLastEdge = i; pmc = 0; block_done = 1; } else { pmc = i; } - } else if (ABS(lc - clock / 2) < tolerance) { - // 32TO - if ((i - pmc) == lc) { // 16T0 was previous one + + // 32TO + } else if (ABS(lastClockDuration - _32T0) < tolerance) { + if ((i - pmc) == lastClockDuration) { // 16T0 was previous one // It's a PMC ! + Dbprintf(_GREEN_("PMC 32T0 FOUND:") " at i: %d", i); i += (128 + 127 + 16 + 32 + 33) - 1; - lastval = i; + bitPosLastEdge = i; pmc = 0; 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) { - bits[bitidx++] = 0; + bits[bitPos++] = 0; + // reset the edge counter to 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 half_switch++; - } else if (ABS(lc - clock) < tolerance) { - // 64TO - bits[bitidx++] = 1; + + // 64T0 + } else if (ABS(lastClockDuration - _64T0) < tolerance) { + bits[bitPos++] = 1; + + // Error } else { - // Error if (++warnings > 10) { if (g_dbglevel >= DBG_EXTENDED) { @@ -126,7 +189,7 @@ size_t DemodPCF7931(uint8_t **outBlocks, bool ledcontrol) { } if (block_done == 1) { - if (bitidx == 128) { + if (bitPos == 128) { for (j = 0; j < 16; ++j) { blocks[num_blocks][j] = 128 * bits[j * 8 + 7] + @@ -141,18 +204,15 @@ size_t DemodPCF7931(uint8_t **outBlocks, bool ledcontrol) { } num_blocks++; } - bitidx = 0; + bitPos = 0; block_done = 0; half_switch = 0; } - if (i < g_GraphTraceLen) { - dir = (dest[i - 1] > dest[i]) ? 0 : 1; - } } - if (bitidx == 255) { - bitidx = 0; + if (bitPos == 255) { + bitPos = 0; } if (num_blocks == 4) { diff --git a/armsrc/pcf7931.h b/armsrc/pcf7931.h index 3be9ea5be..a3e3a032d 100644 --- a/armsrc/pcf7931.h +++ b/armsrc/pcf7931.h @@ -18,6 +18,13 @@ #include "common.h" + +typedef enum{ + UNDEFINED, + FALLING, + RISING +} EdgeType; + size_t DemodPCF7931(uint8_t **outBlocks, bool ledcontrol); bool IsBlock0PCF7931(uint8_t *block); bool IsBlock1PCF7931(const uint8_t *block); From 9bfd55ebe0d5e8e53fce3bd2d561fa558a2047b1 Mon Sep 17 00:00:00 2001 From: tinooo <34310283+tinooo@users.noreply.github.com> Date: Wed, 12 Feb 2025 08:42:02 +0200 Subject: [PATCH 02/12] [PCF7931] draft of working & refacored DemodPCF7931() demod function now seems to work basically. Not all error cases are handled I guess. Also still debug prints, since I've to figure out the rest. Also unclear, why limit the buffer size to 1-2 blocks only? --- armsrc/pcf7931.c | 154 ++++++++++++++++++++++++----------------------- 1 file changed, 78 insertions(+), 76 deletions(-) diff --git a/armsrc/pcf7931.c b/armsrc/pcf7931.c index 67391d226..3e4444ed9 100644 --- a/armsrc/pcf7931.c +++ b/armsrc/pcf7931.c @@ -39,133 +39,118 @@ size_t DemodPCF7931(uint8_t **outBlocks, bool ledcontrol) { 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) { - g_GraphTraceLen = 18000; - } + // 1 Frame is 16 Byte -> 128byte. at a T0 of 64 -> 8129 Samples per frame. + // + PMC -> 384T0 --> 8576 samples required for one block + // to make sure that one complete block is definitely being sampled, we need 2 times that + // which is ~17.xxx samples. round up. and clamp to this value. + + // TODO: Doublecheck why this is being limited? + g_GraphTraceLen = (g_GraphTraceLen > 18000) ? 18000 : g_GraphTraceLen; - int i = 2, j, bitPos; + uint8_t j; uint8_t half_switch; - 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 + uint8_t bitPos; // max 128 bit in one block. if more, then there is an error and PMC was not found. + + uint16_t sample; // to keep track of the current sample that is being analyzed + uint16_t samplePosLastEdge; + uint16_t samplePosCurrentEdge; + 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 + uint8_t beforeLastClockDuration; // store the clock duration of the cycle before the last Clock duration. Basically clockduration -2 + + 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 block_done; int warnings = 0; size_t num_blocks = 0; // int lmin = 64, lmax = 192; // used for some thresholds to identify high/low - 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. + uint8_t threshold = 30; // threshold to filter out noise, from an actual edge. + EdgeType expectedNextEdge = UNDEFINED; // direction in which the next edge is expected should go. BigBuf_Clear_keep_EM(); LFSetupFPGAForADC(LF_DIVISOR_125, true); DoAcquisition_default(0, true, ledcontrol); - // /* Find first local max/min */ - // if (dest[1] > dest[0]) { - // while (i < g_GraphTraceLen) { - // // Todo: dont think that this condition is correct. same issue as below. - // if (!(dest[i] > dest[i - 1]) && dest[i] > lmax) { - // break; - // } - // 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) { + sample = 1; + while (sample < g_GraphTraceLen && expectedNextEdge==UNDEFINED) { // find falling edge - if ((dest[i] + threshold) < dest[i-1]) { + if ((dest[sample] + threshold) < dest[sample-1]) { expectedNextEdge = RISING; // current edge is falling, so next has to be rising // find rising edge - } else if ((dest[i] - threshold) > dest[i-1]){ + } else if ((dest[sample] - threshold) > dest[sample-1]){ expectedNextEdge = FALLING; // current edge is rising, so next has to be falling } - i++; + sample++; } - bitPosLastEdge = i++; + samplePosLastEdge = sample++; half_switch = 0; - pmc = 0; block_done = 0; + bitPos = 0; + lastClockDuration=0; - for (bitPos = 0; i < g_GraphTraceLen; i++) { + // dont reset sample here. we've already found the last edge. continue from here + for ( ; sample < g_GraphTraceLen; sample++) { - // Todo: This condition is not working properly. It is failing, in case the samples are falling/rising RAPIDLY. - // 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. - // 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]); + if (sample%4 == 0){ + // Dbprintf("dest[%d]: %d, bitPos: %d",sample, dest[sample], bitPos); } - // 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 + // condition is searching for the next edge, in the expected diretion. + if ( ((dest[sample] + threshold) < dest[sample-1] && expectedNextEdge == FALLING ) || + ((dest[sample] - threshold) > dest[sample-1] && expectedNextEdge == RISING )) { //okay, next falling/rising edge found - bitPosCurrentEdge = i; - lastClockDuration = bitPosCurrentEdge - bitPosLastEdge; - bitPosLastEdge = i; + expectedNextEdge = (expectedNextEdge == FALLING) ? RISING : FALLING; //toggle the next expected edge + samplePosCurrentEdge = sample; + beforeLastClockDuration = lastClockDuration; // save the previous clock duration for PMC recognition + lastClockDuration = samplePosCurrentEdge - samplePosLastEdge; + samplePosLastEdge = sample; // Switch depending on lastClockDuration length: // Tolerance is 1/8 of clock rate (arbitrary) - // 16T0 if (ABS(lastClockDuration - _16T0) < tolerance) { - if ((i - pmc) == lastClockDuration) { // 16T0 was previous one + + //tollerance is missing for PMC!! TODO + // if the clock before was 16, it is indicating a PMC - check this + if (ABS(beforeLastClockDuration - _16T0) < tolerance) { // It's a PMC - Dbprintf(_GREEN_("PMC 16T0 FOUND:") " at i: %d", i); - i += (128 + 127 + 16 + 32 + 33 + 16) - 1; - bitPosLastEdge = i; - pmc = 0; + Dbprintf(_GREEN_("PMC 16T0 FOUND:") " bitPos: %d, sample: %d", bitPos, sample); + sample += (128 + 127 + 16 + 32 + 33 + 16) - 1; // move to the sample after PMC + samplePosLastEdge = sample; block_done = 1; - } else { - pmc = i; + // TODO: Not sure if sample need to set expected next edge? + } // 32TO } else if (ABS(lastClockDuration - _32T0) < tolerance) { - if ((i - pmc) == lastClockDuration) { // 16T0 was previous one + // if the clock before was 16, it is indicating a PMC - check this + if (ABS(beforeLastClockDuration - _16T0) < tolerance) { // It's a PMC ! - Dbprintf(_GREEN_("PMC 32T0 FOUND:") " at i: %d", i); - i += (128 + 127 + 16 + 32 + 33) - 1; - bitPosLastEdge = i; - pmc = 0; + Dbprintf(_GREEN_("PMC 32T0 FOUND:") " bitPos: %d, sample: %d", bitPos, sample); + sample += (128 + 127 + 16 + 32 + 33) - 1; // move to the sample after PMC + samplePosLastEdge = sample; block_done = 1; + // TODO: Not sure if sample need to set expected next edge? + // 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) { - bits[bitPos++] = 0; + bits[bitPos] = 0; // reset the edge counter to 0 half_switch = 0; + bitPos++; // 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. @@ -174,21 +159,28 @@ size_t DemodPCF7931(uint8_t **outBlocks, bool ledcontrol) { // 64T0 } else if (ABS(lastClockDuration - _64T0) < tolerance) { - bits[bitPos++] = 1; + // this means, bit here is 1 + bits[bitPos] = 1; + bitPos++; // Error } else { + Dbprintf(_RED_("ELSE error case") " bitPos: %d, sample: %d", bitPos, sample); if (++warnings > 10) { if (g_dbglevel >= DBG_EXTENDED) { Dbprintf("Error: too many detection errors, aborting"); - } + } return 0; } } if (block_done == 1) { + Dbprintf(_YELLOW_("Block Done") " bitPos: %d, sample: %d", bitPos, sample); + // check if it is a complete block. If bitpos <128, it means that we did not receive + // a complete block. E.g. at the first start of a transmission. + // only save if a complete block is being received. if (bitPos == 128) { for (j = 0; j < 16; ++j) { blocks[num_blocks][j] = @@ -204,6 +196,7 @@ size_t DemodPCF7931(uint8_t **outBlocks, bool ledcontrol) { } num_blocks++; } + // now start over for the next block / first complete block. bitPos = 0; block_done = 0; half_switch = 0; @@ -211,11 +204,16 @@ size_t DemodPCF7931(uint8_t **outBlocks, bool ledcontrol) { } - if (bitPos == 255) { + // one block only holds 16byte (=128 bit) and then comes the PMC. so if more bit are found than 129, there must be an issue and PMC has not been identfied... + // TODO: not sure what to do in such case... + if (bitPos >= 129) { + Dbprintf(_RED_("PMC should have been found...") " bitPos: %d, sample: %d", bitPos, sample); bitPos = 0; } + // Todo: No idea, why blocks 4 is checked.. if (num_blocks == 4) { + Dbprintf(_RED_("we should never get here!!!") " at sample: %d", sample); break; } } @@ -264,6 +262,9 @@ bool IsBlock1PCF7931(const uint8_t *block) { } void ReadPCF7931(bool ledcontrol) { + + Dbprintf("ReadPCF7931()=========="); + int found_blocks = 0; // successfully read blocks int max_blocks = 8; // readable blocks uint8_t memory_blocks[8][17]; // PCF content @@ -283,6 +284,7 @@ void ReadPCF7931(bool ledcontrol) { int i = 0, j = 0; do { + Dbprintf("ReadPCF7931() -- DO LOOP =========="); i = 0; memset(tmp_blocks, 0, 4 * 16 * sizeof(uint8_t)); From 2da713eba9e5fdd7419488f6dc783181fd7b40a3 Mon Sep 17 00:00:00 2001 From: tinooo <34310283+tinooo@users.noreply.github.com> Date: Fri, 14 Feb 2025 14:40:00 +0100 Subject: [PATCH 03/12] [PCF7931] draft continue with refactoring ReadPCF7931() still not done with DemodPCF7931(). But now including changes in ReadPCF7931(). They work tightly together. Trying to resolve some issues and bugs. Basically it seems to work and my results are consistent. However, they still deviate from what I get if I do analyze the signal using lf read and data commands. still some issues somewhere. --- armsrc/pcf7931.c | 313 +++++++++++++++++++++++------------------------ armsrc/pcf7931.h | 1 - 2 files changed, 152 insertions(+), 162 deletions(-) diff --git a/armsrc/pcf7931.c b/armsrc/pcf7931.c index 3e4444ed9..9007b14ff 100644 --- a/armsrc/pcf7931.c +++ b/armsrc/pcf7931.c @@ -30,6 +30,8 @@ size_t DemodPCF7931(uint8_t **outBlocks, bool ledcontrol) { + const uint8_t DECIMATION = 4; + // 2021 iceman, memor uint8_t bits[256] = {0x00}; uint8_t blocks[8][16]; @@ -45,114 +47,102 @@ size_t DemodPCF7931(uint8_t **outBlocks, bool ledcontrol) { // which is ~17.xxx samples. round up. and clamp to this value. // TODO: Doublecheck why this is being limited? - g_GraphTraceLen = (g_GraphTraceLen > 18000) ? 18000 : g_GraphTraceLen; +// g_GraphTraceLen = (g_GraphTraceLen > 18000) ? 18000 : g_GraphTraceLen; + + BigBuf_Clear_keep_EM(); + LFSetupFPGAForADC(LF_DIVISOR_125, true); + // DoAcquisition_default(0, true, ledcontrol); + // sample with decimation of 2 --> This means double the values can be sampled. + // this is needed to get a complete frame in the buffer (64 * 8 * 16 * 8 + 8*PMC(~380)) = ~68.000 samples. Buffer is only 41.xxx + // with decimation 2, buffer will be twice as big. + DoAcquisition(DECIMATION, 8, 0, 0, false, 0, 0, 0, ledcontrol); + uint8_t j; uint8_t half_switch; uint8_t bitPos; // max 128 bit in one block. if more, then there is an error and PMC was not found. - uint16_t sample; // to keep track of the current sample that is being analyzed - uint16_t samplePosLastEdge; - uint16_t samplePosCurrentEdge; + uint32_t sample; // to keep track of the current sample that is being analyzed + uint32_t samplePosLastEdge; + uint32_t samplePosCurrentEdge; 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 uint8_t beforeLastClockDuration; // store the clock duration of the cycle before the last Clock duration. Basically clockduration -2 - - const uint8_t clock = 64; + + const uint8_t clock = 64/DECIMATION; // this actually is 64, but since samples are decimated by 2, clock is also /2 const uint8_t tolerance = clock / 8; const uint8_t _16T0 = clock/4; const uint8_t _32T0 = clock/2; const uint8_t _64T0 = clock; - int block_done; - int warnings = 0; + const uint16_t pmc16T0Len = (128 + 127 + 16 + 32 + 33 + 16) * clock/64; // calculating the two possible pmc lengths, based on the clock. -4 at the end is to make sure not to increment too far + const uint16_t pmc32T0Len = (128 + 127 + 16 + 32 + 33 ) * clock/64; + + uint8_t block_done; size_t num_blocks = 0; - // int lmin = 64, lmax = 192; // used for some thresholds to identify high/low - uint8_t threshold = 30; // threshold to filter out noise, from an actual edge. - EdgeType expectedNextEdge = UNDEFINED; // direction in which the next edge is expected should go. + uint8_t threshold = 50; // threshold to filter out noise, from an actual edge. + EdgeType expectedNextEdge = FALLING; // direction in which the next edge is expected should go. - - BigBuf_Clear_keep_EM(); - LFSetupFPGAForADC(LF_DIVISOR_125, true); - DoAcquisition_default(0, true, ledcontrol); - - sample = 1; - while (sample < g_GraphTraceLen && expectedNextEdge==UNDEFINED) { - // find falling edge - if ((dest[sample] + threshold) < dest[sample-1]) { - expectedNextEdge = RISING; // current edge is falling, so next has to be rising - - // find rising edge - } else if ((dest[sample] - threshold) > dest[sample-1]){ - expectedNextEdge = FALLING; // current edge is rising, so next has to be falling - } - - sample++; - } - - samplePosLastEdge = sample++; half_switch = 0; + samplePosLastEdge = 0; block_done = 0; bitPos = 0; lastClockDuration=0; - // dont reset sample here. we've already found the last edge. continue from here - for ( ; sample < g_GraphTraceLen; sample++) { - - if (sample%4 == 0){ - // Dbprintf("dest[%d]: %d, bitPos: %d",sample, dest[sample], bitPos); - } - + for (sample = 1 ; sample < g_GraphTraceLen; sample++) { // condition is searching for the next edge, in the expected diretion. if ( ((dest[sample] + threshold) < dest[sample-1] && expectedNextEdge == FALLING ) || ((dest[sample] - threshold) > dest[sample-1] && expectedNextEdge == RISING )) { //okay, next falling/rising edge found - + + + expectedNextEdge = (expectedNextEdge == FALLING) ? RISING : FALLING; //toggle the next expected edge samplePosCurrentEdge = sample; beforeLastClockDuration = lastClockDuration; // save the previous clock duration for PMC recognition lastClockDuration = samplePosCurrentEdge - samplePosLastEdge; samplePosLastEdge = sample; + // Dbprintf("%d, %d, edge found, len: %d, nextEdge: %d", sample, dest[sample], lastClockDuration*DECIMATION, expectedNextEdge); + // Switch depending on lastClockDuration length: - // Tolerance is 1/8 of clock rate (arbitrary) // 16T0 if (ABS(lastClockDuration - _16T0) < tolerance) { - //tollerance is missing for PMC!! TODO - // if the clock before was 16, it is indicating a PMC - check this + // if the clock before also was 16T0, it is a PMC! if (ABS(beforeLastClockDuration - _16T0) < tolerance) { // It's a PMC Dbprintf(_GREEN_("PMC 16T0 FOUND:") " bitPos: %d, sample: %d", bitPos, sample); - sample += (128 + 127 + 16 + 32 + 33 + 16) - 1; // move to the sample after PMC + sample += pmc16T0Len; // move to the sample after PMC + + expectedNextEdge = FALLING; samplePosLastEdge = sample; block_done = 1; - // TODO: Not sure if sample need to set expected next edge? - } // 32TO } else if (ABS(lastClockDuration - _32T0) < tolerance) { - // if the clock before was 16, it is indicating a PMC - check this + // if the clock before also was 16T0, it is a PMC! if (ABS(beforeLastClockDuration - _16T0) < tolerance) { // It's a PMC ! Dbprintf(_GREEN_("PMC 32T0 FOUND:") " bitPos: %d, sample: %d", bitPos, sample); - sample += (128 + 127 + 16 + 32 + 33) - 1; // move to the sample after PMC + + sample += pmc32T0Len; // move to the sample after PMC + + expectedNextEdge = FALLING; samplePosLastEdge = sample; block_done = 1; - // TODO: Not sure if sample need to set expected next edge? - - // if no pmc, then its a normal bit. Check if its the second time, the edge changed - // if yes, then the bit is 0 + // 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) { bits[bitPos] = 0; // reset the edge counter to 0 half_switch = 0; bitPos++; - // so it is the first time the edge changed. No bit value will be set here, bit if the + // if 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 half_switch++; @@ -165,19 +155,17 @@ size_t DemodPCF7931(uint8_t **outBlocks, bool ledcontrol) { // Error } else { - Dbprintf(_RED_("ELSE error case") " bitPos: %d, sample: %d", bitPos, sample); - if (++warnings > 10) { + // some Error. maybe check tolerances. + // likeley to happen in the first block. + Dbprintf(_RED_("ERROR in demodulation") " Length last clock: %d - check threshold/tolerance/signal. Toss block", lastClockDuration*DECIMATION); - if (g_dbglevel >= DBG_EXTENDED) { - Dbprintf("Error: too many detection errors, aborting"); - } - - return 0; - } + // Toss this block. + block_done = 1; } if (block_done == 1) { - Dbprintf(_YELLOW_("Block Done") " bitPos: %d, sample: %d", bitPos, sample); + // Dbprintf(_YELLOW_("Block Done") " bitPos: %d, sample: %d", bitPos, sample); + // check if it is a complete block. If bitpos <128, it means that we did not receive // a complete block. E.g. at the first start of a transmission. // only save if a complete block is being received. @@ -202,6 +190,8 @@ size_t DemodPCF7931(uint8_t **outBlocks, bool ledcontrol) { half_switch = 0; } + }else { + // Dbprintf("%d, %d", sample, dest[sample]); } // one block only holds 16byte (=128 bit) and then comes the PMC. so if more bit are found than 129, there must be an issue and PMC has not been identfied... @@ -211,12 +201,8 @@ size_t DemodPCF7931(uint8_t **outBlocks, bool ledcontrol) { bitPos = 0; } - // Todo: No idea, why blocks 4 is checked.. - if (num_blocks == 4) { - Dbprintf(_RED_("we should never get here!!!") " at sample: %d", sample); - break; - } - } + } + memcpy(outBlocks, blocks, 16 * num_blocks); return num_blocks; } @@ -265,23 +251,29 @@ void ReadPCF7931(bool ledcontrol) { Dbprintf("ReadPCF7931()=========="); + uint8_t maxBlocks = 8; // readable blocks + int found_blocks = 0; // successfully read blocks - int max_blocks = 8; // readable blocks - uint8_t memory_blocks[8][17]; // PCF content - uint8_t single_blocks[8][17]; // PFC blocks with unknown position + + // TODO: Why 17 byte len? 16 should be good. + uint8_t memory_blocks[maxBlocks][17]; // PCF content + uint8_t single_blocks[maxBlocks][17]; // PFC blocks with unknown position + uint8_t tmp_blocks[4][16]; // temporary read buffer + int single_blocks_cnt = 0; size_t n; // transmitted blocks - uint8_t tmp_blocks[4][16]; // temporary read buffer - - uint8_t found_0_1 = 0; // flag: blocks 0 and 1 were found + + //uint8_t found_0_1 = 0; // flag: blocks 0 and 1 were found int errors = 0; // error counter int tries = 0; // tries counter + // reuse lenghts and consts to properly clear memset(memory_blocks, 0, 8 * 17 * sizeof(uint8_t)); memset(single_blocks, 0, 8 * 17 * sizeof(uint8_t)); - int i = 0, j = 0; + int i = 0; + //j = 0; do { Dbprintf("ReadPCF7931() -- DO LOOP =========="); @@ -294,15 +286,13 @@ void ReadPCF7931(bool ledcontrol) { // exit if no block is received if (errors >= 10 && found_blocks == 0 && single_blocks_cnt == 0) { - - if (g_dbglevel >= DBG_INFO) - Dbprintf("[!!] Error, no tag or bad tag"); - + Dbprintf("[!!] Error, no tag or bad tag"); return; } - // exit if too many errors during reading - if (tries > 50 && (2 * errors > tries)) { + // exit if too many tries without finding the first block + if (tries > 10) { + Dbprintf("End after 10 tries"); if (g_dbglevel >= DBG_INFO) { Dbprintf("[!!] Error reading the tag, only partial content"); } @@ -310,93 +300,94 @@ void ReadPCF7931(bool ledcontrol) { goto end; } - // our logic breaks if we don't get at least two blocks - if (n < 2) { - // skip if all 0s block or no blocks - if (n == 0 || !memcmp(tmp_blocks[0], "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 16)) - continue; + // // our logic breaks if we don't get at least two blocks + // if (n < 2) { + // // skip if all 0s block or no blocks + // if (n == 0 || !memcmp(tmp_blocks[0], "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 16)) + // continue; - // add block to single blocks list - if (single_blocks_cnt < max_blocks) { - for (i = 0; i < single_blocks_cnt; ++i) { - if (!memcmp(single_blocks[i], tmp_blocks[0], 16)) { - j = 1; - break; - } - } - if (j != 1) { - memcpy(single_blocks[single_blocks_cnt], tmp_blocks[0], 16); - print_result("got single block", single_blocks[single_blocks_cnt], 16); - single_blocks_cnt++; - } - j = 0; - } - ++tries; - continue; - } + // // add block to single blocks list + // if (single_blocks_cnt < maxBlocks) { + // for (i = 0; i < single_blocks_cnt; ++i) { + // if (!memcmp(single_blocks[i], tmp_blocks[0], 16)) { + // j = 1; + // break; + // } + // } + // if (j != 1) { + // memcpy(single_blocks[single_blocks_cnt], tmp_blocks[0], 16); + // print_result("got single block", single_blocks[single_blocks_cnt], 16); + // single_blocks_cnt++; + // } + // j = 0; + // } + // ++tries; + // continue; + // } - if (g_dbglevel >= DBG_EXTENDED) - Dbprintf("(dbg) got %d blocks (%d/%d found) (%d tries, %d errors)", n, found_blocks, (max_blocks == 0 ? found_blocks : max_blocks), tries, errors); + // Dbprintf("(dbg) got %d blocks (%d/%d found) (%d tries, %d errors)", n, found_blocks, (maxBlocks == 0 ? found_blocks : maxBlocks), tries, errors); + // if (g_dbglevel >= DBG_EXTENDED) + // Dbprintf("(dbg) got %d blocks (%d/%d found) (%d tries, %d errors)", n, found_blocks, (maxBlocks == 0 ? found_blocks : maxBlocks), tries, errors); for (i = 0; i < n; ++i) { print_result("got consecutive blocks", tmp_blocks[i], 16); } - i = 0; - if (!found_0_1) { - while (i < n - 1) { - if (IsBlock0PCF7931(tmp_blocks[i]) && IsBlock1PCF7931(tmp_blocks[i + 1])) { - found_0_1 = 1; - memcpy(memory_blocks[0], tmp_blocks[i], 16); - memcpy(memory_blocks[1], tmp_blocks[i + 1], 16); - memory_blocks[0][ALLOC] = memory_blocks[1][ALLOC] = 1; - // block 1 tells how many blocks are going to be sent - max_blocks = MAX((memory_blocks[1][14] & 0x7f), memory_blocks[1][15]) + 1; - found_blocks = 2; + // i = 0; + // if (!found_0_1) { + // while (i < n - 1) { + // if (IsBlock0PCF7931(tmp_blocks[i]) && IsBlock1PCF7931(tmp_blocks[i + 1])) { + // found_0_1 = 1; + // memcpy(memory_blocks[0], tmp_blocks[i], 16); + // memcpy(memory_blocks[1], tmp_blocks[i + 1], 16); + // memory_blocks[0][ALLOC] = memory_blocks[1][ALLOC] = 1; + // // block 1 tells how many blocks are going to be sent + // maxBlocks = MAX((memory_blocks[1][14] & 0x7f), memory_blocks[1][15]) + 1; + // found_blocks = 2; - Dbprintf("Found blocks 0 and 1. PCF is transmitting %d blocks.", max_blocks); + // Dbprintf("Found blocks 0 and 1. PCF is transmitting %d blocks.", maxBlocks); - // handle the following blocks - for (j = i + 2; j < n; ++j) { - memcpy(memory_blocks[found_blocks], tmp_blocks[j], 16); - memory_blocks[found_blocks][ALLOC] = 1; - ++found_blocks; - } - break; - } - ++i; - } - } else { - // Trying to re-order blocks - // Look for identical block in memory blocks - while (i < n - 1) { - // skip all zeroes blocks - if (memcmp(tmp_blocks[i], "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 16)) { - for (j = 1; j < max_blocks - 1; ++j) { - if (!memcmp(tmp_blocks[i], memory_blocks[j], 16) && !memory_blocks[j + 1][ALLOC]) { - memcpy(memory_blocks[j + 1], tmp_blocks[i + 1], 16); - memory_blocks[j + 1][ALLOC] = 1; - if (++found_blocks >= max_blocks) goto end; - } - } - } - if (memcmp(tmp_blocks[i + 1], "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 16)) { - for (j = 0; j < max_blocks; ++j) { - if (!memcmp(tmp_blocks[i + 1], memory_blocks[j], 16) && !memory_blocks[(j == 0 ? max_blocks : j) - 1][ALLOC]) { - if (j == 0) { - memcpy(memory_blocks[max_blocks - 1], tmp_blocks[i], 16); - memory_blocks[max_blocks - 1][ALLOC] = 1; - } else { - memcpy(memory_blocks[j - 1], tmp_blocks[i], 16); - memory_blocks[j - 1][ALLOC] = 1; - } - if (++found_blocks >= max_blocks) goto end; - } - } - } - ++i; - } - } + // // handle the following blocks + // for (j = i + 2; j < n; ++j) { + // memcpy(memory_blocks[found_blocks], tmp_blocks[j], 16); + // memory_blocks[found_blocks][ALLOC] = 1; + // ++found_blocks; + // } + // break; + // } + // ++i; + // } + // } else { + // // Trying to re-order blocks + // // Look for identical block in memory blocks + // while (i < n - 1) { + // // skip all zeroes blocks + // if (memcmp(tmp_blocks[i], "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 16)) { + // for (j = 1; j < maxBlocks - 1; ++j) { + // if (!memcmp(tmp_blocks[i], memory_blocks[j], 16) && !memory_blocks[j + 1][ALLOC]) { + // memcpy(memory_blocks[j + 1], tmp_blocks[i + 1], 16); + // memory_blocks[j + 1][ALLOC] = 1; + // if (++found_blocks >= maxBlocks) goto end; + // } + // } + // } + // if (memcmp(tmp_blocks[i + 1], "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 16)) { + // for (j = 0; j < maxBlocks; ++j) { + // if (!memcmp(tmp_blocks[i + 1], memory_blocks[j], 16) && !memory_blocks[(j == 0 ? maxBlocks : j) - 1][ALLOC]) { + // if (j == 0) { + // memcpy(memory_blocks[maxBlocks - 1], tmp_blocks[i], 16); + // memory_blocks[maxBlocks - 1][ALLOC] = 1; + // } else { + // memcpy(memory_blocks[j - 1], tmp_blocks[i], 16); + // memory_blocks[j - 1][ALLOC] = 1; + // } + // if (++found_blocks >= maxBlocks) goto end; + // } + // } + // } + // ++i; + // } + // } ++tries; if (BUTTON_PRESS()) { if (g_dbglevel >= DBG_EXTENDED) @@ -404,13 +395,13 @@ void ReadPCF7931(bool ledcontrol) { goto end; } - } while (found_blocks < max_blocks); + } while (found_blocks < maxBlocks); end: Dbprintf("-----------------------------------------"); Dbprintf("Memory content:"); Dbprintf("-----------------------------------------"); - for (i = 0; i < max_blocks; ++i) { + for (i = 0; i < maxBlocks; ++i) { if (memory_blocks[i][ALLOC]) print_result("Block", memory_blocks[i], 16); else @@ -418,7 +409,7 @@ end: } Dbprintf("-----------------------------------------"); - if (found_blocks < max_blocks) { + if (found_blocks < maxBlocks) { Dbprintf("-----------------------------------------"); Dbprintf("Blocks with unknown position:"); Dbprintf("-----------------------------------------"); diff --git a/armsrc/pcf7931.h b/armsrc/pcf7931.h index a3e3a032d..352997678 100644 --- a/armsrc/pcf7931.h +++ b/armsrc/pcf7931.h @@ -20,7 +20,6 @@ typedef enum{ - UNDEFINED, FALLING, RISING } EdgeType; From 3939e28640a822468b31478fa7712e6531bb27e9 Mon Sep 17 00:00:00 2001 From: tinooo <34310283+tinooo@users.noreply.github.com> Date: Tue, 4 Mar 2025 10:30:59 +0100 Subject: [PATCH 04/12] [PCF7931] Starting refactor of write procedure added comments --- armsrc/pcf7931.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/armsrc/pcf7931.c b/armsrc/pcf7931.c index 9007b14ff..843d48ced 100644 --- a/armsrc/pcf7931.c +++ b/armsrc/pcf7931.c @@ -645,8 +645,8 @@ bool AddPatternPCF7931(uint32_t a, uint32_t b, uint32_t c, uint32_t *tab) { uint32_t u = 0; for (u = 0; tab[u] != 0; u += 3) {} //we put the cursor at the last value of the array - tab[u] = (u == 0) ? a : a + tab[u - 1]; - tab[u + 1] = b + tab[u]; + tab[u] = (u == 0) ? a : a + tab[u - 1]; // if it is the first value of the array, nothing needs to be added. + tab[u + 1] = b + tab[u]; // otherwise always add up the values, because later on it is compared to a counter tab[u + 2] = c + tab[u + 1]; return true; From f6600ec96213f903cfc81c9551b302aeb2e17c0c Mon Sep 17 00:00:00 2001 From: tinooo <34310283+tinooo@users.noreply.github.com> Date: Tue, 4 Mar 2025 10:35:30 +0100 Subject: [PATCH 05/12] [PCF7931] Refactor removed early returns unneccessary returns. --- armsrc/pcf7931.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/armsrc/pcf7931.c b/armsrc/pcf7931.c index 843d48ced..3e5a89075 100644 --- a/armsrc/pcf7931.c +++ b/armsrc/pcf7931.c @@ -591,9 +591,9 @@ bool AddBytePCF7931(uint8_t byte, uint32_t *tab, int32_t l, int32_t p) { uint32_t u; for (u = 0; u < 8; ++u) { if (byte & (1 << u)) { //bit is 1 - if (AddBitPCF7931(1, tab, l, p) == 1) return true; + AddBitPCF7931(1, tab, l, p); } else { //bit is 0 - if (AddBitPCF7931(0, tab, l, p) == 1) return true; + AddBitPCF7931(0, tab, l, p); } } @@ -620,9 +620,8 @@ bool AddBitPCF7931(bool b, uint32_t *tab, int32_t l, int32_t p) { tab[u + 1] = 6 * T0_PCF + tab[u] + l; tab[u + 2] = 88 * T0_PCF + tab[u + 1] - l - p; - return false; + } else { //add a bit 0 - if (u == 0) tab[u] = 98 * T0_PCF + p; else @@ -630,7 +629,7 @@ bool AddBitPCF7931(bool b, uint32_t *tab, int32_t l, int32_t p) { tab[u + 1] = 6 * T0_PCF + tab[u] + l; tab[u + 2] = 24 * T0_PCF + tab[u + 1] - l - p; - return false; + } return true; } From ea96a3b0c923e9ed294b98de83932cd02993f3ef Mon Sep 17 00:00:00 2001 From: tinooo <34310283+tinooo@users.noreply.github.com> Date: Tue, 4 Mar 2025 13:26:15 +0100 Subject: [PATCH 06/12] [PCF7931] refactor write function rename some variables for more clear reading changed data type to meaningfull size --- armsrc/pcf7931.c | 127 ++++++++++++++++++++++++++--------------------- armsrc/pcf7931.h | 6 +-- 2 files changed, 73 insertions(+), 60 deletions(-) diff --git a/armsrc/pcf7931.c b/armsrc/pcf7931.c index 3e5a89075..a49dfa327 100644 --- a/armsrc/pcf7931.c +++ b/armsrc/pcf7931.c @@ -29,15 +29,10 @@ #define ALLOC 16 size_t DemodPCF7931(uint8_t **outBlocks, bool ledcontrol) { - const uint8_t DECIMATION = 4; - - // 2021 iceman, memor uint8_t bits[256] = {0x00}; uint8_t blocks[8][16]; - uint8_t *dest = BigBuf_get_addr(); - 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. @@ -51,18 +46,12 @@ size_t DemodPCF7931(uint8_t **outBlocks, bool ledcontrol) { BigBuf_Clear_keep_EM(); LFSetupFPGAForADC(LF_DIVISOR_125, true); - // DoAcquisition_default(0, true, ledcontrol); - // sample with decimation of 2 --> This means double the values can be sampled. - // this is needed to get a complete frame in the buffer (64 * 8 * 16 * 8 + 8*PMC(~380)) = ~68.000 samples. Buffer is only 41.xxx - // with decimation 2, buffer will be twice as big. DoAcquisition(DECIMATION, 8, 0, 0, false, 0, 0, 0, ledcontrol); - uint8_t j; uint8_t half_switch; + uint8_t bitPos; - uint8_t bitPos; // max 128 bit in one block. if more, then there is an error and PMC was not found. - uint32_t sample; // to keep track of the current sample that is being analyzed uint32_t samplePosLastEdge; uint32_t samplePosCurrentEdge; @@ -421,7 +410,13 @@ end: reply_mix(CMD_ACK, 0, 0, 0, 0, 0); } -static void RealWritePCF7931(uint8_t *pass, uint16_t init_delay, int32_t l, int32_t p, uint8_t address, uint8_t byte, uint8_t data, bool ledcontrol) { +static void RealWritePCF7931( + uint8_t *pass, + uint16_t init_delay, + int8_t offsetPulseWidth, int8_t offsetPulsePosition, + uint8_t address, uint8_t byte, uint8_t data, + bool ledcontrol){ + uint32_t tab[1024] = {0}; // data times frame uint32_t u = 0; uint8_t parity = 0; @@ -429,28 +424,36 @@ static void RealWritePCF7931(uint8_t *pass, uint16_t init_delay, int32_t l, int3 //BUILD OF THE DATA FRAME //alimentation of the tag (time for initializing) + // ToDo: This could be optimized/automated. e.g. Read one cycle, find PMC and calculate time. + // I dont understand, why 8192/2 AddPatternPCF7931(init_delay, 0, 8192 / 2 * T0_PCF, tab); + + // why "... + 70"? Why not "... + x * T0"? + // I think he just added 70 to be somewhere in The PMC window, which is 32T0 (=32*8 = 256) + // 3*T0 = PMC width + // 29*T0 = rest of PMC window (total 32T0 = 3+29) + // after the PMC, it directly goes to the password indication bit. AddPatternPCF7931(8192 / 2 * T0_PCF + 319 * T0_PCF + 70, 3 * T0_PCF, 29 * T0_PCF, tab); //password indication bit - AddBitPCF7931(1, tab, l, p); + AddBitPCF7931(1, tab, offsetPulseWidth, offsetPulsePosition); //password (on 56 bits) - AddBytePCF7931(pass[0], tab, l, p); - AddBytePCF7931(pass[1], tab, l, p); - AddBytePCF7931(pass[2], tab, l, p); - AddBytePCF7931(pass[3], tab, l, p); - AddBytePCF7931(pass[4], tab, l, p); - AddBytePCF7931(pass[5], tab, l, p); - AddBytePCF7931(pass[6], tab, l, p); - //programming mode (0 or 1) - AddBitPCF7931(0, tab, l, p); + AddBytePCF7931(pass[0], tab, offsetPulseWidth, offsetPulsePosition); + AddBytePCF7931(pass[1], tab, offsetPulseWidth, offsetPulsePosition); + AddBytePCF7931(pass[2], tab, offsetPulseWidth, offsetPulsePosition); + AddBytePCF7931(pass[3], tab, offsetPulseWidth, offsetPulsePosition); + AddBytePCF7931(pass[4], tab, offsetPulseWidth, offsetPulsePosition); + AddBytePCF7931(pass[5], tab, offsetPulseWidth, offsetPulsePosition); + AddBytePCF7931(pass[6], tab, offsetPulseWidth, offsetPulsePosition); + //programming mode (0 or 1) -> 0 = byte wise; 1 = block wise programming + AddBitPCF7931(0, tab, offsetPulseWidth, offsetPulsePosition); //block address on 6 bits for (u = 0; u < 6; ++u) { if (address & (1 << u)) { // bit 1 ++parity; - AddBitPCF7931(1, tab, l, p); + AddBitPCF7931(1, tab, offsetPulseWidth, offsetPulsePosition); } else { // bit 0 - AddBitPCF7931(0, tab, l, p); + AddBitPCF7931(0, tab, offsetPulseWidth, offsetPulsePosition); } } @@ -458,28 +461,29 @@ static void RealWritePCF7931(uint8_t *pass, uint16_t init_delay, int32_t l, int3 for (u = 0; u < 4; ++u) { if (byte & (1 << u)) { // bit 1 parity++; - AddBitPCF7931(1, tab, l, p); + AddBitPCF7931(1, tab, offsetPulseWidth, offsetPulsePosition); } else // bit 0 - AddBitPCF7931(0, tab, l, p); + AddBitPCF7931(0, tab, offsetPulseWidth, offsetPulsePosition); } //data on 8 bits for (u = 0; u < 8; u++) { if (data & (1 << u)) { // bit 1 parity++; - AddBitPCF7931(1, tab, l, p); + AddBitPCF7931(1, tab, offsetPulseWidth, offsetPulsePosition); } else //bit 0 - AddBitPCF7931(0, tab, l, p); + AddBitPCF7931(0, tab, offsetPulseWidth, offsetPulsePosition); } //parity bit if ((parity % 2) == 0) - AddBitPCF7931(0, tab, l, p); //even parity + AddBitPCF7931(0, tab, offsetPulseWidth, offsetPulsePosition); //even parity else - AddBitPCF7931(1, tab, l, p);//odd parity + AddBitPCF7931(1, tab, offsetPulseWidth, offsetPulsePosition);//odd parity - //time access memory - AddPatternPCF7931(5120 + 2680, 0, 0, tab); + // time access memory (640T0) + // Not sure why 335*T0, but should not matter. Since programming should be finished at that point + AddPatternPCF7931((640 + 335)* T0_PCF, 0, 0, tab); //conversion of the scale time for (u = 0; u < 500; ++u) @@ -500,14 +504,19 @@ static void RealWritePCF7931(uint8_t *pass, uint16_t init_delay, int32_t l, int3 /* Write on a byte of a PCF7931 tag * @param address : address of the block to write - @param byte : address of the byte to write - @param data : data to write + * @param byte : address of the byte to write + * @param data : data to write */ -void WritePCF7931(uint8_t pass1, uint8_t pass2, uint8_t pass3, uint8_t pass4, uint8_t pass5, uint8_t pass6, uint8_t pass7, uint16_t init_delay, int32_t l, int32_t p, uint8_t address, uint8_t byte, uint8_t data, bool ledcontrol) { +void WritePCF7931( + uint8_t pass1, uint8_t pass2, uint8_t pass3, uint8_t pass4, uint8_t pass5, uint8_t pass6, uint8_t pass7, + uint16_t init_delay, + int8_t offsetPulseWidth, int8_t offsetPulsePosition, + uint8_t address, uint8_t byte, uint8_t data, + bool ledcontrol) { if (g_dbglevel >= DBG_INFO) { Dbprintf("Initialization delay : %d us", init_delay); - Dbprintf("Offsets : %d us on the low pulses width, %d us on the low pulses positions", l, p); + Dbprintf("Offsets : %d us on the low pulses width, %d us on the low pulses positions", offsetPulseWidth, offsetPulsePosition); } Dbprintf("Password (LSB first on each byte): %02x %02x %02x %02x %02x %02x %02x", pass1, pass2, pass3, pass4, pass5, pass6, pass7); @@ -517,11 +526,11 @@ void WritePCF7931(uint8_t pass1, uint8_t pass2, uint8_t pass3, uint8_t pass4, ui uint8_t password[7] = {pass1, pass2, pass3, pass4, pass5, pass6, pass7}; - RealWritePCF7931(password, init_delay, l, p, address, byte, data, ledcontrol); + RealWritePCF7931(password, init_delay, offsetPulseWidth, offsetPulsePosition, address, byte, data, ledcontrol); } -/* Send a trame to a PCF7931 tags +/* Send a frame to a PCF7931 tags * @param tab : array of the data frame */ @@ -581,32 +590,36 @@ void SendCmdPCF7931(const uint32_t *tab, bool ledcontrol) { } -/* Add a byte for building the data frame of PCF7931 tags +/* Add a byte for building the data frame of PCF7931 tags. + * See Datasheet of PCF7931 diagramm on page 8. This explains pulse widht & positioning + * Normally, no offset should be required. * @param b : byte to add * @param tab : array of the data frame - * @param l : offset on low pulse width - * @param p : offset on low pulse positioning + * @param offsetPulseWidth : offset on low pulse width in µs (default pulse widht is 6T0) + * @param offsetPulsePosition : offset on low pulse positioning in µs */ -bool AddBytePCF7931(uint8_t byte, uint32_t *tab, int32_t l, int32_t p) { +bool AddBytePCF7931(uint8_t byte, uint32_t *tab, int8_t offsetPulseWidth, int8_t offsetPulsePosition) { uint32_t u; for (u = 0; u < 8; ++u) { if (byte & (1 << u)) { //bit is 1 - AddBitPCF7931(1, tab, l, p); + AddBitPCF7931(1, tab, offsetPulseWidth, offsetPulsePosition); } else { //bit is 0 - AddBitPCF7931(0, tab, l, p); + AddBitPCF7931(0, tab, offsetPulseWidth, offsetPulsePosition); } } return false; } -/* Add a bits for building the data frame of PCF7931 tags +/* Add a bits for building the data frame of PCF7931 tags. + * See Datasheet of PCF7931 diagramm on page 8. This explains pulse widht & positioning + * Normally, no offset should be required. * @param b : bit to add * @param tab : array of the data frame - * @param l : offset on low pulse width - * @param p : offset on low pulse positioning + * @param offsetPulseWidth : offset on low pulse width in µs (default pulse widht is 6T0) + * @param offsetPulsePosition : offset on low pulse positioning in µs */ -bool AddBitPCF7931(bool b, uint32_t *tab, int32_t l, int32_t p) { +bool AddBitPCF7931(bool b, uint32_t *tab, int8_t offsetPulseWidth, int8_t offsetPulsePosition) { uint8_t u = 0; //we put the cursor at the last value of the array @@ -614,21 +627,21 @@ bool AddBitPCF7931(bool b, uint32_t *tab, int32_t l, int32_t p) { if (b == 1) { //add a bit 1 if (u == 0) - tab[u] = 34 * T0_PCF + p; + tab[u] = 34 * T0_PCF + offsetPulsePosition; else - tab[u] = 34 * T0_PCF + tab[u - 1] + p; + tab[u] = 34 * T0_PCF + tab[u - 1] + offsetPulsePosition; - tab[u + 1] = 6 * T0_PCF + tab[u] + l; - tab[u + 2] = 88 * T0_PCF + tab[u + 1] - l - p; + tab[u + 1] = 6 * T0_PCF + tab[u] + offsetPulseWidth; + tab[u + 2] = 88 * T0_PCF + tab[u + 1] - offsetPulseWidth - offsetPulsePosition; } else { //add a bit 0 if (u == 0) - tab[u] = 98 * T0_PCF + p; + tab[u] = 98 * T0_PCF + offsetPulsePosition; else - tab[u] = 98 * T0_PCF + tab[u - 1] + p; + tab[u] = 98 * T0_PCF + tab[u - 1] + offsetPulsePosition; - tab[u + 1] = 6 * T0_PCF + tab[u] + l; - tab[u + 2] = 24 * T0_PCF + tab[u + 1] - l - p; + tab[u + 1] = 6 * T0_PCF + tab[u] + offsetPulseWidth; + tab[u + 2] = 24 * T0_PCF + tab[u + 1] - offsetPulseWidth - offsetPulsePosition; } return true; diff --git a/armsrc/pcf7931.h b/armsrc/pcf7931.h index 352997678..78496c193 100644 --- a/armsrc/pcf7931.h +++ b/armsrc/pcf7931.h @@ -29,9 +29,9 @@ bool IsBlock0PCF7931(uint8_t *block); bool IsBlock1PCF7931(const uint8_t *block); void ReadPCF7931(bool ledcontrol); void SendCmdPCF7931(const uint32_t *tab, bool ledcontrol); -bool AddBytePCF7931(uint8_t byte, uint32_t *tab, int32_t l, int32_t p); -bool AddBitPCF7931(bool b, uint32_t *tab, int32_t l, int32_t p); +bool AddBytePCF7931(uint8_t byte, uint32_t *tab, int8_t offsetPulseWidth, int8_t offsetPulsePosition); +bool AddBitPCF7931(bool b, uint32_t *tab, int8_t offsetPulseWidth, int8_t offsetPulsePosition); bool AddPatternPCF7931(uint32_t a, uint32_t b, uint32_t c, uint32_t *tab); -void WritePCF7931(uint8_t pass1, uint8_t pass2, uint8_t pass3, uint8_t pass4, uint8_t pass5, uint8_t pass6, uint8_t pass7, uint16_t init_delay, int32_t l, int32_t p, uint8_t address, uint8_t byte, uint8_t data, bool ledcontrol); +void WritePCF7931(uint8_t pass1, uint8_t pass2, uint8_t pass3, uint8_t pass4, uint8_t pass5, uint8_t pass6, uint8_t pass7, uint16_t init_delay, int8_t offsetPulseWidth, int8_t offsetPulsePosition, uint8_t address, uint8_t byte, uint8_t data, bool ledcontrol); #endif From 8723037e683cb752489283fea3432a92ab79040d Mon Sep 17 00:00:00 2001 From: tinooo <34310283+tinooo@users.noreply.github.com> Date: Tue, 4 Mar 2025 15:56:38 +0100 Subject: [PATCH 07/12] [PCF7931] refactor SendCmdPCF7931 first steps in understading and optimizing this function. replace != with < - if we don't poll fast enough, it is possible that the condition != is missed. --- armsrc/pcf7931.c | 8 ++++---- client/src/cmdlfpcf7931.c | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/armsrc/pcf7931.c b/armsrc/pcf7931.c index a49dfa327..d2d5ab9f6 100644 --- a/armsrc/pcf7931.c +++ b/armsrc/pcf7931.c @@ -555,7 +555,7 @@ void SendCmdPCF7931(const uint32_t *tab, bool ledcontrol) { AT91C_BASE_PMC->PMC_PCER |= (0x1 << AT91C_ID_TC0); AT91C_BASE_TCB->TCB_BMR = AT91C_TCB_TC0XC0S_NONE | AT91C_TCB_TC1XC1S_TIOA0 | AT91C_TCB_TC2XC2S_NONE; AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS; // timer disable - AT91C_BASE_TC0->TC_CMR = AT91C_TC_CLKS_TIMER_DIV3_CLOCK; // clock at 48/32 MHz + AT91C_BASE_TC0->TC_CMR = AT91C_TC_CLKS_TIMER_DIV3_CLOCK; // clock at 48/32 MHz (48Mhz clock, 32 = prescaler (div3)) AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN; // Assert a sync signal. This sets all timers to 0 on next active clock edge @@ -565,19 +565,19 @@ void SendCmdPCF7931(const uint32_t *tab, bool ledcontrol) { for (u = 0; tab[u] != 0; u += 3) { // modulate antenna HIGH(GPIO_SSC_DOUT); - while (tempo != tab[u]) { + while (tempo < tab[u]) { tempo = AT91C_BASE_TC0->TC_CV; } // stop modulating antenna LOW(GPIO_SSC_DOUT); - while (tempo != tab[u + 1]) { + while (tempo < tab[u + 1]) { tempo = AT91C_BASE_TC0->TC_CV; } // modulate antenna HIGH(GPIO_SSC_DOUT); - while (tempo != tab[u + 2]) { + while (tempo < tab[u + 2]) { tempo = AT91C_BASE_TC0->TC_CV; } } diff --git a/client/src/cmdlfpcf7931.c b/client/src/cmdlfpcf7931.c index 53bc19f03..8b7e73def 100644 --- a/client/src/cmdlfpcf7931.c +++ b/client/src/cmdlfpcf7931.c @@ -105,8 +105,8 @@ static int CmdLFPCF7931Config(const char *Cmd) { arg_lit0("r", "reset", "Reset configuration to default values"), arg_str0("p", "pwd", "", "Password, 7bytes, LSB-order"), arg_u64_0("d", "delay", "", "Tag initialization delay (in us)"), - arg_int0(NULL, "lw", "", "offset, low pulses width (in us)"), - arg_int0(NULL, "lp", "", "offset, low pulses position (in us)"), + arg_int0(NULL, "lw", "", "offset, low pulses width (in us), optional!"), + arg_int0(NULL, "lp", "", "offset, low pulses position (in us), optional!"), arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, true); From d3a87ead613f27f67f71dd1036c82d7e97dc961d Mon Sep 17 00:00:00 2001 From: tinooo <34310283+tinooo@users.noreply.github.com> Date: Tue, 4 Mar 2025 16:09:21 +0100 Subject: [PATCH 08/12] [PCF7930] refactor move code move "remapping" of dataframes to the actual send function, where the timer is located --- armsrc/pcf7931.c | 31 +++++++++++++++---------------- armsrc/pcf7931.h | 2 +- 2 files changed, 16 insertions(+), 17 deletions(-) diff --git a/armsrc/pcf7931.c b/armsrc/pcf7931.c index d2d5ab9f6..fbd1b2b10 100644 --- a/armsrc/pcf7931.c +++ b/armsrc/pcf7931.c @@ -420,7 +420,6 @@ static void RealWritePCF7931( uint32_t tab[1024] = {0}; // data times frame uint32_t u = 0; uint8_t parity = 0; - bool comp = 0; //BUILD OF THE DATA FRAME //alimentation of the tag (time for initializing) @@ -485,20 +484,6 @@ static void RealWritePCF7931( // Not sure why 335*T0, but should not matter. Since programming should be finished at that point AddPatternPCF7931((640 + 335)* T0_PCF, 0, 0, tab); - //conversion of the scale time - for (u = 0; u < 500; ++u) - tab[u] = (tab[u] * 3) / 2; - - //compensation of the counter reload - while (!comp) { - comp = 1; - for (u = 0; tab[u] != 0; ++u) - if (tab[u] > 0xFFFF) { - tab[u] -= 0xFFFF; - comp = 0; - } - } - SendCmdPCF7931(tab, ledcontrol); } @@ -534,7 +519,7 @@ void WritePCF7931( * @param tab : array of the data frame */ -void SendCmdPCF7931(const uint32_t *tab, bool ledcontrol) { +void SendCmdPCF7931(uint32_t *tab, bool ledcontrol) { uint16_t u = 0, tempo = 0; if (g_dbglevel >= DBG_INFO) { @@ -546,6 +531,20 @@ void SendCmdPCF7931(const uint32_t *tab, bool ledcontrol) { FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_PASSTHRU); if (ledcontrol) LED_A_ON(); + + // rescale the values to match the time of the timer below. + for (u = 0; u < 500; ++u) { + tab[u] = (tab[u] * 3) / 2; + } + + // compensation for the counter overflow + // only one overflow should be possible. + for (u = 0; tab[u] != 0; ++u) + if (tab[u] > 0xFFFF) { + tab[u] -= 0xFFFF; + break; + } + // steal this pin from the SSP and use it to control the modulation AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT; diff --git a/armsrc/pcf7931.h b/armsrc/pcf7931.h index 78496c193..314fb7e3c 100644 --- a/armsrc/pcf7931.h +++ b/armsrc/pcf7931.h @@ -28,7 +28,7 @@ size_t DemodPCF7931(uint8_t **outBlocks, bool ledcontrol); bool IsBlock0PCF7931(uint8_t *block); bool IsBlock1PCF7931(const uint8_t *block); void ReadPCF7931(bool ledcontrol); -void SendCmdPCF7931(const uint32_t *tab, bool ledcontrol); +void SendCmdPCF7931(uint32_t *tab, bool ledcontrol); bool AddBytePCF7931(uint8_t byte, uint32_t *tab, int8_t offsetPulseWidth, int8_t offsetPulsePosition); bool AddBitPCF7931(bool b, uint32_t *tab, int8_t offsetPulseWidth, int8_t offsetPulsePosition); bool AddPatternPCF7931(uint32_t a, uint32_t b, uint32_t c, uint32_t *tab); From 23ddf69f70676d38aaf38652427a4f465cc60654 Mon Sep 17 00:00:00 2001 From: tinooo <34310283+tinooo@users.noreply.github.com> Date: Wed, 12 Mar 2025 16:37:46 +0100 Subject: [PATCH 09/12] [PCF7931] added IIR filter different tags seem to behave differently. an old tag from the car had way worse signal. Therefore filtering made it way better. Still not ideal. --- armsrc/pcf7931.c | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/armsrc/pcf7931.c b/armsrc/pcf7931.c index fbd1b2b10..c3f5ffab4 100644 --- a/armsrc/pcf7931.c +++ b/armsrc/pcf7931.c @@ -28,6 +28,13 @@ #define T0_PCF 8 //period for the pcf7931 in us #define ALLOC 16 +// IIR filter consts +#define IIR_CONST1 0.1f +#define IIR_CONST2 0.9f + +// theshold for recognition of positive/negative slope +#define THRESHOLD 80 + size_t DemodPCF7931(uint8_t **outBlocks, bool ledcontrol) { const uint8_t DECIMATION = 4; uint8_t bits[256] = {0x00}; @@ -70,7 +77,6 @@ size_t DemodPCF7931(uint8_t **outBlocks, bool ledcontrol) { uint8_t block_done; size_t num_blocks = 0; - uint8_t threshold = 50; // threshold to filter out noise, from an actual edge. EdgeType expectedNextEdge = FALLING; // direction in which the next edge is expected should go. half_switch = 0; @@ -78,15 +84,16 @@ size_t DemodPCF7931(uint8_t **outBlocks, bool ledcontrol) { block_done = 0; bitPos = 0; lastClockDuration=0; - - for (sample = 1 ; sample < g_GraphTraceLen; sample++) { + + for (sample = 1 ; sample < g_GraphTraceLen-4; sample++) { // condition is searching for the next edge, in the expected diretion. - if ( ((dest[sample] + threshold) < dest[sample-1] && expectedNextEdge == FALLING ) || - ((dest[sample] - threshold) > dest[sample-1] && expectedNextEdge == RISING )) { + //todo: without flouz + dest[sample] = (uint8_t)(dest[sample-1] * IIR_CONST1 + dest[sample] * IIR_CONST2); // apply IIR filter + + if ( ((dest[sample] + THRESHOLD) < dest[sample-1] && expectedNextEdge == FALLING ) || + ((dest[sample] - THRESHOLD) > dest[sample-1] && expectedNextEdge == RISING )) { //okay, next falling/rising edge found - - - + expectedNextEdge = (expectedNextEdge == FALLING) ? RISING : FALLING; //toggle the next expected edge samplePosCurrentEdge = sample; beforeLastClockDuration = lastClockDuration; // save the previous clock duration for PMC recognition @@ -146,7 +153,10 @@ size_t DemodPCF7931(uint8_t **outBlocks, bool ledcontrol) { } else { // some Error. maybe check tolerances. // likeley to happen in the first block. - Dbprintf(_RED_("ERROR in demodulation") " Length last clock: %d - check threshold/tolerance/signal. Toss block", lastClockDuration*DECIMATION); + + // In an Ideal world, this can be enabled. However, if only bad antenna field, this print will flood the output + // and one might miss some "good" frames. + //Dbprintf(_RED_("ERROR in demodulation") " Length last clock: %d - check threshold/tolerance/signal. Toss block", lastClockDuration*DECIMATION); // Toss this block. block_done = 1; From 0b2b2384578e326f751a366f29ae96af2785b8f5 Mon Sep 17 00:00:00 2001 From: tinooo <34310283+tinooo@users.noreply.github.com> Date: Wed, 12 Mar 2025 17:11:28 +0100 Subject: [PATCH 10/12] [PCF7931] getting things ready for PR since this is somekind of work in progress, I'm still going for a PR. This commit is reworking some comments and making the code stable (at least as good es or better as before). Also made als const as #define --- armsrc/pcf7931.c | 59 ++++++++++++++++++++++++++++-------------------- 1 file changed, 34 insertions(+), 25 deletions(-) diff --git a/armsrc/pcf7931.c b/armsrc/pcf7931.c index c3f5ffab4..a2c2121e4 100644 --- a/armsrc/pcf7931.c +++ b/armsrc/pcf7931.c @@ -32,15 +32,28 @@ #define IIR_CONST1 0.1f #define IIR_CONST2 0.9f +// used to decimate samples. this allows DoAcquisition to sample for a longer duration. +// Decimation of 4 makes sure that all blocks can be sampled at once! +#define DECIMATION 4 + +#define CLOCK (64/DECIMATION) // this actually is 64, but since samples are decimated by 2, CLOCK is also /2 +#define TOLERANCE (CLOCK / 8) +#define _16T0 (CLOCK/4) +#define _32T0 (CLOCK/2) +#define _64T0 (CLOCK) + +// calculating the two possible pmc lengths, based on the clock. -4 at the end is to make sure not to increment too far +#define PMC_16T0_LEN ((128 + 127 + 16 + 32 + 33 + 16) * CLOCK/64); +#define PMC_32T0_LEN ((128 + 127 + 16 + 32 + 33 ) * CLOCK/64); + // theshold for recognition of positive/negative slope #define THRESHOLD 80 size_t DemodPCF7931(uint8_t **outBlocks, bool ledcontrol) { - const uint8_t DECIMATION = 4; uint8_t bits[256] = {0x00}; uint8_t blocks[8][16]; uint8_t *dest = BigBuf_get_addr(); - int g_GraphTraceLen = BigBuf_max_traceLen(); + uint16_t 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. // 1 Frame is 16 Byte -> 128byte. at a T0 of 64 -> 8129 Samples per frame. @@ -48,8 +61,8 @@ size_t DemodPCF7931(uint8_t **outBlocks, bool ledcontrol) { // to make sure that one complete block is definitely being sampled, we need 2 times that // which is ~17.xxx samples. round up. and clamp to this value. - // TODO: Doublecheck why this is being limited? -// g_GraphTraceLen = (g_GraphTraceLen > 18000) ? 18000 : g_GraphTraceLen; + // TODO: Doublecheck why this is being limited? - seems not to be needed. + // g_GraphTraceLen = (g_GraphTraceLen > 18000) ? 18000 : g_GraphTraceLen; BigBuf_Clear_keep_EM(); LFSetupFPGAForADC(LF_DIVISOR_125, true); @@ -66,15 +79,6 @@ size_t DemodPCF7931(uint8_t **outBlocks, bool ledcontrol) { uint8_t beforeLastClockDuration; // store the clock duration of the cycle before the last Clock duration. Basically clockduration -2 - const uint8_t clock = 64/DECIMATION; // this actually is 64, but since samples are decimated by 2, clock is also /2 - const uint8_t tolerance = clock / 8; - const uint8_t _16T0 = clock/4; - const uint8_t _32T0 = clock/2; - const uint8_t _64T0 = clock; - - const uint16_t pmc16T0Len = (128 + 127 + 16 + 32 + 33 + 16) * clock/64; // calculating the two possible pmc lengths, based on the clock. -4 at the end is to make sure not to increment too far - const uint16_t pmc32T0Len = (128 + 127 + 16 + 32 + 33 ) * clock/64; - uint8_t block_done; size_t num_blocks = 0; EdgeType expectedNextEdge = FALLING; // direction in which the next edge is expected should go. @@ -104,13 +108,13 @@ size_t DemodPCF7931(uint8_t **outBlocks, bool ledcontrol) { // Switch depending on lastClockDuration length: // 16T0 - if (ABS(lastClockDuration - _16T0) < tolerance) { + if (ABS(lastClockDuration - _16T0) < TOLERANCE) { // if the clock before also was 16T0, it is a PMC! - if (ABS(beforeLastClockDuration - _16T0) < tolerance) { + if (ABS(beforeLastClockDuration - _16T0) < TOLERANCE) { // It's a PMC Dbprintf(_GREEN_("PMC 16T0 FOUND:") " bitPos: %d, sample: %d", bitPos, sample); - sample += pmc16T0Len; // move to the sample after PMC + sample += PMC_16T0_LEN; // move to the sample after PMC expectedNextEdge = FALLING; samplePosLastEdge = sample; @@ -118,13 +122,13 @@ size_t DemodPCF7931(uint8_t **outBlocks, bool ledcontrol) { } // 32TO - } else if (ABS(lastClockDuration - _32T0) < tolerance) { + } else if (ABS(lastClockDuration - _32T0) < TOLERANCE) { // if the clock before also was 16T0, it is a PMC! - if (ABS(beforeLastClockDuration - _16T0) < tolerance) { + if (ABS(beforeLastClockDuration - _16T0) < TOLERANCE) { // It's a PMC ! Dbprintf(_GREEN_("PMC 32T0 FOUND:") " bitPos: %d, sample: %d", bitPos, sample); - sample += pmc32T0Len; // move to the sample after PMC + sample += PMC_32T0_LEN; // move to the sample after PMC expectedNextEdge = FALLING; samplePosLastEdge = sample; @@ -144,7 +148,7 @@ size_t DemodPCF7931(uint8_t **outBlocks, bool ledcontrol) { half_switch++; // 64T0 - } else if (ABS(lastClockDuration - _64T0) < tolerance) { + } else if (ABS(lastClockDuration - _64T0) < TOLERANCE) { // this means, bit here is 1 bits[bitPos] = 1; bitPos++; @@ -248,10 +252,7 @@ bool IsBlock1PCF7931(const uint8_t *block) { void ReadPCF7931(bool ledcontrol) { - Dbprintf("ReadPCF7931()=========="); - uint8_t maxBlocks = 8; // readable blocks - int found_blocks = 0; // successfully read blocks // TODO: Why 17 byte len? 16 should be good. @@ -275,7 +276,7 @@ void ReadPCF7931(bool ledcontrol) { //j = 0; do { - Dbprintf("ReadPCF7931() -- DO LOOP =========="); + Dbprintf("ReadPCF7931() -- Reading Loop =========="); i = 0; memset(tmp_blocks, 0, 4 * 16 * sizeof(uint8_t)); @@ -299,6 +300,9 @@ void ReadPCF7931(bool ledcontrol) { goto end; } + // This part was not working properly. + // So currently the blocks are not being sorted, but at least printed. + // // our logic breaks if we don't get at least two blocks // if (n < 2) { // // skip if all 0s block or no blocks @@ -328,8 +332,9 @@ void ReadPCF7931(bool ledcontrol) { // if (g_dbglevel >= DBG_EXTENDED) // Dbprintf("(dbg) got %d blocks (%d/%d found) (%d tries, %d errors)", n, found_blocks, (maxBlocks == 0 ? found_blocks : maxBlocks), tries, errors); + // print blocks that have been found for (i = 0; i < n; ++i) { - print_result("got consecutive blocks", tmp_blocks[i], 16); + print_result("Block found: ", tmp_blocks[i], 16); } // i = 0; @@ -396,7 +401,9 @@ void ReadPCF7931(bool ledcontrol) { } } while (found_blocks < maxBlocks); + end: +/* Dbprintf("-----------------------------------------"); Dbprintf("Memory content:"); Dbprintf("-----------------------------------------"); @@ -417,6 +424,8 @@ end: Dbprintf("-----------------------------------------"); } +*/ + reply_mix(CMD_ACK, 0, 0, 0, 0, 0); } From e9ef11f81273e84da95d2a824f6310b86eb6d7ed Mon Sep 17 00:00:00 2001 From: tinooo <34310283+tinooo@users.noreply.github.com> Date: Fri, 14 Mar 2025 09:01:06 +0100 Subject: [PATCH 11/12] [PCF7931] Added infos to CHANGELOG.md --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a50827e96..7510597a5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,8 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] +- Improved `pcf7931` generic readability of the code. Unified datatypes and added documentation/explainations (@tinooo) +- Improved `lf pcf7931` read code - fixed some checks for more stability (@tinooo) - Changed `trace list -t seos` - improved annotation (@iceman1001) - Added `make commands` to regenerate commands documentation files and autocompletion data independently of `make style` (@doegox) - Added texecom identification, thanks @en4rab ! (@iceman1001) From 939f5cb11fc53f470b1360f9d1e22b65cedb5ff0 Mon Sep 17 00:00:00 2001 From: tinooo <34310283+tinooo@users.noreply.github.com> Date: Fri, 14 Mar 2025 09:05:53 +0100 Subject: [PATCH 12/12] [PCF7931] Added type cast to compare equally sized types the github pipeline was stressed about comparing an uint16_t to an uint32_t. --- armsrc/pcf7931.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/armsrc/pcf7931.c b/armsrc/pcf7931.c index a2c2121e4..c1f2e3f7f 100644 --- a/armsrc/pcf7931.c +++ b/armsrc/pcf7931.c @@ -583,19 +583,19 @@ void SendCmdPCF7931(uint32_t *tab, bool ledcontrol) { for (u = 0; tab[u] != 0; u += 3) { // modulate antenna HIGH(GPIO_SSC_DOUT); - while (tempo < tab[u]) { + while ((uint32_t)tempo < tab[u]) { tempo = AT91C_BASE_TC0->TC_CV; } // stop modulating antenna LOW(GPIO_SSC_DOUT); - while (tempo < tab[u + 1]) { + while ((uint32_t)tempo < tab[u + 1]) { tempo = AT91C_BASE_TC0->TC_CV; } // modulate antenna HIGH(GPIO_SSC_DOUT); - while (tempo < tab[u + 2]) { + while ((uint32_t)tempo < tab[u + 2]) { tempo = AT91C_BASE_TC0->TC_CV; } }