mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-19 21:03:48 -07:00
[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:
parent
f8abfc0731
commit
3a8dc89dca
2 changed files with 115 additions and 48 deletions
156
armsrc/pcf7931.c
156
armsrc/pcf7931.c
|
@ -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) {
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue