mirror of
https://github.com/portapack-mayhem/mayhem-firmware.git
synced 2026-08-21 23:19:02 +00:00
Updated subcar processors (#2913)
This commit is contained in:
+73
-9
@@ -266,10 +266,11 @@ void SubCarRecentEntryDetailView::parseProtocol() {
|
||||
if (entry_.sensorType == FPC_Invalid) return;
|
||||
|
||||
if (entry_.sensorType == FPC_SUZUKI) {
|
||||
uint32_t serial_button = (((entry_.data >> 32) & 0xFFF) << 20) | (entry_.data >> 12);
|
||||
serial = serial_button >> 4;
|
||||
uint8_t buttonid = serial_button & 0xF;
|
||||
cnt = (entry_.data >> 44) & 0xFFFF;
|
||||
uint32_t data_high = (uint32_t)(entry_.data >> 32);
|
||||
uint32_t data_low = (uint32_t)entry_.data;
|
||||
serial = ((data_high & 0xFFF) << 16) | (data_low >> 16);
|
||||
uint8_t buttonid = (data_low >> 12) & 0xF;
|
||||
cnt = (data_high << 4) >> 16;
|
||||
btn = to_string_dec_uint(buttonid);
|
||||
return;
|
||||
}
|
||||
@@ -320,15 +321,78 @@ void SubCarRecentEntryDetailView::parseProtocol() {
|
||||
}
|
||||
|
||||
if (entry_.sensorType == FPC_KIAV5) {
|
||||
serial = (uint32_t)(((entry_.data >> 32) & 0x0FFFFFFF) >> 1);
|
||||
uint8_t button = (entry_.data >> 61) & 0x07;
|
||||
uint64_t yek = 0;
|
||||
for (int i = 0; i < 8; i++) {
|
||||
uint8_t byte = (entry_.data2 >> (i * 8)) & 0xFF;
|
||||
uint8_t reversed = 0;
|
||||
for (int b = 0; b < 8; b++) {
|
||||
if (byte & (1 << b))
|
||||
reversed |= (1 << (7 - b));
|
||||
}
|
||||
yek |= ((uint64_t)reversed << ((7 - i) * 8));
|
||||
}
|
||||
serial = (uint32_t)((yek >> 32) & 0x0FFFFFFF);
|
||||
uint8_t button = (uint8_t)((yek >> 60) & 0x0F);
|
||||
uint32_t encrypted = (uint32_t)(yek & 0xFFFFFFFF);
|
||||
btn = to_string_dec_uint(button);
|
||||
cnt = (uint16_t)(entry_.data & 0xFFFF);
|
||||
// decode
|
||||
uint8_t keystore_bytes[] = {0x53, 0x54, 0x46, 0x52, 0x4b, 0x45, 0x30, 0x30};
|
||||
uint8_t s0 = (encrypted & 0xFF);
|
||||
uint8_t s1 = (encrypted >> 8) & 0xFF;
|
||||
uint8_t s2 = (encrypted >> 16) & 0xFF;
|
||||
uint8_t s3 = (encrypted >> 24) & 0xFF;
|
||||
int round_index = 1;
|
||||
for (size_t i = 0; i < 18; i++) {
|
||||
uint8_t r = keystore_bytes[round_index] & 0xFF;
|
||||
int steps = 8;
|
||||
while (steps > 0) {
|
||||
uint8_t base;
|
||||
if ((s3 & 0x40) == 0) {
|
||||
base = (s3 & 0x02) == 0 ? 0x74 : 0x2E;
|
||||
} else {
|
||||
base = (s3 & 0x02) == 0 ? 0x3A : 0x5C;
|
||||
}
|
||||
|
||||
if (s2 & 0x08) {
|
||||
base = (((base >> 4) & 0x0F) | ((base & 0x0F) << 4)) & 0xFF;
|
||||
}
|
||||
if (s1 & 0x01) {
|
||||
base = ((base & 0x3F) << 2) & 0xFF;
|
||||
}
|
||||
if (s0 & 0x01) {
|
||||
base = (base << 1) & 0xFF;
|
||||
}
|
||||
|
||||
uint8_t temp = (s3 ^ s1) & 0xFF;
|
||||
s3 = ((s3 & 0x7F) << 1) & 0xFF;
|
||||
if (s2 & 0x80) {
|
||||
s3 |= 0x01;
|
||||
}
|
||||
s2 = ((s2 & 0x7F) << 1) & 0xFF;
|
||||
if (s1 & 0x80) {
|
||||
s2 |= 0x01;
|
||||
}
|
||||
s1 = ((s1 & 0x7F) << 1) & 0xFF;
|
||||
if (s0 & 0x80) {
|
||||
s1 |= 0x01;
|
||||
}
|
||||
s0 = ((s0 & 0x7F) << 1) & 0xFF;
|
||||
|
||||
uint8_t chk = (base ^ (r ^ temp)) & 0xFF;
|
||||
if (chk & 0x80) {
|
||||
s0 |= 0x01;
|
||||
}
|
||||
r = ((r & 0x7F) << 1) & 0xFF;
|
||||
steps--;
|
||||
}
|
||||
round_index = (round_index - 1) & 0x7;
|
||||
}
|
||||
cnt = (s0 + (s1 << 8)) & 0xFFFF;
|
||||
}
|
||||
|
||||
if (entry_.sensorType == FPC_KIAV3V4) {
|
||||
// not decrypted!
|
||||
serial = SD_NO_SERIAL; //(uint32_t)entry_.data;
|
||||
serial = (uint32_t)entry_.data;
|
||||
// uint8_t button = entry_.data2 & 0xFF;
|
||||
btn = "?"; // to_string_dec_uint(button);
|
||||
}
|
||||
@@ -344,7 +408,7 @@ void SubCarRecentEntryDetailView::parseProtocol() {
|
||||
if (entry_.sensorType == FPC_KIAV1) {
|
||||
serial = (uint32_t)((entry_.data >> 24) & 0xFFFFFFFF);
|
||||
uint8_t button = (uint8_t)((entry_.data >> 16) & 0xFF);
|
||||
cnt = (uint8_t)((entry_.data >> 8) & 0xFF);
|
||||
cnt = (uint8_t)((entry_.data >> 4) & 0xF) << 8 | ((entry_.data >> 8) & 0xFF);
|
||||
btn = to_string_dec_uint(button);
|
||||
}
|
||||
|
||||
|
||||
@@ -161,8 +161,6 @@ class FProtoSubCarFiatV0 : public FProtoSubCarBase {
|
||||
}
|
||||
|
||||
if (bit_count > 0x46) {
|
||||
final_count = bit_count;
|
||||
|
||||
endbyte = (uint8_t)data_low;
|
||||
/*
|
||||
generic.data = ((uint64_t)hop << 32) | fix;
|
||||
@@ -192,13 +190,11 @@ class FProtoSubCarFiatV0 : public FProtoSubCarBase {
|
||||
|
||||
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;
|
||||
uint8_t bit_count = 0;
|
||||
uint32_t hop = 0;
|
||||
uint32_t fix = 0;
|
||||
uint8_t endbyte = 0;
|
||||
uint8_t final_count = 0;
|
||||
uint32_t te_last = 0;
|
||||
};
|
||||
|
||||
@@ -59,20 +59,26 @@ class FProtoSubCarKiaV0 : public FProtoSubCarBase {
|
||||
break;
|
||||
case KIADecoderStepSaveDuration:
|
||||
if (level) {
|
||||
if (duration >=
|
||||
(te_long + te_delta * 2UL)) {
|
||||
// Signal ended too early!
|
||||
// FURI_LOG_W(TAG, "Signal ended at %u bits (expected 61). Duration: %lu", decode_count_bit, duration);
|
||||
|
||||
if (duration >= (te_long + te_delta * 2UL)) {
|
||||
// End of transmission detected
|
||||
parser_step = KIADecoderStepReset;
|
||||
|
||||
if (decode_count_bit == min_count_bit_for_found) {
|
||||
// instance->generic.data = decode_data;
|
||||
// data = decode_data;
|
||||
data_count_bit = decode_count_bit;
|
||||
// just used for log yet, so skip
|
||||
// if (kia_verify_crc()) {
|
||||
// FURI_LOG_I(TAG, "Valid signal received with correct CRC");
|
||||
// } else {
|
||||
// FURI_LOG_W(TAG, "Signal received but CRC mismatch!");
|
||||
// }
|
||||
|
||||
if (callback)
|
||||
callback(this);
|
||||
} else {
|
||||
// FURI_LOG_E(TAG, "Incomplete signal: only %u bits", decode_count_bit);
|
||||
// FURI_LOG_E(TAG, "Incomplete signal: only %u bits", instance->decoder.decode_count_bit);
|
||||
}
|
||||
|
||||
decode_data = 0;
|
||||
decode_count_bit = 0;
|
||||
break;
|
||||
@@ -80,26 +86,19 @@ class FProtoSubCarKiaV0 : public FProtoSubCarBase {
|
||||
te_last = duration;
|
||||
parser_step = KIADecoderStepCheckDuration;
|
||||
}
|
||||
|
||||
} else {
|
||||
parser_step = KIADecoderStepReset;
|
||||
}
|
||||
break;
|
||||
case KIADecoderStepCheckDuration:
|
||||
if (!level) {
|
||||
if ((DURATION_DIFF(te_last, te_short) < te_delta) &&
|
||||
(DURATION_DIFF(duration, te_short) < te_delta)) {
|
||||
if ((DURATION_DIFF(te_last, te_short) < te_delta) && (DURATION_DIFF(duration, te_short) < te_delta)) {
|
||||
subghz_protocol_blocks_add_bit(0);
|
||||
if (decode_count_bit % 10 == 0) {
|
||||
// FURI_LOG_D(TAG, "Decoded %u bits so far", decode_count_bit);
|
||||
}
|
||||
parser_step = KIADecoderStepSaveDuration;
|
||||
} else if (
|
||||
(DURATION_DIFF(te_last, te_long) < te_delta) &&
|
||||
(DURATION_DIFF(duration, te_long) < te_delta)) {
|
||||
(DURATION_DIFF(te_last, te_long) < te_delta) && (DURATION_DIFF(duration, te_long) < te_delta)) {
|
||||
subghz_protocol_blocks_add_bit(1);
|
||||
if (decode_count_bit % 10 == 0) {
|
||||
// FURI_LOG_D(TAG, "Decoded %u bits so far", decode_count_bit);
|
||||
}
|
||||
parser_step = KIADecoderStepSaveDuration;
|
||||
} else {
|
||||
// FURI_LOG_W(TAG, "Timing mismatch at bit %u. Last: %lu, Current: %lu", decode_count_bit, te_last, duration);
|
||||
|
||||
@@ -5,8 +5,7 @@
|
||||
typedef enum {
|
||||
KiaV1DecoderStepReset = 0,
|
||||
KiaV1DecoderStepCheckPreamble,
|
||||
KiaV1DecoderStepFoundShortLow,
|
||||
KiaV1DecoderStepCollectRawBits,
|
||||
KiaV1DecoderStepDecodeData,
|
||||
} KiaV1DecoderStep;
|
||||
|
||||
class FProtoSubCarKiaV1 : public FProtoSubCarBase {
|
||||
@@ -16,177 +15,74 @@ class FProtoSubCarKiaV1 : public FProtoSubCarBase {
|
||||
te_short = 800;
|
||||
te_long = 1600;
|
||||
te_delta = 200;
|
||||
min_count_bit_for_found = 56;
|
||||
}
|
||||
void kia_v1_add_raw_bit(bool bit) {
|
||||
if (raw_bit_count < 192) {
|
||||
uint16_t byte_idx = raw_bit_count / 8;
|
||||
uint8_t bit_idx = 7 - (raw_bit_count % 8);
|
||||
if (bit) {
|
||||
raw_bits[byte_idx] |= (1 << bit_idx);
|
||||
} else {
|
||||
raw_bits[byte_idx] &= ~(1 << bit_idx);
|
||||
}
|
||||
raw_bit_count++;
|
||||
}
|
||||
}
|
||||
inline bool kia_v1_get_raw_bit(uint16_t idx) {
|
||||
uint16_t byte_idx = idx / 8;
|
||||
uint8_t bit_idx = 7 - (idx % 8);
|
||||
return (raw_bits[byte_idx] >> bit_idx) & 1;
|
||||
}
|
||||
bool kia_v1_manchester_decode() {
|
||||
if (raw_bit_count < 113) {
|
||||
// FURI_LOG_D(TAG, "Not enough raw bits: %u", raw_bit_count);
|
||||
return false;
|
||||
}
|
||||
// Try different offsets to find best alignment (RTL-433 uses -1 bit offset)
|
||||
uint16_t best_bits = 0;
|
||||
uint64_t best_data = 0;
|
||||
// uint16_t best_offset = 0;
|
||||
|
||||
for (uint16_t offset = 0; offset < 8; offset++) {
|
||||
uint64_t data = 0;
|
||||
uint16_t decoded_bits = 0;
|
||||
|
||||
for (uint16_t i = offset; i + 1 < raw_bit_count && decoded_bits < 56; i += 2) {
|
||||
bool bit1 = kia_v1_get_raw_bit(i);
|
||||
bool bit2 = kia_v1_get_raw_bit(i + 1);
|
||||
|
||||
uint8_t two_bits = (bit1 << 1) | bit2;
|
||||
|
||||
// V1 uses: 10=1, 01=0
|
||||
if (two_bits == 0x02) { // 10 = decoded 1
|
||||
data = (data << 1) | 1;
|
||||
decoded_bits++;
|
||||
} else if (two_bits == 0x01) { // 01 = decoded 0
|
||||
data = (data << 1);
|
||||
decoded_bits++;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (decoded_bits > best_bits) {
|
||||
best_bits = decoded_bits;
|
||||
best_data = data;
|
||||
// best_offset = offset;
|
||||
}
|
||||
}
|
||||
|
||||
// FURI_LOG_I(TAG, "Best: offset=%u bits=%u data=%014llX", best_offset, best_bits, best_data);
|
||||
|
||||
decode_data = best_data;
|
||||
decode_count_bit = best_bits;
|
||||
|
||||
return best_bits >= min_count_bit_for_found;
|
||||
min_count_bit_for_found = 57;
|
||||
}
|
||||
|
||||
void feed(bool level, uint32_t duration) {
|
||||
ManchesterEvent event = ManchesterEventReset;
|
||||
|
||||
switch (parser_step) {
|
||||
case KiaV1DecoderStepReset:
|
||||
// Preamble 0xCCCCCCCD produces alternating LONG pulses
|
||||
if ((level) && (DURATION_DIFF(duration, te_long) <
|
||||
te_delta)) {
|
||||
if ((level) && (DURATION_DIFF(duration, te_long) < te_delta)) {
|
||||
parser_step = KiaV1DecoderStepCheckPreamble;
|
||||
te_last = duration;
|
||||
header_count = 1;
|
||||
header_count = 0;
|
||||
decode_data = 0;
|
||||
decode_count_bit = 0;
|
||||
FProtoGeneral::manchester_advance(manchester_saved_state, ManchesterEventReset, &manchester_saved_state, NULL);
|
||||
}
|
||||
break;
|
||||
|
||||
case KiaV1DecoderStepCheckPreamble:
|
||||
if (level) {
|
||||
if (DURATION_DIFF(duration, te_long) <
|
||||
te_delta) {
|
||||
te_last = duration;
|
||||
if (!level) {
|
||||
if ((DURATION_DIFF(duration, te_long) < te_delta) && (DURATION_DIFF(te_last, te_long) < te_delta)) {
|
||||
header_count++;
|
||||
} else if (
|
||||
DURATION_DIFF(duration, te_short) <
|
||||
te_delta) {
|
||||
te_last = duration;
|
||||
} else {
|
||||
parser_step = KiaV1DecoderStepReset;
|
||||
}
|
||||
} else {
|
||||
// LOW pulse
|
||||
if (DURATION_DIFF(duration, te_long) <
|
||||
te_delta) {
|
||||
header_count++;
|
||||
} else if (
|
||||
DURATION_DIFF(duration, te_short) <
|
||||
te_delta) {
|
||||
// Short LOW - this is the start of sync (0xCD ends: ...long H, short L, short H)
|
||||
if (header_count > 12) {
|
||||
parser_step = KiaV1DecoderStepFoundShortLow;
|
||||
}
|
||||
} else {
|
||||
parser_step = KiaV1DecoderStepReset;
|
||||
}
|
||||
if (header_count > 70) {
|
||||
if ((!level) && (DURATION_DIFF(duration, te_short) < te_delta) && (DURATION_DIFF(te_last, te_long) < te_delta)) {
|
||||
decode_count_bit = 1;
|
||||
subghz_protocol_blocks_add_bit(1);
|
||||
header_count = 0;
|
||||
parser_step = KiaV1DecoderStepDecodeData;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case KiaV1DecoderStepFoundShortLow:
|
||||
// Expecting SHORT HIGH to complete sync
|
||||
if (level && (DURATION_DIFF(duration, te_short) <
|
||||
te_delta)) {
|
||||
// FURI_LOG_I(TAG, "Sync! hdr=%u", header_count);
|
||||
parser_step = KiaV1DecoderStepCollectRawBits;
|
||||
raw_bit_count = 0;
|
||||
memset(raw_bits, 0, sizeof(raw_bits));
|
||||
// Add the sync short HIGH as first raw bit
|
||||
kia_v1_add_raw_bit(true);
|
||||
} else {
|
||||
parser_step = KiaV1DecoderStepReset;
|
||||
case KiaV1DecoderStepDecodeData:
|
||||
if ((DURATION_DIFF(duration, te_short) < te_delta)) {
|
||||
event = level ? ManchesterEventShortLow : ManchesterEventShortHigh;
|
||||
} else if ((DURATION_DIFF(duration, te_long) <
|
||||
te_delta)) {
|
||||
event = level ? ManchesterEventLongLow : ManchesterEventLongHigh;
|
||||
}
|
||||
break;
|
||||
|
||||
case KiaV1DecoderStepCollectRawBits:
|
||||
if (duration > 2400) {
|
||||
// FURI_LOG_I(TAG, "End! raw_bits=%u", raw_bit_count);
|
||||
|
||||
if (kia_v1_manchester_decode()) {
|
||||
// instance->generic.data = decode_data;
|
||||
data_count_bit = raw_bit_count / 8;
|
||||
|
||||
// Extract fields from 56-bit data per RTL-433:
|
||||
// Serial: bits 55-24 (32 bits)
|
||||
// Btn: bits 23-16 (8 bits)
|
||||
// Count: bits 15-8 (8 bits)
|
||||
// CRC: bits 7-0 (8 bits)
|
||||
// instance->generic.serial = (uint32_t)((instance->generic.data >> 24) & 0xFFFFFFFF);
|
||||
// instance->generic.btn = (uint8_t)((instance->generic.data >> 16) & 0xFF);
|
||||
// instance->generic.cnt = (uint8_t)((instance->generic.data >> 8) & 0xFF);
|
||||
|
||||
if (callback)
|
||||
callback(this);
|
||||
if (event != ManchesterEventReset) {
|
||||
bool data;
|
||||
bool data_ok = FProtoGeneral::manchester_advance(manchester_saved_state, event, &manchester_saved_state, &data);
|
||||
if (data_ok) {
|
||||
decode_data = (decode_data << 1) | data;
|
||||
decode_count_bit++;
|
||||
}
|
||||
}
|
||||
|
||||
if (decode_count_bit == min_count_bit_for_found) {
|
||||
// instance->generic.data = decode_data;
|
||||
data_count_bit = decode_count_bit;
|
||||
if (callback)
|
||||
callback(this);
|
||||
|
||||
decode_data = 0;
|
||||
decode_count_bit = 0;
|
||||
parser_step = KiaV1DecoderStepReset;
|
||||
break;
|
||||
}
|
||||
|
||||
int num_bits = 0;
|
||||
if (DURATION_DIFF(duration, te_short) <
|
||||
te_delta) {
|
||||
num_bits = 1;
|
||||
} else if (
|
||||
DURATION_DIFF(duration, te_long) <
|
||||
te_delta) {
|
||||
num_bits = 2;
|
||||
} else {
|
||||
parser_step = KiaV1DecoderStepReset;
|
||||
break;
|
||||
}
|
||||
|
||||
for (int i = 0; i < num_bits; i++) {
|
||||
kia_v1_add_raw_bit(level);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t raw_bits[24]{0};
|
||||
uint16_t raw_bit_count = 0;
|
||||
uint16_t header_count = 0;
|
||||
uint8_t header_count = 0;
|
||||
ManchesterState manchester_saved_state = ManchesterStateStart1;
|
||||
};
|
||||
|
||||
@@ -15,65 +15,7 @@ class FProtoSubCarKiaV2 : public FProtoSubCarBase {
|
||||
te_short = 500;
|
||||
te_long = 1000;
|
||||
te_delta = 160;
|
||||
min_count_bit_for_found = 51;
|
||||
}
|
||||
|
||||
void kia_v2_add_raw_bit(bool bit) {
|
||||
if (raw_bit_count < 160) {
|
||||
uint16_t byte_idx = raw_bit_count / 8;
|
||||
uint8_t bit_idx = 7 - (raw_bit_count % 8);
|
||||
if (bit) {
|
||||
raw_bits[byte_idx] |= (1 << bit_idx);
|
||||
} else {
|
||||
raw_bits[byte_idx] &= ~(1 << bit_idx);
|
||||
}
|
||||
raw_bit_count++;
|
||||
}
|
||||
}
|
||||
inline bool kia_v2_get_raw_bit(uint16_t idx) {
|
||||
uint16_t byte_idx = idx / 8;
|
||||
uint8_t bit_idx = 7 - (idx % 8);
|
||||
return (raw_bits[byte_idx] >> bit_idx) & 1;
|
||||
}
|
||||
bool kia_v2_manchester_decode() {
|
||||
if (raw_bit_count < 100) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint16_t best_bits = 0;
|
||||
uint64_t best_data = 0;
|
||||
|
||||
for (uint16_t offset = 0; offset < 8; offset++) {
|
||||
uint64_t data = 0;
|
||||
uint16_t decoded_bits = 0;
|
||||
|
||||
for (uint16_t i = offset; i + 1 < raw_bit_count && decoded_bits < 53; i += 2) {
|
||||
bool bit1 = kia_v2_get_raw_bit(i);
|
||||
bool bit2 = kia_v2_get_raw_bit(i + 1);
|
||||
|
||||
uint8_t two_bits = (bit1 << 1) | bit2;
|
||||
|
||||
if (two_bits == 0x02) {
|
||||
data = (data << 1) | 1;
|
||||
decoded_bits++;
|
||||
} else if (two_bits == 0x01) {
|
||||
data = (data << 1);
|
||||
decoded_bits++;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (decoded_bits > best_bits) {
|
||||
best_bits = decoded_bits;
|
||||
best_data = data;
|
||||
}
|
||||
}
|
||||
|
||||
decode_data = best_data;
|
||||
decode_count_bit = best_bits;
|
||||
|
||||
return best_bits >= min_count_bit_for_found;
|
||||
min_count_bit_for_found = 53;
|
||||
}
|
||||
|
||||
void feed(bool level, uint32_t duration) {
|
||||
@@ -82,86 +24,85 @@ class FProtoSubCarKiaV2 : public FProtoSubCarBase {
|
||||
if ((level) && (DURATION_DIFF(duration, te_long) < te_delta)) {
|
||||
parser_step = KiaV2DecoderStepCheckPreamble;
|
||||
te_last = duration;
|
||||
header_count = 1;
|
||||
header_count = 0;
|
||||
FProtoGeneral::manchester_advance(manchester_state, ManchesterEventReset, &manchester_state, NULL);
|
||||
}
|
||||
break;
|
||||
|
||||
case KiaV2DecoderStepCheckPreamble:
|
||||
if (level) {
|
||||
if (DURATION_DIFF(duration, te_long) <
|
||||
te_delta) {
|
||||
if (level) // HIGH pulse
|
||||
{
|
||||
if (DURATION_DIFF(duration, te_long) < te_delta) {
|
||||
te_last = duration;
|
||||
header_count++;
|
||||
} else if (
|
||||
DURATION_DIFF(duration, te_short) <
|
||||
te_delta) {
|
||||
te_last = duration;
|
||||
} else {
|
||||
parser_step = KiaV2DecoderStepReset;
|
||||
}
|
||||
} else {
|
||||
if (DURATION_DIFF(duration, te_long) <
|
||||
te_delta) {
|
||||
header_count++;
|
||||
} else if (
|
||||
DURATION_DIFF(duration, te_short) <
|
||||
te_delta) {
|
||||
if (header_count > 10 &&
|
||||
DURATION_DIFF(te_last, te_short) <
|
||||
te_delta) {
|
||||
DURATION_DIFF(duration, te_short) < te_delta) {
|
||||
if (header_count >= 100) {
|
||||
header_count = 0;
|
||||
decode_data = 0;
|
||||
decode_count_bit = 1;
|
||||
parser_step = KiaV2DecoderStepCollectRawBits;
|
||||
raw_bit_count = 0;
|
||||
memset(raw_bits, 0, sizeof(raw_bits));
|
||||
subghz_protocol_blocks_add_bit(1);
|
||||
} else {
|
||||
te_last = duration;
|
||||
}
|
||||
} else {
|
||||
parser_step = KiaV2DecoderStepReset;
|
||||
}
|
||||
} else {
|
||||
if (DURATION_DIFF(duration, te_long) < te_delta) {
|
||||
header_count++;
|
||||
te_last = duration;
|
||||
} else if (
|
||||
DURATION_DIFF(duration, te_short) < te_delta) {
|
||||
te_last = duration;
|
||||
} else {
|
||||
parser_step = KiaV2DecoderStepReset;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case KiaV2DecoderStepCollectRawBits:
|
||||
if (duration > 1500) {
|
||||
if (kia_v2_manchester_decode()) {
|
||||
/*data = decode_data;
|
||||
data_count_bit = decode_count_bit;
|
||||
case KiaV2DecoderStepCollectRawBits: {
|
||||
ManchesterEvent event;
|
||||
|
||||
serial = (uint32_t)((data >> 20) & 0xFFFFFFFF);
|
||||
btn = (uint8_t)((data >> 16) & 0x0F);
|
||||
|
||||
uint16_t raw_count = (uint16_t)((data >> 4) & 0xFFF);
|
||||
cnt = ((raw_count >> 4) | (raw_count << 8)) & 0xFFF;
|
||||
*/
|
||||
data_count_bit = decode_count_bit;
|
||||
if (callback)
|
||||
callback(this);
|
||||
}
|
||||
|
||||
parser_step = KiaV2DecoderStepReset;
|
||||
break;
|
||||
}
|
||||
|
||||
int num_bits = 0;
|
||||
if (DURATION_DIFF(duration, te_short) <
|
||||
te_delta) {
|
||||
num_bits = 1;
|
||||
if (DURATION_DIFF(duration, te_short) < te_delta) {
|
||||
event = level ? ManchesterEventShortLow : ManchesterEventShortHigh;
|
||||
} else if (
|
||||
DURATION_DIFF(duration, te_long) <
|
||||
te_delta) {
|
||||
num_bits = 2;
|
||||
DURATION_DIFF(duration, te_long) < te_delta) {
|
||||
event = level ? ManchesterEventLongLow : ManchesterEventLongHigh;
|
||||
} else {
|
||||
parser_step = KiaV2DecoderStepReset;
|
||||
break;
|
||||
}
|
||||
|
||||
for (int i = 0; i < num_bits; i++) {
|
||||
kia_v2_add_raw_bit(level);
|
||||
}
|
||||
bool data_bit;
|
||||
if (FProtoGeneral::manchester_advance(manchester_state, event, &manchester_state, &data_bit)) {
|
||||
decode_data = (decode_data << 1) | data_bit;
|
||||
decode_count_bit++;
|
||||
|
||||
if (decode_count_bit == 53) {
|
||||
// instance->generic.data = decode_data;
|
||||
data_count_bit = decode_count_bit;
|
||||
|
||||
// instance->generic.serial = (uint32_t)((instance->generic.data >> 20) & 0xFFFFFFFF);
|
||||
// instance->generic.btn = (uint8_t)((instance->generic.data >> 16) & 0x0F);
|
||||
|
||||
// uint16_t raw_count = (uint16_t)((instance->generic.data >> 4) & 0xFFF);
|
||||
// instance->generic.cnt = ((raw_count >> 4) | (raw_count << 8)) & 0xFFF;
|
||||
|
||||
if (callback)
|
||||
callback(this);
|
||||
|
||||
decode_data = 0;
|
||||
decode_count_bit = 0;
|
||||
header_count = 0;
|
||||
parser_step = KiaV2DecoderStepReset;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t raw_bits[20]{0};
|
||||
uint16_t raw_bit_count = 0;
|
||||
uint16_t header_count = 0;
|
||||
ManchesterState manchester_state = ManchesterStateMid1;
|
||||
};
|
||||
|
||||
@@ -15,7 +15,7 @@ class FProtoSubCarKiaV3V4 : public FProtoSubCarBase {
|
||||
te_short = 400;
|
||||
te_long = 800;
|
||||
te_delta = 150;
|
||||
min_count_bit_for_found = 64;
|
||||
min_count_bit_for_found = 68;
|
||||
}
|
||||
uint8_t reverse8(uint8_t byte) {
|
||||
byte = (byte & 0xF0) >> 4 | (byte & 0x0F) << 4;
|
||||
@@ -36,7 +36,7 @@ class FProtoSubCarKiaV3V4 : public FProtoSubCarBase {
|
||||
}
|
||||
}
|
||||
bool kia_v3_v4_process_buffer() {
|
||||
if (raw_bit_count < 64) {
|
||||
if (raw_bit_count < 68) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ class FProtoSubCarKiaV3V4 : public FProtoSubCarBase {
|
||||
|
||||
uint8_t btn = (reverse8(b[7]) & 0xF0) >> 4;
|
||||
decode_data = serial;
|
||||
decode_count_bit = 64;
|
||||
decode_count_bit = 68;
|
||||
decode_data2 = btn;
|
||||
data_count_bit = decode_count_bit;
|
||||
if (callback)
|
||||
@@ -93,8 +93,7 @@ class FProtoSubCarKiaV3V4 : public FProtoSubCarBase {
|
||||
void feed(bool level, uint32_t duration) {
|
||||
switch (parser_step) {
|
||||
case KiaV3V4DecoderStepReset:
|
||||
if (level && DURATION_DIFF(duration, te_short) <
|
||||
te_delta) {
|
||||
if (level && DURATION_DIFF(duration, te_short) < te_delta) {
|
||||
parser_step = KiaV3V4DecoderStepCheckPreamble;
|
||||
te_last = duration;
|
||||
header_count = 1;
|
||||
@@ -103,8 +102,7 @@ class FProtoSubCarKiaV3V4 : public FProtoSubCarBase {
|
||||
|
||||
case KiaV3V4DecoderStepCheckPreamble:
|
||||
if (level) {
|
||||
if (DURATION_DIFF(duration, te_short) <
|
||||
te_delta) {
|
||||
if (DURATION_DIFF(duration, te_short) < te_delta) {
|
||||
te_last = duration;
|
||||
} else if (duration > 1000 && duration < 1500) {
|
||||
// V4 style: Sync is LONG HIGH
|
||||
@@ -130,11 +128,7 @@ class FProtoSubCarKiaV3V4 : public FProtoSubCarBase {
|
||||
} else {
|
||||
parser_step = KiaV3V4DecoderStepReset;
|
||||
}
|
||||
} else if (
|
||||
DURATION_DIFF(duration, te_short) <
|
||||
te_delta &&
|
||||
DURATION_DIFF(te_last, te_short) <
|
||||
te_delta) {
|
||||
} else if (DURATION_DIFF(duration, te_short) < te_delta && DURATION_DIFF(te_last, te_short) < te_delta) {
|
||||
header_count++;
|
||||
} else if (duration > 1500) {
|
||||
parser_step = KiaV3V4DecoderStepReset;
|
||||
@@ -149,12 +143,10 @@ class FProtoSubCarKiaV3V4 : public FProtoSubCarBase {
|
||||
kia_v3_v4_process_buffer();
|
||||
parser_step = KiaV3V4DecoderStepReset;
|
||||
} else if (
|
||||
DURATION_DIFF(duration, te_short) <
|
||||
te_delta) {
|
||||
DURATION_DIFF(duration, te_short) < te_delta) {
|
||||
kia_v3_v4_add_raw_bit(false);
|
||||
} else if (
|
||||
DURATION_DIFF(duration, te_long) <
|
||||
te_delta) {
|
||||
DURATION_DIFF(duration, te_long) < te_delta) {
|
||||
kia_v3_v4_add_raw_bit(true);
|
||||
} else {
|
||||
parser_step = KiaV3V4DecoderStepReset;
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
#pragma once
|
||||
#include "subcarbase.hpp"
|
||||
#include <cstring>
|
||||
|
||||
typedef enum {
|
||||
KiaV5DecoderStepReset = 0,
|
||||
KiaV5DecoderStepCheckPreamble,
|
||||
KiaV5DecoderStepCollectRawBits,
|
||||
KiaV5DecoderStepData,
|
||||
} KiaV5DecoderStep;
|
||||
|
||||
class FProtoSubCarKiaV5 : public FProtoSubCarBase {
|
||||
@@ -17,74 +18,37 @@ class FProtoSubCarKiaV5 : public FProtoSubCarBase {
|
||||
min_count_bit_for_found = 64;
|
||||
}
|
||||
|
||||
inline bool kia_v5_get_raw_bit(uint16_t idx) {
|
||||
uint16_t byte_idx = idx / 8;
|
||||
uint8_t bit_idx = 7 - (idx % 8);
|
||||
return (raw_bits[byte_idx] >> bit_idx) & 1;
|
||||
}
|
||||
|
||||
void kia_v5_add_raw_bit(bool bit) {
|
||||
if (raw_bit_count < 256) {
|
||||
uint16_t byte_idx = raw_bit_count / 8;
|
||||
uint8_t bit_idx = 7 - (raw_bit_count % 8);
|
||||
if (bit) {
|
||||
raw_bits[byte_idx] |= (1 << bit_idx);
|
||||
} else {
|
||||
raw_bits[byte_idx] &= ~(1 << bit_idx);
|
||||
}
|
||||
raw_bit_count++;
|
||||
}
|
||||
}
|
||||
|
||||
bool kia_v5_manchester_decode() {
|
||||
if (raw_bit_count < 130) {
|
||||
return false;
|
||||
}
|
||||
|
||||
decode_data = 0;
|
||||
decode_count_bit = 0;
|
||||
|
||||
// Start at offset 2 for proper Manchester alignment
|
||||
const uint16_t start_bit = 2;
|
||||
|
||||
for (uint16_t i = start_bit;
|
||||
i + 1 < raw_bit_count && decode_count_bit < 64;
|
||||
i += 2) {
|
||||
bool bit1 = kia_v5_get_raw_bit(i);
|
||||
bool bit2 = kia_v5_get_raw_bit(i + 1);
|
||||
|
||||
uint8_t two_bits = (bit1 << 1) | bit2;
|
||||
|
||||
if (two_bits == 0x01) { // 01 = decoded 1
|
||||
decode_data = (decode_data << 1) | 1;
|
||||
decode_count_bit++;
|
||||
} else if (two_bits == 0x02) { // 10 = decoded 0
|
||||
decode_data = (decode_data << 1);
|
||||
decode_count_bit++;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return decode_count_bit >= min_count_bit_for_found;
|
||||
void kia_v5_add_bit(bool bit) {
|
||||
decode_data = (decode_data << 1) | (bit ? 1 : 0);
|
||||
decode_count_bit++;
|
||||
}
|
||||
|
||||
void feed(bool level, uint32_t duration) {
|
||||
switch (parser_step) {
|
||||
case KiaV5DecoderStepReset:
|
||||
if ((level) && (DURATION_DIFF(duration, te_short) <
|
||||
te_delta)) {
|
||||
if ((level) && (DURATION_DIFF(duration, te_short) < te_delta)) {
|
||||
parser_step = KiaV5DecoderStepCheckPreamble;
|
||||
te_last = duration;
|
||||
header_count = 1;
|
||||
decode_count_bit = 0;
|
||||
decode_data = 0;
|
||||
FProtoGeneral::manchester_advance(manchester_state, ManchesterEventReset, &manchester_state, NULL);
|
||||
}
|
||||
break;
|
||||
|
||||
case KiaV5DecoderStepCheckPreamble:
|
||||
if (level) {
|
||||
if ((DURATION_DIFF(duration, te_short) <
|
||||
te_delta) ||
|
||||
(DURATION_DIFF(duration, te_long) <
|
||||
te_delta)) {
|
||||
if (DURATION_DIFF(duration, te_long) < te_delta) {
|
||||
if (header_count > 40) {
|
||||
parser_step = KiaV5DecoderStepData;
|
||||
decode_count_bit = 0;
|
||||
decode_data = 0;
|
||||
decode_data2 = 0;
|
||||
header_count = 0;
|
||||
} else {
|
||||
te_last = duration;
|
||||
}
|
||||
} else if (DURATION_DIFF(duration, te_short) < te_delta) {
|
||||
te_last = duration;
|
||||
} else {
|
||||
parser_step = KiaV5DecoderStepReset;
|
||||
@@ -100,13 +64,7 @@ class FProtoSubCarKiaV5 : public FProtoSubCarBase {
|
||||
te_delta) &&
|
||||
(DURATION_DIFF(te_last, te_short) <
|
||||
te_delta)) {
|
||||
if (header_count > 40) {
|
||||
parser_step = KiaV5DecoderStepCollectRawBits;
|
||||
raw_bit_count = 0;
|
||||
memset(raw_bits, 0, sizeof(raw_bits));
|
||||
} else {
|
||||
header_count++;
|
||||
}
|
||||
header_count++;
|
||||
} else if (
|
||||
DURATION_DIFF(te_last, te_long) <
|
||||
te_delta) {
|
||||
@@ -114,33 +72,21 @@ class FProtoSubCarKiaV5 : public FProtoSubCarBase {
|
||||
} else {
|
||||
parser_step = KiaV5DecoderStepReset;
|
||||
}
|
||||
te_last = duration;
|
||||
}
|
||||
break;
|
||||
|
||||
case KiaV5DecoderStepCollectRawBits:
|
||||
if (duration > 1200) {
|
||||
if (kia_v5_manchester_decode()) {
|
||||
// generic.data = decode_data;
|
||||
// generic.data_count_bit = decode_count_bit;
|
||||
data_count_bit = decode_count_bit;
|
||||
// Compute yek (bit-reverse each byte)
|
||||
uint64_t yek = 0;
|
||||
for (int i = 0; i < 8; i++) {
|
||||
uint8_t byte = (decode_data >> (i * 8)) & 0xFF;
|
||||
uint8_t reversed = 0;
|
||||
for (int b = 0; b < 8; b++) {
|
||||
if (byte & (1 << b))
|
||||
reversed |= (1 << (7 - b));
|
||||
}
|
||||
yek |= ((uint64_t)reversed << ((7 - i) * 8));
|
||||
}
|
||||
decode_data = yek;
|
||||
|
||||
// Shift serial right by 1 to correct alignment
|
||||
// generic.serial = (uint32_t)(((yek >> 32) & 0x0FFFFFFF) >> 1);
|
||||
// generic.btn = (uint8_t)((yek >> 61) & 0x07); // Shift btn too
|
||||
// generic.cnt = (uint16_t)(yek & 0xFFFF);
|
||||
case KiaV5DecoderStepData: {
|
||||
ManchesterEvent event;
|
||||
|
||||
if (DURATION_DIFF(duration, te_short) < te_delta) {
|
||||
event = level ? ManchesterEventShortHigh : ManchesterEventShortLow;
|
||||
} else if (DURATION_DIFF(duration, te_long) < te_delta) {
|
||||
event = level ? ManchesterEventLongHigh : ManchesterEventLongLow;
|
||||
} else {
|
||||
if (decode_count_bit >= min_count_bit_for_found) {
|
||||
// instance->generic.data = instance->decode_data2;
|
||||
data_count_bit = (decode_count_bit > 67) ? 67 : decode_count_bit;
|
||||
if (callback)
|
||||
callback(this);
|
||||
}
|
||||
@@ -149,28 +95,22 @@ class FProtoSubCarKiaV5 : public FProtoSubCarBase {
|
||||
break;
|
||||
}
|
||||
|
||||
int num_bits = 0;
|
||||
if (DURATION_DIFF(duration, te_short) <
|
||||
te_delta) {
|
||||
num_bits = 1;
|
||||
} else if (
|
||||
DURATION_DIFF(duration, te_long) <
|
||||
te_delta) {
|
||||
num_bits = 2;
|
||||
} else {
|
||||
parser_step = KiaV5DecoderStepReset;
|
||||
break;
|
||||
}
|
||||
|
||||
for (int i = 0; i < num_bits; i++) {
|
||||
kia_v5_add_raw_bit(level);
|
||||
bool data_bit;
|
||||
if (decode_count_bit <= 66 && FProtoGeneral::manchester_advance(manchester_state, event, &manchester_state, &data_bit)) {
|
||||
kia_v5_add_bit(data_bit);
|
||||
|
||||
if (decode_count_bit == 64) {
|
||||
decode_data2 = decode_data;
|
||||
decode_data = 0;
|
||||
}
|
||||
}
|
||||
|
||||
te_last = duration;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t raw_bits[32]{};
|
||||
uint16_t raw_bit_count = 0;
|
||||
uint16_t header_count = 0;
|
||||
ManchesterState manchester_state = ManchesterStateMid1;
|
||||
};
|
||||
|
||||
@@ -20,6 +20,7 @@ class FProtoSubCarSubaru : public FProtoSubCarBase {
|
||||
te_delta = 260;
|
||||
min_count_bit_for_found = 64;
|
||||
}
|
||||
|
||||
void subghz_protocol_decoder_subaru_reset() {
|
||||
parser_step = SubaruDecoderStepReset;
|
||||
te_last = 0;
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
|
||||
typedef enum {
|
||||
SuzukiDecoderStepReset = 0,
|
||||
SuzukiDecoderStepFoundStartPulse,
|
||||
SuzukiDecoderStepSaveDuration,
|
||||
SuzukiDecoderStepCountPreamble = 1,
|
||||
SuzukiDecoderStepDecodeData = 2,
|
||||
} SuzukiDecoderStep;
|
||||
|
||||
class FProtoSubCarSuzuki : public FProtoSubCarBase {
|
||||
@@ -20,54 +20,45 @@ class FProtoSubCarSuzuki : public FProtoSubCarBase {
|
||||
min_count_bit_for_found = 64;
|
||||
}
|
||||
void suzuki_add_bit(uint32_t bit) {
|
||||
uint32_t carry = data_low >> 31;
|
||||
data_low = (data_low << 1) | bit;
|
||||
data_high = (data_high << 1) | carry;
|
||||
data_count_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;
|
||||
data_low = 0;
|
||||
data_high = 0;
|
||||
decode_data = 0;
|
||||
}
|
||||
|
||||
void feed(bool level, uint32_t duration) {
|
||||
switch (parser_step) {
|
||||
case SuzukiDecoderStepReset:
|
||||
// Wait for short HIGH pulse (~250µs) to start preamble
|
||||
if (!level)
|
||||
// Wait for HIGH pulse (~250µs) to start preamble
|
||||
if (!level) {
|
||||
return;
|
||||
|
||||
}
|
||||
if (DURATION_DIFF(duration, te_short) > te_delta) {
|
||||
return;
|
||||
}
|
||||
|
||||
data_low = 0;
|
||||
data_high = 0;
|
||||
parser_step = SuzukiDecoderStepFoundStartPulse;
|
||||
decode_data = 0;
|
||||
decode_count_bit = 0;
|
||||
parser_step = SuzukiDecoderStepCountPreamble;
|
||||
header_count = 0;
|
||||
data_count_bit = 0;
|
||||
break;
|
||||
|
||||
case SuzukiDecoderStepFoundStartPulse:
|
||||
case SuzukiDecoderStepCountPreamble:
|
||||
if (level) {
|
||||
// HIGH pulse
|
||||
if (header_count < 257) {
|
||||
// Still in preamble - just count
|
||||
return;
|
||||
}
|
||||
|
||||
// After preamble, look for long HIGH to start data
|
||||
if (DURATION_DIFF(duration, te_long) < te_delta) {
|
||||
parser_step = SuzukiDecoderStepSaveDuration;
|
||||
suzuki_add_bit(1);
|
||||
if (header_count >= 300) {
|
||||
if (DURATION_DIFF(duration, te_long) <= te_delta) {
|
||||
parser_step = SuzukiDecoderStepDecodeData;
|
||||
suzuki_add_bit(1);
|
||||
}
|
||||
}
|
||||
// Ignore short HIGHs after preamble until we see a long one
|
||||
} else {
|
||||
// LOW pulse - count as header if short
|
||||
if (DURATION_DIFF(duration, te_short) < te_delta) {
|
||||
if (DURATION_DIFF(duration, te_short) <= te_delta) {
|
||||
te_last = duration;
|
||||
header_count++;
|
||||
} else {
|
||||
@@ -76,45 +67,69 @@ class FProtoSubCarSuzuki : public FProtoSubCarBase {
|
||||
}
|
||||
break;
|
||||
|
||||
case SuzukiDecoderStepSaveDuration:
|
||||
case SuzukiDecoderStepDecodeData:
|
||||
|
||||
if (level) {
|
||||
// HIGH pulse - determines bit value
|
||||
// Long HIGH (~500µs) = 1, Short HIGH (~250µs) = 0
|
||||
if (DURATION_DIFF(duration, te_long) < te_delta) {
|
||||
suzuki_add_bit(1);
|
||||
} else if (DURATION_DIFF(duration, te_short) < te_delta) {
|
||||
suzuki_add_bit(0);
|
||||
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 {
|
||||
parser_step = SuzukiDecoderStepReset;
|
||||
uint32_t diff_long = duration - 500;
|
||||
if (diff_long <= 99) {
|
||||
suzuki_add_bit(1);
|
||||
}
|
||||
}
|
||||
// Stay in this state for next bit
|
||||
} else {
|
||||
// LOW pulse - check for gap (end of transmission)
|
||||
if (DURATION_DIFF(duration, SUZUKI_GAP_TIME) < SUZUKI_GAP_DELTA) {
|
||||
// Gap found - end of transmission
|
||||
if (data_count_bit == 64) {
|
||||
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;
|
||||
decode_data = ((uint64_t)data_high << 32) | (uint64_t)data_low;
|
||||
// Check manufacturer nibble (should be 0xF)
|
||||
uint8_t manufacturer = (data_high >> 28) & 0xF;
|
||||
if (manufacturer == 0xF) {
|
||||
// Extract fields
|
||||
decode_data2 = 0; // Not used
|
||||
if (callback) {
|
||||
callback(this);
|
||||
}
|
||||
|
||||
/*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;
|
||||
}
|
||||
// Short LOW pulses are ignored - stay in this state
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t header_count = 0;
|
||||
uint32_t data_high = 0;
|
||||
uint32_t data_low = 0;
|
||||
uint8_t data_count_bit = 0;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user