 4418e73b26
			
		
	
	
		4418e73b26
		
			
		
	
	
	
	
		
			
			* ToolBox: add manchester-decoder and manchester-encoder * SubGhz: add new FM config cc1101 * Subghz: add protocol Kia * SubGhz: fix receiving the last packet Nero Radio * SubGhz: app protocol CAME Twin (TW2EE/TW4EE) * SubGhz: add protocol CAME Atomo (AT03EV/ AT04EV) * F7: sync with F6 * SubGhz: add frequency analyzer * SubGhz: remove space from file name * SubGhz: frequency analyzer add filter and fix view * [FL-1939] GubGhz: Frequency analyzer redesign * SubGhz: fix incorrect subghz api call sequence in frequency analyzer worker Co-authored-by: Aleksandr Kutuzov <alleteam@gmail.com>
		
			
				
	
	
		
			232 lines
		
	
	
		
			8.9 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			232 lines
		
	
	
		
			8.9 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| #include "subghz_protocol_came_atomo.h"
 | |
| #include "subghz_protocol_common.h"
 | |
| #include <lib/toolbox/manchester-decoder.h>
 | |
| 
 | |
| struct SubGhzProtocolCameAtomo {
 | |
|     SubGhzProtocolCommon common;
 | |
|     ManchesterState manchester_saved_state;
 | |
| };
 | |
| 
 | |
| typedef enum {
 | |
|     CameAtomoDecoderStepReset = 0,
 | |
|     CameAtomoDecoderStepDecoderData,
 | |
| } CameAtomoDecoderStep;
 | |
| 
 | |
| SubGhzProtocolCameAtomo* subghz_protocol_came_atomo_alloc() {
 | |
|     SubGhzProtocolCameAtomo* instance = furi_alloc(sizeof(SubGhzProtocolCameAtomo));
 | |
| 
 | |
|     instance->common.name = "CAME Atomo";
 | |
|     instance->common.code_min_count_bit_for_found = 62;
 | |
|     instance->common.te_short = 600;
 | |
|     instance->common.te_long = 1200;
 | |
|     instance->common.te_delta = 250;
 | |
|     instance->common.type_protocol = SubGhzProtocolCommonTypeStatic;
 | |
|     instance->common.to_string = (SubGhzProtocolCommonToStr)subghz_protocol_came_atomo_to_str;
 | |
|     // instance->common.to_save_string =
 | |
|     //     (SubGhzProtocolCommonGetStrSave)subghz_protocol_came_atomo_to_save_str;
 | |
|     //instance->common.to_load_protocol_from_file =
 | |
|     //    (SubGhzProtocolCommonLoadFromFile)subghz_protocol_came_atomo_to_load_protocol_from_file;
 | |
|     instance->common.to_load_protocol =
 | |
|         (SubGhzProtocolCommonLoadFromRAW)subghz_decoder_came_atomo_to_load_protocol;
 | |
|     // instance->common.get_upload_protocol =
 | |
|     //     (SubGhzProtocolCommonEncoderGetUpLoad)subghz_protocol_came_atomo_send_key;
 | |
| 
 | |
|     return instance;
 | |
| }
 | |
| 
 | |
| void subghz_protocol_came_atomo_free(SubGhzProtocolCameAtomo* instance) {
 | |
|     furi_assert(instance);
 | |
|     free(instance);
 | |
| }
 | |
| 
 | |
| /** Analysis of received data
 | |
|  * 
 | |
|  * @param instance SubGhzProtocolCameAtomo instance
 | |
|  */
 | |
| void subghz_protocol_came_atomo_remote_controller(SubGhzProtocolCameAtomo* instance) {
 | |
| }
 | |
| 
 | |
| void subghz_protocol_came_atomo_reset(SubGhzProtocolCameAtomo* instance) {
 | |
|     instance->common.parser_step = CameAtomoDecoderStepReset;
 | |
|     manchester_advance(
 | |
|         instance->manchester_saved_state,
 | |
|         ManchesterEventReset,
 | |
|         &instance->manchester_saved_state,
 | |
|         NULL);
 | |
| }
 | |
| 
 | |
