From bed011473d72e7542ef189995264bad3d5aed7af Mon Sep 17 00:00:00 2001 From: HTotoo Date: Sun, 10 Dec 2023 15:35:17 +0100 Subject: [PATCH] More protos --- firmware/application/apps/ui_subghzd.cpp | 4 + firmware/baseband/fprotos/fprotogeneral.hpp | 7 ++ firmware/baseband/fprotos/s-honeywellwdb.hpp | 76 +++++++++++++++++ firmware/baseband/fprotos/s-hormann.hpp | 87 ++++++++++++++++++++ firmware/baseband/fprotos/subghzdprotos.hpp | 32 +++---- firmware/baseband/fprotos/subghztypes.hpp | 2 + 6 files changed, 194 insertions(+), 14 deletions(-) create mode 100644 firmware/baseband/fprotos/s-honeywellwdb.hpp create mode 100644 firmware/baseband/fprotos/s-hormann.hpp diff --git a/firmware/application/apps/ui_subghzd.cpp b/firmware/application/apps/ui_subghzd.cpp index 94f779ea..b60be88a 100644 --- a/firmware/application/apps/ui_subghzd.cpp +++ b/firmware/application/apps/ui_subghzd.cpp @@ -160,6 +160,10 @@ const char* SubGhzDView::getSensorTypeName(FPROTO_SUBGHZD_SENSOR type) { return "Holtek HT12X"; case FPS_HONEYWELL: return "Honeywell"; + case FPS_HONEYWELLWDB: + return "Honeywell Wdb"; + case FPS_HORMANN: + return "Hormann"; case FPS_Invalid: default: return "Unknown"; diff --git a/firmware/baseband/fprotos/fprotogeneral.hpp b/firmware/baseband/fprotos/fprotogeneral.hpp index 25c03cdc..c2b33f8e 100644 --- a/firmware/baseband/fprotos/fprotogeneral.hpp +++ b/firmware/baseband/fprotos/fprotogeneral.hpp @@ -65,6 +65,13 @@ class FProtoGeneral { *next_state = new_state; return result; } + static uint8_t subghz_protocol_blocks_get_parity(uint64_t key, uint8_t bit_count) { + uint8_t parity = 0; + for (uint8_t i = 0; i < bit_count; i++) { + parity += bit_read(key, i); + } + return parity & 0x01; + } static uint8_t subghz_protocol_blocks_add_bytes(uint8_t const message[], size_t size) { uint32_t result = 0; for (size_t i = 0; i < size; ++i) { diff --git a/firmware/baseband/fprotos/s-honeywellwdb.hpp b/firmware/baseband/fprotos/s-honeywellwdb.hpp new file mode 100644 index 00000000..27bb4cf6 --- /dev/null +++ b/firmware/baseband/fprotos/s-honeywellwdb.hpp @@ -0,0 +1,76 @@ + +#ifndef __FPROTO_HONEYWELLWDB_H__ +#define __FPROTO_HONEYWELLWDB_H__ + +#include "subghzdbase.hpp" + +typedef enum { + Honeywell_WDBDecoderStepReset = 0, + Honeywell_WDBDecoderStepFoundStartBit, + Honeywell_WDBDecoderStepSaveDuration, + Honeywell_WDBDecoderStepCheckDuration, +} Honeywell_WDBDecoderStep; + +class FProtoSubGhzDCHoneywellWdb : public FProtoSubGhzDBase { + public: + FProtoSubGhzDCHoneywellWdb() { + sensorType = FPS_HONEYWELLWDB; + } + + void feed(bool level, uint32_t duration) { + switch (parser_step) { + case Honeywell_WDBDecoderStepReset: + if ((!level) && (DURATION_DIFF(duration, te_short * 3) < te_delta)) { + // Found header Honeywell_WDB + decode_count_bit = 0; + decode_data = 0; + parser_step = Honeywell_WDBDecoderStepSaveDuration; + } + break; + case Honeywell_WDBDecoderStepSaveDuration: + if (level) { // save interval + if (DURATION_DIFF(duration, te_short * 3) < te_delta) { + if ((decode_count_bit == min_count_bit_for_found) && + ((decode_data & 0x01) == FProtoGeneral::subghz_protocol_blocks_get_parity(decode_data >> 1, min_count_bit_for_found - 1))) { + data = decode_data; + data_count_bit = decode_count_bit; + // controller has too much, should be done on ui side + if (callback) callback(this); + } + parser_step = Honeywell_WDBDecoderStepReset; + break; + } + te_last = duration; + parser_step = Honeywell_WDBDecoderStepCheckDuration; + } else { + parser_step = Honeywell_WDBDecoderStepReset; + } + break; + case Honeywell_WDBDecoderStepCheckDuration: + if (!level) { + if ((DURATION_DIFF(te_last, te_short) < te_delta) && + (DURATION_DIFF(duration, te_long) < te_delta)) { + subghz_protocol_blocks_add_bit(0); + parser_step = Honeywell_WDBDecoderStepSaveDuration; + } else if ( + (DURATION_DIFF(te_last, te_long) < te_delta) && + (DURATION_DIFF(duration, te_short) < te_delta)) { + subghz_protocol_blocks_add_bit(1); + parser_step = Honeywell_WDBDecoderStepSaveDuration; + } else + parser_step = Honeywell_WDBDecoderStepReset; + } else { + parser_step = Honeywell_WDBDecoderStepReset; + } + break; + } + } + + protected: + uint32_t te_short = 160; + uint32_t te_long = 320; + uint32_t te_delta = 61; + uint32_t min_count_bit_for_found = 48; +}; + +#endif diff --git a/firmware/baseband/fprotos/s-hormann.hpp b/firmware/baseband/fprotos/s-hormann.hpp new file mode 100644 index 00000000..f2081031 --- /dev/null +++ b/firmware/baseband/fprotos/s-hormann.hpp @@ -0,0 +1,87 @@ + +#ifndef __FPROTO_HORMANN_H__ +#define __FPROTO_HORMANN_H__ + +#include "subghzdbase.hpp" + +typedef enum { + HormannDecoderStepReset = 0, + HormannDecoderStepFoundStartHeader, + HormannDecoderStepFoundHeader, + HormannDecoderStepFoundStartBit, + HormannDecoderStepSaveDuration, + HormannDecoderStepCheckDuration, +} HormannDecoderStep; + +#define HORMANN_HSM_PATTERN 0xFF000000003 + +class FProtoSubGhzDCHormann : public FProtoSubGhzDBase { + public: + FProtoSubGhzDCHormann() { + sensorType = FPS_HORMANN; + } + + void feed(bool level, uint32_t duration) { + switch (parser_step) { + case HormannDecoderStepReset: + if ((level) && (DURATION_DIFF(duration, te_short * 24) < te_delta * 24)) { + parser_step = HormannDecoderStepFoundStartBit; + } + break; + case HormannDecoderStepFoundStartBit: + if ((!level) && (DURATION_DIFF(duration, te_short) < te_delta)) { + parser_step = HormannDecoderStepSaveDuration; + decode_data = 0; + decode_count_bit = 0; + } else { + parser_step = HormannDecoderStepReset; + } + break; + case HormannDecoderStepSaveDuration: + if (level) { // save interval + if (duration >= (te_short * 5) && (decode_data & HORMANN_HSM_PATTERN) == HORMANN_HSM_PATTERN) { + parser_step = HormannDecoderStepFoundStartBit; + if (decode_count_bit >= + min_count_bit_for_found) { + data = decode_data; + data_count_bit = decode_count_bit; + // controller + btn = (data >> 4) & 0xF; + if (callback) callback(this); + } + break; + } + te_last = duration; + parser_step = HormannDecoderStepCheckDuration; + } else { + parser_step = HormannDecoderStepReset; + } + break; + case HormannDecoderStepCheckDuration: + if (!level) { + if ((DURATION_DIFF(te_last, te_short) < te_delta) && + (DURATION_DIFF(duration, te_long) < te_delta)) { + subghz_protocol_blocks_add_bit(0); + parser_step = HormannDecoderStepSaveDuration; + } else if ( + (DURATION_DIFF(te_last, te_long) < te_delta) && + (DURATION_DIFF(duration, te_short) < te_delta)) { + subghz_protocol_blocks_add_bit(1); + parser_step = HormannDecoderStepSaveDuration; + } else + parser_step = HormannDecoderStepReset; + } else { + parser_step = HormannDecoderStepReset; + } + break; + } + } + + protected: + uint32_t te_short = 500; + uint32_t te_long = 1000; + uint32_t te_delta = 200; + uint32_t min_count_bit_for_found = 44; +}; + +#endif diff --git a/firmware/baseband/fprotos/subghzdprotos.hpp b/firmware/baseband/fprotos/subghzdprotos.hpp index 618e5155..48603496 100644 --- a/firmware/baseband/fprotos/subghzdprotos.hpp +++ b/firmware/baseband/fprotos/subghzdprotos.hpp @@ -25,6 +25,8 @@ So include here the .hpp, and add a new element to the protos vector in the cons #include "s-holtek.hpp" #include "s-holtek_ht12x.hpp" #include "s-honeywell.hpp" +#include "s-honeywellwdb.hpp" +#include "s-hormann.hpp" #ifndef __FPROTO_PROTOLISTSGZ_H__ #define __FPROTO_PROTOLISTSGZ_H__ @@ -34,20 +36,22 @@ class SubGhzDProtos : public FProtoListGeneral { SubGhzDProtos() { // add protos // protos.push_back(std::make_unique()); // 1 //skip since fm - protos.push_back(std::make_unique()); // 2 - protos.push_back(std::make_unique()); // 3 - protos.push_back(std::make_unique()); // 4, 5, 6 - protos.push_back(std::make_unique()); // 7 - protos.push_back(std::make_unique()); // 8 - protos.push_back(std::make_unique()); // 9 - protos.push_back(std::make_unique()); // 10 - protos.push_back(std::make_unique()); // 11 - protos.push_back(std::make_unique()); // 12 - protos.push_back(std::make_unique()); // 13 - protos.push_back(std::make_unique()); // 14 - protos.push_back(std::make_unique()); // 15 - protos.push_back(std::make_unique()); // 16 - protos.push_back(std::make_unique()); // 17 + protos.push_back(std::make_unique()); // 2 + protos.push_back(std::make_unique()); // 3 + protos.push_back(std::make_unique()); // 4, 5, 6 + protos.push_back(std::make_unique()); // 7 + protos.push_back(std::make_unique()); // 8 + protos.push_back(std::make_unique()); // 9 + protos.push_back(std::make_unique()); // 10 + protos.push_back(std::make_unique()); // 11 + protos.push_back(std::make_unique()); // 12 + protos.push_back(std::make_unique()); // 13 + protos.push_back(std::make_unique()); // 14 + protos.push_back(std::make_unique()); // 15 + protos.push_back(std::make_unique()); // 16 + protos.push_back(std::make_unique()); // 17 + protos.push_back(std::make_unique()); // 18 + protos.push_back(std::make_unique()); // 19 // set callback for them for (const auto& obj : protos) { diff --git a/firmware/baseband/fprotos/subghztypes.hpp b/firmware/baseband/fprotos/subghztypes.hpp index 19c10e01..d9b3575c 100644 --- a/firmware/baseband/fprotos/subghztypes.hpp +++ b/firmware/baseband/fprotos/subghztypes.hpp @@ -36,6 +36,8 @@ enum FPROTO_SUBGHZD_SENSOR { FPS_HOLTEK = 15, FPS_HOLTEKHT12X = 16, FPS_HONEYWELL = 17, + FPS_HONEYWELLWDB = 18, + FPS_HORMANN = 19, }; #endif