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

136 lines
4.5 KiB
C++

#pragma once
#include "subcarbase.hpp"
#define SUZUKI_GAP_TIME 2000
#define SUZUKI_GAP_DELTA 400
typedef enum {
SuzukiDecoderStepReset = 0,
SuzukiDecoderStepCountPreamble = 1,
SuzukiDecoderStepDecodeData = 2,
} SuzukiDecoderStep;
class FProtoSubCarSuzuki : public FProtoSubCarBase {
public:
FProtoSubCarSuzuki() {
sensorType = FPC_SUZUKI;
te_short = 250;
te_long = 500;
te_delta = 110;
min_count_bit_for_found = 64;
}
void suzuki_add_bit(uint32_t bit) {
decode_data = (decode_data << 1) | bit;
decode_count_bit++;
}
void subghz_protocol_decoder_suzuki_reset() {
parser_step = SuzukiDecoderStepReset;
header_count = 0;
data_count_bit = 0;
decode_data = 0;
}
void feed(bool level, uint32_t duration) {
switch (parser_step) {
case SuzukiDecoderStepReset:
// Wait for HIGH pulse (~250µs) to start preamble
if (!level) {
return;
}
if (DURATION_DIFF(duration, te_short) > te_delta) {
return;
}
decode_data = 0;
decode_count_bit = 0;
parser_step = SuzukiDecoderStepCountPreamble;
header_count = 0;
break;
case SuzukiDecoderStepCountPreamble:
if (level) {
// HIGH pulse
if (header_count >= 300) {
if (DURATION_DIFF(duration, te_long) <= te_delta) {
parser_step = SuzukiDecoderStepDecodeData;
suzuki_add_bit(1);
}
}
} else {
if (DURATION_DIFF(duration, te_short) <= te_delta) {
te_last = duration;
header_count++;
} else {
parser_step = SuzukiDecoderStepReset;
}
}
break;
case SuzukiDecoderStepDecodeData:
if (level) {
// HIGH pulse - determines bit value
if (duration < te_long) {
uint32_t diff_long = 500 - duration;
if (diff_long > 99) {
uint32_t diff_short;
if (duration < 250) {
diff_short = 250 - duration;
} else {
diff_short = duration - 250;
}
if (diff_short <= 99) {
suzuki_add_bit(0);
}
} else {
suzuki_add_bit(1);
}
} else {
uint32_t diff_long = duration - 500;
if (diff_long <= 99) {
suzuki_add_bit(1);
}
}
} else {
// LOW pulse - check for gap (end of transmission)
uint32_t diff_gap;
if (duration < SUZUKI_GAP_TIME) {
diff_gap = SUZUKI_GAP_TIME - duration;
} else {
diff_gap = duration - SUZUKI_GAP_TIME;
}
if (diff_gap <= SUZUKI_GAP_DELTA) {
if (decode_count_bit == 64) {
// instance->generic.data = decode_data;
data_count_bit = 64;
/*uint64_t data = instance->generic.data;
uint32_t data_high = (uint32_t)(data >> 32);
uint32_t data_low = (uint32_t)data;
instance->generic.serial = ((data_high & 0xFFF) << 16) | (data_low >> 16);
instance->generic.btn = (data_low >> 12) & 0xF;
instance->generic.cnt = (data_high << 4) >> 16;
*/
if (callback) {
callback(this);
}
}
decode_data = 0;
decode_count_bit = 0;
parser_step = SuzukiDecoderStepReset;
}
}
break;
}
}
uint16_t header_count = 0;
uint8_t data_count_bit = 0;
};