From 28d89fbb8807e33783d4afdd8181288b80ea3994 Mon Sep 17 00:00:00 2001 From: HTotoo Date: Sat, 9 Dec 2023 21:00:34 +0100 Subject: [PATCH] Came Atomo, fixes --- firmware/application/apps/ui_subghzd.cpp | 2 + firmware/baseband/fprotos/s-came_atomo.hpp | 139 ++++++++++++++++++++ firmware/baseband/fprotos/subghzdprotos.hpp | 3 + firmware/baseband/fprotos/subghztypes.hpp | 1 + firmware/baseband/proc_subghzd.cpp | 2 +- 5 files changed, 146 insertions(+), 1 deletion(-) create mode 100644 firmware/baseband/fprotos/s-came_atomo.hpp diff --git a/firmware/application/apps/ui_subghzd.cpp b/firmware/application/apps/ui_subghzd.cpp index 190c1f1b1..b041b04d2 100644 --- a/firmware/application/apps/ui_subghzd.cpp +++ b/firmware/application/apps/ui_subghzd.cpp @@ -138,6 +138,8 @@ const char* SubGhzDView::getSensorTypeName(FPROTO_SUBGHZD_SENSOR type) { return "Prastel"; case FPS_AIRFORCE: return "Airforce"; + case FPS_CAMEATOMO: + return "Came Atomo"; case FPS_Invalid: default: return "Unknown"; diff --git a/firmware/baseband/fprotos/s-came_atomo.hpp b/firmware/baseband/fprotos/s-came_atomo.hpp new file mode 100644 index 000000000..e9d5ec7bc --- /dev/null +++ b/firmware/baseband/fprotos/s-came_atomo.hpp @@ -0,0 +1,139 @@ + +#ifndef __FPROTO_CAMEATOMO_H__ +#define __FPROTO_CAMEATOMO_H__ + +#include "subghzdbase.hpp" + +typedef enum { + CameAtomoDecoderStepReset = 0, + CameAtomoDecoderStepDecoderData, +} CameAtomoDecoderStep; + +class FProtoSubGhzDCameAtomo : public FProtoSubGhzDBase { + public: + FProtoSubGhzDCameAtomo() { + sensorType = FPS_CAMEATOMO; + } + + void feed(bool level, uint32_t duration) { + ManchesterEvent event = ManchesterEventReset; + switch (parser_step) { + case CameAtomoDecoderStepReset: + if ((!level) && (DURATION_DIFF(duration, te_long * 60) < + te_delta * 40)) { + // Found header CAME + parser_step = CameAtomoDecoderStepDecoderData; + decode_data = 0; + decode_count_bit = 1; + FProtoGeneral::manchester_advance(manchester_saved_state, ManchesterEventReset, &manchester_saved_state, NULL); + FProtoGeneral::manchester_advance(manchester_saved_state, ManchesterEventShortLow, &manchester_saved_state, NULL); + } + break; + case CameAtomoDecoderStepDecoderData: + if (!level) { + if (DURATION_DIFF(duration, te_short) < te_delta) { + event = ManchesterEventShortLow; + } else if ( + DURATION_DIFF(duration, te_long) < te_delta) { + event = ManchesterEventLongLow; + } else if ( + duration >= ((uint32_t)te_long * 2 + te_delta)) { + if (decode_count_bit == + min_count_bit_for_found) { + data = decode_data; + data_count_bit = decode_count_bit; + subghz_protocol_came_atomo_remote_controller(); + if (callback) callback(this); + } + decode_data = 0; + decode_count_bit = 1; + FProtoGeneral::manchester_advance(manchester_saved_state, ManchesterEventReset, &manchester_saved_state, NULL); + FProtoGeneral::manchester_advance(manchester_saved_state, ManchesterEventShortLow, &manchester_saved_state, NULL); + } else { + parser_step = CameAtomoDecoderStepReset; + } + } else { + if (DURATION_DIFF(duration, te_short) < te_delta) { + event = ManchesterEventShortHigh; + } else if ( + DURATION_DIFF(duration, te_long) < te_delta) { + event = ManchesterEventLongHigh; + } else { + parser_step = CameAtomoDecoderStepReset; + } + } + 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++; + } + } + break; + } + } + + protected: + uint32_t te_short = 600; + uint32_t te_long = 1200; + uint32_t te_delta = 250; + uint32_t min_count_bit_for_found = 62; + + void atomo_decrypt(uint8_t* buff) { + buff[0] = (buff[0] ^ 5) & 0x7F; + uint8_t tmpB = (-buff[0]) & 0x7F; + + uint8_t bitCnt = 8; + while (bitCnt < 59) { + if ((tmpB & 0x18) && (((tmpB / 8) & 3) != 3)) { + tmpB = ((tmpB << 1) & 0xFF) | 1; + } else { + tmpB = (tmpB << 1) & 0xFF; + } + + if (tmpB & 0x80) { + buff[bitCnt / 8] ^= (0x80 >> (bitCnt & 7)); + } + bitCnt++; + } + } + void subghz_protocol_came_atomo_remote_controller() { + data ^= 0xFFFFFFFFFFFFFFFF; + data <<= 4; + + uint8_t pack[8] = {}; + pack[0] = (data >> 56); + pack[1] = ((data >> 48) & 0xFF); + pack[2] = ((data >> 40) & 0xFF); + pack[3] = ((data >> 32) & 0xFF); + pack[4] = ((data >> 24) & 0xFF); + pack[5] = ((data >> 16) & 0xFF); + pack[6] = ((data >> 8) & 0xFF); + pack[7] = (data & 0xFF); + + atomo_decrypt(pack); + + cnt_2 = pack[0]; + cnt = (uint16_t)pack[1] << 8 | pack[2]; + serial = (uint32_t)(pack[3]) << 24 | pack[4] << 16 | pack[5] << 8 | pack[6]; + + uint8_t btn_decode = (pack[7] >> 4); + if (btn_decode == 0x0) { + btn = 0x1; + } else if (btn_decode == 0x2) { + btn = 0x2; + } else if (btn_decode == 0x4) { + btn = 0x3; + } else if (btn_decode == 0x6) { + btn = 0x4; + } + + uint32_t hi = pack[0] << 24 | pack[1] << 16 | pack[2] << 8 | pack[3]; + uint32_t lo = pack[4] << 24 | pack[5] << 16 | pack[6] << 8 | pack[7]; + data_2 = (uint64_t)hi << 32 | lo; + } +}; + +#endif diff --git a/firmware/baseband/fprotos/subghzdprotos.hpp b/firmware/baseband/fprotos/subghzdprotos.hpp index 308104b84..b02931a68 100644 --- a/firmware/baseband/fprotos/subghzdprotos.hpp +++ b/firmware/baseband/fprotos/subghzdprotos.hpp @@ -14,6 +14,7 @@ So include here the .hpp, and add a new element to the protos vector in the cons #include "s-princeton.hpp" #include "s-bett.hpp" #include "s-came.hpp" +#include "s-came_atomo.hpp" #ifndef __FPROTO_PROTOLISTSGZ_H__ #define __FPROTO_PROTOLISTSGZ_H__ @@ -26,6 +27,7 @@ class SubGhzDProtos : public FProtoListGeneral { 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 // set callback for them for (const auto& obj : protos) { @@ -35,6 +37,7 @@ class SubGhzDProtos : public FProtoListGeneral { static void callbackTarget(FProtoSubGhzDBase* instance) { SubGhzDDataMessage packet_message{instance->getSensorType(), instance->getSensorSerial(), instance->getBits(), instance->getData(), instance->getData2(), instance->getBtn()}; + // todo add cnt, cnt2 shared_memory.application_queue.push(packet_message); } diff --git a/firmware/baseband/fprotos/subghztypes.hpp b/firmware/baseband/fprotos/subghztypes.hpp index 99c4202c6..f26f7c3e1 100644 --- a/firmware/baseband/fprotos/subghztypes.hpp +++ b/firmware/baseband/fprotos/subghztypes.hpp @@ -25,6 +25,7 @@ enum FPROTO_SUBGHZD_SENSOR { FPS_CAME = 4, FPS_PRASTEL = 5, FPS_AIRFORCE = 6, + FPS_CAMEATOMO = 7, }; #endif \ No newline at end of file diff --git a/firmware/baseband/proc_subghzd.cpp b/firmware/baseband/proc_subghzd.cpp index 82d66f897..2bbeb8dd5 100644 --- a/firmware/baseband/proc_subghzd.cpp +++ b/firmware/baseband/proc_subghzd.cpp @@ -71,7 +71,7 @@ void WeatherProcessor::on_message(const Message* const message) { } void WeatherProcessor::configure(const SubGhzFPRxConfigureMessage& message) { - constexpr size_t decim_0_output_fs = baseband_fs / decim_0.decimation_factor; + // constexpr size_t decim_0_output_fs = baseband_fs / decim_0.decimation_factor; //unused // constexpr size_t decim_1_output_fs = decim_0_output_fs / decim_1.decimation_factor; //unused decim_0.configure(taps_200k_wfm_decim_0.taps);