flipperzero-firmware/lib/subghz/protocols/subghz_protocol_nero_sketch.c
Skorpionm a024e470b7
SubGhz: read and save static remotes. Create new static and dynamic remotes. (#646)
* SubGhz: the functions of saving loading KeeLog have been modified, saving KeeLog is prohibited
* SubGhz: Fix displaying Nice FlorS in the Raed scene
* SubGhz: Fix displaying Faac SLH in the Raed scene
* SubGhz: Fix displaying iDo in the Raed scene
* SubGhz: Fix displaying Star Line in the Raed scene
* SubGhz: Fix displaying Nice Flo in the Raed scene, added save and load functions. (testing needed, no remote control)
* SubGhz: subghz_beginadded common encoder upload signal
* SubGhz: add Came encoder
* SubGhz: modified pricenton encoder, fix view transmitter hide the "Send" button if there is no encoder
* SubGhz: add nice flo encoder, need testing no remote control
* SubGhz: add gate_tx encoder
* SubGhz: add nero_sketch encoder
* SubGhz: add keelog encoder
* SubGhz: add long upload upload while the button is pressed while releasing the transfer is over, with a check for sticking (maximum 200 upload repetitions)
* SubGhz: fix max upload
* SubGhz: Fix structure subghz add encoder
* SubGhz: add generating and sending a dynamic keelog key, refactoring the code
* SubGhz: add notifications
* SubGhz: add creating a new remote control (Pricenton, Nice Flo 12bit, Nice Flo 24bit, CAME 12bit, CAME 24bit, Gate TX, DoorHan)
* SubGhz: Fix load file, fix scene start
* Subghz: Fix show key
* SubGhz: Fix subghz_cli
* SubGhz: Fix furi-hal-subghz
* Format sources
* SubGhz: standard notification scheme, fix broken assert in DMA.
* SubGhz: move level alignment logic to furi-hal-subghz, fix spelling, cleanup.

Co-authored-by: Aleksandr Kutuzov <alleteam@gmail.com>
2021-08-16 22:56:23 +03:00

252 lines
10 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "subghz_protocol_nero_sketch.h"
struct SubGhzProtocolNeroSketch {
SubGhzProtocolCommon common;
};
SubGhzProtocolNeroSketch* subghz_protocol_nero_sketch_alloc(void) {
SubGhzProtocolNeroSketch* instance = furi_alloc(sizeof(SubGhzProtocolNeroSketch));
instance->common.name = "Nero Sketch";
instance->common.code_min_count_bit_for_found = 40;
instance->common.te_short = 330;
instance->common.te_long = 660;
instance->common.te_delta = 150;
instance->common.type_protocol = TYPE_PROTOCOL_STATIC;
instance->common.to_string = (SubGhzProtocolCommonToStr)subghz_protocol_nero_sketch_to_str;
instance->common.to_save_string =
(SubGhzProtocolCommonGetStrSave)subghz_protocol_nero_sketch_to_save_str;
instance->common.to_load_protocol=
(SubGhzProtocolCommonLoad)subghz_protocol_nero_sketch_to_load_protocol;
instance->common.get_upload_protocol =
(SubGhzProtocolEncoderCommonGetUpLoad)subghz_protocol_nero_sketch_send_key;
return instance;
}
void subghz_protocol_nero_sketch_free(SubGhzProtocolNeroSketch* instance) {
furi_assert(instance);
free(instance);
}
bool subghz_protocol_nero_sketch_send_key(SubGhzProtocolNeroSketch* instance, SubGhzProtocolEncoderCommon* encoder){
furi_assert(instance);
furi_assert(encoder);
size_t index = 0;
encoder->size_upload = 47*2+2+(instance->common.code_last_count_bit * 2) + 2;
if(encoder->size_upload > SUBGHZ_ENCODER_UPLOAD_MAX_SIZE) return false;
//Send header
for(uint8_t i = 0; i < 47; i++){
encoder->upload[index++] = level_duration_make(true, (uint32_t)instance->common.te_short);
encoder->upload[index++] = level_duration_make(false, (uint32_t)instance->common.te_short);
}
//Send start bit
encoder->upload[index++] = level_duration_make(true, (uint32_t)instance->common.te_short*4);
encoder->upload[index++] = level_duration_make(false, (uint32_t)instance->common.te_short);
//Send key data
for (uint8_t i = instance->common.code_last_count_bit; i > 0; i--) {
if(bit_read(instance->common.code_last_found, i - 1)){
//send bit 1
encoder->upload[index++] = level_duration_make(true, (uint32_t)instance->common.te_long);
encoder->upload[index++] = level_duration_make(false, (uint32_t)instance->common.te_short);
}else{
//send bit 0
encoder->upload[index++] = level_duration_make(true, (uint32_t)instance->common.te_short);
encoder->upload[index++] = level_duration_make(false, (uint32_t)instance->common.te_long);
}
}
//Send stop bit
encoder->upload[index++] = level_duration_make(true, (uint32_t)instance->common.te_short*3);
encoder->upload[index++] = level_duration_make(false, (uint32_t)instance->common.te_short);
return true;
}
void subghz_protocol_nero_sketch_reset(SubGhzProtocolNeroSketch* instance) {
instance->common.parser_step = 0;
}
/** Analysis of received data
*
* @param instance SubGhzProtocolNeroSketch instance
*/
// void subghz_protocol_nero_sketch_check_remote_controller(SubGhzProtocolNeroSketch* instance) {
// //пока не понятно с серийником, но код статический
// // uint64_t code_found_reverse = subghz_protocol_common_reverse_key(instance->common.code_found, instance->common.code_count_bit);
// // uint32_t code_fix = code_found_reverse & 0xFFFFFFFF;
// // //uint32_t code_hop = (code_found_reverse >> 24) & 0xFFFFF;
// // instance->common.serial = code_fix & 0xFFFFFFF;
// // instance->common.btn = (code_fix >> 28) & 0x0F;
// //if (instance->common.callback) instance->common.callback((SubGhzProtocolCommon*)instance, instance->common.context);
// }
void subghz_protocol_nero_sketch_parse(SubGhzProtocolNeroSketch* instance, bool level, uint32_t duration) {
switch (instance->common.parser_step) {
case 0:
if ((level)
&& (DURATION_DIFF(duration,instance->common.te_short)< instance->common.te_delta)) {
instance->common.parser_step = 1;
instance->common.te_last = duration;
instance->common.header_count = 0;
} else {
instance->common.parser_step = 0;
}
break;
case 1:
if (level){
if((DURATION_DIFF(duration,instance->common.te_short)< instance->common.te_delta )
|| (DURATION_DIFF(duration,instance->common.te_short*4)< instance->common.te_delta)) {
instance->common.te_last = duration;
} else {
instance->common.parser_step = 0;
}
} else if(DURATION_DIFF(duration,instance->common.te_short)< instance->common.te_delta){
if(DURATION_DIFF(instance->common.te_last,instance->common.te_short)< instance->common.te_delta){
// Found header
instance->common.header_count++;
break;
}else if(DURATION_DIFF(instance->common.te_last,instance->common.te_short*4)< instance->common.te_delta){
// Found start bit
if(instance->common.header_count>40) {
instance->common.parser_step = 2;
instance->common.code_found = 0;
instance->common.code_count_bit = 0;
}else {
instance->common.parser_step = 0;
}
} else {
instance->common.parser_step = 0;
}
} else {
instance->common.parser_step = 0;
}
break;
case 2:
if (level) {
if (duration >= (instance->common.te_short * 2 + instance->common.te_delta*2)) {
//Found stop bit
instance->common.parser_step = 0;
if (instance->common.code_count_bit>= instance->common.code_min_count_bit_for_found) {
instance->common.code_last_found = instance->common.code_found;
instance->common.code_last_count_bit = instance->common.code_count_bit;
if (instance->common.callback) instance->common.callback((SubGhzProtocolCommon*)instance, instance->common.context);
}
instance->common.code_found = 0;
instance->common.code_count_bit = 0;
break;
} else {
instance->common.te_last = duration;
instance->common.parser_step = 3;
}
}else{
instance->common.parser_step = 0;
}
break;
case 3:
if(!level){
if ((DURATION_DIFF(instance->common.te_last,instance->common.te_short)< instance->common.te_delta)
&& (DURATION_DIFF(duration,instance->common.te_long)< instance->common.te_delta)) {
subghz_protocol_common_add_bit(&instance->common, 0);
instance->common.parser_step = 2;
} else if ((DURATION_DIFF(instance->common.te_last,instance->common.te_long )< instance->common.te_delta)
&& (DURATION_DIFF(duration,instance->common.te_short)< instance->common.te_delta)) {
subghz_protocol_common_add_bit(&instance->common, 1);
instance->common.parser_step = 2;
} else {
instance->common.parser_step = 0;
}
} else {
instance->common.parser_step = 0;
}
break;
}
}
void subghz_protocol_nero_sketch_to_str(SubGhzProtocolNeroSketch* instance, string_t output) {
uint32_t code_found_hi = instance->common.code_last_found >> 32;
uint32_t code_found_lo = instance->common.code_last_found & 0x00000000ffffffff;
uint64_t code_found_reverse = subghz_protocol_common_reverse_key(instance->common.code_last_found, instance->common.code_last_count_bit);
uint32_t code_found_reverse_hi = code_found_reverse>>32;
uint32_t code_found_reverse_lo = code_found_reverse&0x00000000ffffffff;
string_cat_printf(output,
"%s, %d Bit\r\n"
" KEY:0x%lX%08lX\r\n"
" YEK:0x%lX%08lX\r\n",
instance->common.name,
instance->common.code_last_count_bit,
code_found_hi,
code_found_lo,
code_found_reverse_hi,
code_found_reverse_lo
);
}
void subghz_protocol_nero_sketch_to_save_str(SubGhzProtocolNeroSketch* instance, string_t output) {
uint32_t code_found_hi = instance->common.code_last_found >> 32;
uint32_t code_found_lo = instance->common.code_last_found & 0x00000000ffffffff;
string_printf(
output,
"Protocol: %s\n"
"Bit: %d\n"
"Key: %08lX%08lX\n",
instance->common.name,
instance->common.code_last_count_bit,
code_found_hi,
code_found_lo
);
}
bool subghz_protocol_nero_sketch_to_load_protocol(FileWorker* file_worker, SubGhzProtocolNeroSketch* instance){
bool loaded = false;
string_t temp_str;
string_init(temp_str);
int res = 0;
int data = 0;
do {
// Read and parse bit data from 2nd line
if(!file_worker_read_until(file_worker, temp_str, '\n')) {
break;
}
res = sscanf(string_get_cstr(temp_str), "Bit: %d\n", &data);
if(res != 1) {
break;
}
instance->common.code_last_count_bit = (uint8_t)data;
// Read and parse key data from 3nd line
if(!file_worker_read_until(file_worker, temp_str, '\n')) {
break;
}
uint32_t temp_key_hi = 0;
uint32_t temp_key_lo = 0;
res = sscanf(string_get_cstr(temp_str), "Key: %08lX%08lX\n", &temp_key_hi, &temp_key_lo);
if(res != 2) {
break;
}
instance->common.code_last_found = (uint64_t)temp_key_hi<<32 | temp_key_lo;
loaded = true;
} while(0);
string_clear(temp_str);
return loaded;
}