| void subghz_protocol_came_atomo_parse(
 | |
|     SubGhzProtocolCameAtomo* instance,
 | |
|     bool level,
 | |
|     uint32_t duration) {
 | |
|     ManchesterEvent event = ManchesterEventReset;
 | |
|     switch(instance->common.parser_step) {
 | |
|     case CameAtomoDecoderStepReset:
 | |
|         if((!level) && (DURATION_DIFF(duration, instance->common.te_long * 65) <
 | |
|                         instance->common.te_delta * 20)) {
 | |
|             //Found header CAME
 | |
|             instance->common.parser_step = CameAtomoDecoderStepDecoderData;
 | |
|             instance->common.code_found = 0;
 | |
|             instance->common.code_count_bit = 1;
 | |
|             manchester_advance(
 | |
|                 instance->manchester_saved_state,
 | |
|                 ManchesterEventReset,
 | |
|                 &instance->manchester_saved_state,
 | |
|                 NULL);
 | |
|             manchester_advance(
 | |
|                 instance->manchester_saved_state,
 | |
|                 ManchesterEventShortLow,
 | |
|                 &instance->manchester_saved_state,
 | |
|                 NULL);
 | |
|         } else {
 | |
|             instance->common.parser_step = CameAtomoDecoderStepReset;
 | |
|         }
 | |
|         break;
 | |
|     case CameAtomoDecoderStepDecoderData:
 | |
|         if(!level) {
 | |
|             if(DURATION_DIFF(duration, instance->common.te_short) < instance->common.te_delta) {
 | |
|                 event = ManchesterEventShortLow;
 | |
|             } else if(DURATION_DIFF(duration, instance->common.te_long) < instance->common.te_delta) {
 | |
|                 event = ManchesterEventLongLow;
 | |
|             } else if(duration >= (instance->common.te_long * 2 + instance->common.te_delta)) {
 | |
|                 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;
 | |
|                     // 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;
 | |
|                     // FURI_LOG_I(
 | |
|                     //     "ATOMO",
 | |
|                     //     "%08lX%08lX  %08lX%08lX  %d",
 | |
|                     //     code_found_hi,
 | |
|                     //     code_found_lo,
 | |
|                     //     code_found_reverse_hi,
 | |
|                     //     code_found_reverse_lo,
 | |
|                     //     instance->common.code_last_count_bit);
 | |
|                     if(instance->common.callback)
 | |
|                         instance->common.callback(
 | |
|                             (SubGhzProtocolCommon*)instance, instance->common.context);
 | |
|                 }
 | |
|                 instance->common.code_found = 0;
 | |
|                 instance->common.code_count_bit = 1;
 | |
|                 manchester_advance(
 | |
|                     instance->manchester_saved_state,
 | |
|                     ManchesterEventReset,
 | |
|                     &instance->manchester_saved_state,
 | |
|                     NULL);
 | |
|                 manchester_advance(
 | |
|                     instance->manchester_saved_state,
 | |
|                     ManchesterEventShortLow,
 | |
|                     &instance->manchester_saved_state,
 | |
|                     NULL);
 | |
|             } else {
 | |
|                 instance->common.parser_step = CameAtomoDecoderStepReset;
 | |
|             }
 | |
|         } else {
 | |
|             if(DURATION_DIFF(duration, instance->common.te_short) < instance->common.te_delta) {
 | |
|                 event = ManchesterEventShortHigh;
 | |
|             } else if(DURATION_DIFF(duration, instance->common.te_long) < instance->common.te_delta) {
 | |
|                 event = ManchesterEventLongHigh;
 | |
|             } else {
 | |
|                 instance->common.parser_step = CameAtomoDecoderStepReset;
 | |
|             }
 | |
|         }
 | |
|         if(event != ManchesterEventReset) {
 | |
|             bool data;
 | |
|             bool data_ok = manchester_advance(
 | |
|                 instance->manchester_saved_state, event, &instance->manchester_saved_state, &data);
 | |
| 
 | |
|             if(data_ok) {
 | |
|                 instance->common.code_found = (instance->common.code_found << 1) | !data;
 | |
|                 instance->common.code_count_bit++;
 | |
|             }
 | |
|         }
 | |
|         break;
 | |
|     }
 | |
| }
 | |
| void subghz_protocol_came_atomo_to_str(SubGhzProtocolCameAtomo* 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_cat_printf(
 | |
|         output,
 | |
|         "%s %dbit\r\n"
 | |
|         "Key:0x%lX%08lX\r\n",
 | |
|         instance->common.name,
 | |
|         instance->common.code_last_count_bit,
 | |
|         code_found_hi,
 | |
|         code_found_lo);
 | |
| }
 | |
| 
 | |
| // void subghz_protocol_came_atomo_to_save_str(SubGhzProtocolCameAtomo* instance, string_t output) {
 | |
| //     string_printf(
 | |
| //         output,
 | |
| //         "Protocol: %s\n"
 | |
| //         "Bit: %d\n"
 | |
| //         "Key: %08lX%08lX\r\n",
 | |
| //         instance->common.name,
 | |
| //         instance->common.code_last_count_bit,
 | |
| //         (uint32_t)(instance->common.code_last_found >> 32),
 | |
| //         (uint32_t)(instance->common.code_last_found & 0xFFFFFFFF));
 | |
| // }
 | |
| 
 | |
| // bool subghz_protocol_came_atomo_to_load_protocol_from_file(
 | |
| //     FileWorker* file_worker,
 | |
| //     SubGhzProtocolCameAtomo* 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;
 | |
| //         }
 | |
| //         // strlen("Key: ") = 5
 | |
| //         string_right(temp_str, 5);
 | |
| 
 | |
| //         uint8_t buf_key[8] = {0};
 | |
| //         if(!subghz_protocol_common_read_hex(temp_str, buf_key, 8)) {
 | |
| //             break;
 | |
| //         }
 | |
| 
 | |
| //         for(uint8_t i = 0; i < 8; i++) {
 | |
| //             instance->common.code_last_found = instance->common.code_last_found << 8 | buf_key[i];
 | |
| //         }
 | |
| 
 | |
| //         loaded = true;
 | |
| //     } while(0);
 | |
| 
 | |
| //     string_clear(temp_str);
 | |
| 
 | |
| //     subghz_protocol_came_atomo_remote_controller(instance);
 | |
| //     return loaded;
 | |
| // }
 | |
| 
 | |
| void subghz_decoder_came_atomo_to_load_protocol(SubGhzProtocolCameAtomo* instance, void* context) {
 | |
|     furi_assert(context);
 | |
|     furi_assert(instance);
 | |
|     SubGhzProtocolCommonLoad* data = context;
 | |
|     instance->common.code_last_found = data->code_found;
 | |
|     instance->common.code_last_count_bit = data->code_count_bit;
 | |
|     subghz_protocol_came_atomo_remote_controller(instance);
 | |
| }
 |