mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-19 21:03:48 -07:00
[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?
This commit is contained in:
parent
3a8dc89dca
commit
9bfd55ebe0
1 changed files with 78 additions and 76 deletions
152
armsrc/pcf7931.c
152
armsrc/pcf7931.c
|
@ -39,133 +39,118 @@ size_t DemodPCF7931(uint8_t **outBlocks, bool ledcontrol) {
|
||||||
int g_GraphTraceLen = BigBuf_max_traceLen();
|
int g_GraphTraceLen = BigBuf_max_traceLen();
|
||||||
// limit g_GraphTraceLen to a little more than 2 data frames.
|
// limit g_GraphTraceLen to a little more than 2 data frames.
|
||||||
// To make sure a complete dataframe is in the dataset.
|
// To make sure a complete dataframe is in the dataset.
|
||||||
if (g_GraphTraceLen > 18000) {
|
// 1 Frame is 16 Byte -> 128byte. at a T0 of 64 -> 8129 Samples per frame.
|
||||||
g_GraphTraceLen = 18000;
|
// + 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.
|
||||||
|
|
||||||
int i = 2, j, bitPos;
|
// TODO: Doublecheck why this is being limited?
|
||||||
|
g_GraphTraceLen = (g_GraphTraceLen > 18000) ? 18000 : g_GraphTraceLen;
|
||||||
|
|
||||||
|
uint8_t j;
|
||||||
uint8_t half_switch;
|
uint8_t half_switch;
|
||||||
|
|
||||||
uint16_t bitPosLastEdge;
|
uint8_t bitPos; // max 128 bit in one block. if more, then there is an error and PMC was not found.
|
||||||
uint16_t bitPosCurrentEdge;
|
|
||||||
uint8_t lastClockDuration; // used to store the duration of the last "clock", for decoding.
|
uint16_t sample; // to keep track of the current sample that is being analyzed
|
||||||
// clock may not be the correct term, maybe bit is better.
|
uint16_t samplePosLastEdge;
|
||||||
// The duration between two edges is meant
|
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 clock = 64;
|
||||||
const uint8_t tolerance = clock / 8;
|
const uint8_t tolerance = clock / 8;
|
||||||
const uint8_t _16T0 = clock/4;
|
const uint8_t _16T0 = clock/4;
|
||||||
const uint8_t _32T0 = clock/2;
|
const uint8_t _32T0 = clock/2;
|
||||||
const uint8_t _64T0 = clock;
|
const uint8_t _64T0 = clock;
|
||||||
|
|
||||||
int pmc, block_done;
|
int block_done;
|
||||||
int warnings = 0;
|
int warnings = 0;
|
||||||
size_t num_blocks = 0;
|
size_t num_blocks = 0;
|
||||||
// int lmin = 64, lmax = 192; // used for some thresholds to identify high/low
|
// 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.
|
uint8_t threshold = 30; // threshold to filter out noise, from an actual edge.
|
||||||
EdgeType expectedNextEdge = UNDEFINED; // direction in which the next slope is expected should go.
|
EdgeType expectedNextEdge = UNDEFINED; // direction in which the next edge 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 */
|
sample = 1;
|
||||||
// if (dest[1] > dest[0]) {
|
while (sample < g_GraphTraceLen && expectedNextEdge==UNDEFINED) {
|
||||||
// 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
|
// 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
|
expectedNextEdge = RISING; // current edge is falling, so next has to be rising
|
||||||
|
|
||||||
// find rising edge
|
// 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
|
expectedNextEdge = FALLING; // current edge is rising, so next has to be falling
|
||||||
}
|
}
|
||||||
|
|
||||||
i++;
|
sample++;
|
||||||
}
|
}
|
||||||
|
|
||||||
bitPosLastEdge = i++;
|
samplePosLastEdge = sample++;
|
||||||
half_switch = 0;
|
half_switch = 0;
|
||||||
pmc = 0;
|
|
||||||
block_done = 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.
|
if (sample%4 == 0){
|
||||||
// Imagine dest[i-1] = 255 and dest[i] = 0. THis would mean a clear falling edge.
|
// Dbprintf("dest[%d]: %d, bitPos: %d",sample, dest[sample], bitPos);
|
||||||
// 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.
|
// condition is searching for the next edge, in the expected diretion.
|
||||||
if ( ((dest[i] + threshold) < dest[i-1] && expectedNextEdge == FALLING ) ||
|
if ( ((dest[sample] + threshold) < dest[sample-1] && expectedNextEdge == FALLING ) ||
|
||||||
((dest[i] - threshold) > dest[i-1] && expectedNextEdge == RISING )) {
|
((dest[sample] - threshold) > dest[sample-1] && expectedNextEdge == RISING )) {
|
||||||
|
//okay, next falling/rising edge found
|
||||||
|
|
||||||
expectedNextEdge = (expectedNextEdge == FALLING) ? RISING : FALLING; //toggle the next expected edge
|
expectedNextEdge = (expectedNextEdge == FALLING) ? RISING : FALLING; //toggle the next expected edge
|
||||||
//okay, next falling/rising edge found
|
samplePosCurrentEdge = sample;
|
||||||
bitPosCurrentEdge = i;
|
beforeLastClockDuration = lastClockDuration; // save the previous clock duration for PMC recognition
|
||||||
|
lastClockDuration = samplePosCurrentEdge - samplePosLastEdge;
|
||||||
lastClockDuration = bitPosCurrentEdge - bitPosLastEdge;
|
samplePosLastEdge = sample;
|
||||||
bitPosLastEdge = i;
|
|
||||||
|
|
||||||
// Switch depending on lastClockDuration length:
|
// Switch depending on lastClockDuration length:
|
||||||
// Tolerance is 1/8 of clock rate (arbitrary)
|
// Tolerance is 1/8 of clock rate (arbitrary)
|
||||||
|
|
||||||
// 16T0
|
// 16T0
|
||||||
if (ABS(lastClockDuration - _16T0) < tolerance) {
|
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
|
// It's a PMC
|
||||||
Dbprintf(_GREEN_("PMC 16T0 FOUND:") " at i: %d", i);
|
Dbprintf(_GREEN_("PMC 16T0 FOUND:") " bitPos: %d, sample: %d", bitPos, sample);
|
||||||
i += (128 + 127 + 16 + 32 + 33 + 16) - 1;
|
sample += (128 + 127 + 16 + 32 + 33 + 16) - 1; // move to the sample after PMC
|
||||||
bitPosLastEdge = i;
|
samplePosLastEdge = sample;
|
||||||
pmc = 0;
|
|
||||||
block_done = 1;
|
block_done = 1;
|
||||||
} else {
|
// TODO: Not sure if sample need to set expected next edge?
|
||||||
pmc = i;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 32TO
|
// 32TO
|
||||||
} else if (ABS(lastClockDuration - _32T0) < tolerance) {
|
} 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 !
|
// It's a PMC !
|
||||||
Dbprintf(_GREEN_("PMC 32T0 FOUND:") " at i: %d", i);
|
Dbprintf(_GREEN_("PMC 32T0 FOUND:") " bitPos: %d, sample: %d", bitPos, sample);
|
||||||
i += (128 + 127 + 16 + 32 + 33) - 1;
|
sample += (128 + 127 + 16 + 32 + 33) - 1; // move to the sample after PMC
|
||||||
bitPosLastEdge = i;
|
samplePosLastEdge = sample;
|
||||||
pmc = 0;
|
|
||||||
block_done = 1;
|
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 no pmc, then its a normal bit. Check if its the second time, the edge changed
|
||||||
// if yes, then the bit is 0
|
// if yes, then the bit is 0
|
||||||
} else if (half_switch == 1) {
|
} else if (half_switch == 1) {
|
||||||
bits[bitPos++] = 0;
|
bits[bitPos] = 0;
|
||||||
// reset the edge counter to 0
|
// reset the edge counter to 0
|
||||||
half_switch = 0;
|
half_switch = 0;
|
||||||
|
bitPos++;
|
||||||
|
|
||||||
// so it is the first time the edge changed. No bit value will be set here, bit if the
|
// 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.
|
// edge changes again, it will be. see case above.
|
||||||
|
@ -174,10 +159,13 @@ size_t DemodPCF7931(uint8_t **outBlocks, bool ledcontrol) {
|
||||||
|
|
||||||
// 64T0
|
// 64T0
|
||||||
} else if (ABS(lastClockDuration - _64T0) < tolerance) {
|
} else if (ABS(lastClockDuration - _64T0) < tolerance) {
|
||||||
bits[bitPos++] = 1;
|
// this means, bit here is 1
|
||||||
|
bits[bitPos] = 1;
|
||||||
|
bitPos++;
|
||||||
|
|
||||||
// Error
|
// Error
|
||||||
} else {
|
} else {
|
||||||
|
Dbprintf(_RED_("ELSE error case") " bitPos: %d, sample: %d", bitPos, sample);
|
||||||
if (++warnings > 10) {
|
if (++warnings > 10) {
|
||||||
|
|
||||||
if (g_dbglevel >= DBG_EXTENDED) {
|
if (g_dbglevel >= DBG_EXTENDED) {
|
||||||
|
@ -189,6 +177,10 @@ size_t DemodPCF7931(uint8_t **outBlocks, bool ledcontrol) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (block_done == 1) {
|
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) {
|
if (bitPos == 128) {
|
||||||
for (j = 0; j < 16; ++j) {
|
for (j = 0; j < 16; ++j) {
|
||||||
blocks[num_blocks][j] =
|
blocks[num_blocks][j] =
|
||||||
|
@ -204,6 +196,7 @@ size_t DemodPCF7931(uint8_t **outBlocks, bool ledcontrol) {
|
||||||
}
|
}
|
||||||
num_blocks++;
|
num_blocks++;
|
||||||
}
|
}
|
||||||
|
// now start over for the next block / first complete block.
|
||||||
bitPos = 0;
|
bitPos = 0;
|
||||||
block_done = 0;
|
block_done = 0;
|
||||||
half_switch = 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;
|
bitPos = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Todo: No idea, why blocks 4 is checked..
|
||||||
if (num_blocks == 4) {
|
if (num_blocks == 4) {
|
||||||
|
Dbprintf(_RED_("we should never get here!!!") " at sample: %d", sample);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -264,6 +262,9 @@ bool IsBlock1PCF7931(const uint8_t *block) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ReadPCF7931(bool ledcontrol) {
|
void ReadPCF7931(bool ledcontrol) {
|
||||||
|
|
||||||
|
Dbprintf("ReadPCF7931()==========");
|
||||||
|
|
||||||
int found_blocks = 0; // successfully read blocks
|
int found_blocks = 0; // successfully read blocks
|
||||||
int max_blocks = 8; // readable blocks
|
int max_blocks = 8; // readable blocks
|
||||||
uint8_t memory_blocks[8][17]; // PCF content
|
uint8_t memory_blocks[8][17]; // PCF content
|
||||||
|
@ -283,6 +284,7 @@ void ReadPCF7931(bool ledcontrol) {
|
||||||
int i = 0, j = 0;
|
int i = 0, j = 0;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
Dbprintf("ReadPCF7931() -- DO LOOP ==========");
|
||||||
i = 0;
|
i = 0;
|
||||||
|
|
||||||
memset(tmp_blocks, 0, 4 * 16 * sizeof(uint8_t));
|
memset(tmp_blocks, 0, 4 * 16 * sizeof(uint8_t));
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue