Files
mayhem-firmware/firmware/baseband/fprotos/c-fiat_v0.hpp
T
2026-01-10 14:47:33 +01:00

201 lines
7.8 KiB
C++

#pragma once
#include "subcarbase.hpp"
#include <cstring>
typedef enum {
FiatV0DecoderStepReset = 0,
FiatV0DecoderStepPreamble = 1,
FiatV0DecoderStepData = 2,
} FiatV0DecoderStep;
class FProtoSubCarFiatV0 : public FProtoSubCarBase {
public:
FProtoSubCarFiatV0() {
sensorType = FPC_FIATV0;
te_short = 200;
te_long = 400;
te_delta = 100;
min_count_bit_for_found = 64;
}
void feed(bool level, uint32_t duration) {
uint32_t gap_threshold = 800;
uint32_t diff;
switch (decoder_state) {
case FiatV0DecoderStepReset:
if (!level) {
return;
}
if (duration < te_short) {
diff = te_short - duration;
} else {
diff = duration - te_short;
}
if (diff < te_delta) {
data_low = 0;
data_high = 0;
decoder_state = FiatV0DecoderStepPreamble;
te_last = duration;
preamble_count = 0;
bit_count = 0;
FProtoGeneral::manchester_advance(
manchester_state,
ManchesterEventReset,
&manchester_state,
NULL);
}
break;
case FiatV0DecoderStepPreamble:
if (level) {
return;
}
if (duration < te_short) {
diff = te_short - duration;
if (diff < te_delta) {
preamble_count++;
te_last = duration;
if (preamble_count >= 0x96) {
if (duration < gap_threshold) {
diff = gap_threshold - duration;
} else {
diff = duration - gap_threshold;
}
if (diff < te_delta) {
decoder_state = FiatV0DecoderStepData;
preamble_count = 0;
data_low = 0;
data_high = 0;
bit_count = 0;
te_last = duration;
return;
}
}
} else {
decoder_state = FiatV0DecoderStepReset;
if (preamble_count >= 0x96) {
if (duration < gap_threshold) {
diff = gap_threshold - duration;
} else {
diff = duration - gap_threshold;
}
if (diff < te_delta) {
decoder_state = FiatV0DecoderStepData;
preamble_count = 0;
data_low = 0;
data_high = 0;
bit_count = 0;
te_last = duration;
return;
}
}
}
} else {
diff = duration - te_short;
if (diff < te_delta) {
preamble_count++;
te_last = duration;
} else {
decoder_state = FiatV0DecoderStepReset;
}
if (preamble_count >= 0x96) {
if (duration >= 799) {
diff = duration - gap_threshold;
} else {
diff = gap_threshold - duration;
}
if (diff < te_delta) {
decoder_state = FiatV0DecoderStepData;
preamble_count = 0;
data_low = 0;
data_high = 0;
bit_count = 0;
te_last = duration;
return;
}
}
}
break;
case FiatV0DecoderStepData:
ManchesterEvent event = ManchesterEventReset;
if (duration < te_short) {
diff = te_short - duration;
if (diff < te_delta) {
event = level ? ManchesterEventShortLow : ManchesterEventShortHigh;
}
} else {
diff = duration - te_short;
if (diff < te_delta) {
event = level ? ManchesterEventShortLow : ManchesterEventShortHigh;
} else {
if (duration < te_long) {
diff = te_long - duration;
} else {
diff = duration - te_long;
}
if (diff < te_delta) {
event = level ? ManchesterEventLongLow : ManchesterEventLongHigh;
}
}
}
if (event != ManchesterEventReset) {
bool data_bit_bool;
if (FProtoGeneral::manchester_advance(
manchester_state,
event,
&manchester_state,
&data_bit_bool)) {
uint32_t new_bit = data_bit_bool ? 1 : 0;
uint32_t carry = (data_low >> 31) & 1;
data_low = (data_low << 1) | new_bit;
data_high = (data_high << 1) | carry;
bit_count++;
if (bit_count == 0x40) {
fix = data_low;
hop = data_high;
data_low = 0;
data_high = 0;
}
if (bit_count > 0x46) {
endbyte = (uint8_t)data_low;
/*
generic.data = ((uint64_t)hop << 32) | fix;
generic.data_count_bit = 64;
generic.serial = fix;
generic.btn = endbyte; // still exported as btn for UI compatibility
generic.cnt = hop;
*/
decode_data = ((uint64_t)hop << 32) | fix; // this is my own data passer, not the original
decode_data2 = endbyte;
data_count_bit = 64;
if (callback) {
callback(this);
}
data_low = 0;
data_high = 0;
bit_count = 0;
decoder_state = FiatV0DecoderStepReset;
}
}
}
te_last = duration;
break;
}
}
ManchesterState manchester_state = ManchesterStateMid1;
uint8_t decoder_state = 0;
uint8_t bit_count = 0;
uint8_t endbyte = 0;
uint16_t preamble_count = 0;
uint32_t data_low = 0;
uint32_t data_high = 0;
uint32_t hop = 0;
uint32_t fix = 0;
};