More protos

This commit is contained in:
HTotoo 2023-12-09 22:40:13 +01:00
parent d1de61d9e5
commit 25786026ac
8 changed files with 373 additions and 2 deletions

View File

@ -142,6 +142,12 @@ const char* SubGhzDView::getSensorTypeName(FPROTO_SUBGHZD_SENSOR type) {
return "Came Atomo"; return "Came Atomo";
case FPS_CAMETWEE: case FPS_CAMETWEE:
return "Came Twee"; return "Came Twee";
case FPS_CHAMBCODE:
return "Chamb Code";
case FPS_CLEMSA:
return "Clemsa";
case FPS_DOITRAND:
return "Doitrand";
case FPS_Invalid: case FPS_Invalid:
default: default:
return "Unknown"; return "Unknown";

View File

@ -7,6 +7,17 @@
#include <stddef.h> #include <stddef.h>
#define bit_read(value, bit) (((value) >> (bit)) & 0x01) #define bit_read(value, bit) (((value) >> (bit)) & 0x01)
#define bit_set(value, bit) \
({ \
__typeof__(value) _one = (1); \
(value) |= (_one << (bit)); \
})
#define bit_clear(value, bit) \
({ \
__typeof__(value) _one = (1); \
(value) &= ~(_one << (bit)); \
})
#define bit_write(value, bit, bitvalue) (bitvalue ? bit_set(value, bit) : bit_clear(value, bit))
#define DURATION_DIFF(x, y) (((x) < (y)) ? ((y) - (x)) : ((x) - (y))) #define DURATION_DIFF(x, y) (((x) < (y)) ? ((y) - (x)) : ((x) - (y)))

View File

@ -119,10 +119,10 @@ class FProtoSubGhzDCameTwee : public FProtoSubGhzDBase {
*/ */
uint8_t cnt_parcel = (uint8_t)(data & 0xF); uint8_t cnt_parcel = (uint8_t)(data & 0xF);
uint32_t data = (uint32_t)(data & 0x0FFFFFFFF); uint32_t dataa = (uint32_t)(data & 0x0FFFFFFFF);
data = (data ^ came_twee_magic_numbers_xor[cnt_parcel]); data = (data ^ came_twee_magic_numbers_xor[cnt_parcel]);
serial = data; serial = dataa;
data /= 4; data /= 4;
btn = (data >> 4) & 0x0F; btn = (data >> 4) & 0x0F;
data >>= 16; data >>= 16;

View File

@ -0,0 +1,165 @@
#ifndef __FPROTO_CHAMBCODE_H__
#define __FPROTO_CHAMBCODE_H__
#include "subghzdbase.hpp"
#define CHAMBERLAIN_CODE_BIT_STOP 0b0001
#define CHAMBERLAIN_CODE_BIT_1 0b0011
#define CHAMBERLAIN_CODE_BIT_0 0b0111
#define CHAMBERLAIN_7_CODE_MASK 0xF000000FF0F
#define CHAMBERLAIN_8_CODE_MASK 0xF00000F00F
#define CHAMBERLAIN_9_CODE_MASK 0xF000000000F
#define CHAMBERLAIN_7_CODE_MASK_CHECK 0x10000001101
#define CHAMBERLAIN_8_CODE_MASK_CHECK 0x1000001001
#define CHAMBERLAIN_9_CODE_MASK_CHECK 0x10000000001
typedef enum {
Chamb_CodeDecoderStepReset = 0,
Chamb_CodeDecoderStepFoundStartBit,
Chamb_CodeDecoderStepSaveDuration,
Chamb_CodeDecoderStepCheckDuration,
} Chamb_CodeDecoderStep;
class FProtoSubGhzDChambCode : public FProtoSubGhzDBase {
public:
FProtoSubGhzDChambCode() {
sensorType = FPS_CHAMBCODE;
}
void feed(bool level, uint32_t duration) {
switch (parser_step) {
case Chamb_CodeDecoderStepReset:
if ((!level) && (DURATION_DIFF(duration, te_short * 39) < te_delta * 20)) {
// Found header Chamb_Code
parser_step = Chamb_CodeDecoderStepFoundStartBit;
}
break;
case Chamb_CodeDecoderStepFoundStartBit:
if ((level) && (DURATION_DIFF(duration, te_short) < te_delta)) {
// Found start bit Chamb_Code
decode_data = 0;
decode_count_bit = 0;
decode_data = decode_data << 4 | CHAMBERLAIN_CODE_BIT_STOP;
decode_count_bit++;
parser_step = Chamb_CodeDecoderStepSaveDuration;
} else {
parser_step = Chamb_CodeDecoderStepReset;
}
break;
case Chamb_CodeDecoderStepSaveDuration:
if (!level) { // save interval
if (duration > te_short * 5) {
if (decode_count_bit >=
min_count_bit_for_found) {
serial = SD_NO_SERIAL;
btn = SD_NO_BTN;
if (subghz_protocol_decoder_chamb_code_check_mask_and_parse()) {
data = decode_data;
data_count_bit = decode_count_bit;
if (callback) callback(this);
}
}
parser_step = Chamb_CodeDecoderStepReset;
} else {
te_last = duration;
parser_step = Chamb_CodeDecoderStepCheckDuration;
}
} else {
parser_step = Chamb_CodeDecoderStepReset;
}
break;
case Chamb_CodeDecoderStepCheckDuration:
if (level) {
if ((DURATION_DIFF( // Found stop bit Chamb_Code
te_last,
te_short * 3) <
te_delta) &&
(DURATION_DIFF(duration, te_short) <
te_delta)) {
decode_data = decode_data << 4 |
CHAMBERLAIN_CODE_BIT_STOP;
decode_count_bit++;
parser_step = Chamb_CodeDecoderStepSaveDuration;
} else if (
(DURATION_DIFF(
te_last, te_short * 2) <
te_delta) &&
(DURATION_DIFF(duration, te_short * 2) <
te_delta)) {
decode_data = decode_data << 4 |
CHAMBERLAIN_CODE_BIT_1;
decode_count_bit++;
parser_step = Chamb_CodeDecoderStepSaveDuration;
} else if (
(DURATION_DIFF(
te_last, te_short) <
te_delta) &&
(DURATION_DIFF(duration, te_short * 3) <
te_delta)) {
decode_data = decode_data << 4 |
CHAMBERLAIN_CODE_BIT_0;
decode_count_bit++;
parser_step = Chamb_CodeDecoderStepSaveDuration;
} else {
parser_step = Chamb_CodeDecoderStepReset;
}
} else {
parser_step = Chamb_CodeDecoderStepReset;
}
break;
}
}
protected:
uint32_t te_short = 1000;
uint32_t te_long = 3000;
uint32_t te_delta = 200;
uint32_t min_count_bit_for_found = 10;
bool subghz_protocol_decoder_chamb_code_check_mask_and_parse() {
if (decode_count_bit > min_count_bit_for_found + 1)
return false;
if ((decode_data & CHAMBERLAIN_7_CODE_MASK) == CHAMBERLAIN_7_CODE_MASK_CHECK) {
decode_count_bit = 7;
decode_data &= ~CHAMBERLAIN_7_CODE_MASK;
decode_data = (decode_data >> 12) | ((decode_data >> 4) & 0xF);
} else if (
(decode_data & CHAMBERLAIN_8_CODE_MASK) == CHAMBERLAIN_8_CODE_MASK_CHECK) {
decode_count_bit = 8;
decode_data &= ~CHAMBERLAIN_8_CODE_MASK;
decode_data = decode_data >> 4 | CHAMBERLAIN_CODE_BIT_0 << 8; // DIP 6 no use
} else if (
(decode_data & CHAMBERLAIN_9_CODE_MASK) == CHAMBERLAIN_9_CODE_MASK_CHECK) {
decode_count_bit = 9;
decode_data &= ~CHAMBERLAIN_9_CODE_MASK;
decode_data >>= 4;
} else {
return false;
}
return subghz_protocol_chamb_code_to_bit(&decode_data, decode_count_bit);
}
bool subghz_protocol_chamb_code_to_bit(uint64_t* data, uint8_t size) {
uint64_t data_tmp = data[0];
uint64_t data_res = 0;
for (uint8_t i = 0; i < size; i++) {
if ((data_tmp & 0xFll) == CHAMBERLAIN_CODE_BIT_0) {
bit_write(data_res, i, 0);
} else if ((data_tmp & 0xFll) == CHAMBERLAIN_CODE_BIT_1) {
bit_write(data_res, i, 1);
} else {
return false;
}
data_tmp >>= 4;
}
data[0] = data_res;
return true;
}
};
#endif

View File

@ -0,0 +1,92 @@
#ifndef __FPROTO_CLEMSA_H__
#define __FPROTO_CLEMSA_H__
#include "subghzdbase.hpp"
typedef enum {
ClemsaDecoderStepReset = 0,
ClemsaDecoderStepSaveDuration,
ClemsaDecoderStepCheckDuration,
} ClemsaDecoderStep;
class FProtoSubGhzDClemsa : public FProtoSubGhzDBase {
public:
FProtoSubGhzDClemsa() {
sensorType = FPS_CLEMSA;
}
void feed(bool level, uint32_t duration) {
switch (parser_step) {
case ClemsaDecoderStepReset:
if ((!level) && (DURATION_DIFF(duration, te_short * 51) < te_delta * 25)) {
parser_step = ClemsaDecoderStepSaveDuration;
decode_data = 0;
decode_count_bit = 0;
}
break;
case ClemsaDecoderStepSaveDuration:
if (level) {
te_last = duration;
parser_step = ClemsaDecoderStepCheckDuration;
} else {
parser_step = ClemsaDecoderStepReset;
}
break;
case ClemsaDecoderStepCheckDuration:
if (!level) {
if ((DURATION_DIFF(te_last, te_short) < te_delta) &&
(DURATION_DIFF(duration, te_long) < te_delta * 3)) {
subghz_protocol_blocks_add_bit(0);
parser_step = ClemsaDecoderStepSaveDuration;
} else if (
(DURATION_DIFF(te_last, te_long) < te_delta * 3) &&
(DURATION_DIFF(duration, te_short) < te_delta)) {
subghz_protocol_blocks_add_bit(1);
parser_step = ClemsaDecoderStepSaveDuration;
} else if (
DURATION_DIFF(duration, te_short * 51) < te_delta * 25) {
if ((DURATION_DIFF(te_last, te_short) < te_delta)) {
subghz_protocol_blocks_add_bit(0);
} else if ((DURATION_DIFF(te_last, te_long) < te_delta * 3)) {
subghz_protocol_blocks_add_bit(1);
} else {
parser_step = ClemsaDecoderStepReset;
}
if (decode_count_bit ==
min_count_bit_for_found) {
data = decode_data;
data_count_bit = decode_count_bit;
subghz_protocol_clemsa_check_remote_controller();
if (callback) callback(this);
}
parser_step = ClemsaDecoderStepSaveDuration;
decode_data = 0;
decode_count_bit = 0;
} else {
parser_step = ClemsaDecoderStepReset;
}
} else {
parser_step = ClemsaDecoderStepReset;
}
break;
}
}
protected:
uint32_t te_short = 385;
uint32_t te_long = 2695;
uint32_t te_delta = 150;
uint32_t min_count_bit_for_found = 18;
void subghz_protocol_clemsa_check_remote_controller() {
serial = (data >> 2) & 0xFFFF;
btn = (data & 0x03);
}
};
#endif

View File

@ -0,0 +1,88 @@
#ifndef __FPROTO_DOITRAND_H__
#define __FPROTO_DOITRAND_H__
#include "subghzdbase.hpp"
typedef enum {
DoitrandDecoderStepReset = 0,
DoitrandDecoderStepFoundStartBit,
DoitrandDecoderStepSaveDuration,
DoitrandDecoderStepCheckDuration,
} DoitrandDecoderStep;
class FProtoSubGhzDDoitrand : public FProtoSubGhzDBase {
public:
FProtoSubGhzDDoitrand() {
sensorType = FPS_DOITRAND;
}
void feed(bool level, uint32_t duration) {
switch (parser_step) {
case DoitrandDecoderStepReset:
if ((!level) && (DURATION_DIFF(duration, te_short * 62) < te_delta * 30)) {
// Found Preambula
parser_step = DoitrandDecoderStepFoundStartBit;
}
break;
case DoitrandDecoderStepFoundStartBit:
if (level && ((DURATION_DIFF(duration, (te_short * 2)) < te_delta * 3))) {
// Found start bit
parser_step = DoitrandDecoderStepSaveDuration;
decode_data = 0;
decode_count_bit = 0;
} else {
parser_step = DoitrandDecoderStepReset;
}
break;
case DoitrandDecoderStepSaveDuration:
if (!level) {
if (duration >= ((uint32_t)te_short * 10 + te_delta)) {
parser_step = DoitrandDecoderStepFoundStartBit;
if (decode_count_bit == min_count_bit_for_found) {
data = decode_data;
data_count_bit = decode_count_bit;
// controller
cnt = (data >> 24) | ((data >> 15) & 0x1);
btn = ((data >> 18) & 0x3);
if (callback) callback(this);
}
decode_data = 0;
decode_count_bit = 0;
break;
} else {
te_last = duration;
parser_step = DoitrandDecoderStepCheckDuration;
}
}
break;
case DoitrandDecoderStepCheckDuration:
if (level) {
if ((DURATION_DIFF(te_last, te_short) < te_delta) &&
(DURATION_DIFF(duration, te_long) < te_delta * 3)) {
subghz_protocol_blocks_add_bit(0);
parser_step = DoitrandDecoderStepSaveDuration;
} else if (
(DURATION_DIFF(te_last, te_long) < te_delta * 3) &&
(DURATION_DIFF(duration, te_short) < te_delta)) {
subghz_protocol_blocks_add_bit(1);
parser_step = DoitrandDecoderStepSaveDuration;
} else {
parser_step = DoitrandDecoderStepReset;
}
} else {
parser_step = DoitrandDecoderStepReset;
}
break;
}
}
protected:
uint32_t te_short = 400;
uint32_t te_long = 1100;
uint32_t te_delta = 150;
uint32_t min_count_bit_for_found = 37;
};
#endif

View File

@ -16,6 +16,9 @@ So include here the .hpp, and add a new element to the protos vector in the cons
#include "s-came.hpp" #include "s-came.hpp"
#include "s-came_atomo.hpp" #include "s-came_atomo.hpp"
#include "s-came_twee.hpp" #include "s-came_twee.hpp"
#include "s-chambcode.hpp"
#include "s-clemsa.hpp"
#include "s-doitrand.hpp"
#ifndef __FPROTO_PROTOLISTSGZ_H__ #ifndef __FPROTO_PROTOLISTSGZ_H__
#define __FPROTO_PROTOLISTSGZ_H__ #define __FPROTO_PROTOLISTSGZ_H__
@ -30,6 +33,9 @@ class SubGhzDProtos : public FProtoListGeneral {
protos.push_back(std::make_unique<FProtoSubGhzDCame>()); // 4, 5, 6 protos.push_back(std::make_unique<FProtoSubGhzDCame>()); // 4, 5, 6
protos.push_back(std::make_unique<FProtoSubGhzDCameAtomo>()); // 7 protos.push_back(std::make_unique<FProtoSubGhzDCameAtomo>()); // 7
protos.push_back(std::make_unique<FProtoSubGhzDCameTwee>()); // 8 protos.push_back(std::make_unique<FProtoSubGhzDCameTwee>()); // 8
protos.push_back(std::make_unique<FProtoSubGhzDChambCode>()); // 9
protos.push_back(std::make_unique<FProtoSubGhzDClemsa>()); // 10
protos.push_back(std::make_unique<FProtoSubGhzDDoitrand>()); // 11
// set callback for them // set callback for them
for (const auto& obj : protos) { for (const auto& obj : protos) {

View File

@ -27,6 +27,9 @@ enum FPROTO_SUBGHZD_SENSOR {
FPS_AIRFORCE = 6, FPS_AIRFORCE = 6,
FPS_CAMEATOMO = 7, FPS_CAMEATOMO = 7,
FPS_CAMETWEE = 8, FPS_CAMETWEE = 8,
FPS_CHAMBCODE = 9,
FPS_CLEMSA = 10,
FPS_DOITRAND = 11,
}; };
#endif #endif