From 09527c3ab6dfdecf33c99e2bbe6eddaa64c30aa3 Mon Sep 17 00:00:00 2001 From: gid9798 <30450294+gid9798@users.noreply.github.com> Date: Sat, 20 May 2023 01:15:36 +0300 Subject: [PATCH 01/52] keeloq --- .../main/subghz/helpers/subghz_txrx.c | 6 + .../main/subghz/helpers/subghz_txrx.h | 2 + .../scenes/subghz_scene_receiver_info.c | 7 +- .../main/subghz/scenes/subghz_scene_rpc.c | 7 +- .../subghz/scenes/subghz_scene_transmitter.c | 8 +- .../main/subghz_remote/subghz_remote_app_i.c | 5 +- firmware/targets/f7/api_symbols.csv | 6 +- lib/subghz/environment.c | 30 +++++ lib/subghz/environment.h | 12 ++ lib/subghz/protocols/keeloq.c | 120 ++++++++++-------- lib/subghz/protocols/keeloq.h | 4 - lib/subghz/protocols/star_line.c | 77 ++++++----- 12 files changed, 176 insertions(+), 108 deletions(-) diff --git a/applications/main/subghz/helpers/subghz_txrx.c b/applications/main/subghz/helpers/subghz_txrx.c index c1f519ba0..c2d7e1bf5 100644 --- a/applications/main/subghz/helpers/subghz_txrx.c +++ b/applications/main/subghz/helpers/subghz_txrx.c @@ -557,6 +557,12 @@ bool subghz_txrx_get_debug_pin_state(SubGhzTxRx* instance) { return instance->debug_pin_state; } +void subghz_txrx_reset_dynamic(SubGhzTxRx* instance) { + furi_assert(instance); + subghz_environment_reset_keeloq(instance->environment); + subghz_custom_btns_reset(); +} + SubGhzReceiver* subghz_txrx_get_receiver(SubGhzTxRx* instance) { furi_assert(instance); return instance->receiver; diff --git a/applications/main/subghz/helpers/subghz_txrx.h b/applications/main/subghz/helpers/subghz_txrx.h index fd7c024b8..6c28cc5f0 100644 --- a/applications/main/subghz/helpers/subghz_txrx.h +++ b/applications/main/subghz/helpers/subghz_txrx.h @@ -293,4 +293,6 @@ void subghz_txrx_set_raw_file_encoder_worker_callback_end( void subghz_txrx_set_debug_pin_state(SubGhzTxRx* instance, bool state); bool subghz_txrx_get_debug_pin_state(SubGhzTxRx* instance); +void subghz_txrx_reset_dynamic(SubGhzTxRx* instance); + SubGhzReceiver* subghz_txrx_get_receiver(SubGhzTxRx* instance); // TODO use only in DecodeRaw diff --git a/applications/main/subghz/scenes/subghz_scene_receiver_info.c b/applications/main/subghz/scenes/subghz_scene_receiver_info.c index 2d89de731..d9ba5bd84 100644 --- a/applications/main/subghz/scenes/subghz_scene_receiver_info.c +++ b/applications/main/subghz/scenes/subghz_scene_receiver_info.c @@ -191,10 +191,5 @@ void subghz_scene_receiver_info_on_exit(void* context) { SubGhz* subghz = context; widget_reset(subghz->widget); - keeloq_reset_mfname(); - keeloq_reset_kl_type(); - keeloq_reset_original_btn(); - subghz_custom_btns_reset(); - star_line_reset_mfname(); - star_line_reset_kl_type(); + subghz_txrx_reset_dynamic(subghz->txrx); } diff --git a/applications/main/subghz/scenes/subghz_scene_rpc.c b/applications/main/subghz/scenes/subghz_scene_rpc.c index ef718c4e1..edadc89bb 100644 --- a/applications/main/subghz/scenes/subghz_scene_rpc.c +++ b/applications/main/subghz/scenes/subghz_scene_rpc.c @@ -110,10 +110,5 @@ void subghz_scene_rpc_on_exit(void* context) { popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignTop); popup_set_icon(popup, 0, 0, NULL); - keeloq_reset_mfname(); - keeloq_reset_kl_type(); - keeloq_reset_original_btn(); - subghz_custom_btns_reset(); - star_line_reset_mfname(); - star_line_reset_kl_type(); + subghz_txrx_reset_dynamic(subghz->txrx); } diff --git a/applications/main/subghz/scenes/subghz_scene_transmitter.c b/applications/main/subghz/scenes/subghz_scene_transmitter.c index 15a53603d..933f619f0 100644 --- a/applications/main/subghz/scenes/subghz_scene_transmitter.c +++ b/applications/main/subghz/scenes/subghz_scene_transmitter.c @@ -107,10 +107,6 @@ bool subghz_scene_transmitter_on_event(void* context, SceneManagerEvent event) { void subghz_scene_transmitter_on_exit(void* context) { SubGhz* subghz = context; subghz->state_notifications = SubGhzNotificationStateIDLE; - keeloq_reset_mfname(); - keeloq_reset_kl_type(); - keeloq_reset_original_btn(); - subghz_custom_btns_reset(); - star_line_reset_mfname(); - star_line_reset_kl_type(); + + subghz_txrx_reset_dynamic(subghz->txrx); } diff --git a/applications/main/subghz_remote/subghz_remote_app_i.c b/applications/main/subghz_remote/subghz_remote_app_i.c index 349fb87cd..6086b4c25 100644 --- a/applications/main/subghz_remote/subghz_remote_app_i.c +++ b/applications/main/subghz_remote/subghz_remote_app_i.c @@ -256,12 +256,9 @@ bool subrem_tx_stop_sub(SubGhzRemoteApp* app, bool forced) { subrem_save_protocol_to_file( sub_preset->fff_data, furi_string_get_cstr(sub_preset->file_path)); - keeloq_reset_mfname(); - keeloq_reset_kl_type(); + subghz_environment_reset_keeloq(app->environment); keeloq_reset_original_btn(); subghz_custom_btns_reset(); - star_line_reset_mfname(); - star_line_reset_kl_type(); } app->tx_running = false; diff --git a/firmware/targets/f7/api_symbols.csv b/firmware/targets/f7/api_symbols.csv index 84d0beda8..ddda9dcba 100644 --- a/firmware/targets/f7/api_symbols.csv +++ b/firmware/targets/f7/api_symbols.csv @@ -1,5 +1,5 @@ entry,status,name,type,params -Version,+,26.3,, +Version,+,26.5,, Header,+,applications/services/bt/bt_service/bt.h,, Header,+,applications/services/cli/cli.h,, Header,+,applications/services/cli/cli_vcp.h,, @@ -2731,7 +2731,11 @@ Function,+,subghz_environment_get_keystore,SubGhzKeystore*,SubGhzEnvironment* Function,+,subghz_environment_get_nice_flor_s_rainbow_table_file_name,const char*,SubGhzEnvironment* Function,+,subghz_environment_get_protocol_name_registry,const char*,"SubGhzEnvironment*, size_t" Function,+,subghz_environment_get_protocol_registry,void*,SubGhzEnvironment* +Function,-,subghz_environment_keeloq_get_kl_type,uint8_t,SubGhzEnvironment* +Function,-,subghz_environment_keeloq_get_mf,const char*,SubGhzEnvironment* +Function,-,subghz_environment_keeloq_set_mf,void,"SubGhzEnvironment*, const char*, uint8_t" Function,+,subghz_environment_load_keystore,_Bool,"SubGhzEnvironment*, const char*" +Function,+,subghz_environment_reset_keeloq,void,SubGhzEnvironment* Function,+,subghz_environment_set_alutech_at_4n_rainbow_table_file_name,void,"SubGhzEnvironment*, const char*" Function,+,subghz_environment_set_came_atomo_rainbow_table_file_name,void,"SubGhzEnvironment*, const char*" Function,+,subghz_environment_set_nice_flor_s_rainbow_table_file_name,void,"SubGhzEnvironment*, const char*" diff --git a/lib/subghz/environment.c b/lib/subghz/environment.c index 5ded243c4..55caedb6d 100644 --- a/lib/subghz/environment.c +++ b/lib/subghz/environment.c @@ -7,6 +7,8 @@ struct SubGhzEnvironment { const char* came_atomo_rainbow_table_file_name; const char* nice_flor_s_rainbow_table_file_name; const char* alutech_at_4n_rainbow_table_file_name; + const char* mfname; + uint8_t kl_type; }; SubGhzEnvironment* subghz_environment_alloc() { @@ -17,6 +19,8 @@ SubGhzEnvironment* subghz_environment_alloc() { instance->came_atomo_rainbow_table_file_name = NULL; instance->nice_flor_s_rainbow_table_file_name = NULL; instance->alutech_at_4n_rainbow_table_file_name = NULL; + instance->mfname = ""; + instance->kl_type = 0; return instance; } @@ -115,4 +119,30 @@ const char* } else { return NULL; } +} + +void subghz_environment_reset_keeloq(SubGhzEnvironment* instance) { + furi_assert(instance); + + instance->mfname = ""; + instance->kl_type = 0; +} + +const char* subghz_environment_keeloq_get_mf(SubGhzEnvironment* instance) { + furi_assert(instance); + + return instance->mfname; +} + +uint8_t subghz_environment_keeloq_get_kl_type(SubGhzEnvironment* instance) { + furi_assert(instance); + + return instance->kl_type; +} + +void subghz_environment_keeloq_set_mf(SubGhzEnvironment* instance, const char* mf, uint8_t kl_type) { + furi_assert(instance); + + instance->mfname = mf; + instance->kl_type = kl_type; } \ No newline at end of file diff --git a/lib/subghz/environment.h b/lib/subghz/environment.h index 7bd38ba2f..a23341e2f 100644 --- a/lib/subghz/environment.h +++ b/lib/subghz/environment.h @@ -110,6 +110,18 @@ void* subghz_environment_get_protocol_registry(SubGhzEnvironment* instance); */ const char* subghz_environment_get_protocol_name_registry(SubGhzEnvironment* instance, size_t idx); +/** + * Resetting the parameters used in the keeloq protocol. + * @param instance Pointer to a SubGhzEnvironment instance + */ +void subghz_environment_reset_keeloq(SubGhzEnvironment* instance); + +// Private + +const char* subghz_environment_keeloq_get_mf(SubGhzEnvironment* instance); +uint8_t subghz_environment_keeloq_get_kl_type(SubGhzEnvironment* instance); +void subghz_environment_keeloq_set_mf(SubGhzEnvironment* instance, const char* mf, uint8_t kl_type); + #ifdef __cplusplus } #endif diff --git a/lib/subghz/protocols/keeloq.c b/lib/subghz/protocols/keeloq.c index 26b5a20a9..0d151e68f 100644 --- a/lib/subghz/protocols/keeloq.c +++ b/lib/subghz/protocols/keeloq.c @@ -89,26 +89,20 @@ const SubGhzProtocol subghz_protocol_keeloq = { .decoder = &subghz_protocol_keeloq_decoder, .encoder = &subghz_protocol_keeloq_encoder, }; - -static const char* mfname; -static uint8_t kl_type; +// TODO: +// static const char* mfname; +// static uint8_t kl_type; static uint8_t klq_prog_mode; static uint16_t temp_counter; +static SubGhzEnvironment* kl_environment; + void keeloq_reset_original_btn() { subghz_custom_btns_reset(); temp_counter = 0; klq_prog_mode = KEELOQ_PROG_MODE_OFF; } -void keeloq_reset_mfname() { - mfname = ""; -} - -void keeloq_reset_kl_type() { - kl_type = 0; -} - /** * Analysis of received data * @param instance Pointer to a SubGhzBlockGeneric* instance @@ -127,6 +121,8 @@ void* subghz_protocol_encoder_keeloq_alloc(SubGhzEnvironment* environment) { instance->generic.protocol_name = instance->base.protocol->name; instance->keystore = subghz_environment_get_keystore(environment); + kl_environment = environment; + instance->encoder.repeat = 100; instance->encoder.size_upload = 256; instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration)); @@ -252,7 +248,7 @@ static bool subghz_protocol_keeloq_gen_data( decrypt = btn << 28 | (0x000) << 16 | instance->generic.cnt; // Beninca / Allmatic -> no serial - simple XOR } - + uint8_t kl_type_en = subghz_environment_keeloq_get_kl_type(kl_environment); for M_EACH( manufacture_code, @@ -292,21 +288,21 @@ static bool subghz_protocol_keeloq_gen_data( hop = subghz_protocol_keeloq_common_encrypt(decrypt, man); break; case KEELOQ_LEARNING_UNKNOWN: - if(kl_type == 1) { + if(kl_type_en == 1) { hop = subghz_protocol_keeloq_common_encrypt( decrypt, manufacture_code->key); } - if(kl_type == 2) { + if(kl_type_en == 2) { man = subghz_protocol_keeloq_common_normal_learning( fix, manufacture_code->key); hop = subghz_protocol_keeloq_common_encrypt(decrypt, man); } - if(kl_type == 3) { + if(kl_type_en == 3) { man = subghz_protocol_keeloq_common_secure_learning( fix, instance->generic.seed, manufacture_code->key); hop = subghz_protocol_keeloq_common_encrypt(decrypt, man); } - if(kl_type == 4) { + if(kl_type_en == 4) { man = subghz_protocol_keeloq_common_magic_xor_type1_learning( instance->generic.serial, manufacture_code->key); hop = subghz_protocol_keeloq_common_encrypt(decrypt, man); @@ -507,7 +503,15 @@ SubGhzProtocolStatus if(flipper_format_read_string( flipper_format, "Manufacture", instance->manufacture_from_file)) { instance->manufacture_name = furi_string_get_cstr(instance->manufacture_from_file); - mfname = furi_string_get_cstr(instance->manufacture_from_file); + subghz_environment_keeloq_set_mf( + kl_environment, + furi_string_get_cstr(instance->manufacture_from_file), + subghz_environment_keeloq_get_kl_type(kl_environment)); + // TODO: + FURI_LOG_W( + "MF encoder", + "Alloc enviro 0x%X", + (uintptr_t)subghz_environment_keeloq_get_mf(kl_environment)); } else { FURI_LOG_D(TAG, "ENCODER: Missing Manufacture"); } @@ -579,6 +583,7 @@ void* subghz_protocol_decoder_keeloq_alloc(SubGhzEnvironment* environment) { instance->keystore = subghz_environment_get_keystore(environment); instance->manufacture_from_file = furi_string_alloc(); + kl_environment = environment; klq_prog_mode = KEELOQ_PROG_MODE_OFF; return instance; @@ -596,8 +601,7 @@ void subghz_protocol_decoder_keeloq_reset(void* context) { furi_assert(context); SubGhzProtocolDecoderKeeloq* instance = context; instance->decoder.parser_step = KeeloqDecoderStepReset; - mfname = ""; - kl_type = 0; + subghz_environment_reset_keeloq(kl_environment); } void subghz_protocol_decoder_keeloq_feed(void* context, bool level, uint32_t duration) { @@ -740,9 +744,15 @@ static uint8_t subghz_protocol_keeloq_check_remote_controller_selector( uint32_t decrypt = 0; uint64_t man; bool mf_not_set = false; - if(mfname == 0x0) { - mfname = ""; - } + // TODO: + // if(mfname == 0x0) { + // mfname = ""; + // } + + const char* mfname = subghz_environment_keeloq_get_mf(kl_environment); + uint8_t kl_type_en = subghz_environment_keeloq_get_kl_type(kl_environment); + // TODO: + FURI_LOG_W("RMcontroll", "MF NAME: %s", mfname); if(strcmp(mfname, "Unknown") == 0) { return 1; @@ -758,7 +768,8 @@ static uint8_t subghz_protocol_keeloq_check_remote_controller_selector( decrypt = subghz_protocol_keeloq_common_decrypt(hop, manufacture_code->key); if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) { *manufacture_name = furi_string_get_cstr(manufacture_code->name); - mfname = *manufacture_name; + subghz_environment_keeloq_set_mf( + kl_environment, *manufacture_name, kl_type_en); return 1; } break; @@ -770,7 +781,8 @@ static uint8_t subghz_protocol_keeloq_check_remote_controller_selector( decrypt = subghz_protocol_keeloq_common_decrypt(hop, man); if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) { *manufacture_name = furi_string_get_cstr(manufacture_code->name); - mfname = *manufacture_name; + subghz_environment_keeloq_set_mf( + kl_environment, *manufacture_name, kl_type_en); return 1; } break; @@ -780,7 +792,8 @@ static uint8_t subghz_protocol_keeloq_check_remote_controller_selector( decrypt = subghz_protocol_keeloq_common_decrypt(hop, man); if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) { *manufacture_name = furi_string_get_cstr(manufacture_code->name); - mfname = *manufacture_name; + subghz_environment_keeloq_set_mf( + kl_environment, *manufacture_name, kl_type_en); return 1; } break; @@ -790,7 +803,8 @@ static uint8_t subghz_protocol_keeloq_check_remote_controller_selector( decrypt = subghz_protocol_keeloq_common_decrypt(hop, man); if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) { *manufacture_name = furi_string_get_cstr(manufacture_code->name); - mfname = *manufacture_name; + subghz_environment_keeloq_set_mf( + kl_environment, *manufacture_name, kl_type_en); return 1; } break; @@ -800,7 +814,8 @@ static uint8_t subghz_protocol_keeloq_check_remote_controller_selector( decrypt = subghz_protocol_keeloq_common_decrypt(hop, man); if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) { *manufacture_name = furi_string_get_cstr(manufacture_code->name); - mfname = *manufacture_name; + subghz_environment_keeloq_set_mf( + kl_environment, *manufacture_name, kl_type_en); return 1; } break; @@ -810,7 +825,8 @@ static uint8_t subghz_protocol_keeloq_check_remote_controller_selector( decrypt = subghz_protocol_keeloq_common_decrypt(hop, man); if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) { *manufacture_name = furi_string_get_cstr(manufacture_code->name); - mfname = *manufacture_name; + subghz_environment_keeloq_set_mf( + kl_environment, *manufacture_name, kl_type_en); return 1; } break; @@ -820,7 +836,8 @@ static uint8_t subghz_protocol_keeloq_check_remote_controller_selector( decrypt = subghz_protocol_keeloq_common_decrypt(hop, man); if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) { *manufacture_name = furi_string_get_cstr(manufacture_code->name); - mfname = *manufacture_name; + subghz_environment_keeloq_set_mf( + kl_environment, *manufacture_name, kl_type_en); return 1; } break; @@ -829,8 +846,7 @@ static uint8_t subghz_protocol_keeloq_check_remote_controller_selector( decrypt = subghz_protocol_keeloq_common_decrypt(hop, manufacture_code->key); if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) { *manufacture_name = furi_string_get_cstr(manufacture_code->name); - mfname = *manufacture_name; - kl_type = 1; + subghz_environment_keeloq_set_mf(kl_environment, *manufacture_name, 1); return 1; } @@ -845,8 +861,7 @@ static uint8_t subghz_protocol_keeloq_check_remote_controller_selector( decrypt = subghz_protocol_keeloq_common_decrypt(hop, man_rev); if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) { *manufacture_name = furi_string_get_cstr(manufacture_code->name); - mfname = *manufacture_name; - kl_type = 1; + subghz_environment_keeloq_set_mf(kl_environment, *manufacture_name, 1); return 1; } @@ -858,8 +873,7 @@ static uint8_t subghz_protocol_keeloq_check_remote_controller_selector( decrypt = subghz_protocol_keeloq_common_decrypt(hop, man); if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) { *manufacture_name = furi_string_get_cstr(manufacture_code->name); - mfname = *manufacture_name; - kl_type = 2; + subghz_environment_keeloq_set_mf(kl_environment, *manufacture_name, 2); return 1; } @@ -868,8 +882,7 @@ static uint8_t subghz_protocol_keeloq_check_remote_controller_selector( decrypt = subghz_protocol_keeloq_common_decrypt(hop, man); if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) { *manufacture_name = furi_string_get_cstr(manufacture_code->name); - mfname = *manufacture_name; - kl_type = 2; + subghz_environment_keeloq_set_mf(kl_environment, *manufacture_name, 2); return 1; } @@ -879,8 +892,7 @@ static uint8_t subghz_protocol_keeloq_check_remote_controller_selector( decrypt = subghz_protocol_keeloq_common_decrypt(hop, man); if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) { *manufacture_name = furi_string_get_cstr(manufacture_code->name); - mfname = *manufacture_name; - kl_type = 3; + subghz_environment_keeloq_set_mf(kl_environment, *manufacture_name, 3); return 1; } @@ -890,8 +902,7 @@ static uint8_t subghz_protocol_keeloq_check_remote_controller_selector( decrypt = subghz_protocol_keeloq_common_decrypt(hop, man); if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) { *manufacture_name = furi_string_get_cstr(manufacture_code->name); - mfname = *manufacture_name; - kl_type = 3; + subghz_environment_keeloq_set_mf(kl_environment, *manufacture_name, 3); return 1; } @@ -901,8 +912,7 @@ static uint8_t subghz_protocol_keeloq_check_remote_controller_selector( decrypt = subghz_protocol_keeloq_common_decrypt(hop, man); if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) { *manufacture_name = furi_string_get_cstr(manufacture_code->name); - mfname = *manufacture_name; - kl_type = 4; + subghz_environment_keeloq_set_mf(kl_environment, *manufacture_name, 4); return 1; } @@ -911,8 +921,7 @@ static uint8_t subghz_protocol_keeloq_check_remote_controller_selector( decrypt = subghz_protocol_keeloq_common_decrypt(hop, man); if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) { *manufacture_name = furi_string_get_cstr(manufacture_code->name); - mfname = *manufacture_name; - kl_type = 4; + subghz_environment_keeloq_set_mf(kl_environment, *manufacture_name, 4); return 1; } @@ -922,7 +931,7 @@ static uint8_t subghz_protocol_keeloq_check_remote_controller_selector( } *manufacture_name = "Unknown"; - mfname = "Unknown"; + subghz_environment_keeloq_set_mf(kl_environment, "Unknown", kl_type_en); instance->cnt = 0; return 0; @@ -935,6 +944,7 @@ static void subghz_protocol_keeloq_check_remote_controller( uint64_t key = subghz_protocol_blocks_reverse_key(instance->data, instance->data_count_bit); uint32_t key_fix = key >> 32; uint32_t key_hop = key & 0x00000000ffffffff; + uint8_t kl_type_en = subghz_environment_keeloq_get_kl_type(kl_environment); // If we are in BFT / Aprimatic programming mode we will set previous remembered counter and skip mf keys check if(klq_prog_mode == KEELOQ_PROG_MODE_OFF) { @@ -942,11 +952,11 @@ static void subghz_protocol_keeloq_check_remote_controller( if((key_hop >> 24) == ((key_hop >> 16) & 0x00ff) && (key_fix >> 28) == ((key_hop >> 12) & 0x0f) && (key_hop & 0xFFF) == 0x404) { *manufacture_name = "AN-Motors"; - mfname = *manufacture_name; + subghz_environment_keeloq_set_mf(kl_environment, *manufacture_name, kl_type_en); instance->cnt = key_hop >> 16; } else if((key_hop & 0xFFF) == (0x000) && (key_fix >> 28) == ((key_hop >> 12) & 0x0f)) { *manufacture_name = "HCS101"; - mfname = *manufacture_name; + subghz_environment_keeloq_set_mf(kl_environment, *manufacture_name, kl_type_en); instance->cnt = key_hop >> 16; } else { subghz_protocol_keeloq_check_remote_controller_selector( @@ -956,11 +966,11 @@ static void subghz_protocol_keeloq_check_remote_controller( } else if(klq_prog_mode == KEELOQ_PROG_MODE_BFT) { *manufacture_name = "BFT"; - mfname = *manufacture_name; + subghz_environment_keeloq_set_mf(kl_environment, *manufacture_name, kl_type_en); instance->cnt = temp_counter; } else if(klq_prog_mode == KEELOQ_PROG_MODE_APRIMATIC) { *manufacture_name = "Aprimatic"; - mfname = *manufacture_name; + subghz_environment_keeloq_set_mf(kl_environment, *manufacture_name, kl_type_en); instance->cnt = temp_counter; } @@ -1052,7 +1062,15 @@ SubGhzProtocolStatus if(flipper_format_read_string( flipper_format, "Manufacture", instance->manufacture_from_file)) { instance->manufacture_name = furi_string_get_cstr(instance->manufacture_from_file); - mfname = furi_string_get_cstr(instance->manufacture_from_file); + subghz_environment_keeloq_set_mf( + kl_environment, + furi_string_get_cstr(instance->manufacture_from_file), + subghz_environment_keeloq_get_kl_type(kl_environment)); + // TODO: + FURI_LOG_W( + "MF decoder", + "Alloc enviro 0x%X", + (uintptr_t)subghz_environment_keeloq_get_mf(kl_environment)); } else { FURI_LOG_D(TAG, "DECODER: Missing Manufacture"); } diff --git a/lib/subghz/protocols/keeloq.h b/lib/subghz/protocols/keeloq.h index 9862e0e92..26f569e8c 100644 --- a/lib/subghz/protocols/keeloq.h +++ b/lib/subghz/protocols/keeloq.h @@ -13,10 +13,6 @@ extern const SubGhzProtocolDecoder subghz_protocol_keeloq_decoder; extern const SubGhzProtocolEncoder subghz_protocol_keeloq_encoder; extern const SubGhzProtocol subghz_protocol_keeloq; -void keeloq_reset_mfname(); - -void keeloq_reset_kl_type(); - void keeloq_reset_original_btn(); /** diff --git a/lib/subghz/protocols/star_line.c b/lib/subghz/protocols/star_line.c index 362e34f3c..64d9bef80 100644 --- a/lib/subghz/protocols/star_line.c +++ b/lib/subghz/protocols/star_line.c @@ -82,18 +82,12 @@ const SubGhzProtocol subghz_protocol_star_line = { .decoder = &subghz_protocol_star_line_decoder, .encoder = &subghz_protocol_star_line_encoder, }; +// TODO: +// static const char* mfname; -static const char* mfname; +// static int kl_type; -static int kl_type; - -void star_line_reset_mfname() { - mfname = ""; -} - -void star_line_reset_kl_type() { - kl_type = 0; -} +static SubGhzEnvironment* kl_environment; /** * Analysis of received data @@ -113,6 +107,8 @@ void* subghz_protocol_encoder_star_line_alloc(SubGhzEnvironment* environment) { instance->generic.protocol_name = instance->base.protocol->name; instance->keystore = subghz_environment_get_keystore(environment); + kl_environment = environment; + instance->manufacture_from_file = furi_string_alloc(); instance->encoder.repeat = 10; @@ -163,6 +159,7 @@ static bool instance->generic.data, instance->generic.data_count_bit); hop = code_found_reverse & 0x00000000ffffffff; } else { + uint8_t kl_type_en = subghz_environment_keeloq_get_kl_type(kl_environment); for M_EACH( manufacture_code, @@ -184,11 +181,11 @@ static bool hop = subghz_protocol_keeloq_common_encrypt(decrypt, man); break; case KEELOQ_LEARNING_UNKNOWN: - if(kl_type == 1) { + if(kl_type_en == 1) { hop = subghz_protocol_keeloq_common_encrypt( decrypt, manufacture_code->key); } - if(kl_type == 2) { + if(kl_type_en == 2) { man = subghz_protocol_keeloq_common_normal_learning( fix, manufacture_code->key); hop = subghz_protocol_keeloq_common_encrypt(decrypt, man); @@ -300,7 +297,15 @@ SubGhzProtocolStatus if(flipper_format_read_string( flipper_format, "Manufacture", instance->manufacture_from_file)) { instance->manufacture_name = furi_string_get_cstr(instance->manufacture_from_file); - mfname = furi_string_get_cstr(instance->manufacture_from_file); + subghz_environment_keeloq_set_mf( + kl_environment, + furi_string_get_cstr(instance->manufacture_from_file), + subghz_environment_keeloq_get_kl_type(kl_environment)); + // TODO: + FURI_LOG_W( + "MF encoder", + "Alloc enviro 0x%X", + (uintptr_t)subghz_environment_keeloq_get_mf(kl_environment)); } else { FURI_LOG_D(TAG, "ENCODER: Missing Manufacture"); } @@ -366,6 +371,7 @@ void* subghz_protocol_decoder_star_line_alloc(SubGhzEnvironment* environment) { instance->manufacture_from_file = furi_string_alloc(); instance->keystore = subghz_environment_get_keystore(environment); + kl_environment = environment; return instance; } @@ -382,8 +388,7 @@ void subghz_protocol_decoder_star_line_reset(void* context) { furi_assert(context); SubGhzProtocolDecoderStarLine* instance = context; instance->decoder.parser_step = StarLineDecoderStepReset; - mfname = ""; - kl_type = 0; + subghz_environment_reset_keeloq(kl_environment); } void subghz_protocol_decoder_star_line_feed(void* context, bool level, uint32_t duration) { @@ -523,9 +528,15 @@ static uint8_t subghz_protocol_star_line_check_remote_controller_selector( uint32_t decrypt = 0; uint64_t man_normal_learning; bool mf_not_set = false; - if(mfname == 0x0) { - mfname = ""; - } + // TODO: + // if(mfname == 0x0) { + // mfname = ""; + // } + + const char* mfname = subghz_environment_keeloq_get_mf(kl_environment); + uint8_t kl_type_en = subghz_environment_keeloq_get_kl_type(kl_environment); + // TODO: + FURI_LOG_W("RMcontroll", "MF NAME: %s", mfname); if(strcmp(mfname, "Unknown") == 0) { return 1; @@ -542,7 +553,8 @@ static uint8_t subghz_protocol_star_line_check_remote_controller_selector( if(subghz_protocol_star_line_check_decrypt( instance, decrypt, btn, end_serial)) { *manufacture_name = furi_string_get_cstr(manufacture_code->name); - mfname = *manufacture_name; + subghz_environment_keeloq_set_mf( + kl_environment, *manufacture_name, kl_type_en); return 1; } break; @@ -555,7 +567,8 @@ static uint8_t subghz_protocol_star_line_check_remote_controller_selector( if(subghz_protocol_star_line_check_decrypt( instance, decrypt, btn, end_serial)) { *manufacture_name = furi_string_get_cstr(manufacture_code->name); - mfname = *manufacture_name; + subghz_environment_keeloq_set_mf( + kl_environment, *manufacture_name, kl_type_en); return 1; } break; @@ -565,8 +578,7 @@ static uint8_t subghz_protocol_star_line_check_remote_controller_selector( if(subghz_protocol_star_line_check_decrypt( instance, decrypt, btn, end_serial)) { *manufacture_name = furi_string_get_cstr(manufacture_code->name); - mfname = *manufacture_name; - kl_type = 1; + subghz_environment_keeloq_set_mf(kl_environment, *manufacture_name, 1); return 1; } // Check for mirrored man @@ -580,8 +592,7 @@ static uint8_t subghz_protocol_star_line_check_remote_controller_selector( if(subghz_protocol_star_line_check_decrypt( instance, decrypt, btn, end_serial)) { *manufacture_name = furi_string_get_cstr(manufacture_code->name); - mfname = *manufacture_name; - kl_type = 1; + subghz_environment_keeloq_set_mf(kl_environment, *manufacture_name, 1); return 1; } //########################### @@ -593,8 +604,7 @@ static uint8_t subghz_protocol_star_line_check_remote_controller_selector( if(subghz_protocol_star_line_check_decrypt( instance, decrypt, btn, end_serial)) { *manufacture_name = furi_string_get_cstr(manufacture_code->name); - mfname = *manufacture_name; - kl_type = 2; + subghz_environment_keeloq_set_mf(kl_environment, *manufacture_name, 2); return 1; } // Check for mirrored man @@ -604,8 +614,7 @@ static uint8_t subghz_protocol_star_line_check_remote_controller_selector( if(subghz_protocol_star_line_check_decrypt( instance, decrypt, btn, end_serial)) { *manufacture_name = furi_string_get_cstr(manufacture_code->name); - mfname = *manufacture_name; - kl_type = 2; + subghz_environment_keeloq_set_mf(kl_environment, *manufacture_name, 2); return 1; } break; @@ -614,7 +623,7 @@ static uint8_t subghz_protocol_star_line_check_remote_controller_selector( } *manufacture_name = "Unknown"; - mfname = "Unknown"; + subghz_environment_keeloq_set_mf(kl_environment, "Unknown", kl_type_en); instance->cnt = 0; return 0; @@ -690,7 +699,15 @@ SubGhzProtocolStatus if(flipper_format_read_string( flipper_format, "Manufacture", instance->manufacture_from_file)) { instance->manufacture_name = furi_string_get_cstr(instance->manufacture_from_file); - mfname = furi_string_get_cstr(instance->manufacture_from_file); + subghz_environment_keeloq_set_mf( + kl_environment, + furi_string_get_cstr(instance->manufacture_from_file), + subghz_environment_keeloq_get_kl_type(kl_environment)); + // TODO: + FURI_LOG_W( + "MF decoder", + "Alloc enviro 0x%X", + (uintptr_t)subghz_environment_keeloq_get_mf(kl_environment)); } else { FURI_LOG_D(TAG, "DECODER: Missing Manufacture"); } From 230965612087afc3a9c67312d32040b16fd6ba3a Mon Sep 17 00:00:00 2001 From: gid9798 <30450294+gid9798@users.noreply.github.com> Date: Sat, 20 May 2023 01:19:13 +0300 Subject: [PATCH 02/52] clean up --- lib/subghz/protocols/keeloq.c | 16 +--------------- lib/subghz/protocols/star_line.c | 16 ---------------- 2 files changed, 1 insertion(+), 31 deletions(-) diff --git a/lib/subghz/protocols/keeloq.c b/lib/subghz/protocols/keeloq.c index 0d151e68f..94126c4e7 100644 --- a/lib/subghz/protocols/keeloq.c +++ b/lib/subghz/protocols/keeloq.c @@ -89,9 +89,7 @@ const SubGhzProtocol subghz_protocol_keeloq = { .decoder = &subghz_protocol_keeloq_decoder, .encoder = &subghz_protocol_keeloq_encoder, }; -// TODO: -// static const char* mfname; -// static uint8_t kl_type; + static uint8_t klq_prog_mode; static uint16_t temp_counter; @@ -507,11 +505,6 @@ SubGhzProtocolStatus kl_environment, furi_string_get_cstr(instance->manufacture_from_file), subghz_environment_keeloq_get_kl_type(kl_environment)); - // TODO: - FURI_LOG_W( - "MF encoder", - "Alloc enviro 0x%X", - (uintptr_t)subghz_environment_keeloq_get_mf(kl_environment)); } else { FURI_LOG_D(TAG, "ENCODER: Missing Manufacture"); } @@ -751,8 +744,6 @@ static uint8_t subghz_protocol_keeloq_check_remote_controller_selector( const char* mfname = subghz_environment_keeloq_get_mf(kl_environment); uint8_t kl_type_en = subghz_environment_keeloq_get_kl_type(kl_environment); - // TODO: - FURI_LOG_W("RMcontroll", "MF NAME: %s", mfname); if(strcmp(mfname, "Unknown") == 0) { return 1; @@ -1066,11 +1057,6 @@ SubGhzProtocolStatus kl_environment, furi_string_get_cstr(instance->manufacture_from_file), subghz_environment_keeloq_get_kl_type(kl_environment)); - // TODO: - FURI_LOG_W( - "MF decoder", - "Alloc enviro 0x%X", - (uintptr_t)subghz_environment_keeloq_get_mf(kl_environment)); } else { FURI_LOG_D(TAG, "DECODER: Missing Manufacture"); } diff --git a/lib/subghz/protocols/star_line.c b/lib/subghz/protocols/star_line.c index 64d9bef80..4b5412c39 100644 --- a/lib/subghz/protocols/star_line.c +++ b/lib/subghz/protocols/star_line.c @@ -82,10 +82,6 @@ const SubGhzProtocol subghz_protocol_star_line = { .decoder = &subghz_protocol_star_line_decoder, .encoder = &subghz_protocol_star_line_encoder, }; -// TODO: -// static const char* mfname; - -// static int kl_type; static SubGhzEnvironment* kl_environment; @@ -301,11 +297,6 @@ SubGhzProtocolStatus kl_environment, furi_string_get_cstr(instance->manufacture_from_file), subghz_environment_keeloq_get_kl_type(kl_environment)); - // TODO: - FURI_LOG_W( - "MF encoder", - "Alloc enviro 0x%X", - (uintptr_t)subghz_environment_keeloq_get_mf(kl_environment)); } else { FURI_LOG_D(TAG, "ENCODER: Missing Manufacture"); } @@ -535,8 +526,6 @@ static uint8_t subghz_protocol_star_line_check_remote_controller_selector( const char* mfname = subghz_environment_keeloq_get_mf(kl_environment); uint8_t kl_type_en = subghz_environment_keeloq_get_kl_type(kl_environment); - // TODO: - FURI_LOG_W("RMcontroll", "MF NAME: %s", mfname); if(strcmp(mfname, "Unknown") == 0) { return 1; @@ -703,11 +692,6 @@ SubGhzProtocolStatus kl_environment, furi_string_get_cstr(instance->manufacture_from_file), subghz_environment_keeloq_get_kl_type(kl_environment)); - // TODO: - FURI_LOG_W( - "MF decoder", - "Alloc enviro 0x%X", - (uintptr_t)subghz_environment_keeloq_get_mf(kl_environment)); } else { FURI_LOG_D(TAG, "DECODER: Missing Manufacture"); } From 2af8f00d0df40915e3b574166c674709334c8a19 Mon Sep 17 00:00:00 2001 From: gid9798 <30450294+gid9798@users.noreply.github.com> Date: Sat, 20 May 2023 01:25:05 +0300 Subject: [PATCH 03/52] fix --- firmware/targets/f7/api_symbols.csv | 4 ---- lib/subghz/protocols/star_line.h | 4 ---- 2 files changed, 8 deletions(-) diff --git a/firmware/targets/f7/api_symbols.csv b/firmware/targets/f7/api_symbols.csv index ddda9dcba..441352021 100644 --- a/firmware/targets/f7/api_symbols.csv +++ b/firmware/targets/f7/api_symbols.csv @@ -1825,8 +1825,6 @@ Function,-,j1f,float,float Function,-,jn,double,"int, double" Function,-,jnf,float,"int, float" Function,-,jrand48,long,unsigned short[3] -Function,-,keeloq_reset_kl_type,void, -Function,-,keeloq_reset_mfname,void, Function,-,keeloq_reset_original_btn,void, Function,-,l64a,char*,long Function,-,labs,long,long @@ -2568,8 +2566,6 @@ Function,+,srand,void,unsigned Function,-,srand48,void,long Function,-,srandom,void,unsigned Function,+,sscanf,int,"const char*, const char*, ..." -Function,-,star_line_reset_kl_type,void, -Function,-,star_line_reset_mfname,void, Function,+,storage_common_copy,FS_Error,"Storage*, const char*, const char*" Function,+,storage_common_exists,_Bool,"Storage*, const char*" Function,+,storage_common_fs_info,FS_Error,"Storage*, const char*, uint64_t*, uint64_t*" diff --git a/lib/subghz/protocols/star_line.h b/lib/subghz/protocols/star_line.h index 901b82f7c..851819ec7 100644 --- a/lib/subghz/protocols/star_line.h +++ b/lib/subghz/protocols/star_line.h @@ -11,10 +11,6 @@ extern const SubGhzProtocolDecoder subghz_protocol_star_line_decoder; extern const SubGhzProtocolEncoder subghz_protocol_star_line_encoder; extern const SubGhzProtocol subghz_protocol_star_line; -void star_line_reset_mfname(); - -void star_line_reset_kl_type(); - /** * Allocate SubGhzProtocolEncoderStarLine. * @param environment Pointer to a SubGhzEnvironment instance From 2414346ec3f217610c0043a3093061fab51a4a30 Mon Sep 17 00:00:00 2001 From: gid9798 <30450294+gid9798@users.noreply.github.com> Date: Sat, 20 May 2023 16:15:01 +0300 Subject: [PATCH 04/52] keeloq to kestore --- .../main/subghz/helpers/subghz_txrx.c | 2 + firmware/targets/f7/api_symbols.csv | 6 +- lib/subghz/environment.c | 22 +---- lib/subghz/environment.h | 6 -- lib/subghz/protocols/keeloq.c | 81 +++++++++---------- lib/subghz/protocols/star_line.c | 46 +++++------ lib/subghz/subghz_keystore.c | 14 +++- lib/subghz/subghz_keystore.h | 2 + lib/subghz/subghz_keystore_i.h | 9 +++ 9 files changed, 83 insertions(+), 105 deletions(-) create mode 100644 lib/subghz/subghz_keystore_i.h diff --git a/applications/main/subghz/helpers/subghz_txrx.c b/applications/main/subghz/helpers/subghz_txrx.c index c2d7e1bf5..9d957cd29 100644 --- a/applications/main/subghz/helpers/subghz_txrx.c +++ b/applications/main/subghz/helpers/subghz_txrx.c @@ -560,6 +560,8 @@ bool subghz_txrx_get_debug_pin_state(SubGhzTxRx* instance) { void subghz_txrx_reset_dynamic(SubGhzTxRx* instance) { furi_assert(instance); subghz_environment_reset_keeloq(instance->environment); + + keeloq_reset_original_btn(); subghz_custom_btns_reset(); } diff --git a/firmware/targets/f7/api_symbols.csv b/firmware/targets/f7/api_symbols.csv index 441352021..1e00e181c 100644 --- a/firmware/targets/f7/api_symbols.csv +++ b/firmware/targets/f7/api_symbols.csv @@ -1,5 +1,5 @@ entry,status,name,type,params -Version,+,26.5,, +Version,+,26.6,, Header,+,applications/services/bt/bt_service/bt.h,, Header,+,applications/services/cli/cli.h,, Header,+,applications/services/cli/cli_vcp.h,, @@ -2727,9 +2727,6 @@ Function,+,subghz_environment_get_keystore,SubGhzKeystore*,SubGhzEnvironment* Function,+,subghz_environment_get_nice_flor_s_rainbow_table_file_name,const char*,SubGhzEnvironment* Function,+,subghz_environment_get_protocol_name_registry,const char*,"SubGhzEnvironment*, size_t" Function,+,subghz_environment_get_protocol_registry,void*,SubGhzEnvironment* -Function,-,subghz_environment_keeloq_get_kl_type,uint8_t,SubGhzEnvironment* -Function,-,subghz_environment_keeloq_get_mf,const char*,SubGhzEnvironment* -Function,-,subghz_environment_keeloq_set_mf,void,"SubGhzEnvironment*, const char*, uint8_t" Function,+,subghz_environment_load_keystore,_Bool,"SubGhzEnvironment*, const char*" Function,+,subghz_environment_reset_keeloq,void,SubGhzEnvironment* Function,+,subghz_environment_set_alutech_at_4n_rainbow_table_file_name,void,"SubGhzEnvironment*, const char*" @@ -2742,6 +2739,7 @@ Function,-,subghz_keystore_get_data,SubGhzKeyArray_t*,SubGhzKeystore* Function,-,subghz_keystore_load,_Bool,"SubGhzKeystore*, const char*" Function,-,subghz_keystore_raw_encrypted_save,_Bool,"const char*, const char*, uint8_t*" Function,-,subghz_keystore_raw_get_data,_Bool,"const char*, size_t, uint8_t*, size_t" +Function,-,subghz_keystore_reset_kl,void,SubGhzKeystore* Function,-,subghz_keystore_save,_Bool,"SubGhzKeystore*, const char*, uint8_t*" Function,-,subghz_protocol_alutech_at_4n_create_data,_Bool,"void*, FlipperFormat*, uint32_t, uint8_t, uint16_t, SubGhzRadioPreset*" Function,+,subghz_protocol_blocks_add_bit,void,"SubGhzBlockDecoder*, uint8_t" diff --git a/lib/subghz/environment.c b/lib/subghz/environment.c index 55caedb6d..bcada8752 100644 --- a/lib/subghz/environment.c +++ b/lib/subghz/environment.c @@ -124,25 +124,5 @@ const char* void subghz_environment_reset_keeloq(SubGhzEnvironment* instance) { furi_assert(instance); - instance->mfname = ""; - instance->kl_type = 0; + subghz_keystore_reset_kl(instance->keystore); } - -const char* subghz_environment_keeloq_get_mf(SubGhzEnvironment* instance) { - furi_assert(instance); - - return instance->mfname; -} - -uint8_t subghz_environment_keeloq_get_kl_type(SubGhzEnvironment* instance) { - furi_assert(instance); - - return instance->kl_type; -} - -void subghz_environment_keeloq_set_mf(SubGhzEnvironment* instance, const char* mf, uint8_t kl_type) { - furi_assert(instance); - - instance->mfname = mf; - instance->kl_type = kl_type; -} \ No newline at end of file diff --git a/lib/subghz/environment.h b/lib/subghz/environment.h index a23341e2f..67de48df9 100644 --- a/lib/subghz/environment.h +++ b/lib/subghz/environment.h @@ -116,12 +116,6 @@ const char* subghz_environment_get_protocol_name_registry(SubGhzEnvironment* ins */ void subghz_environment_reset_keeloq(SubGhzEnvironment* instance); -// Private - -const char* subghz_environment_keeloq_get_mf(SubGhzEnvironment* instance); -uint8_t subghz_environment_keeloq_get_kl_type(SubGhzEnvironment* instance); -void subghz_environment_keeloq_set_mf(SubGhzEnvironment* instance, const char* mf, uint8_t kl_type); - #ifdef __cplusplus } #endif diff --git a/lib/subghz/protocols/keeloq.c b/lib/subghz/protocols/keeloq.c index 94126c4e7..df7ae748d 100644 --- a/lib/subghz/protocols/keeloq.c +++ b/lib/subghz/protocols/keeloq.c @@ -11,6 +11,7 @@ #include "../blocks/math.h" #include "../blocks/custom_btn.h" +#include "../subghz_keystore_i.h" #define TAG "SubGhzProtocolKeeloq" @@ -93,8 +94,6 @@ const SubGhzProtocol subghz_protocol_keeloq = { static uint8_t klq_prog_mode; static uint16_t temp_counter; -static SubGhzEnvironment* kl_environment; - void keeloq_reset_original_btn() { subghz_custom_btns_reset(); temp_counter = 0; @@ -119,8 +118,6 @@ void* subghz_protocol_encoder_keeloq_alloc(SubGhzEnvironment* environment) { instance->generic.protocol_name = instance->base.protocol->name; instance->keystore = subghz_environment_get_keystore(environment); - kl_environment = environment; - instance->encoder.repeat = 100; instance->encoder.size_upload = 256; instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration)); @@ -246,7 +243,7 @@ static bool subghz_protocol_keeloq_gen_data( decrypt = btn << 28 | (0x000) << 16 | instance->generic.cnt; // Beninca / Allmatic -> no serial - simple XOR } - uint8_t kl_type_en = subghz_environment_keeloq_get_kl_type(kl_environment); + uint8_t kl_type_en = instance->keystore->kl_type; for M_EACH( manufacture_code, @@ -501,10 +498,7 @@ SubGhzProtocolStatus if(flipper_format_read_string( flipper_format, "Manufacture", instance->manufacture_from_file)) { instance->manufacture_name = furi_string_get_cstr(instance->manufacture_from_file); - subghz_environment_keeloq_set_mf( - kl_environment, - furi_string_get_cstr(instance->manufacture_from_file), - subghz_environment_keeloq_get_kl_type(kl_environment)); + instance->keystore->mfname = instance->manufacture_name; } else { FURI_LOG_D(TAG, "ENCODER: Missing Manufacture"); } @@ -576,7 +570,6 @@ void* subghz_protocol_decoder_keeloq_alloc(SubGhzEnvironment* environment) { instance->keystore = subghz_environment_get_keystore(environment); instance->manufacture_from_file = furi_string_alloc(); - kl_environment = environment; klq_prog_mode = KEELOQ_PROG_MODE_OFF; return instance; @@ -594,7 +587,9 @@ void subghz_protocol_decoder_keeloq_reset(void* context) { furi_assert(context); SubGhzProtocolDecoderKeeloq* instance = context; instance->decoder.parser_step = KeeloqDecoderStepReset; - subghz_environment_reset_keeloq(kl_environment); + // TODO + instance->keystore->mfname = ""; + instance->keystore->kl_type = 0; } void subghz_protocol_decoder_keeloq_feed(void* context, bool level, uint32_t duration) { @@ -742,8 +737,7 @@ static uint8_t subghz_protocol_keeloq_check_remote_controller_selector( // mfname = ""; // } - const char* mfname = subghz_environment_keeloq_get_mf(kl_environment); - uint8_t kl_type_en = subghz_environment_keeloq_get_kl_type(kl_environment); + const char* mfname = keystore->mfname; if(strcmp(mfname, "Unknown") == 0) { return 1; @@ -759,8 +753,7 @@ static uint8_t subghz_protocol_keeloq_check_remote_controller_selector( decrypt = subghz_protocol_keeloq_common_decrypt(hop, manufacture_code->key); if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) { *manufacture_name = furi_string_get_cstr(manufacture_code->name); - subghz_environment_keeloq_set_mf( - kl_environment, *manufacture_name, kl_type_en); + keystore->mfname = *manufacture_name; return 1; } break; @@ -772,8 +765,7 @@ static uint8_t subghz_protocol_keeloq_check_remote_controller_selector( decrypt = subghz_protocol_keeloq_common_decrypt(hop, man); if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) { *manufacture_name = furi_string_get_cstr(manufacture_code->name); - subghz_environment_keeloq_set_mf( - kl_environment, *manufacture_name, kl_type_en); + keystore->mfname = *manufacture_name; return 1; } break; @@ -783,8 +775,7 @@ static uint8_t subghz_protocol_keeloq_check_remote_controller_selector( decrypt = subghz_protocol_keeloq_common_decrypt(hop, man); if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) { *manufacture_name = furi_string_get_cstr(manufacture_code->name); - subghz_environment_keeloq_set_mf( - kl_environment, *manufacture_name, kl_type_en); + keystore->mfname = *manufacture_name; return 1; } break; @@ -794,8 +785,7 @@ static uint8_t subghz_protocol_keeloq_check_remote_controller_selector( decrypt = subghz_protocol_keeloq_common_decrypt(hop, man); if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) { *manufacture_name = furi_string_get_cstr(manufacture_code->name); - subghz_environment_keeloq_set_mf( - kl_environment, *manufacture_name, kl_type_en); + keystore->mfname = *manufacture_name; return 1; } break; @@ -805,8 +795,7 @@ static uint8_t subghz_protocol_keeloq_check_remote_controller_selector( decrypt = subghz_protocol_keeloq_common_decrypt(hop, man); if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) { *manufacture_name = furi_string_get_cstr(manufacture_code->name); - subghz_environment_keeloq_set_mf( - kl_environment, *manufacture_name, kl_type_en); + keystore->mfname = *manufacture_name; return 1; } break; @@ -816,8 +805,7 @@ static uint8_t subghz_protocol_keeloq_check_remote_controller_selector( decrypt = subghz_protocol_keeloq_common_decrypt(hop, man); if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) { *manufacture_name = furi_string_get_cstr(manufacture_code->name); - subghz_environment_keeloq_set_mf( - kl_environment, *manufacture_name, kl_type_en); + keystore->mfname = *manufacture_name; return 1; } break; @@ -827,8 +815,7 @@ static uint8_t subghz_protocol_keeloq_check_remote_controller_selector( decrypt = subghz_protocol_keeloq_common_decrypt(hop, man); if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) { *manufacture_name = furi_string_get_cstr(manufacture_code->name); - subghz_environment_keeloq_set_mf( - kl_environment, *manufacture_name, kl_type_en); + keystore->mfname = *manufacture_name; return 1; } break; @@ -837,7 +824,8 @@ static uint8_t subghz_protocol_keeloq_check_remote_controller_selector( decrypt = subghz_protocol_keeloq_common_decrypt(hop, manufacture_code->key); if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) { *manufacture_name = furi_string_get_cstr(manufacture_code->name); - subghz_environment_keeloq_set_mf(kl_environment, *manufacture_name, 1); + keystore->mfname = *manufacture_name; + keystore->kl_type = 1; return 1; } @@ -852,7 +840,8 @@ static uint8_t subghz_protocol_keeloq_check_remote_controller_selector( decrypt = subghz_protocol_keeloq_common_decrypt(hop, man_rev); if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) { *manufacture_name = furi_string_get_cstr(manufacture_code->name); - subghz_environment_keeloq_set_mf(kl_environment, *manufacture_name, 1); + keystore->mfname = *manufacture_name; + keystore->kl_type = 1; return 1; } @@ -864,7 +853,8 @@ static uint8_t subghz_protocol_keeloq_check_remote_controller_selector( decrypt = subghz_protocol_keeloq_common_decrypt(hop, man); if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) { *manufacture_name = furi_string_get_cstr(manufacture_code->name); - subghz_environment_keeloq_set_mf(kl_environment, *manufacture_name, 2); + keystore->mfname = *manufacture_name; + keystore->kl_type = 2; return 1; } @@ -873,7 +863,8 @@ static uint8_t subghz_protocol_keeloq_check_remote_controller_selector( decrypt = subghz_protocol_keeloq_common_decrypt(hop, man); if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) { *manufacture_name = furi_string_get_cstr(manufacture_code->name); - subghz_environment_keeloq_set_mf(kl_environment, *manufacture_name, 2); + keystore->mfname = *manufacture_name; + keystore->kl_type = 2; return 1; } @@ -883,7 +874,8 @@ static uint8_t subghz_protocol_keeloq_check_remote_controller_selector( decrypt = subghz_protocol_keeloq_common_decrypt(hop, man); if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) { *manufacture_name = furi_string_get_cstr(manufacture_code->name); - subghz_environment_keeloq_set_mf(kl_environment, *manufacture_name, 3); + keystore->mfname = *manufacture_name; + keystore->kl_type = 3; return 1; } @@ -893,7 +885,8 @@ static uint8_t subghz_protocol_keeloq_check_remote_controller_selector( decrypt = subghz_protocol_keeloq_common_decrypt(hop, man); if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) { *manufacture_name = furi_string_get_cstr(manufacture_code->name); - subghz_environment_keeloq_set_mf(kl_environment, *manufacture_name, 3); + keystore->mfname = *manufacture_name; + keystore->kl_type = 3; return 1; } @@ -903,7 +896,8 @@ static uint8_t subghz_protocol_keeloq_check_remote_controller_selector( decrypt = subghz_protocol_keeloq_common_decrypt(hop, man); if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) { *manufacture_name = furi_string_get_cstr(manufacture_code->name); - subghz_environment_keeloq_set_mf(kl_environment, *manufacture_name, 4); + keystore->mfname = *manufacture_name; + keystore->kl_type = 4; return 1; } @@ -912,7 +906,8 @@ static uint8_t subghz_protocol_keeloq_check_remote_controller_selector( decrypt = subghz_protocol_keeloq_common_decrypt(hop, man); if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) { *manufacture_name = furi_string_get_cstr(manufacture_code->name); - subghz_environment_keeloq_set_mf(kl_environment, *manufacture_name, 4); + keystore->mfname = *manufacture_name; + keystore->kl_type = 4; return 1; } @@ -922,7 +917,7 @@ static uint8_t subghz_protocol_keeloq_check_remote_controller_selector( } *manufacture_name = "Unknown"; - subghz_environment_keeloq_set_mf(kl_environment, "Unknown", kl_type_en); + keystore->mfname = "Unknown"; instance->cnt = 0; return 0; @@ -935,7 +930,6 @@ static void subghz_protocol_keeloq_check_remote_controller( uint64_t key = subghz_protocol_blocks_reverse_key(instance->data, instance->data_count_bit); uint32_t key_fix = key >> 32; uint32_t key_hop = key & 0x00000000ffffffff; - uint8_t kl_type_en = subghz_environment_keeloq_get_kl_type(kl_environment); // If we are in BFT / Aprimatic programming mode we will set previous remembered counter and skip mf keys check if(klq_prog_mode == KEELOQ_PROG_MODE_OFF) { @@ -943,11 +937,11 @@ static void subghz_protocol_keeloq_check_remote_controller( if((key_hop >> 24) == ((key_hop >> 16) & 0x00ff) && (key_fix >> 28) == ((key_hop >> 12) & 0x0f) && (key_hop & 0xFFF) == 0x404) { *manufacture_name = "AN-Motors"; - subghz_environment_keeloq_set_mf(kl_environment, *manufacture_name, kl_type_en); + keystore->mfname = *manufacture_name; instance->cnt = key_hop >> 16; } else if((key_hop & 0xFFF) == (0x000) && (key_fix >> 28) == ((key_hop >> 12) & 0x0f)) { *manufacture_name = "HCS101"; - subghz_environment_keeloq_set_mf(kl_environment, *manufacture_name, kl_type_en); + keystore->mfname = *manufacture_name; instance->cnt = key_hop >> 16; } else { subghz_protocol_keeloq_check_remote_controller_selector( @@ -957,11 +951,11 @@ static void subghz_protocol_keeloq_check_remote_controller( } else if(klq_prog_mode == KEELOQ_PROG_MODE_BFT) { *manufacture_name = "BFT"; - subghz_environment_keeloq_set_mf(kl_environment, *manufacture_name, kl_type_en); + keystore->mfname = *manufacture_name; instance->cnt = temp_counter; } else if(klq_prog_mode == KEELOQ_PROG_MODE_APRIMATIC) { *manufacture_name = "Aprimatic"; - subghz_environment_keeloq_set_mf(kl_environment, *manufacture_name, kl_type_en); + keystore->mfname = *manufacture_name; instance->cnt = temp_counter; } @@ -1053,10 +1047,7 @@ SubGhzProtocolStatus if(flipper_format_read_string( flipper_format, "Manufacture", instance->manufacture_from_file)) { instance->manufacture_name = furi_string_get_cstr(instance->manufacture_from_file); - subghz_environment_keeloq_set_mf( - kl_environment, - furi_string_get_cstr(instance->manufacture_from_file), - subghz_environment_keeloq_get_kl_type(kl_environment)); + instance->keystore->mfname = instance->manufacture_name; } else { FURI_LOG_D(TAG, "DECODER: Missing Manufacture"); } diff --git a/lib/subghz/protocols/star_line.c b/lib/subghz/protocols/star_line.c index 4b5412c39..05afd80a6 100644 --- a/lib/subghz/protocols/star_line.c +++ b/lib/subghz/protocols/star_line.c @@ -10,6 +10,8 @@ #include "../blocks/generic.h" #include "../blocks/math.h" +#include "../subghz_keystore_i.h" + #define TAG "SubGhzProtocolStarLine" static const SubGhzBlockConst subghz_protocol_star_line_const = { @@ -83,8 +85,6 @@ const SubGhzProtocol subghz_protocol_star_line = { .encoder = &subghz_protocol_star_line_encoder, }; -static SubGhzEnvironment* kl_environment; - /** * Analysis of received data * @param instance Pointer to a SubGhzBlockGeneric* instance @@ -103,8 +103,6 @@ void* subghz_protocol_encoder_star_line_alloc(SubGhzEnvironment* environment) { instance->generic.protocol_name = instance->base.protocol->name; instance->keystore = subghz_environment_get_keystore(environment); - kl_environment = environment; - instance->manufacture_from_file = furi_string_alloc(); instance->encoder.repeat = 10; @@ -155,7 +153,7 @@ static bool instance->generic.data, instance->generic.data_count_bit); hop = code_found_reverse & 0x00000000ffffffff; } else { - uint8_t kl_type_en = subghz_environment_keeloq_get_kl_type(kl_environment); + uint8_t kl_type_en = instance->keystore->kl_type; for M_EACH( manufacture_code, @@ -293,10 +291,7 @@ SubGhzProtocolStatus if(flipper_format_read_string( flipper_format, "Manufacture", instance->manufacture_from_file)) { instance->manufacture_name = furi_string_get_cstr(instance->manufacture_from_file); - subghz_environment_keeloq_set_mf( - kl_environment, - furi_string_get_cstr(instance->manufacture_from_file), - subghz_environment_keeloq_get_kl_type(kl_environment)); + instance->keystore->mfname = instance->manufacture_name; } else { FURI_LOG_D(TAG, "ENCODER: Missing Manufacture"); } @@ -362,7 +357,6 @@ void* subghz_protocol_decoder_star_line_alloc(SubGhzEnvironment* environment) { instance->manufacture_from_file = furi_string_alloc(); instance->keystore = subghz_environment_get_keystore(environment); - kl_environment = environment; return instance; } @@ -379,7 +373,9 @@ void subghz_protocol_decoder_star_line_reset(void* context) { furi_assert(context); SubGhzProtocolDecoderStarLine* instance = context; instance->decoder.parser_step = StarLineDecoderStepReset; - subghz_environment_reset_keeloq(kl_environment); + // TODO + instance->keystore->mfname = ""; + instance->keystore->kl_type = 0; } void subghz_protocol_decoder_star_line_feed(void* context, bool level, uint32_t duration) { @@ -524,8 +520,7 @@ static uint8_t subghz_protocol_star_line_check_remote_controller_selector( // mfname = ""; // } - const char* mfname = subghz_environment_keeloq_get_mf(kl_environment); - uint8_t kl_type_en = subghz_environment_keeloq_get_kl_type(kl_environment); + const char* mfname = keystore->mfname; if(strcmp(mfname, "Unknown") == 0) { return 1; @@ -542,8 +537,7 @@ static uint8_t subghz_protocol_star_line_check_remote_controller_selector( if(subghz_protocol_star_line_check_decrypt( instance, decrypt, btn, end_serial)) { *manufacture_name = furi_string_get_cstr(manufacture_code->name); - subghz_environment_keeloq_set_mf( - kl_environment, *manufacture_name, kl_type_en); + keystore->mfname = *manufacture_name; return 1; } break; @@ -556,8 +550,7 @@ static uint8_t subghz_protocol_star_line_check_remote_controller_selector( if(subghz_protocol_star_line_check_decrypt( instance, decrypt, btn, end_serial)) { *manufacture_name = furi_string_get_cstr(manufacture_code->name); - subghz_environment_keeloq_set_mf( - kl_environment, *manufacture_name, kl_type_en); + keystore->mfname = *manufacture_name; return 1; } break; @@ -567,7 +560,8 @@ static uint8_t subghz_protocol_star_line_check_remote_controller_selector( if(subghz_protocol_star_line_check_decrypt( instance, decrypt, btn, end_serial)) { *manufacture_name = furi_string_get_cstr(manufacture_code->name); - subghz_environment_keeloq_set_mf(kl_environment, *manufacture_name, 1); + keystore->mfname = *manufacture_name; + keystore->kl_type = 1; return 1; } // Check for mirrored man @@ -581,7 +575,8 @@ static uint8_t subghz_protocol_star_line_check_remote_controller_selector( if(subghz_protocol_star_line_check_decrypt( instance, decrypt, btn, end_serial)) { *manufacture_name = furi_string_get_cstr(manufacture_code->name); - subghz_environment_keeloq_set_mf(kl_environment, *manufacture_name, 1); + keystore->mfname = *manufacture_name; + keystore->kl_type = 1; return 1; } //########################### @@ -593,7 +588,8 @@ static uint8_t subghz_protocol_star_line_check_remote_controller_selector( if(subghz_protocol_star_line_check_decrypt( instance, decrypt, btn, end_serial)) { *manufacture_name = furi_string_get_cstr(manufacture_code->name); - subghz_environment_keeloq_set_mf(kl_environment, *manufacture_name, 2); + keystore->mfname = *manufacture_name; + keystore->kl_type = 2; return 1; } // Check for mirrored man @@ -603,7 +599,8 @@ static uint8_t subghz_protocol_star_line_check_remote_controller_selector( if(subghz_protocol_star_line_check_decrypt( instance, decrypt, btn, end_serial)) { *manufacture_name = furi_string_get_cstr(manufacture_code->name); - subghz_environment_keeloq_set_mf(kl_environment, *manufacture_name, 2); + keystore->mfname = *manufacture_name; + keystore->kl_type = 2; return 1; } break; @@ -612,7 +609,7 @@ static uint8_t subghz_protocol_star_line_check_remote_controller_selector( } *manufacture_name = "Unknown"; - subghz_environment_keeloq_set_mf(kl_environment, "Unknown", kl_type_en); + keystore->mfname = "Unknown"; instance->cnt = 0; return 0; @@ -688,10 +685,7 @@ SubGhzProtocolStatus if(flipper_format_read_string( flipper_format, "Manufacture", instance->manufacture_from_file)) { instance->manufacture_name = furi_string_get_cstr(instance->manufacture_from_file); - subghz_environment_keeloq_set_mf( - kl_environment, - furi_string_get_cstr(instance->manufacture_from_file), - subghz_environment_keeloq_get_kl_type(kl_environment)); + instance->keystore->mfname = instance->manufacture_name; } else { FURI_LOG_D(TAG, "DECODER: Missing Manufacture"); } diff --git a/lib/subghz/subghz_keystore.c b/lib/subghz/subghz_keystore.c index e0b1cf6ca..d8f83fc89 100644 --- a/lib/subghz/subghz_keystore.c +++ b/lib/subghz/subghz_keystore.c @@ -1,4 +1,5 @@ #include "subghz_keystore.h" +#include "subghz_keystore_i.h" #include #include @@ -26,18 +27,25 @@ typedef enum { SubGhzKeystoreEncryptionAES256, } SubGhzKeystoreEncryption; -struct SubGhzKeystore { - SubGhzKeyArray_t data; -}; + SubGhzKeystore* subghz_keystore_alloc() { SubGhzKeystore* instance = malloc(sizeof(SubGhzKeystore)); SubGhzKeyArray_init(instance->data); + subghz_keystore_reset_kl(instance); + return instance; } +void subghz_keystore_reset_kl(SubGhzKeystore* instance) { + furi_assert(instance); + + instance->mfname = ""; + instance->kl_type = 0; +} + void subghz_keystore_free(SubGhzKeystore* instance) { furi_assert(instance); diff --git a/lib/subghz/subghz_keystore.h b/lib/subghz/subghz_keystore.h index 06ae8adae..dfb5c7373 100644 --- a/lib/subghz/subghz_keystore.h +++ b/lib/subghz/subghz_keystore.h @@ -75,6 +75,8 @@ bool subghz_keystore_raw_encrypted_save( */ bool subghz_keystore_raw_get_data(const char* file_name, size_t offset, uint8_t* data, size_t len); +void subghz_keystore_reset_kl(SubGhzKeystore* instance); + #ifdef __cplusplus } #endif diff --git a/lib/subghz/subghz_keystore_i.h b/lib/subghz/subghz_keystore_i.h new file mode 100644 index 000000000..8bf2f1e51 --- /dev/null +++ b/lib/subghz/subghz_keystore_i.h @@ -0,0 +1,9 @@ +#pragma once + +#include + +struct SubGhzKeystore { + SubGhzKeyArray_t data; + const char* mfname; + uint8_t kl_type; +}; From 7b426b936eb0a40e6b13f5c355124cf9a9342450 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Sun, 28 May 2023 19:24:21 +0300 Subject: [PATCH 05/52] Comment debug logs in digital signal and comment some debug logs in nfc v --- lib/digital_signal/digital_signal.c | 12 ++++++------ lib/nfc/protocols/nfcv.c | 24 ++++++++++++------------ 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/lib/digital_signal/digital_signal.c b/lib/digital_signal/digital_signal.c index 51a87d22a..ae110ed97 100644 --- a/lib/digital_signal/digital_signal.c +++ b/lib/digital_signal/digital_signal.c @@ -215,12 +215,12 @@ void digital_signal_prepare_arr(DigitalSignal* signal) { uint32_t edge_scaled = (internals->factor * signal->edge_timings[pos]) / (1024 * 1024); uint32_t pulse_duration = edge_scaled + internals->reload_reg_remainder; if(pulse_duration < 10 || pulse_duration > 10000000) { - FURI_LOG_D( + /*FURI_LOG_D( TAG, "[prepare] pulse_duration out of range: %lu = %lu * %llu", pulse_duration, signal->edge_timings[pos], - internals->factor); + internals->factor);*/ pulse_duration = 100; } uint32_t pulse_ticks = (pulse_duration + T_TIM_DIV2) / T_TIM; @@ -482,13 +482,13 @@ static void digital_sequence_finish(DigitalSequence* sequence) { prev_timer = DWT->CYCCNT; } if(DWT->CYCCNT - prev_timer > wait_ticks) { - FURI_LOG_D( + /*FURI_LOG_D( TAG, "[SEQ] hung %lu ms in finish (ARR 0x%08lx, read %lu, write %lu)", wait_ms, TIM2->ARR, dma_buffer->read_pos, - dma_buffer->write_pos); + dma_buffer->write_pos);*/ break; } } while(1); @@ -516,13 +516,13 @@ static void digital_sequence_queue_pulse(DigitalSequence* sequence, uint32_t len prev_timer = DWT->CYCCNT; } if(DWT->CYCCNT - prev_timer > wait_ticks) { - FURI_LOG_D( + /*FURI_LOG_D( TAG, "[SEQ] hung %lu ms in queue (ARR 0x%08lx, read %lu, write %lu)", wait_ms, TIM2->ARR, dma_buffer->read_pos, - dma_buffer->write_pos); + dma_buffer->write_pos);*/ break; } } while(1); diff --git a/lib/nfc/protocols/nfcv.c b/lib/nfc/protocols/nfcv.c index 471993b63..6b0928ea7 100644 --- a/lib/nfc/protocols/nfcv.c +++ b/lib/nfc/protocols/nfcv.c @@ -52,7 +52,7 @@ ReturnCode nfcv_read_blocks(NfcVReader* reader, NfcVData* nfcv_data) { uint16_t received = 0; for(size_t block = 0; block < nfcv_data->block_num; block++) { uint8_t rxBuf[32]; - FURI_LOG_D(TAG, "Reading block %d/%d", block, (nfcv_data->block_num - 1)); + //FURI_LOG_D(TAG, "Reading block %d/%d", block, (nfcv_data->block_num - 1)); ReturnCode ret = ERR_NONE; for(int tries = 0; tries < NFCV_COMMAND_RETRIES; tries++) { @@ -64,18 +64,18 @@ ReturnCode nfcv_read_blocks(NfcVReader* reader, NfcVData* nfcv_data) { } } if(ret != ERR_NONE) { - FURI_LOG_D(TAG, "failed to read: %d", ret); + //FURI_LOG_D(TAG, "failed to read: %d", ret); return ret; } memcpy( &(nfcv_data->data[block * nfcv_data->block_size]), &rxBuf[1], nfcv_data->block_size); - FURI_LOG_D( + /*FURI_LOG_D( TAG, " %02X %02X %02X %02X", nfcv_data->data[block * nfcv_data->block_size + 0], nfcv_data->data[block * nfcv_data->block_size + 1], nfcv_data->data[block * nfcv_data->block_size + 2], - nfcv_data->data[block * nfcv_data->block_size + 3]); + nfcv_data->data[block * nfcv_data->block_size + 3]);*/ } return ERR_NONE; @@ -86,7 +86,7 @@ ReturnCode nfcv_read_sysinfo(FuriHalNfcDevData* nfc_data, NfcVData* nfcv_data) { uint16_t received = 0; ReturnCode ret = ERR_NONE; - FURI_LOG_D(TAG, "Read SYSTEM INFORMATION..."); + //FURI_LOG_D(TAG, "Read SYSTEM INFORMATION..."); for(int tries = 0; tries < NFCV_COMMAND_RETRIES; tries++) { /* TODO: needs proper abstraction via fury_hal(_ll)_* */ @@ -110,7 +110,7 @@ ReturnCode nfcv_read_sysinfo(FuriHalNfcDevData* nfc_data, NfcVData* nfcv_data) { nfcv_data->block_num = rxBuf[NFCV_UID_LENGTH + 4] + 1; nfcv_data->block_size = rxBuf[NFCV_UID_LENGTH + 5] + 1; nfcv_data->ic_ref = rxBuf[NFCV_UID_LENGTH + 6]; - FURI_LOG_D( + /*FURI_LOG_D( TAG, " UID: %02X %02X %02X %02X %02X %02X %02X %02X", nfc_data->uid[0], @@ -128,10 +128,10 @@ ReturnCode nfcv_read_sysinfo(FuriHalNfcDevData* nfc_data, NfcVData* nfcv_data) { nfcv_data->afi, nfcv_data->block_num, nfcv_data->block_size, - nfcv_data->ic_ref); + nfcv_data->ic_ref);*/ return ret; } - FURI_LOG_D(TAG, "Failed: %d", ret); + //FURI_LOG_D(TAG, "Failed: %d", ret); return ret; } @@ -1081,9 +1081,9 @@ void nfcv_emu_sniff_packet( break; } - if(strlen(nfcv_data->last_command) > 0) { + /*if(strlen(nfcv_data->last_command) > 0) { FURI_LOG_D(TAG, "Received command %s", nfcv_data->last_command); - } + }*/ } void nfcv_emu_init(FuriHalNfcDevData* nfc_data, NfcVData* nfcv_data) { @@ -1137,7 +1137,7 @@ void nfcv_emu_init(FuriHalNfcDevData* nfc_data, NfcVData* nfcv_data) { } } - FURI_LOG_D(TAG, "Starting NfcV emulation"); + /*FURI_LOG_D(TAG, "Starting NfcV emulation"); FURI_LOG_D( TAG, " UID: %02X %02X %02X %02X %02X %02X %02X %02X", @@ -1148,7 +1148,7 @@ void nfcv_emu_init(FuriHalNfcDevData* nfc_data, NfcVData* nfcv_data) { nfc_data->uid[4], nfc_data->uid[5], nfc_data->uid[6], - nfc_data->uid[7]); + nfc_data->uid[7]);*/ switch(nfcv_data->sub_type) { case NfcVTypeSlixL: From 44426c7612f4dff67f9e2faf8bc3cd3d15613814 Mon Sep 17 00:00:00 2001 From: Sebastian Mauer Date: Mon, 29 May 2023 10:19:42 +0200 Subject: [PATCH 06/52] [LRFID] Add support for Nexkey/Nexwatch (#2680) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [LRFID] Add support for Nexkey/Nexwatch * Update protocol_nexwatch.c: Remove unnecessary check Co-authored-by: SG Co-authored-by: あく --- lib/lfrfid/protocols/lfrfid_protocols.c | 4 +- lib/lfrfid/protocols/lfrfid_protocols.h | 3 +- lib/lfrfid/protocols/protocol_nexwatch.c | 323 +++++++++++++++++++++++ lib/lfrfid/protocols/protocol_nexwatch.h | 4 + 4 files changed, 332 insertions(+), 2 deletions(-) create mode 100644 lib/lfrfid/protocols/protocol_nexwatch.c create mode 100644 lib/lfrfid/protocols/protocol_nexwatch.h diff --git a/lib/lfrfid/protocols/lfrfid_protocols.c b/lib/lfrfid/protocols/lfrfid_protocols.c index 2c1f0ad97..f07218d7f 100644 --- a/lib/lfrfid/protocols/lfrfid_protocols.c +++ b/lib/lfrfid/protocols/lfrfid_protocols.c @@ -16,6 +16,7 @@ #include "protocol_pac_stanley.h" #include "protocol_keri.h" #include "protocol_gallagher.h" +#include "protocol_nexwatch.h" const ProtocolBase* lfrfid_protocols[] = { [LFRFIDProtocolEM4100] = &protocol_em4100, @@ -35,4 +36,5 @@ const ProtocolBase* lfrfid_protocols[] = { [LFRFIDProtocolPACStanley] = &protocol_pac_stanley, [LFRFIDProtocolKeri] = &protocol_keri, [LFRFIDProtocolGallagher] = &protocol_gallagher, -}; \ No newline at end of file + [LFRFIDProtocolNexwatch] = &protocol_nexwatch, +}; diff --git a/lib/lfrfid/protocols/lfrfid_protocols.h b/lib/lfrfid/protocols/lfrfid_protocols.h index 848f003a3..0cb7cbc84 100644 --- a/lib/lfrfid/protocols/lfrfid_protocols.h +++ b/lib/lfrfid/protocols/lfrfid_protocols.h @@ -25,6 +25,7 @@ typedef enum { LFRFIDProtocolPACStanley, LFRFIDProtocolKeri, LFRFIDProtocolGallagher, + LFRFIDProtocolNexwatch, LFRFIDProtocolMax, } LFRFIDProtocol; @@ -39,4 +40,4 @@ typedef struct { union { LFRFIDT5577 t5577; }; -} LFRFIDWriteRequest; \ No newline at end of file +} LFRFIDWriteRequest; diff --git a/lib/lfrfid/protocols/protocol_nexwatch.c b/lib/lfrfid/protocols/protocol_nexwatch.c new file mode 100644 index 000000000..3bbbb42f5 --- /dev/null +++ b/lib/lfrfid/protocols/protocol_nexwatch.c @@ -0,0 +1,323 @@ +#include +#include +#include +#include "lfrfid_protocols.h" + +#define NEXWATCH_PREAMBLE_BIT_SIZE (8) +#define NEXWATCH_PREAMBLE_DATA_SIZE (1) + +#define NEXWATCH_ENCODED_BIT_SIZE (96) +#define NEXWATCH_ENCODED_DATA_SIZE ((NEXWATCH_ENCODED_BIT_SIZE) / 8) + +#define NEXWATCH_DECODED_BIT_SIZE (NEXWATCH_DECODED_DATA_SIZE * 8) +#define NEXWATCH_DECODED_DATA_SIZE (8) + +#define NEXWATCH_US_PER_BIT (255) +#define NEXWATCH_ENCODER_PULSES_PER_BIT (16) + +typedef struct { + uint8_t magic; + char desc[13]; + uint8_t chk; +} ProtocolNexwatchMagic; + +ProtocolNexwatchMagic magic_items[] = { + {0xBE, "Quadrakey", 0}, + {0x88, "Nexkey", 0}, + {0x86, "Honeywell", 0}}; + +typedef struct { + uint8_t data_index; + uint8_t bit_clock_index; + bool last_bit; + bool current_polarity; + bool pulse_phase; +} ProtocolNexwatchEncoder; + +typedef struct { + uint8_t encoded_data[NEXWATCH_ENCODED_DATA_SIZE]; + uint8_t negative_encoded_data[NEXWATCH_ENCODED_DATA_SIZE]; + uint8_t corrupted_encoded_data[NEXWATCH_ENCODED_DATA_SIZE]; + uint8_t corrupted_negative_encoded_data[NEXWATCH_ENCODED_DATA_SIZE]; + + uint8_t data[NEXWATCH_DECODED_DATA_SIZE]; + ProtocolNexwatchEncoder encoder; +} ProtocolNexwatch; + +ProtocolNexwatch* protocol_nexwatch_alloc(void) { + ProtocolNexwatch* protocol = malloc(sizeof(ProtocolNexwatch)); + return protocol; +}; + +void protocol_nexwatch_free(ProtocolNexwatch* protocol) { + free(protocol); +}; + +uint8_t* protocol_nexwatch_get_data(ProtocolNexwatch* protocol) { + return protocol->data; +}; + +void protocol_nexwatch_decoder_start(ProtocolNexwatch* protocol) { + memset(protocol->encoded_data, 0, NEXWATCH_ENCODED_DATA_SIZE); + memset(protocol->negative_encoded_data, 0, NEXWATCH_ENCODED_DATA_SIZE); + memset(protocol->corrupted_encoded_data, 0, NEXWATCH_ENCODED_DATA_SIZE); + memset(protocol->corrupted_negative_encoded_data, 0, NEXWATCH_ENCODED_DATA_SIZE); +}; + +static bool protocol_nexwatch_check_preamble(uint8_t* data, size_t bit_index) { + // 01010110 + if(bit_lib_get_bits(data, bit_index, 8) != 0b01010110) return false; + return true; +} + +static uint8_t protocol_nexwatch_parity_swap(uint8_t parity) { + uint8_t a = (((parity >> 3) & 1)); + a |= (((parity >> 1) & 1) << 1); + a |= (((parity >> 2) & 1) << 2); + a |= ((parity & 1) << 3); + return a; +} + +static uint8_t protocol_nexwatch_parity(const uint8_t hexid[5]) { + uint8_t p = 0; + for(uint8_t i = 0; i < 5; i++) { + p ^= ((hexid[i]) & 0xF0) >> 4; + p ^= ((hexid[i]) & 0x0F); + } + return protocol_nexwatch_parity_swap(p); +} + +static uint8_t protocol_nexwatch_checksum(uint8_t magic, uint32_t id, uint8_t parity) { + uint8_t a = ((id >> 24) & 0xFF); + a -= ((id >> 16) & 0xFF); + a -= ((id >> 8) & 0xFF); + a -= (id & 0xFF); + a -= magic; + a -= (bit_lib_reverse_8_fast(parity) >> 4); + return bit_lib_reverse_8_fast(a); +} + +static bool protocol_nexwatch_can_be_decoded(uint8_t* data) { + if(!protocol_nexwatch_check_preamble(data, 0)) return false; + + // Check for reserved word (32-bit) + if(bit_lib_get_bits_32(data, 8, 32) != 0) { + return false; + } + + uint8_t parity = bit_lib_get_bits(data, 76, 4); + + // parity check + // from 32b hex id, 4b mode + uint8_t hex[5] = {0}; + for(uint8_t i = 0; i < 5; i++) { + hex[i] = bit_lib_get_bits(data, 40 + (i * 8), 8); + } + //mode is only 4 bits. + hex[4] &= 0xf0; + uint8_t calc_parity = protocol_nexwatch_parity(hex); + + if(calc_parity != parity) { + return false; + } + + return true; +} + +static bool protocol_nexwatch_decoder_feed_internal(bool polarity, uint32_t time, uint8_t* data) { + time += (NEXWATCH_US_PER_BIT / 2); + + size_t bit_count = (time / NEXWATCH_US_PER_BIT); + bool result = false; + + if(bit_count < NEXWATCH_ENCODED_BIT_SIZE) { + for(size_t i = 0; i < bit_count; i++) { + bit_lib_push_bit(data, NEXWATCH_ENCODED_DATA_SIZE, polarity); + if(protocol_nexwatch_can_be_decoded(data)) { + result = true; + break; + } + } + } + + return result; +} + +static void protocol_nexwatch_descramble(uint32_t* id, uint32_t* scrambled) { + // 255 = Not used/Unknown other values are the bit offset in the ID/FC values + const uint8_t hex_2_id[] = {31, 27, 23, 19, 15, 11, 7, 3, 30, 26, 22, 18, 14, 10, 6, 2, + 29, 25, 21, 17, 13, 9, 5, 1, 28, 24, 20, 16, 12, 8, 4, 0}; + + *id = 0; + for(uint8_t idx = 0; idx < 32; idx++) { + bool bit_state = (*scrambled >> hex_2_id[idx]) & 1; + *id |= (bit_state << (31 - idx)); + } +} + +static void protocol_nexwatch_decoder_save(uint8_t* data_to, const uint8_t* data_from) { + uint32_t id = bit_lib_get_bits_32(data_from, 40, 32); + data_to[4] = (uint8_t)id; + data_to[3] = (uint8_t)(id >>= 8); + data_to[2] = (uint8_t)(id >>= 8); + data_to[1] = (uint8_t)(id >>= 8); + data_to[0] = (uint8_t)(id >>= 8); + uint32_t check = bit_lib_get_bits_32(data_from, 72, 24); + data_to[7] = (uint8_t)check; + data_to[6] = (uint8_t)(check >>= 8); + data_to[5] = (uint8_t)(check >>= 8); +} + +bool protocol_nexwatch_decoder_feed(ProtocolNexwatch* protocol, bool level, uint32_t duration) { + bool result = false; + + if(duration > (NEXWATCH_US_PER_BIT / 2)) { + if(protocol_nexwatch_decoder_feed_internal(level, duration, protocol->encoded_data)) { + protocol_nexwatch_decoder_save(protocol->data, protocol->encoded_data); + result = true; + return result; + } + + if(protocol_nexwatch_decoder_feed_internal( + !level, duration, protocol->negative_encoded_data)) { + protocol_nexwatch_decoder_save(protocol->data, protocol->negative_encoded_data); + result = true; + return result; + } + } + + if(duration > (NEXWATCH_US_PER_BIT / 4)) { + // Try to decode wrong phase synced data + if(level) { + duration += 120; + } else { + if(duration > 120) { + duration -= 120; + } + } + + if(protocol_nexwatch_decoder_feed_internal( + level, duration, protocol->corrupted_encoded_data)) { + protocol_nexwatch_decoder_save(protocol->data, protocol->corrupted_encoded_data); + + result = true; + return result; + } + + if(protocol_nexwatch_decoder_feed_internal( + !level, duration, protocol->corrupted_negative_encoded_data)) { + protocol_nexwatch_decoder_save( + protocol->data, protocol->corrupted_negative_encoded_data); + + result = true; + return result; + } + } + + return result; +}; + +bool protocol_nexwatch_encoder_start(ProtocolNexwatch* protocol) { + memset(protocol->encoded_data, 0, NEXWATCH_ENCODED_DATA_SIZE); + *(uint32_t*)&protocol->encoded_data[0] = 0b00000000000000000000000001010110; + bit_lib_copy_bits(protocol->encoded_data, 32, 32, protocol->data, 0); + bit_lib_copy_bits(protocol->encoded_data, 64, 32, protocol->data, 32); + + protocol->encoder.last_bit = + bit_lib_get_bit(protocol->encoded_data, NEXWATCH_ENCODED_BIT_SIZE - 1); + protocol->encoder.data_index = 0; + protocol->encoder.current_polarity = true; + protocol->encoder.pulse_phase = true; + protocol->encoder.bit_clock_index = 0; + + return true; +}; + +LevelDuration protocol_nexwatch_encoder_yield(ProtocolNexwatch* protocol) { + LevelDuration level_duration; + ProtocolNexwatchEncoder* encoder = &protocol->encoder; + + if(encoder->pulse_phase) { + level_duration = level_duration_make(encoder->current_polarity, 1); + encoder->pulse_phase = false; + } else { + level_duration = level_duration_make(!encoder->current_polarity, 1); + encoder->pulse_phase = true; + + encoder->bit_clock_index++; + if(encoder->bit_clock_index >= NEXWATCH_ENCODER_PULSES_PER_BIT) { + encoder->bit_clock_index = 0; + + bool current_bit = bit_lib_get_bit(protocol->encoded_data, encoder->data_index); + + if(current_bit != encoder->last_bit) { + encoder->current_polarity = !encoder->current_polarity; + } + + encoder->last_bit = current_bit; + + bit_lib_increment_index(encoder->data_index, NEXWATCH_ENCODED_BIT_SIZE); + } + } + + return level_duration; +}; + +void protocol_nexwatch_render_data(ProtocolNexwatch* protocol, FuriString* result) { + uint32_t id = 0; + uint32_t scrambled = bit_lib_get_bits_32(protocol->data, 8, 32); + protocol_nexwatch_descramble(&id, &scrambled); + + uint8_t m_idx; + uint8_t mode = bit_lib_get_bits(protocol->data, 40, 4); + uint8_t parity = bit_lib_get_bits(protocol->data, 44, 4); + uint8_t chk = bit_lib_get_bits(protocol->data, 48, 8); + for(m_idx = 0; m_idx < 3; m_idx++) { + magic_items[m_idx].chk = protocol_nexwatch_checksum(magic_items[m_idx].magic, id, parity); + if(magic_items[m_idx].chk == chk) { + break; + } + } + furi_string_printf(result, "ID: %lu, M:%u\r\nType: %s\r\n", id, mode, magic_items[m_idx].desc); +} + +bool protocol_nexwatch_write_data(ProtocolNexwatch* protocol, void* data) { + LFRFIDWriteRequest* request = (LFRFIDWriteRequest*)data; + bool result = false; + + protocol_nexwatch_encoder_start(protocol); + if(request->write_type == LFRFIDWriteTypeT5577) { + request->t5577.block[0] = LFRFID_T5577_MODULATION_PSK1 | LFRFID_T5577_BITRATE_RF_32 | + (3 << LFRFID_T5577_MAXBLOCK_SHIFT); + request->t5577.block[1] = bit_lib_get_bits_32(protocol->encoded_data, 0, 32); + request->t5577.block[2] = bit_lib_get_bits_32(protocol->encoded_data, 32, 32); + request->t5577.block[3] = bit_lib_get_bits_32(protocol->encoded_data, 64, 32); + request->t5577.blocks_to_write = 4; + result = true; + } + return result; +}; + +const ProtocolBase protocol_nexwatch = { + .name = "Nexwatch", + .manufacturer = "Honeywell", + .data_size = NEXWATCH_DECODED_DATA_SIZE, + .features = LFRFIDFeaturePSK, + .validate_count = 6, + .alloc = (ProtocolAlloc)protocol_nexwatch_alloc, + .free = (ProtocolFree)protocol_nexwatch_free, + .get_data = (ProtocolGetData)protocol_nexwatch_get_data, + .decoder = + { + .start = (ProtocolDecoderStart)protocol_nexwatch_decoder_start, + .feed = (ProtocolDecoderFeed)protocol_nexwatch_decoder_feed, + }, + .encoder = + { + .start = (ProtocolEncoderStart)protocol_nexwatch_encoder_start, + .yield = (ProtocolEncoderYield)protocol_nexwatch_encoder_yield, + }, + .render_data = (ProtocolRenderData)protocol_nexwatch_render_data, + .render_brief_data = (ProtocolRenderData)protocol_nexwatch_render_data, + .write_data = (ProtocolWriteData)protocol_nexwatch_write_data, +}; diff --git a/lib/lfrfid/protocols/protocol_nexwatch.h b/lib/lfrfid/protocols/protocol_nexwatch.h new file mode 100644 index 000000000..0872ca7dc --- /dev/null +++ b/lib/lfrfid/protocols/protocol_nexwatch.h @@ -0,0 +1,4 @@ +#pragma once +#include + +extern const ProtocolBase protocol_nexwatch; From f9390e0cbdf62e4b1c6309adff4940e655633b66 Mon Sep 17 00:00:00 2001 From: minchogaydarov <134236905+minchogaydarov@users.noreply.github.com> Date: Mon, 29 May 2023 10:04:38 +0100 Subject: [PATCH 07/52] Add Carrier 42QHB12D8S (#2707) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: あく --- assets/resources/infrared/assets/ac.ir | 36 ++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/assets/resources/infrared/assets/ac.ir b/assets/resources/infrared/assets/ac.ir index e06c95f71..142c49243 100644 --- a/assets/resources/infrared/assets/ac.ir +++ b/assets/resources/infrared/assets/ac.ir @@ -434,3 +434,39 @@ frequency: 38000 duty_cycle: 0.330000 data: 4401 4441 528 1629 529 550 528 1628 529 551 528 550 528 551 527 551 528 1629 529 1629 529 550 529 1630 528 551 528 549 530 550 529 551 528 549 529 550 529 1629 529 1628 530 549 530 1629 529 550 529 1628 529 1629 529 1631 527 1628 530 1628 529 1629 528 1628 530 1629 529 1629 529 1629 529 1629 528 1629 529 1629 529 1630 528 1629 529 1629 529 1628 529 1629 528 551 528 1629 529 550 529 550 530 548 529 1631 527 551 528 1629 529 5235 4402 4439 530 550 528 1629 529 549 530 1628 529 1629 529 1628 530 1629 529 549 530 550 529 1628 530 552 526 1628 529 1628 530 1628 530 1627 531 1628 529 1629 528 551 528 550 529 1628 530 550 528 1628 529 549 529 550 528 550 529 549 530 548 530 551 528 550 528 578 500 550 529 550 529 551 527 549 530 549 529 549 529 550 528 548 530 550 528 549 529 1629 528 550 529 1630 528 1628 530 1628 530 549 530 1628 529 549 529 # +# Model: Carrier 42QHB12D8S +name: Off +type: raw +frequency: 38000 +duty_cycle: 0.330000 +data: 4467 4363 599 1556 599 478 599 1556 599 1558 597 505 572 505 572 1583 571 505 572 506 624 1531 653 423 651 426 624 1530 622 1532 572 505 572 1583 571 506 571 1584 571 1583 571 1584 571 1584 571 507 570 1585 570 1585 570 1585 570 508 569 508 569 508 592 485 570 1585 593 484 570 508 569 1586 569 1586 592 1563 593 485 569 508 592 485 592 485 570 508 569 508 570 508 569 508 569 1586 569 1586 569 1586 569 1586 569 1586 569 5187 4461 4371 568 1586 569 508 593 1562 593 1563 569 509 591 486 591 1563 569 508 592 486 592 1563 592 485 592 486 591 1563 592 1563 591 486 592 1564 591 486 592 1563 593 1563 591 1563 592 1564 592 485 592 1563 592 1563 592 1564 591 486 591 486 592 485 592 485 592 1563 592 486 591 486 592 1564 591 1563 592 1563 592 486 592 485 592 486 591 486 592 485 592 486 591 486 591 486 591 1563 592 1563 593 1563 591 1564 591 1563 591 +# +name: Dh +type: raw +frequency: 38000 +duty_cycle: 0.330000 +data: 4440 4390 571 1583 572 505 572 1583 596 1559 571 505 572 505 572 1583 596 481 596 481 597 1559 625 451 654 423 625 1529 595 1560 596 480 572 1583 572 505 596 482 594 483 571 1583 571 1584 571 1584 571 1584 571 1585 569 1585 593 1562 594 1561 593 485 569 508 593 484 592 485 593 484 592 485 592 1563 569 508 592 1562 592 485 570 1586 592 485 592 486 569 1586 592 485 569 1585 570 508 569 1586 569 508 569 1585 570 1586 569 5186 4438 4393 569 1585 593 485 592 1562 569 1585 569 508 569 508 569 1585 591 486 593 484 591 1563 591 486 591 486 590 1564 569 1585 569 508 593 1562 592 486 592 485 569 508 591 1563 592 1562 569 1586 569 1586 591 1563 592 1563 590 1564 591 1563 592 486 569 508 569 508 569 508 569 508 592 486 592 1563 568 508 593 1563 591 486 592 1563 569 508 592 486 592 1563 591 486 592 1563 592 485 592 1563 592 486 592 1563 591 1563 592 +# +name: Cool_hi +type: raw +frequency: 38000 +duty_cycle: 0.330000 +data: 4465 4365 598 1557 598 479 598 1557 598 1557 598 479 598 479 598 1556 599 479 598 507 593 1562 652 424 624 452 595 1559 595 1560 594 483 571 1584 594 1561 593 484 593 1562 593 1562 593 1562 593 1562 593 1562 593 1563 592 485 592 1562 593 484 593 485 592 485 592 485 592 485 592 485 592 485 592 485 592 485 592 485 592 485 592 485 592 485 592 485 592 1562 592 1563 592 1562 593 1562 592 1563 592 1563 592 1562 592 1563 592 5165 4439 4394 569 1586 592 485 569 1586 569 1586 569 508 569 508 593 1562 592 485 570 508 592 1563 592 485 594 484 569 1586 569 1586 569 508 569 1586 592 1563 569 508 592 1563 569 1586 592 1563 592 1563 569 1586 569 1585 569 508 569 1586 569 508 569 508 569 508 569 508 592 485 569 508 592 485 569 508 593 485 569 508 569 508 569 508 593 484 570 508 569 1586 593 1562 570 1586 569 1586 592 1563 569 1586 592 1563 592 1563 592 +# +name: Cool_lo +type: raw +frequency: 38000 +duty_cycle: 0.330000 +data: 4465 4364 599 1556 599 479 598 1556 599 1556 599 478 599 479 598 1559 596 505 572 506 571 1584 653 424 624 452 571 1583 572 1583 571 506 571 1583 571 1584 571 506 571 1584 571 1585 570 1585 570 1585 592 1563 592 1562 593 485 592 1563 592 485 593 485 592 485 592 485 592 485 592 485 593 485 592 1563 592 485 592 1563 592 485 592 485 592 485 592 485 592 1563 592 485 592 1563 592 485 592 1563 592 1563 592 1563 592 1563 592 5164 4460 4372 592 1563 592 485 593 1563 592 1563 592 486 591 486 591 1563 592 485 592 485 592 1563 592 485 592 485 592 1563 592 1563 592 485 592 1563 592 1563 592 485 592 1563 592 1563 592 1563 592 1563 592 1563 592 1564 591 486 591 1563 591 485 592 485 592 485 592 485 592 485 592 485 592 485 592 1563 592 485 592 1563 591 486 591 485 592 486 591 485 592 1563 592 485 592 1563 592 485 592 1564 591 1563 592 1563 592 1563 592 +# +name: Heat_hi +type: raw +frequency: 38000 +duty_cycle: 0.330000 +data: 4440 4391 572 1583 572 505 572 1584 571 1583 572 505 572 505 572 1583 596 481 573 505 596 1559 626 451 655 422 625 1529 596 1559 572 505 572 1583 572 1582 572 505 572 1583 572 1583 571 1584 571 1584 571 1585 570 1584 594 484 593 1562 592 485 592 485 592 485 593 485 593 484 593 484 593 1562 593 484 593 1562 593 1563 592 1562 592 1563 592 485 593 484 592 485 593 1562 593 484 593 485 592 485 592 485 592 1562 593 1563 592 5163 4462 4370 592 1563 592 485 592 1563 592 1563 592 485 592 485 592 1563 592 485 592 485 593 1562 593 485 593 485 592 1563 592 1563 592 485 592 1562 593 1563 592 484 593 1563 592 1563 592 1563 592 1563 592 1563 592 1563 592 485 592 1563 592 485 592 485 592 485 592 485 592 485 593 485 592 1563 592 485 592 1563 592 1563 592 1563 592 1563 592 485 592 485 592 485 592 1563 591 485 592 486 591 485 592 485 593 1563 591 1563 593 +# +name: Heat_lo +type: raw +frequency: 38000 +duty_cycle: 0.330000 +data: 4467 4390 571 1583 572 505 595 1560 572 1583 572 505 572 505 596 1559 596 482 596 481 597 1559 626 451 655 422 625 1529 596 1559 596 481 572 1582 573 1583 571 505 572 1583 595 1560 594 1561 592 1562 594 1561 593 1562 593 484 593 1563 592 485 592 485 592 485 592 485 593 484 593 485 592 485 592 1562 593 485 592 1563 592 1562 593 1562 594 483 593 485 593 1562 592 485 593 1561 593 484 593 484 593 484 593 1562 593 1562 592 5163 4462 4370 592 1563 593 484 592 1563 592 1563 592 485 592 485 593 1562 593 484 593 485 592 1562 593 484 593 485 592 1562 593 1562 593 485 592 1563 592 1563 592 485 592 1563 592 1562 593 1562 593 1563 592 1563 592 1562 592 485 593 1562 592 485 592 485 592 485 592 485 592 485 592 485 592 485 592 1563 592 485 592 1563 591 1563 592 1563 593 485 592 485 592 1563 592 485 592 1563 591 485 593 485 592 485 592 1563 592 1563 591 From 66961dab0657b8d1a7d1196f8b89b1021969ca59 Mon Sep 17 00:00:00 2001 From: Nikolay Minaylov Date: Mon, 29 May 2023 12:21:18 +0300 Subject: [PATCH 08/52] BadUSB: script execution pause (#2700) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: あく --- .../main/bad_usb/helpers/ducky_script.c | 96 ++++++++++++++----- .../main/bad_usb/helpers/ducky_script.h | 5 +- .../main/bad_usb/scenes/bad_usb_scene_work.c | 5 +- .../main/bad_usb/views/bad_usb_view.c | 82 ++++++++++++---- 4 files changed, 142 insertions(+), 46 deletions(-) diff --git a/applications/main/bad_usb/helpers/ducky_script.c b/applications/main/bad_usb/helpers/ducky_script.c index 47d8a7e05..5a834ad0a 100644 --- a/applications/main/bad_usb/helpers/ducky_script.c +++ b/applications/main/bad_usb/helpers/ducky_script.c @@ -16,10 +16,11 @@ (((uint8_t)x < 128) ? (script->layout[(uint8_t)x]) : HID_KEYBOARD_NONE) typedef enum { - WorkerEvtToggle = (1 << 0), - WorkerEvtEnd = (1 << 1), - WorkerEvtConnect = (1 << 2), - WorkerEvtDisconnect = (1 << 3), + WorkerEvtStartStop = (1 << 0), + WorkerEvtPauseResume = (1 << 1), + WorkerEvtEnd = (1 << 2), + WorkerEvtConnect = (1 << 3), + WorkerEvtDisconnect = (1 << 4), } WorkerEvtFlags; static const char ducky_cmd_id[] = {"ID"}; @@ -372,6 +373,7 @@ static int32_t bad_usb_worker(void* context) { BadUsbScript* bad_usb = context; BadUsbWorkerState worker_state = BadUsbStateInit; + BadUsbWorkerState pause_state = BadUsbStateRunning; int32_t delay_val = 0; FURI_LOG_I(WORKER_TAG, "Init"); @@ -406,24 +408,24 @@ static int32_t bad_usb_worker(void* context) { } else if(worker_state == BadUsbStateNotConnected) { // State: USB not connected uint32_t flags = bad_usb_flags_get( - WorkerEvtEnd | WorkerEvtConnect | WorkerEvtToggle, FuriWaitForever); + WorkerEvtEnd | WorkerEvtConnect | WorkerEvtStartStop, FuriWaitForever); if(flags & WorkerEvtEnd) { break; } else if(flags & WorkerEvtConnect) { worker_state = BadUsbStateIdle; // Ready to run - } else if(flags & WorkerEvtToggle) { + } else if(flags & WorkerEvtStartStop) { worker_state = BadUsbStateWillRun; // Will run when USB is connected } bad_usb->st.state = worker_state; } else if(worker_state == BadUsbStateIdle) { // State: ready to start uint32_t flags = bad_usb_flags_get( - WorkerEvtEnd | WorkerEvtToggle | WorkerEvtDisconnect, FuriWaitForever); + WorkerEvtEnd | WorkerEvtStartStop | WorkerEvtDisconnect, FuriWaitForever); if(flags & WorkerEvtEnd) { break; - } else if(flags & WorkerEvtToggle) { // Start executing script + } else if(flags & WorkerEvtStartStop) { // Start executing script DOLPHIN_DEED(DolphinDeedBadUsbPlayScript); delay_val = 0; bad_usb->buf_len = 0; @@ -442,7 +444,7 @@ static int32_t bad_usb_worker(void* context) { } else if(worker_state == BadUsbStateWillRun) { // State: start on connection uint32_t flags = bad_usb_flags_get( - WorkerEvtEnd | WorkerEvtConnect | WorkerEvtToggle, FuriWaitForever); + WorkerEvtEnd | WorkerEvtConnect | WorkerEvtStartStop, FuriWaitForever); if(flags & WorkerEvtEnd) { break; @@ -458,17 +460,17 @@ static int32_t bad_usb_worker(void* context) { storage_file_seek(script_file, 0, true); // extra time for PC to recognize Flipper as keyboard flags = furi_thread_flags_wait( - WorkerEvtEnd | WorkerEvtDisconnect | WorkerEvtToggle, + WorkerEvtEnd | WorkerEvtDisconnect | WorkerEvtStartStop, FuriFlagWaitAny | FuriFlagNoClear, 1500); if(flags == (unsigned)FuriFlagErrorTimeout) { // If nothing happened - start script execution worker_state = BadUsbStateRunning; - } else if(flags & WorkerEvtToggle) { + } else if(flags & WorkerEvtStartStop) { worker_state = BadUsbStateIdle; - furi_thread_flags_clear(WorkerEvtToggle); + furi_thread_flags_clear(WorkerEvtStartStop); } - } else if(flags & WorkerEvtToggle) { // Cancel scheduled execution + } else if(flags & WorkerEvtStartStop) { // Cancel scheduled execution worker_state = BadUsbStateNotConnected; } bad_usb->st.state = worker_state; @@ -476,18 +478,23 @@ static int32_t bad_usb_worker(void* context) { } else if(worker_state == BadUsbStateRunning) { // State: running uint16_t delay_cur = (delay_val > 1000) ? (1000) : (delay_val); uint32_t flags = furi_thread_flags_wait( - WorkerEvtEnd | WorkerEvtToggle | WorkerEvtDisconnect, FuriFlagWaitAny, delay_cur); + WorkerEvtEnd | WorkerEvtStartStop | WorkerEvtPauseResume | WorkerEvtDisconnect, + FuriFlagWaitAny, + delay_cur); delay_val -= delay_cur; if(!(flags & FuriFlagError)) { if(flags & WorkerEvtEnd) { break; - } else if(flags & WorkerEvtToggle) { + } else if(flags & WorkerEvtStartStop) { worker_state = BadUsbStateIdle; // Stop executing script furi_hal_hid_kb_release_all(); } else if(flags & WorkerEvtDisconnect) { worker_state = BadUsbStateNotConnected; // USB disconnected furi_hal_hid_kb_release_all(); + } else if(flags & WorkerEvtPauseResume) { + pause_state = BadUsbStateRunning; + worker_state = BadUsbStatePaused; // Pause } bad_usb->st.state = worker_state; continue; @@ -526,13 +533,13 @@ static int32_t bad_usb_worker(void* context) { furi_check((flags & FuriFlagError) == 0); } } else if(worker_state == BadUsbStateWaitForBtn) { // State: Wait for button Press - uint16_t delay_cur = (delay_val > 1000) ? (1000) : (delay_val); - uint32_t flags = furi_thread_flags_wait( - WorkerEvtEnd | WorkerEvtToggle | WorkerEvtDisconnect, FuriFlagWaitAny, delay_cur); + uint32_t flags = bad_usb_flags_get( + WorkerEvtEnd | WorkerEvtStartStop | WorkerEvtPauseResume | WorkerEvtDisconnect, + FuriWaitForever); if(!(flags & FuriFlagError)) { if(flags & WorkerEvtEnd) { break; - } else if(flags & WorkerEvtToggle) { + } else if(flags & WorkerEvtStartStop) { delay_val = 0; worker_state = BadUsbStateRunning; } else if(flags & WorkerEvtDisconnect) { @@ -542,21 +549,55 @@ static int32_t bad_usb_worker(void* context) { bad_usb->st.state = worker_state; continue; } + } else if(worker_state == BadUsbStatePaused) { // State: Paused + uint32_t flags = bad_usb_flags_get( + WorkerEvtEnd | WorkerEvtStartStop | WorkerEvtPauseResume | WorkerEvtDisconnect, + FuriWaitForever); + if(!(flags & FuriFlagError)) { + if(flags & WorkerEvtEnd) { + break; + } else if(flags & WorkerEvtStartStop) { + worker_state = BadUsbStateIdle; // Stop executing script + bad_usb->st.state = worker_state; + furi_hal_hid_kb_release_all(); + } else if(flags & WorkerEvtDisconnect) { + worker_state = BadUsbStateNotConnected; // USB disconnected + bad_usb->st.state = worker_state; + furi_hal_hid_kb_release_all(); + } else if(flags & WorkerEvtPauseResume) { + if(pause_state == BadUsbStateRunning) { + if(delay_val > 0) { + bad_usb->st.state = BadUsbStateDelay; + bad_usb->st.delay_remain = delay_val / 1000; + } else { + bad_usb->st.state = BadUsbStateRunning; + delay_val = 0; + } + worker_state = BadUsbStateRunning; // Resume + } else if(pause_state == BadUsbStateStringDelay) { + bad_usb->st.state = BadUsbStateRunning; + worker_state = BadUsbStateStringDelay; // Resume + } + } + continue; + } } else if(worker_state == BadUsbStateStringDelay) { // State: print string with delays - uint32_t flags = furi_thread_flags_wait( - WorkerEvtEnd | WorkerEvtToggle | WorkerEvtDisconnect, - FuriFlagWaitAny, + uint32_t flags = bad_usb_flags_get( + WorkerEvtEnd | WorkerEvtStartStop | WorkerEvtPauseResume | WorkerEvtDisconnect, bad_usb->stringdelay); if(!(flags & FuriFlagError)) { if(flags & WorkerEvtEnd) { break; - } else if(flags & WorkerEvtToggle) { + } else if(flags & WorkerEvtStartStop) { worker_state = BadUsbStateIdle; // Stop executing script furi_hal_hid_kb_release_all(); } else if(flags & WorkerEvtDisconnect) { worker_state = BadUsbStateNotConnected; // USB disconnected furi_hal_hid_kb_release_all(); + } else if(flags & WorkerEvtPauseResume) { + pause_state = BadUsbStateStringDelay; + worker_state = BadUsbStatePaused; // Pause } bad_usb->st.state = worker_state; continue; @@ -651,9 +692,14 @@ void bad_usb_script_set_keyboard_layout(BadUsbScript* bad_usb, FuriString* layou storage_file_free(layout_file); } -void bad_usb_script_toggle(BadUsbScript* bad_usb) { +void bad_usb_script_start_stop(BadUsbScript* bad_usb) { furi_assert(bad_usb); - furi_thread_flags_set(furi_thread_get_id(bad_usb->thread), WorkerEvtToggle); + furi_thread_flags_set(furi_thread_get_id(bad_usb->thread), WorkerEvtStartStop); +} + +void bad_usb_script_pause_resume(BadUsbScript* bad_usb) { + furi_assert(bad_usb); + furi_thread_flags_set(furi_thread_get_id(bad_usb->thread), WorkerEvtPauseResume); } BadUsbState* bad_usb_script_get_state(BadUsbScript* bad_usb) { diff --git a/applications/main/bad_usb/helpers/ducky_script.h b/applications/main/bad_usb/helpers/ducky_script.h index cff723942..c8705dbdd 100644 --- a/applications/main/bad_usb/helpers/ducky_script.h +++ b/applications/main/bad_usb/helpers/ducky_script.h @@ -16,6 +16,7 @@ typedef enum { BadUsbStateDelay, BadUsbStateStringDelay, BadUsbStateWaitForBtn, + BadUsbStatePaused, BadUsbStateDone, BadUsbStateScriptError, BadUsbStateFileError, @@ -42,7 +43,9 @@ void bad_usb_script_start(BadUsbScript* bad_usb); void bad_usb_script_stop(BadUsbScript* bad_usb); -void bad_usb_script_toggle(BadUsbScript* bad_usb); +void bad_usb_script_start_stop(BadUsbScript* bad_usb); + +void bad_usb_script_pause_resume(BadUsbScript* bad_usb); BadUsbState* bad_usb_script_get_state(BadUsbScript* bad_usb); diff --git a/applications/main/bad_usb/scenes/bad_usb_scene_work.c b/applications/main/bad_usb/scenes/bad_usb_scene_work.c index afc2e6f6f..ad33a124d 100644 --- a/applications/main/bad_usb/scenes/bad_usb_scene_work.c +++ b/applications/main/bad_usb/scenes/bad_usb_scene_work.c @@ -21,7 +21,10 @@ bool bad_usb_scene_work_on_event(void* context, SceneManagerEvent event) { } consumed = true; } else if(event.event == InputKeyOk) { - bad_usb_script_toggle(app->bad_usb_script); + bad_usb_script_start_stop(app->bad_usb_script); + consumed = true; + } else if(event.event == InputKeyRight) { + bad_usb_script_pause_resume(app->bad_usb_script); consumed = true; } } else if(event.type == SceneManagerEventTypeTick) { diff --git a/applications/main/bad_usb/views/bad_usb_view.c b/applications/main/bad_usb/views/bad_usb_view.c index 0ab4365b7..fa75b50d0 100644 --- a/applications/main/bad_usb/views/bad_usb_view.c +++ b/applications/main/bad_usb/views/bad_usb_view.c @@ -16,6 +16,7 @@ typedef struct { char file_name[MAX_NAME_LEN]; char layout[MAX_NAME_LEN]; BadUsbState state; + bool pause_wait; uint8_t anim_frame; } BadUsbModel; @@ -31,11 +32,7 @@ static void bad_usb_draw_callback(Canvas* canvas, void* _model) { if(strlen(model->layout) == 0) { furi_string_set(disp_str, "(default)"); } else { - furi_string_reset(disp_str); - furi_string_push_back(disp_str, '('); - for(size_t i = 0; i < strlen(model->layout); i++) - furi_string_push_back(disp_str, model->layout[i]); - furi_string_push_back(disp_str, ')'); + furi_string_printf(disp_str, "(%s)", model->layout); } elements_string_fit_width(canvas, disp_str, 128 - 2); canvas_draw_str( @@ -45,34 +42,42 @@ static void bad_usb_draw_callback(Canvas* canvas, void* _model) { canvas_draw_icon(canvas, 22, 24, &I_UsbTree_48x22); - if((model->state.state == BadUsbStateIdle) || (model->state.state == BadUsbStateDone) || - (model->state.state == BadUsbStateNotConnected)) { + BadUsbWorkerState state = model->state.state; + + if((state == BadUsbStateIdle) || (state == BadUsbStateDone) || + (state == BadUsbStateNotConnected)) { elements_button_center(canvas, "Run"); elements_button_left(canvas, "Config"); - } else if((model->state.state == BadUsbStateRunning) || (model->state.state == BadUsbStateDelay)) { + } else if((state == BadUsbStateRunning) || (state == BadUsbStateDelay)) { elements_button_center(canvas, "Stop"); - } else if(model->state.state == BadUsbStateWaitForBtn) { + if(!model->pause_wait) { + elements_button_right(canvas, "Pause"); + } + } else if(state == BadUsbStatePaused) { + elements_button_center(canvas, "End"); + elements_button_right(canvas, "Resume"); + } else if(state == BadUsbStateWaitForBtn) { elements_button_center(canvas, "Press to continue"); - } else if(model->state.state == BadUsbStateWillRun) { + } else if(state == BadUsbStateWillRun) { elements_button_center(canvas, "Cancel"); } - if(model->state.state == BadUsbStateNotConnected) { + if(state == BadUsbStateNotConnected) { canvas_draw_icon(canvas, 4, 26, &I_Clock_18x18); canvas_set_font(canvas, FontPrimary); canvas_draw_str_aligned(canvas, 127, 31, AlignRight, AlignBottom, "Connect"); canvas_draw_str_aligned(canvas, 127, 43, AlignRight, AlignBottom, "to USB"); - } else if(model->state.state == BadUsbStateWillRun) { + } else if(state == BadUsbStateWillRun) { canvas_draw_icon(canvas, 4, 26, &I_Clock_18x18); canvas_set_font(canvas, FontPrimary); canvas_draw_str_aligned(canvas, 127, 31, AlignRight, AlignBottom, "Will run"); canvas_draw_str_aligned(canvas, 127, 43, AlignRight, AlignBottom, "on connect"); - } else if(model->state.state == BadUsbStateFileError) { + } else if(state == BadUsbStateFileError) { canvas_draw_icon(canvas, 4, 26, &I_Error_18x18); canvas_set_font(canvas, FontPrimary); canvas_draw_str_aligned(canvas, 127, 31, AlignRight, AlignBottom, "File"); canvas_draw_str_aligned(canvas, 127, 43, AlignRight, AlignBottom, "ERROR"); - } else if(model->state.state == BadUsbStateScriptError) { + } else if(state == BadUsbStateScriptError) { canvas_draw_icon(canvas, 4, 26, &I_Error_18x18); canvas_set_font(canvas, FontPrimary); canvas_draw_str_aligned(canvas, 127, 33, AlignRight, AlignBottom, "ERROR:"); @@ -87,12 +92,12 @@ static void bad_usb_draw_callback(Canvas* canvas, void* _model) { canvas_draw_str_aligned( canvas, 127, 56, AlignRight, AlignBottom, furi_string_get_cstr(disp_str)); furi_string_reset(disp_str); - } else if(model->state.state == BadUsbStateIdle) { + } else if(state == BadUsbStateIdle) { canvas_draw_icon(canvas, 4, 26, &I_Smile_18x18); canvas_set_font(canvas, FontBigNumbers); canvas_draw_str_aligned(canvas, 114, 40, AlignRight, AlignBottom, "0"); canvas_draw_icon(canvas, 117, 26, &I_Percent_10x14); - } else if(model->state.state == BadUsbStateRunning) { + } else if(state == BadUsbStateRunning) { if(model->anim_frame == 0) { canvas_draw_icon(canvas, 4, 23, &I_EviSmile1_18x21); } else { @@ -105,13 +110,13 @@ static void bad_usb_draw_callback(Canvas* canvas, void* _model) { canvas, 114, 40, AlignRight, AlignBottom, furi_string_get_cstr(disp_str)); furi_string_reset(disp_str); canvas_draw_icon(canvas, 117, 26, &I_Percent_10x14); - } else if(model->state.state == BadUsbStateDone) { + } else if(state == BadUsbStateDone) { canvas_draw_icon(canvas, 4, 23, &I_EviSmile1_18x21); canvas_set_font(canvas, FontBigNumbers); canvas_draw_str_aligned(canvas, 114, 40, AlignRight, AlignBottom, "100"); furi_string_reset(disp_str); canvas_draw_icon(canvas, 117, 26, &I_Percent_10x14); - } else if(model->state.state == BadUsbStateDelay) { + } else if(state == BadUsbStateDelay) { if(model->anim_frame == 0) { canvas_draw_icon(canvas, 4, 23, &I_EviWaiting1_18x21); } else { @@ -129,6 +134,22 @@ static void bad_usb_draw_callback(Canvas* canvas, void* _model) { canvas_draw_str_aligned( canvas, 127, 50, AlignRight, AlignBottom, furi_string_get_cstr(disp_str)); furi_string_reset(disp_str); + } else if((state == BadUsbStatePaused) || (state == BadUsbStateWaitForBtn)) { + if(model->anim_frame == 0) { + canvas_draw_icon(canvas, 4, 23, &I_EviWaiting1_18x21); + } else { + canvas_draw_icon(canvas, 4, 23, &I_EviWaiting2_18x21); + } + canvas_set_font(canvas, FontBigNumbers); + furi_string_printf( + disp_str, "%u", ((model->state.line_cur - 1) * 100) / model->state.line_nb); + canvas_draw_str_aligned( + canvas, 114, 40, AlignRight, AlignBottom, furi_string_get_cstr(disp_str)); + furi_string_reset(disp_str); + canvas_draw_icon(canvas, 117, 26, &I_Percent_10x14); + canvas_set_font(canvas, FontSecondary); + canvas_draw_str_aligned(canvas, 127, 50, AlignRight, AlignBottom, "Paused"); + furi_string_reset(disp_str); } else { canvas_draw_icon(canvas, 4, 26, &I_Clock_18x18); } @@ -142,7 +163,27 @@ static bool bad_usb_input_callback(InputEvent* event, void* context) { bool consumed = false; if(event->type == InputTypeShort) { - if((event->key == InputKeyLeft) || (event->key == InputKeyOk)) { + if(event->key == InputKeyLeft) { + consumed = true; + furi_assert(bad_usb->callback); + bad_usb->callback(event->key, bad_usb->context); + } else if(event->key == InputKeyOk) { + with_view_model( + bad_usb->view, BadUsbModel * model, { model->pause_wait = false; }, true); + consumed = true; + furi_assert(bad_usb->callback); + bad_usb->callback(event->key, bad_usb->context); + } else if(event->key == InputKeyRight) { + with_view_model( + bad_usb->view, + BadUsbModel * model, + { + if((model->state.state == BadUsbStateRunning) || + (model->state.state == BadUsbStateDelay)) { + model->pause_wait = true; + } + }, + true); consumed = true; furi_assert(bad_usb->callback); bad_usb->callback(event->key, bad_usb->context); @@ -215,6 +256,9 @@ void bad_usb_set_state(BadUsb* bad_usb, BadUsbState* st) { { memcpy(&(model->state), st, sizeof(BadUsbState)); model->anim_frame ^= 1; + if(model->state.state == BadUsbStatePaused) { + model->pause_wait = false; + } }, true); } From 04f9811c6e1b017e5b776572d591369e33419ae2 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Mon, 29 May 2023 14:17:50 +0300 Subject: [PATCH 09/52] Fix crash when renaming files with long file name --- applications/services/gui/modules/text_input.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/applications/services/gui/modules/text_input.c b/applications/services/gui/modules/text_input.c index 3e521c356..446730e95 100644 --- a/applications/services/gui/modules/text_input.c +++ b/applications/services/gui/modules/text_input.c @@ -175,7 +175,7 @@ static void text_input_view_draw_callback(Canvas* canvas, void* _model) { canvas_draw_str(canvas, 2, 8, model->header); elements_slightly_rounded_frame(canvas, 1, 12, 126, 15); - char buf[model->text_buffer_size + 1]; + char buf[text_length + 1]; if(model->text_buffer) { strlcpy(buf, model->text_buffer, sizeof(buf)); } From 363f555ed74ab79aea0a6700779b22197bf1305d Mon Sep 17 00:00:00 2001 From: micolous Date: Mon, 29 May 2023 21:55:55 +1000 Subject: [PATCH 10/52] Implement support for reading Opal card (Sydney, Australia) (#2683) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Implement support for reading Opal card (Sydney, Australia) * stub_parser_verify_read: used UNUSED macro * furi_hal_rtc: expose calendaring as functions * opal: use bit-packed struct to parse, rather than manually shifting about * Update f18 api symbols Co-authored-by: あく --- .../main/nfc/scenes/nfc_scene_device_info.c | 1 + .../nfc_scene_mf_desfire_read_success.c | 61 +++--- .../main/nfc/scenes/nfc_scene_nfc_data_info.c | 2 +- .../main/nfc/scenes/nfc_scene_saved_menu.c | 1 + firmware/targets/f18/api_symbols.csv | 5 +- firmware/targets/f7/api_symbols.csv | 7 +- firmware/targets/f7/furi_hal/furi_hal_rtc.c | 24 ++- .../targets/furi_hal_include/furi_hal_rtc.h | 24 +++ lib/nfc/nfc_worker.c | 13 ++ lib/nfc/parsers/nfc_supported_card.c | 15 ++ lib/nfc/parsers/nfc_supported_card.h | 6 + lib/nfc/parsers/opal.c | 204 ++++++++++++++++++ lib/nfc/parsers/opal.h | 5 + lib/nfc/protocols/mifare_desfire.c | 24 +++ lib/nfc/protocols/mifare_desfire.h | 3 + 15 files changed, 357 insertions(+), 38 deletions(-) create mode 100644 lib/nfc/parsers/opal.c create mode 100644 lib/nfc/parsers/opal.h diff --git a/applications/main/nfc/scenes/nfc_scene_device_info.c b/applications/main/nfc/scenes/nfc_scene_device_info.c index 9780ffe41..5d51c0816 100644 --- a/applications/main/nfc/scenes/nfc_scene_device_info.c +++ b/applications/main/nfc/scenes/nfc_scene_device_info.c @@ -52,6 +52,7 @@ void nfc_scene_device_info_on_enter(void* context) { } } else if( dev_data->protocol == NfcDeviceProtocolMifareClassic || + dev_data->protocol == NfcDeviceProtocolMifareDesfire || dev_data->protocol == NfcDeviceProtocolMifareUl) { furi_string_set(temp_str, nfc->dev->dev_data.parsed_data); } diff --git a/applications/main/nfc/scenes/nfc_scene_mf_desfire_read_success.c b/applications/main/nfc/scenes/nfc_scene_mf_desfire_read_success.c index 39030397f..633549eb5 100644 --- a/applications/main/nfc/scenes/nfc_scene_mf_desfire_read_success.c +++ b/applications/main/nfc/scenes/nfc_scene_mf_desfire_read_success.c @@ -20,35 +20,40 @@ void nfc_scene_mf_desfire_read_success_on_enter(void* context) { Widget* widget = nfc->widget; // Prepare string for data display - FuriString* temp_str = furi_string_alloc_printf("\e#MIFARE DESfire\n"); - furi_string_cat_printf(temp_str, "UID:"); - for(size_t i = 0; i < nfc_data->uid_len; i++) { - furi_string_cat_printf(temp_str, " %02X", nfc_data->uid[i]); - } - - uint32_t bytes_total = 1UL << (data->version.sw_storage >> 1); - uint32_t bytes_free = data->free_memory ? data->free_memory->bytes : 0; - furi_string_cat_printf(temp_str, "\n%lu", bytes_total); - if(data->version.sw_storage & 1) { - furi_string_push_back(temp_str, '+'); - } - furi_string_cat_printf(temp_str, " bytes, %lu bytes free\n", bytes_free); - - uint16_t n_apps = 0; - uint16_t n_files = 0; - for(MifareDesfireApplication* app = data->app_head; app; app = app->next) { - n_apps++; - for(MifareDesfireFile* file = app->file_head; file; file = file->next) { - n_files++; + FuriString* temp_str = NULL; + if(furi_string_size(nfc->dev->dev_data.parsed_data)) { + temp_str = furi_string_alloc_set(nfc->dev->dev_data.parsed_data); + } else { + temp_str = furi_string_alloc_printf("\e#MIFARE DESFire\n"); + furi_string_cat_printf(temp_str, "UID:"); + for(size_t i = 0; i < nfc_data->uid_len; i++) { + furi_string_cat_printf(temp_str, " %02X", nfc_data->uid[i]); + } + + uint32_t bytes_total = 1UL << (data->version.sw_storage >> 1); + uint32_t bytes_free = data->free_memory ? data->free_memory->bytes : 0; + furi_string_cat_printf(temp_str, "\n%lu", bytes_total); + if(data->version.sw_storage & 1) { + furi_string_push_back(temp_str, '+'); + } + furi_string_cat_printf(temp_str, " bytes, %lu bytes free\n", bytes_free); + + uint16_t n_apps = 0; + uint16_t n_files = 0; + for(MifareDesfireApplication* app = data->app_head; app; app = app->next) { + n_apps++; + for(MifareDesfireFile* file = app->file_head; file; file = file->next) { + n_files++; + } + } + furi_string_cat_printf(temp_str, "%d Application", n_apps); + if(n_apps != 1) { + furi_string_push_back(temp_str, 's'); + } + furi_string_cat_printf(temp_str, ", %d file", n_files); + if(n_files != 1) { + furi_string_push_back(temp_str, 's'); } - } - furi_string_cat_printf(temp_str, "%d Application", n_apps); - if(n_apps != 1) { - furi_string_push_back(temp_str, 's'); - } - furi_string_cat_printf(temp_str, ", %d file", n_files); - if(n_files != 1) { - furi_string_push_back(temp_str, 's'); } notification_message_block(nfc->notifications, &sequence_set_green_255); diff --git a/applications/main/nfc/scenes/nfc_scene_nfc_data_info.c b/applications/main/nfc/scenes/nfc_scene_nfc_data_info.c index 92ad7b56e..b44bb5e64 100644 --- a/applications/main/nfc/scenes/nfc_scene_nfc_data_info.c +++ b/applications/main/nfc/scenes/nfc_scene_nfc_data_info.c @@ -40,7 +40,7 @@ void nfc_scene_nfc_data_info_on_enter(void* context) { furi_string_cat_printf( temp_str, "\e#%s\n", nfc_mf_classic_type(dev_data->mf_classic_data.type)); } else if(protocol == NfcDeviceProtocolMifareDesfire) { - furi_string_cat_printf(temp_str, "\e#MIFARE DESfire\n"); + furi_string_cat_printf(temp_str, "\e#MIFARE DESFire\n"); } else { furi_string_cat_printf(temp_str, "\e#Unknown ISO tag\n"); } diff --git a/applications/main/nfc/scenes/nfc_scene_saved_menu.c b/applications/main/nfc/scenes/nfc_scene_saved_menu.c index e45dc4eb7..4573cdc45 100644 --- a/applications/main/nfc/scenes/nfc_scene_saved_menu.c +++ b/applications/main/nfc/scenes/nfc_scene_saved_menu.c @@ -148,6 +148,7 @@ bool nfc_scene_saved_menu_on_event(void* context, SceneManagerEvent event) { application_info_present = true; } else if( dev_data->protocol == NfcDeviceProtocolMifareClassic || + dev_data->protocol == NfcDeviceProtocolMifareDesfire || dev_data->protocol == NfcDeviceProtocolMifareUl) { application_info_present = nfc_supported_card_verify_and_parse(dev_data); } diff --git a/firmware/targets/f18/api_symbols.csv b/firmware/targets/f18/api_symbols.csv index 68248a6d2..08aa69133 100644 --- a/firmware/targets/f18/api_symbols.csv +++ b/firmware/targets/f18/api_symbols.csv @@ -1,5 +1,5 @@ entry,status,name,type,params -Version,+,27.0,, +Version,+,27.1,, Header,+,applications/services/bt/bt_service/bt.h,, Header,+,applications/services/cli/cli.h,, Header,+,applications/services/cli/cli_vcp.h,, @@ -1048,6 +1048,8 @@ Function,+,furi_hal_rtc_datetime_to_timestamp,uint32_t,FuriHalRtcDateTime* Function,-,furi_hal_rtc_deinit_early,void, Function,+,furi_hal_rtc_get_boot_mode,FuriHalRtcBootMode, Function,+,furi_hal_rtc_get_datetime,void,FuriHalRtcDateTime* +Function,+,furi_hal_rtc_get_days_per_month,uint8_t,"_Bool, uint8_t" +Function,+,furi_hal_rtc_get_days_per_year,uint16_t,uint16_t Function,+,furi_hal_rtc_get_fault_data,uint32_t, Function,+,furi_hal_rtc_get_heap_track_mode,FuriHalRtcHeapTrackMode, Function,+,furi_hal_rtc_get_locale_dateformat,FuriHalRtcLocaleDateFormat, @@ -1060,6 +1062,7 @@ Function,+,furi_hal_rtc_get_timestamp,uint32_t, Function,-,furi_hal_rtc_init,void, Function,-,furi_hal_rtc_init_early,void, Function,+,furi_hal_rtc_is_flag_set,_Bool,FuriHalRtcFlag +Function,+,furi_hal_rtc_is_leap_year,_Bool,uint16_t Function,+,furi_hal_rtc_reset_flag,void,FuriHalRtcFlag Function,+,furi_hal_rtc_set_boot_mode,void,FuriHalRtcBootMode Function,+,furi_hal_rtc_set_datetime,void,FuriHalRtcDateTime* diff --git a/firmware/targets/f7/api_symbols.csv b/firmware/targets/f7/api_symbols.csv index ccbaa5317..1055cb2bf 100644 --- a/firmware/targets/f7/api_symbols.csv +++ b/firmware/targets/f7/api_symbols.csv @@ -1,5 +1,5 @@ entry,status,name,type,params -Version,+,27.0,, +Version,+,27.1,, Header,+,applications/services/bt/bt_service/bt.h,, Header,+,applications/services/cli/cli.h,, Header,+,applications/services/cli/cli_vcp.h,, @@ -1313,6 +1313,8 @@ Function,+,furi_hal_rtc_datetime_to_timestamp,uint32_t,FuriHalRtcDateTime* Function,-,furi_hal_rtc_deinit_early,void, Function,+,furi_hal_rtc_get_boot_mode,FuriHalRtcBootMode, Function,+,furi_hal_rtc_get_datetime,void,FuriHalRtcDateTime* +Function,+,furi_hal_rtc_get_days_per_month,uint8_t,"_Bool, uint8_t" +Function,+,furi_hal_rtc_get_days_per_year,uint16_t,uint16_t Function,+,furi_hal_rtc_get_fault_data,uint32_t, Function,+,furi_hal_rtc_get_heap_track_mode,FuriHalRtcHeapTrackMode, Function,+,furi_hal_rtc_get_locale_dateformat,FuriHalRtcLocaleDateFormat, @@ -1325,6 +1327,7 @@ Function,+,furi_hal_rtc_get_timestamp,uint32_t, Function,-,furi_hal_rtc_init,void, Function,-,furi_hal_rtc_init_early,void, Function,+,furi_hal_rtc_is_flag_set,_Bool,FuriHalRtcFlag +Function,+,furi_hal_rtc_is_leap_year,_Bool,uint16_t Function,+,furi_hal_rtc_reset_flag,void,FuriHalRtcFlag Function,+,furi_hal_rtc_set_boot_mode,void,FuriHalRtcBootMode Function,+,furi_hal_rtc_set_datetime,void,FuriHalRtcDateTime* @@ -1991,6 +1994,8 @@ Function,-,mf_df_cat_key_settings,void,"MifareDesfireKeySettings*, FuriString*" Function,-,mf_df_cat_version,void,"MifareDesfireVersion*, FuriString*" Function,-,mf_df_check_card_type,_Bool,"uint8_t, uint8_t, uint8_t" Function,-,mf_df_clear,void,MifareDesfireData* +Function,-,mf_df_get_application,MifareDesfireApplication*,"MifareDesfireData*, const uint8_t[3]*" +Function,-,mf_df_get_file,MifareDesfireFile*,"MifareDesfireApplication*, uint8_t" Function,-,mf_df_parse_get_application_ids_response,_Bool,"uint8_t*, uint16_t, MifareDesfireApplication**" Function,-,mf_df_parse_get_file_ids_response,_Bool,"uint8_t*, uint16_t, MifareDesfireFile**" Function,-,mf_df_parse_get_file_settings_response,_Bool,"uint8_t*, uint16_t, MifareDesfireFile*" diff --git a/firmware/targets/f7/furi_hal/furi_hal_rtc.c b/firmware/targets/f7/furi_hal/furi_hal_rtc.c index 7bd45c35d..8dfe1a13e 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_rtc.c +++ b/firmware/targets/f7/furi_hal/furi_hal_rtc.c @@ -44,10 +44,8 @@ _Static_assert(sizeof(SystemReg) == 4, "SystemReg size mismatch"); #define FURI_HAL_RTC_SECONDS_PER_DAY (FURI_HAL_RTC_SECONDS_PER_HOUR * 24) #define FURI_HAL_RTC_MONTHS_COUNT 12 #define FURI_HAL_RTC_EPOCH_START_YEAR 1970 -#define FURI_HAL_RTC_IS_LEAP_YEAR(year) \ - ((((year) % 4 == 0) && ((year) % 100 != 0)) || ((year) % 400 == 0)) -static const uint8_t furi_hal_rtc_days_per_month[][FURI_HAL_RTC_MONTHS_COUNT] = { +static const uint8_t furi_hal_rtc_days_per_month[2][FURI_HAL_RTC_MONTHS_COUNT] = { {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}}; @@ -395,7 +393,7 @@ uint32_t furi_hal_rtc_datetime_to_timestamp(FuriHalRtcDateTime* datetime) { uint8_t leap_years = 0; for(uint16_t y = FURI_HAL_RTC_EPOCH_START_YEAR; y < datetime->year; y++) { - if(FURI_HAL_RTC_IS_LEAP_YEAR(y)) { + if(furi_hal_rtc_is_leap_year(y)) { leap_years++; } else { years++; @@ -406,10 +404,10 @@ uint32_t furi_hal_rtc_datetime_to_timestamp(FuriHalRtcDateTime* datetime) { ((years * furi_hal_rtc_days_per_year[0]) + (leap_years * furi_hal_rtc_days_per_year[1])) * FURI_HAL_RTC_SECONDS_PER_DAY; - uint8_t year_index = (FURI_HAL_RTC_IS_LEAP_YEAR(datetime->year)) ? 1 : 0; + bool leap_year = furi_hal_rtc_is_leap_year(datetime->year); - for(uint8_t m = 0; m < (datetime->month - 1); m++) { - timestamp += furi_hal_rtc_days_per_month[year_index][m] * FURI_HAL_RTC_SECONDS_PER_DAY; + for(uint8_t m = 1; m < datetime->month; m++) { + timestamp += furi_hal_rtc_get_days_per_month(leap_year, m) * FURI_HAL_RTC_SECONDS_PER_DAY; } timestamp += (datetime->day - 1) * FURI_HAL_RTC_SECONDS_PER_DAY; @@ -419,3 +417,15 @@ uint32_t furi_hal_rtc_datetime_to_timestamp(FuriHalRtcDateTime* datetime) { return timestamp; } + +uint16_t furi_hal_rtc_get_days_per_year(uint16_t year) { + return furi_hal_rtc_days_per_year[furi_hal_rtc_is_leap_year(year) ? 1 : 0]; +} + +bool furi_hal_rtc_is_leap_year(uint16_t year) { + return (((year) % 4 == 0) && ((year) % 100 != 0)) || ((year) % 400 == 0); +} + +uint8_t furi_hal_rtc_get_days_per_month(bool leap_year, uint8_t month) { + return furi_hal_rtc_days_per_month[leap_year ? 1 : 0][month - 1]; +} diff --git a/firmware/targets/furi_hal_include/furi_hal_rtc.h b/firmware/targets/furi_hal_include/furi_hal_rtc.h index e706c5c76..186d22f07 100644 --- a/firmware/targets/furi_hal_include/furi_hal_rtc.h +++ b/firmware/targets/furi_hal_include/furi_hal_rtc.h @@ -255,6 +255,30 @@ uint32_t furi_hal_rtc_get_timestamp(); */ uint32_t furi_hal_rtc_datetime_to_timestamp(FuriHalRtcDateTime* datetime); +/** Gets the number of days in the year according to the Gregorian calendar. + * + * @param year Input year. + * + * @return number of days in `year`. + */ +uint16_t furi_hal_rtc_get_days_per_year(uint16_t year); + +/** Check if a year a leap year in the Gregorian calendar. + * + * @param year Input year. + * + * @return true if `year` is a leap year. + */ +bool furi_hal_rtc_is_leap_year(uint16_t year); + +/** Get the number of days in the month. + * + * @param leap_year true to calculate based on leap years + * @param month month to check, where 1 = January + * @return the number of days in the month + */ +uint8_t furi_hal_rtc_get_days_per_month(bool leap_year, uint8_t month); + #ifdef __cplusplus } #endif diff --git a/lib/nfc/nfc_worker.c b/lib/nfc/nfc_worker.c index 28a1f6827..daa8fee59 100644 --- a/lib/nfc/nfc_worker.c +++ b/lib/nfc/nfc_worker.c @@ -219,6 +219,19 @@ static bool nfc_worker_read_mf_desfire(NfcWorker* nfc_worker, FuriHalNfcTxRxCont do { if(!furi_hal_nfc_detect(&nfc_worker->dev_data->nfc_data, 300)) break; if(!mf_df_read_card(tx_rx, data)) break; + FURI_LOG_I(TAG, "Trying to parse a supported card ..."); + + // The model for parsing DESFire is a little different to other cards; + // we don't have parsers to provide encryption keys, so we can read the + // data normally, and then pass the read data to a parser. + // + // There are fully-protected DESFire cards, but providing keys for them + // is difficult (and unnessesary for many transit cards). + for(size_t i = 0; i < NfcSupportedCardTypeEnd; i++) { + if(nfc_supported_card[i].protocol == NfcDeviceProtocolMifareDesfire) { + if(nfc_supported_card[i].parse(nfc_worker->dev_data)) break; + } + } read_success = true; } while(false); diff --git a/lib/nfc/parsers/nfc_supported_card.c b/lib/nfc/parsers/nfc_supported_card.c index fc2dc34e0..153d4d3c5 100644 --- a/lib/nfc/parsers/nfc_supported_card.c +++ b/lib/nfc/parsers/nfc_supported_card.c @@ -6,6 +6,7 @@ #include "troika_4k_parser.h" #include "two_cities.h" #include "all_in_one.h" +#include "opal.h" NfcSupportedCard nfc_supported_card[NfcSupportedCardTypeEnd] = { [NfcSupportedCardTypePlantain] = @@ -50,6 +51,14 @@ NfcSupportedCard nfc_supported_card[NfcSupportedCardTypeEnd] = { .read = all_in_one_parser_read, .parse = all_in_one_parser_parse, }, + [NfcSupportedCardTypeOpal] = + { + .protocol = NfcDeviceProtocolMifareDesfire, + .verify = stub_parser_verify_read, + .read = stub_parser_verify_read, + .parse = opal_parser_parse, + }, + }; bool nfc_supported_card_verify_and_parse(NfcDeviceData* dev_data) { @@ -65,3 +74,9 @@ bool nfc_supported_card_verify_and_parse(NfcDeviceData* dev_data) { return card_parsed; } + +bool stub_parser_verify_read(NfcWorker* nfc_worker, FuriHalNfcTxRxContext* tx_rx) { + UNUSED(nfc_worker); + UNUSED(tx_rx); + return false; +} diff --git a/lib/nfc/parsers/nfc_supported_card.h b/lib/nfc/parsers/nfc_supported_card.h index 4af59aded..877bda737 100644 --- a/lib/nfc/parsers/nfc_supported_card.h +++ b/lib/nfc/parsers/nfc_supported_card.h @@ -11,6 +11,7 @@ typedef enum { NfcSupportedCardTypeTroika4K, NfcSupportedCardTypeTwoCities, NfcSupportedCardTypeAllInOne, + NfcSupportedCardTypeOpal, NfcSupportedCardTypeEnd, } NfcSupportedCardType; @@ -31,3 +32,8 @@ typedef struct { extern NfcSupportedCard nfc_supported_card[NfcSupportedCardTypeEnd]; bool nfc_supported_card_verify_and_parse(NfcDeviceData* dev_data); + +// stub_parser_verify_read does nothing, and always reports that it does not +// support the card. This is needed for DESFire card parsers which can't +// provide keys, and only use NfcSupportedCard->parse. +bool stub_parser_verify_read(NfcWorker* nfc_worker, FuriHalNfcTxRxContext* tx_rx); diff --git a/lib/nfc/parsers/opal.c b/lib/nfc/parsers/opal.c new file mode 100644 index 000000000..b5ca37eb6 --- /dev/null +++ b/lib/nfc/parsers/opal.c @@ -0,0 +1,204 @@ +/* + * opal.c - Parser for Opal card (Sydney, Australia). + * + * Copyright 2023 Michael Farrell + * + * This will only read "standard" MIFARE DESFire-based Opal cards. Free travel + * cards (including School Opal cards, veteran, vision-impaired persons and + * TfNSW employees' cards) and single-trip tickets are MIFARE Ultralight C + * cards and not supported. + * + * Reference: https://github.com/metrodroid/metrodroid/wiki/Opal + * + * Note: The card values are all little-endian (like Flipper), but the above + * reference was originally written based on Java APIs, which are big-endian. + * This implementation presumes a little-endian system. + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include "nfc_supported_card.h" +#include "opal.h" + +#include +#include +#include + +#include + +static const uint8_t opal_aid[3] = {0x31, 0x45, 0x53}; +static const char* opal_modes[5] = + {"Rail / Metro", "Ferry / Light Rail", "Bus", "Unknown mode", "Manly Ferry"}; +static const char* opal_usages[14] = { + "New / Unused", + "Tap on: new journey", + "Tap on: transfer from same mode", + "Tap on: transfer from other mode", + "", // Manly Ferry: new journey + "", // Manly Ferry: transfer from ferry + "", // Manly Ferry: transfer from other + "Tap off: distance fare", + "Tap off: flat fare", + "Automated tap off: failed to tap off", + "Tap off: end of trip without start", + "Tap off: reversal", + "Tap on: rejected", + "Unknown usage", +}; + +// Opal file 0x7 structure. Assumes a little-endian CPU. +typedef struct __attribute__((__packed__)) { + uint32_t serial : 32; + uint8_t check_digit : 4; + bool blocked : 1; + uint16_t txn_number : 16; + int32_t balance : 21; + uint16_t days : 15; + uint16_t minutes : 11; + uint8_t mode : 3; + uint16_t usage : 4; + bool auto_topup : 1; + uint8_t weekly_journeys : 4; + uint16_t checksum : 16; +} OpalFile; + +static_assert(sizeof(OpalFile) == 16); + +// Converts an Opal timestamp to FuriHalRtcDateTime. +// +// Opal measures days since 1980-01-01 and minutes since midnight, and presumes +// all days are 1440 minutes. +void opal_date_time_to_furi(uint16_t days, uint16_t minutes, FuriHalRtcDateTime* out) { + if(!out) return; + uint16_t diy; + out->year = 1980; + out->month = 1; + // 1980-01-01 is a Tuesday + out->weekday = ((days + 1) % 7) + 1; + out->hour = minutes / 60; + out->minute = minutes % 60; + out->second = 0; + + // What year is it? + for(;;) { + diy = furi_hal_rtc_get_days_per_year(out->year); + if(days < diy) break; + days -= diy; + out->year++; + } + + // 1-index the day of the year + days++; + // What month is it? + bool is_leap = furi_hal_rtc_is_leap_year(out->year); + + for(;;) { + uint8_t dim = furi_hal_rtc_get_days_per_month(is_leap, out->month); + if(days <= dim) break; + days -= dim; + out->month++; + } + + out->day = days; +} + +bool opal_parser_parse(NfcDeviceData* dev_data) { + if(dev_data->protocol != NfcDeviceProtocolMifareDesfire) { + return false; + } + + MifareDesfireApplication* app = mf_df_get_application(&dev_data->mf_df_data, &opal_aid); + if(app == NULL) { + return false; + } + MifareDesfireFile* f = mf_df_get_file(app, 0x07); + if(f == NULL || f->type != MifareDesfireFileTypeStandard || f->settings.data.size != 16 || + !f->contents) { + return false; + } + + OpalFile* o = (OpalFile*)f->contents; + + uint8_t serial2 = o->serial / 10000000; + uint16_t serial3 = (o->serial / 1000) % 10000; + uint16_t serial4 = (o->serial % 1000); + + if(o->check_digit > 9) { + return false; + } + + char* sign = ""; + if(o->balance < 0) { + // Negative balance. Make this a positive value again and record the + // sign separately, because then we can handle balances of -99..-1 + // cents, as the "dollars" division below would result in a positive + // zero value. + o->balance = abs(o->balance); + sign = "-"; + } + uint8_t cents = o->balance % 100; + int32_t dollars = o->balance / 100; + + FuriHalRtcDateTime timestamp; + opal_date_time_to_furi(o->days, o->minutes, ×tamp); + + if(o->mode >= 3) { + // 3..7 are "reserved", but we use 4 to indicate the Manly Ferry. + o->mode = 3; + } + + if(o->usage >= 4 && o->usage <= 6) { + // Usages 4..6 associated with the Manly Ferry, which correspond to + // usages 1..3 for other modes. + o->usage -= 3; + o->mode = 4; + } + + const char* mode_str = (o->mode <= 4 ? opal_modes[o->mode] : opal_modes[3]); + const char* usage_str = (o->usage <= 12 ? opal_usages[o->usage] : opal_usages[13]); + + furi_string_printf( + dev_data->parsed_data, + "\e#Opal: $%s%ld.%02hu\n3085 22%02hhu %04hu %03hu%01hhu\n%s, %s\n", + sign, + dollars, + cents, + serial2, + serial3, + serial4, + o->check_digit, + mode_str, + usage_str); + FuriString* timestamp_str = furi_string_alloc(); + locale_format_date(timestamp_str, ×tamp, locale_get_date_format(), "-"); + furi_string_cat(dev_data->parsed_data, timestamp_str); + furi_string_cat_str(dev_data->parsed_data, " at "); + + locale_format_time(timestamp_str, ×tamp, locale_get_time_format(), false); + furi_string_cat(dev_data->parsed_data, timestamp_str); + + furi_string_free(timestamp_str); + furi_string_cat_printf( + dev_data->parsed_data, + "\nWeekly journeys: %hhu, Txn #%hu\n", + o->weekly_journeys, + o->txn_number); + + if(o->auto_topup) { + furi_string_cat_str(dev_data->parsed_data, "Auto-topup enabled\n"); + } + if(o->blocked) { + furi_string_cat_str(dev_data->parsed_data, "Card blocked\n"); + } + return true; +} diff --git a/lib/nfc/parsers/opal.h b/lib/nfc/parsers/opal.h new file mode 100644 index 000000000..42caf9a17 --- /dev/null +++ b/lib/nfc/parsers/opal.h @@ -0,0 +1,5 @@ +#pragma once + +#include "nfc_supported_card.h" + +bool opal_parser_parse(NfcDeviceData* dev_data); diff --git a/lib/nfc/protocols/mifare_desfire.c b/lib/nfc/protocols/mifare_desfire.c index 23308ae95..e0ead737f 100644 --- a/lib/nfc/protocols/mifare_desfire.c +++ b/lib/nfc/protocols/mifare_desfire.c @@ -42,6 +42,30 @@ void mf_df_clear(MifareDesfireData* data) { data->app_head = NULL; } +MifareDesfireApplication* mf_df_get_application(MifareDesfireData* data, const uint8_t (*aid)[3]) { + if(!data) { + return NULL; + } + for(MifareDesfireApplication* app = data->app_head; app; app = app->next) { + if(memcmp(aid, app->id, 3) == 0) { + return app; + } + } + return NULL; +} + +MifareDesfireFile* mf_df_get_file(MifareDesfireApplication* app, uint8_t id) { + if(!app) { + return NULL; + } + for(MifareDesfireFile* file = app->file_head; file; file = file->next) { + if(file->id == id) { + return file; + } + } + return NULL; +} + void mf_df_cat_data(MifareDesfireData* data, FuriString* out) { mf_df_cat_card_info(data, out); for(MifareDesfireApplication* app = data->app_head; app; app = app->next) { diff --git a/lib/nfc/protocols/mifare_desfire.h b/lib/nfc/protocols/mifare_desfire.h index 963a18f58..3dc7c4c2a 100644 --- a/lib/nfc/protocols/mifare_desfire.h +++ b/lib/nfc/protocols/mifare_desfire.h @@ -130,6 +130,9 @@ void mf_df_cat_file(MifareDesfireFile* file, FuriString* out); bool mf_df_check_card_type(uint8_t ATQA0, uint8_t ATQA1, uint8_t SAK); +MifareDesfireApplication* mf_df_get_application(MifareDesfireData* data, const uint8_t (*aid)[3]); +MifareDesfireFile* mf_df_get_file(MifareDesfireApplication* app, uint8_t id); + uint16_t mf_df_prepare_get_version(uint8_t* dest); bool mf_df_parse_get_version_response(uint8_t* buf, uint16_t len, MifareDesfireVersion* out); From 23ff7d913a145bffb2007702b1d3262db1f5f1c0 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Mon, 29 May 2023 17:47:45 +0300 Subject: [PATCH 11/52] Update UART Terminal --- .../external/uart_terminal/scenes/uart_terminal_scene_start.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/applications/external/uart_terminal/scenes/uart_terminal_scene_start.c b/applications/external/uart_terminal/scenes/uart_terminal_scene_start.c index d4de748b6..60411b34c 100644 --- a/applications/external/uart_terminal/scenes/uart_terminal_scene_start.c +++ b/applications/external/uart_terminal/scenes/uart_terminal_scene_start.c @@ -28,7 +28,7 @@ const UART_TerminalItem items[NUM_MENU_ITEMS] = { 9, {"115200", "2400", "9600", "19200", "38400", "57600", "230400", "460800", "921600"}, NO_ARGS, - FOCUS_CONSOLE_TOGGLE, + FOCUS_CONSOLE_END, NO_TIP}, {"Send command", {""}, 1, {""}, INPUT_ARGS, FOCUS_CONSOLE_END, NO_TIP}, {"Send AT command", {""}, 1, {"AT"}, INPUT_ARGS, FOCUS_CONSOLE_END, NO_TIP}, From b17125c65caeae8c8191c2fd30016254bacd1536 Mon Sep 17 00:00:00 2001 From: gid9798 <30450294+gid9798@users.noreply.github.com> Date: Mon, 29 May 2023 17:54:01 +0300 Subject: [PATCH 12/52] Desktop Clock: some improvements --- applications/services/desktop/desktop.c | 57 +++++++++++++------------ 1 file changed, 30 insertions(+), 27 deletions(-) diff --git a/applications/services/desktop/desktop.c b/applications/services/desktop/desktop.c index bad120abc..88469af0f 100644 --- a/applications/services/desktop/desktop.c +++ b/applications/services/desktop/desktop.c @@ -49,11 +49,32 @@ static void desktop_dummy_mode_icon_draw_callback(Canvas* canvas, void* context) canvas_draw_icon(canvas, 0, 0, &I_GameMode_11x8); } -static void desktop_toggle_clock_view(Desktop* desktop, bool is_enabled) { +static void desktop_clock_upd_time(Desktop* desktop, bool forced) { furi_assert(desktop); - // clock type upd after 1 minute - desktop->clock_type = (locale_get_time_format() == LocaleTimeFormat24h); + FuriHalRtcDateTime curr_dt; + furi_hal_rtc_get_datetime(&curr_dt); + + if(forced) { + desktop->clock_type = (locale_get_time_format() == LocaleTimeFormat24h); + } + + if(forced || (desktop->minute != curr_dt.minute)) { + if(desktop->clock_type) { + desktop->hour = curr_dt.hour; + } else { + desktop->hour = (curr_dt.hour > 12) ? curr_dt.hour - 12 : + ((curr_dt.hour == 0) ? 12 : curr_dt.hour); + } + desktop->minute = curr_dt.minute; + view_port_update(desktop->clock_viewport); + } +} + +static void desktop_clock_toggle_view(Desktop* desktop, bool is_enabled) { + furi_assert(desktop); + + desktop_clock_upd_time(desktop, true); if(is_enabled) { // && !furi_timer_is_running(desktop->update_clock_timer)) { furi_timer_start(desktop->update_clock_timer, furi_ms_to_ticks(1000)); @@ -141,7 +162,7 @@ static bool desktop_custom_event_callback(void* context, uint32_t event) { // locking and unlocking DESKTOP_SETTINGS_LOAD(&desktop->settings); - desktop_toggle_clock_view(desktop, desktop->settings.display_clock); + desktop_clock_toggle_view(desktop, desktop->settings.display_clock); desktop_auto_lock_arm(desktop); return true; @@ -208,24 +229,12 @@ static void desktop_auto_lock_inhibit(Desktop* desktop) { } } -static void desktop_update_clock_timer_callback(void* context) { +static void desktop_clock_timer_callback(void* context) { furi_assert(context); Desktop* desktop = context; if(gui_get_count_of_enabled_view_port_in_layer(desktop->gui, GuiLayerStatusBarLeft) < 6) { - FuriHalRtcDateTime curr_dt; - furi_hal_rtc_get_datetime(&curr_dt); - - if(desktop->minute != curr_dt.minute) { - if(desktop->clock_type) { - desktop->hour = curr_dt.hour; - } else { - desktop->hour = (curr_dt.hour > 12) ? curr_dt.hour - 12 : - ((curr_dt.hour == 0) ? 12 : curr_dt.hour); - } - desktop->minute = curr_dt.minute; - view_port_update(desktop->clock_viewport); - } + desktop_clock_upd_time(desktop, false); view_port_enabled_set(desktop->clock_viewport, true); } else { @@ -424,18 +433,12 @@ Desktop* desktop_alloc() { desktop->status_pubsub = furi_pubsub_alloc(); desktop->update_clock_timer = - furi_timer_alloc(desktop_update_clock_timer_callback, FuriTimerTypePeriodic, desktop); + furi_timer_alloc(desktop_clock_timer_callback, FuriTimerTypePeriodic, desktop); FuriHalRtcDateTime curr_dt; furi_hal_rtc_get_datetime(&curr_dt); - if(desktop->clock_type) { - desktop->hour = curr_dt.hour; - } else { - desktop->hour = (curr_dt.hour > 12) ? curr_dt.hour - 12 : - ((curr_dt.hour == 0) ? 12 : curr_dt.hour); - } - desktop->minute = curr_dt.minute; + desktop_clock_upd_time(desktop, true); furi_record_create(RECORD_DESKTOP, desktop); @@ -483,7 +486,7 @@ int32_t desktop_srv(void* p) { view_port_enabled_set(desktop->dummy_mode_icon_viewport, desktop->settings.dummy_mode); - desktop_toggle_clock_view(desktop, desktop->settings.display_clock); + desktop_clock_toggle_view(desktop, desktop->settings.display_clock); desktop_main_set_dummy_mode_state(desktop->main_view, desktop->settings.dummy_mode); animation_manager_set_dummy_mode_state( From 3de856f8d53ed45b56dd21674927898552bbdd2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=82=E3=81=8F?= Date: Tue, 30 May 2023 01:05:57 +0900 Subject: [PATCH 13/52] [FL-3295] FuriHal: add bus abstraction (#2614) * FuriHal: add bus abstraction and port some subsystem to it * Make PVS happy, cleanup code * Update API symbols for f18 * F18: backport bus changes from f7 * Revert to STOP2 sleep mode * Fix downgrading the firmware via updater * Port iButton TIM1 to furi_hal_bus * Port Infrared TIM1 and TIM2 to furi_hal_bus * Just enable the timer bus * Port furi_hal_pwm to bus API * Fix include statement * Port furi_hal_rfid to bus API * Port furi_hal_subghz and others to bus API * Remove unneeded include * Improve furi_hal_infrared defines * Reset LPTIM1 via furi_hal_bus API * Crash when trying to enable an already enabled peripheral * Better defines * Improved checks * Lots of macro wrappers * Copy spi changes for f18 * Fix crashes in LFRFID system * Fix crashes in NFC system * Improve comments * Create FuriHalBus.md * Update FuriHalBus.md * Fix crash when launching updater * Documentation: couple small fixes in FuriHalBus * FuriHal: fix copypaste in furi_hal_rfid_tim_reset * FuriHal: reset radio core related peripherals on restart * FuriHalBus: is enabled routine and bug fix for uart * RFID HAL: accomodate furi hal bus Co-authored-by: Georgii Surkov Co-authored-by: Georgii Surkov <37121527+gsurkov@users.noreply.github.com> Co-authored-by: SG --- .../scenes/lfrfid_debug_app_scene_tune.c | 5 +- documentation/FuriHalBus.md | 113 +++++++ firmware/targets/f18/api_symbols.csv | 13 +- firmware/targets/f18/furi_hal/furi_hal.c | 5 + .../targets/f18/furi_hal/furi_hal_resources.c | 14 + .../f18/furi_hal/furi_hal_spi_config.c | 31 +- firmware/targets/f7/api_symbols.csv | 27 +- firmware/targets/f7/furi_hal/furi_hal.c | 5 + firmware/targets/f7/furi_hal/furi_hal_bt.c | 11 + firmware/targets/f7/furi_hal/furi_hal_bus.c | 302 ++++++++++++++++++ firmware/targets/f7/furi_hal/furi_hal_bus.h | 112 +++++++ firmware/targets/f7/furi_hal/furi_hal_clock.c | 84 ----- .../targets/f7/furi_hal/furi_hal_crypto.c | 10 +- firmware/targets/f7/furi_hal/furi_hal_dma.c | 14 + firmware/targets/f7/furi_hal/furi_hal_dma.h | 15 + firmware/targets/f7/furi_hal/furi_hal_flash.c | 22 +- .../targets/f7/furi_hal/furi_hal_i2c_config.c | 32 +- .../targets/f7/furi_hal/furi_hal_ibutton.c | 12 +- .../targets/f7/furi_hal/furi_hal_idle_timer.h | 8 +- .../targets/f7/furi_hal/furi_hal_infrared.c | 300 +++++++++-------- firmware/targets/f7/furi_hal/furi_hal_pwm.c | 19 +- .../targets/f7/furi_hal/furi_hal_random.c | 9 +- .../targets/f7/furi_hal/furi_hal_resources.c | 14 + firmware/targets/f7/furi_hal/furi_hal_rfid.c | 109 ++----- firmware/targets/f7/furi_hal/furi_hal_rfid.h | 60 +--- firmware/targets/f7/furi_hal/furi_hal_rtc.c | 2 +- .../targets/f7/furi_hal/furi_hal_speaker.c | 9 +- .../targets/f7/furi_hal/furi_hal_spi_config.c | 31 +- .../targets/f7/furi_hal/furi_hal_spi_types.h | 2 - .../targets/f7/furi_hal/furi_hal_subghz.c | 9 +- firmware/targets/f7/furi_hal/furi_hal_uart.c | 20 +- firmware/targets/f7/furi_hal/furi_hal_usb.c | 9 + firmware/targets/f7/src/update.c | 6 + firmware/targets/furi_hal_include/furi_hal.h | 2 + .../furi_hal_include/furi_hal_random.h | 3 + lib/digital_signal/digital_signal.c | 4 +- lib/lfrfid/lfrfid_raw_worker.c | 4 +- lib/lfrfid/lfrfid_worker_modes.c | 9 +- lib/lfrfid/tools/t5577.c | 9 +- lib/nfc/parsers/opal.c | 4 +- lib/pulse_reader/pulse_reader.c | 3 + 41 files changed, 944 insertions(+), 528 deletions(-) create mode 100644 documentation/FuriHalBus.md create mode 100644 firmware/targets/f7/furi_hal/furi_hal_bus.c create mode 100644 firmware/targets/f7/furi_hal/furi_hal_bus.h create mode 100644 firmware/targets/f7/furi_hal/furi_hal_dma.c create mode 100644 firmware/targets/f7/furi_hal/furi_hal_dma.h diff --git a/applications/debug/lfrfid_debug/scenes/lfrfid_debug_app_scene_tune.c b/applications/debug/lfrfid_debug/scenes/lfrfid_debug_app_scene_tune.c index c7f3bf24f..74c53ae6d 100644 --- a/applications/debug/lfrfid_debug/scenes/lfrfid_debug_app_scene_tune.c +++ b/applications/debug/lfrfid_debug/scenes/lfrfid_debug_app_scene_tune.c @@ -14,9 +14,7 @@ void lfrfid_debug_scene_tune_on_enter(void* context) { furi_hal_rfid_comp_set_callback(comparator_trigger_callback, app); furi_hal_rfid_comp_start(); - furi_hal_rfid_pins_read(); - furi_hal_rfid_tim_read(125000, 0.5); - furi_hal_rfid_tim_read_start(); + furi_hal_rfid_tim_read_start(125000, 0.5); view_dispatcher_switch_to_view(app->view_dispatcher, LfRfidDebugViewTune); } @@ -43,6 +41,5 @@ void lfrfid_debug_scene_tune_on_exit(void* context) { furi_hal_gpio_init_simple(&gpio_ext_pa7, GpioModeAnalog); furi_hal_rfid_tim_read_stop(); - furi_hal_rfid_tim_reset(); furi_hal_rfid_pins_reset(); } diff --git a/documentation/FuriHalBus.md b/documentation/FuriHalBus.md new file mode 100644 index 000000000..5c754018b --- /dev/null +++ b/documentation/FuriHalBus.md @@ -0,0 +1,113 @@ +# Using FuriHalBus API + +## Basic info + +On system startup, most of the peripheral devices are under reset and not clocked by default. This is done to reduce power consumption and to guarantee that the device will always be in the same state before use. +Some crucial peripherals are enabled right away by the system, others must be explicitly enabled by the user code. + +**NOTE:** Here and afterwards the word *"system"* refers to any code belonging to the operating system, hardware drivers or built-in applications. + +To **ENABLE** a peripheral, call `furi_hal_bus_enable()`. At the time of the call, the peripheral in question MUST be disabled, otherwise a crash will occur to indicate improper use. This means that any given peripheral cannot be enabled twice or more without disabling it first. + +To **DISABLE** a peripheral, call `furi_hal_bus_disable()`. Likewise, the peripheral in question MUST be enabled, otherwise a crash will occur. + +To **RESET** a peripheral, call `furi_hal_bus_reset()`. The peripheral in question MUST be enabled, otherwise a crash will occur. This method is used whenever it is necessary to reset all the peripheral's registers to their initial states without disabling it. + +## Peripherals + +Built-in peripherals are divided into three categories: +- Enabled by the system on startup, never disabled; +- Enabled and disabled by the system on demand; +- Enabled and disabled by the user code. + +### Always-on peripherals + +Below is the list of peripherals that are enabled by the system. The user code must NEVER attempt to disable them. If a corresponding API is provided, the user code must employ it in order to access the peripheral. + +*Table 1* - Peripherals enabled by the system + +| Peripheral | Enabled at | +| :-----------: | :-----------------------: | +| DMA1 | `furi_hal_dma.c` | +| DMA2 | -- | +| DMAMUX | -- | +| GPIOA | `furi_hal_resources.c` | +| GPIOB | -- | +| GPIOC | -- | +| GPIOD | -- | +| GPIOE | -- | +| GPIOH | -- | +| PKA | `furi_hal_bt.c` | +| AES2 | -- | +| HSEM | -- | +| IPCC | -- | +| FLASH | enabled by hardware | + +### On-demand system peripherals + +Below is the list of peripherals that are enabled and disabled by the system. The user code must avoid using them directly, preferring the respective APIs instead. + +When not using the API, these peripherals MUST be enabled by the user code and then disabled when not needed anymore. + +*Table 2* - Peripherals enabled and disabled by the system + +| Peripheral | API header file | +| :-----------: | :-------------------: | +| RNG | `furi_hal_random.h` | +| SPI1 | `furi_hal_spi.h` | +| SPI2 | -- | +| I2C1 | `furi_hal_i2c.h` | +| I2C3 | -- | +| USART1 | `furi_hal_uart.h` | +| LPUART1 | -- | +| USB | `furi_hal_usb.h` | + +### On-demand shared peripherals + +Below is the list of peripherals that are not enabled by default and MUST be enabled by the user code each time it accesses them. + +Note that some of these peripherals may also be used by the system to implement its certain features. +The system will take over any given peripheral only when the respective feature is in use. + +*Table 3* - Peripherals enabled and disabled by user + +| Peripheral | System | Purpose | +| :-----------: | :-------: | ------------------------------------- | +| CRC | | | +| TSC | | | +| ADC | | | +| QUADSPI | | | +| TIM1 | yes | subghz, lfrfid, nfc, infrared, etc... | +| TIM2 | yes | -- | +| TIM16 | yes | speaker | +| TIM17 | | | +| LPTIM1 | yes | tickless idle timer | +| LPTIM2 | yes | pwm | +| SAI1 | | | +| LCD | | | + + +## DMA + +The DMA1,2 peripherals are a special case in that they have multiple independent channels. Some of the channels may be in use by the system. + +Below is the list of DMA channels and their usage by the system. + +*Table 4* - DMA channels + +| DMA | Channel | System | Purpose | +| :---: | :-------: | :-------: | ------------------------- | +| DMA1 | 1 | yes | digital signal | +| -- | 2 | yes | -- | +| -- | 3 | | | +| -- | 4 | yes | pulse reader | +| -- | 5 | | | +| -- | 6 | | | +| -- | 7 | | | +| DMA2 | 1 | yes | infrared, lfrfid, subghz | +| -- | 2 | yes | -- | +| -- | 3 | yes | SPI | +| -- | 4 | yes | SPI | +| -- | 5 | | | +| -- | 6 | | | +| -- | 7 | | | diff --git a/firmware/targets/f18/api_symbols.csv b/firmware/targets/f18/api_symbols.csv index 08aa69133..92c8697aa 100644 --- a/firmware/targets/f18/api_symbols.csv +++ b/firmware/targets/f18/api_symbols.csv @@ -1,5 +1,5 @@ entry,status,name,type,params -Version,+,27.1,, +Version,+,28.0,, Header,+,applications/services/bt/bt_service/bt.h,, Header,+,applications/services/cli/cli.h,, Header,+,applications/services/cli/cli_vcp.h,, @@ -40,8 +40,10 @@ Header,-,firmware/targets/f18/furi_hal/furi_hal_power_calibration.h,, Header,+,firmware/targets/f18/furi_hal/furi_hal_resources.h,, Header,+,firmware/targets/f18/furi_hal/furi_hal_spi_config.h,, Header,+,firmware/targets/f18/furi_hal/furi_hal_target_hw.h,, +Header,+,firmware/targets/f7/furi_hal/furi_hal_bus.h,, Header,+,firmware/targets/f7/furi_hal/furi_hal_clock.h,, Header,+,firmware/targets/f7/furi_hal/furi_hal_console.h,, +Header,+,firmware/targets/f7/furi_hal/furi_hal_dma.h,, Header,+,firmware/targets/f7/furi_hal/furi_hal_flash.h,, Header,+,firmware/targets/f7/furi_hal/furi_hal_gpio.h,, Header,+,firmware/targets/f7/furi_hal/furi_hal_i2c_config.h,, @@ -873,6 +875,12 @@ Function,+,furi_hal_bt_stop_tone_tx,void, Function,+,furi_hal_bt_unlock_core2,void, Function,+,furi_hal_bt_update_battery_level,void,uint8_t Function,+,furi_hal_bt_update_power_state,void, +Function,+,furi_hal_bus_deinit_early,void, +Function,+,furi_hal_bus_disable,void,FuriHalBus +Function,+,furi_hal_bus_enable,void,FuriHalBus +Function,+,furi_hal_bus_init_early,void, +Function,+,furi_hal_bus_is_enabled,_Bool,FuriHalBus +Function,+,furi_hal_bus_reset,void,FuriHalBus Function,+,furi_hal_cdc_get_ctrl_line_state,uint8_t,uint8_t Function,+,furi_hal_cdc_get_port_settings,usb_cdc_line_coding*,uint8_t Function,+,furi_hal_cdc_receive,int32_t,"uint8_t, uint8_t*, uint16_t" @@ -915,6 +923,8 @@ Function,+,furi_hal_debug_disable,void, Function,+,furi_hal_debug_enable,void, Function,+,furi_hal_debug_is_gdb_session_active,_Bool, Function,-,furi_hal_deinit_early,void, +Function,+,furi_hal_dma_deinit_early,void, +Function,+,furi_hal_dma_init_early,void, Function,-,furi_hal_flash_erase,void,uint8_t Function,-,furi_hal_flash_get_base,size_t, Function,-,furi_hal_flash_get_cycles_count,size_t, @@ -1033,6 +1043,7 @@ Function,+,furi_hal_pwm_start,void,"FuriHalPwmOutputId, uint32_t, uint8_t" Function,+,furi_hal_pwm_stop,void,FuriHalPwmOutputId Function,+,furi_hal_random_fill_buf,void,"uint8_t*, uint32_t" Function,+,furi_hal_random_get,uint32_t, +Function,+,furi_hal_random_init,void, Function,+,furi_hal_region_get,const FuriHalRegion*, Function,+,furi_hal_region_get_band,const FuriHalRegionBand*,uint32_t Function,+,furi_hal_region_get_name,const char*, diff --git a/firmware/targets/f18/furi_hal/furi_hal.c b/firmware/targets/f18/furi_hal/furi_hal.c index 4064dd647..5f4e6165d 100644 --- a/firmware/targets/f18/furi_hal/furi_hal.c +++ b/firmware/targets/f18/furi_hal/furi_hal.c @@ -9,6 +9,8 @@ void furi_hal_init_early() { furi_hal_cortex_init_early(); furi_hal_clock_init_early(); + furi_hal_bus_init_early(); + furi_hal_dma_init_early(); furi_hal_resources_init_early(); furi_hal_os_init(); furi_hal_spi_config_init_early(); @@ -22,12 +24,15 @@ void furi_hal_deinit_early() { furi_hal_i2c_deinit_early(); furi_hal_spi_config_deinit_early(); furi_hal_resources_deinit_early(); + furi_hal_dma_deinit_early(); + furi_hal_bus_deinit_early(); furi_hal_clock_deinit_early(); } void furi_hal_init() { furi_hal_mpu_init(); furi_hal_clock_init(); + furi_hal_random_init(); furi_hal_console_init(); furi_hal_rtc_init(); furi_hal_interrupt_init(); diff --git a/firmware/targets/f18/furi_hal/furi_hal_resources.c b/firmware/targets/f18/furi_hal/furi_hal_resources.c index 6db483dbc..32c9b619c 100644 --- a/firmware/targets/f18/furi_hal/furi_hal_resources.c +++ b/firmware/targets/f18/furi_hal/furi_hal_resources.c @@ -1,4 +1,5 @@ #include +#include #include #include @@ -118,6 +119,13 @@ static void furi_hal_resources_init_input_pins(GpioMode mode) { } void furi_hal_resources_init_early() { + furi_hal_bus_enable(FuriHalBusGPIOA); + furi_hal_bus_enable(FuriHalBusGPIOB); + furi_hal_bus_enable(FuriHalBusGPIOC); + furi_hal_bus_enable(FuriHalBusGPIOD); + furi_hal_bus_enable(FuriHalBusGPIOE); + furi_hal_bus_enable(FuriHalBusGPIOH); + furi_hal_resources_init_input_pins(GpioModeInput); // SD Card stepdown control @@ -162,6 +170,12 @@ void furi_hal_resources_init_early() { void furi_hal_resources_deinit_early() { furi_hal_resources_init_input_pins(GpioModeAnalog); + furi_hal_bus_disable(FuriHalBusGPIOA); + furi_hal_bus_disable(FuriHalBusGPIOB); + furi_hal_bus_disable(FuriHalBusGPIOC); + furi_hal_bus_disable(FuriHalBusGPIOD); + furi_hal_bus_disable(FuriHalBusGPIOE); + furi_hal_bus_disable(FuriHalBusGPIOH); } void furi_hal_resources_init() { diff --git a/firmware/targets/f18/furi_hal/furi_hal_spi_config.c b/firmware/targets/f18/furi_hal/furi_hal_spi_config.c index 0fbe55e2a..5ac84906f 100644 --- a/firmware/targets/f18/furi_hal/furi_hal_spi_config.c +++ b/firmware/targets/f18/furi_hal/furi_hal_spi_config.c @@ -1,5 +1,6 @@ #include #include +#include #include #include @@ -96,28 +97,17 @@ void furi_hal_spi_config_init() { static void furi_hal_spi_bus_r_event_callback(FuriHalSpiBus* bus, FuriHalSpiBusEvent event) { if(event == FuriHalSpiBusEventInit) { furi_hal_spi_bus_r_mutex = furi_mutex_alloc(FuriMutexTypeNormal); - FURI_CRITICAL_ENTER(); - LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_SPI1); - FURI_CRITICAL_EXIT(); bus->current_handle = NULL; } else if(event == FuriHalSpiBusEventDeinit) { furi_mutex_free(furi_hal_spi_bus_r_mutex); - FURI_CRITICAL_ENTER(); - LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_SPI1); - LL_APB2_GRP1_ReleaseReset(LL_APB2_GRP1_PERIPH_SPI1); - FURI_CRITICAL_EXIT(); } else if(event == FuriHalSpiBusEventLock) { furi_check(furi_mutex_acquire(furi_hal_spi_bus_r_mutex, FuriWaitForever) == FuriStatusOk); } else if(event == FuriHalSpiBusEventUnlock) { furi_check(furi_mutex_release(furi_hal_spi_bus_r_mutex) == FuriStatusOk); } else if(event == FuriHalSpiBusEventActivate) { - FURI_CRITICAL_ENTER(); - LL_APB2_GRP1_ReleaseReset(LL_APB2_GRP1_PERIPH_SPI1); - FURI_CRITICAL_EXIT(); + furi_hal_bus_enable(FuriHalBusSPI1); } else if(event == FuriHalSpiBusEventDeactivate) { - FURI_CRITICAL_ENTER(); - LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_SPI1); - FURI_CRITICAL_EXIT(); + furi_hal_bus_disable(FuriHalBusSPI1); } } @@ -131,28 +121,17 @@ FuriMutex* furi_hal_spi_bus_d_mutex = NULL; static void furi_hal_spi_bus_d_event_callback(FuriHalSpiBus* bus, FuriHalSpiBusEvent event) { if(event == FuriHalSpiBusEventInit) { furi_hal_spi_bus_d_mutex = furi_mutex_alloc(FuriMutexTypeNormal); - FURI_CRITICAL_ENTER(); - LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_SPI2); - FURI_CRITICAL_EXIT(); bus->current_handle = NULL; } else if(event == FuriHalSpiBusEventDeinit) { furi_mutex_free(furi_hal_spi_bus_d_mutex); - FURI_CRITICAL_ENTER(); - LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_SPI2); - LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_SPI2); - FURI_CRITICAL_EXIT(); } else if(event == FuriHalSpiBusEventLock) { furi_check(furi_mutex_acquire(furi_hal_spi_bus_d_mutex, FuriWaitForever) == FuriStatusOk); } else if(event == FuriHalSpiBusEventUnlock) { furi_check(furi_mutex_release(furi_hal_spi_bus_d_mutex) == FuriStatusOk); } else if(event == FuriHalSpiBusEventActivate) { - FURI_CRITICAL_ENTER(); - LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_SPI2); - FURI_CRITICAL_EXIT(); + furi_hal_bus_enable(FuriHalBusSPI2); } else if(event == FuriHalSpiBusEventDeactivate) { - FURI_CRITICAL_ENTER(); - LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_SPI2); - FURI_CRITICAL_EXIT(); + furi_hal_bus_disable(FuriHalBusSPI2); } } diff --git a/firmware/targets/f7/api_symbols.csv b/firmware/targets/f7/api_symbols.csv index 1055cb2bf..4b48949d9 100644 --- a/firmware/targets/f7/api_symbols.csv +++ b/firmware/targets/f7/api_symbols.csv @@ -1,5 +1,5 @@ entry,status,name,type,params -Version,+,27.1,, +Version,+,28.0,, Header,+,applications/services/bt/bt_service/bt.h,, Header,+,applications/services/cli/cli.h,, Header,+,applications/services/cli/cli_vcp.h,, @@ -36,8 +36,10 @@ Header,+,applications/services/notification/notification_messages.h,, Header,+,applications/services/power/power_service/power.h,, Header,+,applications/services/rpc/rpc_app.h,, Header,+,applications/services/storage/storage.h,, +Header,+,firmware/targets/f7/furi_hal/furi_hal_bus.h,, Header,+,firmware/targets/f7/furi_hal/furi_hal_clock.h,, Header,+,firmware/targets/f7/furi_hal/furi_hal_console.h,, +Header,+,firmware/targets/f7/furi_hal/furi_hal_dma.h,, Header,+,firmware/targets/f7/furi_hal/furi_hal_flash.h,, Header,+,firmware/targets/f7/furi_hal/furi_hal_gpio.h,, Header,+,firmware/targets/f7/furi_hal/furi_hal_i2c_config.h,, @@ -1065,6 +1067,12 @@ Function,+,furi_hal_bt_stop_tone_tx,void, Function,+,furi_hal_bt_unlock_core2,void, Function,+,furi_hal_bt_update_battery_level,void,uint8_t Function,+,furi_hal_bt_update_power_state,void, +Function,+,furi_hal_bus_deinit_early,void, +Function,+,furi_hal_bus_disable,void,FuriHalBus +Function,+,furi_hal_bus_enable,void,FuriHalBus +Function,+,furi_hal_bus_init_early,void, +Function,+,furi_hal_bus_is_enabled,_Bool,FuriHalBus +Function,+,furi_hal_bus_reset,void,FuriHalBus Function,+,furi_hal_cdc_get_ctrl_line_state,uint8_t,uint8_t Function,+,furi_hal_cdc_get_port_settings,usb_cdc_line_coding*,uint8_t Function,+,furi_hal_cdc_receive,int32_t,"uint8_t, uint8_t*, uint16_t" @@ -1107,6 +1115,8 @@ Function,+,furi_hal_debug_disable,void, Function,+,furi_hal_debug_enable,void, Function,+,furi_hal_debug_is_gdb_session_active,_Bool, Function,-,furi_hal_deinit_early,void, +Function,+,furi_hal_dma_deinit_early,void, +Function,+,furi_hal_dma_init_early,void, Function,-,furi_hal_flash_erase,void,uint8_t Function,-,furi_hal_flash_get_base,size_t, Function,-,furi_hal_flash_get_cycles_count,size_t, @@ -1273,6 +1283,7 @@ Function,+,furi_hal_pwm_start,void,"FuriHalPwmOutputId, uint32_t, uint8_t" Function,+,furi_hal_pwm_stop,void,FuriHalPwmOutputId Function,+,furi_hal_random_fill_buf,void,"uint8_t*, uint32_t" Function,+,furi_hal_random_get,uint32_t, +Function,+,furi_hal_random_init,void, Function,+,furi_hal_region_get,const FuriHalRegion*, Function,+,furi_hal_region_get_band,const FuriHalRegionBand*,uint32_t Function,+,furi_hal_region_get_name,const char*, @@ -1284,31 +1295,23 @@ Function,-,furi_hal_resources_deinit_early,void, Function,+,furi_hal_resources_get_ext_pin_number,int32_t,const GpioPin* Function,-,furi_hal_resources_init,void, Function,-,furi_hal_resources_init_early,void, -Function,+,furi_hal_rfid_change_read_config,void,"float, float" Function,+,furi_hal_rfid_comp_set_callback,void,"FuriHalRfidCompCallback, void*" Function,+,furi_hal_rfid_comp_start,void, Function,+,furi_hal_rfid_comp_stop,void, Function,-,furi_hal_rfid_init,void, Function,+,furi_hal_rfid_pin_pull_pulldown,void, Function,+,furi_hal_rfid_pin_pull_release,void, -Function,+,furi_hal_rfid_pins_emulate,void, -Function,+,furi_hal_rfid_pins_read,void, Function,+,furi_hal_rfid_pins_reset,void, -Function,+,furi_hal_rfid_set_emulate_period,void,uint32_t -Function,+,furi_hal_rfid_set_emulate_pulse,void,uint32_t Function,+,furi_hal_rfid_set_read_period,void,uint32_t Function,+,furi_hal_rfid_set_read_pulse,void,uint32_t -Function,+,furi_hal_rfid_tim_emulate,void,float Function,+,furi_hal_rfid_tim_emulate_dma_start,void,"uint32_t*, uint32_t*, size_t, FuriHalRfidDMACallback, void*" Function,+,furi_hal_rfid_tim_emulate_dma_stop,void, -Function,+,furi_hal_rfid_tim_emulate_start,void,"FuriHalRfidEmulateCallback, void*" -Function,+,furi_hal_rfid_tim_emulate_stop,void, -Function,+,furi_hal_rfid_tim_read,void,"float, float" Function,+,furi_hal_rfid_tim_read_capture_start,void,"FuriHalRfidReadCaptureCallback, void*" Function,+,furi_hal_rfid_tim_read_capture_stop,void, -Function,+,furi_hal_rfid_tim_read_start,void, +Function,+,furi_hal_rfid_tim_read_continue,void, +Function,+,furi_hal_rfid_tim_read_pause,void, +Function,+,furi_hal_rfid_tim_read_start,void,"float, float" Function,+,furi_hal_rfid_tim_read_stop,void, -Function,+,furi_hal_rfid_tim_reset,void, Function,+,furi_hal_rtc_datetime_to_timestamp,uint32_t,FuriHalRtcDateTime* Function,-,furi_hal_rtc_deinit_early,void, Function,+,furi_hal_rtc_get_boot_mode,FuriHalRtcBootMode, diff --git a/firmware/targets/f7/furi_hal/furi_hal.c b/firmware/targets/f7/furi_hal/furi_hal.c index 1b710bb96..2062645cd 100644 --- a/firmware/targets/f7/furi_hal/furi_hal.c +++ b/firmware/targets/f7/furi_hal/furi_hal.c @@ -9,6 +9,8 @@ void furi_hal_init_early() { furi_hal_cortex_init_early(); furi_hal_clock_init_early(); + furi_hal_bus_init_early(); + furi_hal_dma_init_early(); furi_hal_resources_init_early(); furi_hal_os_init(); furi_hal_spi_config_init_early(); @@ -22,12 +24,15 @@ void furi_hal_deinit_early() { furi_hal_i2c_deinit_early(); furi_hal_spi_config_deinit_early(); furi_hal_resources_deinit_early(); + furi_hal_dma_deinit_early(); + furi_hal_bus_deinit_early(); furi_hal_clock_deinit_early(); } void furi_hal_init() { furi_hal_mpu_init(); furi_hal_clock_init(); + furi_hal_random_init(); furi_hal_console_init(); furi_hal_rtc_init(); furi_hal_interrupt_init(); diff --git a/firmware/targets/f7/furi_hal/furi_hal_bt.c b/firmware/targets/f7/furi_hal/furi_hal_bt.c index 048a8b309..cec6b8204 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_bt.c +++ b/firmware/targets/f7/furi_hal/furi_hal_bt.c @@ -7,6 +7,7 @@ #include #include #include +#include #include "battery_service.h" #include @@ -80,6 +81,11 @@ FuriHalBtProfileConfig profile_config[FuriHalBtProfileNumber] = { FuriHalBtProfileConfig* current_profile = NULL; void furi_hal_bt_init() { + furi_hal_bus_enable(FuriHalBusHSEM); + furi_hal_bus_enable(FuriHalBusIPCC); + furi_hal_bus_enable(FuriHalBusAES2); + furi_hal_bus_enable(FuriHalBusPKA); + if(!furi_hal_bt_core2_mtx) { furi_hal_bt_core2_mtx = furi_mutex_alloc(FuriMutexTypeNormal); furi_assert(furi_hal_bt_core2_mtx); @@ -256,6 +262,11 @@ void furi_hal_bt_reinit() { furi_delay_ms(100); ble_glue_thread_stop(); + furi_hal_bus_disable(FuriHalBusHSEM); + furi_hal_bus_disable(FuriHalBusIPCC); + furi_hal_bus_disable(FuriHalBusAES2); + furi_hal_bus_disable(FuriHalBusPKA); + FURI_LOG_I(TAG, "Start BT initialization"); furi_hal_bt_init(); diff --git a/firmware/targets/f7/furi_hal/furi_hal_bus.c b/firmware/targets/f7/furi_hal/furi_hal_bus.c new file mode 100644 index 000000000..0a07e9f9e --- /dev/null +++ b/firmware/targets/f7/furi_hal/furi_hal_bus.c @@ -0,0 +1,302 @@ +#include +#include + +#include + +/* Bus bitmask definitions */ +#define FURI_HAL_BUS_IGNORE (0x0U) + +#define FURI_HAL_BUS_AHB1_GRP1 \ + (LL_AHB1_GRP1_PERIPH_DMA1 | LL_AHB1_GRP1_PERIPH_DMA2 | LL_AHB1_GRP1_PERIPH_DMAMUX1 | \ + LL_AHB1_GRP1_PERIPH_CRC | LL_AHB1_GRP1_PERIPH_TSC) + +#if defined(ADC_SUPPORT_5_MSPS) +#define FURI_HAL_BUS_AHB2_GRP1 \ + (LL_AHB2_GRP1_PERIPH_GPIOA | LL_AHB2_GRP1_PERIPH_GPIOB | LL_AHB2_GRP1_PERIPH_GPIOC | \ + LL_AHB2_GRP1_PERIPH_GPIOD | LL_AHB2_GRP1_PERIPH_GPIOE | LL_AHB2_GRP1_PERIPH_GPIOH | \ + LL_AHB2_GRP1_PERIPH_ADC | LL_AHB2_GRP1_PERIPH_AES1) + +#define FURI_HAL_BUS_APB2_GRP1 \ + (LL_APB2_GRP1_PERIPH_TIM1 | LL_APB2_GRP1_PERIPH_SPI1 | LL_APB2_GRP1_PERIPH_USART1 | \ + LL_APB2_GRP1_PERIPH_TIM16 | LL_APB2_GRP1_PERIPH_TIM17 | LL_APB2_GRP1_PERIPH_SAI1) +#else +#define FURI_HAL_BUS_AHB2_GRP1 \ + (LL_AHB2_GRP1_PERIPH_GPIOA | LL_AHB2_GRP1_PERIPH_GPIOB | LL_AHB2_GRP1_PERIPH_GPIOC | \ + LL_AHB2_GRP1_PERIPH_GPIOD | LL_AHB2_GRP1_PERIPH_GPIOE | LL_AHB2_GRP1_PERIPH_GPIOH | \ + LL_AHB2_GRP1_PERIPH_AES1) + +#define FURI_HAL_BUS_APB2_GRP1 \ + (LL_APB2_GRP1_PERIPH_ADC | LL_APB2_GRP1_PERIPH_TIM1 | LL_APB2_GRP1_PERIPH_SPI1 | \ + LL_APB2_GRP1_PERIPH_USART1 | LL_APB2_GRP1_PERIPH_TIM16 | LL_APB2_GRP1_PERIPH_TIM17 | \ + LL_APB2_GRP1_PERIPH_SAI1) +#endif + +#define FURI_HAL_BUS_AHB3_GRP1 \ + (LL_AHB3_GRP1_PERIPH_QUADSPI | LL_AHB3_GRP1_PERIPH_PKA | LL_AHB3_GRP1_PERIPH_AES2 | \ + LL_AHB3_GRP1_PERIPH_RNG | LL_AHB3_GRP1_PERIPH_HSEM | LL_AHB3_GRP1_PERIPH_IPCC) +// LL_AHB3_GRP1_PERIPH_FLASH enabled by default + +#define FURI_HAL_BUS_APB1_GRP1 \ + (LL_APB1_GRP1_PERIPH_TIM2 | LL_APB1_GRP1_PERIPH_LCD | LL_APB1_GRP1_PERIPH_RTCAPB | \ + LL_APB1_GRP1_PERIPH_SPI2 | LL_APB1_GRP1_PERIPH_I2C1 | LL_APB1_GRP1_PERIPH_I2C3 | \ + LL_APB1_GRP1_PERIPH_CRS | LL_APB1_GRP1_PERIPH_USB | LL_APB1_GRP1_PERIPH_LPTIM1) + +#define FURI_HAL_BUS_APB1_GRP2 (LL_APB1_GRP2_PERIPH_LPUART1 | LL_APB1_GRP2_PERIPH_LPTIM2) +#define FURI_HAL_BUS_APB3_GRP1 (LL_APB3_GRP1_PERIPH_RF) + +/* Test macro definitions */ +#define FURI_HAL_BUS_IS_ALL_CLEAR(reg, value) (READ_BIT((reg), (value)) == 0UL) +#define FURI_HAL_BUS_IS_ALL_SET(reg, value) (READ_BIT((reg), (value)) == (value)) + +#define FURI_HAL_BUS_IS_CLOCK_ENABLED(bus, value, ...) \ + (FURI_HAL_BUS_IS_ALL_SET(RCC->bus##ENR##__VA_ARGS__, (value))) +#define FURI_HAL_BUS_IS_CLOCK_DISABLED(bus, value, ...) \ + (FURI_HAL_BUS_IS_ALL_CLEAR(RCC->bus##ENR##__VA_ARGS__, (value))) + +#define FURI_HAL_BUS_IS_RESET_ASSERTED(bus, value, ...) \ + (FURI_HAL_BUS_IS_ALL_SET(RCC->bus##RSTR##__VA_ARGS__, (value))) +#define FURI_HAL_BUS_IS_RESET_DEASSERTED(bus, value, ...) \ + (FURI_HAL_BUS_IS_ALL_CLEAR(RCC->bus##RSTR##__VA_ARGS__, (value))) + +#define FURI_HAL_BUS_IS_PERIPH_ENABLED(bus, value, ...) \ + (FURI_HAL_BUS_IS_RESET_DEASSERTED(bus, (value), __VA_ARGS__) && \ + FURI_HAL_BUS_IS_CLOCK_ENABLED(bus, (value), __VA_ARGS__)) + +#define FURI_HAL_BUS_IS_PERIPH_DISABLED(bus, value, ...) \ + (FURI_HAL_BUS_IS_CLOCK_DISABLED(bus, (value), __VA_ARGS__) && \ + FURI_HAL_BUS_IS_RESET_ASSERTED(bus, (value), __VA_ARGS__)) + +/* Control macro definitions */ +#define FURI_HAL_BUS_RESET_ASSERT(bus, value, grp) LL_##bus##_GRP##grp##_ForceReset(value) +#define FURI_HAL_BUS_RESET_DEASSERT(bus, value, grp) LL_##bus##_GRP##grp##_ReleaseReset(value) + +#define FURI_HAL_BUS_CLOCK_ENABLE(bus, value, grp) LL_##bus##_GRP##grp##_EnableClock(value) +#define FURI_HAL_BUS_CLOCK_DISABLE(bus, value, grp) LL_##bus##_GRP##grp##_DisableClock(value) + +#define FURI_HAL_BUS_PERIPH_ENABLE(bus, value, grp) \ + FURI_HAL_BUS_CLOCK_ENABLE(bus, value, grp); \ + FURI_HAL_BUS_RESET_DEASSERT(bus, value, grp) + +#define FURI_HAL_BUS_PERIPH_DISABLE(bus, value, grp) \ + FURI_HAL_BUS_RESET_ASSERT(bus, value, grp); \ + FURI_HAL_BUS_CLOCK_DISABLE(bus, value, grp) + +#define FURI_HAL_BUS_PERIPH_RESET(bus, value, grp) \ + FURI_HAL_BUS_RESET_ASSERT(bus, value, grp); \ + FURI_HAL_BUS_RESET_DEASSERT(bus, value, grp) + +static const uint32_t furi_hal_bus[] = { + [FuriHalBusAHB1_GRP1] = FURI_HAL_BUS_AHB1_GRP1, + [FuriHalBusDMA1] = LL_AHB1_GRP1_PERIPH_DMA1, + [FuriHalBusDMA2] = LL_AHB1_GRP1_PERIPH_DMA2, + [FuriHalBusDMAMUX1] = LL_AHB1_GRP1_PERIPH_DMAMUX1, + [FuriHalBusCRC] = LL_AHB1_GRP1_PERIPH_CRC, + [FuriHalBusTSC] = LL_AHB1_GRP1_PERIPH_TSC, + + [FuriHalBusAHB2_GRP1] = FURI_HAL_BUS_AHB2_GRP1, + [FuriHalBusGPIOA] = LL_AHB2_GRP1_PERIPH_GPIOA, + [FuriHalBusGPIOB] = LL_AHB2_GRP1_PERIPH_GPIOB, + [FuriHalBusGPIOC] = LL_AHB2_GRP1_PERIPH_GPIOC, + [FuriHalBusGPIOD] = LL_AHB2_GRP1_PERIPH_GPIOD, + [FuriHalBusGPIOE] = LL_AHB2_GRP1_PERIPH_GPIOE, + [FuriHalBusGPIOH] = LL_AHB2_GRP1_PERIPH_GPIOH, +#if defined(ADC_SUPPORT_5_MSPS) + [FuriHalBusADC] = LL_AHB2_GRP1_PERIPH_ADC, +#endif + [FuriHalBusAES1] = LL_AHB2_GRP1_PERIPH_AES1, + + [FuriHalBusAHB3_GRP1] = FURI_HAL_BUS_AHB3_GRP1, + [FuriHalBusQUADSPI] = LL_AHB3_GRP1_PERIPH_QUADSPI, + [FuriHalBusPKA] = LL_AHB3_GRP1_PERIPH_PKA, + [FuriHalBusAES2] = LL_AHB3_GRP1_PERIPH_AES2, + [FuriHalBusRNG] = LL_AHB3_GRP1_PERIPH_RNG, + [FuriHalBusHSEM] = LL_AHB3_GRP1_PERIPH_HSEM, + [FuriHalBusIPCC] = LL_AHB3_GRP1_PERIPH_IPCC, + [FuriHalBusFLASH] = LL_AHB3_GRP1_PERIPH_FLASH, + + [FuriHalBusAPB1_GRP1] = FURI_HAL_BUS_APB1_GRP1, + [FuriHalBusTIM2] = LL_APB1_GRP1_PERIPH_TIM2, + [FuriHalBusLCD] = LL_APB1_GRP1_PERIPH_LCD, + [FuriHalBusSPI2] = LL_APB1_GRP1_PERIPH_SPI2, + [FuriHalBusI2C1] = LL_APB1_GRP1_PERIPH_I2C1, + [FuriHalBusI2C3] = LL_APB1_GRP1_PERIPH_I2C3, + [FuriHalBusCRS] = LL_APB1_GRP1_PERIPH_CRS, + [FuriHalBusUSB] = LL_APB1_GRP1_PERIPH_USB, + [FuriHalBusLPTIM1] = LL_APB1_GRP1_PERIPH_LPTIM1, + + [FuriHalBusAPB1_GRP2] = FURI_HAL_BUS_APB1_GRP2, + [FuriHalBusLPUART1] = LL_APB1_GRP2_PERIPH_LPUART1, + [FuriHalBusLPTIM2] = LL_APB1_GRP2_PERIPH_LPTIM2, + + [FuriHalBusAPB2_GRP1] = FURI_HAL_BUS_APB2_GRP1, +#if defined(ADC_SUPPORT_2_5_MSPS) + [FuriHalBusADC] = LL_APB2_GRP1_PERIPH_ADC, +#endif + [FuriHalBusTIM1] = LL_APB2_GRP1_PERIPH_TIM1, + [FuriHalBusSPI1] = LL_APB2_GRP1_PERIPH_SPI1, + [FuriHalBusUSART1] = LL_APB2_GRP1_PERIPH_USART1, + [FuriHalBusTIM16] = LL_APB2_GRP1_PERIPH_TIM16, + [FuriHalBusTIM17] = LL_APB2_GRP1_PERIPH_TIM17, + [FuriHalBusSAI1] = LL_APB2_GRP1_PERIPH_SAI1, + + [FuriHalBusAPB3_GRP1] = FURI_HAL_BUS_IGNORE, // APB3_GRP1 clocking cannot be changed + [FuriHalBusRF] = LL_APB3_GRP1_PERIPH_RF, +}; + +void furi_hal_bus_init_early() { + FURI_CRITICAL_ENTER(); + + FURI_HAL_BUS_PERIPH_DISABLE(AHB1, FURI_HAL_BUS_AHB1_GRP1, 1); + FURI_HAL_BUS_PERIPH_DISABLE(AHB2, FURI_HAL_BUS_AHB2_GRP1, 1); + FURI_HAL_BUS_PERIPH_DISABLE(AHB3, FURI_HAL_BUS_AHB3_GRP1, 1); + FURI_HAL_BUS_PERIPH_DISABLE(APB1, FURI_HAL_BUS_APB1_GRP1, 1); + FURI_HAL_BUS_PERIPH_DISABLE(APB1, FURI_HAL_BUS_APB1_GRP2, 2); + FURI_HAL_BUS_PERIPH_DISABLE(APB2, FURI_HAL_BUS_APB2_GRP1, 1); + + FURI_HAL_BUS_RESET_ASSERT(APB3, FURI_HAL_BUS_APB3_GRP1, 1); + + FURI_CRITICAL_EXIT(); +} + +void furi_hal_bus_deinit_early() { + FURI_CRITICAL_ENTER(); + + FURI_HAL_BUS_PERIPH_ENABLE(AHB1, FURI_HAL_BUS_AHB1_GRP1, 1); + FURI_HAL_BUS_PERIPH_ENABLE(AHB2, FURI_HAL_BUS_AHB2_GRP1, 1); + FURI_HAL_BUS_PERIPH_ENABLE(AHB3, FURI_HAL_BUS_AHB3_GRP1, 1); + FURI_HAL_BUS_PERIPH_ENABLE(APB1, FURI_HAL_BUS_APB1_GRP1, 1); + FURI_HAL_BUS_PERIPH_ENABLE(APB1, FURI_HAL_BUS_APB1_GRP2, 2); + FURI_HAL_BUS_PERIPH_ENABLE(APB2, FURI_HAL_BUS_APB2_GRP1, 1); + + FURI_HAL_BUS_RESET_DEASSERT(APB3, FURI_HAL_BUS_APB3_GRP1, 1); + + FURI_CRITICAL_EXIT(); +} + +void furi_hal_bus_enable(FuriHalBus bus) { + furi_check(bus < FuriHalBusMAX); + const uint32_t value = furi_hal_bus[bus]; + if(!value) { + return; + } + + FURI_CRITICAL_ENTER(); + if(bus < FuriHalBusAHB2_GRP1) { + furi_check(FURI_HAL_BUS_IS_PERIPH_DISABLED(AHB1, value)); + FURI_HAL_BUS_PERIPH_ENABLE(AHB1, value, 1); + } else if(bus < FuriHalBusAHB3_GRP1) { + furi_check(FURI_HAL_BUS_IS_PERIPH_DISABLED(AHB2, value)); + FURI_HAL_BUS_PERIPH_ENABLE(AHB2, value, 1); + } else if(bus < FuriHalBusAPB1_GRP1) { + furi_check(FURI_HAL_BUS_IS_PERIPH_DISABLED(AHB3, value)); + FURI_HAL_BUS_PERIPH_ENABLE(AHB3, value, 1); + } else if(bus < FuriHalBusAPB1_GRP2) { + furi_check(FURI_HAL_BUS_IS_PERIPH_DISABLED(APB1, value, 1)); + FURI_HAL_BUS_PERIPH_ENABLE(APB1, value, 1); + } else if(bus < FuriHalBusAPB2_GRP1) { + furi_check(FURI_HAL_BUS_IS_PERIPH_DISABLED(APB1, value, 2)); + FURI_HAL_BUS_PERIPH_ENABLE(APB1, value, 2); + } else if(bus < FuriHalBusAPB3_GRP1) { + furi_check(FURI_HAL_BUS_IS_PERIPH_DISABLED(APB2, value)); + FURI_HAL_BUS_PERIPH_ENABLE(APB2, value, 1); + } else { + furi_check(FURI_HAL_BUS_IS_RESET_ASSERTED(APB3, value)); + FURI_HAL_BUS_RESET_DEASSERT(APB3, FURI_HAL_BUS_APB3_GRP1, 1); + } + FURI_CRITICAL_EXIT(); +} + +void furi_hal_bus_reset(FuriHalBus bus) { + furi_check(bus < FuriHalBusMAX); + const uint32_t value = furi_hal_bus[bus]; + if(!value) { + return; + } + + FURI_CRITICAL_ENTER(); + if(bus < FuriHalBusAHB2_GRP1) { + furi_check(FURI_HAL_BUS_IS_PERIPH_ENABLED(AHB1, value)); + FURI_HAL_BUS_PERIPH_RESET(AHB1, value, 1); + } else if(bus < FuriHalBusAHB3_GRP1) { + furi_check(FURI_HAL_BUS_IS_PERIPH_ENABLED(AHB2, value)); + FURI_HAL_BUS_PERIPH_RESET(AHB2, value, 1); + } else if(bus < FuriHalBusAPB1_GRP1) { + furi_check(FURI_HAL_BUS_IS_PERIPH_ENABLED(AHB3, value)); + FURI_HAL_BUS_PERIPH_RESET(AHB3, value, 1); + } else if(bus < FuriHalBusAPB1_GRP2) { + furi_check(FURI_HAL_BUS_IS_PERIPH_ENABLED(APB1, value, 1)); + FURI_HAL_BUS_PERIPH_RESET(APB1, value, 1); + } else if(bus < FuriHalBusAPB2_GRP1) { + furi_check(FURI_HAL_BUS_IS_PERIPH_ENABLED(APB1, value, 2)); + FURI_HAL_BUS_PERIPH_RESET(APB1, value, 2); + } else if(bus < FuriHalBusAPB3_GRP1) { + furi_check(FURI_HAL_BUS_IS_PERIPH_ENABLED(APB2, value)); + FURI_HAL_BUS_PERIPH_RESET(APB2, value, 1); + } else { + furi_check(FURI_HAL_BUS_IS_RESET_DEASSERTED(APB3, value)); + FURI_HAL_BUS_PERIPH_RESET(APB3, value, 1); + } + FURI_CRITICAL_EXIT(); +} + +void furi_hal_bus_disable(FuriHalBus bus) { + furi_check(bus < FuriHalBusMAX); + const uint32_t value = furi_hal_bus[bus]; + if(!value) { + return; + } + + FURI_CRITICAL_ENTER(); + if(bus < FuriHalBusAHB2_GRP1) { + furi_check(FURI_HAL_BUS_IS_PERIPH_ENABLED(AHB1, value)); + FURI_HAL_BUS_PERIPH_DISABLE(AHB1, value, 1); + } else if(bus < FuriHalBusAHB3_GRP1) { + furi_check(FURI_HAL_BUS_IS_PERIPH_ENABLED(AHB2, value)); + FURI_HAL_BUS_PERIPH_DISABLE(AHB2, value, 1); + } else if(bus < FuriHalBusAPB1_GRP1) { + furi_check(FURI_HAL_BUS_IS_PERIPH_ENABLED(AHB3, value)); + FURI_HAL_BUS_PERIPH_DISABLE(AHB3, value, 1); + } else if(bus < FuriHalBusAPB1_GRP2) { + furi_check(FURI_HAL_BUS_IS_PERIPH_ENABLED(APB1, value, 1)); + FURI_HAL_BUS_PERIPH_DISABLE(APB1, value, 1); + } else if(bus < FuriHalBusAPB2_GRP1) { + furi_check(FURI_HAL_BUS_IS_PERIPH_ENABLED(APB1, value, 2)); + FURI_HAL_BUS_PERIPH_DISABLE(APB1, value, 2); + } else if(bus < FuriHalBusAPB3_GRP1) { + furi_check(FURI_HAL_BUS_IS_PERIPH_ENABLED(APB2, value)); + FURI_HAL_BUS_PERIPH_DISABLE(APB2, value, 1); + } else { + furi_check(FURI_HAL_BUS_IS_RESET_DEASSERTED(APB3, value)); + FURI_HAL_BUS_RESET_ASSERT(APB3, FURI_HAL_BUS_APB3_GRP1, 1); + } + FURI_CRITICAL_EXIT(); +} + +bool furi_hal_bus_is_enabled(FuriHalBus bus) { + furi_check(bus < FuriHalBusMAX); + const uint32_t value = furi_hal_bus[bus]; + if(value == FURI_HAL_BUS_IGNORE) { + return true; + } + + bool ret = false; + FURI_CRITICAL_ENTER(); + if(bus < FuriHalBusAHB2_GRP1) { + ret = FURI_HAL_BUS_IS_PERIPH_ENABLED(AHB1, value); + } else if(bus < FuriHalBusAHB3_GRP1) { + ret = FURI_HAL_BUS_IS_PERIPH_ENABLED(AHB2, value); + } else if(bus < FuriHalBusAPB1_GRP1) { + ret = FURI_HAL_BUS_IS_PERIPH_ENABLED(AHB3, value); + } else if(bus < FuriHalBusAPB1_GRP2) { + ret = FURI_HAL_BUS_IS_PERIPH_ENABLED(APB1, value, 1); + } else if(bus < FuriHalBusAPB2_GRP1) { + ret = FURI_HAL_BUS_IS_PERIPH_ENABLED(APB1, value, 2); + } else if(bus < FuriHalBusAPB3_GRP1) { + ret = FURI_HAL_BUS_IS_PERIPH_ENABLED(APB2, value); + } else { + ret = FURI_HAL_BUS_IS_RESET_DEASSERTED(APB3, value); + } + FURI_CRITICAL_EXIT(); + + return ret; +} diff --git a/firmware/targets/f7/furi_hal/furi_hal_bus.h b/firmware/targets/f7/furi_hal/furi_hal_bus.h new file mode 100644 index 000000000..ad4bbec32 --- /dev/null +++ b/firmware/targets/f7/furi_hal/furi_hal_bus.h @@ -0,0 +1,112 @@ +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#include "stm32wbxx.h" +#include "stdbool.h" + +typedef enum { + FuriHalBusAHB1_GRP1, + FuriHalBusDMA1, + FuriHalBusDMA2, + FuriHalBusDMAMUX1, + FuriHalBusCRC, + FuriHalBusTSC, + + FuriHalBusAHB2_GRP1, + FuriHalBusGPIOA, + FuriHalBusGPIOB, + FuriHalBusGPIOC, + FuriHalBusGPIOD, + FuriHalBusGPIOE, + FuriHalBusGPIOH, +#if defined(ADC_SUPPORT_5_MSPS) + FuriHalBusADC, +#endif + FuriHalBusAES1, + + FuriHalBusAHB3_GRP1, + FuriHalBusQUADSPI, + FuriHalBusPKA, + FuriHalBusAES2, + FuriHalBusRNG, + FuriHalBusHSEM, + FuriHalBusIPCC, + FuriHalBusFLASH, + + FuriHalBusAPB1_GRP1, + FuriHalBusTIM2, + FuriHalBusLCD, + FuriHalBusSPI2, + FuriHalBusI2C1, + FuriHalBusI2C3, + FuriHalBusCRS, + FuriHalBusUSB, + FuriHalBusLPTIM1, + + FuriHalBusAPB1_GRP2, + FuriHalBusLPUART1, + FuriHalBusLPTIM2, + + FuriHalBusAPB2_GRP1, +#if defined(ADC_SUPPORT_2_5_MSPS) + FuriHalBusADC, +#endif + FuriHalBusTIM1, + FuriHalBusSPI1, + FuriHalBusUSART1, + FuriHalBusTIM16, + FuriHalBusTIM17, + FuriHalBusSAI1, + + FuriHalBusAPB3_GRP1, + FuriHalBusRF, + + FuriHalBusMAX, +} FuriHalBus; + +/** Early initialization */ +void furi_hal_bus_init_early(); + +/** Early de-initialization */ +void furi_hal_bus_deinit_early(); + +/** + * Enable a peripheral by turning the clocking on and deasserting the reset. + * @param [in] bus Peripheral to be enabled. + * @warning Peripheral must be in disabled state in order to be enabled. + */ +void furi_hal_bus_enable(FuriHalBus bus); + +/** + * Reset a peripheral by sequentially asserting and deasserting the reset. + * @param [in] bus Peripheral to be reset. + * @warning Peripheral must be in enabled state in order to be reset. + */ +void furi_hal_bus_reset(FuriHalBus bus); + +/** + * Disable a peripheral by turning the clocking off and asserting the reset. + * @param [in] bus Peripheral to be disabled. + * @warning Peripheral must be in enabled state in order to be disabled. + */ +void furi_hal_bus_disable(FuriHalBus bus); + +/** Check if peripheral is enabled + * + * @warning FuriHalBusAPB3_GRP1 is a special group of shared peripherals, for + * core1 its clock is always on and the only status we can report is + * peripheral reset status. Check code and Reference Manual for + * details. + * + * @param[in] bus The peripheral to check + * + * @return true if enabled or always enabled, false otherwise + */ +bool furi_hal_bus_is_enabled(FuriHalBus bus); + +#ifdef __cplusplus +} +#endif diff --git a/firmware/targets/f7/furi_hal/furi_hal_clock.c b/firmware/targets/f7/furi_hal/furi_hal_clock.c index a76fbfbca..9d228f0f5 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_clock.c +++ b/firmware/targets/f7/furi_hal/furi_hal_clock.c @@ -6,7 +6,6 @@ #include #include #include -#include #define TAG "FuriHalClock" @@ -19,36 +18,9 @@ void furi_hal_clock_init_early() { LL_SetSystemCoreClock(CPU_CLOCK_HZ_EARLY); LL_Init1msTick(SystemCoreClock); - - LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOA); - LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOB); - LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOC); - LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOD); - LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOE); - LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOH); - - LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_SPI1); - LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_SPI2); - - LL_APB1_GRP2_EnableClock(LL_APB1_GRP2_PERIPH_LPTIM2); - - LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_I2C1); - LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_I2C3); } void furi_hal_clock_deinit_early() { - LL_APB1_GRP1_DisableClock(LL_APB1_GRP1_PERIPH_I2C1); - LL_APB1_GRP1_DisableClock(LL_APB1_GRP1_PERIPH_I2C3); - - LL_APB2_GRP1_DisableClock(LL_APB2_GRP1_PERIPH_SPI1); - LL_APB1_GRP1_DisableClock(LL_APB1_GRP1_PERIPH_SPI2); - - LL_AHB2_GRP1_DisableClock(LL_AHB2_GRP1_PERIPH_GPIOA); - LL_AHB2_GRP1_DisableClock(LL_AHB2_GRP1_PERIPH_GPIOB); - LL_AHB2_GRP1_DisableClock(LL_AHB2_GRP1_PERIPH_GPIOC); - LL_AHB2_GRP1_DisableClock(LL_AHB2_GRP1_PERIPH_GPIOD); - LL_AHB2_GRP1_DisableClock(LL_AHB2_GRP1_PERIPH_GPIOE); - LL_AHB2_GRP1_DisableClock(LL_AHB2_GRP1_PERIPH_GPIOH); } void furi_hal_clock_init() { @@ -137,68 +109,12 @@ void furi_hal_clock_init() { SysTick_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), TICK_INT_PRIORITY, 0)); NVIC_EnableIRQ(SysTick_IRQn); - LL_RCC_SetUSARTClockSource(LL_RCC_USART1_CLKSOURCE_PCLK2); - LL_RCC_SetLPUARTClockSource(LL_RCC_LPUART1_CLKSOURCE_PCLK1); - LL_RCC_SetADCClockSource(LL_RCC_ADC_CLKSOURCE_PLLSAI1); - LL_RCC_SetI2CClockSource(LL_RCC_I2C1_CLKSOURCE_PCLK1); - LL_RCC_SetRNGClockSource(LL_RCC_RNG_CLKSOURCE_CLK48); - LL_RCC_SetUSBClockSource(LL_RCC_USB_CLKSOURCE_PLLSAI1); LL_RCC_SetCLK48ClockSource(LL_RCC_CLK48_CLKSOURCE_PLLSAI1); LL_RCC_HSI_EnableInStopMode(); // Ensure that MR is capable of work in STOP0 LL_RCC_SetSMPSClockSource(LL_RCC_SMPS_CLKSOURCE_HSE); LL_RCC_SetSMPSPrescaler(LL_RCC_SMPS_DIV_1); LL_RCC_SetRFWKPClockSource(LL_RCC_RFWKP_CLKSOURCE_LSE); - // AHB1 GRP1 - LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_DMA1); - LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_DMA2); - LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_DMAMUX1); - LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_CRC); - // LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_TSC); - - // AHB2 GRP1 - LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOA); - LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOB); - LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOC); - LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOD); - LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOE); - LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOH); - LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_ADC); - LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_AES1); - - // AHB3 GRP1 - // LL_AHB3_GRP1_EnableClock(LL_AHB3_GRP1_PERIPH_QUADSPI); - LL_AHB3_GRP1_EnableClock(LL_AHB3_GRP1_PERIPH_PKA); - LL_AHB3_GRP1_EnableClock(LL_AHB3_GRP1_PERIPH_AES2); - LL_AHB3_GRP1_EnableClock(LL_AHB3_GRP1_PERIPH_RNG); - LL_AHB3_GRP1_EnableClock(LL_AHB3_GRP1_PERIPH_HSEM); - LL_AHB3_GRP1_EnableClock(LL_AHB3_GRP1_PERIPH_IPCC); - LL_AHB3_GRP1_EnableClock(LL_AHB3_GRP1_PERIPH_FLASH); - - // APB1 GRP1 - LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM2); - // LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_LCD); - LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_RTCAPB); - // LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_WWDG); - LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_SPI2); - LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_I2C1); - LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_I2C3); - LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_CRS); - LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_USB); - LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_LPTIM1); - - // APB1 GRP2 - LL_APB1_GRP2_EnableClock(LL_APB1_GRP2_PERIPH_LPUART1); - - // APB2 - // LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_ADC); - LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_TIM1); - LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_SPI1); - LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_USART1); - LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_TIM16); - LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_TIM17); - // LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_SAI1); - FURI_LOG_I(TAG, "Init OK"); } diff --git a/firmware/targets/f7/furi_hal/furi_hal_crypto.c b/firmware/targets/f7/furi_hal/furi_hal_crypto.c index e0ed3ab9b..eb5c3b782 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_crypto.c +++ b/firmware/targets/f7/furi_hal/furi_hal_crypto.c @@ -1,8 +1,9 @@ #include #include #include +#include + #include -#include #include #include @@ -241,6 +242,8 @@ bool furi_hal_crypto_store_load_key(uint8_t slot, const uint8_t* iv) { furi_assert(furi_hal_crypto_mutex); furi_check(furi_mutex_acquire(furi_hal_crypto_mutex, FuriWaitForever) == FuriStatusOk); + furi_hal_bus_enable(FuriHalBusAES1); + if(!furi_hal_bt_is_alive()) { return false; } @@ -267,10 +270,7 @@ bool furi_hal_crypto_store_unload_key(uint8_t slot) { SHCI_CmdStatus_t shci_state = SHCI_C2_FUS_UnloadUsrKey(slot); furi_assert(shci_state == SHCI_Success); - FURI_CRITICAL_ENTER(); - LL_AHB2_GRP1_ForceReset(LL_AHB2_GRP1_PERIPH_AES1); - LL_AHB2_GRP1_ReleaseReset(LL_AHB2_GRP1_PERIPH_AES1); - FURI_CRITICAL_EXIT(); + furi_hal_bus_disable(FuriHalBusAES1); furi_check(furi_mutex_release(furi_hal_crypto_mutex) == FuriStatusOk); return (shci_state == SHCI_Success); diff --git a/firmware/targets/f7/furi_hal/furi_hal_dma.c b/firmware/targets/f7/furi_hal/furi_hal_dma.c new file mode 100644 index 000000000..a6a30d906 --- /dev/null +++ b/firmware/targets/f7/furi_hal/furi_hal_dma.c @@ -0,0 +1,14 @@ +#include +#include + +void furi_hal_dma_init_early() { + furi_hal_bus_enable(FuriHalBusDMA1); + furi_hal_bus_enable(FuriHalBusDMA2); + furi_hal_bus_enable(FuriHalBusDMAMUX1); +} + +void furi_hal_dma_deinit_early() { + furi_hal_bus_disable(FuriHalBusDMA1); + furi_hal_bus_disable(FuriHalBusDMA2); + furi_hal_bus_disable(FuriHalBusDMAMUX1); +} diff --git a/firmware/targets/f7/furi_hal/furi_hal_dma.h b/firmware/targets/f7/furi_hal/furi_hal_dma.h new file mode 100644 index 000000000..cadcc7733 --- /dev/null +++ b/firmware/targets/f7/furi_hal/furi_hal_dma.h @@ -0,0 +1,15 @@ +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +/** Early initialization */ +void furi_hal_dma_init_early(); + +/** Early de-initialization */ +void furi_hal_dma_deinit_early(); + +#ifdef __cplusplus +} +#endif diff --git a/firmware/targets/f7/furi_hal/furi_hal_flash.c b/firmware/targets/f7/furi_hal/furi_hal_flash.c index 94d269345..796d20b19 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_flash.c +++ b/firmware/targets/f7/furi_hal/furi_hal_flash.c @@ -11,20 +11,20 @@ #define TAG "FuriHalFlash" #define FURI_HAL_CRITICAL_MSG "Critical flash operation fail" -#define FURI_HAL_FLASH_READ_BLOCK 8 -#define FURI_HAL_FLASH_WRITE_BLOCK 8 -#define FURI_HAL_FLASH_PAGE_SIZE 4096 -#define FURI_HAL_FLASH_CYCLES_COUNT 10000 -#define FURI_HAL_FLASH_TIMEOUT 1000 -#define FURI_HAL_FLASH_KEY1 0x45670123U -#define FURI_HAL_FLASH_KEY2 0xCDEF89ABU -#define FURI_HAL_FLASH_TOTAL_PAGES 256 +#define FURI_HAL_FLASH_READ_BLOCK (8U) +#define FURI_HAL_FLASH_WRITE_BLOCK (8U) +#define FURI_HAL_FLASH_PAGE_SIZE (4096U) +#define FURI_HAL_FLASH_CYCLES_COUNT (10000U) +#define FURI_HAL_FLASH_TIMEOUT (1000U) +#define FURI_HAL_FLASH_KEY1 (0x45670123U) +#define FURI_HAL_FLASH_KEY2 (0xCDEF89ABU) +#define FURI_HAL_FLASH_TOTAL_PAGES (256U) #define FURI_HAL_FLASH_SR_ERRORS \ (FLASH_SR_OPERR | FLASH_SR_PROGERR | FLASH_SR_WRPERR | FLASH_SR_PGAERR | FLASH_SR_SIZERR | \ FLASH_SR_PGSERR | FLASH_SR_MISERR | FLASH_SR_FASTERR | FLASH_SR_RDERR | FLASH_SR_OPTVERR) -#define FURI_HAL_FLASH_OPT_KEY1 0x08192A3B -#define FURI_HAL_FLASH_OPT_KEY2 0x4C5D6E7F +#define FURI_HAL_FLASH_OPT_KEY1 (0x08192A3BU) +#define FURI_HAL_FLASH_OPT_KEY2 (0x4C5D6E7FU) #define FURI_HAL_FLASH_OB_TOTAL_WORDS (0x80 / (sizeof(uint32_t) * 2)) /* STM32CubeWB/Projects/P-NUCLEO-WB55.Nucleo/Applications/BLE/BLE_RfWithFlash/Core/Src/flash_driver.c @@ -35,7 +35,7 @@ > If for any reason this test is never passed, this means there is a failure in the system and there is no other > way to recover than applying a device reset. */ -#define FURI_HAL_FLASH_C2_LOCK_TIMEOUT_MS 3000u /* 3 seconds */ +#define FURI_HAL_FLASH_C2_LOCK_TIMEOUT_MS (3000U) /* 3 seconds */ #define IS_ADDR_ALIGNED_64BITS(__VALUE__) (((__VALUE__)&0x7U) == (0x00UL)) #define IS_FLASH_PROGRAM_ADDRESS(__VALUE__) \ diff --git a/firmware/targets/f7/furi_hal/furi_hal_i2c_config.c b/firmware/targets/f7/furi_hal/furi_hal_i2c_config.c index afc4fdf52..f9d88abb3 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_i2c_config.c +++ b/firmware/targets/f7/furi_hal/furi_hal_i2c_config.c @@ -1,7 +1,8 @@ #include #include #include -#include +#include + #include /** Timing register value is computed with the STM32CubeMX Tool, @@ -21,17 +22,9 @@ FuriMutex* furi_hal_i2c_bus_power_mutex = NULL; static void furi_hal_i2c_bus_power_event(FuriHalI2cBus* bus, FuriHalI2cBusEvent event) { if(event == FuriHalI2cBusEventInit) { furi_hal_i2c_bus_power_mutex = furi_mutex_alloc(FuriMutexTypeNormal); - FURI_CRITICAL_ENTER(); - LL_RCC_SetI2CClockSource(LL_RCC_I2C1_CLKSOURCE_PCLK1); - LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_I2C1); - FURI_CRITICAL_EXIT(); bus->current_handle = NULL; } else if(event == FuriHalI2cBusEventDeinit) { furi_mutex_free(furi_hal_i2c_bus_power_mutex); - FURI_CRITICAL_ENTER(); - LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_I2C1); - LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_I2C1); - FURI_CRITICAL_EXIT(); } else if(event == FuriHalI2cBusEventLock) { furi_check( furi_mutex_acquire(furi_hal_i2c_bus_power_mutex, FuriWaitForever) == FuriStatusOk); @@ -39,12 +32,11 @@ static void furi_hal_i2c_bus_power_event(FuriHalI2cBus* bus, FuriHalI2cBusEvent furi_check(furi_mutex_release(furi_hal_i2c_bus_power_mutex) == FuriStatusOk); } else if(event == FuriHalI2cBusEventActivate) { FURI_CRITICAL_ENTER(); - LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_I2C1); + furi_hal_bus_enable(FuriHalBusI2C1); + LL_RCC_SetI2CClockSource(LL_RCC_I2C1_CLKSOURCE_PCLK1); FURI_CRITICAL_EXIT(); } else if(event == FuriHalI2cBusEventDeactivate) { - FURI_CRITICAL_ENTER(); - LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_I2C1); - FURI_CRITICAL_EXIT(); + furi_hal_bus_disable(FuriHalBusI2C1); } } @@ -58,17 +50,9 @@ FuriMutex* furi_hal_i2c_bus_external_mutex = NULL; static void furi_hal_i2c_bus_external_event(FuriHalI2cBus* bus, FuriHalI2cBusEvent event) { if(event == FuriHalI2cBusEventInit) { furi_hal_i2c_bus_external_mutex = furi_mutex_alloc(FuriMutexTypeNormal); - FURI_CRITICAL_ENTER(); - LL_RCC_SetI2CClockSource(LL_RCC_I2C3_CLKSOURCE_PCLK1); - LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_I2C3); - FURI_CRITICAL_EXIT(); bus->current_handle = NULL; } else if(event == FuriHalI2cBusEventDeinit) { furi_mutex_free(furi_hal_i2c_bus_external_mutex); - FURI_CRITICAL_ENTER(); - LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_I2C3); - LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_I2C3); - FURI_CRITICAL_EXIT(); } else if(event == FuriHalI2cBusEventLock) { furi_check( furi_mutex_acquire(furi_hal_i2c_bus_external_mutex, FuriWaitForever) == FuriStatusOk); @@ -76,13 +60,11 @@ static void furi_hal_i2c_bus_external_event(FuriHalI2cBus* bus, FuriHalI2cBusEve furi_check(furi_mutex_release(furi_hal_i2c_bus_external_mutex) == FuriStatusOk); } else if(event == FuriHalI2cBusEventActivate) { FURI_CRITICAL_ENTER(); + furi_hal_bus_enable(FuriHalBusI2C3); LL_RCC_SetI2CClockSource(LL_RCC_I2C3_CLKSOURCE_PCLK1); - LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_I2C3); FURI_CRITICAL_EXIT(); } else if(event == FuriHalI2cBusEventDeactivate) { - FURI_CRITICAL_ENTER(); - LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_I2C3); - FURI_CRITICAL_EXIT(); + furi_hal_bus_disable(FuriHalBusI2C3); } } diff --git a/firmware/targets/f7/furi_hal/furi_hal_ibutton.c b/firmware/targets/f7/furi_hal/furi_hal_ibutton.c index c8041c9f2..f8f7e4966 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_ibutton.c +++ b/firmware/targets/f7/furi_hal/furi_hal_ibutton.c @@ -1,14 +1,15 @@ #include #include #include +#include #include -#include #include #define TAG "FuriHalIbutton" #define FURI_HAL_IBUTTON_TIMER TIM1 +#define FURI_HAL_IBUTTON_TIMER_BUS FuriHalBusTIM1 #define FURI_HAL_IBUTTON_TIMER_IRQ FuriHalInterruptIdTim1UpTim16 typedef enum { @@ -49,9 +50,7 @@ void furi_hal_ibutton_emulate_start( furi_hal_ibutton->callback = callback; furi_hal_ibutton->context = context; - FURI_CRITICAL_ENTER(); - LL_TIM_DeInit(FURI_HAL_IBUTTON_TIMER); - FURI_CRITICAL_EXIT(); + furi_hal_bus_enable(FURI_HAL_IBUTTON_TIMER_BUS); furi_hal_interrupt_set_isr(FURI_HAL_IBUTTON_TIMER_IRQ, furi_hal_ibutton_emulate_isr, NULL); @@ -81,10 +80,7 @@ void furi_hal_ibutton_emulate_stop() { furi_hal_ibutton->state = FuriHalIbuttonStateIdle; LL_TIM_DisableCounter(FURI_HAL_IBUTTON_TIMER); - FURI_CRITICAL_ENTER(); - LL_TIM_DeInit(FURI_HAL_IBUTTON_TIMER); - FURI_CRITICAL_EXIT(); - + furi_hal_bus_disable(FURI_HAL_IBUTTON_TIMER_BUS); furi_hal_interrupt_set_isr(FURI_HAL_IBUTTON_TIMER_IRQ, NULL, NULL); furi_hal_ibutton->callback = NULL; diff --git a/firmware/targets/f7/furi_hal/furi_hal_idle_timer.h b/firmware/targets/f7/furi_hal/furi_hal_idle_timer.h index 36b45755a..e1ffb1b25 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_idle_timer.h +++ b/firmware/targets/f7/furi_hal/furi_hal_idle_timer.h @@ -1,9 +1,10 @@ #pragma once #include -#include #include -#include +#include + +#include // Timer used for tickless idle #define FURI_HAL_IDLE_TIMER_MAX 0xFFFF @@ -11,6 +12,7 @@ #define FURI_HAL_IDLE_TIMER_IRQ LPTIM1_IRQn static inline void furi_hal_idle_timer_init() { + furi_hal_bus_enable(FuriHalBusLPTIM1); // Configure clock source LL_RCC_SetLPTIMClockSource(LL_RCC_LPTIM1_CLKSOURCE_LSE); // There is a theoretical possibility that we need it @@ -41,7 +43,7 @@ static inline void furi_hal_idle_timer_start(uint32_t count) { static inline void furi_hal_idle_timer_reset() { // Hard reset timer // THE ONLY RELIABLE WAY to stop it according to errata - LL_LPTIM_DeInit(FURI_HAL_IDLE_TIMER); + furi_hal_bus_reset(FuriHalBusLPTIM1); // Prevent IRQ handler call NVIC_ClearPendingIRQ(FURI_HAL_IDLE_TIMER_IRQ); } diff --git a/firmware/targets/f7/furi_hal/furi_hal_infrared.c b/firmware/targets/f7/furi_hal/furi_hal_infrared.c index 7b4f17084..c60db5f20 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_infrared.c +++ b/firmware/targets/f7/furi_hal/furi_hal_infrared.c @@ -1,14 +1,11 @@ #include -#include -#include "stm32wbxx_ll_dma.h" #include #include +#include -#include #include -#include +#include -#include #include #include @@ -27,13 +24,23 @@ (TIM_CCMR2_OC3PE | LL_TIM_OCMODE_FORCED_INACTIVE) /* Space time - force low */ /* DMA Channels definition */ -#define IR_DMA DMA2 -#define IR_DMA_CH1_CHANNEL LL_DMA_CHANNEL_1 -#define IR_DMA_CH2_CHANNEL LL_DMA_CHANNEL_2 -#define IR_DMA_CH1_IRQ FuriHalInterruptIdDma2Ch1 -#define IR_DMA_CH2_IRQ FuriHalInterruptIdDma2Ch2 -#define IR_DMA_CH1_DEF IR_DMA, IR_DMA_CH1_CHANNEL -#define IR_DMA_CH2_DEF IR_DMA, IR_DMA_CH2_CHANNEL +#define INFRARED_DMA DMA2 +#define INFRARED_DMA_CH1_CHANNEL LL_DMA_CHANNEL_1 +#define INFRARED_DMA_CH2_CHANNEL LL_DMA_CHANNEL_2 +#define INFRARED_DMA_CH1_IRQ FuriHalInterruptIdDma2Ch1 +#define INFRARED_DMA_CH2_IRQ FuriHalInterruptIdDma2Ch2 +#define INFRARED_DMA_CH1_DEF INFRARED_DMA, INFRARED_DMA_CH1_CHANNEL +#define INFRARED_DMA_CH2_DEF INFRARED_DMA, INFRARED_DMA_CH2_CHANNEL + +/* Timers definition */ +#define INFRARED_RX_TIMER TIM2 +#define INFRARED_DMA_TIMER TIM1 +#define INFRARED_RX_TIMER_BUS FuriHalBusTIM2 +#define INFRARED_DMA_TIMER_BUS FuriHalBusTIM1 + +/* Misc */ +#define INFRARED_RX_GPIO_ALT GpioAltFn1TIM2 +#define INFRARED_RX_IRQ FuriHalInterruptIdTIM2 typedef struct { FuriHalInfraredRxCaptureCallback capture_callback; @@ -91,8 +98,8 @@ static void furi_hal_infrared_tim_rx_isr() { static uint32_t previous_captured_ch2 = 0; /* Timeout */ - if(LL_TIM_IsActiveFlag_CC3(TIM2)) { - LL_TIM_ClearFlag_CC3(TIM2); + if(LL_TIM_IsActiveFlag_CC3(INFRARED_RX_TIMER)) { + LL_TIM_ClearFlag_CC3(INFRARED_RX_TIMER); furi_assert(furi_hal_infrared_state == InfraredStateAsyncRx); /* Timers CNT register starts to counting from 0 to ARR, but it is @@ -108,13 +115,13 @@ static void furi_hal_infrared_tim_rx_isr() { } /* Rising Edge */ - if(LL_TIM_IsActiveFlag_CC1(TIM2)) { - LL_TIM_ClearFlag_CC1(TIM2); + if(LL_TIM_IsActiveFlag_CC1(INFRARED_RX_TIMER)) { + LL_TIM_ClearFlag_CC1(INFRARED_RX_TIMER); furi_assert(furi_hal_infrared_state == InfraredStateAsyncRx); - if(READ_BIT(TIM2->CCMR1, TIM_CCMR1_CC1S)) { + if(READ_BIT(INFRARED_RX_TIMER->CCMR1, TIM_CCMR1_CC1S)) { /* Low pin level is a Mark state of INFRARED signal. Invert level for further processing. */ - uint32_t duration = LL_TIM_IC_GetCaptureCH1(TIM2) - previous_captured_ch2; + uint32_t duration = LL_TIM_IC_GetCaptureCH1(INFRARED_RX_TIMER) - previous_captured_ch2; if(infrared_tim_rx.capture_callback) infrared_tim_rx.capture_callback(infrared_tim_rx.capture_context, 1, duration); } else { @@ -123,13 +130,13 @@ static void furi_hal_infrared_tim_rx_isr() { } /* Falling Edge */ - if(LL_TIM_IsActiveFlag_CC2(TIM2)) { - LL_TIM_ClearFlag_CC2(TIM2); + if(LL_TIM_IsActiveFlag_CC2(INFRARED_RX_TIMER)) { + LL_TIM_ClearFlag_CC2(INFRARED_RX_TIMER); furi_assert(furi_hal_infrared_state == InfraredStateAsyncRx); - if(READ_BIT(TIM2->CCMR1, TIM_CCMR1_CC2S)) { + if(READ_BIT(INFRARED_RX_TIMER->CCMR1, TIM_CCMR1_CC2S)) { /* High pin level is a Space state of INFRARED signal. Invert level for further processing. */ - uint32_t duration = LL_TIM_IC_GetCaptureCH2(TIM2); + uint32_t duration = LL_TIM_IC_GetCaptureCH2(INFRARED_RX_TIMER); previous_captured_ch2 = duration; if(infrared_tim_rx.capture_callback) infrared_tim_rx.capture_callback(infrared_tim_rx.capture_context, 0, duration); @@ -143,62 +150,66 @@ void furi_hal_infrared_async_rx_start(void) { furi_assert(furi_hal_infrared_state == InfraredStateIdle); furi_hal_gpio_init_ex( - &gpio_infrared_rx, GpioModeAltFunctionPushPull, GpioPullNo, GpioSpeedLow, GpioAltFn1TIM2); + &gpio_infrared_rx, + GpioModeAltFunctionPushPull, + GpioPullNo, + GpioSpeedLow, + INFRARED_RX_GPIO_ALT); + + furi_hal_bus_enable(INFRARED_RX_TIMER_BUS); LL_TIM_InitTypeDef TIM_InitStruct = {0}; TIM_InitStruct.Prescaler = 64 - 1; TIM_InitStruct.CounterMode = LL_TIM_COUNTERMODE_UP; TIM_InitStruct.Autoreload = 0x7FFFFFFE; TIM_InitStruct.ClockDivision = LL_TIM_CLOCKDIVISION_DIV1; - LL_TIM_Init(TIM2, &TIM_InitStruct); + LL_TIM_Init(INFRARED_RX_TIMER, &TIM_InitStruct); - LL_TIM_SetClockSource(TIM2, LL_TIM_CLOCKSOURCE_INTERNAL); - LL_TIM_DisableARRPreload(TIM2); - LL_TIM_SetTriggerInput(TIM2, LL_TIM_TS_TI1FP1); - LL_TIM_SetSlaveMode(TIM2, LL_TIM_SLAVEMODE_RESET); - LL_TIM_CC_DisableChannel(TIM2, LL_TIM_CHANNEL_CH2); - LL_TIM_IC_SetFilter(TIM2, LL_TIM_CHANNEL_CH2, LL_TIM_IC_FILTER_FDIV1); - LL_TIM_IC_SetPolarity(TIM2, LL_TIM_CHANNEL_CH2, LL_TIM_IC_POLARITY_FALLING); - LL_TIM_DisableIT_TRIG(TIM2); - LL_TIM_DisableDMAReq_TRIG(TIM2); - LL_TIM_SetTriggerOutput(TIM2, LL_TIM_TRGO_RESET); - LL_TIM_EnableMasterSlaveMode(TIM2); - LL_TIM_IC_SetActiveInput(TIM2, LL_TIM_CHANNEL_CH1, LL_TIM_ACTIVEINPUT_DIRECTTI); - LL_TIM_IC_SetPrescaler(TIM2, LL_TIM_CHANNEL_CH1, LL_TIM_ICPSC_DIV1); - LL_TIM_IC_SetFilter(TIM2, LL_TIM_CHANNEL_CH1, LL_TIM_IC_FILTER_FDIV1); - LL_TIM_IC_SetPolarity(TIM2, LL_TIM_CHANNEL_CH1, LL_TIM_IC_POLARITY_RISING); - LL_TIM_IC_SetActiveInput(TIM2, LL_TIM_CHANNEL_CH2, LL_TIM_ACTIVEINPUT_INDIRECTTI); - LL_TIM_IC_SetPrescaler(TIM2, LL_TIM_CHANNEL_CH2, LL_TIM_ICPSC_DIV1); + LL_TIM_SetClockSource(INFRARED_RX_TIMER, LL_TIM_CLOCKSOURCE_INTERNAL); + LL_TIM_DisableARRPreload(INFRARED_RX_TIMER); + LL_TIM_SetTriggerInput(INFRARED_RX_TIMER, LL_TIM_TS_TI1FP1); + LL_TIM_SetSlaveMode(INFRARED_RX_TIMER, LL_TIM_SLAVEMODE_RESET); + LL_TIM_CC_DisableChannel(INFRARED_RX_TIMER, LL_TIM_CHANNEL_CH2); + LL_TIM_IC_SetFilter(INFRARED_RX_TIMER, LL_TIM_CHANNEL_CH2, LL_TIM_IC_FILTER_FDIV1); + LL_TIM_IC_SetPolarity(INFRARED_RX_TIMER, LL_TIM_CHANNEL_CH2, LL_TIM_IC_POLARITY_FALLING); + LL_TIM_DisableIT_TRIG(INFRARED_RX_TIMER); + LL_TIM_DisableDMAReq_TRIG(INFRARED_RX_TIMER); + LL_TIM_SetTriggerOutput(INFRARED_RX_TIMER, LL_TIM_TRGO_RESET); + LL_TIM_EnableMasterSlaveMode(INFRARED_RX_TIMER); + LL_TIM_IC_SetActiveInput(INFRARED_RX_TIMER, LL_TIM_CHANNEL_CH1, LL_TIM_ACTIVEINPUT_DIRECTTI); + LL_TIM_IC_SetPrescaler(INFRARED_RX_TIMER, LL_TIM_CHANNEL_CH1, LL_TIM_ICPSC_DIV1); + LL_TIM_IC_SetFilter(INFRARED_RX_TIMER, LL_TIM_CHANNEL_CH1, LL_TIM_IC_FILTER_FDIV1); + LL_TIM_IC_SetPolarity(INFRARED_RX_TIMER, LL_TIM_CHANNEL_CH1, LL_TIM_IC_POLARITY_RISING); + LL_TIM_IC_SetActiveInput(INFRARED_RX_TIMER, LL_TIM_CHANNEL_CH2, LL_TIM_ACTIVEINPUT_INDIRECTTI); + LL_TIM_IC_SetPrescaler(INFRARED_RX_TIMER, LL_TIM_CHANNEL_CH2, LL_TIM_ICPSC_DIV1); - furi_hal_interrupt_set_isr(FuriHalInterruptIdTIM2, furi_hal_infrared_tim_rx_isr, NULL); + furi_hal_interrupt_set_isr(INFRARED_RX_IRQ, furi_hal_infrared_tim_rx_isr, NULL); furi_hal_infrared_state = InfraredStateAsyncRx; - LL_TIM_EnableIT_CC1(TIM2); - LL_TIM_EnableIT_CC2(TIM2); - LL_TIM_CC_EnableChannel(TIM2, LL_TIM_CHANNEL_CH1); - LL_TIM_CC_EnableChannel(TIM2, LL_TIM_CHANNEL_CH2); + LL_TIM_EnableIT_CC1(INFRARED_RX_TIMER); + LL_TIM_EnableIT_CC2(INFRARED_RX_TIMER); + LL_TIM_CC_EnableChannel(INFRARED_RX_TIMER, LL_TIM_CHANNEL_CH1); + LL_TIM_CC_EnableChannel(INFRARED_RX_TIMER, LL_TIM_CHANNEL_CH2); - LL_TIM_SetCounter(TIM2, 0); - LL_TIM_EnableCounter(TIM2); + LL_TIM_SetCounter(INFRARED_RX_TIMER, 0); + LL_TIM_EnableCounter(INFRARED_RX_TIMER); } void furi_hal_infrared_async_rx_stop(void) { furi_assert(furi_hal_infrared_state == InfraredStateAsyncRx); FURI_CRITICAL_ENTER(); - - LL_TIM_DeInit(TIM2); - furi_hal_interrupt_set_isr(FuriHalInterruptIdTIM2, NULL, NULL); + furi_hal_bus_disable(INFRARED_RX_TIMER_BUS); + furi_hal_interrupt_set_isr(INFRARED_RX_IRQ, NULL, NULL); furi_hal_infrared_state = InfraredStateIdle; - FURI_CRITICAL_EXIT(); } void furi_hal_infrared_async_rx_set_timeout(uint32_t timeout_us) { - LL_TIM_OC_SetCompareCH3(TIM2, timeout_us); - LL_TIM_OC_SetMode(TIM2, LL_TIM_CHANNEL_CH3, LL_TIM_OCMODE_ACTIVE); - LL_TIM_CC_EnableChannel(TIM2, LL_TIM_CHANNEL_CH3); - LL_TIM_EnableIT_CC3(TIM2); + LL_TIM_OC_SetCompareCH3(INFRARED_RX_TIMER, timeout_us); + LL_TIM_OC_SetMode(INFRARED_RX_TIMER, LL_TIM_CHANNEL_CH3, LL_TIM_OCMODE_ACTIVE); + LL_TIM_CC_EnableChannel(INFRARED_RX_TIMER, LL_TIM_CHANNEL_CH3); + LL_TIM_EnableIT_CC3(INFRARED_RX_TIMER); } bool furi_hal_infrared_is_busy(void) { @@ -220,16 +231,16 @@ void furi_hal_infrared_async_rx_set_timeout_isr_callback( } static void furi_hal_infrared_tx_dma_terminate(void) { - LL_DMA_DisableIT_TC(IR_DMA_CH1_DEF); - LL_DMA_DisableIT_HT(IR_DMA_CH2_DEF); - LL_DMA_DisableIT_TC(IR_DMA_CH2_DEF); + LL_DMA_DisableIT_TC(INFRARED_DMA_CH1_DEF); + LL_DMA_DisableIT_HT(INFRARED_DMA_CH2_DEF); + LL_DMA_DisableIT_TC(INFRARED_DMA_CH2_DEF); furi_assert(furi_hal_infrared_state == InfraredStateAsyncTxStopInProgress); - LL_DMA_DisableIT_TC(IR_DMA_CH1_DEF); - LL_DMA_DisableChannel(IR_DMA_CH2_DEF); - LL_DMA_DisableChannel(IR_DMA_CH1_DEF); - LL_TIM_DisableCounter(TIM1); + LL_DMA_DisableIT_TC(INFRARED_DMA_CH1_DEF); + LL_DMA_DisableChannel(INFRARED_DMA_CH2_DEF); + LL_DMA_DisableChannel(INFRARED_DMA_CH1_DEF); + LL_TIM_DisableCounter(INFRARED_DMA_TIMER); FuriStatus status = furi_semaphore_release(infrared_tim_tx.stop_semaphore); furi_check(status == FuriStatusOk); furi_hal_infrared_state = InfraredStateAsyncTxStopped; @@ -237,7 +248,7 @@ static void furi_hal_infrared_tx_dma_terminate(void) { static uint8_t furi_hal_infrared_get_current_dma_tx_buffer(void) { uint8_t buf_num = 0; - uint32_t buffer_adr = LL_DMA_GetMemoryAddress(IR_DMA_CH2_DEF); + uint32_t buffer_adr = LL_DMA_GetMemoryAddress(INFRARED_DMA_CH2_DEF); if(buffer_adr == (uint32_t)infrared_tim_tx.buffer[0].data) { buf_num = 0; } else if(buffer_adr == (uint32_t)infrared_tim_tx.buffer[1].data) { @@ -249,13 +260,13 @@ static uint8_t furi_hal_infrared_get_current_dma_tx_buffer(void) { } static void furi_hal_infrared_tx_dma_polarity_isr() { -#if IR_DMA_CH1_CHANNEL == LL_DMA_CHANNEL_1 - if(LL_DMA_IsActiveFlag_TE1(IR_DMA)) { - LL_DMA_ClearFlag_TE1(IR_DMA); +#if INFRARED_DMA_CH1_CHANNEL == LL_DMA_CHANNEL_1 + if(LL_DMA_IsActiveFlag_TE1(INFRARED_DMA)) { + LL_DMA_ClearFlag_TE1(INFRARED_DMA); furi_crash(NULL); } - if(LL_DMA_IsActiveFlag_TC1(IR_DMA) && LL_DMA_IsEnabledIT_TC(IR_DMA_CH1_DEF)) { - LL_DMA_ClearFlag_TC1(IR_DMA); + if(LL_DMA_IsActiveFlag_TC1(INFRARED_DMA) && LL_DMA_IsEnabledIT_TC(INFRARED_DMA_CH1_DEF)) { + LL_DMA_ClearFlag_TC1(INFRARED_DMA); furi_check( (furi_hal_infrared_state == InfraredStateAsyncTx) || @@ -271,23 +282,23 @@ static void furi_hal_infrared_tx_dma_polarity_isr() { } static void furi_hal_infrared_tx_dma_isr() { -#if IR_DMA_CH2_CHANNEL == LL_DMA_CHANNEL_2 - if(LL_DMA_IsActiveFlag_TE2(IR_DMA)) { - LL_DMA_ClearFlag_TE2(IR_DMA); +#if INFRARED_DMA_CH2_CHANNEL == LL_DMA_CHANNEL_2 + if(LL_DMA_IsActiveFlag_TE2(INFRARED_DMA)) { + LL_DMA_ClearFlag_TE2(INFRARED_DMA); furi_crash(NULL); } - if(LL_DMA_IsActiveFlag_HT2(IR_DMA) && LL_DMA_IsEnabledIT_HT(IR_DMA_CH2_DEF)) { - LL_DMA_ClearFlag_HT2(IR_DMA); + if(LL_DMA_IsActiveFlag_HT2(INFRARED_DMA) && LL_DMA_IsEnabledIT_HT(INFRARED_DMA_CH2_DEF)) { + LL_DMA_ClearFlag_HT2(INFRARED_DMA); uint8_t buf_num = furi_hal_infrared_get_current_dma_tx_buffer(); uint8_t next_buf_num = !buf_num; if(infrared_tim_tx.buffer[buf_num].last_packet_end) { - LL_DMA_DisableIT_HT(IR_DMA_CH2_DEF); + LL_DMA_DisableIT_HT(INFRARED_DMA_CH2_DEF); } else if( !infrared_tim_tx.buffer[buf_num].packet_end || (furi_hal_infrared_state == InfraredStateAsyncTx)) { furi_hal_infrared_tx_fill_buffer(next_buf_num, 0); if(infrared_tim_tx.buffer[next_buf_num].last_packet_end) { - LL_DMA_DisableIT_HT(IR_DMA_CH2_DEF); + LL_DMA_DisableIT_HT(INFRARED_DMA_CH2_DEF); } } else if(furi_hal_infrared_state == InfraredStateAsyncTxStopReq) { /* fallthrough */ @@ -295,8 +306,8 @@ static void furi_hal_infrared_tx_dma_isr() { furi_crash(NULL); } } - if(LL_DMA_IsActiveFlag_TC2(IR_DMA) && LL_DMA_IsEnabledIT_TC(IR_DMA_CH2_DEF)) { - LL_DMA_ClearFlag_TC2(IR_DMA); + if(LL_DMA_IsActiveFlag_TC2(INFRARED_DMA) && LL_DMA_IsEnabledIT_TC(INFRARED_DMA_CH2_DEF)) { + LL_DMA_ClearFlag_TC2(INFRARED_DMA); furi_check( (furi_hal_infrared_state == InfraredStateAsyncTxStopInProgress) || (furi_hal_infrared_state == InfraredStateAsyncTxStopReq) || @@ -328,37 +339,40 @@ static void furi_hal_infrared_tx_dma_isr() { } static void furi_hal_infrared_configure_tim_pwm_tx(uint32_t freq, float duty_cycle) { - LL_TIM_DisableCounter(TIM1); - LL_TIM_SetRepetitionCounter(TIM1, 0); - LL_TIM_SetCounter(TIM1, 0); - LL_TIM_SetPrescaler(TIM1, 0); - LL_TIM_SetCounterMode(TIM1, LL_TIM_COUNTERMODE_UP); - LL_TIM_EnableARRPreload(TIM1); + LL_TIM_DisableCounter(INFRARED_DMA_TIMER); + LL_TIM_SetRepetitionCounter(INFRARED_DMA_TIMER, 0); + LL_TIM_SetCounter(INFRARED_DMA_TIMER, 0); + LL_TIM_SetPrescaler(INFRARED_DMA_TIMER, 0); + LL_TIM_SetCounterMode(INFRARED_DMA_TIMER, LL_TIM_COUNTERMODE_UP); + LL_TIM_EnableARRPreload(INFRARED_DMA_TIMER); LL_TIM_SetAutoReload( - TIM1, __LL_TIM_CALC_ARR(SystemCoreClock, LL_TIM_GetPrescaler(TIM1), freq)); + INFRARED_DMA_TIMER, + __LL_TIM_CALC_ARR(SystemCoreClock, LL_TIM_GetPrescaler(INFRARED_DMA_TIMER), freq)); #if defined INFRARED_TX_DEBUG - LL_TIM_OC_SetCompareCH1(TIM1, ((LL_TIM_GetAutoReload(TIM1) + 1) * (1 - duty_cycle))); - LL_TIM_OC_EnablePreload(TIM1, LL_TIM_CHANNEL_CH1); + LL_TIM_OC_SetCompareCH1( + INFRARED_DMA_TIMER, ((LL_TIM_GetAutoReload(INFRARED_DMA_TIMER) + 1) * (1 - duty_cycle))); + LL_TIM_OC_EnablePreload(INFRARED_DMA_TIMER, LL_TIM_CHANNEL_CH1); /* LL_TIM_OCMODE_PWM2 set by DMA */ - LL_TIM_OC_SetMode(TIM1, LL_TIM_CHANNEL_CH1, LL_TIM_OCMODE_FORCED_INACTIVE); - LL_TIM_OC_SetPolarity(TIM1, LL_TIM_CHANNEL_CH1N, LL_TIM_OCPOLARITY_HIGH); - LL_TIM_OC_DisableFast(TIM1, LL_TIM_CHANNEL_CH1); - LL_TIM_CC_EnableChannel(TIM1, LL_TIM_CHANNEL_CH1N); - LL_TIM_DisableIT_CC1(TIM1); + LL_TIM_OC_SetMode(INFRARED_DMA_TIMER, LL_TIM_CHANNEL_CH1, LL_TIM_OCMODE_FORCED_INACTIVE); + LL_TIM_OC_SetPolarity(INFRARED_DMA_TIMER, LL_TIM_CHANNEL_CH1N, LL_TIM_OCPOLARITY_HIGH); + LL_TIM_OC_DisableFast(INFRARED_DMA_TIMER, LL_TIM_CHANNEL_CH1); + LL_TIM_CC_EnableChannel(INFRARED_DMA_TIMER, LL_TIM_CHANNEL_CH1N); + LL_TIM_DisableIT_CC1(INFRARED_DMA_TIMER); #else - LL_TIM_OC_SetCompareCH3(TIM1, ((LL_TIM_GetAutoReload(TIM1) + 1) * (1 - duty_cycle))); - LL_TIM_OC_EnablePreload(TIM1, LL_TIM_CHANNEL_CH3); + LL_TIM_OC_SetCompareCH3( + INFRARED_DMA_TIMER, ((LL_TIM_GetAutoReload(INFRARED_DMA_TIMER) + 1) * (1 - duty_cycle))); + LL_TIM_OC_EnablePreload(INFRARED_DMA_TIMER, LL_TIM_CHANNEL_CH3); /* LL_TIM_OCMODE_PWM2 set by DMA */ - LL_TIM_OC_SetMode(TIM1, LL_TIM_CHANNEL_CH3, LL_TIM_OCMODE_FORCED_INACTIVE); - LL_TIM_OC_SetPolarity(TIM1, LL_TIM_CHANNEL_CH3N, LL_TIM_OCPOLARITY_HIGH); - LL_TIM_OC_DisableFast(TIM1, LL_TIM_CHANNEL_CH3); - LL_TIM_CC_EnableChannel(TIM1, LL_TIM_CHANNEL_CH3N); - LL_TIM_DisableIT_CC3(TIM1); + LL_TIM_OC_SetMode(INFRARED_DMA_TIMER, LL_TIM_CHANNEL_CH3, LL_TIM_OCMODE_FORCED_INACTIVE); + LL_TIM_OC_SetPolarity(INFRARED_DMA_TIMER, LL_TIM_CHANNEL_CH3N, LL_TIM_OCPOLARITY_HIGH); + LL_TIM_OC_DisableFast(INFRARED_DMA_TIMER, LL_TIM_CHANNEL_CH3); + LL_TIM_CC_EnableChannel(INFRARED_DMA_TIMER, LL_TIM_CHANNEL_CH3N); + LL_TIM_DisableIT_CC3(INFRARED_DMA_TIMER); #endif - LL_TIM_DisableMasterSlaveMode(TIM1); - LL_TIM_EnableAllOutputs(TIM1); - LL_TIM_DisableIT_UPDATE(TIM1); - LL_TIM_EnableDMAReq_UPDATE(TIM1); + LL_TIM_DisableMasterSlaveMode(INFRARED_DMA_TIMER); + LL_TIM_EnableAllOutputs(INFRARED_DMA_TIMER); + LL_TIM_DisableIT_UPDATE(INFRARED_DMA_TIMER); + LL_TIM_EnableDMAReq_UPDATE(INFRARED_DMA_TIMER); NVIC_SetPriority(TIM1_UP_TIM16_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 5, 0)); NVIC_EnableIRQ(TIM1_UP_TIM16_IRQn); @@ -367,9 +381,9 @@ static void furi_hal_infrared_configure_tim_pwm_tx(uint32_t freq, float duty_cyc static void furi_hal_infrared_configure_tim_cmgr2_dma_tx(void) { LL_DMA_InitTypeDef dma_config = {0}; #if defined INFRARED_TX_DEBUG - dma_config.PeriphOrM2MSrcAddress = (uint32_t) & (TIM1->CCMR1); + dma_config.PeriphOrM2MSrcAddress = (uint32_t) & (INFRARED_DMA_TIMER->CCMR1); #else - dma_config.PeriphOrM2MSrcAddress = (uint32_t) & (TIM1->CCMR2); + dma_config.PeriphOrM2MSrcAddress = (uint32_t) & (INFRARED_DMA_TIMER->CCMR2); #endif dma_config.MemoryOrM2MDstAddress = (uint32_t)NULL; dma_config.Direction = LL_DMA_DIRECTION_MEMORY_TO_PERIPH; @@ -382,24 +396,25 @@ static void furi_hal_infrared_configure_tim_cmgr2_dma_tx(void) { dma_config.NbData = 0; dma_config.PeriphRequest = LL_DMAMUX_REQ_TIM1_UP; dma_config.Priority = LL_DMA_PRIORITY_VERYHIGH; - LL_DMA_Init(IR_DMA_CH1_DEF, &dma_config); + LL_DMA_Init(INFRARED_DMA_CH1_DEF, &dma_config); -#if IR_DMA_CH1_CHANNEL == LL_DMA_CHANNEL_1 - LL_DMA_ClearFlag_TE1(IR_DMA); - LL_DMA_ClearFlag_TC1(IR_DMA); +#if INFRARED_DMA_CH1_CHANNEL == LL_DMA_CHANNEL_1 + LL_DMA_ClearFlag_TE1(INFRARED_DMA); + LL_DMA_ClearFlag_TC1(INFRARED_DMA); #else #error Update this code. Would you kindly? #endif - LL_DMA_EnableIT_TE(IR_DMA_CH1_DEF); - LL_DMA_EnableIT_TC(IR_DMA_CH1_DEF); + LL_DMA_EnableIT_TE(INFRARED_DMA_CH1_DEF); + LL_DMA_EnableIT_TC(INFRARED_DMA_CH1_DEF); - furi_hal_interrupt_set_isr_ex(IR_DMA_CH1_IRQ, 4, furi_hal_infrared_tx_dma_polarity_isr, NULL); + furi_hal_interrupt_set_isr_ex( + INFRARED_DMA_CH1_IRQ, 4, furi_hal_infrared_tx_dma_polarity_isr, NULL); } static void furi_hal_infrared_configure_tim_rcr_dma_tx(void) { LL_DMA_InitTypeDef dma_config = {0}; - dma_config.PeriphOrM2MSrcAddress = (uint32_t) & (TIM1->RCR); + dma_config.PeriphOrM2MSrcAddress = (uint32_t) & (INFRARED_DMA_TIMER->RCR); dma_config.MemoryOrM2MDstAddress = (uint32_t)NULL; dma_config.Direction = LL_DMA_DIRECTION_MEMORY_TO_PERIPH; dma_config.Mode = LL_DMA_MODE_NORMAL; @@ -410,21 +425,21 @@ static void furi_hal_infrared_configure_tim_rcr_dma_tx(void) { dma_config.NbData = 0; dma_config.PeriphRequest = LL_DMAMUX_REQ_TIM1_UP; dma_config.Priority = LL_DMA_PRIORITY_MEDIUM; - LL_DMA_Init(IR_DMA_CH2_DEF, &dma_config); + LL_DMA_Init(INFRARED_DMA_CH2_DEF, &dma_config); -#if IR_DMA_CH2_CHANNEL == LL_DMA_CHANNEL_2 - LL_DMA_ClearFlag_TC2(IR_DMA); - LL_DMA_ClearFlag_HT2(IR_DMA); - LL_DMA_ClearFlag_TE2(IR_DMA); +#if INFRARED_DMA_CH2_CHANNEL == LL_DMA_CHANNEL_2 + LL_DMA_ClearFlag_TC2(INFRARED_DMA); + LL_DMA_ClearFlag_HT2(INFRARED_DMA); + LL_DMA_ClearFlag_TE2(INFRARED_DMA); #else #error Update this code. Would you kindly? #endif - LL_DMA_EnableIT_TC(IR_DMA_CH2_DEF); - LL_DMA_EnableIT_HT(IR_DMA_CH2_DEF); - LL_DMA_EnableIT_TE(IR_DMA_CH2_DEF); + LL_DMA_EnableIT_TC(INFRARED_DMA_CH2_DEF); + LL_DMA_EnableIT_HT(INFRARED_DMA_CH2_DEF); + LL_DMA_EnableIT_TE(INFRARED_DMA_CH2_DEF); - furi_hal_interrupt_set_isr_ex(IR_DMA_CH2_IRQ, 5, furi_hal_infrared_tx_dma_isr, NULL); + furi_hal_interrupt_set_isr_ex(INFRARED_DMA_CH2_IRQ, 5, furi_hal_infrared_tx_dma_isr, NULL); } static void furi_hal_infrared_tx_fill_buffer_last(uint8_t buf_num) { @@ -526,14 +541,14 @@ static void furi_hal_infrared_tx_dma_set_polarity(uint8_t buf_num, uint8_t polar furi_assert(buffer->polarity != NULL); FURI_CRITICAL_ENTER(); - bool channel_enabled = LL_DMA_IsEnabledChannel(IR_DMA_CH1_DEF); + bool channel_enabled = LL_DMA_IsEnabledChannel(INFRARED_DMA_CH1_DEF); if(channel_enabled) { - LL_DMA_DisableChannel(IR_DMA_CH1_DEF); + LL_DMA_DisableChannel(INFRARED_DMA_CH1_DEF); } - LL_DMA_SetMemoryAddress(IR_DMA_CH1_DEF, (uint32_t)buffer->polarity); - LL_DMA_SetDataLength(IR_DMA_CH1_DEF, buffer->size + polarity_shift); + LL_DMA_SetMemoryAddress(INFRARED_DMA_CH1_DEF, (uint32_t)buffer->polarity); + LL_DMA_SetDataLength(INFRARED_DMA_CH1_DEF, buffer->size + polarity_shift); if(channel_enabled) { - LL_DMA_EnableChannel(IR_DMA_CH1_DEF); + LL_DMA_EnableChannel(INFRARED_DMA_CH1_DEF); } FURI_CRITICAL_EXIT(); } @@ -546,14 +561,14 @@ static void furi_hal_infrared_tx_dma_set_buffer(uint8_t buf_num) { /* non-circular mode requires disabled channel before setup */ FURI_CRITICAL_ENTER(); - bool channel_enabled = LL_DMA_IsEnabledChannel(IR_DMA_CH2_DEF); + bool channel_enabled = LL_DMA_IsEnabledChannel(INFRARED_DMA_CH2_DEF); if(channel_enabled) { - LL_DMA_DisableChannel(IR_DMA_CH2_DEF); + LL_DMA_DisableChannel(INFRARED_DMA_CH2_DEF); } - LL_DMA_SetMemoryAddress(IR_DMA_CH2_DEF, (uint32_t)buffer->data); - LL_DMA_SetDataLength(IR_DMA_CH2_DEF, buffer->size); + LL_DMA_SetMemoryAddress(INFRARED_DMA_CH2_DEF, (uint32_t)buffer->data); + LL_DMA_SetDataLength(INFRARED_DMA_CH2_DEF, buffer->size); if(channel_enabled) { - LL_DMA_EnableChannel(IR_DMA_CH2_DEF); + LL_DMA_EnableChannel(INFRARED_DMA_CH2_DEF); } FURI_CRITICAL_EXIT(); } @@ -564,9 +579,10 @@ static void furi_hal_infrared_async_tx_free_resources(void) { (furi_hal_infrared_state == InfraredStateAsyncTxStopped)); furi_hal_gpio_init(&gpio_infrared_tx, GpioModeAnalog, GpioPullDown, GpioSpeedLow); - furi_hal_interrupt_set_isr(IR_DMA_CH1_IRQ, NULL, NULL); - furi_hal_interrupt_set_isr(IR_DMA_CH2_IRQ, NULL, NULL); - LL_TIM_DeInit(TIM1); + furi_hal_interrupt_set_isr(INFRARED_DMA_CH1_IRQ, NULL, NULL); + furi_hal_interrupt_set_isr(INFRARED_DMA_CH2_IRQ, NULL, NULL); + + furi_hal_bus_disable(INFRARED_DMA_TIMER_BUS); furi_semaphore_free(infrared_tim_tx.stop_semaphore); free(infrared_tim_tx.buffer[0].data); @@ -607,6 +623,8 @@ void furi_hal_infrared_async_tx_start(uint32_t freq, float duty_cycle) { furi_hal_infrared_tx_fill_buffer(0, INFRARED_POLARITY_SHIFT); + furi_hal_bus_enable(INFRARED_DMA_TIMER_BUS); + furi_hal_infrared_configure_tim_pwm_tx(freq, duty_cycle); furi_hal_infrared_configure_tim_cmgr2_dma_tx(); furi_hal_infrared_configure_tim_rcr_dma_tx(); @@ -615,11 +633,11 @@ void furi_hal_infrared_async_tx_start(uint32_t freq, float duty_cycle) { furi_hal_infrared_state = InfraredStateAsyncTx; - LL_TIM_ClearFlag_UPDATE(TIM1); - LL_DMA_EnableChannel(IR_DMA_CH1_DEF); - LL_DMA_EnableChannel(IR_DMA_CH2_DEF); + LL_TIM_ClearFlag_UPDATE(INFRARED_DMA_TIMER); + LL_DMA_EnableChannel(INFRARED_DMA_CH1_DEF); + LL_DMA_EnableChannel(INFRARED_DMA_CH2_DEF); furi_delay_us(5); - LL_TIM_GenerateEvent_UPDATE(TIM1); /* DMA -> TIMx_RCR */ + LL_TIM_GenerateEvent_UPDATE(INFRARED_DMA_TIMER); /* DMA -> TIMx_RCR */ furi_delay_us(5); LL_GPIO_ResetOutputPin( gpio_infrared_tx.port, gpio_infrared_tx.pin); /* when disable it prevents false pulse */ @@ -627,8 +645,8 @@ void furi_hal_infrared_async_tx_start(uint32_t freq, float duty_cycle) { &gpio_infrared_tx, GpioModeAltFunctionPushPull, GpioPullUp, GpioSpeedHigh, GpioAltFn1TIM1); FURI_CRITICAL_ENTER(); - LL_TIM_GenerateEvent_UPDATE(TIM1); /* TIMx_RCR -> Repetition counter */ - LL_TIM_EnableCounter(TIM1); + LL_TIM_GenerateEvent_UPDATE(INFRARED_DMA_TIMER); /* TIMx_RCR -> Repetition counter */ + LL_TIM_EnableCounter(INFRARED_DMA_TIMER); FURI_CRITICAL_EXIT(); } diff --git a/firmware/targets/f7/furi_hal/furi_hal_pwm.c b/firmware/targets/f7/furi_hal/furi_hal_pwm.c index 8f84b5fd8..7e985cbb1 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_pwm.c +++ b/firmware/targets/f7/furi_hal/furi_hal_pwm.c @@ -1,8 +1,7 @@ #include -#include #include +#include -#include #include #include #include @@ -29,9 +28,7 @@ void furi_hal_pwm_start(FuriHalPwmOutputId channel, uint32_t freq, uint8_t duty) GpioSpeedVeryHigh, GpioAltFn1TIM1); - FURI_CRITICAL_ENTER(); - LL_TIM_DeInit(TIM1); - FURI_CRITICAL_EXIT(); + furi_hal_bus_enable(FuriHalBusTIM1); LL_TIM_SetCounterMode(TIM1, LL_TIM_COUNTERMODE_UP); LL_TIM_SetRepetitionCounter(TIM1, 0); @@ -58,9 +55,7 @@ void furi_hal_pwm_start(FuriHalPwmOutputId channel, uint32_t freq, uint8_t duty) GpioSpeedVeryHigh, GpioAltFn14LPTIM2); - FURI_CRITICAL_ENTER(); - LL_LPTIM_DeInit(LPTIM2); - FURI_CRITICAL_EXIT(); + furi_hal_bus_enable(FuriHalBusLPTIM2); LL_LPTIM_SetUpdateMode(LPTIM2, LL_LPTIM_UPDATE_MODE_ENDOFPERIOD); LL_RCC_SetLPTIMClockSource(LL_RCC_LPTIM2_CLKSOURCE_PCLK1); @@ -80,14 +75,10 @@ void furi_hal_pwm_start(FuriHalPwmOutputId channel, uint32_t freq, uint8_t duty) void furi_hal_pwm_stop(FuriHalPwmOutputId channel) { if(channel == FuriHalPwmOutputIdTim1PA7) { furi_hal_gpio_init_simple(&gpio_ext_pa7, GpioModeAnalog); - FURI_CRITICAL_ENTER(); - LL_TIM_DeInit(TIM1); - FURI_CRITICAL_EXIT(); + furi_hal_bus_disable(FuriHalBusTIM1); } else if(channel == FuriHalPwmOutputIdLptim2PA4) { furi_hal_gpio_init_simple(&gpio_ext_pa4, GpioModeAnalog); - FURI_CRITICAL_ENTER(); - LL_LPTIM_DeInit(LPTIM2); - FURI_CRITICAL_EXIT(); + furi_hal_bus_disable(FuriHalBusLPTIM2); } } diff --git a/firmware/targets/f7/furi_hal/furi_hal_random.c b/firmware/targets/f7/furi_hal/furi_hal_random.c index d3461c4d1..cf4b552f6 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_random.c +++ b/firmware/targets/f7/furi_hal/furi_hal_random.c @@ -1,8 +1,9 @@ #include +#include #include -#include #include +#include #include #include @@ -32,6 +33,11 @@ static uint32_t furi_hal_random_read_rng() { return LL_RNG_ReadRandData32(RNG); } +void furi_hal_random_init() { + furi_hal_bus_enable(FuriHalBusRNG); + LL_RCC_SetRNGClockSource(LL_RCC_RNG_CLKSOURCE_CLK48); +} + uint32_t furi_hal_random_get() { while(LL_HSEM_1StepLock(HSEM, CFG_HW_RNG_SEMID)) ; @@ -40,6 +46,7 @@ uint32_t furi_hal_random_get() { const uint32_t random_val = furi_hal_random_read_rng(); LL_RNG_Disable(RNG); + ; LL_HSEM_ReleaseLock(HSEM, CFG_HW_RNG_SEMID, 0); return random_val; diff --git a/firmware/targets/f7/furi_hal/furi_hal_resources.c b/firmware/targets/f7/furi_hal/furi_hal_resources.c index abfd977e5..561cef08a 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_resources.c +++ b/firmware/targets/f7/furi_hal/furi_hal_resources.c @@ -1,4 +1,5 @@ #include +#include #include #include @@ -106,6 +107,13 @@ static void furi_hal_resources_init_input_pins(GpioMode mode) { } void furi_hal_resources_init_early() { + furi_hal_bus_enable(FuriHalBusGPIOA); + furi_hal_bus_enable(FuriHalBusGPIOB); + furi_hal_bus_enable(FuriHalBusGPIOC); + furi_hal_bus_enable(FuriHalBusGPIOD); + furi_hal_bus_enable(FuriHalBusGPIOE); + furi_hal_bus_enable(FuriHalBusGPIOH); + furi_hal_resources_init_input_pins(GpioModeInput); // SD Card stepdown control @@ -150,6 +158,12 @@ void furi_hal_resources_init_early() { void furi_hal_resources_deinit_early() { furi_hal_resources_init_input_pins(GpioModeAnalog); + furi_hal_bus_disable(FuriHalBusGPIOA); + furi_hal_bus_disable(FuriHalBusGPIOB); + furi_hal_bus_disable(FuriHalBusGPIOC); + furi_hal_bus_disable(FuriHalBusGPIOD); + furi_hal_bus_disable(FuriHalBusGPIOE); + furi_hal_bus_disable(FuriHalBusGPIOH); } void furi_hal_resources_init() { diff --git a/firmware/targets/f7/furi_hal/furi_hal_rfid.c b/firmware/targets/f7/furi_hal/furi_hal_rfid.c index 145e49df2..fa0c19b09 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_rfid.c +++ b/firmware/targets/f7/furi_hal/furi_hal_rfid.c @@ -2,6 +2,7 @@ #include #include #include +#include #include #include @@ -9,15 +10,18 @@ #include #define FURI_HAL_RFID_READ_TIMER TIM1 +#define FURI_HAL_RFID_READ_TIMER_BUS FuriHalBusTIM1 #define FURI_HAL_RFID_READ_TIMER_CHANNEL LL_TIM_CHANNEL_CH1N // We can't use N channel for LL_TIM_OC_Init, so... #define FURI_HAL_RFID_READ_TIMER_CHANNEL_CONFIG LL_TIM_CHANNEL_CH1 #define FURI_HAL_RFID_EMULATE_TIMER TIM2 +#define FURI_HAL_RFID_EMULATE_TIMER_BUS FuriHalBusTIM2 #define FURI_HAL_RFID_EMULATE_TIMER_IRQ FuriHalInterruptIdTIM2 #define FURI_HAL_RFID_EMULATE_TIMER_CHANNEL LL_TIM_CHANNEL_CH3 #define RFID_CAPTURE_TIM TIM2 +#define RFID_CAPTURE_TIM_BUS FuriHalBusTIM2 #define RFID_CAPTURE_IND_CH LL_TIM_CHANNEL_CH3 #define RFID_CAPTURE_DIR_CH LL_TIM_CHANNEL_CH4 @@ -30,7 +34,6 @@ #define RFID_DMA_CH2_DEF RFID_DMA, RFID_DMA_CH2_CHANNEL typedef struct { - FuriHalRfidEmulateCallback callback; FuriHalRfidDMACallback dma_callback; FuriHalRfidReadCaptureCallback read_capture_callback; void* context; @@ -56,11 +59,7 @@ void furi_hal_rfid_init() { COMP_InitStruct.InputPlus = LL_COMP_INPUT_PLUS_IO1; COMP_InitStruct.InputMinus = LL_COMP_INPUT_MINUS_1_2VREFINT; COMP_InitStruct.InputHysteresis = LL_COMP_HYSTERESIS_HIGH; -#ifdef INVERT_RFID_IN - COMP_InitStruct.OutputPolarity = LL_COMP_OUTPUTPOL_INVERTED; -#else COMP_InitStruct.OutputPolarity = LL_COMP_OUTPUTPOL_NONINVERTED; -#endif COMP_InitStruct.OutputBlankingSource = LL_COMP_BLANKINGSRC_NONE; LL_COMP_Init(COMP1, &COMP_InitStruct); LL_COMP_SetCommonWindowMode(__LL_COMP_COMMON_INSTANCE(COMP1), LL_COMP_WINDOWMODE_DISABLE); @@ -92,7 +91,7 @@ void furi_hal_rfid_pins_reset() { furi_hal_gpio_init(&gpio_rfid_data_in, GpioModeAnalog, GpioPullNo, GpioSpeedLow); } -void furi_hal_rfid_pins_emulate() { +static void furi_hal_rfid_pins_emulate() { // ibutton low furi_hal_ibutton_pin_configure(); furi_hal_ibutton_pin_write(false); @@ -113,7 +112,7 @@ void furi_hal_rfid_pins_emulate() { &gpio_rfid_carrier, GpioModeAltFunctionPushPull, GpioPullNo, GpioSpeedLow, GpioAltFn2TIM2); } -void furi_hal_rfid_pins_read() { +static void furi_hal_rfid_pins_read() { // ibutton low furi_hal_ibutton_pin_configure(); furi_hal_ibutton_pin_write(false); @@ -142,10 +141,10 @@ void furi_hal_rfid_pin_pull_pulldown() { furi_hal_gpio_write(&gpio_nfc_irq_rfid_pull, false); } -void furi_hal_rfid_tim_read(float freq, float duty_cycle) { - FURI_CRITICAL_ENTER(); - LL_TIM_DeInit(FURI_HAL_RFID_READ_TIMER); - FURI_CRITICAL_EXIT(); +void furi_hal_rfid_tim_read_start(float freq, float duty_cycle) { + furi_hal_bus_enable(FURI_HAL_RFID_READ_TIMER_BUS); + + furi_hal_rfid_pins_read(); LL_TIM_InitTypeDef TIM_InitStruct = {0}; TIM_InitStruct.Autoreload = (SystemCoreClock / freq) - 1; @@ -160,23 +159,23 @@ void furi_hal_rfid_tim_read(float freq, float duty_cycle) { FURI_HAL_RFID_READ_TIMER, FURI_HAL_RFID_READ_TIMER_CHANNEL_CONFIG, &TIM_OC_InitStruct); LL_TIM_EnableCounter(FURI_HAL_RFID_READ_TIMER); + + furi_hal_rfid_tim_read_continue(); } -void furi_hal_rfid_tim_read_start() { +void furi_hal_rfid_tim_read_continue() { LL_TIM_EnableAllOutputs(FURI_HAL_RFID_READ_TIMER); } -void furi_hal_rfid_tim_read_stop() { +void furi_hal_rfid_tim_read_pause() { LL_TIM_DisableAllOutputs(FURI_HAL_RFID_READ_TIMER); } -void furi_hal_rfid_tim_emulate(float freq) { - UNUSED(freq); // FIXME - // basic PWM setup with needed freq and internal clock - FURI_CRITICAL_ENTER(); - LL_TIM_DeInit(FURI_HAL_RFID_EMULATE_TIMER); - FURI_CRITICAL_EXIT(); +void furi_hal_rfid_tim_read_stop() { + furi_hal_bus_disable(FURI_HAL_RFID_READ_TIMER_BUS); +} +static void furi_hal_rfid_tim_emulate() { LL_TIM_SetPrescaler(FURI_HAL_RFID_EMULATE_TIMER, 0); LL_TIM_SetCounterMode(FURI_HAL_RFID_EMULATE_TIMER, LL_TIM_COUNTERMODE_UP); LL_TIM_SetAutoReload(FURI_HAL_RFID_EMULATE_TIMER, 1); @@ -201,32 +200,6 @@ void furi_hal_rfid_tim_emulate(float freq) { LL_TIM_GenerateEvent_UPDATE(FURI_HAL_RFID_EMULATE_TIMER); } -static void furi_hal_rfid_emulate_isr() { - if(LL_TIM_IsActiveFlag_UPDATE(FURI_HAL_RFID_EMULATE_TIMER)) { - LL_TIM_ClearFlag_UPDATE(FURI_HAL_RFID_EMULATE_TIMER); - furi_hal_rfid->callback(furi_hal_rfid->context); - } -} - -void furi_hal_rfid_tim_emulate_start(FuriHalRfidEmulateCallback callback, void* context) { - furi_assert(furi_hal_rfid); - - furi_hal_rfid->callback = callback; - furi_hal_rfid->context = context; - - furi_hal_interrupt_set_isr(FURI_HAL_RFID_EMULATE_TIMER_IRQ, furi_hal_rfid_emulate_isr, NULL); - - LL_TIM_EnableIT_UPDATE(FURI_HAL_RFID_EMULATE_TIMER); - LL_TIM_EnableAllOutputs(FURI_HAL_RFID_EMULATE_TIMER); - LL_TIM_EnableCounter(FURI_HAL_RFID_EMULATE_TIMER); -} - -void furi_hal_rfid_tim_emulate_stop() { - LL_TIM_DisableCounter(FURI_HAL_RFID_EMULATE_TIMER); - LL_TIM_DisableAllOutputs(FURI_HAL_RFID_EMULATE_TIMER); - furi_hal_interrupt_set_isr(FURI_HAL_RFID_EMULATE_TIMER_IRQ, NULL, NULL); -} - static void furi_hal_capture_dma_isr(void* context) { UNUSED(context); @@ -247,15 +220,13 @@ static void furi_hal_capture_dma_isr(void* context) { } void furi_hal_rfid_tim_read_capture_start(FuriHalRfidReadCaptureCallback callback, void* context) { - FURI_CRITICAL_ENTER(); - LL_TIM_DeInit(RFID_CAPTURE_TIM); - FURI_CRITICAL_EXIT(); - furi_assert(furi_hal_rfid); furi_hal_rfid->read_capture_callback = callback; furi_hal_rfid->context = context; + furi_hal_bus_enable(RFID_CAPTURE_TIM_BUS); + // Timer: base LL_TIM_InitTypeDef TIM_InitStruct = {0}; TIM_InitStruct.Prescaler = 64 - 1; @@ -303,10 +274,7 @@ void furi_hal_rfid_tim_read_capture_stop() { furi_hal_rfid_comp_stop(); furi_hal_interrupt_set_isr(FURI_HAL_RFID_EMULATE_TIMER_IRQ, NULL, NULL); - - FURI_CRITICAL_ENTER(); - LL_TIM_DeInit(RFID_CAPTURE_TIM); - FURI_CRITICAL_EXIT(); + furi_hal_bus_disable(RFID_CAPTURE_TIM_BUS); } static void furi_hal_rfid_dma_isr() { @@ -341,7 +309,8 @@ void furi_hal_rfid_tim_emulate_dma_start( furi_hal_rfid_pins_emulate(); // configure timer - furi_hal_rfid_tim_emulate(125000); + furi_hal_bus_enable(FURI_HAL_RFID_EMULATE_TIMER_BUS); + furi_hal_rfid_tim_emulate(); LL_TIM_OC_SetPolarity( FURI_HAL_RFID_EMULATE_TIMER, FURI_HAL_RFID_EMULATE_TIMER_CHANNEL, LL_TIM_OCPOLARITY_HIGH); LL_TIM_EnableDMAReq_UPDATE(FURI_HAL_RFID_EMULATE_TIMER); @@ -405,32 +374,12 @@ void furi_hal_rfid_tim_emulate_dma_stop() { LL_DMA_DeInit(RFID_DMA_CH1_DEF); LL_DMA_DeInit(RFID_DMA_CH2_DEF); - LL_TIM_DeInit(FURI_HAL_RFID_EMULATE_TIMER); + + furi_hal_bus_disable(FURI_HAL_RFID_EMULATE_TIMER_BUS); FURI_CRITICAL_EXIT(); } -void furi_hal_rfid_tim_reset() { - FURI_CRITICAL_ENTER(); - - LL_TIM_DeInit(FURI_HAL_RFID_READ_TIMER); - LL_TIM_DeInit(FURI_HAL_RFID_EMULATE_TIMER); - - FURI_CRITICAL_EXIT(); -} - -void furi_hal_rfid_set_emulate_period(uint32_t period) { - LL_TIM_SetAutoReload(FURI_HAL_RFID_EMULATE_TIMER, period); -} - -void furi_hal_rfid_set_emulate_pulse(uint32_t pulse) { -#if FURI_HAL_RFID_EMULATE_TIMER_CHANNEL == LL_TIM_CHANNEL_CH3 - LL_TIM_OC_SetCompareCH3(FURI_HAL_RFID_EMULATE_TIMER, pulse); -#else -#error Update this code. Would you kindly? -#endif -} - void furi_hal_rfid_set_read_period(uint32_t period) { LL_TIM_SetAutoReload(FURI_HAL_RFID_READ_TIMER, period); } @@ -443,12 +392,6 @@ void furi_hal_rfid_set_read_pulse(uint32_t pulse) { #endif } -void furi_hal_rfid_change_read_config(float freq, float duty_cycle) { - uint32_t period = (uint32_t)((SystemCoreClock) / freq) - 1; - furi_hal_rfid_set_read_period(period); - furi_hal_rfid_set_read_pulse(period * duty_cycle); -} - void furi_hal_rfid_comp_start() { LL_COMP_Enable(COMP1); // Magic @@ -483,4 +426,4 @@ void COMP_IRQHandler() { (LL_COMP_ReadOutputLevel(COMP1) == LL_COMP_OUTPUT_LEVEL_LOW), furi_hal_rfid_comp_callback_context); } -} \ No newline at end of file +} diff --git a/firmware/targets/f7/furi_hal/furi_hal_rfid.h b/firmware/targets/f7/furi_hal/furi_hal_rfid.h index 36563c1d1..78d9b6658 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_rfid.h +++ b/firmware/targets/f7/furi_hal/furi_hal_rfid.h @@ -21,14 +21,6 @@ void furi_hal_rfid_init(); */ void furi_hal_rfid_pins_reset(); -/** Config rfid pins to emulate state - */ -void furi_hal_rfid_pins_emulate(); - -/** Config rfid pins to read state - */ -void furi_hal_rfid_pins_read(); - /** Release rfid pull pin */ void furi_hal_rfid_pin_pull_release(); @@ -37,33 +29,24 @@ void furi_hal_rfid_pin_pull_release(); */ void furi_hal_rfid_pin_pull_pulldown(); -/** Config rfid timer to read state - * +/** Start read timer * @param freq timer frequency * @param duty_cycle timer duty cycle, 0.0-1.0 */ -void furi_hal_rfid_tim_read(float freq, float duty_cycle); +void furi_hal_rfid_tim_read_start(float freq, float duty_cycle); -/** Start read timer +/** Pause read timer, to be able to continue later */ -void furi_hal_rfid_tim_read_start(); +void furi_hal_rfid_tim_read_pause(); + +/** Continue read timer + */ +void furi_hal_rfid_tim_read_continue(); /** Stop read timer */ void furi_hal_rfid_tim_read_stop(); -/** Config rfid timer to emulate state - * - * @param freq timer frequency - */ -void furi_hal_rfid_tim_emulate(float freq); - -typedef void (*FuriHalRfidEmulateCallback)(void* context); - -/** Start emulation timer - */ -void furi_hal_rfid_tim_emulate_start(FuriHalRfidEmulateCallback callback, void* context); - typedef void (*FuriHalRfidReadCaptureCallback)(bool level, uint32_t duration, void* context); void furi_hal_rfid_tim_read_capture_start(FuriHalRfidReadCaptureCallback callback, void* context); @@ -81,26 +64,6 @@ void furi_hal_rfid_tim_emulate_dma_start( void furi_hal_rfid_tim_emulate_dma_stop(); -/** Stop emulation timer - */ -void furi_hal_rfid_tim_emulate_stop(); - -/** Config rfid timers to reset state - */ -void furi_hal_rfid_tim_reset(); - -/** Set emulation timer period - * - * @param period overall duration - */ -void furi_hal_rfid_set_emulate_period(uint32_t period); - -/** Set emulation timer pulse - * - * @param pulse duration of high level - */ -void furi_hal_rfid_set_emulate_pulse(uint32_t pulse); - /** Set read timer period * * @param period overall duration @@ -113,13 +76,6 @@ void furi_hal_rfid_set_read_period(uint32_t period); */ void furi_hal_rfid_set_read_pulse(uint32_t pulse); -/** Сhanges the configuration of the RFID timer "on a fly" - * - * @param freq new frequency - * @param duty_cycle new duty cycle - */ -void furi_hal_rfid_change_read_config(float freq, float duty_cycle); - /** Start/Enable comparator */ void furi_hal_rfid_comp_start(); diff --git a/firmware/targets/f7/furi_hal/furi_hal_rtc.c b/firmware/targets/f7/furi_hal/furi_hal_rtc.c index 8dfe1a13e..a8e25faad 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_rtc.c +++ b/firmware/targets/f7/furi_hal/furi_hal_rtc.c @@ -2,8 +2,8 @@ #include #include -#include #include +#include #include #include #include diff --git a/firmware/targets/f7/furi_hal/furi_hal_speaker.c b/firmware/targets/f7/furi_hal/furi_hal_speaker.c index 5421509cc..ad7ed994a 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_speaker.c +++ b/firmware/targets/f7/furi_hal/furi_hal_speaker.c @@ -2,6 +2,7 @@ #include #include #include +#include #include #include @@ -20,16 +21,11 @@ static FuriMutex* furi_hal_speaker_mutex = NULL; void furi_hal_speaker_init() { furi_assert(furi_hal_speaker_mutex == NULL); furi_hal_speaker_mutex = furi_mutex_alloc(FuriMutexTypeNormal); - FURI_CRITICAL_ENTER(); - LL_TIM_DeInit(FURI_HAL_SPEAKER_TIMER); - FURI_CRITICAL_EXIT(); FURI_LOG_I(TAG, "Init OK"); } void furi_hal_speaker_deinit() { furi_check(furi_hal_speaker_mutex != NULL); - LL_TIM_DeInit(FURI_HAL_SPEAKER_TIMER); - furi_hal_gpio_init(&gpio_speaker, GpioModeAnalog, GpioPullNo, GpioSpeedLow); furi_mutex_free(furi_hal_speaker_mutex); furi_hal_speaker_mutex = NULL; } @@ -39,6 +35,7 @@ bool furi_hal_speaker_acquire(uint32_t timeout) { if(furi_mutex_acquire(furi_hal_speaker_mutex, timeout) == FuriStatusOk) { furi_hal_power_insomnia_enter(); + furi_hal_bus_enable(FuriHalBusTIM16); furi_hal_gpio_init_ex( &gpio_speaker, GpioModeAltFunctionPushPull, GpioPullNo, GpioSpeedLow, GpioAltFn14TIM16); return true; @@ -53,6 +50,8 @@ void furi_hal_speaker_release() { furi_hal_speaker_stop(); furi_hal_gpio_init(&gpio_speaker, GpioModeAnalog, GpioPullDown, GpioSpeedLow); + + furi_hal_bus_disable(FuriHalBusTIM16); furi_hal_power_insomnia_exit(); furi_check(furi_mutex_release(furi_hal_speaker_mutex) == FuriStatusOk); diff --git a/firmware/targets/f7/furi_hal/furi_hal_spi_config.c b/firmware/targets/f7/furi_hal/furi_hal_spi_config.c index 9cf332dac..09ac79d2a 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_spi_config.c +++ b/firmware/targets/f7/furi_hal/furi_hal_spi_config.c @@ -1,6 +1,7 @@ #include #include #include +#include #include #define TAG "FuriHalSpiConfig" @@ -100,28 +101,17 @@ void furi_hal_spi_config_init() { static void furi_hal_spi_bus_r_event_callback(FuriHalSpiBus* bus, FuriHalSpiBusEvent event) { if(event == FuriHalSpiBusEventInit) { furi_hal_spi_bus_r_mutex = furi_mutex_alloc(FuriMutexTypeNormal); - FURI_CRITICAL_ENTER(); - LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_SPI1); - FURI_CRITICAL_EXIT(); bus->current_handle = NULL; } else if(event == FuriHalSpiBusEventDeinit) { furi_mutex_free(furi_hal_spi_bus_r_mutex); - FURI_CRITICAL_ENTER(); - LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_SPI1); - LL_APB2_GRP1_ReleaseReset(LL_APB2_GRP1_PERIPH_SPI1); - FURI_CRITICAL_EXIT(); } else if(event == FuriHalSpiBusEventLock) { furi_check(furi_mutex_acquire(furi_hal_spi_bus_r_mutex, FuriWaitForever) == FuriStatusOk); } else if(event == FuriHalSpiBusEventUnlock) { furi_check(furi_mutex_release(furi_hal_spi_bus_r_mutex) == FuriStatusOk); } else if(event == FuriHalSpiBusEventActivate) { - FURI_CRITICAL_ENTER(); - LL_APB2_GRP1_ReleaseReset(LL_APB2_GRP1_PERIPH_SPI1); - FURI_CRITICAL_EXIT(); + furi_hal_bus_enable(FuriHalBusSPI1); } else if(event == FuriHalSpiBusEventDeactivate) { - FURI_CRITICAL_ENTER(); - LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_SPI1); - FURI_CRITICAL_EXIT(); + furi_hal_bus_disable(FuriHalBusSPI1); } } @@ -135,28 +125,17 @@ FuriMutex* furi_hal_spi_bus_d_mutex = NULL; static void furi_hal_spi_bus_d_event_callback(FuriHalSpiBus* bus, FuriHalSpiBusEvent event) { if(event == FuriHalSpiBusEventInit) { furi_hal_spi_bus_d_mutex = furi_mutex_alloc(FuriMutexTypeNormal); - FURI_CRITICAL_ENTER(); - LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_SPI2); - FURI_CRITICAL_EXIT(); bus->current_handle = NULL; } else if(event == FuriHalSpiBusEventDeinit) { furi_mutex_free(furi_hal_spi_bus_d_mutex); - FURI_CRITICAL_ENTER(); - LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_SPI2); - LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_SPI2); - FURI_CRITICAL_EXIT(); } else if(event == FuriHalSpiBusEventLock) { furi_check(furi_mutex_acquire(furi_hal_spi_bus_d_mutex, FuriWaitForever) == FuriStatusOk); } else if(event == FuriHalSpiBusEventUnlock) { furi_check(furi_mutex_release(furi_hal_spi_bus_d_mutex) == FuriStatusOk); } else if(event == FuriHalSpiBusEventActivate) { - FURI_CRITICAL_ENTER(); - LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_SPI2); - FURI_CRITICAL_EXIT(); + furi_hal_bus_enable(FuriHalBusSPI2); } else if(event == FuriHalSpiBusEventDeactivate) { - FURI_CRITICAL_ENTER(); - LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_SPI2); - FURI_CRITICAL_EXIT(); + furi_hal_bus_disable(FuriHalBusSPI2); } } diff --git a/firmware/targets/f7/furi_hal/furi_hal_spi_types.h b/firmware/targets/f7/furi_hal/furi_hal_spi_types.h index d2273f38b..ecc18d50d 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_spi_types.h +++ b/firmware/targets/f7/furi_hal/furi_hal_spi_types.h @@ -6,8 +6,6 @@ #include #include -#include -#include #ifdef __cplusplus extern "C" { diff --git a/firmware/targets/f7/furi_hal/furi_hal_subghz.c b/firmware/targets/f7/furi_hal/furi_hal_subghz.c index 596464613..6d671a9e1 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_subghz.c +++ b/firmware/targets/f7/furi_hal/furi_hal_subghz.c @@ -7,6 +7,7 @@ #include #include #include +#include #include @@ -433,6 +434,8 @@ void furi_hal_subghz_start_async_rx(FuriHalSubGhzCaptureCallback callback, void* furi_hal_gpio_init_ex( &gpio_cc1101_g0, GpioModeAltFunctionPushPull, GpioPullNo, GpioSpeedLow, GpioAltFn1TIM2); + furi_hal_bus_enable(FuriHalBusTIM2); + // Timer: base LL_TIM_InitTypeDef TIM_InitStruct = {0}; TIM_InitStruct.Prescaler = 64 - 1; @@ -496,7 +499,7 @@ void furi_hal_subghz_stop_async_rx() { furi_hal_subghz_idle(); FURI_CRITICAL_ENTER(); - LL_TIM_DeInit(TIM2); + furi_hal_bus_disable(FuriHalBusTIM2); // Stop debug furi_hal_subghz_stop_debug(); @@ -658,6 +661,8 @@ bool furi_hal_subghz_start_async_tx(FuriHalSubGhzAsyncTxCallback callback, void* LL_DMA_EnableIT_HT(SUBGHZ_DMA_CH1_DEF); LL_DMA_EnableChannel(SUBGHZ_DMA_CH1_DEF); + furi_hal_bus_enable(FuriHalBusTIM2); + // Configure TIM2 LL_TIM_InitTypeDef TIM_InitStruct = {0}; TIM_InitStruct.Prescaler = 64 - 1; @@ -740,7 +745,7 @@ void furi_hal_subghz_stop_async_tx() { // Deinitialize Timer FURI_CRITICAL_ENTER(); - LL_TIM_DeInit(TIM2); + furi_hal_bus_disable(FuriHalBusTIM2); furi_hal_interrupt_set_isr(FuriHalInterruptIdTIM2, NULL, NULL); // Deinitialize DMA diff --git a/firmware/targets/f7/furi_hal/furi_hal_uart.c b/firmware/targets/f7/furi_hal/furi_hal_uart.c index 71b5c7ba0..209c6be6a 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_uart.c +++ b/firmware/targets/f7/furi_hal/furi_hal_uart.c @@ -4,6 +4,7 @@ #include #include #include +#include #include @@ -13,6 +14,9 @@ static void (*irq_cb[2])(uint8_t ev, uint8_t data, void* context); static void* irq_ctx[2]; static void furi_hal_usart_init(uint32_t baud) { + furi_hal_bus_enable(FuriHalBusUSART1); + LL_RCC_SetUSARTClockSource(LL_RCC_USART1_CLKSOURCE_PCLK2); + furi_hal_gpio_init_ex( &gpio_usart_tx, GpioModeAltFunctionPushPull, @@ -50,6 +54,9 @@ static void furi_hal_usart_init(uint32_t baud) { } static void furi_hal_lpuart_init(uint32_t baud) { + furi_hal_bus_enable(FuriHalBusLPUART1); + LL_RCC_SetLPUARTClockSource(LL_RCC_LPUART1_CLKSOURCE_PCLK1); + furi_hal_gpio_init_ex( &gpio_ext_pc0, GpioModeAltFunctionPushPull, @@ -86,10 +93,11 @@ static void furi_hal_lpuart_init(uint32_t baud) { } void furi_hal_uart_init(FuriHalUartId ch, uint32_t baud) { - if(ch == FuriHalUartIdLPUART1) + if(ch == FuriHalUartIdLPUART1) { furi_hal_lpuart_init(baud); - else if(ch == FuriHalUartIdUSART1) + } else if(ch == FuriHalUartIdUSART1) { furi_hal_usart_init(baud); + } } void furi_hal_uart_set_br(FuriHalUartId ch, uint32_t baud) { @@ -126,11 +134,15 @@ void furi_hal_uart_set_br(FuriHalUartId ch, uint32_t baud) { void furi_hal_uart_deinit(FuriHalUartId ch) { furi_hal_uart_set_irq_cb(ch, NULL, NULL); if(ch == FuriHalUartIdUSART1) { - LL_USART_Disable(USART1); + if(furi_hal_bus_is_enabled(FuriHalBusUSART1)) { + furi_hal_bus_disable(FuriHalBusUSART1); + } furi_hal_gpio_init(&gpio_usart_tx, GpioModeAnalog, GpioPullNo, GpioSpeedLow); furi_hal_gpio_init(&gpio_usart_rx, GpioModeAnalog, GpioPullNo, GpioSpeedLow); } else if(ch == FuriHalUartIdLPUART1) { - LL_LPUART_Disable(LPUART1); + if(furi_hal_bus_is_enabled(FuriHalBusLPUART1)) { + furi_hal_bus_disable(FuriHalBusLPUART1); + } furi_hal_gpio_init(&gpio_ext_pc0, GpioModeAnalog, GpioPullNo, GpioSpeedLow); furi_hal_gpio_init(&gpio_ext_pc1, GpioModeAnalog, GpioPullNo, GpioSpeedLow); } diff --git a/firmware/targets/f7/furi_hal/furi_hal_usb.c b/firmware/targets/f7/furi_hal/furi_hal_usb.c index 011add953..b88168d5d 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_usb.c +++ b/firmware/targets/f7/furi_hal/furi_hal_usb.c @@ -2,7 +2,9 @@ #include #include #include + #include +#include #include #include @@ -86,6 +88,8 @@ static void wkup_evt(usbd_device* dev, uint8_t event, uint8_t ep); /* Low-level init */ void furi_hal_usb_init(void) { + LL_RCC_SetUSBClockSource(LL_RCC_USB_CLKSOURCE_PLLSAI1); + LL_GPIO_InitTypeDef GPIO_InitStruct = {0}; LL_PWR_EnableVddUSB(); @@ -98,7 +102,10 @@ void furi_hal_usb_init(void) { LL_GPIO_Init(GPIOA, &GPIO_InitStruct); usbd_init(&udev, &usbd_hw, USB_EP0_SIZE, ubuf, sizeof(ubuf)); + + FURI_CRITICAL_ENTER(); usbd_enable(&udev, true); + FURI_CRITICAL_EXIT(); usbd_reg_descr(&udev, usb_descriptor_get); usbd_reg_event(&udev, usbd_evt_susp, susp_evt); @@ -359,8 +366,10 @@ static void usb_process_mode_reinit() { usbd_connect(&udev, false); usb.enabled = false; + FURI_CRITICAL_ENTER(); usbd_enable(&udev, false); usbd_enable(&udev, true); + FURI_CRITICAL_EXIT(); furi_delay_ms(USB_RECONNECT_DELAY); usb_process_mode_start(usb.interface, usb.interface_context); diff --git a/firmware/targets/f7/src/update.c b/firmware/targets/f7/src/update.c index c1e1084c2..c6235a150 100644 --- a/firmware/targets/f7/src/update.c +++ b/firmware/targets/f7/src/update.c @@ -38,6 +38,12 @@ static bool flipper_update_mount_sd() { } static bool flipper_update_init() { + // TODO: Configure missing peripherals properly + furi_hal_bus_enable(FuriHalBusHSEM); + furi_hal_bus_enable(FuriHalBusIPCC); + furi_hal_bus_enable(FuriHalBusRNG); + furi_hal_bus_enable(FuriHalBusUSART1); + furi_hal_clock_init(); furi_hal_rtc_init(); furi_hal_interrupt_init(); diff --git a/firmware/targets/furi_hal_include/furi_hal.h b/firmware/targets/furi_hal_include/furi_hal.h index 2eb4688d4..9341dccec 100644 --- a/firmware/targets/furi_hal_include/furi_hal.h +++ b/firmware/targets/furi_hal_include/furi_hal.h @@ -12,9 +12,11 @@ struct STOP_EXTERNING_ME {}; #include #include +#include #include #include #include +#include #include #include #include diff --git a/firmware/targets/furi_hal_include/furi_hal_random.h b/firmware/targets/furi_hal_include/furi_hal_random.h index ee69326f4..5ca9cb723 100644 --- a/firmware/targets/furi_hal_include/furi_hal_random.h +++ b/firmware/targets/furi_hal_include/furi_hal_random.h @@ -6,6 +6,9 @@ extern "C" { #endif +/** Initialize random subsystem */ +void furi_hal_random_init(); + /** Get random value * * @return random value diff --git a/lib/digital_signal/digital_signal.c b/lib/digital_signal/digital_signal.c index 51a87d22a..ab25458b5 100644 --- a/lib/digital_signal/digital_signal.c +++ b/lib/digital_signal/digital_signal.c @@ -243,10 +243,12 @@ static void digital_signal_stop_timer() { LL_TIM_DisableCounter(TIM2); LL_TIM_DisableUpdateEvent(TIM2); LL_TIM_DisableDMAReq_UPDATE(TIM2); + + furi_hal_bus_disable(FuriHalBusTIM2); } static void digital_signal_setup_timer() { - digital_signal_stop_timer(); + furi_hal_bus_enable(FuriHalBusTIM2); LL_TIM_SetCounterMode(TIM2, LL_TIM_COUNTERMODE_UP); LL_TIM_SetClockDivision(TIM2, LL_TIM_CLOCKDIVISION_DIV1); diff --git a/lib/lfrfid/lfrfid_raw_worker.c b/lib/lfrfid/lfrfid_raw_worker.c index 22c0bbd02..aa962a47d 100644 --- a/lib/lfrfid/lfrfid_raw_worker.c +++ b/lib/lfrfid/lfrfid_raw_worker.c @@ -151,9 +151,7 @@ static int32_t lfrfid_raw_read_worker_thread(void* thread_context) { if(file_valid) { // setup carrier - furi_hal_rfid_pins_read(); - furi_hal_rfid_tim_read(worker->frequency, worker->duty_cycle); - furi_hal_rfid_tim_read_start(); + furi_hal_rfid_tim_read_start(worker->frequency, worker->duty_cycle); // stabilize detector furi_delay_ms(1500); diff --git a/lib/lfrfid/lfrfid_worker_modes.c b/lib/lfrfid/lfrfid_worker_modes.c index 9b6f16eb1..8a2667774 100644 --- a/lib/lfrfid/lfrfid_worker_modes.c +++ b/lib/lfrfid/lfrfid_worker_modes.c @@ -100,24 +100,21 @@ static LFRFIDWorkerReadState lfrfid_worker_read_internal( uint32_t timeout, ProtocolId* result_protocol) { LFRFIDWorkerReadState state = LFRFIDWorkerReadTimeout; - furi_hal_rfid_pins_read(); if(feature & LFRFIDFeatureASK) { - furi_hal_rfid_tim_read(125000, 0.5); + furi_hal_rfid_tim_read_start(125000, 0.5); FURI_LOG_D(TAG, "Start ASK"); if(worker->read_cb) { worker->read_cb(LFRFIDWorkerReadStartASK, PROTOCOL_NO, worker->cb_ctx); } } else { - furi_hal_rfid_tim_read(62500, 0.25); + furi_hal_rfid_tim_read_start(62500, 0.25); FURI_LOG_D(TAG, "Start PSK"); if(worker->read_cb) { worker->read_cb(LFRFIDWorkerReadStartPSK, PROTOCOL_NO, worker->cb_ctx); } } - furi_hal_rfid_tim_read_start(); - // stabilize detector lfrfid_worker_delay(worker, LFRFID_WORKER_READ_STABILIZE_TIME_MS); @@ -205,7 +202,7 @@ static LFRFIDWorkerReadState lfrfid_worker_read_internal( average_index = 0; if(worker->read_cb) { - if(average > 0.2 && average < 0.8) { + if(average > 0.2f && average < 0.8f) { if(!card_detected) { card_detected = true; worker->read_cb( diff --git a/lib/lfrfid/tools/t5577.c b/lib/lfrfid/tools/t5577.c index 3444afea3..00c9ddfb6 100644 --- a/lib/lfrfid/tools/t5577.c +++ b/lib/lfrfid/tools/t5577.c @@ -14,9 +14,7 @@ #define T5577_OPCODE_RESET 0b00 static void t5577_start() { - furi_hal_rfid_tim_read(125000, 0.5); - furi_hal_rfid_pins_read(); - furi_hal_rfid_tim_read_start(); + furi_hal_rfid_tim_read_start(125000, 0.5); // do not ground the antenna furi_hal_rfid_pin_pull_release(); @@ -24,14 +22,13 @@ static void t5577_start() { static void t5577_stop() { furi_hal_rfid_tim_read_stop(); - furi_hal_rfid_tim_reset(); furi_hal_rfid_pins_reset(); } static void t5577_write_gap(uint32_t gap_time) { - furi_hal_rfid_tim_read_stop(); + furi_hal_rfid_tim_read_pause(); furi_delay_us(gap_time * 8); - furi_hal_rfid_tim_read_start(); + furi_hal_rfid_tim_read_continue(); } static void t5577_write_bit(bool value) { diff --git a/lib/nfc/parsers/opal.c b/lib/nfc/parsers/opal.c index b5ca37eb6..2a6b5d122 100644 --- a/lib/nfc/parsers/opal.c +++ b/lib/nfc/parsers/opal.c @@ -143,7 +143,7 @@ bool opal_parser_parse(NfcDeviceData* dev_data) { // sign separately, because then we can handle balances of -99..-1 // cents, as the "dollars" division below would result in a positive // zero value. - o->balance = abs(o->balance); + o->balance = abs(o->balance); //-V1081 sign = "-"; } uint8_t cents = o->balance % 100; @@ -164,7 +164,7 @@ bool opal_parser_parse(NfcDeviceData* dev_data) { o->mode = 4; } - const char* mode_str = (o->mode <= 4 ? opal_modes[o->mode] : opal_modes[3]); + const char* mode_str = (o->mode <= 4 ? opal_modes[o->mode] : opal_modes[3]); //-V547 const char* usage_str = (o->usage <= 12 ? opal_usages[o->usage] : opal_usages[13]); furi_string_printf( diff --git a/lib/pulse_reader/pulse_reader.c b/lib/pulse_reader/pulse_reader.c index 74d99fe80..1c3cb4a58 100644 --- a/lib/pulse_reader/pulse_reader.c +++ b/lib/pulse_reader/pulse_reader.c @@ -135,6 +135,7 @@ void pulse_reader_stop(PulseReader* signal) { LL_DMA_DisableChannel(DMA1, signal->dma_channel + 1); LL_DMAMUX_DisableRequestGen(NULL, LL_DMAMUX_REQ_GEN_0); LL_TIM_DisableCounter(TIM2); + furi_hal_bus_disable(FuriHalBusTIM2); furi_hal_gpio_init_simple(signal->gpio, GpioModeAnalog); } @@ -146,6 +147,8 @@ void pulse_reader_start(PulseReader* signal) { signal->dma_config_gpio.MemoryOrM2MDstAddress = (uint32_t)signal->gpio_buffer; signal->dma_config_gpio.NbData = signal->size; + furi_hal_bus_enable(FuriHalBusTIM2); + /* start counter */ LL_TIM_SetCounterMode(TIM2, LL_TIM_COUNTERMODE_UP); LL_TIM_SetClockDivision(TIM2, LL_TIM_CLOCKDIVISION_DIV1); From b3aaffc95de4bc94e08db86e96e98ab53b3fe1d7 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Mon, 29 May 2023 19:33:04 +0300 Subject: [PATCH 14/52] Update wifi marauder plugin --- .../wifi_marauder_companion/ReadMe.md | 19 +++++++++++++++++++ .../wifi_marauder_app.h | 2 +- 2 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 applications/external/wifi_marauder_companion/ReadMe.md diff --git a/applications/external/wifi_marauder_companion/ReadMe.md b/applications/external/wifi_marauder_companion/ReadMe.md new file mode 100644 index 000000000..fd690ece6 --- /dev/null +++ b/applications/external/wifi_marauder_companion/ReadMe.md @@ -0,0 +1,19 @@ +# WiFi Marauder companion app for Flipper Zero + +## https://github.com/0xchocolate/flipperzero-wifi-marauder + +Requires a connected dev board running Marauder FW. [See install instructions from UberGuidoZ here.](https://github.com/UberGuidoZ/Flipper/tree/main/Wifi_DevBoard#marauder-install-information) + +## Support + +For app feedback, bugs, and feature requests, please [create an issue here](https://github.com/0xchocolate/flipperzero-firmware-with-wifi-marauder-companion/issues). + +You can find me (0xchocolate) on discord as @cococode#6011. + +If you'd like to donate to the app development effort: +**ETH**: `0xf32A1F0CD6122C97d8953183E53cB889cc087C9b` +**BTC**: `bc1qtw7s25cwdkuaups22yna8sttfxn0usm2f35wc3` + +Find more info about Marauder and support its developer (justcallmekoko aka WillStunForFood) here: https://github.com/justcallmekoko/ESP32Marauder + +If you found the app preinstalled in a firmware release, consider supporting the maintainers! diff --git a/applications/external/wifi_marauder_companion/wifi_marauder_app.h b/applications/external/wifi_marauder_companion/wifi_marauder_app.h index 5457f89d8..3a342bbba 100644 --- a/applications/external/wifi_marauder_companion/wifi_marauder_app.h +++ b/applications/external/wifi_marauder_companion/wifi_marauder_app.h @@ -4,7 +4,7 @@ extern "C" { #endif -#define WIFI_MARAUDER_APP_VERSION "v0.3.7" +#define WIFI_MARAUDER_APP_VERSION "v0.4.0" typedef struct WifiMarauderApp WifiMarauderApp; From 8d2ea14f0694af81f7e0b04232e910e504d8cfc4 Mon Sep 17 00:00:00 2001 From: hedger Date: Mon, 29 May 2023 20:40:56 +0400 Subject: [PATCH 15/52] [FL-3330] fbt: added hooks for build & dist environments; added FW_ORIGIN_* macro for apps & SDK (#2705) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fbt: added hooks for build & dist environments * Moved env hooks to an optional file * Fixed var name * Added fw origin to device info * Bumped device info version * fbt: added FIRMWARE_ORIGIN option. Different implementation for FW_ORIGIN_* C macro. * api: bumped versions * fbt: added fbt_options_local.py * gitignore: cleanup Co-authored-by: あく --- .gitignore | 22 +++---- documentation/fbt.md | 2 + fbt_options.py | 7 ++ firmware.scons | 11 ++++ firmware/targets/f18/api_symbols.csv | 4 +- firmware/targets/f7/api_symbols.csv | 4 +- firmware/targets/f7/furi_hal/furi_hal_info.c | 20 +++++- furi/core/core_defines.h | 5 ++ lib/toolbox/version.c | 15 ++++- lib/toolbox/version.h | 11 ++++ scripts/debug/flipperversion.py | 16 ++++- scripts/fbt_tools/fbt_envhooks.py | 67 ++++++++++++++++++++ scripts/fbt_tools/fbt_version.py | 4 +- scripts/ufbt/SConstruct | 5 ++ scripts/version.py | 23 +++++++ site_scons/commandline.scons | 7 ++ 16 files changed, 206 insertions(+), 17 deletions(-) create mode 100644 scripts/fbt_tools/fbt_envhooks.py diff --git a/.gitignore b/.gitignore index bf17a94e2..d60dcec3f 100644 --- a/.gitignore +++ b/.gitignore @@ -30,27 +30,25 @@ bindings/ .mxproject Brewfile.lock.json -# Visual Studio Code -/.vscode/ - # Kate .kateproject .kateconfig -# legendary cmake's -build -CMakeLists.txt - -# bundle output -dist - # kde .directory # SCons .sconsign.dblite + + +# Visual Studio Code +/.vscode + +# bundle output +/dist + # SCons build dir -build/ +/build # Toolchain /toolchain @@ -64,3 +62,5 @@ PVS-Studio.log *.PVS-Studio.* .gdbinit + +/fbt_options_local.py \ No newline at end of file diff --git a/documentation/fbt.md b/documentation/fbt.md index d9eb8f4aa..c19780ef5 100644 --- a/documentation/fbt.md +++ b/documentation/fbt.md @@ -114,6 +114,8 @@ To run cleanup (think of `make clean`) for specified targets, add the `-c` optio Default configuration variables are set in the configuration file: `fbt_options.py`. Values set in the command line have higher precedence over the configuration file. +You can also create a file called `fbt_options_local.py` that will be evaluated when loading default options file, enabling persisent overriding of default options without modifying default configuration. + You can find out available options with `./fbt -h`. ### Firmware application set diff --git a/fbt_options.py b/fbt_options.py index d05b882a0..b6fcc70f2 100644 --- a/fbt_options.py +++ b/fbt_options.py @@ -1,7 +1,9 @@ +from pathlib import Path import posixpath # For more details on these options, run 'fbt -h' +FIRMWARE_ORIGIN = "Official" # Default hardware target TARGET_HW = 7 @@ -75,3 +77,8 @@ FIRMWARE_APPS = { } FIRMWARE_APP_SET = "default" + +custom_options_fn = "fbt_options_local.py" + +if Path(custom_options_fn).exists(): + exec(compile(Path(custom_options_fn).read_text(), custom_options_fn, "exec")) diff --git a/firmware.scons b/firmware.scons index c46996899..a91b7cdfc 100644 --- a/firmware.scons +++ b/firmware.scons @@ -18,6 +18,7 @@ env = ENV.Clone( "fbt_apps", "pvsstudio", "fbt_hwtarget", + "fbt_envhooks", ], COMPILATIONDB_USE_ABSPATH=False, BUILD_DIR=fw_build_meta["build_dir"], @@ -72,6 +73,8 @@ env = ENV.Clone( _APP_ICONS=None, ) +env.PreConfigureFwEnvionment() + if env["IS_BASE_FIRMWARE"]: env.Append( FIRMWARE_BUILD_CFG="firmware", @@ -100,6 +103,13 @@ lib_targets = env.BuildModules( ], ) +# Configure firmware origin definitions +env.Append( + CPPDEFINES=[ + env.subst("FW_ORIGIN_${FIRMWARE_ORIGIN}"), + ] +) + # Now, env is fully set up with everything to build apps fwenv = env.Clone(FW_ARTIFACTS=[]) @@ -271,5 +281,6 @@ if should_gen_cdb_and_link_dir(fwenv, BUILD_TARGETS): Alias(fwenv["FIRMWARE_BUILD_CFG"] + "_all", fw_artifacts) +env.PostConfigureFwEnvionment() Return("fwenv") diff --git a/firmware/targets/f18/api_symbols.csv b/firmware/targets/f18/api_symbols.csv index 92c8697aa..7f0dcebd5 100644 --- a/firmware/targets/f18/api_symbols.csv +++ b/firmware/targets/f18/api_symbols.csv @@ -1,5 +1,5 @@ entry,status,name,type,params -Version,+,28.0,, +Version,+,28.1,, Header,+,applications/services/bt/bt_service/bt.h,, Header,+,applications/services/cli/cli.h,, Header,+,applications/services/cli/cli_vcp.h,, @@ -2003,6 +2003,8 @@ Function,-,vdprintf,int,"int, const char*, __gnuc_va_list" Function,+,version_get,const Version*, Function,+,version_get_builddate,const char*,const Version* Function,+,version_get_dirty_flag,_Bool,const Version* +Function,+,version_get_firmware_origin,const char*,const Version* +Function,+,version_get_git_origin,const char*,const Version* Function,+,version_get_gitbranch,const char*,const Version* Function,+,version_get_gitbranchnum,const char*,const Version* Function,+,version_get_githash,const char*,const Version* diff --git a/firmware/targets/f7/api_symbols.csv b/firmware/targets/f7/api_symbols.csv index 4b48949d9..1259f0fce 100644 --- a/firmware/targets/f7/api_symbols.csv +++ b/firmware/targets/f7/api_symbols.csv @@ -1,5 +1,5 @@ entry,status,name,type,params -Version,+,28.0,, +Version,+,28.1,, Header,+,applications/services/bt/bt_service/bt.h,, Header,+,applications/services/cli/cli.h,, Header,+,applications/services/cli/cli_vcp.h,, @@ -2945,6 +2945,8 @@ Function,-,vdprintf,int,"int, const char*, __gnuc_va_list" Function,+,version_get,const Version*, Function,+,version_get_builddate,const char*,const Version* Function,+,version_get_dirty_flag,_Bool,const Version* +Function,+,version_get_firmware_origin,const char*,const Version* +Function,+,version_get_git_origin,const char*,const Version* Function,+,version_get_gitbranch,const char*,const Version* Function,+,version_get_gitbranchnum,const char*,const Version* Function,+,version_get_githash,const char*,const Version* diff --git a/firmware/targets/f7/furi_hal/furi_hal_info.c b/firmware/targets/f7/furi_hal/furi_hal_info.c index 4c034ff35..47672c97a 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_info.c +++ b/firmware/targets/f7/furi_hal/furi_hal_info.c @@ -26,7 +26,7 @@ void furi_hal_info_get(PropertyValueCallback out, char sep, void* context) { property_value_out(&property_context, NULL, 2, "format", "minor", "1"); } else { property_value_out(&property_context, NULL, 3, "device", "info", "major", "2"); - property_value_out(&property_context, NULL, 3, "device", "info", "minor", "1"); + property_value_out(&property_context, NULL, 3, "device", "info", "minor", "2"); } // Model name @@ -173,6 +173,24 @@ void furi_hal_info_get(PropertyValueCallback out, char sep, void* context) { &property_context, "%d", 3, "firmware", "api", "major", api_version_major); property_value_out( &property_context, "%d", 3, "firmware", "api", "minor", api_version_minor); + + property_value_out( + &property_context, + NULL, + 3, + "firmware", + "origin", + "fork", + version_get_firmware_origin(firmware_version)); + + property_value_out( + &property_context, + NULL, + 3, + "firmware", + "origin", + "git", + version_get_git_origin(firmware_version)); } if(furi_hal_bt_is_alive()) { diff --git a/furi/core/core_defines.h b/furi/core/core_defines.h index 830bb191c..4309c20c5 100644 --- a/furi/core/core_defines.h +++ b/furi/core/core_defines.h @@ -78,6 +78,11 @@ extern "C" { #define TOSTRING(x) STRINGIFY(x) #endif +#ifndef CONCATENATE +#define CONCATENATE(a, b) CONCATENATE_(a, b) +#define CONCATENATE_(a, b) a##b +#endif + #ifndef REVERSE_BYTES_U32 #define REVERSE_BYTES_U32(x) \ ((((x)&0x000000FF) << 24) | (((x)&0x0000FF00) << 8) | (((x)&0x00FF0000) >> 8) | \ diff --git a/lib/toolbox/version.c b/lib/toolbox/version.c index 6ba68e364..876695f07 100644 --- a/lib/toolbox/version.c +++ b/lib/toolbox/version.c @@ -5,7 +5,7 @@ #define VERSION_MAGIC (0xBE40u) #define VERSION_MAJOR (0x1u) -#define VERSION_MINOR (0x0u) +#define VERSION_MINOR (0x1u) struct Version { // Header @@ -20,6 +20,9 @@ struct Version { // Payload bits and pieces const uint8_t target; const bool build_is_dirty; + // v 1.1 + const char* firmware_origin; + const char* git_origin; }; /* version of current running firmware (bootloader/flipper) */ @@ -37,6 +40,8 @@ static const Version version = { , .target = TARGET, .build_is_dirty = BUILD_DIRTY, + .firmware_origin = FIRMWARE_ORIGIN, + .git_origin = GIT_ORIGIN, }; const Version* version_get(void) { @@ -71,3 +76,11 @@ uint8_t version_get_target(const Version* v) { bool version_get_dirty_flag(const Version* v) { return v ? v->build_is_dirty : version.build_is_dirty; } + +const char* version_get_firmware_origin(const Version* v) { + return v ? v->firmware_origin : version.firmware_origin; +} + +const char* version_get_git_origin(const Version* v) { + return v ? v->git_origin : version.git_origin; +} diff --git a/lib/toolbox/version.h b/lib/toolbox/version.h index 652ff3fea..0c04e5c75 100644 --- a/lib/toolbox/version.h +++ b/lib/toolbox/version.h @@ -82,6 +82,17 @@ uint8_t version_get_target(const Version* v); */ bool version_get_dirty_flag(const Version* v); +/** + * Get firmware origin. "Official" for mainline firmware, fork name for forks. + * Set by FIRMWARE_ORIGIN fbt argument. +*/ +const char* version_get_firmware_origin(const Version* v); + +/** + * Get git repo origin +*/ +const char* version_get_git_origin(const Version* v); + #ifdef __cplusplus } #endif diff --git a/scripts/debug/flipperversion.py b/scripts/debug/flipperversion.py index 4ac3bd200..56915c0f2 100644 --- a/scripts/debug/flipperversion.py +++ b/scripts/debug/flipperversion.py @@ -23,6 +23,10 @@ class VersionData: version: str target: int build_is_dirty: bool + # Since version 1.1 + firmware_origin: str = "" + git_origin: str = "" + # More fields may be added in the future extra: Optional[Dict[str, str]] = field(default_factory=dict) @@ -52,7 +56,7 @@ class VersionLoader: # Struct version 1.0 extra_data = int(self.version_ptr[5].cast(self._uint_type)) - return VersionData( + version_data = VersionData( git_hash=self.version_ptr[1].cast(self._cstr_type).string(), git_branch=self.version_ptr[2].cast(self._cstr_type).string(), build_date=self.version_ptr[3].cast(self._cstr_type).string(), @@ -60,6 +64,12 @@ class VersionLoader: target=extra_data & 0xF, build_is_dirty=bool((extra_data >> 8) & 0xF), ) + if minor >= 1: + version_data.firmware_origin = ( + self.version_ptr[6].cast(self._cstr_type).string() + ) + version_data.git_origin = self.version_ptr[7].cast(self._cstr_type).string() + return version_data def load_unversioned(self): """Parse an early version of the version struct.""" @@ -104,6 +114,10 @@ class FlipperFwVersion(gdb.Command): print(f"\tGit commit: {v.version.git_hash}") print(f"\tDirty: {v.version.build_is_dirty}") print(f"\tHW Target: {v.version.target}") + if v.version.firmware_origin: + print(f"\tOrigin: {v.version.firmware_origin}") + if v.version.git_origin: + print(f"\tGit origin: {v.version.git_origin}") FlipperFwVersion() diff --git a/scripts/fbt_tools/fbt_envhooks.py b/scripts/fbt_tools/fbt_envhooks.py new file mode 100644 index 000000000..0538e173c --- /dev/null +++ b/scripts/fbt_tools/fbt_envhooks.py @@ -0,0 +1,67 @@ +""" + +To introduce changes to firmware build environment that are specific to your fork: + + create a file "scripts/fbt/fbt_hooks.py" + +With it, you can define functions that will be called at specific points of +firmware build configuration, with environment as an argument. + +For example, you can define a function `PreConfigureFwEnvionment(env)` that +defines that will be a part of SDK build, so applications can +use them for conditional compilation. + +Here is a list of all available hooks: + + PreConfigureFwEnvionment(env): + This function is called on firmware environment (incl. updater) + before any major configuration is done. + + PostConfigureFwEnvionment(env): + This function is called on firmware environment (incl. updater) + after all configuration is done. + + PreConfigureUfbtEnvionment(env): + This function is called on ufbt environment at the beginning of + its configuration, before dist environment is created. + + PostConfigureUfbtEnvionment(env): + This function is called on ufbt dist_env environment after all + configuration and target creation is done. +""" + + +class DefaultFbtHooks: + pass + + +try: + from fbt import fbt_hooks +except ImportError: + fbt_hooks = DefaultFbtHooks() + + +def generate(env): + stub_hook = lambda env: None + control_hooks = [ + "PreConfigureFwEnvionment", + "PostConfigureFwEnvionment", + "PreConfigureUfbtEnvionment", + "PostConfigureUfbtEnvionment", + ] + + if ( + isinstance(fbt_hooks, DefaultFbtHooks) + and env.subst("${FIRMWARE_ORIGIN}") != "Official" + ): + # If fbt_hooks.py is not present, but we are not building official firmware, + # create "scripts/fbt/fbt_hooks.py" to implement changes to firmware build environment. + pass + + for hook_name in control_hooks: + hook_fn = getattr(fbt_hooks, hook_name, stub_hook) + env.AddMethod(hook_fn, hook_name) + + +def exists(): + return True diff --git a/scripts/fbt_tools/fbt_version.py b/scripts/fbt_tools/fbt_version.py index 8469e181a..aead13b29 100644 --- a/scripts/fbt_tools/fbt_version.py +++ b/scripts/fbt_tools/fbt_version.py @@ -19,7 +19,9 @@ def generate(env): BUILDERS={ "VersionBuilder": Builder( action=Action( - '${PYTHON3} "${VERSION_SCRIPT}" generate -t ${TARGET_HW} -o ${TARGET.dir.posix} --dir "${ROOT_DIR}"', + '${PYTHON3} "${VERSION_SCRIPT}" generate ' + "-t ${TARGET_HW} -fw-origin ${FIRMWARE_ORIGIN} " + '-o ${TARGET.dir.posix} --dir "${ROOT_DIR}"', "${VERSIONCOMSTR}", ), emitter=version_emitter, diff --git a/scripts/ufbt/SConstruct b/scripts/ufbt/SConstruct index 4dd1fb5b9..d72de380c 100644 --- a/scripts/ufbt/SConstruct +++ b/scripts/ufbt/SConstruct @@ -98,6 +98,7 @@ env = core_env.Clone( "fbt_apps", "fbt_extapps", "fbt_assets", + "fbt_envhooks", ("compilation_db", {"COMPILATIONDB_COMSTR": "\tCDB\t${TARGET}"}), ], FBT_FAP_DEBUG_ELF_ROOT=ufbt_build_dir, @@ -117,6 +118,8 @@ env = core_env.Clone( wrap_tempfile(env, "LINKCOM") wrap_tempfile(env, "ARCOM") +env.PreConfigureUfbtEnvionment() + # print(env.Dump()) # Dist env @@ -474,3 +477,5 @@ dist_env.PhonyTarget( "env", "@echo $( ${FBT_SCRIPT_DIR}/toolchain/fbtenv.sh $)", ) + +dist_env.PostConfigureUfbtEnvionment() diff --git a/scripts/version.py b/scripts/version.py index 3d68b2e98..f00c1f531 100644 --- a/scripts/version.py +++ b/scripts/version.py @@ -45,8 +45,23 @@ class GitVersion: "GIT_BRANCH": branch, "VERSION": version, "BUILD_DIRTY": dirty and 1 or 0, + "GIT_ORIGIN": ",".join(self._get_git_origins()), } + def _get_git_origins(self): + try: + remotes = self._exec_git("remote -v") + except subprocess.CalledProcessError: + return set() + origins = set() + for line in remotes.split("\n"): + if not line: + continue + _, destination = line.split("\t") + url, _ = destination.split(" ") + origins.add(url) + return origins + def _exec_git(self, args): cmd = ["git"] cmd.extend(args.split(" ")) @@ -74,6 +89,13 @@ class Main(App): help="hardware target", required=True, ) + self.parser_generate.add_argument( + "-fw-origin", + dest="firmware_origin", + type=str, + help="firmware origin", + required=True, + ) self.parser_generate.add_argument("--dir", dest="sourcedir", required=True) self.parser_generate.set_defaults(func=self.generate) @@ -89,6 +111,7 @@ class Main(App): { "BUILD_DATE": build_date.strftime("%d-%m-%Y"), "TARGET": self.args.target, + "FIRMWARE_ORIGIN": self.args.firmware_origin, } ) diff --git a/site_scons/commandline.scons b/site_scons/commandline.scons index 2e9486627..e31927c59 100644 --- a/site_scons/commandline.scons +++ b/site_scons/commandline.scons @@ -236,6 +236,13 @@ vars.AddVariables( help="Don't open browser after generating error repots", default=False, ), + ( + "FIRMWARE_ORIGIN", + "Firmware origin. 'Official' if follows upstream's API structure, otherwise fork name. " + " This will also create a C define FW_ORIGIN_ so that " + " app can check what version it is being built for.", + "Official", + ), ) Return("vars") From 467f3265e026949750b150d3ff0e0f248d3e2044 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Mon, 29 May 2023 21:01:00 +0300 Subject: [PATCH 16/52] bus changes --- .../targets/f7/furi_hal/furi_hal_infrared.c | 303 ++++++++++-------- .../targets/f7/furi_hal/furi_hal_subghz.c | 9 +- 2 files changed, 168 insertions(+), 144 deletions(-) diff --git a/firmware/targets/f7/furi_hal/furi_hal_infrared.c b/firmware/targets/f7/furi_hal/furi_hal_infrared.c index e833c4731..b2d906923 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_infrared.c +++ b/firmware/targets/f7/furi_hal/furi_hal_infrared.c @@ -1,14 +1,11 @@ #include -#include -#include "stm32wbxx_ll_dma.h" #include #include +#include -#include #include -#include +#include -#include #include #include @@ -21,13 +18,23 @@ (TIM_CCMR2_OC3PE | LL_TIM_OCMODE_FORCED_INACTIVE) /* Space time - force low */ /* DMA Channels definition */ -#define IR_DMA DMA2 -#define IR_DMA_CH1_CHANNEL LL_DMA_CHANNEL_1 -#define IR_DMA_CH2_CHANNEL LL_DMA_CHANNEL_2 -#define IR_DMA_CH1_IRQ FuriHalInterruptIdDma2Ch1 -#define IR_DMA_CH2_IRQ FuriHalInterruptIdDma2Ch2 -#define IR_DMA_CH1_DEF IR_DMA, IR_DMA_CH1_CHANNEL -#define IR_DMA_CH2_DEF IR_DMA, IR_DMA_CH2_CHANNEL +#define INFRARED_DMA DMA2 +#define INFRARED_DMA_CH1_CHANNEL LL_DMA_CHANNEL_1 +#define INFRARED_DMA_CH2_CHANNEL LL_DMA_CHANNEL_2 +#define INFRARED_DMA_CH1_IRQ FuriHalInterruptIdDma2Ch1 +#define INFRARED_DMA_CH2_IRQ FuriHalInterruptIdDma2Ch2 +#define INFRARED_DMA_CH1_DEF INFRARED_DMA, INFRARED_DMA_CH1_CHANNEL +#define INFRARED_DMA_CH2_DEF INFRARED_DMA, INFRARED_DMA_CH2_CHANNEL + +/* Timers definition */ +#define INFRARED_RX_TIMER TIM2 +#define INFRARED_DMA_TIMER TIM1 +#define INFRARED_RX_TIMER_BUS FuriHalBusTIM2 +#define INFRARED_DMA_TIMER_BUS FuriHalBusTIM1 + +/* Misc */ +#define INFRARED_RX_GPIO_ALT GpioAltFn1TIM2 +#define INFRARED_RX_IRQ FuriHalInterruptIdTIM2 typedef struct { FuriHalInfraredRxCaptureCallback capture_callback; @@ -94,8 +101,8 @@ static void furi_hal_infrared_tim_rx_isr() { static uint32_t previous_captured_ch2 = 0; /* Timeout */ - if(LL_TIM_IsActiveFlag_CC3(TIM2)) { - LL_TIM_ClearFlag_CC3(TIM2); + if(LL_TIM_IsActiveFlag_CC3(INFRARED_RX_TIMER)) { + LL_TIM_ClearFlag_CC3(INFRARED_RX_TIMER); furi_assert(furi_hal_infrared_state == InfraredStateAsyncRx); /* Timers CNT register starts to counting from 0 to ARR, but it is @@ -111,13 +118,13 @@ static void furi_hal_infrared_tim_rx_isr() { } /* Rising Edge */ - if(LL_TIM_IsActiveFlag_CC1(TIM2)) { - LL_TIM_ClearFlag_CC1(TIM2); + if(LL_TIM_IsActiveFlag_CC1(INFRARED_RX_TIMER)) { + LL_TIM_ClearFlag_CC1(INFRARED_RX_TIMER); furi_assert(furi_hal_infrared_state == InfraredStateAsyncRx); - if(READ_BIT(TIM2->CCMR1, TIM_CCMR1_CC1S)) { + if(READ_BIT(INFRARED_RX_TIMER->CCMR1, TIM_CCMR1_CC1S)) { /* Low pin level is a Mark state of INFRARED signal. Invert level for further processing. */ - uint32_t duration = LL_TIM_IC_GetCaptureCH1(TIM2) - previous_captured_ch2; + uint32_t duration = LL_TIM_IC_GetCaptureCH1(INFRARED_RX_TIMER) - previous_captured_ch2; if(infrared_tim_rx.capture_callback) infrared_tim_rx.capture_callback(infrared_tim_rx.capture_context, 1, duration); } else { @@ -126,13 +133,13 @@ static void furi_hal_infrared_tim_rx_isr() { } /* Falling Edge */ - if(LL_TIM_IsActiveFlag_CC2(TIM2)) { - LL_TIM_ClearFlag_CC2(TIM2); + if(LL_TIM_IsActiveFlag_CC2(INFRARED_RX_TIMER)) { + LL_TIM_ClearFlag_CC2(INFRARED_RX_TIMER); furi_assert(furi_hal_infrared_state == InfraredStateAsyncRx); - if(READ_BIT(TIM2->CCMR1, TIM_CCMR1_CC2S)) { + if(READ_BIT(INFRARED_RX_TIMER->CCMR1, TIM_CCMR1_CC2S)) { /* High pin level is a Space state of INFRARED signal. Invert level for further processing. */ - uint32_t duration = LL_TIM_IC_GetCaptureCH2(TIM2); + uint32_t duration = LL_TIM_IC_GetCaptureCH2(INFRARED_RX_TIMER); previous_captured_ch2 = duration; if(infrared_tim_rx.capture_callback) infrared_tim_rx.capture_callback(infrared_tim_rx.capture_context, 0, duration); @@ -146,62 +153,66 @@ void furi_hal_infrared_async_rx_start(void) { furi_assert(furi_hal_infrared_state == InfraredStateIdle); furi_hal_gpio_init_ex( - &gpio_infrared_rx, GpioModeAltFunctionPushPull, GpioPullNo, GpioSpeedLow, GpioAltFn1TIM2); + &gpio_infrared_rx, + GpioModeAltFunctionPushPull, + GpioPullNo, + GpioSpeedLow, + INFRARED_RX_GPIO_ALT); + + furi_hal_bus_enable(INFRARED_RX_TIMER_BUS); LL_TIM_InitTypeDef TIM_InitStruct = {0}; TIM_InitStruct.Prescaler = 64 - 1; TIM_InitStruct.CounterMode = LL_TIM_COUNTERMODE_UP; TIM_InitStruct.Autoreload = 0x7FFFFFFE; TIM_InitStruct.ClockDivision = LL_TIM_CLOCKDIVISION_DIV1; - LL_TIM_Init(TIM2, &TIM_InitStruct); + LL_TIM_Init(INFRARED_RX_TIMER, &TIM_InitStruct); - LL_TIM_SetClockSource(TIM2, LL_TIM_CLOCKSOURCE_INTERNAL); - LL_TIM_DisableARRPreload(TIM2); - LL_TIM_SetTriggerInput(TIM2, LL_TIM_TS_TI1FP1); - LL_TIM_SetSlaveMode(TIM2, LL_TIM_SLAVEMODE_RESET); - LL_TIM_CC_DisableChannel(TIM2, LL_TIM_CHANNEL_CH2); - LL_TIM_IC_SetFilter(TIM2, LL_TIM_CHANNEL_CH2, LL_TIM_IC_FILTER_FDIV1); - LL_TIM_IC_SetPolarity(TIM2, LL_TIM_CHANNEL_CH2, LL_TIM_IC_POLARITY_FALLING); - LL_TIM_DisableIT_TRIG(TIM2); - LL_TIM_DisableDMAReq_TRIG(TIM2); - LL_TIM_SetTriggerOutput(TIM2, LL_TIM_TRGO_RESET); - LL_TIM_EnableMasterSlaveMode(TIM2); - LL_TIM_IC_SetActiveInput(TIM2, LL_TIM_CHANNEL_CH1, LL_TIM_ACTIVEINPUT_DIRECTTI); - LL_TIM_IC_SetPrescaler(TIM2, LL_TIM_CHANNEL_CH1, LL_TIM_ICPSC_DIV1); - LL_TIM_IC_SetFilter(TIM2, LL_TIM_CHANNEL_CH1, LL_TIM_IC_FILTER_FDIV1); - LL_TIM_IC_SetPolarity(TIM2, LL_TIM_CHANNEL_CH1, LL_TIM_IC_POLARITY_RISING); - LL_TIM_IC_SetActiveInput(TIM2, LL_TIM_CHANNEL_CH2, LL_TIM_ACTIVEINPUT_INDIRECTTI); - LL_TIM_IC_SetPrescaler(TIM2, LL_TIM_CHANNEL_CH2, LL_TIM_ICPSC_DIV1); + LL_TIM_SetClockSource(INFRARED_RX_TIMER, LL_TIM_CLOCKSOURCE_INTERNAL); + LL_TIM_DisableARRPreload(INFRARED_RX_TIMER); + LL_TIM_SetTriggerInput(INFRARED_RX_TIMER, LL_TIM_TS_TI1FP1); + LL_TIM_SetSlaveMode(INFRARED_RX_TIMER, LL_TIM_SLAVEMODE_RESET); + LL_TIM_CC_DisableChannel(INFRARED_RX_TIMER, LL_TIM_CHANNEL_CH2); + LL_TIM_IC_SetFilter(INFRARED_RX_TIMER, LL_TIM_CHANNEL_CH2, LL_TIM_IC_FILTER_FDIV1); + LL_TIM_IC_SetPolarity(INFRARED_RX_TIMER, LL_TIM_CHANNEL_CH2, LL_TIM_IC_POLARITY_FALLING); + LL_TIM_DisableIT_TRIG(INFRARED_RX_TIMER); + LL_TIM_DisableDMAReq_TRIG(INFRARED_RX_TIMER); + LL_TIM_SetTriggerOutput(INFRARED_RX_TIMER, LL_TIM_TRGO_RESET); + LL_TIM_EnableMasterSlaveMode(INFRARED_RX_TIMER); + LL_TIM_IC_SetActiveInput(INFRARED_RX_TIMER, LL_TIM_CHANNEL_CH1, LL_TIM_ACTIVEINPUT_DIRECTTI); + LL_TIM_IC_SetPrescaler(INFRARED_RX_TIMER, LL_TIM_CHANNEL_CH1, LL_TIM_ICPSC_DIV1); + LL_TIM_IC_SetFilter(INFRARED_RX_TIMER, LL_TIM_CHANNEL_CH1, LL_TIM_IC_FILTER_FDIV1); + LL_TIM_IC_SetPolarity(INFRARED_RX_TIMER, LL_TIM_CHANNEL_CH1, LL_TIM_IC_POLARITY_RISING); + LL_TIM_IC_SetActiveInput(INFRARED_RX_TIMER, LL_TIM_CHANNEL_CH2, LL_TIM_ACTIVEINPUT_INDIRECTTI); + LL_TIM_IC_SetPrescaler(INFRARED_RX_TIMER, LL_TIM_CHANNEL_CH2, LL_TIM_ICPSC_DIV1); - furi_hal_interrupt_set_isr(FuriHalInterruptIdTIM2, furi_hal_infrared_tim_rx_isr, NULL); + furi_hal_interrupt_set_isr(INFRARED_RX_IRQ, furi_hal_infrared_tim_rx_isr, NULL); furi_hal_infrared_state = InfraredStateAsyncRx; - LL_TIM_EnableIT_CC1(TIM2); - LL_TIM_EnableIT_CC2(TIM2); - LL_TIM_CC_EnableChannel(TIM2, LL_TIM_CHANNEL_CH1); - LL_TIM_CC_EnableChannel(TIM2, LL_TIM_CHANNEL_CH2); + LL_TIM_EnableIT_CC1(INFRARED_RX_TIMER); + LL_TIM_EnableIT_CC2(INFRARED_RX_TIMER); + LL_TIM_CC_EnableChannel(INFRARED_RX_TIMER, LL_TIM_CHANNEL_CH1); + LL_TIM_CC_EnableChannel(INFRARED_RX_TIMER, LL_TIM_CHANNEL_CH2); - LL_TIM_SetCounter(TIM2, 0); - LL_TIM_EnableCounter(TIM2); + LL_TIM_SetCounter(INFRARED_RX_TIMER, 0); + LL_TIM_EnableCounter(INFRARED_RX_TIMER); } void furi_hal_infrared_async_rx_stop(void) { furi_assert(furi_hal_infrared_state == InfraredStateAsyncRx); FURI_CRITICAL_ENTER(); - - LL_TIM_DeInit(TIM2); - furi_hal_interrupt_set_isr(FuriHalInterruptIdTIM2, NULL, NULL); + furi_hal_bus_disable(INFRARED_RX_TIMER_BUS); + furi_hal_interrupt_set_isr(INFRARED_RX_IRQ, NULL, NULL); furi_hal_infrared_state = InfraredStateIdle; - FURI_CRITICAL_EXIT(); } void furi_hal_infrared_async_rx_set_timeout(uint32_t timeout_us) { - LL_TIM_OC_SetCompareCH3(TIM2, timeout_us); - LL_TIM_OC_SetMode(TIM2, LL_TIM_CHANNEL_CH3, LL_TIM_OCMODE_ACTIVE); - LL_TIM_CC_EnableChannel(TIM2, LL_TIM_CHANNEL_CH3); - LL_TIM_EnableIT_CC3(TIM2); + LL_TIM_OC_SetCompareCH3(INFRARED_RX_TIMER, timeout_us); + LL_TIM_OC_SetMode(INFRARED_RX_TIMER, LL_TIM_CHANNEL_CH3, LL_TIM_OCMODE_ACTIVE); + LL_TIM_CC_EnableChannel(INFRARED_RX_TIMER, LL_TIM_CHANNEL_CH3); + LL_TIM_EnableIT_CC3(INFRARED_RX_TIMER); } bool furi_hal_infrared_is_busy(void) { @@ -223,16 +234,16 @@ void furi_hal_infrared_async_rx_set_timeout_isr_callback( } static void furi_hal_infrared_tx_dma_terminate(void) { - LL_DMA_DisableIT_TC(IR_DMA_CH1_DEF); - LL_DMA_DisableIT_HT(IR_DMA_CH2_DEF); - LL_DMA_DisableIT_TC(IR_DMA_CH2_DEF); + LL_DMA_DisableIT_TC(INFRARED_DMA_CH1_DEF); + LL_DMA_DisableIT_HT(INFRARED_DMA_CH2_DEF); + LL_DMA_DisableIT_TC(INFRARED_DMA_CH2_DEF); furi_assert(furi_hal_infrared_state == InfraredStateAsyncTxStopInProgress); - LL_DMA_DisableIT_TC(IR_DMA_CH1_DEF); - LL_DMA_DisableChannel(IR_DMA_CH2_DEF); - LL_DMA_DisableChannel(IR_DMA_CH1_DEF); - LL_TIM_DisableCounter(TIM1); + LL_DMA_DisableIT_TC(INFRARED_DMA_CH1_DEF); + LL_DMA_DisableChannel(INFRARED_DMA_CH2_DEF); + LL_DMA_DisableChannel(INFRARED_DMA_CH1_DEF); + LL_TIM_DisableCounter(INFRARED_DMA_TIMER); FuriStatus status = furi_semaphore_release(infrared_tim_tx.stop_semaphore); furi_check(status == FuriStatusOk); furi_hal_infrared_state = InfraredStateAsyncTxStopped; @@ -240,7 +251,7 @@ static void furi_hal_infrared_tx_dma_terminate(void) { static uint8_t furi_hal_infrared_get_current_dma_tx_buffer(void) { uint8_t buf_num = 0; - uint32_t buffer_adr = LL_DMA_GetMemoryAddress(IR_DMA_CH2_DEF); + uint32_t buffer_adr = LL_DMA_GetMemoryAddress(INFRARED_DMA_CH2_DEF); if(buffer_adr == (uint32_t)infrared_tim_tx.buffer[0].data) { buf_num = 0; } else if(buffer_adr == (uint32_t)infrared_tim_tx.buffer[1].data) { @@ -252,13 +263,13 @@ static uint8_t furi_hal_infrared_get_current_dma_tx_buffer(void) { } static void furi_hal_infrared_tx_dma_polarity_isr() { -#if IR_DMA_CH1_CHANNEL == LL_DMA_CHANNEL_1 - if(LL_DMA_IsActiveFlag_TE1(IR_DMA)) { - LL_DMA_ClearFlag_TE1(IR_DMA); +#if INFRARED_DMA_CH1_CHANNEL == LL_DMA_CHANNEL_1 + if(LL_DMA_IsActiveFlag_TE1(INFRARED_DMA)) { + LL_DMA_ClearFlag_TE1(INFRARED_DMA); furi_crash(NULL); } - if(LL_DMA_IsActiveFlag_TC1(IR_DMA) && LL_DMA_IsEnabledIT_TC(IR_DMA_CH1_DEF)) { - LL_DMA_ClearFlag_TC1(IR_DMA); + if(LL_DMA_IsActiveFlag_TC1(INFRARED_DMA) && LL_DMA_IsEnabledIT_TC(INFRARED_DMA_CH1_DEF)) { + LL_DMA_ClearFlag_TC1(INFRARED_DMA); furi_check( (furi_hal_infrared_state == InfraredStateAsyncTx) || @@ -274,23 +285,23 @@ static void furi_hal_infrared_tx_dma_polarity_isr() { } static void furi_hal_infrared_tx_dma_isr() { -#if IR_DMA_CH2_CHANNEL == LL_DMA_CHANNEL_2 - if(LL_DMA_IsActiveFlag_TE2(IR_DMA)) { - LL_DMA_ClearFlag_TE2(IR_DMA); +#if INFRARED_DMA_CH2_CHANNEL == LL_DMA_CHANNEL_2 + if(LL_DMA_IsActiveFlag_TE2(INFRARED_DMA)) { + LL_DMA_ClearFlag_TE2(INFRARED_DMA); furi_crash(NULL); } - if(LL_DMA_IsActiveFlag_HT2(IR_DMA) && LL_DMA_IsEnabledIT_HT(IR_DMA_CH2_DEF)) { - LL_DMA_ClearFlag_HT2(IR_DMA); + if(LL_DMA_IsActiveFlag_HT2(INFRARED_DMA) && LL_DMA_IsEnabledIT_HT(INFRARED_DMA_CH2_DEF)) { + LL_DMA_ClearFlag_HT2(INFRARED_DMA); uint8_t buf_num = furi_hal_infrared_get_current_dma_tx_buffer(); uint8_t next_buf_num = !buf_num; if(infrared_tim_tx.buffer[buf_num].last_packet_end) { - LL_DMA_DisableIT_HT(IR_DMA_CH2_DEF); + LL_DMA_DisableIT_HT(INFRARED_DMA_CH2_DEF); } else if( !infrared_tim_tx.buffer[buf_num].packet_end || (furi_hal_infrared_state == InfraredStateAsyncTx)) { furi_hal_infrared_tx_fill_buffer(next_buf_num, 0); if(infrared_tim_tx.buffer[next_buf_num].last_packet_end) { - LL_DMA_DisableIT_HT(IR_DMA_CH2_DEF); + LL_DMA_DisableIT_HT(INFRARED_DMA_CH2_DEF); } } else if(furi_hal_infrared_state == InfraredStateAsyncTxStopReq) { /* fallthrough */ @@ -298,8 +309,8 @@ static void furi_hal_infrared_tx_dma_isr() { furi_crash(NULL); } } - if(LL_DMA_IsActiveFlag_TC2(IR_DMA) && LL_DMA_IsEnabledIT_TC(IR_DMA_CH2_DEF)) { - LL_DMA_ClearFlag_TC2(IR_DMA); + if(LL_DMA_IsActiveFlag_TC2(INFRARED_DMA) && LL_DMA_IsEnabledIT_TC(INFRARED_DMA_CH2_DEF)) { + LL_DMA_ClearFlag_TC2(INFRARED_DMA); furi_check( (furi_hal_infrared_state == InfraredStateAsyncTxStopInProgress) || (furi_hal_infrared_state == InfraredStateAsyncTxStopReq) || @@ -331,37 +342,42 @@ static void furi_hal_infrared_tx_dma_isr() { } static void furi_hal_infrared_configure_tim_pwm_tx(uint32_t freq, float duty_cycle) { - LL_TIM_DisableCounter(TIM1); - LL_TIM_SetRepetitionCounter(TIM1, 0); - LL_TIM_SetCounter(TIM1, 0); - LL_TIM_SetPrescaler(TIM1, 0); - LL_TIM_SetCounterMode(TIM1, LL_TIM_COUNTERMODE_UP); - LL_TIM_EnableARRPreload(TIM1); + LL_TIM_DisableCounter(INFRARED_DMA_TIMER); + LL_TIM_SetRepetitionCounter(INFRARED_DMA_TIMER, 0); + LL_TIM_SetCounter(INFRARED_DMA_TIMER, 0); + LL_TIM_SetPrescaler(INFRARED_DMA_TIMER, 0); + LL_TIM_SetCounterMode(INFRARED_DMA_TIMER, LL_TIM_COUNTERMODE_UP); + LL_TIM_EnableARRPreload(INFRARED_DMA_TIMER); LL_TIM_SetAutoReload( - TIM1, __LL_TIM_CALC_ARR(SystemCoreClock, LL_TIM_GetPrescaler(TIM1), freq)); + INFRARED_DMA_TIMER, + __LL_TIM_CALC_ARR(SystemCoreClock, LL_TIM_GetPrescaler(INFRARED_DMA_TIMER), freq)); if(infrared_external_output) { - LL_TIM_OC_SetCompareCH1(TIM1, ((LL_TIM_GetAutoReload(TIM1) + 1) * (1 - duty_cycle))); - LL_TIM_OC_EnablePreload(TIM1, LL_TIM_CHANNEL_CH1); + LL_TIM_OC_SetCompareCH1( + INFRARED_DMA_TIMER, + ((LL_TIM_GetAutoReload(INFRARED_DMA_TIMER) + 1) * (1 - duty_cycle))); + LL_TIM_OC_EnablePreload(INFRARED_DMA_TIMER, LL_TIM_CHANNEL_CH1); /* LL_TIM_OCMODE_PWM2 set by DMA */ - LL_TIM_OC_SetMode(TIM1, LL_TIM_CHANNEL_CH1, LL_TIM_OCMODE_FORCED_INACTIVE); - LL_TIM_OC_SetPolarity(TIM1, LL_TIM_CHANNEL_CH1N, LL_TIM_OCPOLARITY_HIGH); - LL_TIM_OC_DisableFast(TIM1, LL_TIM_CHANNEL_CH1); - LL_TIM_CC_EnableChannel(TIM1, LL_TIM_CHANNEL_CH1N); - LL_TIM_DisableIT_CC1(TIM1); + LL_TIM_OC_SetMode(INFRARED_DMA_TIMER, LL_TIM_CHANNEL_CH1, LL_TIM_OCMODE_FORCED_INACTIVE); + LL_TIM_OC_SetPolarity(INFRARED_DMA_TIMER, LL_TIM_CHANNEL_CH1N, LL_TIM_OCPOLARITY_HIGH); + LL_TIM_OC_DisableFast(INFRARED_DMA_TIMER, LL_TIM_CHANNEL_CH1); + LL_TIM_CC_EnableChannel(INFRARED_DMA_TIMER, LL_TIM_CHANNEL_CH1N); + LL_TIM_DisableIT_CC1(INFRARED_DMA_TIMER); } else { - LL_TIM_OC_SetCompareCH3(TIM1, ((LL_TIM_GetAutoReload(TIM1) + 1) * (1 - duty_cycle))); - LL_TIM_OC_EnablePreload(TIM1, LL_TIM_CHANNEL_CH3); + LL_TIM_OC_SetCompareCH3( + INFRARED_DMA_TIMER, + ((LL_TIM_GetAutoReload(INFRARED_DMA_TIMER) + 1) * (1 - duty_cycle))); + LL_TIM_OC_EnablePreload(INFRARED_DMA_TIMER, LL_TIM_CHANNEL_CH3); /* LL_TIM_OCMODE_PWM2 set by DMA */ - LL_TIM_OC_SetMode(TIM1, LL_TIM_CHANNEL_CH3, LL_TIM_OCMODE_FORCED_INACTIVE); - LL_TIM_OC_SetPolarity(TIM1, LL_TIM_CHANNEL_CH3N, LL_TIM_OCPOLARITY_HIGH); - LL_TIM_OC_DisableFast(TIM1, LL_TIM_CHANNEL_CH3); - LL_TIM_CC_EnableChannel(TIM1, LL_TIM_CHANNEL_CH3N); - LL_TIM_DisableIT_CC3(TIM1); + LL_TIM_OC_SetMode(INFRARED_DMA_TIMER, LL_TIM_CHANNEL_CH3, LL_TIM_OCMODE_FORCED_INACTIVE); + LL_TIM_OC_SetPolarity(INFRARED_DMA_TIMER, LL_TIM_CHANNEL_CH3N, LL_TIM_OCPOLARITY_HIGH); + LL_TIM_OC_DisableFast(INFRARED_DMA_TIMER, LL_TIM_CHANNEL_CH3); + LL_TIM_CC_EnableChannel(INFRARED_DMA_TIMER, LL_TIM_CHANNEL_CH3N); + LL_TIM_DisableIT_CC3(INFRARED_DMA_TIMER); } - LL_TIM_DisableMasterSlaveMode(TIM1); - LL_TIM_EnableAllOutputs(TIM1); - LL_TIM_DisableIT_UPDATE(TIM1); - LL_TIM_EnableDMAReq_UPDATE(TIM1); + LL_TIM_DisableMasterSlaveMode(INFRARED_DMA_TIMER); + LL_TIM_EnableAllOutputs(INFRARED_DMA_TIMER); + LL_TIM_DisableIT_UPDATE(INFRARED_DMA_TIMER); + LL_TIM_EnableDMAReq_UPDATE(INFRARED_DMA_TIMER); NVIC_SetPriority(TIM1_UP_TIM16_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 5, 0)); NVIC_EnableIRQ(TIM1_UP_TIM16_IRQn); @@ -370,9 +386,9 @@ static void furi_hal_infrared_configure_tim_pwm_tx(uint32_t freq, float duty_cyc static void furi_hal_infrared_configure_tim_cmgr2_dma_tx(void) { LL_DMA_InitTypeDef dma_config = {0}; if(infrared_external_output) { - dma_config.PeriphOrM2MSrcAddress = (uint32_t) & (TIM1->CCMR1); + dma_config.PeriphOrM2MSrcAddress = (uint32_t) & (INFRARED_DMA_TIMER->CCMR1); } else { - dma_config.PeriphOrM2MSrcAddress = (uint32_t) & (TIM1->CCMR2); + dma_config.PeriphOrM2MSrcAddress = (uint32_t) & (INFRARED_DMA_TIMER->CCMR2); } dma_config.MemoryOrM2MDstAddress = (uint32_t)NULL; dma_config.Direction = LL_DMA_DIRECTION_MEMORY_TO_PERIPH; @@ -385,24 +401,25 @@ static void furi_hal_infrared_configure_tim_cmgr2_dma_tx(void) { dma_config.NbData = 0; dma_config.PeriphRequest = LL_DMAMUX_REQ_TIM1_UP; dma_config.Priority = LL_DMA_PRIORITY_VERYHIGH; - LL_DMA_Init(IR_DMA_CH1_DEF, &dma_config); + LL_DMA_Init(INFRARED_DMA_CH1_DEF, &dma_config); -#if IR_DMA_CH1_CHANNEL == LL_DMA_CHANNEL_1 - LL_DMA_ClearFlag_TE1(IR_DMA); - LL_DMA_ClearFlag_TC1(IR_DMA); +#if INFRARED_DMA_CH1_CHANNEL == LL_DMA_CHANNEL_1 + LL_DMA_ClearFlag_TE1(INFRARED_DMA); + LL_DMA_ClearFlag_TC1(INFRARED_DMA); #else #error Update this code. Would you kindly? #endif - LL_DMA_EnableIT_TE(IR_DMA_CH1_DEF); - LL_DMA_EnableIT_TC(IR_DMA_CH1_DEF); + LL_DMA_EnableIT_TE(INFRARED_DMA_CH1_DEF); + LL_DMA_EnableIT_TC(INFRARED_DMA_CH1_DEF); - furi_hal_interrupt_set_isr_ex(IR_DMA_CH1_IRQ, 4, furi_hal_infrared_tx_dma_polarity_isr, NULL); + furi_hal_interrupt_set_isr_ex( + INFRARED_DMA_CH1_IRQ, 4, furi_hal_infrared_tx_dma_polarity_isr, NULL); } static void furi_hal_infrared_configure_tim_rcr_dma_tx(void) { LL_DMA_InitTypeDef dma_config = {0}; - dma_config.PeriphOrM2MSrcAddress = (uint32_t) & (TIM1->RCR); + dma_config.PeriphOrM2MSrcAddress = (uint32_t) & (INFRARED_DMA_TIMER->RCR); dma_config.MemoryOrM2MDstAddress = (uint32_t)NULL; dma_config.Direction = LL_DMA_DIRECTION_MEMORY_TO_PERIPH; dma_config.Mode = LL_DMA_MODE_NORMAL; @@ -413,21 +430,21 @@ static void furi_hal_infrared_configure_tim_rcr_dma_tx(void) { dma_config.NbData = 0; dma_config.PeriphRequest = LL_DMAMUX_REQ_TIM1_UP; dma_config.Priority = LL_DMA_PRIORITY_MEDIUM; - LL_DMA_Init(IR_DMA_CH2_DEF, &dma_config); + LL_DMA_Init(INFRARED_DMA_CH2_DEF, &dma_config); -#if IR_DMA_CH2_CHANNEL == LL_DMA_CHANNEL_2 - LL_DMA_ClearFlag_TC2(IR_DMA); - LL_DMA_ClearFlag_HT2(IR_DMA); - LL_DMA_ClearFlag_TE2(IR_DMA); +#if INFRARED_DMA_CH2_CHANNEL == LL_DMA_CHANNEL_2 + LL_DMA_ClearFlag_TC2(INFRARED_DMA); + LL_DMA_ClearFlag_HT2(INFRARED_DMA); + LL_DMA_ClearFlag_TE2(INFRARED_DMA); #else #error Update this code. Would you kindly? #endif - LL_DMA_EnableIT_TC(IR_DMA_CH2_DEF); - LL_DMA_EnableIT_HT(IR_DMA_CH2_DEF); - LL_DMA_EnableIT_TE(IR_DMA_CH2_DEF); + LL_DMA_EnableIT_TC(INFRARED_DMA_CH2_DEF); + LL_DMA_EnableIT_HT(INFRARED_DMA_CH2_DEF); + LL_DMA_EnableIT_TE(INFRARED_DMA_CH2_DEF); - furi_hal_interrupt_set_isr_ex(IR_DMA_CH2_IRQ, 5, furi_hal_infrared_tx_dma_isr, NULL); + furi_hal_interrupt_set_isr_ex(INFRARED_DMA_CH2_IRQ, 5, furi_hal_infrared_tx_dma_isr, NULL); } static void furi_hal_infrared_tx_fill_buffer_last(uint8_t buf_num) { @@ -529,14 +546,14 @@ static void furi_hal_infrared_tx_dma_set_polarity(uint8_t buf_num, uint8_t polar furi_assert(buffer->polarity != NULL); FURI_CRITICAL_ENTER(); - bool channel_enabled = LL_DMA_IsEnabledChannel(IR_DMA_CH1_DEF); + bool channel_enabled = LL_DMA_IsEnabledChannel(INFRARED_DMA_CH1_DEF); if(channel_enabled) { - LL_DMA_DisableChannel(IR_DMA_CH1_DEF); + LL_DMA_DisableChannel(INFRARED_DMA_CH1_DEF); } - LL_DMA_SetMemoryAddress(IR_DMA_CH1_DEF, (uint32_t)buffer->polarity); - LL_DMA_SetDataLength(IR_DMA_CH1_DEF, buffer->size + polarity_shift); + LL_DMA_SetMemoryAddress(INFRARED_DMA_CH1_DEF, (uint32_t)buffer->polarity); + LL_DMA_SetDataLength(INFRARED_DMA_CH1_DEF, buffer->size + polarity_shift); if(channel_enabled) { - LL_DMA_EnableChannel(IR_DMA_CH1_DEF); + LL_DMA_EnableChannel(INFRARED_DMA_CH1_DEF); } FURI_CRITICAL_EXIT(); } @@ -549,14 +566,14 @@ static void furi_hal_infrared_tx_dma_set_buffer(uint8_t buf_num) { /* non-circular mode requires disabled channel before setup */ FURI_CRITICAL_ENTER(); - bool channel_enabled = LL_DMA_IsEnabledChannel(IR_DMA_CH2_DEF); + bool channel_enabled = LL_DMA_IsEnabledChannel(INFRARED_DMA_CH2_DEF); if(channel_enabled) { - LL_DMA_DisableChannel(IR_DMA_CH2_DEF); + LL_DMA_DisableChannel(INFRARED_DMA_CH2_DEF); } - LL_DMA_SetMemoryAddress(IR_DMA_CH2_DEF, (uint32_t)buffer->data); - LL_DMA_SetDataLength(IR_DMA_CH2_DEF, buffer->size); + LL_DMA_SetMemoryAddress(INFRARED_DMA_CH2_DEF, (uint32_t)buffer->data); + LL_DMA_SetDataLength(INFRARED_DMA_CH2_DEF, buffer->size); if(channel_enabled) { - LL_DMA_EnableChannel(IR_DMA_CH2_DEF); + LL_DMA_EnableChannel(INFRARED_DMA_CH2_DEF); } FURI_CRITICAL_EXIT(); } @@ -570,10 +587,10 @@ static void furi_hal_infrared_async_tx_free_resources(void) { furi_hal_gpio_init(&gpio_ext_pa7, GpioModeAnalog, GpioPullDown, GpioSpeedLow); } else { furi_hal_gpio_init(&gpio_infrared_tx, GpioModeAnalog, GpioPullDown, GpioSpeedLow); - } - furi_hal_interrupt_set_isr(IR_DMA_CH1_IRQ, NULL, NULL); - furi_hal_interrupt_set_isr(IR_DMA_CH2_IRQ, NULL, NULL); - LL_TIM_DeInit(TIM1); + furi_hal_interrupt_set_isr(INFRARED_DMA_CH1_IRQ, NULL, NULL); + furi_hal_interrupt_set_isr(INFRARED_DMA_CH2_IRQ, NULL, NULL); + + furi_hal_bus_disable(INFRARED_DMA_TIMER_BUS); furi_semaphore_free(infrared_tim_tx.stop_semaphore); free(infrared_tim_tx.buffer[0].data); @@ -614,6 +631,8 @@ void furi_hal_infrared_async_tx_start(uint32_t freq, float duty_cycle) { furi_hal_infrared_tx_fill_buffer(0, INFRARED_POLARITY_SHIFT); + furi_hal_bus_enable(INFRARED_DMA_TIMER_BUS); + furi_hal_infrared_configure_tim_pwm_tx(freq, duty_cycle); furi_hal_infrared_configure_tim_cmgr2_dma_tx(); furi_hal_infrared_configure_tim_rcr_dma_tx(); @@ -622,11 +641,11 @@ void furi_hal_infrared_async_tx_start(uint32_t freq, float duty_cycle) { furi_hal_infrared_state = InfraredStateAsyncTx; - LL_TIM_ClearFlag_UPDATE(TIM1); - LL_DMA_EnableChannel(IR_DMA_CH1_DEF); - LL_DMA_EnableChannel(IR_DMA_CH2_DEF); + LL_TIM_ClearFlag_UPDATE(INFRARED_DMA_TIMER); + LL_DMA_EnableChannel(INFRARED_DMA_CH1_DEF); + LL_DMA_EnableChannel(INFRARED_DMA_CH2_DEF); furi_delay_us(5); - LL_TIM_GenerateEvent_UPDATE(TIM1); /* DMA -> TIMx_RCR */ + LL_TIM_GenerateEvent_UPDATE(INFRARED_DMA_TIMER); /* DMA -> TIMx_RCR */ furi_delay_us(5); if(infrared_external_output) { LL_GPIO_ResetOutputPin( @@ -646,8 +665,8 @@ void furi_hal_infrared_async_tx_start(uint32_t freq, float duty_cycle) { } FURI_CRITICAL_ENTER(); - LL_TIM_GenerateEvent_UPDATE(TIM1); /* TIMx_RCR -> Repetition counter */ - LL_TIM_EnableCounter(TIM1); + LL_TIM_GenerateEvent_UPDATE(INFRARED_DMA_TIMER); /* TIMx_RCR -> Repetition counter */ + LL_TIM_EnableCounter(INFRARED_DMA_TIMER); FURI_CRITICAL_EXIT(); } diff --git a/firmware/targets/f7/furi_hal/furi_hal_subghz.c b/firmware/targets/f7/furi_hal/furi_hal_subghz.c index 06a7990fb..8125971e9 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_subghz.c +++ b/firmware/targets/f7/furi_hal/furi_hal_subghz.c @@ -7,6 +7,7 @@ #include #include #include +#include #include @@ -596,6 +597,8 @@ void furi_hal_subghz_start_async_rx(FuriHalSubGhzCaptureCallback callback, void* furi_hal_subghz_capture_callback = callback; furi_hal_subghz_capture_callback_context = context; + furi_hal_bus_enable(FuriHalBusTIM2); + // Timer: base LL_TIM_InitTypeDef TIM_InitStruct = {0}; TIM_InitStruct.Prescaler = 64 - 1; @@ -680,7 +683,7 @@ void furi_hal_subghz_stop_async_rx() { furi_hal_subghz_idle(); FURI_CRITICAL_ENTER(); - LL_TIM_DeInit(TIM2); + furi_hal_bus_disable(FuriHalBusTIM2); // Stop debug furi_hal_subghz_stop_debug(); @@ -859,6 +862,8 @@ bool furi_hal_subghz_start_async_tx(FuriHalSubGhzAsyncTxCallback callback, void* LL_DMA_EnableIT_HT(SUBGHZ_DMA_CH1_DEF); LL_DMA_EnableChannel(SUBGHZ_DMA_CH1_DEF); + furi_hal_bus_enable(FuriHalBusTIM2); + // Configure TIM2 LL_TIM_InitTypeDef TIM_InitStruct = {0}; TIM_InitStruct.Prescaler = 64 - 1; @@ -958,7 +963,7 @@ void furi_hal_subghz_stop_async_tx() { // Deinitialize Timer FURI_CRITICAL_ENTER(); - LL_TIM_DeInit(TIM2); + furi_hal_bus_disable(FuriHalBusTIM2); furi_hal_interrupt_set_isr(FuriHalInterruptIdTIM2, NULL, NULL); // Deinitialize DMA From e474b851bf027b1c11cf607fc1389d40e83decd9 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Mon, 29 May 2023 21:29:13 +0300 Subject: [PATCH 17/52] fix for new bus changes --- applications/main/lfrfid/helpers/rfid_writer.c | 9 +++------ firmware/targets/f7/furi_hal/furi_hal_infrared.c | 5 +++-- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/applications/main/lfrfid/helpers/rfid_writer.c b/applications/main/lfrfid/helpers/rfid_writer.c index 7cc6326c4..8125a1b9d 100644 --- a/applications/main/lfrfid/helpers/rfid_writer.c +++ b/applications/main/lfrfid/helpers/rfid_writer.c @@ -2,9 +2,7 @@ #include void writer_start() { - furi_hal_rfid_tim_read(125000, 0.5); - furi_hal_rfid_pins_read(); - furi_hal_rfid_tim_read_start(); + furi_hal_rfid_tim_read_start(125000, 0.5); // do not ground the antenna furi_hal_rfid_pin_pull_release(); @@ -12,14 +10,13 @@ void writer_start() { void writer_stop() { furi_hal_rfid_tim_read_stop(); - furi_hal_rfid_tim_reset(); furi_hal_rfid_pins_reset(); } void write_gap(uint32_t gap_time) { - furi_hal_rfid_tim_read_stop(); + furi_hal_rfid_tim_read_pause(); furi_delay_us(gap_time * 8); - furi_hal_rfid_tim_read_start(); + furi_hal_rfid_tim_read_continue(); } void write_bit(T55xxTiming* t55xxtiming, bool value) { diff --git a/firmware/targets/f7/furi_hal/furi_hal_infrared.c b/firmware/targets/f7/furi_hal/furi_hal_infrared.c index b2d906923..e6fb69307 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_infrared.c +++ b/firmware/targets/f7/furi_hal/furi_hal_infrared.c @@ -386,9 +386,9 @@ static void furi_hal_infrared_configure_tim_pwm_tx(uint32_t freq, float duty_cyc static void furi_hal_infrared_configure_tim_cmgr2_dma_tx(void) { LL_DMA_InitTypeDef dma_config = {0}; if(infrared_external_output) { - dma_config.PeriphOrM2MSrcAddress = (uint32_t) & (INFRARED_DMA_TIMER->CCMR1); + dma_config.PeriphOrM2MSrcAddress = (uint32_t) & (INFRARED_DMA_TIMER->CCMR1); } else { - dma_config.PeriphOrM2MSrcAddress = (uint32_t) & (INFRARED_DMA_TIMER->CCMR2); + dma_config.PeriphOrM2MSrcAddress = (uint32_t) & (INFRARED_DMA_TIMER->CCMR2); } dma_config.MemoryOrM2MDstAddress = (uint32_t)NULL; dma_config.Direction = LL_DMA_DIRECTION_MEMORY_TO_PERIPH; @@ -587,6 +587,7 @@ static void furi_hal_infrared_async_tx_free_resources(void) { furi_hal_gpio_init(&gpio_ext_pa7, GpioModeAnalog, GpioPullDown, GpioSpeedLow); } else { furi_hal_gpio_init(&gpio_infrared_tx, GpioModeAnalog, GpioPullDown, GpioSpeedLow); + } furi_hal_interrupt_set_isr(INFRARED_DMA_CH1_IRQ, NULL, NULL); furi_hal_interrupt_set_isr(INFRARED_DMA_CH2_IRQ, NULL, NULL); From a4c1ad22efca0a869ac1b1e90736d1005c32166b Mon Sep 17 00:00:00 2001 From: gid9798 <30450294+gid9798@users.noreply.github.com> Date: Mon, 29 May 2023 22:15:07 +0300 Subject: [PATCH 18/52] Removing duplicate code in t5577 passwd clear --- .../main/lfrfid/helpers/rfid_writer.c | 96 ------------------- .../main/lfrfid/helpers/rfid_writer.h | 26 ----- .../lfrfid/scenes/lfrfid_scene_clear_t5577.c | 31 ++---- firmware/targets/f7/api_symbols.csv | 3 +- lib/lfrfid/tools/t5577.c | 31 +++++- lib/lfrfid/tools/t5577.h | 2 + 6 files changed, 42 insertions(+), 147 deletions(-) delete mode 100644 applications/main/lfrfid/helpers/rfid_writer.c delete mode 100644 applications/main/lfrfid/helpers/rfid_writer.h diff --git a/applications/main/lfrfid/helpers/rfid_writer.c b/applications/main/lfrfid/helpers/rfid_writer.c deleted file mode 100644 index 7cc6326c4..000000000 --- a/applications/main/lfrfid/helpers/rfid_writer.c +++ /dev/null @@ -1,96 +0,0 @@ -#include "rfid_writer.h" -#include - -void writer_start() { - furi_hal_rfid_tim_read(125000, 0.5); - furi_hal_rfid_pins_read(); - furi_hal_rfid_tim_read_start(); - - // do not ground the antenna - furi_hal_rfid_pin_pull_release(); -} - -void writer_stop() { - furi_hal_rfid_tim_read_stop(); - furi_hal_rfid_tim_reset(); - furi_hal_rfid_pins_reset(); -} - -void write_gap(uint32_t gap_time) { - furi_hal_rfid_tim_read_stop(); - furi_delay_us(gap_time * 8); - furi_hal_rfid_tim_read_start(); -} - -void write_bit(T55xxTiming* t55xxtiming, bool value) { - if(value) { - furi_delay_us(t55xxtiming->data_1 * 8); - } else { - furi_delay_us(t55xxtiming->data_0 * 8); - } - write_gap(t55xxtiming->write_gap); -} - -void write_block( - T55xxTiming* t55xxtiming, - uint8_t page, - uint8_t block, - bool lock_bit, - uint32_t data, - bool password_enable, - uint32_t password) { - furi_delay_us(t55xxtiming->wait_time * 8); - - //client: https://github.com/Proxmark/proxmark3/blob/6116334485ca77343eda51c557cdc81032afcf38/client/cmdlft55xx.c#L944 - //hardware: https://github.com/Proxmark/proxmark3/blob/555fa197730c061bbf0ab01334e99bc47fb3dc06/armsrc/lfops.c#L1465 - //hardware: https://github.com/Proxmark/proxmark3/blob/555fa197730c061bbf0ab01334e99bc47fb3dc06/armsrc/lfops.c#L1396 - - // start gap - write_gap(t55xxtiming->start_gap); - - // opcode - switch(page) { - case 0: - write_bit(t55xxtiming, 1); - write_bit(t55xxtiming, 0); - break; - case 1: - write_bit(t55xxtiming, 1); - write_bit(t55xxtiming, 1); - break; - default: - furi_check(false); - break; - } - - // password - if(password_enable) { - for(uint8_t i = 0; i < 32; i++) { - write_bit(t55xxtiming, (password >> (31 - i)) & 1); - } - } - - // lock bit - write_bit(t55xxtiming, lock_bit); - - // data - for(uint8_t i = 0; i < 32; i++) { - write_bit(t55xxtiming, (data >> (31 - i)) & 1); - } - - // block address - write_bit(t55xxtiming, (block >> 2) & 1); - write_bit(t55xxtiming, (block >> 1) & 1); - write_bit(t55xxtiming, (block >> 0) & 1); - - furi_delay_us(t55xxtiming->program * 8); - - furi_delay_us(t55xxtiming->wait_time * 8); - write_reset(t55xxtiming); -} - -void write_reset(T55xxTiming* t55xxtiming) { - write_gap(t55xxtiming->start_gap); - write_bit(t55xxtiming, 1); - write_bit(t55xxtiming, 0); -} \ No newline at end of file diff --git a/applications/main/lfrfid/helpers/rfid_writer.h b/applications/main/lfrfid/helpers/rfid_writer.h deleted file mode 100644 index 2b97bd321..000000000 --- a/applications/main/lfrfid/helpers/rfid_writer.h +++ /dev/null @@ -1,26 +0,0 @@ -#include -#include - -typedef struct { - uint16_t wait_time; - uint8_t start_gap; - uint8_t write_gap; - uint8_t data_0; - uint8_t data_1; - uint16_t program; -} T55xxTiming; - -void writer_start(); -void writer_stop(); -void write_gap(uint32_t gap_time); -void write_bit(T55xxTiming* t55xxtiming, bool value); -void write_block( - T55xxTiming* t55xxtiming, - uint8_t page, - uint8_t block, - bool lock_bit, - uint32_t data, - bool password_enable, - uint32_t password); - -void write_reset(T55xxTiming* t55xxtiming); \ No newline at end of file diff --git a/applications/main/lfrfid/scenes/lfrfid_scene_clear_t5577.c b/applications/main/lfrfid/scenes/lfrfid_scene_clear_t5577.c index 3b9b41909..08636e036 100644 --- a/applications/main/lfrfid/scenes/lfrfid_scene_clear_t5577.c +++ b/applications/main/lfrfid/scenes/lfrfid_scene_clear_t5577.c @@ -1,17 +1,7 @@ #include "../lfrfid_i.h" -#include "../helpers/rfid_writer.h" - -static void writer_initialize(T55xxTiming* t55xxtiming) { - t55xxtiming->wait_time = 400; - t55xxtiming->start_gap = 30; - t55xxtiming->write_gap = 18; - t55xxtiming->data_0 = 24; - t55xxtiming->data_1 = 56; - t55xxtiming->program = 700; -} +#define TAG "Clear T5577" static void lfrfid_clear_t5577_password_and_config_to_EM(LfRfid* app) { - T55xxTiming* t55xxtiming = malloc(sizeof(T55xxTiming)); Popup* popup = app->popup; char curr_buf[32] = {}; //TODO: use .txt file in resources for passwords. @@ -35,30 +25,27 @@ static void lfrfid_clear_t5577_password_and_config_to_EM(LfRfid* app) { 0x07d7bb0b, 0x9636ef8f, 0xb5f44686, 0x9E3779B9, 0xC6EF3720, 0x7854794A, 0xF1EA5EED, 0x69314718, 0x57721566, 0x93C467E3, 0x27182818, 0x50415353}; const uint8_t default_passwords_len = sizeof(default_passwords) / sizeof(uint32_t); - const uint32_t em_config_block_data = - 0b00000000000101001000000001000000; //no pwd&aor config block - - writer_initialize(t55xxtiming); popup_set_header(popup, "Removing\npassword", 90, 36, AlignCenter, AlignCenter); popup_set_icon(popup, 0, 3, &I_RFIDDolphinSend_97x61); popup_set_text(popup, curr_buf, 90, 56, AlignCenter, AlignCenter); notification_message(app->notifications, &sequence_blink_start_magenta); + LFRFIDT5577 data = { + .block[0] = 0b00000000000101001000000001000000, + .blocks_to_write = 1, + }; + for(uint8_t i = 0; i < default_passwords_len; i++) { - FURI_CRITICAL_ENTER(); snprintf(curr_buf, sizeof(curr_buf), "Pass %d of %d", i, default_passwords_len); view_dispatcher_switch_to_view(app->view_dispatcher, LfRfidViewPopup); - writer_start(); - write_block(t55xxtiming, 0, 0, false, em_config_block_data, true, default_passwords[i]); - write_reset(t55xxtiming); - writer_stop(); - FURI_CRITICAL_EXIT(); + + t5577_write_with_pass(&data, default_passwords[i]); furi_delay_ms(8); } + notification_message(app->notifications, &sequence_blink_stop); popup_reset(app->popup); - free(t55xxtiming); } void lfrfid_scene_clear_t5577_on_enter(void* context) { diff --git a/firmware/targets/f7/api_symbols.csv b/firmware/targets/f7/api_symbols.csv index ae38d0c84..bc9ce6650 100644 --- a/firmware/targets/f7/api_symbols.csv +++ b/firmware/targets/f7/api_symbols.csv @@ -1,5 +1,5 @@ entry,status,name,type,params -Version,+,27.0,, +Version,+,27.1,, Header,+,applications/services/bt/bt_service/bt.h,, Header,+,applications/services/cli/cli.h,, Header,+,applications/services/cli/cli_vcp.h,, @@ -3367,6 +3367,7 @@ Function,+,submenu_set_header,void,"Submenu*, const char*" Function,+,submenu_set_selected_item,void,"Submenu*, uint32_t" Function,-,system,int,const char* Function,+,t5577_write,void,LFRFIDT5577* +Function,-,t5577_write_with_pass,void,"LFRFIDT5577*, uint32_t" Function,-,tan,double,double Function,-,tanf,float,float Function,-,tanh,double,double diff --git a/lib/lfrfid/tools/t5577.c b/lib/lfrfid/tools/t5577.c index 3444afea3..686c1aa6a 100644 --- a/lib/lfrfid/tools/t5577.c +++ b/lib/lfrfid/tools/t5577.c @@ -54,7 +54,12 @@ static void t5577_write_reset() { t5577_write_bit(0); } -static void t5577_write_block(uint8_t block, bool lock_bit, uint32_t data) { +static void t5577_write_block_pass( + uint8_t block, + bool lock_bit, + uint32_t data, + bool with_pass, + uint32_t password) { furi_delay_us(T5577_TIMING_WAIT_TIME * 8); // start gap @@ -63,6 +68,13 @@ static void t5577_write_block(uint8_t block, bool lock_bit, uint32_t data) { // opcode for page 0 t5577_write_opcode(T5577_OPCODE_PAGE_0); + // password + if(with_pass) { + for(uint8_t i = 0; i < 32; i++) { + t5577_write_bit((password >> (31 - i)) & 1); + } + } + // lock bit t5577_write_bit(lock_bit); @@ -82,11 +94,26 @@ static void t5577_write_block(uint8_t block, bool lock_bit, uint32_t data) { t5577_write_reset(); } +static void t5577_write_block_simple(uint8_t block, bool lock_bit, uint32_t data) { + t5577_write_block_pass(block, lock_bit, data, false, 0); +} + void t5577_write(LFRFIDT5577* data) { t5577_start(); FURI_CRITICAL_ENTER(); for(size_t i = 0; i < data->blocks_to_write; i++) { - t5577_write_block(i, false, data->block[i]); + t5577_write_block_simple(i, false, data->block[i]); + } + t5577_write_reset(); + FURI_CRITICAL_EXIT(); + t5577_stop(); +} + +void t5577_write_with_pass(LFRFIDT5577* data, uint32_t password) { + t5577_start(); + FURI_CRITICAL_ENTER(); + for(size_t i = 0; i < data->blocks_to_write; i++) { + t5577_write_block_pass(0, false, data->block[i], true, password); } t5577_write_reset(); FURI_CRITICAL_EXIT(); diff --git a/lib/lfrfid/tools/t5577.h b/lib/lfrfid/tools/t5577.h index 6d53b5dc7..c77984476 100644 --- a/lib/lfrfid/tools/t5577.h +++ b/lib/lfrfid/tools/t5577.h @@ -51,6 +51,8 @@ typedef struct { */ void t5577_write(LFRFIDT5577* data); +void t5577_write_with_pass(LFRFIDT5577* data, uint32_t password); + #ifdef __cplusplus } #endif \ No newline at end of file From 70cda48632139e246c549903f3addf927da2bee3 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Mon, 29 May 2023 22:44:05 +0300 Subject: [PATCH 19/52] Change fw origin --- fbt_options.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fbt_options.py b/fbt_options.py index a6ae0925f..561b818d4 100644 --- a/fbt_options.py +++ b/fbt_options.py @@ -3,7 +3,7 @@ import posixpath # For more details on these options, run 'fbt -h' -FIRMWARE_ORIGIN = "Official" +FIRMWARE_ORIGIN = "Unleashed" # Default hardware target TARGET_HW = 7 From 2e70470d1233d89671998e1416087f1d5555ecaf Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Mon, 29 May 2023 23:12:38 +0300 Subject: [PATCH 20/52] remove unused var --- applications/external/bad_bt/application.fam | 1 - 1 file changed, 1 deletion(-) diff --git a/applications/external/bad_bt/application.fam b/applications/external/bad_bt/application.fam index ddd8eee19..a3544b997 100644 --- a/applications/external/bad_bt/application.fam +++ b/applications/external/bad_bt/application.fam @@ -13,5 +13,4 @@ App( fap_category="Tools", fap_icon="images/badbt_10px.png", fap_icon_assets="images", - fap_icon_assets_symbol="bad_bt", ) From 121526f52173b66e736cc355d70fb4fba1947dcd Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Mon, 29 May 2023 23:50:13 +0300 Subject: [PATCH 21/52] Use AC Remote from OFW, same for Audio remote ASSETS update needed, will be done soon --- .../scenes/infrared_scene_universal_ac.c | 54 +- .../scenes/infrared_scene_universal_audio.c | 75 +- assets/icons/Infrared/CoolHi_25x27.png | Bin 0 -> 3680 bytes assets/icons/Infrared/CoolHi_hvr_25x27.png | Bin 0 -> 3669 bytes assets/icons/Infrared/CoolLo_25x27.png | Bin 0 -> 3676 bytes assets/icons/Infrared/CoolLo_hvr_25x27.png | Bin 0 -> 3657 bytes assets/icons/Infrared/Dehumidify_25x27.png | Bin 0 -> 3665 bytes .../icons/Infrared/Dehumidify_hvr_25x27.png | Bin 0 -> 3652 bytes assets/icons/Infrared/HeatHi_25x27.png | Bin 0 -> 3676 bytes assets/icons/Infrared/HeatHi_hvr_25x27.png | Bin 0 -> 3661 bytes assets/icons/Infrared/HeatLo_25x27.png | Bin 0 -> 3670 bytes assets/icons/Infrared/HeatLo_hvr_25x27.png | Bin 0 -> 3655 bytes assets/icons/Infrared/Off_25x27.png | Bin 0 -> 9530 bytes assets/icons/Infrared/Off_hvr_25x27.png | Bin 0 -> 8460 bytes assets/icons/Infrared/Pause_25x27.png | Bin 0 -> 3634 bytes assets/icons/Infrared/Pause_hvr_25x27.png | Bin 0 -> 3623 bytes assets/icons/Infrared/Play_25x27.png | Bin 0 -> 3653 bytes assets/icons/Infrared/Play_hvr_25x27.png | Bin 0 -> 3643 bytes assets/icons/Infrared/Swing_25x27.png | Bin 1706 -> 0 bytes assets/icons/Infrared/Swing_hvr_25x27.png | Bin 1686 -> 0 bytes assets/icons/Infrared/TrackNext_25x27.png | Bin 0 -> 3651 bytes assets/icons/Infrared/TrackNext_hvr_25x27.png | Bin 0 -> 3639 bytes assets/icons/Infrared/TrackPrev_25x27.png | Bin 0 -> 3657 bytes assets/icons/Infrared/TrackPrev_hvr_25x27.png | Bin 0 -> 3644 bytes assets/resources/infrared/assets/ac.ir | 2050 +++-------------- 25 files changed, 437 insertions(+), 1742 deletions(-) create mode 100644 assets/icons/Infrared/CoolHi_25x27.png create mode 100644 assets/icons/Infrared/CoolHi_hvr_25x27.png create mode 100644 assets/icons/Infrared/CoolLo_25x27.png create mode 100644 assets/icons/Infrared/CoolLo_hvr_25x27.png create mode 100644 assets/icons/Infrared/Dehumidify_25x27.png create mode 100644 assets/icons/Infrared/Dehumidify_hvr_25x27.png create mode 100644 assets/icons/Infrared/HeatHi_25x27.png create mode 100644 assets/icons/Infrared/HeatHi_hvr_25x27.png create mode 100644 assets/icons/Infrared/HeatLo_25x27.png create mode 100644 assets/icons/Infrared/HeatLo_hvr_25x27.png create mode 100644 assets/icons/Infrared/Off_25x27.png create mode 100644 assets/icons/Infrared/Off_hvr_25x27.png create mode 100644 assets/icons/Infrared/Pause_25x27.png create mode 100644 assets/icons/Infrared/Pause_hvr_25x27.png create mode 100644 assets/icons/Infrared/Play_25x27.png create mode 100644 assets/icons/Infrared/Play_hvr_25x27.png delete mode 100644 assets/icons/Infrared/Swing_25x27.png delete mode 100644 assets/icons/Infrared/Swing_hvr_25x27.png create mode 100644 assets/icons/Infrared/TrackNext_25x27.png create mode 100644 assets/icons/Infrared/TrackNext_hvr_25x27.png create mode 100644 assets/icons/Infrared/TrackPrev_25x27.png create mode 100644 assets/icons/Infrared/TrackPrev_hvr_25x27.png diff --git a/applications/main/infrared/scenes/infrared_scene_universal_ac.c b/applications/main/infrared/scenes/infrared_scene_universal_ac.c index 68a6ea942..58f067735 100644 --- a/applications/main/infrared/scenes/infrared_scene_universal_ac.c +++ b/applications/main/infrared/scenes/infrared_scene_universal_ac.c @@ -11,7 +11,6 @@ void infrared_scene_universal_ac_on_enter(void* context) { infrared_brute_force_set_db_filename(brute_force, EXT_PATH("infrared/assets/ac.ir")); - //TODO Improve A/C universal remote button_panel_reserve(button_panel, 2, 3); uint32_t i = 0; button_panel_add_item( @@ -20,77 +19,74 @@ void infrared_scene_universal_ac_on_enter(void* context) { 0, 0, 3, - 24, - &I_Power_25x27, - &I_Power_hvr_25x27, + 22, + &I_Off_25x27, + &I_Off_hvr_25x27, infrared_scene_universal_common_item_callback, context); - infrared_brute_force_add_record(brute_force, i++, "POWER"); + infrared_brute_force_add_record(brute_force, i++, "Off"); button_panel_add_item( button_panel, i, 1, 0, 36, - 24, - &I_Mode_25x27, - &I_Mode_hvr_25x27, + 22, + &I_Dehumidify_25x27, + &I_Dehumidify_hvr_25x27, infrared_scene_universal_common_item_callback, context); - infrared_brute_force_add_record(brute_force, i++, "MODE"); + infrared_brute_force_add_record(brute_force, i++, "Dh"); button_panel_add_item( button_panel, i, 0, 1, 3, - 66, - &I_Vol_up_25x27, - &I_Vol_up_hvr_25x27, + 59, + &I_CoolHi_25x27, + &I_CoolHi_hvr_25x27, infrared_scene_universal_common_item_callback, context); - infrared_brute_force_add_record(brute_force, i++, "TEMP+"); + infrared_brute_force_add_record(brute_force, i++, "Cool_hi"); button_panel_add_item( button_panel, i, 1, 1, 36, - 66, - &I_Vol_down_25x27, - &I_Vol_down_hvr_25x27, + 59, + &I_HeatHi_25x27, + &I_HeatHi_hvr_25x27, infrared_scene_universal_common_item_callback, context); - infrared_brute_force_add_record(brute_force, i++, "TEMP-"); + infrared_brute_force_add_record(brute_force, i++, "Heat_hi"); button_panel_add_item( button_panel, i, 0, 2, 3, - 98, - &I_Swing_25x27, - &I_Swing_hvr_25x27, + 91, + &I_CoolLo_25x27, + &I_CoolLo_hvr_25x27, infrared_scene_universal_common_item_callback, context); - infrared_brute_force_add_record(brute_force, i++, "SWING"); + infrared_brute_force_add_record(brute_force, i++, "Cool_lo"); button_panel_add_item( button_panel, i, 1, 2, 36, - 98, - &I_Timer_25x27, - &I_Timer_hvr_25x27, + 91, + &I_HeatLo_25x27, + &I_HeatLo_hvr_25x27, infrared_scene_universal_common_item_callback, context); - infrared_brute_force_add_record(brute_force, i++, "TIMER"); + infrared_brute_force_add_record(brute_force, i++, "Heat_lo"); - button_panel_add_label(button_panel, 6, 11, FontPrimary, "AC remote"); - button_panel_add_label(button_panel, 20, 63, FontSecondary, "Temp"); - button_panel_add_label(button_panel, 8, 23, FontSecondary, "Pwr"); - button_panel_add_label(button_panel, 40, 23, FontSecondary, "Mod"); + button_panel_add_label(button_panel, 6, 10, FontPrimary, "AC remote"); view_set_orientation(view_stack_get_view(infrared->view_stack), ViewOrientationVertical); view_dispatcher_switch_to_view(infrared->view_dispatcher, InfraredViewStack); diff --git a/applications/main/infrared/scenes/infrared_scene_universal_audio.c b/applications/main/infrared/scenes/infrared_scene_universal_audio.c index d3b7e083b..00c86fff4 100644 --- a/applications/main/infrared/scenes/infrared_scene_universal_audio.c +++ b/applications/main/infrared/scenes/infrared_scene_universal_audio.c @@ -10,8 +10,8 @@ void infrared_scene_universal_audio_on_enter(void* context) { InfraredBruteForce* brute_force = infrared->brute_force; infrared_brute_force_set_db_filename(brute_force, EXT_PATH("infrared/assets/audio.ir")); - //TODO Improve Audio universal remote - button_panel_reserve(button_panel, 2, 2); + + button_panel_reserve(button_panel, 2, 4); uint32_t i = 0; button_panel_add_item( button_panel, @@ -19,51 +19,98 @@ void infrared_scene_universal_audio_on_enter(void* context) { 0, 0, 3, - 19, + 11, &I_Power_25x27, &I_Power_hvr_25x27, infrared_scene_universal_common_item_callback, context); - infrared_brute_force_add_record(brute_force, i++, "POWER"); + infrared_brute_force_add_record(brute_force, i++, "Power"); button_panel_add_item( button_panel, i, 1, 0, 36, - 19, + 11, &I_Mute_25x27, &I_Mute_hvr_25x27, infrared_scene_universal_common_item_callback, context); - infrared_brute_force_add_record(brute_force, i++, "MUTE"); + infrared_brute_force_add_record(brute_force, i++, "Mute"); button_panel_add_item( button_panel, i, 0, 1, 3, - 64, - &I_Vol_up_25x27, - &I_Vol_up_hvr_25x27, + 41, + &I_Play_25x27, + &I_Play_hvr_25x27, infrared_scene_universal_common_item_callback, context); - infrared_brute_force_add_record(brute_force, i++, "VOL+"); + infrared_brute_force_add_record(brute_force, i++, "Play"); button_panel_add_item( button_panel, i, 1, 1, 36, - 64, + 41, + &I_Pause_25x27, + &I_Pause_hvr_25x27, + infrared_scene_universal_common_item_callback, + context); + infrared_brute_force_add_record(brute_force, i++, "Pause"); + button_panel_add_item( + button_panel, + i, + 0, + 2, + 3, + 71, + &I_TrackPrev_25x27, + &I_TrackPrev_hvr_25x27, + infrared_scene_universal_common_item_callback, + context); + infrared_brute_force_add_record(brute_force, i++, "Prev"); + button_panel_add_item( + button_panel, + i, + 1, + 2, + 36, + 71, + &I_TrackNext_25x27, + &I_TrackNext_hvr_25x27, + infrared_scene_universal_common_item_callback, + context); + infrared_brute_force_add_record(brute_force, i++, "Next"); + button_panel_add_item( + button_panel, + i, + 0, + 3, + 3, + 101, &I_Vol_down_25x27, &I_Vol_down_hvr_25x27, infrared_scene_universal_common_item_callback, context); - infrared_brute_force_add_record(brute_force, i++, "VOL-"); + infrared_brute_force_add_record(brute_force, i++, "Vol_dn"); + button_panel_add_item( + button_panel, + i, + 1, + 3, + 36, + 101, + &I_Vol_up_25x27, + &I_Vol_up_hvr_25x27, + infrared_scene_universal_common_item_callback, + context); + infrared_brute_force_add_record(brute_force, i++, "Vol_up"); - button_panel_add_label(button_panel, 5, 11, FontSecondary, "Audio remote"); - button_panel_add_label(button_panel, 17, 60, FontSecondary, "Volume"); + button_panel_add_label(button_panel, 1, 8, FontPrimary, "Mus. remote"); view_set_orientation(view_stack_get_view(infrared->view_stack), ViewOrientationVertical); view_dispatcher_switch_to_view(infrared->view_dispatcher, InfraredViewStack); diff --git a/assets/icons/Infrared/CoolHi_25x27.png b/assets/icons/Infrared/CoolHi_25x27.png new file mode 100644 index 0000000000000000000000000000000000000000..cea29a5b9e764c88ae56f305368568d04e544876 GIT binary patch literal 3680 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 literal 0 HcmV?d00001 diff --git a/assets/icons/Infrared/CoolHi_hvr_25x27.png b/assets/icons/Infrared/CoolHi_hvr_25x27.png new file mode 100644 index 0000000000000000000000000000000000000000..692ac7b8be718dfe02b460c9ce9a710857feb562 GIT binary patch literal 3669 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 literal 0 HcmV?d00001 diff --git a/assets/icons/Infrared/CoolLo_25x27.png b/assets/icons/Infrared/CoolLo_25x27.png new file mode 100644 index 0000000000000000000000000000000000000000..23288e44f158d4034bebfd6a2a9005514b132a9d GIT binary patch literal 3676 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 literal 0 HcmV?d00001 diff --git a/assets/icons/Infrared/CoolLo_hvr_25x27.png b/assets/icons/Infrared/CoolLo_hvr_25x27.png new file mode 100644 index 0000000000000000000000000000000000000000..ae5316e4d49992b01a39a4298e36cac1fd365388 GIT binary patch literal 3657 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 P_yK!sCtMlE=iI*m`3F!x literal 0 HcmV?d00001 diff --git a/assets/icons/Infrared/Dehumidify_25x27.png b/assets/icons/Infrared/Dehumidify_25x27.png new file mode 100644 index 0000000000000000000000000000000000000000..dca77ae410bcc2196a693023640372da1b1912ea GIT binary patch literal 3665 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 Y0_*BPx59$cJUb46GqS>#p?%qL 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 Tfe|}@hk%WR1FiydCgT49&LB(v literal 0 HcmV?d00001 diff --git a/assets/icons/Infrared/HeatHi_25x27.png b/assets/icons/Infrared/HeatHi_25x27.png new file mode 100644 index 0000000000000000000000000000000000000000..a1724f995562587ec54740789f37729d567e0f88 GIT binary patch literal 3676 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 literal 0 HcmV?d00001 diff --git a/assets/icons/Infrared/HeatHi_hvr_25x27.png b/assets/icons/Infrared/HeatHi_hvr_25x27.png new file mode 100644 index 0000000000000000000000000000000000000000..b92108d68de2ab09bed6b451e36396881e5611ea GIT binary patch literal 3661 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 T-|@M}j{(?QJ7Y`Hry~9hE1FGt literal 0 HcmV?d00001 diff --git a/assets/icons/Infrared/HeatLo_25x27.png b/assets/icons/Infrared/HeatLo_25x27.png new file mode 100644 index 0000000000000000000000000000000000000000..af2e59d4940aefa657c280acb8073800408dabba GIT binary patch literal 3670 zcmaJ^c|4Ts+kYIgZ1Ir!msi)vJwq#1jD5O z(~x*{K45Cj6P}%};tb^S0Uljmo>PE>7T}?J`BOg-p1qL~$^*D3D@ya^CIX=S}vG&Xu0I92Deffl}0tn2wa4_pjLo@t1INN8plfZsFXhG7gDAvq&YZ44j!Q^ z@nPjP0OTf0bF*F93gU>Db2$3()#7KgzP#Yy0egB*ZO`mwtqH9<7=DaD zoVI=M$ReNbX_4IX>(_lMB}|_HxpTv=D~#RR;O^e685)|Io*uMrMZ1$aT`z4@n$I-4 zZk_uh%;?AZ+K1;Kl_TJ%A}sheJ~Y2xwaq)!b4%!|=jf*diyu!#c77=IgIldUYls?B zQ;z!r;<1@GR^WNyIP@*`mq+?`ygyE8Zt@yW=mC$;8uNrEY89UH;{9f$DoJEDeq0BD z40V< z|DmQmqfH_|JoK-km0O$9l4xP?@Iy=w_0mYRT6Fg#1q~1ATT=zyMn~W1B!)Po+2xry ziXrixB$(5rRv#h6XVxLOpQJb(%j0>Cs1z?Kn-R64*ksAK@47PRRjiaF*d|fW66SP` z0CKTZSVl2_LByOiuT4DG0l*`FMAuuuk|Qb|QEx?`U}_2t4qi3CC-TOd1YhE$9kEO`#;Ot_pCeXi3|_N5@Nf>*ChD zdMem_`yz0SLi&7cG>CNA%#vtJv>UW61RYY=-8(E~AjEssu~`+IRA}>9rFQQhtp_~e zuo$AHrqa883Hzavp|O}&1Lb{j7`ST9&0nl49uWHW^_lniJ1Na+7G>#L9#l$tHSFzI zDS$}U1Rd>&n$DhXnbw(>pH^IU7tZ!H4S2BO{87!R^Q^VpjO2{&3_m#?Zsu}7(`l^m zE@7`;!U=TQ-D;prE+r@9p|Ycp|`0eF2&gn^Um_ll%ivW zF~yWZI>F>YnA=tyzgvrKi#_InV{XNnsrojMh?iVdkfx%aSV{Ex2)$O7iteF{7c}b9 zw-oBGql$~}A}~7EI<8etE6F}40#oS$8@E|@LbGZGX)9sZ#-*0jKdQ^;>)O`9$S3`Z zQ`1t3C6*{;g_=dl9e0vS9CxmFG- z_REvMTZd)8@Gn?Q&v|}2Jja$^Fdp16`~A=*=oVp%_Pt=uLX^l~C92FnBFZ^n^inT? zZlnNhANlHtIn`o{$s?tZ(k8Da*7O?PA29#TT;c|`?c|j56s?Wcc3*{GMN!2D{{_F8 z>4dMzSI<9Yd(5`I`*rud?spk_St!_h_-xi}*88l9ryeJQPH0vaRzD+KRZgGCcU!Ek z_m4V(aLXgQoH$iwUY1>US4Vw=I-_Sj>=kiNXnmu)xPmDdchFcqZreqRFL~tEqEP3b9AB zXHaLVdViOCD>d6WtKWhmOQ{LGvJ!he&L*-8l4cCal5ZR9XqdKUtp%K#4C!0T&Z^34 zUML)SxTwEKU5pvM^IG?gdXAe;;G32X%m>GrUK5c!DcXJ$rD66M`v}UDStY0!G|{!} z{iCOO?BaFOlC1GJW9FSH<0&J9arn5~nb!u5PdlD=*|*Sh&O}XME-USL?}Y610tMkm zcqqJa5oQtYzie)VTvU7!Z-N{lf2$l?FuRdkVj7dm(dwMdAp}IDT;KoP^NAk|D={ClKZ;C+%BDj*PBDV- za++783S^2P`!tcMrna$mhROe9CaF;`ebu_8XHn(~G6 z$>%~>DLJZg`=$T&r_jSG03l>qMlMPf71N8hxC<)aco@Y7N?e zeaV7rT6tK5N(kOB;&fAIWYZHKzj+ZC;hCsQ^P}$FeePG1B zetpaM)$FH+sC^lpd?=XzUJ+KLLZ9Y zl<@B8yoGrCug|x$m)Kfj`eH7>-ERA+#J~nm&#enhtREIb4qvztS~@Av|LX+>iURa3 zI&(SGJj*$A)7{g(*8a6|@4GMKAwMieewDbbYvdMey+U|J9iEHqPogaM+{jMJz7z)e zW7K2hUUlfK7iZ$E1bwMik~P_f+qph_to|71a#v4pJTuoTWtvbDzo!$AP0dOYgh@PufJShn~)g`W2$a( zy6T45s*7dy_Vs60O&83DFk>+TChps#gG-~A&o;7iS9(V+*7>8Z^lT@tB}icQBxEFX zMTBl3vg*=52jx zoR@nz($?H|`1z|K9oXsB`}JD()|eu`{|3I%W6Bme^jhFzbV*El1ob3;p0tT z`LU#z9J%|2$-)s?&U7CZo5UmoX5Ms9GRTTXqL7`)B=6vWS7ajq;8mj%h%6%B7U@N& zK}fqkkRTd^iv|EAlOP7k%a6cQAE502t#L* zK?V?*mY24+Hpl=0A$ybHo;p4xFHI0!8xDiQxVM28%m4}3LBbHAzb`O1Ak*6i>4Y`^ zI~@0f0{gO93?vlFX0st|9SEICfx-|71XLRig~PSD9$JCH{wz|EmVcnqPX;VG(2GfB zu&8u@&@Lm%lYX9s0&~Uwl?9FQ53PUT-<9Il3>rjYKw%K=-K>5(;_?5#D~ky4QIc*`M_j>&?ZQ;S3G+49pGx6}vkSGzK>^mdvDHAbXoL=`_%v zStF_css)StSH8co-v33*UwL57{}l`6ih=I-_W$(yr-?g2yW4+;mwWhU{K@{@nP+l` zyQ1^!?r$5vgDnBKv$Mn9x-|EPaTk&m){GD|eEXK0IG`wq8QDA&a?i}-X6;u@vxtKX z@Znsc4@XYAu=h~%hTNnAiLg5RI;`-G>W!=A{idIB2h`6WtjHX>eg4-XJf~`~sm1&b oR5o@)5^Qm9KKWsKq2KKJKdp6hzzPFtG_@gL>~06@sx z3~R?;rP+@RFDLt5&wA?&0Q|;e4Cb^s1_Pqesb1uZL;wgF&$cJw>=z|bo73xPi`cN+ z7F0V4UXUF+K1@7GQALhV^i-_ey)g;frUS;tTrwTGv78ABVK*dfRRyo}kMhjP-A{;o z5PQ9A`+e{OpW)igk3GB3NAwp;*0L-5cp7;HQ_VDNwZa4o(MJ!wi)?Rgdp`#;4Chy% z0iwJWo^t*>@*KccsGi;la3fDWz!5MgzzZ~5Wi_fFiD8L+MrXKkgk9rkWF(!m;0+T8 z41*HTj{rjxjMSCEZ3vlc9aGwQEs{w9GS3eE{VcA<5!5o0gZ8-^!+#~>WkQj>v zymf(+zBAX20lYdO?q$)607lgSb#q5AGvG-T(AX;~P!8}40_wK0QO5zUV8E?IUOoW0 zmH~*HtUBubd7?~oL4{qZjB>qd1%z?93$L0VkE0{xsB*8l)CqBI!ahQ#A*4AlLmD2g zDe`XZH2~x$NwBkB+X?6uF6-^pPN)<AS^u&3*D?qUnz+0oD)ML2#?Ndo^A~ zeAZUXF9Dl*V-21Mjzix%{_5BO%k#sG>NcnTj27_Zf<8xZl3Kx856-U^N}_m1%y0Ptz&We}1lLtz(9R10*xYcHCq^>sO@~w) zxsNpMpKKEN;ii2Jt~19WRMMD@XS{kyUYnzBQE9Y_#=`PNoS%njKyU zqi7=E3A{N?%C+HqTt*$d2MKcHu^jH#@$w10QW;TOa!qDjV(|)~&RB6(0nI((ehY@3z9$pseA6ki_r)_TYt z4vWE?smc$FB_4!|2FGGrbri(nFmR>noBPb4KEw@(4VVo0+Q~1f7G`Oh9hOh-9QX7o z=Rw?71)b=Kn#-PRnbVk)nUh;};m>wA^n18v|3TTV>%uANdC_^zd2V7l+{ocUrrlJ* zJ=_7UL}zsAy-K^swlM_tKmNpcd0;B#sCC*K$ARue z(@$xiIM8wLMhe*=QLyyxfA4w0!OSj|Hbzoo87cxXLs1A6QN|h@T zNnQLYr&1JCWK^KI!lFk-(?tRfYYyGG#KLp-A!Q~G8uqh=d~Z{W9g4C~f3cUbCl%@z z#1xSVs5pa%p-ww-+)gc)EjE~kwz*Hw&(^kq1U#fG0#xOEgo>jtg=@7cKJ6L1a#^J& zeMhz?9#vF$4}sA*rQuj%w|3jhfM+({Z|e@jnr}flKW#1a`n34U@ejvk9%))u!-%dv zMX712_+qnS+hWr%b=qZ1`Pq-^jBA{>!-b97Pbs-7nUWHF_h&EIkJ(S<^XE%ip^zJ8 zkRqQvnR_)@W`l43a(Yhvxv(5dYW{R!-NN@HA3CT2ght-h&~N-%UhrklS2m6=o@Il(q+o+=_CF7FM6F zmNV_FsvjMHq-&{b+1~TI=YG#{hE^5|HUeMBTF4s7nyGSg4scejEU0`zG%ufXe&n=V zS?e3+jBv`sJ2;=MFe%M0JvLlZT9bbuzuG$4x;ST;)bixd%FfEdD(NTlqudi^m6Xa5 z0?A#9RQ0N?WjVPnIpk%??>i_Sp_nn@Vp(U|Q2%FiapW1~bY}0JWrL7c>#2)S624Eg zZ&YKp@?iJzR&us|)}Sd#id5|%xfUBAXA#j2Nz;d9$+S&%)Xkk@Z1|mhA2hI$omG+5 zyi_ppcv*Xyyc{!m_qFET<2gGY|%S+d_rjlUB8=o8Lac|?V$oJ4f=YUqjULZlYwoakA4 zUC}jhQ|HdgUDlFVv)KDvm3h$?j%u>_k98#%5aoJ)ffM|*68ld?pW!aidvU!|g)(GQ zyyTcx7FwqmWaSfnuBj`c={bkb7Xb(U`KXXDlOs!KZSYX1ndgM>(b+Qk5^>kd#3!WE zB(9DsPX^4(#8A5$GA3_7D=coU_U!W-@LK#ht(M~=oLZFjF-_Q4Xl(qM(9D@@F&8K3oblLu|u zYwpx!mQ}m@R4)hBJrDNUT$IVt>781y3;a`(H9VAqKuy)H1yMI&ZEnm+PKDByc6z&O z#+XXWrL{J-=hqFFjK(liF+&C}yOX0UlUFY^GIQ7ZCrvlGqayoulQt4XF#8iT61$^? zqQB&v)JGsb7|?eXf8=BOJo^-Lq;~J`c9%&>LPNKPzKrztr}y7WTTM%Dpj^q@`P}$L z`td|tbKBAS&HxSAx%D&KOHIs4rtHdt84;VgE1;{&EbnhmH|*c!ZzoG9C$qRX)7O5i zXx)z3`@>`y;~Dl;F9wr9Cjv&ERCglCoI)TG?T7@=K)+6+9sqDElW}+k-pUf`L8U+l zdp?i=3XP2h06l{M8o|Sd$N;$$Nn~FXc%`NR3?h4?z>Zp0>Q*!i(VJ`*L?_w@S>rr{ zd^`}IU;}-SUI3C!Kp`>+pa9B6Uw>o(3j7x@lD*$EL&2cGTo^tm@V`ajtxkh5R5}r) z1A(b|sH>}kbPy1tCjsuR;YILJ1;N$fFer?D>!`tWkZ=to3<3K40<#0sJ-v{2Sd+iQ zu}>(lH-kY#LZM716T;MhQ0XKn41qvE)!|S$T#fCa<{#+GAOxuS`pf@hz!LpE=wup$ zO!WorF%sOVml!B8TkOBHpwRxI_4WU|QtX;R0|+!I45Gf5)lWw&tN-mvq5R|R&#)u@ zNAG_n_QwU%h)_GCKlKvbgWWqX`MppyB!*5TFsO7Km3r}KAy0c#8B~97Dh&kJfWSb? zRs;{S@1EuOUl1!Rq`9v@gW&5yG{>UAY!V2W?1?loK6z40#{>;OdD0jLGsYSj>FAt9 z=%5iAShR@=M&l+S#R^-mLffcCck3@`ie&-fF4*)vaP4|j!VyE*&A;681M zGiI+W7AtS;?i71xXO1<(1&lwt)x-~gcrhU?)*vAUH2E;%@~3wd15bhbD#c<7{6fvc zeXnE*2DpZL(&enF-TVl=7ijw7ZDsW_ O0dr$(Y#G`u;{O0;Ay2me literal 0 HcmV?d00001 diff --git a/assets/icons/Infrared/Off_25x27.png b/assets/icons/Infrared/Off_25x27.png new file mode 100644 index 0000000000000000000000000000000000000000..c15100606ac9b2c46fec8d5ed290d72345fb22e2 GIT binary patch literal 9530 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 T&A>rCE`gSso@%+Wb;y4K-_9ky literal 0 HcmV?d00001 diff --git a/assets/icons/Infrared/Off_hvr_25x27.png b/assets/icons/Infrared/Off_hvr_25x27.png new file mode 100644 index 0000000000000000000000000000000000000000..d5e5e6f45d78e070d06e033bd529d0067de94301 GIT binary patch literal 8460 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 literal 0 HcmV?d00001 diff --git a/assets/icons/Infrared/Pause_25x27.png b/assets/icons/Infrared/Pause_25x27.png new file mode 100644 index 0000000000000000000000000000000000000000..a371ba81718e864efe908e61f34bc842079cc20d GIT binary patch literal 3634 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 literal 0 HcmV?d00001 diff --git a/assets/icons/Infrared/Pause_hvr_25x27.png b/assets/icons/Infrared/Pause_hvr_25x27.png new file mode 100644 index 0000000000000000000000000000000000000000..472d583db0ff9adc5ef810675c8b915c6e5a899c GIT binary patch literal 3623 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 HpN{x9W3^Ap literal 0 HcmV?d00001 diff --git a/assets/icons/Infrared/Play_hvr_25x27.png b/assets/icons/Infrared/Play_hvr_25x27.png new file mode 100644 index 0000000000000000000000000000000000000000..6708dcdbf2c7ac0c656bbb1c2441fb0f4d6fc9c5 GIT binary patch literal 3643 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 diff --git a/assets/icons/Infrared/TrackNext_25x27.png b/assets/icons/Infrared/TrackNext_25x27.png new file mode 100644 index 0000000000000000000000000000000000000000..7b8f283915e45ba2289fbee3ff5413fea15fb461 GIT binary patch literal 3651 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 SxG~3f0odCdwl1|i74;vAA8iN# literal 0 HcmV?d00001 diff --git a/assets/icons/Infrared/TrackNext_hvr_25x27.png b/assets/icons/Infrared/TrackNext_hvr_25x27.png new file mode 100644 index 0000000000000000000000000000000000000000..a4de4fc3cbe582349b8c79bbb7ec6e931e8bc792 GIT binary patch literal 3639 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 W@<`O{ko&lf02|BW7A0mL7ybo9V{1nM literal 0 HcmV?d00001 diff --git a/assets/icons/Infrared/TrackPrev_hvr_25x27.png b/assets/icons/Infrared/TrackPrev_hvr_25x27.png new file mode 100644 index 0000000000000000000000000000000000000000..838055341e568fed60b3e28a280fe839d2c9db9e GIT binary patch literal 3644 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 Date: Tue, 30 May 2023 00:12:46 +0300 Subject: [PATCH 22/52] Rename buttons in OFW naming scheme --- .../scenes/infrared_scene_universal_fan.c | 12 +- .../infrared_scene_universal_projector.c | 8 +- .../scenes/infrared_scene_universal_tv.c | 12 +- assets/resources/infrared/assets/audio.ir | 724 +++++++++--------- assets/resources/infrared/assets/fans.ir | 520 ++++++------- .../resources/infrared/assets/projectors.ir | 304 ++++---- assets/resources/infrared/assets/tv.ir | 680 ++++++++-------- 7 files changed, 1130 insertions(+), 1130 deletions(-) diff --git a/applications/main/infrared/scenes/infrared_scene_universal_fan.c b/applications/main/infrared/scenes/infrared_scene_universal_fan.c index 37657ac3c..967e15c24 100644 --- a/applications/main/infrared/scenes/infrared_scene_universal_fan.c +++ b/applications/main/infrared/scenes/infrared_scene_universal_fan.c @@ -25,7 +25,7 @@ void infrared_scene_universal_fan_on_enter(void* context) { &I_Power_hvr_25x27, infrared_scene_universal_common_item_callback, context); - infrared_brute_force_add_record(brute_force, i++, "POWER"); + infrared_brute_force_add_record(brute_force, i++, "Power"); button_panel_add_item( button_panel, i, @@ -37,7 +37,7 @@ void infrared_scene_universal_fan_on_enter(void* context) { &I_Mode_hvr_25x27, infrared_scene_universal_common_item_callback, context); - infrared_brute_force_add_record(brute_force, i++, "MODE"); + infrared_brute_force_add_record(brute_force, i++, "Mode"); button_panel_add_item( button_panel, i, @@ -49,7 +49,7 @@ void infrared_scene_universal_fan_on_enter(void* context) { &I_Vol_up_hvr_25x27, infrared_scene_universal_common_item_callback, context); - infrared_brute_force_add_record(brute_force, i++, "SPEED+"); + infrared_brute_force_add_record(brute_force, i++, "Speed_up"); button_panel_add_item( button_panel, i, @@ -61,7 +61,7 @@ void infrared_scene_universal_fan_on_enter(void* context) { &I_Vol_down_hvr_25x27, infrared_scene_universal_common_item_callback, context); - infrared_brute_force_add_record(brute_force, i++, "SPEED-"); + infrared_brute_force_add_record(brute_force, i++, "Speed_dn"); button_panel_add_item( button_panel, i, @@ -73,7 +73,7 @@ void infrared_scene_universal_fan_on_enter(void* context) { &I_Rotate_hvr_25x27, infrared_scene_universal_common_item_callback, context); - infrared_brute_force_add_record(brute_force, i++, "ROTATE"); + infrared_brute_force_add_record(brute_force, i++, "Rotate"); button_panel_add_item( button_panel, i, @@ -85,7 +85,7 @@ void infrared_scene_universal_fan_on_enter(void* context) { &I_Timer_hvr_25x27, infrared_scene_universal_common_item_callback, context); - infrared_brute_force_add_record(brute_force, i++, "TIMER"); + infrared_brute_force_add_record(brute_force, i++, "Timer"); button_panel_add_label(button_panel, 5, 11, FontPrimary, "Fan remote"); button_panel_add_label(button_panel, 20, 63, FontSecondary, "Speed"); diff --git a/applications/main/infrared/scenes/infrared_scene_universal_projector.c b/applications/main/infrared/scenes/infrared_scene_universal_projector.c index 11a0077f5..32d84dde6 100644 --- a/applications/main/infrared/scenes/infrared_scene_universal_projector.c +++ b/applications/main/infrared/scenes/infrared_scene_universal_projector.c @@ -24,7 +24,7 @@ void infrared_scene_universal_projector_on_enter(void* context) { &I_Power_hvr_25x27, infrared_scene_universal_common_item_callback, context); - infrared_brute_force_add_record(brute_force, i++, "POWER"); + infrared_brute_force_add_record(brute_force, i++, "Power"); button_panel_add_item( button_panel, i, @@ -36,7 +36,7 @@ void infrared_scene_universal_projector_on_enter(void* context) { &I_Mute_hvr_25x27, infrared_scene_universal_common_item_callback, context); - infrared_brute_force_add_record(brute_force, i++, "MUTE"); + infrared_brute_force_add_record(brute_force, i++, "Mute"); button_panel_add_item( button_panel, i, @@ -48,7 +48,7 @@ void infrared_scene_universal_projector_on_enter(void* context) { &I_Vol_up_hvr_25x27, infrared_scene_universal_common_item_callback, context); - infrared_brute_force_add_record(brute_force, i++, "VOL+"); + infrared_brute_force_add_record(brute_force, i++, "Vol_up"); button_panel_add_item( button_panel, i, @@ -60,7 +60,7 @@ void infrared_scene_universal_projector_on_enter(void* context) { &I_Vol_down_hvr_25x27, infrared_scene_universal_common_item_callback, context); - infrared_brute_force_add_record(brute_force, i++, "VOL-"); + infrared_brute_force_add_record(brute_force, i++, "Vol_dn"); button_panel_add_label(button_panel, 10, 11, FontPrimary, "Projector"); button_panel_add_label(button_panel, 17, 60, FontSecondary, "Volume"); diff --git a/applications/main/infrared/scenes/infrared_scene_universal_tv.c b/applications/main/infrared/scenes/infrared_scene_universal_tv.c index 583f21fa3..e21bf8f90 100644 --- a/applications/main/infrared/scenes/infrared_scene_universal_tv.c +++ b/applications/main/infrared/scenes/infrared_scene_universal_tv.c @@ -24,7 +24,7 @@ void infrared_scene_universal_tv_on_enter(void* context) { &I_Power_hvr_25x27, infrared_scene_universal_common_item_callback, context); - infrared_brute_force_add_record(brute_force, i++, "POWER"); + infrared_brute_force_add_record(brute_force, i++, "Power"); button_panel_add_item( button_panel, i, @@ -36,7 +36,7 @@ void infrared_scene_universal_tv_on_enter(void* context) { &I_Mute_hvr_25x27, infrared_scene_universal_common_item_callback, context); - infrared_brute_force_add_record(brute_force, i++, "MUTE"); + infrared_brute_force_add_record(brute_force, i++, "Mute"); button_panel_add_item( button_panel, i, @@ -48,7 +48,7 @@ void infrared_scene_universal_tv_on_enter(void* context) { &I_Vol_up_hvr_25x27, infrared_scene_universal_common_item_callback, context); - infrared_brute_force_add_record(brute_force, i++, "VOL+"); + infrared_brute_force_add_record(brute_force, i++, "Vol_up"); button_panel_add_item( button_panel, i, @@ -60,7 +60,7 @@ void infrared_scene_universal_tv_on_enter(void* context) { &I_Up_hvr_25x27, infrared_scene_universal_common_item_callback, context); - infrared_brute_force_add_record(brute_force, i++, "CH+"); + infrared_brute_force_add_record(brute_force, i++, "Ch_next"); button_panel_add_item( button_panel, i, @@ -72,7 +72,7 @@ void infrared_scene_universal_tv_on_enter(void* context) { &I_Vol_down_hvr_25x27, infrared_scene_universal_common_item_callback, context); - infrared_brute_force_add_record(brute_force, i++, "VOL-"); + infrared_brute_force_add_record(brute_force, i++, "Vol_dn"); button_panel_add_item( button_panel, i, @@ -84,7 +84,7 @@ void infrared_scene_universal_tv_on_enter(void* context) { &I_Down_hvr_25x27, infrared_scene_universal_common_item_callback, context); - infrared_brute_force_add_record(brute_force, i++, "CH-"); + infrared_brute_force_add_record(brute_force, i++, "Ch_prev"); button_panel_add_label(button_panel, 6, 11, FontPrimary, "TV remote"); button_panel_add_label(button_panel, 9, 64, FontSecondary, "Vol"); diff --git a/assets/resources/infrared/assets/audio.ir b/assets/resources/infrared/assets/audio.ir index 14c18c04c..cfb89f911 100644 --- a/assets/resources/infrared/assets/audio.ir +++ b/assets/resources/infrared/assets/audio.ir @@ -3,2175 +3,2175 @@ Version: 1 # Last Updated 14th Apr, 2023 # Last Checked 17th May, 2023 # -name: POWER +name: Power type: parsed protocol: NEC address: 77 00 00 00 command: F1 00 00 00 # -name: MUTE +name: Mute type: parsed protocol: NEC address: 77 00 00 00 command: F3 00 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NEC address: 77 00 00 00 command: FB 00 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NEC address: 77 00 00 00 command: FC 00 00 00 # -name: POWER +name: Power type: parsed protocol: NEC address: 80 00 00 00 command: 1A 00 00 00 # -name: POWER +name: Power type: parsed protocol: NECext address: 10 E7 00 00 command: 46 B9 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NECext address: 10 E7 00 00 command: 06 F9 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NECext address: 10 E7 00 00 command: 47 B8 00 00 # -name: MUTE +name: Mute type: parsed protocol: NECext address: 10 E7 00 00 command: 41 BE 00 00 # -name: POWER +name: Power type: parsed protocol: RC5 address: 10 00 00 00 command: 0C 00 00 00 # -name: MUTE +name: Mute type: parsed protocol: RC5 address: 10 00 00 00 command: 0D 00 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: RC5 address: 10 00 00 00 command: 10 00 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: RC5 address: 10 00 00 00 command: 11 00 00 00 # -name: POWER +name: Power type: parsed protocol: NEC address: 00 00 00 00 command: 40 00 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NEC address: 00 00 00 00 command: 41 00 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NEC address: 00 00 00 00 command: 45 00 00 00 # -name: MUTE +name: Mute type: parsed protocol: NEC address: 00 00 00 00 command: 48 00 00 00 # -name: POWER +name: Power type: parsed protocol: NECext address: 2D D3 00 00 command: 12 ED 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NECext address: 2D D3 00 00 command: 11 EE 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NECext address: 2D D3 00 00 command: 10 EF 00 00 # -name: MUTE +name: Mute type: parsed protocol: NECext address: 2D D3 00 00 command: 13 EC 00 00 # -name: POWER +name: Power type: parsed protocol: SIRC15 address: 44 00 00 00 command: 15 00 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: SIRC15 address: 44 00 00 00 command: 12 00 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: SIRC15 address: 44 00 00 00 command: 13 00 00 00 # -name: MUTE +name: Mute type: parsed protocol: SIRC15 address: 44 00 00 00 command: 14 00 00 00 # -name: POWER +name: Power type: parsed protocol: NECext address: 02 A0 00 00 command: 80 7F 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NECext address: 02 A0 00 00 command: AA 55 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NECext address: 02 A0 00 00 command: 6A 95 00 00 # -name: MUTE +name: Mute type: parsed protocol: NECext address: 02 A0 00 00 command: EA 15 00 00 # Standby -name: POWER +name: Power type: parsed protocol: NEC address: 04 00 00 00 command: 16 00 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NEC address: 04 00 00 00 command: 13 00 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NEC address: 04 00 00 00 command: 0B 00 00 00 # -name: MUTE +name: Mute type: parsed protocol: NEC address: 04 00 00 00 command: 06 00 00 00 # -name: POWER +name: Power type: parsed protocol: NECext address: 29 A1 00 00 command: 7F 80 00 00 # -name: MUTE +name: Mute type: parsed protocol: NECext address: 29 A1 00 00 command: 9B 64 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NECext address: 29 A1 00 00 command: 9E 61 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NECext address: 29 A1 00 00 command: 9F 60 00 00 # -name: POWER +name: Power type: parsed protocol: NEC address: 7A 00 00 00 command: 1F 00 00 00 # -name: POWER +name: Power type: parsed protocol: NEC address: 00 00 00 00 command: 1C 00 00 00 # -name: MUTE +name: Mute type: parsed protocol: NEC address: 00 00 00 00 command: 0B 00 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NEC address: 00 00 00 00 command: 0F 00 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NEC address: 00 00 00 00 command: 05 00 00 00 # -name: VOL+ +name: Vol_up type: raw frequency: 38000 duty_cycle: 0.330000 data: 4617 4406 584 448 557 448 557 449 556 449 555 1430 580 1432 577 452 552 454 550 1460 549 1462 548 1462 549 1462 548 457 548 457 548 457 548 457 548 4463 548 457 548 457 548 457 548 458 548 1462 548 1462 548 1462 548 457 548 1463 547 1462 548 1462 548 458 547 458 548 458 548 458 547 1463 547 458 547 458 547 458 548 1463 547 55451 4606 4440 549 457 548 457 548 457 548 457 548 1462 548 1462 548 457 548 457 548 1462 548 1461 549 1462 548 1462 548 457 548 457 548 457 548 457 548 4462 548 457 548 457 548 457 548 457 548 1462 548 1462 548 1462 548 457 548 1462 548 1462 548 1462 547 457 548 458 547 458 547 458 547 1462 548 458 547 458 547 458 547 1462 548 # -name: VOL- +name: Vol_dn type: raw frequency: 38000 duty_cycle: 0.330000 data: 4614 4408 583 449 555 450 555 451 553 451 554 1432 577 1434 576 453 551 454 550 1460 549 1461 549 1461 549 1461 549 457 548 457 548 457 548 457 548 4461 548 457 548 457 548 457 548 457 548 457 548 457 548 457 548 1462 548 1461 549 1461 549 1461 548 457 548 1462 549 1461 549 1461 548 457 548 457 548 457 548 458 547 1462 548 55443 4606 4440 549 456 549 456 549 456 549 456 549 1461 549 1461 549 457 548 457 548 1461 549 1461 549 1461 549 1461 549 456 549 457 548 457 548 457 548 4461 549 456 549 457 548 457 548 457 548 457 548 457 548 457 548 1462 548 1461 549 1461 549 1461 548 457 548 1461 549 1461 549 1461 549 457 548 457 548 458 547 457 548 1462 548 # -name: POWER +name: Power type: raw frequency: 38000 duty_cycle: 0.330000 data: 4588 4435 556 477 556 449 555 450 555 451 554 1428 582 1429 581 451 553 452 552 1457 552 1458 551 1461 548 1463 547 458 547 458 547 458 547 458 547 4464 547 458 547 458 547 458 547 458 548 458 547 458 547 458 548 458 547 1463 547 1463 547 1464 546 459 547 1464 546 1464 546 1463 547 1464 546 459 546 459 546 459 546 1464 547 55456 4581 4468 546 458 547 458 547 458 547 458 547 1463 547 1463 547 458 547 459 547 1463 547 1464 546 1464 546 1464 547 459 546 459 546 459 546 459 547 4465 546 459 546 459 546 459 546 459 546 459 547 459 546 459 546 459 546 1464 546 1464 546 1465 546 460 545 1465 545 1465 545 1465 546 1465 546 460 545 460 546 460 545 1466 544 # -name: POWER +name: Power type: parsed protocol: NECext address: 3F 5C 00 00 command: 18 E7 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NECext address: 3F 5C 00 00 command: 55 AA 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NECext address: 3F 5C 00 00 command: 59 A6 00 00 # -name: MUTE +name: Mute type: parsed protocol: NECext address: 3F 5C 00 00 command: 15 EA 00 00 # -name: MUTE +name: Mute type: parsed protocol: NECext address: 00 FB 00 00 command: 1E E1 00 00 # -name: POWER +name: Power type: parsed protocol: NECext address: 00 FB 00 00 command: 1D E2 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NECext address: 00 FB 00 00 command: 18 E7 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NECext address: 00 FB 00 00 command: 0A F5 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NECext address: 80 D9 00 00 command: 8A 75 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NECext address: 80 D9 00 00 command: 88 77 00 00 # -name: MUTE +name: Mute type: parsed protocol: NECext address: 80 D9 00 00 command: 8C 73 00 00 # -name: POWER +name: Power type: parsed protocol: NECext address: 78 0E 00 00 command: 00 FF 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NECext address: 78 0E 00 00 command: 19 E6 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NECext address: 78 0E 00 00 command: 1C E3 00 00 # -name: MUTE +name: Mute type: parsed protocol: NECext address: 78 0E 00 00 command: 18 E7 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NEC address: 20 00 00 00 command: 14 00 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NEC address: 20 00 00 00 command: 10 00 00 00 # # ON -name: POWER +name: Power type: parsed protocol: RC5 address: 10 00 00 00 command: 0E 00 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NECext address: 10 E7 00 00 command: 0C F3 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NECext address: 10 E7 00 00 command: 09 F6 00 00 # -name: POWER +name: Power type: raw frequency: 38000 duty_cycle: 0.330000 data: 3309 1906 410 1178 411 1177 412 416 435 445 406 448 414 440 411 1150 439 415 436 1178 411 1177 412 442 409 444 407 1181 408 419 432 1182 407 420 442 1146 433 448 414 440 411 442 409 444 407 446 416 438 413 441 410 443 408 419 432 1182 407 446 405 422 440 414 437 416 435 445 406 1181 408 446 405 448 414 440 411 442 409 418 433 446 416 438 413 1175 414 413 438 1176 413 414 437 443 408 419 432 421 441 413 438 42493 3308 3343 355 43011 3309 3316 382 43009 3310 3314 384 43007 3303 3347 361 # -name: VOL+ +name: Vol_up type: raw frequency: 38000 duty_cycle: 0.330000 data: 3307 1879 437 1177 412 1176 413 415 436 417 434 446 405 448 414 1174 415 412 439 1149 440 1147 442 438 413 440 411 1177 412 441 410 1178 411 442 409 1179 410 417 434 419 432 448 414 440 411 442 409 444 407 446 416 438 413 441 410 1151 438 415 436 444 407 446 416 412 439 414 437 1177 412 1176 413 414 437 416 435 1152 437 1177 412 416 435 444 407 446 416 1146 433 421 441 1173 406 422 440 413 438 442 409 444 407 40133 3308 3341 357 42862 3301 3347 361 42859 3304 3319 379 # -name: VOL- +name: Vol_dn type: raw frequency: 38000 duty_cycle: 0.330000 data: 3310 1876 440 1174 415 1173 405 422 440 414 437 443 408 445 406 1182 407 420 442 1173 406 1182 407 420 442 412 439 1175 414 440 411 1150 439 415 436 1152 437 416 435 419 432 447 415 440 411 442 409 418 433 420 442 438 413 440 411 1177 412 415 436 418 433 420 442 438 413 441 410 1151 438 1150 439 415 436 1178 411 1150 439 1149 440 414 437 417 434 445 406 1155 434 420 442 438 413 1175 414 413 438 442 409 444 407 39503 3303 3320 388 42857 3304 3319 379 42867 3305 3317 381 # -name: MUTE +name: Mute type: raw frequency: 38000 duty_cycle: 0.330000 data: 3305 1907 409 1178 411 1177 412 442 409 418 433 447 415 439 412 1176 413 441 410 1177 412 1176 413 441 410 443 408 1180 409 445 406 1181 408 446 416 1172 406 448 413 440 411 442 409 445 406 447 414 439 412 442 409 444 407 447 414 1173 405 449 413 441 410 443 408 446 405 448 413 1174 415 440 411 442 409 1178 411 1177 412 1177 412 442 409 444 407 447 415 439 412 441 410 444 407 1180 409 445 406 448 414 440 411 41125 3303 3347 360 42906 3308 3315 382 # -name: MUTE +name: Mute type: parsed protocol: NECext address: BA A0 00 00 command: 01 FE 00 00 # -name: POWER +name: Power type: parsed protocol: Kaseikyo address: AC 02 20 00 command: D1 03 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: Kaseikyo address: A0 02 20 00 command: 00 02 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: Kaseikyo address: A0 02 20 00 command: 10 02 00 00 # -name: MUTE +name: Mute type: parsed protocol: Kaseikyo address: A0 02 20 00 command: 20 03 00 00 # -name: POWER +name: Power type: parsed protocol: NEC address: 01 00 00 00 command: 02 00 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NEC address: 01 00 00 00 command: 01 00 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NEC address: 01 00 00 00 command: 0B 00 00 00 # -name: MUTE +name: Mute type: parsed protocol: NEC address: 01 00 00 00 command: 06 00 00 00 # -name: POWER +name: Power type: raw frequency: 38000 duty_cycle: 0.330000 data: 9150 4435 643 1608 643 468 644 469 642 364 749 468 643 447 665 449 663 469 643 452 660 470 642 450 662 442 670 449 662 469 643 1579 672 1608 642 1580 671 1609 641 1607 643 1578 672 1607 643 1608 642 1606 644 1606 644 1606 644 1607 643 1576 675 1579 671 1605 674 438 645 466 673 438 646 466 674 437 673 439 672 439 673 438 646 1604 673 1577 673 1578 673 1577 674 1577 673 23799 9095 4485 616 # -name: VOL+ +name: Vol_up type: parsed protocol: NEC42 address: 01 00 00 00 command: 0C 00 00 00 # -name: VOL- +name: Vol_dn type: raw frequency: 38000 duty_cycle: 0.330000 data: 9151 4434 644 1608 643 376 737 379 733 446 666 449 663 468 644 469 643 468 644 468 644 468 644 447 665 448 664 468 644 450 662 1608 643 1607 644 1576 676 1607 644 1608 643 1578 674 1608 643 1577 674 1579 672 1607 643 1608 643 1607 644 1607 644 1608 643 448 664 1608 643 448 664 468 644 469 643 380 732 468 644 469 643 1607 644 468 644 1608 643 1608 644 1609 643 1608 643 23837 9152 4434 642 # -name: POWER +name: Power type: raw frequency: 38000 duty_cycle: 0.330000 data: 8968 4344 670 460 670 460 670 1566 669 462 668 486 643 487 642 489 641 1595 640 490 640 491 640 1596 640 491 640 1596 640 1596 640 1596 640 491 640 1596 640 1596 640 1596 640 1596 640 1596 640 1596 640 1596 640 1622 640 491 640 491 640 491 640 491 640 491 640 491 640 491 640 491 639 # -name: POWER +name: Power type: parsed protocol: SIRC address: 10 00 00 00 command: 2E 00 00 00 # -name: POWER +name: Power type: parsed protocol: NECext address: 00 FD 00 00 command: 01 FE 00 00 # -name: MUTE +name: Mute type: parsed protocol: NECext address: 00 FD 00 00 command: 03 FC 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NECext address: 00 FD 00 00 command: 09 F6 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NECext address: 00 FD 00 00 command: 07 F8 00 00 # -name: POWER +name: Power type: raw frequency: 38000 duty_cycle: 0.330000 data: 1042 1461 540 1460 541 1460 541 1460 541 1459 542 1459 542 454 536 460 540 456 544 452 538 458 542 454 546 450 540 456 544 1457 544 1456 545 1448 542 50531 1041 1462 539 1462 539 1461 540 1461 540 1460 541 1460 541 455 545 451 539 457 543 480 510 459 541 481 519 451 539 457 543 1457 543 1457 544 1449 541 50515 1037 1467 544 1456 545 1456 545 1455 546 1455 535 1465 536 486 514 483 517 479 511 485 515 481 509 487 513 483 517 478 512 1462 539 1462 539 1454 536 50537 1035 1467 544 1457 544 1457 544 1456 545 1456 544 1456 545 477 513 483 517 479 511 486 514 481 519 477 513 484 516 479 511 1464 536 1463 538 1455 546 # -name: POWER +name: Power type: raw frequency: 38000 duty_cycle: 0.330000 data: 1010 1491 509 1490 510 1488 512 487 513 487 513 1486 514 1485 515 484 516 1483 517 482 518 482 518 1481 509 1489 511 488 512 487 513 1486 514 484 516 50963 1011 1489 511 1488 512 1487 513 485 515 486 514 1485 515 1484 516 484 516 1483 517 482 518 482 518 1481 509 1489 511 489 511 489 511 1487 513 486 514 50986 1008 1492 518 1480 510 1488 512 487 513 487 513 1486 514 1484 516 484 516 1483 517 482 518 481 519 1480 510 1488 512 487 513 487 513 1486 514 484 516 50972 1012 1488 512 1486 514 1484 516 483 517 483 517 1482 518 1480 510 489 511 1487 513 486 514 486 514 1485 515 1483 517 483 517 483 517 1481 509 490 510 50976 1008 1491 509 1489 511 1487 513 485 515 485 515 1484 516 1481 509 491 509 1489 511 488 512 488 512 1487 513 1485 515 484 516 484 516 1483 517 481 509 # -name: POWER +name: Power type: raw frequency: 38000 duty_cycle: 0.330000 data: 1011 1479 517 477 516 481 512 1480 516 1473 513 482 511 485 518 1473 513 482 511 1481 515 1474 512 482 511 485 518 1473 513 1477 509 486 517 1473 513 50728 1014 1475 511 484 509 487 516 1475 511 1479 517 477 516 480 513 1478 508 487 516 1475 511 1479 517 478 514 480 513 1479 517 1473 513 508 484 1479 517 50725 1016 1473 513 481 512 484 519 1473 513 1477 509 485 518 478 515 1476 510 485 518 1473 513 1477 509 486 517 478 515 1476 510 1480 516 479 514 1476 510 50735 1069 1421 513 481 512 484 509 1483 513 1477 509 486 517 479 514 1477 509 486 517 1474 512 1479 507 488 515 480 513 1479 507 1483 513 482 511 1479 517 50733 1011 1478 508 513 490 506 486 1478 508 1483 513 508 485 511 482 1482 514 508 485 1480 516 1473 513 508 485 511 482 1483 513 1477 509 512 491 1473 513 50735 1008 1480 516 479 514 508 485 1480 516 1474 512 509 484 486 517 1472 514 508 485 1480 516 1474 512 509 484 512 481 1482 514 1477 509 512 491 1472 514 50738 1006 1509 487 508 485 486 507 1509 487 1503 483 513 490 505 488 1502 484 512 491 1473 513 1503 483 512 491 505 488 1476 510 1507 489 506 487 1503 483 # -name: MUTE +name: Mute type: raw frequency: 38000 duty_cycle: 0.330000 data: 1010 1479 517 1474 512 509 484 512 491 505 488 507 486 510 483 512 491 505 488 508 485 1505 491 1474 512 1478 508 1483 513 1477 509 1482 514 1475 511 50713 1005 1483 513 1475 511 511 482 513 490 505 488 507 486 483 510 511 482 487 516 505 488 1501 485 1478 508 1483 513 1476 510 1479 507 1483 513 1474 512 50707 1012 1501 485 1479 506 513 490 505 488 507 486 509 484 511 482 487 516 505 488 508 485 1504 482 1482 514 1476 592 1396 590 1400 513 1476 510 1478 508 50715 1015 1473 513 1476 510 484 508 513 490 504 489 480 513 508 485 483 510 511 482 488 515 1473 513 1477 509 1480 516 1474 512 1477 591 1397 516 1472 514 # -name: VOL+ +name: Vol_up type: raw frequency: 38000 duty_cycle: 0.330000 data: 1041 1462 538 1462 538 485 515 481 519 478 512 484 516 1458 542 1458 542 1459 541 481 519 1481 519 1455 545 1482 518 1456 544 479 511 486 514 474 516 50532 1039 1464 536 1490 510 487 513 483 517 480 510 486 514 1460 540 1486 514 1460 540 483 517 1457 543 1484 516 1458 542 1458 542 481 519 477 513 476 513 50534 1036 1467 543 1457 543 480 509 460 540 483 517 479 511 1463 537 1463 537 1464 536 486 514 1487 513 1461 539 1461 539 1462 538 484 516 481 519 469 510 # -name: VOL- +name: Vol_dn type: raw frequency: 38000 duty_cycle: 0.330000 data: 1042 1461 539 457 543 1458 542 1458 542 1458 542 1458 542 454 536 461 539 457 543 1457 543 453 537 460 540 456 544 452 538 1463 537 1463 537 1456 544 50530 1065 1438 572 424 566 1434 566 1435 565 1435 565 1436 544 452 537 459 572 424 545 1456 544 451 539 458 542 454 536 460 540 1461 539 1461 539 1454 536 50538 1036 1467 543 452 537 1464 536 1464 536 1464 536 1465 545 450 540 456 544 452 537 1464 536 460 540 455 545 452 538 458 542 1459 541 1460 540 1452 538 # -name: VOL+ +name: Vol_up type: raw frequency: 38000 duty_cycle: 0.330000 data: 1044 1456 544 455 545 455 534 1464 536 1462 538 1460 540 1458 542 1456 544 1455 545 1453 537 1461 539 460 540 459 541 459 561 437 542 457 543 456 544 50915 1016 1483 517 482 518 482 518 1481 509 1489 511 1487 513 1486 514 1485 515 1483 517 1482 508 1490 510 489 511 488 512 487 513 487 513 486 514 485 515 50956 1047 1452 538 462 538 462 538 1461 539 1460 540 1458 542 1457 543 1456 544 1454 546 1453 547 1451 539 461 539 460 540 460 540 459 541 459 541 457 543 # -name: VOL- +name: Vol_dn type: raw frequency: 38000 duty_cycle: 0.330000 data: 1017 1484 516 1482 518 481 519 1480 510 1489 511 1487 513 1486 514 1485 515 1483 517 482 518 1480 510 490 510 489 511 489 511 488 512 488 512 486 514 50956 1015 1486 514 1484 516 484 516 1483 517 1482 518 1480 510 1489 511 1488 512 1486 514 486 514 1485 515 484 516 484 516 483 517 483 517 482 518 481 509 50960 1011 1488 512 1486 514 486 514 1485 515 1483 517 1482 518 1480 510 1488 512 1486 514 486 514 1484 516 483 517 483 517 482 518 481 519 481 508 489 511 50961 1040 1461 539 1459 541 459 541 1458 542 1456 544 1455 545 1454 546 1452 538 1460 540 460 540 1458 542 457 543 456 544 456 544 455 545 455 545 453 547 # -name: VOL+ +name: Vol_up type: raw frequency: 38000 duty_cycle: 0.330000 data: 1006 1485 511 1479 517 1473 513 509 484 511 482 514 489 506 487 508 485 511 482 513 490 505 488 1477 509 1481 515 1475 511 1480 516 1474 512 1477 509 50734 1007 1483 513 1477 509 1482 514 507 486 509 484 511 492 503 490 506 487 508 485 510 483 513 490 1474 512 1479 517 1473 513 1477 509 1481 515 1474 512 50729 1012 1477 509 1481 515 1474 512 509 484 512 491 504 489 506 487 508 485 511 482 513 490 506 487 1477 509 1481 515 1475 511 1479 517 1473 513 1476 510 # -name: VOL- +name: Vol_dn type: raw frequency: 38000 duty_cycle: 0.330000 data: 1012 1503 483 514 489 1475 511 483 510 486 517 478 515 481 512 483 510 486 517 1473 513 508 485 1480 516 1475 511 1479 507 1483 513 1477 509 1480 588 50646 1012 1476 510 512 491 1473 513 508 485 485 508 488 515 480 513 482 511 512 481 1482 514 482 511 1480 516 1473 513 1478 508 1482 514 1476 510 1479 590 50651 1007 1507 489 507 485 1478 508 514 489 506 487 509 484 485 508 488 515 506 487 1503 483 513 490 1474 512 1478 508 1483 513 1477 509 1481 515 1473 513 50721 1009 1505 491 478 515 1475 511 510 483 486 517 478 515 507 486 483 510 512 491 1472 514 508 485 1505 491 1473 513 1477 509 1481 587 1403 510 1478 508 50733 1008 1506 490 479 514 1477 509 512 481 514 489 506 487 508 485 484 509 513 490 1473 513 509 483 1481 515 1474 512 1479 507 1482 514 1476 510 1478 590 50642 1006 1508 488 508 485 1478 508 487 516 479 514 481 512 510 483 486 517 504 489 1474 512 510 483 1482 514 1475 511 1479 507 1483 513 1477 509 1480 516 # -name: POWER +name: Power type: parsed protocol: NEC address: 20 00 00 00 command: 09 00 00 00 # -name: MUTE +name: Mute type: parsed protocol: NEC address: 20 00 00 00 command: 1F 00 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NEC address: 20 00 00 00 command: 0E 00 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NEC address: 20 00 00 00 command: 1A 00 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NEC address: 20 00 00 00 command: 02 00 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NEC address: 20 00 00 00 command: 05 00 00 00 # -name: POWER +name: Power type: parsed protocol: NEC address: 20 00 00 00 command: 0C 00 00 00 # -name: MUTE +name: Mute type: parsed protocol: NEC address: 20 00 00 00 command: 08 00 00 00 # -name: POWER +name: Power type: parsed protocol: NEC address: 00 00 00 00 command: 12 00 00 00 # -name: MUTE +name: Mute type: parsed protocol: NEC address: 00 00 00 00 command: 1E 00 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NEC address: 00 00 00 00 command: 03 00 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NEC address: 00 00 00 00 command: 01 00 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NEC address: 00 00 00 00 command: 1F 00 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NEC address: 00 00 00 00 command: 09 00 00 00 # -name: POWER +name: Power type: parsed protocol: NECext address: 10 E7 00 00 command: 01 FE 00 00 # -name: MUTE +name: Mute type: parsed protocol: NECext address: 10 E7 00 00 command: 00 FF 00 00 # -name: MUTE +name: Mute type: parsed protocol: NECext address: 10 E7 00 00 command: 2B D4 00 00 # -name: MUTE +name: Mute type: parsed protocol: NECext address: 78 0E 00 00 command: 09 F6 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NECext address: 78 0E 00 00 command: 01 FE 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NECext address: 78 0E 00 00 command: 02 FD 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NEC address: 00 00 00 00 command: 06 00 00 00 # -name: POWER +name: Power type: parsed protocol: NEC address: 02 00 00 00 command: 0A 00 00 00 # -name: MUTE +name: Mute type: parsed protocol: NEC address: 02 00 00 00 command: 0D 00 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NEC address: 02 00 00 00 command: 1C 00 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NEC address: 02 00 00 00 command: 07 00 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NEC address: 00 00 00 00 command: 14 00 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NEC address: 00 00 00 00 command: 08 00 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NECext address: 86 FF 00 00 command: 14 EB 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NECext address: 86 FF 00 00 command: 13 EC 00 00 # -name: POWER +name: Power type: parsed protocol: NECext address: 86 FF 00 00 command: 1B E4 00 00 # -name: MUTE +name: Mute type: parsed protocol: NECext address: 86 FF 00 00 command: 2A D5 00 00 # -name: POWER +name: Power type: parsed protocol: NEC address: 00 00 00 00 command: 07 00 00 00 # -name: MUTE +name: Mute type: parsed protocol: NEC address: 00 00 00 00 command: 00 00 00 00 # -name: MUTE +name: Mute type: parsed protocol: NECext address: 40 AF 00 00 command: 19 E6 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NECext address: 02 BD 00 00 command: 26 D9 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NECext address: 02 BD 00 00 command: 28 D7 00 00 # -name: POWER +name: Power type: parsed protocol: NECext address: 02 BD 00 00 command: 53 AC 00 00 # -name: MUTE +name: Mute type: parsed protocol: NECext address: 02 BD 00 00 command: AD 52 00 00 # -name: POWER +name: Power type: parsed protocol: SIRC address: 10 00 00 00 command: 2F 00 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: SIRC address: 10 00 00 00 command: 12 00 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: SIRC address: 10 00 00 00 command: 13 00 00 00 # -name: POWER +name: Power type: parsed protocol: NECext address: 85 23 00 00 command: 99 66 00 00 # -name: MUTE +name: Mute type: parsed protocol: NECext address: 85 23 00 00 command: 97 68 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NECext address: 85 23 00 00 command: 57 A8 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NECext address: 85 23 00 00 command: 47 B8 00 00 # -name: POWER +name: Power type: parsed protocol: NEC address: 08 00 00 00 command: 10 00 00 00 # -name: MUTE +name: Mute type: parsed protocol: NEC address: 08 00 00 00 command: 16 00 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NECext address: 86 FF 00 00 command: 21 DE 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NECext address: 86 FF 00 00 command: 2B D4 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NECext address: BA 4B 00 00 command: 03 FC 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NECext address: BA 4B 00 00 command: 02 FD 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NECext address: BA A0 00 00 command: 03 FC 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NECext address: BA A0 00 00 command: 02 FD 00 00 # -name: VOL+ +name: Vol_up type: raw frequency: 38000 duty_cycle: 0.330000 data: 1014 1477 517 478 514 509 483 487 515 480 512 484 508 488 514 1479 515 1476 508 1483 511 1481 513 1478 516 1475 509 1482 512 1479 515 480 512 483 509 50775 1014 1477 517 504 488 508 484 513 489 506 486 510 482 514 488 1478 516 1475 509 1483 511 1480 514 1477 517 1474 510 1482 512 1478 516 505 487 509 483 50770 1009 1481 513 508 484 512 490 506 486 510 482 514 488 508 484 1481 513 1478 516 1475 509 1483 511 1480 514 1477 517 1475 509 1482 512 509 483 513 489 # -name: VOL- +name: Vol_dn type: raw frequency: 38000 duty_cycle: 0.330000 data: 1010 1508 486 509 483 513 489 507 485 512 490 505 487 510 482 1509 485 511 491 1501 483 1509 485 1507 487 1504 490 1502 482 1509 485 511 491 1500 484 50779 1010 1506 488 508 484 512 490 505 487 509 483 513 489 506 486 1506 488 507 485 1506 488 1503 481 1510 484 1508 486 1505 489 1503 481 514 488 1503 491 # -name: POWER +name: Power type: parsed protocol: NECext address: BA A0 00 00 command: 4C B3 00 00 # -name: MUTE +name: Mute type: parsed protocol: NECext address: BA A0 00 00 command: 01 FD 00 00 # -name: POWER +name: Power type: raw frequency: 38000 duty_cycle: 0.330000 data: 1004 1513 481 515 487 1478 516 505 487 510 482 1484 510 1481 513 508 484 512 490 1475 509 513 489 1477 507 1484 510 511 481 515 487 1479 515 1474 510 50774 1005 1484 510 513 489 1476 508 513 489 508 484 1482 512 1479 515 506 486 511 481 1483 511 512 490 1475 509 1483 511 510 482 515 487 1504 490 1475 509 50777 1013 1503 491 506 486 1505 489 507 485 512 490 1501 483 1508 486 510 482 514 488 1503 481 515 487 1504 490 1500 484 512 490 506 486 1506 488 1502 482 # -name: MUTE +name: Mute type: raw frequency: 38000 duty_cycle: 0.330000 data: 1014 1477 507 514 488 508 484 512 490 505 487 509 483 513 489 507 485 1480 514 1477 517 1475 509 1483 511 1480 514 1477 517 1475 509 1482 512 508 484 50774 1004 1486 508 513 489 507 485 511 491 504 488 508 484 513 489 505 487 1479 515 1476 508 1484 510 1481 513 1478 516 1475 509 1482 512 1480 514 507 485 50771 1007 1507 487 509 483 513 489 507 485 511 481 515 487 508 484 513 489 1502 482 1483 511 1481 513 1479 515 1476 508 1484 510 1481 513 1478 516 506 486 # -name: POWER +name: Power type: parsed protocol: NECext address: BA 4B 00 00 command: 4C B3 00 00 # -name: MUTE +name: Mute type: parsed protocol: NECext address: BA 4B 00 00 command: 01 FE 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NECext address: 83 22 00 00 command: 0A F5 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NECext address: 83 22 00 00 command: 01 FE 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NEC address: 35 00 00 00 command: 45 00 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NEC address: 35 00 00 00 command: 1B 00 00 00 # -name: POWER +name: Power type: parsed protocol: NEC address: 35 00 00 00 command: 09 00 00 00 # -name: MUTE +name: Mute type: parsed protocol: NEC address: 35 00 00 00 command: 51 00 00 00 # -name: POWER +name: Power type: parsed protocol: NECext address: 83 22 00 00 command: 08 F7 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NECext address: 0A 1D 00 00 command: 08 F7 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NECext address: 0A 1D 00 00 command: 0A F5 00 00 # -name: MUTE +name: Mute type: parsed protocol: NECext address: 0A 1D 00 00 command: 03 FC 00 00 # -name: POWER +name: Power type: parsed protocol: NECext address: 0A 1D 00 00 command: 01 FE 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NEC address: 20 00 00 00 command: 06 00 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NEC address: 20 00 00 00 command: 07 00 00 00 # -name: MUTE +name: Mute type: parsed protocol: NEC address: 20 00 00 00 command: 1E 00 00 00 # -name: MUTE +name: Mute type: parsed protocol: NEC address: 80 00 00 00 command: 01 00 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NEC address: 80 00 00 00 command: 03 00 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NEC address: 80 00 00 00 command: 06 00 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: Samsung32 address: 2C 00 00 00 command: 17 00 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: Samsung32 address: 2C 00 00 00 command: 16 00 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NECext address: 83 22 00 00 command: 16 E9 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NECext address: 83 22 00 00 command: 0F F0 00 00 # -name: POWER +name: Power type: parsed protocol: NECext address: 83 22 00 00 command: 0C F3 00 00 # -name: MUTE +name: Mute type: parsed protocol: NECext address: 83 22 00 00 command: 15 EA 00 00 # -name: POWER +name: Power type: parsed protocol: Kaseikyo address: A0 02 20 00 command: D0 03 00 00 # -name: POWER +name: Power type: parsed protocol: NECext address: C8 91 00 00 command: 00 FF 00 00 # -name: MUTE +name: Mute type: parsed protocol: NECext address: C8 91 00 00 command: 20 DF 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NECext address: C8 91 00 00 command: 1E E1 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NECext address: C8 91 00 00 command: 1F E0 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: RC6 address: 10 00 00 00 command: 10 00 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: RC6 address: 10 00 00 00 command: 11 00 00 00 # -name: POWER +name: Power type: parsed protocol: RC6 address: 10 00 00 00 command: 0C 00 00 00 # -name: VOL+ +name: Vol_up type: raw frequency: 38000 duty_cycle: 0.330000 data: 4559 4461 546 490 515 495 521 490 515 495 489 1484 516 1482 550 486 519 491 493 1480 520 1478 522 1477 523 1475 546 490 515 495 521 490 515 495 489 4493 545 491 525 486 519 491 514 496 488 1484 516 1483 517 1481 551 486 488 1485 515 1483 517 1482 550 486 519 491 525 486 519 491 493 1479 542 494 522 489 516 467 517 1482 550 # -name: VOL- +name: Vol_dn type: raw frequency: 38000 duty_cycle: 0.330000 data: 4550 4469 548 462 543 467 549 461 544 466 518 1481 520 1479 542 468 548 462 522 1477 523 1476 514 1485 515 1483 549 461 544 466 550 461 544 466 518 4491 547 463 542 468 548 462 543 467 549 462 543 467 549 461 523 1476 514 1485 515 1484 516 1482 550 461 513 1486 514 1485 515 1483 549 461 544 466 550 461 544 493 491 1481 540 # -name: VOL+ +name: Vol_up type: raw frequency: 38000 duty_cycle: 0.330000 data: 4496 4442 513 503 488 502 489 501 490 500 491 1505 487 1508 484 505 486 504 487 1508 484 1511 492 1503 489 1499 514 484 486 504 487 502 489 501 490 4449 517 499 492 499 492 497 483 507 484 1511 492 1504 488 1499 514 483 487 1509 483 1512 491 1504 488 503 488 501 490 500 491 499 492 1504 488 501 490 500 491 492 509 1494 488 55126 4496 4446 541 482 488 502 489 501 490 500 491 1505 487 1508 484 505 486 504 487 1508 484 1503 510 1493 489 1480 512 504 487 503 488 502 489 500 491 4449 517 498 493 497 483 507 484 505 486 1502 511 1492 490 1504 488 502 489 1507 485 1509 483 1512 491 473 518 498 493 496 484 505 486 1510 483 499 512 484 486 504 487 1508 484 # -name: VOL- +name: Vol_dn type: raw frequency: 38000 duty_cycle: 0.330000 data: 4492 4434 510 505 486 505 486 504 487 503 488 1481 511 1484 518 499 492 498 493 1476 516 1479 513 1483 519 1469 596 402 516 500 491 499 492 498 493 4447 518 498 493 497 483 507 484 506 485 504 487 503 488 494 517 1485 486 1483 519 1476 516 1480 512 504 486 1508 484 1486 517 1479 565 425 513 502 488 501 490 492 509 1467 515 # -name: VOL+ +name: Vol_up type: raw frequency: 38000 duty_cycle: 0.330000 data: 4500 4436 516 504 486 510 490 505 485 510 490 1500 491 1474 517 505 485 484 516 1501 490 1501 490 1501 490 1501 490 505 485 511 489 506 484 485 515 4449 513 482 508 513 487 508 482 514 486 1504 487 1504 487 1504 487 482 508 1509 482 1509 492 1499 492 504 486 509 491 504 486 509 491 1500 491 504 486 510 490 478 512 1505 486 55017 4492 4444 508 512 488 508 482 513 487 508 482 1508 483 1482 509 513 487 508 482 1509 482 1509 482 1483 508 1483 508 513 487 508 482 514 486 509 481 4457 515 506 484 511 489 506 484 511 489 1501 490 1475 516 1501 490 506 484 1480 511 1507 484 1480 511 511 489 506 484 512 488 507 483 1507 484 512 488 507 483 512 488 1503 488 # -name: VOL- +name: Vol_dn type: raw frequency: 38000 duty_cycle: 0.330000 data: 4493 4443 509 512 488 507 483 512 488 507 483 1482 509 1482 509 512 488 507 483 1482 509 1482 509 1482 509 1482 509 512 488 507 483 513 487 508 482 4457 516 505 485 510 490 505 485 510 490 505 485 511 489 505 485 1480 511 1480 511 1480 511 1481 510 484 516 1476 515 1476 515 1476 515 481 509 486 514 481 509 486 514 1476 515 55014 4498 4438 514 482 508 487 513 482 508 488 512 1477 514 1477 514 482 508 487 513 1477 514 1477 514 1477 514 1477 514 482 518 477 513 482 518 477 513 4451 511 485 515 479 511 485 515 480 510 485 515 480 510 485 515 1475 516 1475 516 1476 515 1476 515 480 510 1481 510 1481 510 1481 510 486 514 481 509 486 514 481 509 1482 509 # -name: VOL+ +name: Vol_up type: raw frequency: 38000 duty_cycle: 0.330000 data: 4524 4473 512 516 491 511 486 516 491 511 496 1482 522 1482 522 506 491 512 495 1483 521 1483 521 1483 521 1483 521 506 491 512 495 507 490 512 495 4475 521 507 490 513 494 508 489 513 494 1484 520 1484 520 1483 521 507 490 1488 516 1488 516 1488 516 511 496 506 491 511 496 506 491 1488 516 511 496 506 491 512 495 1483 521 55356 4533 4463 512 516 491 511 486 516 491 511 496 1507 487 1492 512 515 492 510 487 1492 512 1492 512 1491 513 1491 513 515 492 510 487 515 492 510 487 4484 512 516 491 511 496 506 491 512 495 1483 521 1482 522 1482 522 506 491 1488 516 1487 517 1487 517 511 496 506 491 512 495 506 491 1488 516 512 495 507 490 512 495 1483 521 # -name: VOL- +name: Vol_dn type: raw frequency: 38000 duty_cycle: 0.330000 data: 4533 4464 521 507 490 512 495 507 490 513 494 1484 520 1484 520 508 489 513 494 1484 520 1484 520 1483 521 1483 521 506 491 511 496 506 491 512 495 4475 521 507 490 512 495 507 490 513 494 508 489 513 494 508 489 1490 514 1490 514 1490 514 1490 514 514 493 1485 519 1485 519 1485 519 509 488 515 492 510 487 516 491 1487 517 55369 4531 4465 520 508 489 514 493 509 488 515 492 1486 518 1486 518 509 488 514 493 1486 518 1485 519 1485 519 1485 519 509 488 514 493 509 488 515 492 4478 518 511 486 516 491 511 496 506 491 512 495 507 490 512 495 1483 521 1483 521 1483 521 1483 521 507 490 1488 516 1488 516 1488 516 512 495 507 490 513 494 508 489 1490 514 # -name: POWER +name: Power type: raw frequency: 38000 duty_cycle: 0.330000 data: 4530 4465 521 507 490 513 494 507 490 513 494 1509 496 1483 521 506 491 512 495 1508 486 1492 512 1492 513 1491 513 514 493 509 488 514 493 509 488 4483 513 514 493 509 488 515 492 510 487 515 492 510 487 515 492 510 487 1517 488 1491 513 1490 515 513 494 1510 494 1484 520 1483 521 1483 521 506 491 512 495 506 491 1487 517 55357 4528 4468 518 510 487 515 492 510 487 515 492 1512 493 1485 519 509 488 514 493 1510 494 1483 522 1483 521 1482 512 516 491 511 486 516 491 511 486 4484 512 516 491 511 486 516 491 511 486 516 491 511 486 516 491 511 496 1507 487 1491 513 1491 514 514 493 1510 495 1484 521 1483 522 1483 522 506 491 511 486 516 491 1513 491 # -name: POWER +name: Power type: raw frequency: 38000 duty_cycle: 0.330000 data: 4495 4440 512 509 491 504 486 509 491 504 486 1478 513 1479 512 509 491 504 486 1478 513 1479 512 1479 512 1479 512 509 491 504 486 509 491 504 486 4452 511 511 489 506 484 511 489 506 484 511 489 506 484 511 489 506 484 1480 511 1480 511 1480 511 510 491 1500 491 1475 516 1475 516 1475 516 504 486 510 490 505 485 1479 512 55017 4497 4439 513 507 483 513 487 507 483 513 487 1476 515 1477 514 507 483 513 487 1476 515 1476 515 1477 514 1477 514 481 509 512 488 507 483 512 488 4451 512 509 491 504 486 509 491 504 486 483 517 504 486 509 492 504 486 1504 487 1504 487 1478 513 508 482 1509 482 1509 482 1509 482 1483 508 513 487 508 482 513 487 1504 487 # -name: MUTE +name: Mute type: raw frequency: 38000 duty_cycle: 0.330000 data: 4501 4435 517 504 486 510 490 505 485 510 490 1475 516 1475 516 506 484 511 489 1476 515 1476 515 1476 515 1477 514 507 483 512 488 507 483 513 487 4451 511 510 490 479 511 484 516 506 484 1481 510 511 489 506 484 511 489 1476 515 1476 515 1477 514 507 483 512 488 1477 514 1477 514 1478 513 508 482 513 487 508 482 1484 517 55011 4496 4440 512 509 491 478 512 483 517 504 486 1480 511 1480 511 484 516 505 485 1480 511 1480 511 1481 510 1481 510 484 516 506 484 511 489 506 484 4455 517 504 486 509 491 504 486 483 517 1474 517 505 485 510 490 505 485 1480 511 1480 511 1481 510 511 489 480 510 1481 510 1481 510 1482 509 485 515 507 483 512 488 1477 514 # -name: POWER +name: Power type: parsed protocol: Samsung32 address: 2C 00 00 00 command: 1E 00 00 00 # -name: MUTE +name: Mute type: parsed protocol: Samsung32 address: 2C 00 00 00 command: 1F 00 00 00 # -name: POWER +name: Power type: raw frequency: 38000 duty_cycle: 0.330000 data: 4504 4432 511 509 492 504 486 509 492 504 486 1478 514 1477 515 507 484 512 489 1476 516 1475 517 1475 517 1474 518 503 487 509 492 503 487 508 493 4446 508 513 488 507 483 512 489 507 483 512 489 506 484 511 490 506 484 1481 511 1480 512 1479 513 509 492 1473 519 1473 519 1472 509 1482 510 511 490 506 484 511 490 1475 517 54985 4498 4437 517 504 486 509 492 504 486 509 492 1473 519 1472 509 512 489 506 484 1481 511 1480 512 1480 512 1479 513 508 493 502 488 507 483 512 489 4449 516 506 485 511 490 505 485 510 491 505 485 510 491 504 486 509 492 1473 519 1473 508 1483 561 434 515 1476 516 1475 517 1474 518 1473 519 502 488 507 483 512 489 1476 516 # -name: MUTE +name: Mute type: raw frequency: 38000 duty_cycle: 0.330000 data: 4531 4406 516 478 512 484 538 457 544 452 538 1453 518 1473 519 476 546 450 540 1451 509 1482 510 1481 511 1480 512 483 539 457 544 452 538 457 544 4420 513 482 540 456 545 450 540 455 546 1445 547 449 541 454 536 458 543 1449 543 1449 543 1448 544 451 539 456 545 1445 547 1445 547 1444 537 458 543 453 537 457 544 1448 544 54957 4495 4440 514 481 520 477 513 482 519 476 514 1476 516 1475 517 478 512 484 517 1474 518 1473 519 1472 520 1471 521 474 516 479 511 484 517 479 511 4452 512 509 492 503 487 508 493 503 487 1477 515 507 483 512 489 506 484 1481 511 1481 511 1480 512 509 492 503 487 1478 514 1478 514 1477 515 506 484 511 490 505 485 1480 512 # -name: POWER +name: Power type: raw frequency: 38000 duty_cycle: 0.330000 data: 4551 4468 549 461 544 493 523 460 545 466 518 1480 520 1479 542 468 548 489 495 1477 523 1475 515 1484 516 1483 549 461 544 493 523 487 518 466 518 4490 548 462 543 493 523 488 517 466 550 461 544 466 550 460 545 465 519 1480 520 1478 522 1477 544 465 519 1480 520 1479 521 1477 523 1476 545 464 541 496 520 490 494 1479 542 55901 4554 4465 542 494 522 489 516 494 522 488 496 1477 523 1476 545 490 515 495 489 1484 516 1483 517 1481 519 1479 542 494 522 489 516 494 522 488 496 4487 541 495 521 490 515 495 521 489 516 494 522 488 517 493 523 488 496 1476 525 1475 515 1483 549 488 496 1476 524 1475 515 1484 516 1482 550 486 519 491 525 486 488 1485 547 55897 4548 4470 548 462 543 468 548 462 543 467 517 1482 518 1480 541 469 547 490 494 1478 575 1423 515 1485 515 1483 549 461 544 466 550 461 544 466 518 4491 547 462 543 467 549 462 543 467 549 461 544 466 539 497 519 492 492 1480 520 1478 522 1477 544 465 519 1480 520 1479 521 1477 513 1486 546 464 541 469 547 464 520 1478 543 # -name: MUTE +name: Mute type: raw frequency: 38000 duty_cycle: 0.330000 data: 4553 4467 550 459 546 464 541 469 547 464 520 1479 521 1477 544 492 524 486 498 1475 515 1484 516 1482 518 1481 540 496 520 490 515 495 521 490 494 4488 550 486 519 491 525 486 519 491 493 1479 542 494 522 489 516 494 490 1482 518 1481 519 1480 541 494 522 489 495 1478 522 1476 514 1485 547 489 516 494 522 489 495 1477 544 # -name: POWER +name: Power type: raw frequency: 38000 duty_cycle: 0.330000 data: 4555 4483 516 516 488 519 495 512 492 515 489 1525 493 1519 489 518 496 511 493 1521 487 1525 493 1520 488 1524 494 513 491 517 487 520 494 514 490 4501 519 513 491 516 488 520 494 513 491 517 487 521 493 514 490 518 486 1527 491 1522 496 1517 491 516 488 1525 493 1520 488 1525 493 1520 488 519 495 512 492 516 488 1525 493 # -name: VOL+ +name: Vol_up type: parsed protocol: RC5 address: 13 00 00 00 command: 0D 00 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: RC5 address: 13 00 00 00 command: 0E 00 00 00 # -name: POWER +name: Power type: parsed protocol: RC5 address: 13 00 00 00 command: 0B 00 00 00 # -name: MUTE +name: Mute type: parsed protocol: RC5 address: 13 00 00 00 command: 0C 00 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: SIRC address: 01 00 00 00 command: 12 00 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: SIRC address: 01 00 00 00 command: 13 00 00 00 # -name: VOL+ +name: Vol_up type: raw frequency: 38000 duty_cycle: 0.330000 data: 4552 4468 574 436 566 444 568 442 570 441 540 1458 546 1453 572 439 573 437 544 1455 539 1460 544 1456 548 1450 575 436 566 444 568 442 570 440 541 4468 594 416 565 445 567 443 569 441 540 1459 545 1453 541 1459 566 444 547 1452 542 1457 547 1452 593 417 564 446 566 444 568 442 539 1460 565 446 566 444 568 442 539 1460 565 55957 4581 4437 543 467 545 466 546 464 538 472 519 1480 514 1485 540 471 541 469 512 1486 518 1481 513 1486 518 1481 575 436 566 444 568 442 570 440 541 4468 543 468 544 465 547 464 538 472 519 1480 514 1485 519 1479 546 465 516 1483 511 1488 516 1483 542 468 544 466 546 464 538 473 519 1480 545 466 546 464 538 472 519 1480 545 # -name: VOL- +name: Vol_dn type: raw frequency: 38000 duty_cycle: 0.330000 data: 4546 4473 538 473 539 470 542 469 543 467 514 1484 520 1479 545 465 547 463 518 1481 513 1486 518 1481 513 1487 538 472 540 470 542 469 543 466 515 4495 546 463 539 472 540 470 542 468 544 466 546 491 521 462 519 1480 513 1485 519 1480 514 1486 539 472 519 1479 515 1484 520 1479 546 464 548 463 539 471 541 469 512 1487 548 # -name: POWER +name: Power type: raw frequency: 38000 duty_cycle: 0.330000 data: 4549 4469 542 468 544 467 545 465 537 473 519 1481 513 1485 540 471 541 469 512 1487 517 1482 512 1487 517 1482 543 467 545 465 547 463 539 472 519 4489 543 468 544 466 546 464 538 473 539 470 542 468 544 466 546 465 516 1482 512 1487 517 1482 543 468 513 1485 519 1480 514 1485 519 1480 545 465 547 463 539 472 520 1479 546 55899 4549 4470 541 469 574 436 566 445 546 463 549 1450 513 1486 539 471 572 438 543 1456 548 1451 543 1456 548 1451 574 436 566 445 567 443 569 441 540 4469 573 437 575 435 567 443 569 441 571 439 573 437 565 445 567 443 549 1451 543 1456 548 1451 574 436 545 1454 540 1459 545 1454 540 1459 566 444 568 442 570 440 541 1458 567 55878 4580 4439 572 439 573 437 565 445 567 443 548 1451 543 1456 569 441 571 439 542 1457 547 1452 542 1457 547 1452 573 437 575 435 567 443 569 442 539 4469 573 438 574 436 566 444 568 442 570 440 572 438 574 436 566 444 547 1452 542 1457 547 1452 573 437 544 1455 539 1460 544 1455 539 1460 575 435 567 444 568 442 539 1459 566 55879 4578 4442 569 441 571 439 573 437 575 435 546 1453 541 1458 567 444 568 441 540 1459 545 1454 540 1459 545 1454 571 439 573 437 575 435 567 444 548 4461 571 440 572 438 574 436 566 444 568 442 570 440 572 438 574 436 545 1454 540 1459 545 1454 571 439 542 1457 547 1452 542 1457 547 1452 573 437 575 435 567 444 547 1451 574 55871 4554 4465 546 464 538 473 539 471 541 469 512 1487 517 1481 544 467 545 465 516 1483 511 1488 516 1483 511 1488 547 463 539 472 540 470 542 468 513 4496 546 464 538 472 540 470 542 468 544 466 546 464 538 473 539 471 510 1488 516 1483 511 1488 547 463 518 1481 513 1486 518 1481 513 1486 539 472 540 470 542 467 514 1485 540 # -name: MUTE +name: Mute type: raw frequency: 38000 duty_cycle: 0.330000 data: 4555 4465 546 464 538 472 540 470 542 468 513 1486 518 1481 544 467 545 465 516 1483 511 1488 516 1483 511 1488 537 473 539 472 540 470 542 468 513 4496 546 464 538 473 539 471 541 469 512 1487 538 472 540 470 542 469 512 1486 518 1481 544 1455 570 441 571 439 542 1457 547 1452 542 1457 568 442 570 440 572 438 543 1456 569 55920 4555 4464 547 464 538 472 540 470 542 468 513 1486 518 1481 544 466 546 464 517 1482 512 1487 517 1482 512 1487 538 473 539 471 541 469 543 467 514 4495 547 463 539 472 540 470 542 468 513 1486 539 471 541 469 543 467 514 1485 519 1479 515 1485 540 470 542 468 513 1486 518 1481 513 1486 539 471 541 469 543 467 514 1485 540 # -name: POWER +name: Power type: parsed protocol: SIRC15 address: 10 00 00 00 command: 15 00 00 00 # -name: POWER +name: Power type: parsed protocol: SIRC address: 01 00 00 00 command: 15 00 00 00 # -name: MUTE +name: Mute type: parsed protocol: SIRC address: 01 00 00 00 command: 14 00 00 00 # -name: POWER +name: Power type: parsed protocol: SIRC address: 10 00 00 00 command: 15 00 00 00 # -name: POWER +name: Power type: parsed protocol: SIRC15 address: 30 00 00 00 command: 15 00 00 00 # -name: MUTE +name: Mute type: parsed protocol: SIRC15 address: 30 00 00 00 command: 14 00 00 00 # -name: POWER +name: Power type: parsed protocol: NECext address: 86 FF 00 00 command: 1C E3 00 00 # -name: MUTE +name: Mute type: parsed protocol: NECext address: 86 FF 00 00 command: 1D E2 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NEC address: 80 00 00 00 command: 0D 00 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NEC address: 80 00 00 00 command: 08 00 00 00 # -name: POWER +name: Power type: parsed protocol: NEC address: 80 00 00 00 command: 12 00 00 00 # -name: MUTE +name: Mute type: parsed protocol: NEC address: 80 00 00 00 command: 1E 00 00 00 # -name: POWER +name: Power type: parsed protocol: NECext address: EF 01 00 00 command: 25 DA 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NECext address: EF 01 00 00 command: 14 EB 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NECext address: EF 01 00 00 command: 13 EC 00 00 # -name: MUTE +name: Mute type: parsed protocol: NECext address: EF 01 00 00 command: 28 D7 00 00 # -name: VOL+ +name: Vol_up type: raw frequency: 38000 duty_cycle: 0.330000 data: 1048 580 597 1165 596 582 595 1167 594 875 599 578 599 1455 593 585 592 1171 600 577 600 576 601 13191 1042 586 591 1170 601 576 601 1161 600 869 595 582 595 1459 599 578 599 1163 598 580 597 579 598 13195 1048 580 597 1165 596 581 596 1167 594 875 599 578 599 1456 592 585 592 1171 600 577 600 577 600 13192 1052 576 601 1162 599 578 599 1163 598 871 593 584 593 1462 596 581 596 1166 595 582 595 582 595 # -name: VOL- +name: Vol_dn type: raw frequency: 38000 duty_cycle: 0.330000 data: 1048 553 624 1138 623 554 623 1139 622 848 626 551 626 1427 621 556 652 1403 655 522 655 814 650 12579 1050 552 656 1106 624 553 624 1138 623 847 627 550 627 1427 621 556 621 1434 624 553 624 845 619 12612 1079 523 623 1139 622 555 622 1139 622 848 626 550 627 1427 621 556 621 1434 624 553 624 845 619 12613 1047 556 621 1141 620 556 621 1141 620 850 624 552 625 1429 619 558 619 1435 623 554 623 846 628 12600 1050 552 625 1137 624 553 624 1137 624 846 618 558 619 1435 623 554 623 1431 627 550 627 842 622 12609 1051 551 626 1136 625 551 626 1136 625 844 620 557 620 1434 624 554 623 1431 627 550 627 843 621 # -name: POWER +name: Power type: raw frequency: 38000 duty_cycle: 0.330000 data: 1073 528 649 1114 647 530 647 1116 645 825 649 527 650 1405 653 1402 625 552 646 1409 649 1113 648 11417 1077 524 653 1110 651 526 651 1112 649 820 654 523 654 1400 648 1407 651 526 651 1404 654 1109 652 11414 1079 523 654 1109 652 524 653 1111 650 819 624 554 654 1401 647 1408 650 529 648 1406 652 1111 650 11416 1077 525 652 1110 651 526 651 1112 649 820 654 523 654 1401 647 1408 650 528 649 1405 622 1141 651 11414 1080 521 646 1116 624 553 645 1117 654 816 648 529 648 1406 652 1403 655 523 644 1410 648 1114 647 11418 1075 526 651 1111 650 527 650 1112 649 820 623 554 654 1400 648 1407 651 526 651 1403 655 1107 654 # -name: MUTE +name: Mute type: raw frequency: 38000 duty_cycle: 0.330000 data: 1051 550 627 1135 626 551 626 1136 625 845 619 850 624 553 675 794 629 842 622 555 622 555 622 13780 1047 555 622 1140 621 557 620 1141 620 850 624 845 619 558 619 850 624 846 618 559 618 559 618 13782 1045 558 619 1143 618 559 618 1144 627 842 622 847 627 550 627 842 622 848 626 551 626 551 626 13774 1053 549 618 1144 627 550 627 1135 626 843 621 849 625 551 626 844 620 850 624 553 624 552 625 13776 1051 551 626 1137 624 553 624 1138 623 846 618 851 623 554 623 846 628 841 623 554 623 554 623 13776 1051 551 626 1136 625 552 625 1137 624 845 619 850 624 553 624 846 618 852 622 555 622 554 623 13778 1049 554 623 1139 622 555 622 1140 621 849 625 844 620 557 620 850 624 846 618 559 618 558 619 # -name: POWER +name: Power type: parsed protocol: NEC address: 78 00 00 00 command: CC 00 00 00 # -name: MUTE +name: Mute type: parsed protocol: NEC address: 78 00 00 00 command: 9C 00 00 00 # -name: POWER +name: Power type: parsed protocol: NEC address: 7E 00 00 00 command: 2A 00 00 00 # -name: MUTE +name: Mute type: parsed protocol: NEC address: 7A 00 00 00 command: 1C 00 00 00 # -name: POWER +name: Power type: raw frequency: 38000 duty_cycle: 0.330000 data: 274 789 254 1792 275 814 250 787 246 816 248 1798 279 784 249 813 251 785 248 788 245 1827 281 1791 275 1825 272 790 253 783 250 43886 277 786 278 1795 272 791 252 783 281 782 251 785 269 1804 273 1800 277 1822 275 1798 279 783 270 766 277 759 274 1825 272 1800 277 43886 277 759 274 1825 272 764 279 756 277 786 278 1795 282 781 272 763 280 755 278 785 279 1794 273 1827 270 1802 275 761 272 791 273 43888 276 761 272 1800 277 786 278 758 275 760 273 790 274 1799 278 1821 276 1796 281 1792 275 788 276 760 273 789 275 1798 279 1794 273 43889 278 785 248 1825 272 790 253 782 272 764 279 1793 274 790 274 761 282 781 273 763 280 1793 273 1825 272 1800 277 813 220 789 275 # -name: POWER +name: Power type: raw frequency: 38000 duty_cycle: 0.330000 data: 270 793 250 1795 272 818 246 791 252 809 244 766 277 1795 282 781 272 790 253 809 224 1822 275 1797 280 1820 277 785 248 788 245 43889 273 790 274 1799 278 785 248 788 276 787 246 1826 271 792 251 1794 273 1827 270 1802 275 788 245 791 273 790 253 1819 278 1794 273 43889 274 789 254 1818 269 767 276 786 247 789 275 788 245 1827 270 792 251 785 248 814 250 1796 281 1819 248 1825 272 790 253 783 271 43889 245 791 273 1799 278 786 278 784 249 787 246 1827 281 781 252 1821 276 1796 281 1792 274 814 250 786 247 789 244 1829 279 1793 274 43888 275 815 218 1828 280 783 250 786 278 785 248 788 245 1827 280 782 251 785 268 794 249 1797 280 1819 278 1794 272 791 252 810 254 # -name: VOL+ +name: Vol_up type: raw frequency: 38000 duty_cycle: 0.330000 data: 277 759 274 1799 278 784 280 783 250 812 242 1804 273 816 227 808 246 791 252 1819 248 1825 273 1826 251 1822 276 786 247 789 244 43888 274 815 249 1797 280 783 250 812 252 784 249 813 241 1805 272 1827 250 1822 275 787 246 816 217 819 255 807 226 1820 278 1795 272 43888 273 789 254 1817 270 793 251 785 248 814 250 1795 282 807 247 790 253 783 250 1822 276 1796 281 1818 249 1824 274 814 229 807 247 # -name: VOL- +name: Vol_dn type: raw frequency: 38000 duty_cycle: 0.330000 data: 275 762 271 1800 277 786 278 784 249 813 241 795 248 1824 253 784 270 792 251 1821 246 1826 272 1801 276 1823 275 762 271 790 243 43889 274 789 275 1797 280 783 250 812 252 784 249 1823 275 762 271 1827 250 1822 276 787 246 816 217 818 246 790 253 1819 268 1804 273 43886 277 786 247 1825 273 764 280 783 250 811 253 784 249 1822 276 761 272 816 228 1819 279 1794 273 1826 251 1821 277 786 247 815 249 # -name: MUTE +name: Mute type: raw frequency: 38000 duty_cycle: 0.330000 data: 275 762 271 1800 277 786 278 784 249 813 241 795 248 814 219 817 247 789 254 1818 249 1824 274 1798 279 1820 278 759 274 788 245 43887 274 789 275 1798 279 783 250 812 252 784 249 1823 274 1798 279 1820 247 1826 271 765 278 809 224 812 252 784 249 1823 275 1798 279 43880 281 782 251 1821 277 760 273 789 244 818 246 790 253 808 246 791 252 809 224 1822 275 1797 280 1819 248 1825 273 790 253 808 246 # -name: POWER +name: Power type: parsed protocol: NECext address: 87 7C 00 00 command: 80 7F 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NECext address: 87 7C 00 00 command: 88 77 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NECext address: 87 7C 00 00 command: 8C 73 00 00 # -name: MUTE +name: Mute type: parsed protocol: NECext address: 87 7C 00 00 command: 94 6B 00 00 # -name: POWER +name: Power type: parsed protocol: NECext address: D2 6C 00 00 command: CB 34 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NECext address: D2 6D 00 00 command: 02 FD 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NECext address: D2 6D 00 00 command: 03 FC 00 00 # -name: MUTE +name: Mute type: parsed protocol: NECext address: D2 6D 00 00 command: 05 FA 00 00 # -name: POWER +name: Power type: parsed protocol: NECext address: D2 03 00 00 command: 04 FB 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NECext address: D2 03 00 00 command: 02 FD 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NECext address: D2 03 00 00 command: 03 FC 00 00 # -name: MUTE +name: Mute type: parsed protocol: NECext address: D2 03 00 00 command: 05 FA 00 00 # -name: POWER +name: Power type: parsed protocol: RC5 address: 14 00 00 00 command: 0C 00 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: RC5 address: 14 00 00 00 command: 11 00 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: RC5 address: 14 00 00 00 command: 10 00 00 00 # -name: POWER +name: Power type: parsed protocol: SIRC15 address: 10 00 00 00 command: 60 00 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: SIRC15 address: 30 00 00 00 command: 12 00 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: SIRC15 address: 30 00 00 00 command: 13 00 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: SIRC15 address: 10 00 00 00 command: 12 00 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: SIRC15 address: 10 00 00 00 command: 13 00 00 00 # -name: POWER +name: Power type: parsed protocol: NECext address: 7E 81 00 00 command: 2A D4 00 00 # -name: MUTE +name: Mute type: parsed protocol: NECext address: 7A 85 00 00 command: 1C E2 00 00 # -name: POWER +name: Power type: parsed protocol: NEC address: 78 00 00 00 command: 0F 00 00 00 # -name: POWER +name: Power type: parsed protocol: NEC address: 78 00 00 00 command: 4F 00 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NEC address: 7A 00 00 00 command: 1A 00 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NEC address: 7A 00 00 00 command: 1B 00 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NECext address: 7A 85 00 00 command: 1A E4 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NECext address: 7A 85 00 00 command: 1B E5 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NEC address: 78 00 00 00 command: 1E 00 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NEC address: 78 00 00 00 command: 1F 00 00 00 # -name: MUTE +name: Mute type: parsed protocol: RC5X address: 0A 00 00 00 command: 2F 00 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NEC address: 00 00 00 00 command: 15 00 00 00 # -name: POWER +name: Power type: raw frequency: 38000 duty_cycle: 0.330000 data: 8437 4188 538 1565 539 1565 539 513 544 508 538 513 544 1559 545 507 539 1564 540 1564 540 1563 541 1563 541 511 546 1557 547 505 542 511 546 505 542 20497 597 1507 545 1559 545 507 539 512 545 507 539 1564 540 512 545 1558 546 1558 546 1558 546 1557 547 505 542 1562 542 510 547 505 542 510 547 20492 540 1564 540 1564 540 512 545 506 540 511 546 1558 546 505 542 1562 542 1562 542 1562 542 1561 543 509 548 1555 538 514 543 509 537 514 543 20495 547 1558 546 1557 547 505 541 511 546 505 542 1562 542 510 547 1556 548 1556 548 1556 548 1556 537 514 543 1560 544 508 538 514 543 508 538 20501 541 1562 542 1562 542 510 547 505 541 510 547 1556 548 504 543 1561 543 1561 543 1560 544 1560 544 508 538 1565 539 513 544 507 539 513 544 20494 548 1556 548 1556 548 504 543 509 548 504 543 1560 544 508 539 1565 539 1565 539 1564 540 1564 540 512 545 1559 545 506 540 512 545 506 540 20499 543 1560 544 1560 544 508 539 513 544 508 538 1564 540 512 545 1559 545 1558 546 1558 546 1558 546 506 541 1563 541 510 547 505 542 510 547 # -name: VOL+ +name: Vol_up type: raw frequency: 38000 duty_cycle: 0.330000 data: 8430 4194 542 1562 542 1562 542 510 547 505 541 510 547 1556 548 504 542 1561 543 509 548 1556 548 1556 548 1556 548 1556 548 504 542 509 537 514 543 20496 545 1559 545 1559 545 507 539 512 545 507 539 1564 540 512 545 1559 545 507 539 1564 540 1564 540 1563 541 1563 541 511 546 506 540 511 546 20494 546 1557 547 1557 547 505 541 510 547 505 541 1562 542 510 547 1556 548 505 541 1562 542 1562 542 1561 543 1561 543 509 548 504 542 509 537 20501 540 1565 539 1565 539 512 545 507 539 512 545 1559 545 507 539 1564 540 512 545 1559 545 1558 546 1558 546 1558 546 506 540 511 546 506 540 20498 543 1562 542 1562 542 510 547 505 541 510 547 1557 547 505 541 1562 542 509 548 1556 548 1556 548 1556 548 1556 548 504 542 509 548 504 542 20497 543 1560 544 1560 544 508 538 513 544 508 538 1565 539 513 544 1560 544 508 538 1565 539 1565 539 1565 539 1564 540 513 544 507 539 512 545 20495 545 1558 546 1558 546 506 540 511 546 506 540 1563 541 511 546 1558 546 506 540 1563 541 1563 541 1563 541 1562 542 510 547 505 541 510 547 20493 548 1556 548 1556 548 504 542 509 548 504 542 1561 543 509 537 1566 538 514 543 1560 544 1560 544 1560 544 1560 544 508 538 513 544 508 538 20501 539 1564 540 1564 540 512 545 507 539 512 545 1559 545 507 539 1564 540 512 545 1559 545 1558 546 1558 546 1558 546 506 540 511 546 506 540 # -name: VOL- +name: Vol_dn type: raw frequency: 38000 duty_cycle: 0.330000 data: 8434 4191 545 1559 545 1559 545 534 512 513 544 507 539 1564 540 538 519 1559 545 1558 546 1558 546 1558 546 1558 546 1558 546 533 513 511 546 506 540 19446 547 1557 547 1557 547 532 514 511 546 532 514 1562 593 459 546 1557 547 1557 547 1557 547 1557 547 1557 547 1557 547 531 515 510 547 505 541 19446 548 1556 548 1556 548 530 516 509 548 504 543 1561 543 535 512 1566 538 1565 539 1565 539 1565 539 1565 539 1565 539 540 517 509 537 514 543 19444 539 1565 539 1565 539 513 544 508 538 513 544 1559 545 534 512 1564 540 1564 540 1564 540 1564 540 1564 540 1564 540 539 518 507 539 513 544 19442 541 1563 541 1563 541 538 519 507 539 512 545 1558 546 506 540 1563 541 1563 541 1563 541 1563 541 1563 541 1562 542 537 520 505 541 511 546 19440 595 1509 543 1561 543 536 521 504 542 509 548 1555 538 540 517 1560 544 1560 544 1560 544 1560 544 1560 544 1560 544 534 512 513 544 508 538 19448 546 1559 545 1559 545 533 513 512 545 507 539 1563 541 538 519 1558 546 1558 546 1558 546 1557 547 1558 546 1558 546 533 513 512 545 506 540 19447 546 1557 547 1557 547 532 514 511 546 506 540 1562 542 537 520 1557 547 1557 547 1557 547 1557 547 1557 547 1557 547 505 542 510 547 505 541 19445 548 1556 548 1556 548 531 515 510 547 504 542 1561 543 536 521 1555 538 1566 538 1566 538 1566 538 1566 538 1565 539 514 543 509 537 514 543 # -name: MUTE +name: Mute type: raw frequency: 38000 duty_cycle: 0.330000 data: 8435 4189 547 1557 547 1557 547 505 541 510 547 505 541 1562 542 510 547 1557 547 505 541 510 547 1557 546 1557 547 1557 547 505 541 510 547 505 541 21550 547 1558 545 1558 546 506 540 511 546 506 540 1563 541 511 546 1558 545 506 540 511 546 1558 546 1558 546 1558 546 506 540 511 546 506 540 21551 546 1558 546 1558 546 506 540 512 545 506 540 1563 540 512 545 1558 546 506 540 512 545 1558 546 1558 546 1558 546 506 540 512 545 506 540 21551 546 1559 545 1559 545 507 539 512 545 507 539 1564 539 512 545 1559 545 507 539 512 545 1559 545 1559 545 1559 545 507 539 512 545 507 539 21552 545 1559 545 1559 545 507 539 513 544 507 539 1564 540 512 545 1559 545 507 539 512 545 1559 545 1559 545 1559 545 507 539 512 545 507 539 21552 545 1559 545 1559 545 507 539 513 544 507 539 1565 538 513 544 1559 545 507 539 513 544 1559 545 1559 544 1559 545 534 512 513 544 507 539 21553 544 1560 544 1560 544 534 512 513 544 508 538 1565 539 539 518 1560 544 534 512 513 544 1560 544 1560 544 1560 544 534 512 513 544 508 538 # -name: POWER +name: Power type: parsed protocol: NEC address: 20 00 00 00 command: 41 00 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NEC address: 20 00 00 00 command: 42 00 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NEC address: 20 00 00 00 command: 43 00 00 00 # -name: MUTE +name: Mute type: parsed protocol: NEC address: 20 00 00 00 command: 1B 00 00 00 # -name: VOL+ +name: Vol_up type: raw frequency: 38000 duty_cycle: 0.330000 data: 8498 4205 651 1471 576 530 550 1572 547 535 545 536 544 1578 541 540 550 1572 547 535 545 1576 543 539 541 1580 549 1572 547 534 546 1576 543 539 541 540 550 1571 548 533 547 1574 545 537 543 539 541 541 549 532 548 1574 545 536 544 1578 541 540 550 1571 548 1572 547 1574 545 1576 543 26533 8497 4203 653 1468 569 538 542 1579 550 531 549 533 547 1573 546 535 545 1576 543 538 542 1579 550 531 549 1571 548 1573 546 536 544 1576 543 539 541 540 550 1571 548 533 547 1574 545 536 544 538 542 540 550 530 550 1572 547 534 546 1575 544 537 543 1578 541 1579 550 1570 549 1572 547 26524 8496 4207 576 1570 549 533 547 1574 545 537 543 539 541 1580 549 532 548 1573 546 536 544 1577 542 539 551 1570 549 1572 547 534 546 1575 544 538 542 540 550 1571 548 534 546 1575 544 538 542 540 550 531 549 533 547 1575 544 537 543 1579 550 531 549 1571 548 1572 547 1574 545 1576 543 26529 8491 4211 573 1573 546 535 545 1576 543 539 551 530 550 1571 548 533 547 1574 545 536 544 1578 541 540 550 1570 549 1572 547 534 546 1575 544 538 542 539 541 1580 549 532 548 1572 547 535 545 537 543 539 541 540 550 1571 548 533 547 1574 545 537 543 1578 541 1579 550 1571 548 1574 545 26522 8498 4202 571 1574 545 537 543 1578 541 541 549 532 548 1573 546 534 546 1575 544 537 543 1577 542 540 550 1570 549 1571 548 533 547 1574 545 537 543 538 542 1579 550 531 549 1572 547 534 546 536 544 537 543 538 542 1579 550 531 549 1572 547 535 545 1575 544 1577 542 1579 550 1571 548 26522 8498 4203 570 1575 544 537 543 1578 541 541 549 532 548 1573 546 535 545 1575 544 538 542 1579 550 531 549 1571 548 1572 547 535 545 1575 544 538 542 539 541 1580 549 532 548 1572 547 534 546 536 544 537 543 539 541 1579 550 531 549 1571 548 533 547 1573 546 1574 545 1575 544 1577 542 # -name: VOL- +name: Vol_dn type: raw frequency: 38000 duty_cycle: 0.330000 data: 8490 4211 573 1573 546 535 545 1576 543 539 541 540 550 1571 548 532 548 1573 546 535 545 1576 543 539 541 1579 550 1571 548 533 547 1574 545 536 544 1576 543 1578 541 540 550 1570 549 533 547 534 546 536 544 537 543 539 541 540 550 1570 549 532 548 1572 547 1573 546 1574 545 1576 543 26528 8492 4208 648 1475 572 534 546 1575 544 537 543 539 541 1580 549 532 548 1573 546 535 545 1576 543 538 542 1579 550 1571 548 533 547 1575 544 537 543 1577 542 1579 550 532 548 1573 546 535 545 537 543 539 541 541 549 532 548 533 547 1575 544 537 543 1578 541 1579 550 1571 548 1573 546 26523 8496 4203 622 1499 569 537 543 1578 541 541 549 532 548 1572 547 534 546 1574 545 537 543 1578 541 540 550 1570 549 1571 548 534 546 1575 544 538 542 1578 541 1580 549 532 548 1573 546 536 544 538 542 540 550 532 548 533 547 535 545 1576 543 539 541 1579 550 1571 548 1573 546 1574 545 26521 8498 4201 572 1573 546 536 544 1577 542 540 550 531 549 1571 548 533 547 1573 546 536 544 1576 543 539 541 1579 550 1570 549 532 548 1573 546 535 545 1576 543 1578 541 540 550 1571 548 533 547 535 545 537 543 538 542 540 550 531 549 1572 547 534 546 1575 544 1576 543 1577 542 1579 550 26522 8498 4203 570 1575 544 538 542 1579 550 532 548 533 547 1575 544 537 543 1578 541 540 550 1570 549 533 547 1573 546 1575 544 537 543 1578 541 540 550 1571 548 1573 546 536 544 1578 551 531 549 533 547 535 545 537 543 539 541 540 550 1571 548 533 547 1575 544 1576 543 1578 541 1580 549 26521 8498 4203 570 1576 543 538 542 1580 549 532 548 533 547 1574 545 536 544 1577 542 540 550 1570 549 533 547 1573 546 1575 544 538 542 1579 550 531 549 1571 548 1573 546 536 544 1576 543 539 551 531 549 532 548 534 546 536 544 538 542 1579 550 531 549 1572 547 1573 546 1574 545 1576 543 # -name: POWER +name: Power type: raw frequency: 38000 duty_cycle: 0.330000 data: 8500 4203 653 1468 569 538 542 1579 550 532 548 534 546 1575 544 536 544 1578 541 540 550 1572 547 534 546 1575 544 1577 542 539 541 1580 550 532 548 534 546 535 545 1576 543 1577 542 1579 551 532 548 534 546 536 544 1577 542 1578 552 531 549 533 547 534 546 1574 545 1575 544 1577 542 26533 8492 4211 573 1573 546 535 545 1576 543 539 551 530 550 1571 548 533 547 1574 545 536 544 1577 542 540 550 1570 549 1572 547 534 546 1576 543 539 541 541 549 532 548 1573 546 1574 545 1576 543 539 551 531 549 533 547 1573 546 1576 543 539 541 541 549 532 548 1573 546 1574 545 1576 543 26532 8493 4209 575 1571 548 533 547 1575 544 537 543 539 541 1580 550 531 549 1572 547 534 546 1576 543 538 542 1579 551 1570 549 532 548 1574 545 537 543 538 542 540 550 1570 549 1572 547 1575 544 537 543 539 541 540 550 1571 548 1573 546 536 544 538 542 539 551 1570 549 1572 547 1574 545 26530 8496 4207 567 1579 551 531 549 1572 547 535 545 536 544 1576 543 538 542 1579 551 530 550 1571 548 534 546 1574 545 1576 543 538 542 1579 551 532 548 533 547 534 546 1576 543 1577 542 1579 551 532 548 534 546 535 545 1576 543 1578 541 540 550 532 548 533 547 1574 545 1575 544 1577 542 26531 8495 4210 574 1571 548 534 546 1575 544 538 542 539 551 1569 550 531 549 1572 547 535 545 1576 543 539 541 1579 550 1571 548 534 546 1575 544 538 542 540 550 531 549 1572 547 1549 570 1551 568 539 551 531 549 532 548 1573 546 1550 569 538 542 540 550 531 549 1571 548 1548 571 1550 569 # -name: POWER +name: Power type: parsed protocol: NECext address: 00 EF 00 00 command: 1C E3 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NECext address: 00 EF 00 00 command: 00 FF 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NECext address: 00 EF 00 00 command: 04 FB 00 00 # -name: POWER +name: Power type: parsed protocol: NEC42 address: 6E 00 00 00 command: 00 00 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NEC42 address: 6E 00 00 00 command: 4D 00 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NEC42 address: 6E 00 00 00 command: 4E 00 00 00 # -name: POWER +name: Power type: parsed protocol: NEC42 address: 6E 00 00 00 command: 0E 00 00 00 # -name: POWER +name: Power type: raw frequency: 38000 duty_cycle: 0.330000 data: 8441 4184 542 1562 541 1562 542 511 546 506 540 511 546 1557 546 506 540 1563 541 1563 540 1563 541 512 545 507 539 512 545 507 539 512 545 507 539 22605 538 1565 539 1565 538 514 543 509 537 514 543 1560 543 509 548 1555 548 1556 548 1556 547 504 542 510 547 505 541 510 547 505 541 510 547 22597 546 1559 544 1559 545 507 539 513 544 507 539 1564 539 513 544 1559 544 1559 545 545 508 549 513 508 538 513 544 508 538 513 544 22601 542 1562 542 1561 543 510 547 505 541 510 547 1557 547 505 541 1562 542 1562 542 1562 542 510 547 505 541 510 547 505 541 511 546 505 541 22603 540 1564 539 1565 538 513 544 508 538 513 544 1560 544 508 538 1565 538 1565 538 1566 537 514 543 509 548 504 542 509 548 504 542 509 548 22597 546 1558 546 1558 546 506 540 512 545 507 539 1564 540 512 545 1559 545 1559 544 1559 544 507 539 513 544 508 538 513 544 508 538 513 544 22600 543 1561 542 1562 542 510 547 505 541 510 547 1557 547 505 541 1562 541 1563 540 1563 541 511 546 506 540 511 546 506 540 511 546 506 540 22604 539 1565 538 1566 537 514 543 509 548 504 542 1561 543 509 548 1556 548 1556 548 1556 547 504 542 510 547 505 541 510 547 505 541 510 547 22598 545 1559 544 1559 545 507 539 512 545 507 539 1564 540 512 545 1559 544 1559 545 1559 545 508 538 513 544 508 538 513 544 508 538 513 544 22601 542 1562 542 1562 542 511 546 505 541 511 546 1557 546 506 540 1563 541 1563 540 1563 541 511 546 506 540 511 546 506 540 512 545 506 540 22604 539 1565 538 1566 537 514 543 509 548 504 542 1561 543 509 548 1556 547 1556 547 1556 548 504 542 510 547 505 541 510 547 505 541 510 547 # -name: POWER +name: Power type: parsed protocol: SIRC address: 10 00 00 00 command: 60 00 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NEC address: 08 00 00 00 command: 0E 00 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NEC address: 08 00 00 00 command: 1A 00 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NEC address: 00 00 00 00 command: 57 00 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NEC address: 4D 00 00 00 command: 04 00 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NEC address: 4D 00 00 00 command: 05 00 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NEC address: 4D 00 00 00 command: 02 00 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NEC address: 4D 00 00 00 command: 03 00 00 00 # -name: POWER +name: Power type: parsed protocol: NEC address: 4D 00 00 00 command: 00 00 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NEC address: 00 00 00 00 command: 19 00 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NEC address: 00 00 00 00 command: 16 00 00 00 # -name: MUTE +name: Mute type: parsed protocol: NEC address: 00 00 00 00 command: 44 00 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NECext address: 12 36 00 00 command: 0A F5 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NECext address: 12 36 00 00 command: 0B F4 00 00 # -name: MUTE +name: Mute type: parsed protocol: NECext address: 12 36 00 00 command: 09 F6 00 00 # -name: POWER +name: Power type: parsed protocol: NECext address: 12 36 00 00 command: 01 FE 00 00 # # OFF -name: POWER +name: Power type: parsed protocol: RC5 address: 10 00 00 00 command: 0F 00 00 00 # -name: POWER +name: Power type: parsed protocol: NEC address: 00 00 00 00 command: 02 00 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NEC address: 00 00 00 00 command: 0A 00 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NEC address: 00 00 00 00 command: 0E 00 00 00 # -name: POWER +name: Power type: parsed protocol: SIRC address: 0F 00 00 00 command: 15 00 00 00 # -name: POWER +name: Power type: parsed protocol: Samsung32 address: 10 00 00 00 command: 1E 00 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: Samsung32 address: 10 00 00 00 command: 17 00 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: Samsung32 address: 10 00 00 00 command: 16 00 00 00 # -name: MUTE +name: Mute type: parsed protocol: Samsung32 address: 10 00 00 00 command: 1F 00 00 00 # -name: POWER +name: Power type: parsed protocol: Kaseikyo address: 51 54 32 01 command: 03 00 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: Kaseikyo address: 51 54 32 01 command: 04 00 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: Kaseikyo address: 51 54 32 01 command: 05 00 00 00 # -name: MUTE +name: Mute type: parsed protocol: Kaseikyo address: 51 54 32 01 command: 06 00 00 00 # -name: POWER +name: Power type: raw frequency: 38000 duty_cycle: 0.330000 data: 4567 4454 549 481 522 481 523 480 498 506 498 1509 499 1509 523 480 499 505 523 1484 523 1484 523 1485 521 1487 520 484 519 485 519 485 519 471 519 4488 518 485 519 485 518 485 519 485 518 485 519 485 519 485 519 485 519 1489 519 1489 518 1489 518 485 519 1489 518 1490 518 1490 517 1490 518 486 518 486 518 486 518 1490 518 # -name: VOL+ +name: Vol_up type: raw frequency: 38000 duty_cycle: 0.330000 data: 4571 4453 552 478 525 478 526 478 500 504 500 1507 501 1506 526 478 525 477 526 1481 526 1481 526 1482 524 1483 523 481 522 482 521 481 522 468 522 4484 521 482 521 482 521 482 522 481 522 1486 521 1486 521 1486 521 482 521 1486 522 1486 522 1486 522 482 522 482 522 482 522 482 522 1486 522 483 521 482 521 483 521 1487 521 55474 4547 4477 524 479 524 480 524 480 523 480 523 1485 523 1484 524 481 523 481 523 1485 523 1485 522 1485 523 1485 523 480 524 480 524 481 523 467 524 4484 523 481 523 481 523 481 523 481 523 1485 523 1485 523 1485 523 481 523 1485 523 1485 523 1485 523 481 523 481 523 481 523 481 523 1485 523 481 523 481 523 481 523 1486 522 # -name: VOL- +name: Vol_dn type: raw frequency: 38000 duty_cycle: 0.330000 data: 4572 4453 552 456 548 479 524 479 500 504 500 1482 526 1482 551 478 526 478 525 1483 524 1484 523 1486 521 1487 521 483 521 483 521 483 521 470 520 4487 521 483 521 483 521 483 521 483 521 483 521 483 521 483 521 1488 520 1488 520 1488 520 1488 520 483 521 1488 520 1488 520 1488 520 483 521 483 521 483 521 483 521 1488 520 55457 4565 4483 521 483 521 483 521 483 521 483 520 1488 520 1487 521 483 521 483 520 1488 520 1488 520 1488 520 1488 520 483 520 484 520 484 520 470 521 4487 520 484 520 483 520 484 520 484 520 484 520 484 519 484 520 1488 520 1488 520 1488 519 1488 520 484 520 1488 520 1488 520 1488 520 484 520 484 520 484 520 484 520 1489 519 # -name: MUTE +name: Mute type: raw frequency: 38000 duty_cycle: 0.330000 data: 4573 4451 552 477 527 478 526 477 526 478 501 1507 501 1506 502 502 527 477 526 1481 527 1481 527 1481 526 1482 525 479 524 480 523 481 523 468 523 4485 522 481 522 482 522 482 522 482 522 1486 522 482 521 482 522 482 522 1486 522 1486 522 1486 522 482 522 482 521 1487 521 1487 521 1487 521 482 521 483 521 483 521 1487 521 55462 4547 4474 524 478 525 479 524 480 523 480 523 1484 523 1484 523 480 523 480 523 1484 523 1484 524 1484 523 1485 522 480 523 480 524 480 523 467 523 4484 522 480 524 481 523 481 523 481 523 1485 523 481 522 481 523 481 523 1485 522 1485 523 1485 523 481 523 481 522 1485 522 1485 522 1485 523 481 522 481 522 481 523 1485 523 # -name: VOL- +name: Vol_dn type: parsed protocol: NECext address: 10 E7 00 00 command: 49 B6 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NECext address: 10 E7 00 00 command: 05 FA 00 00 # -name: MUTE +name: Mute type: parsed protocol: NEC address: 20 00 00 00 command: 50 00 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NEC address: 00 00 00 00 command: 0C 00 00 00 # -name: MUTE +name: Mute type: parsed protocol: NEC address: 00 00 00 00 command: 47 00 00 00 # -name: POWER +name: Power type: parsed protocol: NEC address: 80 00 00 00 command: 02 00 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NEC address: 80 00 00 00 command: 05 00 00 00 # -name: MUTE +name: Mute type: parsed protocol: NEC address: 80 00 00 00 command: 04 00 00 00 # -name: MUTE +name: Mute type: parsed protocol: NEC42 address: 6E 00 00 00 command: 4C 00 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NEC address: 01 00 00 00 command: 11 00 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NEC address: 01 00 00 00 command: 10 00 00 00 # -name: POWER +name: Power type: raw frequency: 38000 duty_cycle: 0.330000 data: 4555 4463 532 473 532 473 531 474 530 474 530 1478 531 1478 531 475 529 476 528 1482 551 1480 529 1480 528 1481 528 477 527 478 527 478 526 478 527 4498 526 477 527 477 527 478 526 478 526 478 526 478 526 478 527 478 526 1483 527 1483 526 1483 526 478 526 1483 527 1483 527 1483 526 1483 526 478 526 478 527 478 527 1484 526 55527 4527 4492 526 478 526 478 526 478 526 479 526 1483 527 1483 526 478 526 478 526 1483 527 1483 526 1483 526 1483 526 478 527 478 526 479 526 478 526 4497 526 478 526 478 526 478 526 478 526 478 526 478 526 478 526 478 526 1484 525 1483 526 1484 525 478 526 1484 525 1484 525 1484 525 1484 525 478 526 479 526 479 525 1484 525 # -name: VOL+ +name: Vol_up type: raw frequency: 38000 duty_cycle: 0.330000 data: 4552 4463 531 474 530 474 530 474 530 474 530 1478 531 1478 531 475 529 476 553 1455 554 1478 530 1479 529 1481 527 477 527 478 526 478 526 478 526 4497 526 478 526 478 526 478 526 477 527 1483 526 1482 527 1482 527 478 526 1483 526 1483 526 1483 526 478 526 478 526 478 526 478 526 1483 526 478 526 478 526 478 526 1483 526 # -name: VOL- +name: Vol_dn type: raw frequency: 38000 duty_cycle: 0.330000 data: 325 50440 173 137541 4551 4465 530 475 529 475 529 474 530 474 530 1479 530 1479 529 476 528 477 527 1480 554 1457 551 1480 528 1481 527 477 527 478 526 478 526 478 526 4497 525 478 526 478 526 478 526 478 526 479 525 479 525 479 525 1484 525 1483 526 1484 525 1483 526 479 525 1483 526 1483 526 1483 526 479 525 479 525 479 525 479 525 1484 525 # -name: POWER +name: Power type: parsed protocol: NECext address: 30 FC 00 00 command: 10 EF 00 00 # -name: MUTE +name: Mute type: parsed protocol: NECext address: 30 FC 00 00 command: 0C F3 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NECext address: 30 FC 00 00 command: 0D F2 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NECext address: 30 FC 00 00 command: 17 E8 00 00 # -name: POWER +name: Power type: parsed protocol: NEC address: 00 00 00 00 command: 04 00 00 00 # -name: POWER +name: Power type: parsed protocol: NEC address: FD 00 00 00 command: E2 00 00 00 # -name: MUTE +name: Mute type: parsed protocol: NEC address: FD 00 00 00 command: E1 00 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NEC address: FD 00 00 00 command: E7 00 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NEC address: FD 00 00 00 command: B9 00 00 00 # -name: POWER +name: Power type: raw frequency: 38000 duty_cycle: 0.330000 data: 2760 833 499 418 470 419 416 887 445 872 893 468 416 469 414 442 443 441 444 440 446 440 446 440 446 440 892 882 445 444 466 446 439 447 438 448 437 449 884 447 437 450 437 894 436 449 437 449 437 449 437 449 437 449 884 448 436 894 437 450 436 116126 2673 887 445 473 440 449 439 893 438 880 884 448 437 449 437 449 437 449 437 449 437 449 437 449 437 449 884 890 437 449 437 449 437 450 436 449 437 449 884 448 436 451 437 894 436 449 437 450 436 450 436 449 437 450 883 448 436 894 436 449 437 116123 2672 888 469 449 439 450 437 893 438 881 883 448 437 449 437 449 437 449 437 449 438 449 437 449 437 449 884 891 437 449 437 449 437 449 437 449 437 449 884 448 436 451 437 894 437 449 437 449 437 449 437 449 437 449 884 448 436 894 437 449 437 # -name: MUTE +name: Mute type: raw frequency: 38000 duty_cycle: 0.330000 data: 2701 861 496 420 445 444 444 885 446 871 892 441 444 441 444 441 471 415 471 415 470 417 467 444 440 446 883 891 436 449 437 449 437 450 436 450 436 449 883 448 437 451 436 894 436 450 436 450 436 450 436 450 436 450 882 449 436 894 883 116552 2698 862 469 448 438 449 438 894 437 880 884 448 437 449 437 448 438 449 437 449 437 449 437 449 437 449 884 890 437 449 437 449 437 449 437 449 437 449 884 448 437 450 437 893 437 449 437 449 437 449 437 449 437 449 884 448 436 894 883 # -name: VOL+ +name: Vol_up type: parsed protocol: NECext address: 10 E7 00 00 command: 3C C3 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NECext address: 10 E7 00 00 command: 4D B2 00 00 # -name: POWER +name: Power type: parsed protocol: Kaseikyo address: 52 54 32 00 command: 83 00 00 00 # -name: MUTE +name: Mute type: parsed protocol: Kaseikyo address: 52 54 32 00 command: 86 00 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: Kaseikyo address: 52 54 32 00 command: 84 00 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: Kaseikyo address: 52 54 32 00 command: 85 00 00 00 # -name: POWER +name: Power type: parsed protocol: NEC address: 00 00 00 00 diff --git a/assets/resources/infrared/assets/fans.ir b/assets/resources/infrared/assets/fans.ir index a741daf8e..734de79e0 100644 --- a/assets/resources/infrared/assets/fans.ir +++ b/assets/resources/infrared/assets/fans.ir @@ -3,1532 +3,1532 @@ Version: 1 # Last Updated 17th May, 2023 # Last Checked 17th May, 2023 # -name: POWER +name: Power type: raw frequency: 38000 duty_cycle: 0.330000 data: 1301 370 1299 371 558 1107 1301 371 1272 398 557 1108 562 1107 562 1107 561 1108 560 1110 559 1110 1272 7254 1269 423 1244 425 530 1140 1242 427 1241 428 527 1142 527 1142 527 1142 527 1142 527 1142 527 1142 1241 7285 1241 428 1241 428 528 1142 1240 428 1241 428 528 1142 527 1142 527 1142 527 1142 527 1142 527 1142 1240 7284 1240 428 1241 429 527 1142 1241 429 1240 429 527 1142 527 1142 528 1142 527 1142 527 1142 527 1142 1240 # -name: SPEED+ +name: Speed_up type: raw frequency: 38000 duty_cycle: 0.330000 data: 1268 400 1267 424 505 1164 1243 426 1242 427 504 1166 503 1166 503 1166 528 1141 1242 428 503 1166 503 8024 1241 427 1241 428 528 1141 1241 428 1241 428 503 1166 503 1167 502 1167 527 1142 1241 428 503 1166 503 8024 1241 427 1242 427 504 1167 1241 428 1241 428 503 1167 503 1167 503 1166 528 1142 1242 428 503 1167 502 8024 1241 428 1241 428 503 1167 1241 428 1241 428 503 1167 503 1167 503 1167 503 1167 1241 428 528 1142 503 8025 1240 429 1240 429 502 1167 1241 429 1240 429 502 1167 503 1167 503 1167 502 1167 1240 429 502 1168 501 8026 1239 430 1239 430 501 1169 1238 431 1238 430 501 1170 524 1170 475 1171 499 1170 1237 456 475 1195 474 # -name: MODE +name: Mode type: raw frequency: 38000 duty_cycle: 0.330000 data: 1242 425 1242 401 554 1140 1242 426 1243 428 504 1165 504 1167 1240 427 530 1141 530 1139 504 1167 527 7998 1241 427 1242 427 503 1166 1241 427 1242 428 529 1141 503 1167 1239 429 528 1141 503 1168 529 1140 528 7999 1240 428 1241 427 504 1167 1240 429 1239 429 528 1142 502 1167 1241 428 503 1167 503 1166 528 1142 528 7999 1240 429 1240 429 501 1168 1240 428 1242 427 528 1143 527 1142 1241 428 503 1167 502 1167 528 1142 502 8026 1239 428 1242 428 528 1142 1215 455 1240 427 504 1169 500 1168 1241 427 503 1168 527 1141 504 1166 530 7999 1239 429 1240 429 503 1167 1240 430 1239 430 502 1168 502 1168 1238 430 503 1169 526 1142 503 1167 502 8026 1239 429 1240 429 502 1168 1239 430 1241 428 502 1168 502 1168 1239 429 502 1167 503 1167 502 1168 502 8025 1239 428 1241 429 527 1143 1239 428 1241 429 502 1168 526 1142 1242 428 502 1167 502 1168 502 1167 502 # -name: POWER +name: Power type: raw frequency: 38000 duty_cycle: 0.330000 data: 9086 4339 707 443 681 445 681 422 704 445 681 445 681 445 681 445 681 445 656 1563 683 1563 682 1563 707 1539 706 1562 682 1562 682 1564 680 1565 679 1566 679 448 679 1567 678 448 679 448 679 448 679 1566 679 448 679 448 678 1566 679 448 678 1566 678 1566 678 1566 678 448 678 1566 679 39846 9058 2132 679 # -name: SPEED+ +name: Speed_up type: raw frequency: 38000 duty_cycle: 0.330000 data: 9083 4342 705 446 679 447 679 447 680 447 680 447 679 425 702 447 679 447 654 1564 681 1564 680 1565 680 1591 680 1565 680 1565 679 1565 679 1566 678 1568 677 1569 676 1569 676 451 676 450 677 450 677 1569 676 451 676 451 675 450 677 450 677 1570 675 1570 675 1569 676 451 676 1569 676 39854 9056 2136 677 # -name: TIMER +name: Timer type: raw frequency: 38000 duty_cycle: 0.330000 data: 9267 4339 708 443 682 445 682 422 734 416 711 416 711 416 711 415 712 415 658 1563 682 1564 682 1565 681 1587 684 1562 683 1563 683 1563 682 1564 681 1565 680 447 679 447 679 1566 679 1566 680 447 680 447 680 447 680 447 680 1566 679 1566 679 447 680 447 680 1566 679 1566 679 1566 679 # -name: ROTATE +name: Rotate type: raw frequency: 38000 duty_cycle: 0.330000 data: 9085 4343 705 446 679 447 680 447 680 447 679 425 701 447 679 423 703 446 655 1563 682 1563 681 1565 679 1589 681 1564 680 1563 680 1564 679 1566 678 449 677 450 676 1568 677 1568 677 1569 676 450 676 450 676 450 677 1568 677 1568 677 450 676 450 676 450 677 1568 676 1568 677 1568 676 # -name: MODE +name: Mode type: raw frequency: 38000 duty_cycle: 0.330000 data: 1284 419 1288 442 417 1258 1288 415 1282 448 411 1264 443 1258 439 1263 444 1258 1288 415 444 1258 439 8679 1284 419 1288 441 407 1267 1289 441 1256 447 412 1262 435 1267 440 1262 435 1293 1263 413 435 1267 440 8679 1284 418 1289 441 407 1267 1289 414 1283 447 412 1262 435 1267 440 1261 436 1267 1289 413 435 1267 440 8678 1285 418 1289 440 408 1267 1289 440 1257 447 412 1262 435 1267 440 1262 435 1268 1288 414 434 1268 439 8679 1284 418 1289 440 408 1267 1289 413 1284 445 414 1261 436 1266 441 1260 437 1266 1290 412 436 1266 441 8676 1287 415 1282 448 411 1264 1282 421 1286 443 416 1258 439 1263 434 1267 440 1262 1284 419 440 1262 435 8683 1280 422 1285 444 415 1287 1259 444 1253 449 410 1292 415 1285 412 1264 443 1259 1287 416 443 1259 438 8680 1284 420 1287 414 434 1268 1288 415 1282 447 412 1289 408 1267 440 1262 435 1267 1289 414 434 1268 439 # -name: TIMER +name: Timer type: raw frequency: 38000 duty_cycle: 0.330000 data: 1283 420 1287 443 416 1259 1287 443 1254 449 410 1292 415 1260 437 1266 1290 439 409 1266 442 1261 436 8684 1290 413 1284 446 413 1263 1283 447 1261 442 417 1258 439 1263 444 1259 1287 442 417 1259 438 1264 443 8677 1287 416 1281 449 410 1265 1281 449 1259 444 415 1260 437 1265 442 1260 1286 443 416 1260 437 1265 442 8676 1288 415 1282 447 412 1263 1283 447 1261 442 417 1257 440 1263 434 1268 1288 441 418 1257 440 1263 434 8685 1289 414 1283 447 412 1263 1283 447 1261 442 417 1258 439 1263 445 1258 1288 442 417 1258 439 1264 444 8676 1288 415 1282 448 411 1264 1282 448 1260 444 415 1259 438 1264 443 1260 1286 417 442 1260 437 1265 442 8677 1286 416 1281 449 410 1265 1281 422 1285 444 415 1260 437 1265 442 1260 1286 417 442 1260 437 1265 442 # -name: ROTATE +name: Rotate type: raw frequency: 38000 duty_cycle: 0.330000 data: 1281 422 1285 444 415 1260 1286 444 1263 439 409 1266 441 1261 1285 445 414 1261 436 1266 441 1261 436 8682 1281 421 1286 444 415 1260 1286 445 1262 439 409 1266 441 1261 1285 445 414 1261 436 1266 441 1260 437 8683 1280 422 1286 444 415 1261 1285 445 1262 440 408 1267 440 1262 1284 446 413 1262 435 1268 439 1262 435 8684 1279 423 1284 445 414 1261 1285 445 1263 439 409 1265 442 1260 1286 444 415 1260 437 1265 442 1259 438 8682 1281 421 1286 443 416 1259 1287 443 1254 448 411 1264 443 1259 1287 443 416 1259 438 1265 442 1260 437 8682 1281 421 1286 444 415 1260 1286 444 1253 450 409 1266 441 1261 1285 445 414 1261 436 1266 441 1261 436 8683 1290 413 1284 445 414 1262 1283 446 1261 441 407 1294 413 1262 1284 420 439 1263 434 1267 440 1262 435 # -name: TIMER +name: Timer type: raw frequency: 38000 duty_cycle: 0.330000 data: 1294 371 1351 322 443 1200 1295 346 1297 373 444 1224 445 1198 1300 345 498 1170 473 1171 496 1173 471 8057 1295 372 1297 347 444 1224 1296 347 1296 349 494 1172 470 1174 1293 376 469 1174 469 1200 468 1175 468 8082 1293 351 1318 349 468 1175 1292 377 1294 349 468 1177 491 1175 1293 350 442 1226 468 1175 468 1201 467 8083 1293 350 1268 401 467 1175 1293 351 1318 350 467 1175 442 1226 1293 350 467 1177 466 1200 468 1176 441 8133 1292 351 1267 400 468 1175 1292 351 1292 376 466 1177 467 1202 1291 352 442 1202 465 1203 441 1201 442 8132 1267 376 1267 402 440 1202 1266 377 1290 379 439 1226 416 1253 1241 402 415 1228 439 1229 414 1228 415 8161 1239 403 1240 404 439 1229 1240 403 1240 429 414 1229 414 1231 1264 404 413 1229 414 1255 413 1229 413 8161 1238 404 1239 405 437 1230 1239 404 1238 430 412 1230 412 1232 1262 405 412 1231 412 1256 412 1231 412 8162 1238 406 1237 406 411 1258 1237 406 1237 431 412 1256 387 1256 1213 456 386 1256 386 1257 412 1256 386 8164 1237 431 1212 431 386 1283 1212 431 1212 432 411 1257 386 1257 1211 457 386 1257 386 1258 411 1258 385 8164 1212 431 1212 432 411 1256 1213 431 1236 433 386 1256 387 1257 1238 430 386 1257 386 1282 386 1256 386 -# ON/SPEED+ -name: POWER +# ON/Speed_up +name: Power type: raw frequency: 38000 duty_cycle: 0.330000 data: 1330 364 1385 320 523 1158 1332 365 1329 364 479 1213 481 1213 481 1213 481 1213 481 1213 1332 390 480 8072 1358 362 1329 364 478 1216 1328 366 1328 367 476 1218 476 1218 476 1218 476 1218 476 1218 1328 367 476 8103 1328 367 1327 367 476 1218 1327 367 1327 367 476 1218 476 1218 476 1218 476 1218 476 1218 1327 367 476 8103 1327 367 1327 367 476 1218 1327 368 1326 367 476 1218 476 1219 475 1219 475 1219 475 1219 1326 368 475 8104 1327 368 1326 368 475 1219 1327 368 1326 368 475 1219 475 1219 475 1219 475 1219 475 1219 1326 368 475 8105 1326 368 1326 368 475 1219 1327 368 1326 368 475 1220 474 1220 474 1220 475 1220 474 1220 1325 368 475 8105 1326 369 1325 369 474 1220 1326 369 1325 369 474 1220 474 1220 474 1220 474 1220 474 1220 1326 369 474 8106 1325 369 1325 369 474 1220 1325 369 1326 369 474 1220 474 1220 474 1220 474 1220 474 1221 1324 370 473 8132 1273 422 1272 422 446 1248 1272 422 1297 397 421 1275 419 1300 419 1276 419 1275 419 1250 1297 398 445 8135 1297 397 1297 397 447 1247 1298 397 1297 397 447 1247 447 1247 447 1247 447 1247 447 1247 1298 397 447 8134 1298 397 1298 397 447 1248 1297 397 1297 397 447 1248 446 1248 446 1248 447 1248 447 1248 1297 397 447 8133 1298 397 1297 397 447 1248 1297 397 1297 397 447 1248 446 1248 447 1248 446 1248 446 1248 1297 398 446 8134 1297 398 1296 398 446 1248 1297 398 1296 398 446 1248 446 1248 446 1248 446 1248 446 1248 1296 398 446 8134 1295 398 1296 398 446 1248 1296 398 1296 398 446 1249 445 1249 445 1249 445 1249 445 1249 1295 399 445 8134 1295 399 1295 399 445 1249 1295 399 1295 399 445 1249 445 1249 445 1250 444 1249 445 1249 1295 399 445 8135 1295 400 1294 400 444 1250 1294 400 1295 400 444 1250 444 1250 444 1250 444 1250 444 1250 1294 401 443 8137 1293 401 1294 401 442 1251 1294 401 1293 401 442 1253 442 1252 442 1252 442 1252 442 1252 1293 427 417 8140 1292 426 1268 427 417 1277 1243 452 1267 427 417 1278 417 1277 417 1278 417 1277 417 1277 1268 427 417 8163 1242 452 1242 452 417 1278 1242 453 1241 453 391 1303 391 1303 392 1303 391 1303 391 1303 1242 453 415 8165 1241 453 1241 453 391 1304 1241 453 1241 454 390 1305 389 1304 390 1304 390 1305 389 1305 1240 480 364 8216 1214 480 1214 480 363 1331 1214 480 1214 480 364 1331 363 1331 363 1331 363 1331 363 1331 1214 481 363 8218 1213 481 1213 481 363 1333 1212 508 1186 508 335 1359 335 1359 335 1359 335 1359 335 1360 1186 508 335 8247 1184 509 1185 535 307 1387 1159 536 1158 589 253 1389 306 1415 278 1416 252 1442 199 1575 1052 # -name: POWER +name: Power type: raw frequency: 38000 duty_cycle: 0.330000 data: 1318 346 1298 324 494 1201 1291 345 1297 375 466 1174 470 1200 442 1201 467 1201 441 1201 466 1204 1265 7229 1373 322 1266 375 466 1202 1267 325 1318 378 465 1200 442 1202 465 1202 442 1201 441 1202 467 1171 1297 7281 1268 325 1399 323 439 1200 1293 348 1351 322 441 1202 522 1145 498 1172 439 1204 496 1171 471 1148 1346 7227 1323 322 1266 325 574 1145 1322 322 1347 322 496 1115 528 1171 497 1145 497 1148 521 1145 497 1145 1291 7285 1322 322 1321 323 521 1147 1321 322 1346 322 496 1172 470 1147 522 1145 498 1146 519 1149 497 1171 1297 7252 1323 322 1321 323 520 1144 1323 322 1343 323 498 1144 498 1147 522 1146 496 1146 571 1123 471 1145 1323 7229 1345 322 1321 322 570 1097 1322 323 1320 323 521 1146 496 1146 519 1148 498 1145 498 1149 520 1145 1322 7229 1347 323 1320 322 464 1202 1323 323 1320 322 522 1145 497 1145 466 1228 471 1116 527 1147 522 1147 1321 7226 1348 322 1266 375 442 1202 1292 348 1295 375 523 1146 442 1201 442 1202 466 1200 442 1200 467 1202 1268 7281 1292 375 1270 346 471 1201 1293 373 1270 374 523 1145 445 1199 443 1200 469 1199 443 1200 524 1144 1269 7258 1292 374 1269 374 468 1200 1269 374 1269 400 443 1200 443 1201 467 1201 498 1146 497 1172 497 1145 1324 # -name: POWER +name: Power type: parsed protocol: NECext address: 4B 14 00 00 command: 80 7F 00 00 # -name: MODE +name: Mode type: parsed protocol: NECext address: 4B 14 00 00 command: 20 DF 00 00 # -name: ROTATE +name: Rotate type: parsed protocol: NECext address: 4B 14 00 00 command: C0 3F 00 00 # -name: TIMER +name: Timer type: parsed protocol: NECext address: 4B 14 00 00 command: A0 5F 00 00 # -name: POWER +name: Power type: raw frequency: 38000 duty_cycle: 0.330000 data: 9137 4430 630 1594 661 464 659 1625 630 1624 631 1625 630 1596 659 1596 660 1624 631 492 631 1624 632 1623 632 1593 662 1597 658 1624 631 1625 630 1595 660 491 632 1595 661 1595 660 1624 631 1624 631 1596 660 1624 631 1624 631 1593 663 435 689 491 632 434 690 491 632 491 632 463 661 490 634 # -name: SPEED+ +name: Speed_up type: raw frequency: 38000 duty_cycle: 0.330000 data: 9107 4400 660 1622 633 464 659 1623 632 1596 659 1622 633 1622 633 1623 632 1622 633 493 630 1593 662 1595 660 1623 632 1593 662 1623 632 1596 659 1623 632 1622 633 420 703 1594 661 424 699 1592 663 1594 661 1595 660 1597 658 423 700 1623 632 489 634 1593 662 461 662 431 692 488 635 489 634 # -name: SPEED- +name: Speed_dn type: raw frequency: 38000 duty_cycle: 0.330000 data: 9106 4428 632 1595 660 463 660 1595 660 1622 633 1593 662 1622 633 1622 633 1595 660 490 633 1595 660 1595 660 1592 663 1593 662 1623 632 1623 632 1594 661 1623 632 1595 660 1594 661 1596 659 489 634 1595 660 1595 660 1596 659 463 660 490 633 462 662 422 701 1595 660 464 659 490 633 428 695 # -name: MODE +name: Mode type: raw frequency: 38000 duty_cycle: 0.330000 data: 9136 4401 659 1624 631 463 660 1624 631 1593 663 1623 632 1624 632 1596 660 1594 661 464 659 1597 658 1593 662 1623 632 1595 660 1623 632 1624 631 1594 662 489 634 1623 633 431 693 1594 662 1623 633 1594 662 1595 661 1593 663 1592 663 461 663 1623 632 463 660 434 689 463 660 463 661 426 698 # -name: ROTATE +name: Rotate type: raw frequency: 38000 duty_cycle: 0.330000 data: 9142 4400 661 1593 662 491 632 1624 632 1598 657 1594 662 1594 662 1596 660 1596 660 490 634 1596 660 1596 660 1624 631 1594 662 1623 632 1594 662 1624 632 1624 632 491 632 1624 632 1595 661 1624 631 1624 632 1594 662 1624 631 491 633 1624 632 464 659 492 632 432 692 430 694 464 660 432 692 # -name: TIMER +name: Timer type: raw frequency: 38000 duty_cycle: 0.330000 data: 9134 4428 632 1597 658 355 768 1624 631 1623 632 1623 632 1597 658 1623 632 1622 633 463 660 1595 660 1622 633 1596 659 1595 660 1622 633 1623 632 1596 659 1622 633 1623 632 436 687 1623 633 1622 633 1622 633 1622 633 1598 657 434 689 489 634 1622 633 466 657 489 634 490 633 490 633 440 684 # -name: POWER +name: Power type: raw frequency: 38000 duty_cycle: 0.330000 data: 8980 4377 620 1599 620 489 620 488 621 488 621 488 622 488 621 488 621 488 621 488 621 1597 622 1598 621 1598 621 1597 622 1597 622 1597 622 1597 622 1597 621 1598 646 463 646 464 645 464 645 465 644 466 643 466 643 466 643 466 643 1575 643 1576 643 1576 643 1576 643 1576 643 1576 643 1576 643 1576 643 466 643 466 643 466 643 466 643 466 643 466 643 466 644 466 643 1576 643 1576 643 1576 643 1576 643 1576 643 1576 643 # -name: ROTATE +name: Rotate type: raw frequency: 38000 duty_cycle: 0.330000 data: 9011 4375 620 1598 621 462 647 488 621 488 621 488 676 434 621 488 621 489 620 488 621 1598 621 1598 621 1598 621 1598 621 1597 622 1598 621 1597 622 1597 622 1598 621 488 621 489 644 1576 644 466 643 466 643 466 643 466 643 466 644 1576 643 1576 643 466 643 1576 643 1576 643 1576 643 1576 643 1576 643 466 644 466 643 1576 643 466 644 466 643 466 644 466 643 466 643 1575 644 1576 643 466 643 1575 643 1576 643 1576 643 # -name: POWER +name: Power type: raw frequency: 38000 duty_cycle: 0.330000 data: 2262 692 881 585 883 583 903 564 903 1294 882 584 881 584 882 559 820 673 895 1300 882 611 881 584 882 584 882 584 882 585 881 584 881 584 882 585 880 1317 879 586 829 1371 827 640 825 51208 2245 690 772 1424 831 50893 2240 691 772 1429 771 50906 2244 690 773 1400 772 # -name: SPEED+ +name: Speed_up type: raw frequency: 38000 duty_cycle: 0.330000 data: 2264 668 770 721 745 694 772 694 796 1401 826 639 771 694 771 693 772 694 771 1426 798 668 769 1429 795 670 795 1404 794 672 794 1405 767 1431 767 1430 794 672 794 1404 794 1404 794 1404 766 50878 2261 645 817 1405 794 50857 2238 668 795 1428 769 # -name: SPEED- +name: Speed_dn type: raw frequency: 38000 duty_cycle: 0.330000 data: 2264 642 823 669 797 643 822 644 822 1376 822 642 799 668 797 669 823 645 820 1401 796 670 794 1379 792 700 793 1381 790 1407 793 674 791 700 793 1406 792 673 793 673 792 673 793 673 792 50785 2262 666 796 1401 797 # -name: ROTATE +name: Rotate type: raw frequency: 38000 duty_cycle: 0.330000 data: 2323 611 796 669 800 664 802 692 773 1424 774 691 801 664 774 691 774 692 773 1423 800 668 822 667 798 1376 769 1427 771 696 769 696 770 1429 795 1404 794 672 794 1404 794 671 795 1404 794 51269 2214 691 769 1427 796 # # ON/SPEED -name: POWER +name: Power type: parsed protocol: NECext address: 00 FC 00 00 command: 84 7B 00 00 # -name: POWER +name: Power type: raw frequency: 38000 duty_cycle: 0.330000 data: 1285 426 1258 427 414 1267 1248 436 1258 427 414 1267 406 1276 408 1248 435 1247 437 1271 413 1244 1282 7286 1279 432 1252 433 409 1273 1253 431 1253 432 410 1273 411 1271 413 1243 440 1241 442 1240 433 1275 1251 7292 1283 427 1257 428 413 1268 1258 427 1257 428 414 1268 416 1240 433 1249 434 1248 435 1246 438 1245 1281 7287 1278 406 1278 434 408 1274 1252 432 1252 433 409 1274 410 1246 438 1244 440 1243 440 1241 443 1240 1275 7294 1281 402 1282 430 412 1270 1256 428 1256 429 412 1243 441 1241 443 1240 433 1249 434 1247 436 1246 1280 7288 1277 433 1251 434 408 1248 1278 432 1251 433 409 1273 411 1245 439 1244 440 1242 442 1240 433 1249 1277 7292 1283 400 1304 406 435 1246 1248 436 1279 405 436 1246 406 1249 434 1247 436 1245 438 1244 440 1242 1284 7285 1280 430 1285 400 442 1241 1285 399 1285 400 441 1240 444 1212 440 1241 443 1240 433 1249 434 1273 1284 7259 1306 404 1280 405 436 1245 1281 403 1281 404 438 1244 440 1216 468 1214 438 1244 440 1242 442 1241 1305 7262 1303 408 1276 407 434 1249 1277 407 1276 407 435 1248 436 1220 464 1219 464 1217 466 1242 441 1214 1312 # -name: SPEED+ +name: Speed_up type: raw frequency: 38000 duty_cycle: 0.330000 data: 1280 431 1252 431 410 1244 1281 430 1253 430 411 1270 413 1242 441 1240 433 1249 434 1247 1278 433 408 8129 1277 433 1250 433 408 1274 1251 432 1251 433 409 1273 410 1271 412 1269 414 1241 432 1250 1275 435 406 8133 1283 426 1257 427 414 1267 1248 436 1247 436 405 1276 407 1248 435 1247 436 1245 438 1244 1281 429 412 8126 1280 430 1253 430 411 1270 1255 429 1254 429 412 1269 414 1241 432 1276 407 1248 435 1247 1278 432 410 8129 1277 432 1251 433 408 1273 1252 431 1252 431 411 1272 411 1269 414 1241 442 1240 433 1275 1250 434 408 8130 1276 434 1249 434 407 1275 1250 433 1250 433 408 1274 409 1272 411 1244 439 1268 415 1240 1275 436 405 8133 1283 427 1256 427 414 1267 1248 436 1258 426 405 1277 406 1274 409 1273 410 1245 438 1244 1281 429 412 8125 1281 429 1254 429 412 1269 1256 428 1255 428 413 1268 415 1266 407 1248 435 1247 436 1245 1280 430 411 8127 1279 431 1252 431 411 1271 1254 430 1253 430 412 1270 413 1268 415 1240 433 1275 408 1247 1278 432 410 8128 1278 432 1251 432 410 1272 1253 431 1252 431 410 1271 412 1242 441 1267 406 1250 433 1248 1277 433 409 8129 1277 433 1250 433 409 1272 1253 431 1252 431 410 1271 412 1242 441 1241 432 1250 433 1248 1277 433 409 8129 1277 433 1250 434 408 1246 1279 432 1251 432 409 1245 438 1244 439 1242 441 1240 433 1249 1276 434 407 # -name: POWER +name: Power type: raw frequency: 38000 duty_cycle: 0.330000 data: 2356 608 934 1216 825 1320 826 1348 793 646 824 673 792 667 792 663 792 720 793 692 793 687 818 657 817 652 817 649 816 1310 815 1306 815 102511 2320 668 819 1332 817 1328 817 1325 815 655 815 650 815 645 815 640 815 699 814 671 814 666 814 661 814 657 813 652 813 1337 788 1333 787 # -name: ROTATE +name: Rotate type: raw frequency: 38000 duty_cycle: 0.330000 data: 390 9025 2296 666 821 1329 821 1324 821 1319 821 647 822 642 822 666 793 661 793 1385 793 691 819 660 819 655 818 652 816 1314 815 644 815 1305 815 101869 2318 668 818 1331 817 1328 816 1323 816 654 815 649 815 645 814 640 814 1363 815 670 815 665 814 660 815 655 814 1316 814 645 814 1306 814 # -name: SPEED+ +name: Speed_up type: raw frequency: 38000 duty_cycle: 0.330000 data: 2346 612 875 1275 931 1214 929 1211 875 594 875 588 876 582 822 633 821 691 848 1303 847 659 819 1321 817 652 816 1314 815 1310 814 640 814 101247 2320 667 819 1330 818 1327 816 1324 815 654 815 649 815 644 815 639 815 698 814 1335 815 665 814 1325 814 655 814 1315 815 1310 815 640 814 # -name: SPEED- +name: Speed_dn type: raw frequency: 38000 duty_cycle: 0.330000 data: 2313 646 841 1308 841 1303 841 1298 841 626 843 621 842 614 819 634 820 1359 844 1333 817 1328 815 1324 814 1321 812 1317 812 647 812 1308 811 99132 2317 670 816 1333 815 1330 813 1326 813 657 812 652 812 647 812 642 812 1366 812 1338 811 1332 812 1328 812 1323 811 1317 813 647 812 1307 812 # -name: POWER +name: Power type: raw frequency: 38000 duty_cycle: 0.330000 data: 3533 1663 476 420 450 1234 508 421 449 394 477 420 450 420 474 387 459 421 475 396 558 385 432 386 484 386 485 386 434 1263 479 419 447 395 475 394 476 393 478 393 478 392 478 1264 477 393 478 1264 478 1266 500 387 483 395 475 1268 473 397 474 397 474 397 474 397 474 1268 473 397 474 397 474 397 474 397 474 1268 472 1270 472 398 473 398 473 1269 473 398 473 398 473 397 474 1268 473 1269 473 398 473 398 473 1269 472 398 473 1269 472 398 473 1269 472 398 473 1269 472 398 473 74625 3552 1673 473 397 472 1270 472 399 471 399 471 400 470 400 470 401 470 401 470 401 469 401 470 402 469 402 469 402 469 1272 471 400 470 400 470 401 469 402 468 427 444 427 444 1273 471 400 470 1272 470 1271 471 400 470 401 469 1273 470 401 469 427 443 428 442 428 417 1300 469 426 443 428 417 453 442 428 417 1325 443 1274 468 427 443 428 417 1325 443 427 417 454 416 454 416 1326 417 1325 442 427 417 453 417 1325 417 453 417 1325 418 453 416 1326 416 453 417 1326 416 454 416 -# TIMER UP -name: TIMER +# Timer UP +name: Timer type: parsed protocol: NEC address: 80 00 00 00 command: 07 00 00 00 # -name: SPEED+ +name: Speed_up type: raw frequency: 38000 duty_cycle: 0.330000 data: 1367 345 1338 347 491 1170 1361 349 1334 350 488 1198 489 1198 488 1199 488 1199 487 1200 1334 352 486 7953 1333 353 1332 353 486 1200 1333 353 1332 353 486 1200 486 1201 486 1200 486 1200 487 1201 1332 353 486 7953 1332 353 1333 353 485 1201 1332 353 1332 353 485 1201 485 1201 485 1201 486 1200 486 1200 1333 353 486 7953 1333 353 1332 354 485 1201 1332 353 1332 353 485 1201 486 1201 485 1201 485 1201 486 1201 1332 354 484 7954 1332 353 1332 353 485 1201 1332 354 1331 354 485 1201 485 1201 486 1201 486 1201 486 1201 1333 354 484 7954 1332 354 1331 354 485 1201 1332 355 1331 354 484 1201 485 1201 486 1202 485 1201 486 1201 1331 355 484 7953 1332 354 1331 354 484 1201 1332 355 1330 355 483 1202 484 1201 486 1201 485 1202 484 1202 1331 355 484 7954 1331 354 1331 354 484 1202 1331 355 1330 354 484 1202 485 1201 485 1202 484 1202 485 1202 1330 355 484 # -name: TIMER +name: Timer type: raw frequency: 38000 duty_cycle: 0.330000 data: 1367 335 1349 346 492 1166 1365 346 1338 347 491 1170 516 1172 514 1173 1359 349 489 1197 489 1198 488 7950 1334 352 1332 352 486 1200 1333 352 1333 352 486 1200 486 1200 486 1200 1333 352 486 1200 486 1200 487 7953 1332 352 1333 353 485 1200 1333 353 1332 353 485 1200 486 1200 486 1200 1333 353 485 1200 486 1200 487 7951 1333 353 1332 352 486 1200 1333 353 1332 353 486 1200 486 1200 486 1200 1333 353 486 1200 486 1200 486 7952 1333 352 1333 353 485 1200 1333 353 1332 353 486 1200 486 1200 486 1200 1333 353 485 1200 486 1200 486 7952 1332 353 1332 353 485 1200 1333 353 1331 353 485 1200 486 1201 485 1201 1332 353 485 1201 485 1201 486 7952 1331 353 1332 354 484 1201 1332 354 1331 354 484 1201 485 1202 484 1201 1332 354 484 1202 484 1202 485 # -name: ROTATE +name: Rotate type: raw frequency: 38000 duty_cycle: 0.330000 data: 1337 374 1311 374 464 1194 1339 373 1340 345 493 1165 521 1165 1365 347 492 1167 519 1168 518 1168 518 7920 1363 347 1336 349 489 1197 1334 352 1333 353 485 1200 486 1200 1333 352 486 1200 486 1200 486 1200 486 # -name: POWER +name: Power type: parsed protocol: NECext address: BA F0 00 00 command: 03 FC 00 00 # -name: SPEED+ +name: Speed_up type: parsed protocol: NECext address: BA F0 00 00 command: 50 AF 00 00 # -name: SPEED- +name: Speed_dn type: parsed protocol: NECext address: BA F0 00 00 command: 41 BE 00 00 # -name: TIMER +name: Timer type: parsed protocol: NECext address: BA F0 00 00 command: 40 BF 00 00 # -name: POWER +name: Power type: parsed protocol: NECext address: BA F0 00 00 command: 53 AC 00 00 # -name: POWER +name: Power type: raw frequency: 38000 duty_cycle: 0.330000 data: 9069 4477 591 1695 622 528 625 525 618 505 617 532 621 527 626 497 625 525 618 532 621 1661 615 1640 595 1688 599 1684 613 1643 592 1691 626 1656 620 1636 620 1663 624 526 617 505 628 523 620 529 624 525 618 504 618 531 622 527 616 1643 623 1662 625 1658 618 1637 598 1685 622 1659 627 1655 570 1685 622 528 625 523 620 502 620 529 624 524 619 503 588 561 623 526 617 1667 619 1639 627 1654 622 1660 616 1638 617 1664 622 # -name: SPEED+ +name: Speed_up type: raw frequency: 38000 duty_cycle: 0.330000 data: 9014 4522 597 1687 610 512 590 559 594 555 619 503 599 550 593 556 597 551 613 509 593 1688 588 1692 615 1639 596 1684 592 1689 587 1666 590 1691 595 1685 591 1689 566 1689 597 551 592 557 638 485 596 553 590 558 595 527 595 554 589 559 594 1686 611 1643 592 1688 588 1692 646 1607 597 1684 592 1688 619 1634 591 558 595 553 590 532 590 558 595 553 590 559 615 506 596 553 590 1693 594 1685 571 1683 593 1686 590 1690 565 # -name: MODE +name: Mode type: raw frequency: 38000 duty_cycle: 0.330000 data: 9066 4476 623 1662 625 525 618 504 587 561 623 526 617 531 622 501 621 528 625 524 619 1661 564 1692 625 1655 621 1660 565 1690 627 1654 622 1659 586 1668 618 1663 623 1657 619 1636 620 529 624 524 619 502 620 529 624 524 619 529 614 509 624 525 618 1663 613 1640 626 1655 621 1659 617 1637 619 1662 625 1656 620 1633 623 527 626 523 620 529 614 508 625 524 619 530 623 499 593 557 617 1663 623 1657 619 1635 621 1660 616 # -name: TIMER +name: Timer type: raw frequency: 38000 duty_cycle: 0.330000 data: 9038 4530 589 1665 590 559 594 555 598 551 613 510 592 558 595 553 590 532 590 559 594 1686 590 1690 617 1637 598 1683 593 1687 620 1634 591 1691 595 1685 622 1632 593 557 596 1684 592 530 592 557 596 552 591 558 616 506 596 553 590 1690 596 526 596 1684 592 1688 588 1692 563 1690 596 1684 592 1687 620 503 589 1691 595 553 621 501 591 558 595 553 590 532 590 558 595 1689 597 551 623 1630 595 1686 590 1689 587 1666 589 # -name: POWER +name: Power type: raw frequency: 38000 duty_cycle: 0.330000 data: 4609 4601 539 1515 545 1511 539 1518 542 1514 546 1510 540 1517 543 2559 541 1515 545 1511 539 2563 537 1519 541 2561 539 1516 544 1512 548 2554 546 1510 540 1515 4604 4605 545 1509 541 1515 545 1538 512 1518 542 1514 546 1511 539 2563 537 1519 541 1515 545 2557 543 1513 547 2555 545 1510 540 1516 544 2559 541 1514 546 13748 9234 2298 545 52033 9228 2304 539 52041 9230 2303 540 # -name: SPEED+ +name: Speed_up type: raw frequency: 38000 duty_cycle: 0.330000 data: 4605 4603 547 1508 541 1515 545 1511 539 1518 542 1514 546 1511 539 2562 538 1518 542 1515 545 1511 538 2564 547 1509 541 1517 543 1513 547 2555 545 2556 544 1512 4607 4603 547 1508 542 1515 545 1511 539 1518 542 1514 546 1511 538 2564 546 1510 539 1517 543 1514 546 2557 543 1513 547 1510 540 1517 543 2559 541 2561 539 13755 9237 2297 546 52031 9229 2306 547 52033 9237 2297 546 # -name: MODE +name: Mode type: raw frequency: 38000 duty_cycle: 0.330000 data: 4608 4604 546 1509 541 1516 544 1513 547 1509 540 1516 544 1513 547 2555 545 1512 537 2565 545 1511 539 1518 542 2561 539 1516 544 1513 547 1510 539 2563 537 1517 4612 4599 541 1514 546 1511 539 1518 542 1514 546 1511 539 1518 542 2561 539 1518 542 2561 539 1517 543 1514 546 2557 543 1513 547 1510 540 1516 544 2559 541 13755 9237 2298 545 52044 9237 2298 545 # -name: TIMER +name: Timer type: raw frequency: 38000 duty_cycle: 0.330000 data: 4606 4604 546 1509 541 1516 544 1512 548 1509 541 1516 544 1512 548 2554 546 1510 540 1517 543 2559 541 1515 545 2557 543 2558 542 1514 546 1511 539 1517 543 1512 4607 4601 539 1516 544 1513 547 1509 541 1516 544 1512 548 1508 542 2561 539 1516 544 1513 547 2555 545 1511 538 2589 522 2555 545 1511 539 1518 542 1515 545 13389 9233 2301 542 51673 9227 2306 547 # -name: ROTATE +name: Rotate type: raw frequency: 38000 duty_cycle: 0.330000 data: 1273 401 1272 426 416 1232 1273 427 1247 426 405 1242 442 1231 442 1231 1274 426 405 1242 431 1242 431 7968 1274 400 1273 426 416 1232 1273 426 1247 426 405 1241 432 1241 432 1241 1275 425 406 1267 406 1240 433 7967 1275 398 1275 424 407 1240 1276 424 1249 424 407 1239 434 1238 435 1238 1278 422 409 1237 436 1237 436 7963 1279 394 1279 420 411 1262 1243 430 1243 430 412 1234 439 1234 439 1233 1272 428 414 1232 441 1232 441 7958 1273 426 1248 426 405 1241 1275 426 1248 425 406 1266 407 1240 433 1240 1276 424 407 1265 408 1238 435 7965 1277 422 1251 423 408 1238 1278 423 1250 423 408 1264 409 1238 435 1264 1251 422 409 1264 409 1237 436 7964 1278 422 1251 422 409 1264 1251 422 1251 422 409 1263 410 1262 411 1262 1254 420 411 1262 411 1235 438 7961 1270 429 1244 429 413 1260 1245 428 1245 427 415 1258 415 1231 432 1241 1274 425 406 1267 406 1240 433 7965 1277 423 1250 423 408 1265 1250 423 1250 423 408 1264 409 1237 436 1237 1278 421 410 1262 411 1262 411 7961 1270 429 1244 429 413 1260 1245 429 1244 429 413 1260 413 1233 440 1259 1246 427 415 1259 414 1258 415 7959 1272 427 1246 427 415 1259 1246 427 1246 427 415 1257 406 1267 406 1241 1274 425 406 1266 407 1266 407 7965 1277 422 1251 422 409 1264 1251 421 1252 421 410 1262 411 1261 412 1235 1270 429 413 1260 413 1233 440 7958 1273 426 1247 425 406 1267 1249 425 1248 424 407 1266 407 1265 408 1265 1250 423 408 1264 409 1263 410 7962 1280 420 1253 420 411 1261 1244 430 1243 429 413 1259 414 1232 441 1231 1274 427 415 1257 406 1240 433 7965 1277 423 1250 423 408 1264 1251 422 1251 422 409 1262 411 1235 438 1235 1280 420 411 1260 413 1232 441 7957 1274 426 1247 425 406 1266 1250 425 1248 424 407 1265 408 1238 435 1264 1251 423 408 1263 410 1236 437 # Osc -name: ROTATE +name: Rotate type: raw frequency: 38000 duty_cycle: 0.330000 data: 1338 374 1311 374 464 1194 1339 374 1311 374 464 1194 492 1194 492 1194 520 1165 1368 346 492 1167 519 7918 1364 347 1337 348 490 1195 1336 351 1333 352 486 1200 486 1201 485 1201 486 1201 1332 353 485 1201 485 7952 1332 353 1332 353 485 1200 1333 353 1332 353 485 1201 485 1201 485 1201 485 1201 1332 354 485 1201 485 7954 1331 354 1331 354 485 1201 1332 354 1331 354 485 1201 485 1202 485 1202 485 1202 1331 354 485 1201 485 7954 1331 354 1331 354 484 1202 1331 355 1330 355 483 1202 484 1203 483 1203 484 1203 1330 355 484 1203 483 # -name: SPEED+ +name: Speed_up type: raw frequency: 38000 duty_cycle: 0.330000 data: 1280 394 1280 420 411 1236 1269 430 1254 419 412 1235 438 1234 439 1233 440 1233 440 1233 1272 427 415 8311 1279 395 1278 420 411 1236 1269 430 1243 430 412 1234 439 1234 439 1233 440 1233 440 1233 1272 427 415 8312 1277 396 1277 422 409 1264 1252 421 1252 421 410 1236 437 1235 438 1233 440 1259 414 1259 1246 427 415 8312 1277 422 1251 423 408 1264 1251 423 1250 423 408 1238 435 1237 436 1237 436 1263 410 1237 1278 421 410 8315 1274 425 1248 425 406 1240 1276 424 1249 424 407 1265 408 1238 435 1264 409 1237 436 1237 1279 421 410 8318 1271 402 1271 428 414 1233 1272 427 1246 427 415 1231 432 1241 432 1240 433 1240 433 1240 1276 424 407 8319 1271 429 1245 428 414 1233 1272 428 1245 427 415 1231 442 1231 432 1240 433 1240 433 1239 1277 423 408 8318 1271 401 1272 427 415 1232 1273 427 1246 426 405 1267 406 1240 433 1239 434 1238 435 1238 1278 422 409 8317 1272 401 1272 426 405 1242 1274 426 1248 425 406 1240 433 1239 434 1238 435 1238 435 1238 1278 421 410 8317 1272 401 1272 426 405 1242 1274 425 1249 425 406 1240 434 1239 434 1238 435 1238 435 1238 1278 421 410 8316 1273 400 1273 426 405 1241 1275 425 1248 425 406 1239 434 1239 434 1238 435 1238 435 1238 1278 421 410 # -name: POWER +name: Power type: raw frequency: 38000 duty_cycle: 0.330000 data: 1341 395 1311 395 455 1220 1341 395 1311 396 454 1248 456 1248 457 1248 456 1247 457 1247 457 1247 1338 7184 1335 399 1307 399 450 1254 1307 399 1307 400 449 1255 450 1255 450 1254 450 1254 450 1254 450 1254 1307 8332 1306 401 1306 400 449 1256 1306 400 1306 401 449 1255 450 1255 449 1255 449 1255 449 1255 449 1255 1306 7214 1306 400 1307 400 450 1255 1306 400 1306 400 450 1255 449 1255 449 1255 449 1255 449 1255 449 1256 1306 8333 1306 401 1307 401 449 1256 1307 402 1306 402 448 1256 449 1256 448 1256 448 1256 448 1256 448 1256 1307 7215 1305 401 1306 402 448 1256 1306 402 1305 402 448 1257 447 1257 447 1257 447 1256 448 1256 448 1257 1305 8333 1304 402 1305 402 448 1257 1304 402 1304 403 447 1257 447 1257 448 1257 447 1257 447 1257 447 1257 1304 7216 1304 403 1303 403 446 1257 1304 403 1304 403 446 1258 447 1258 446 1257 447 1257 447 1258 447 1257 1304 8334 1304 402 1305 403 446 1257 1304 403 1303 403 447 1258 446 1257 448 1258 446 1258 446 1258 446 1258 1303 7217 1303 404 1303 404 445 1259 1302 404 1302 428 421 1259 446 1283 421 1259 445 1283 421 1283 421 1284 1278 8361 1277 429 1278 429 420 1284 1278 429 1277 429 420 1284 420 1284 420 1284 420 1284 420 1284 419 1285 1277 7243 1277 429 1277 429 421 1284 1277 429 1277 429 420 1284 420 1284 420 1284 420 1284 420 1284 420 1284 1277 8361 1277 430 1276 430 420 1285 1276 430 1277 430 419 1285 419 1285 419 1285 420 1284 420 1285 420 1285 1276 7244 1276 431 1276 430 419 1286 1276 430 1276 431 418 1286 418 1286 418 1286 418 1286 418 1285 419 1285 1276 8363 1275 431 1276 431 418 1286 1275 431 1276 432 417 1286 418 1286 418 1286 418 1286 419 1286 418 1286 1275 7246 1275 432 1275 432 417 1288 1274 457 1249 457 392 1312 392 1312 392 1289 415 1312 392 1312 392 1313 1249 8390 1248 458 1249 458 391 1313 1249 458 1248 458 391 1313 391 1314 390 1313 391 1314 390 1314 390 1314 1248 7273 1247 459 1223 484 390 1315 1247 460 1222 510 339 1365 364 1315 365 1339 390 1315 388 1341 339 1340 1222 8415 1222 484 1222 510 339 1365 1197 510 1197 510 339 1365 340 1365 339 1365 339 1365 339 1365 339 1365 1197 7324 1196 511 1196 511 338 1366 1196 511 1195 511 338 1366 338 1367 337 1367 337 1367 337 1367 337 1367 1195 # -name: SPEED+ +name: Speed_up type: raw frequency: 38000 duty_cycle: 0.330000 data: 1341 368 1338 392 457 1219 1370 364 1341 364 485 1190 540 1164 513 1190 513 1191 512 1194 1365 366 481 8031 1338 370 1336 371 477 1226 1335 371 1335 371 477 1226 477 1226 477 1226 477 1226 477 1226 1334 371 477 9153 1334 371 1334 371 477 1226 1334 371 1335 371 477 1227 476 1227 476 1227 476 1227 476 1227 1334 372 476 8036 1334 372 1333 372 476 1227 1333 372 1333 372 476 1227 476 1227 476 1227 476 1227 476 1227 1334 373 475 9154 1334 373 1333 373 475 1228 1332 373 1332 373 475 1229 475 1228 475 1229 474 1229 474 1229 1331 374 474 8038 1331 374 1332 374 474 1229 1331 374 1331 398 450 1253 450 1253 450 1253 450 1253 450 1253 1307 398 450 9179 1307 398 1307 398 450 1253 1307 399 1306 398 450 1254 449 1254 449 1253 450 1254 449 1254 1306 398 450 8063 1306 398 1307 399 449 1254 1306 399 1306 399 449 1254 449 1254 449 1254 449 1254 449 1254 1307 399 449 # -name: MODE +name: Mode type: raw frequency: 38000 duty_cycle: 0.330000 data: 1372 339 1369 363 486 1190 1374 363 1344 363 486 1190 515 1191 513 1191 513 1192 1370 365 483 1220 484 8036 1339 371 1337 371 478 1227 1337 371 1337 371 478 1227 478 1227 478 1227 478 1227 1336 371 478 1227 478 9159 1336 372 1336 371 478 1227 1336 371 1336 372 477 1227 478 1227 477 1227 477 1227 1336 372 477 1228 477 8041 1335 372 1335 372 477 1227 1336 372 1335 372 477 1228 477 1228 477 1228 477 1228 1335 373 476 1228 477 9160 1335 373 1334 373 476 1228 1335 373 1334 373 476 1229 475 1229 476 1229 475 1229 1334 374 475 1229 475 8042 1334 375 1331 398 451 1230 1333 398 1309 398 451 1254 450 1254 451 1253 451 1253 1308 398 450 1254 450 # -name: TIMER +name: Timer type: raw frequency: 38000 duty_cycle: 0.330000 data: 1342 366 1370 339 511 1191 1373 364 1343 364 511 1165 540 1165 514 1192 1371 364 484 1219 485 1220 484 8036 1339 370 1337 371 478 1227 1336 371 1336 371 478 1227 478 1227 478 1227 1336 372 477 1227 478 1227 478 9162 1336 372 1335 372 477 1228 1335 372 1335 373 476 1228 477 1228 477 1228 1336 372 477 1228 477 1228 476 8044 1336 372 1335 373 476 1228 1335 398 1309 398 451 1254 451 1254 451 1255 1308 400 449 1255 450 1256 449 9188 1306 403 1304 428 421 1260 1303 428 1279 429 419 1284 421 1284 420 1284 1279 429 420 1285 420 1284 420 8099 1276 457 1250 457 391 1313 1225 483 1224 484 364 1338 366 1338 392 1313 1225 484 364 1339 366 1339 390 9244 1225 509 1198 510 338 1366 1197 510 1197 537 311 1367 338 1393 311 1394 1169 591 256 11618 1170 539 1168 565 282 1395 1169 565 1142 538 310 1341 365 1312 419 1259 1305 400 449 1254 450 1255 449 9186 1307 400 1306 400 448 1255 1307 399 1307 400 448 1255 449 1255 449 1255 1307 400 448 1255 449 1255 449 8068 1306 400 1306 400 448 1256 1306 400 1306 401 447 1256 448 1256 448 1256 1306 401 447 1256 448 1257 447 # -name: POWER +name: Power type: raw frequency: 38000 duty_cycle: 0.330000 data: 170 535 1281 413 1276 418 436 1259 1275 423 1276 444 410 1258 431 1264 435 1260 439 1256 433 1262 437 1258 1276 6529 173 475 1280 414 1275 419 435 1260 1274 450 1249 419 435 1259 430 1265 434 1261 438 1257 432 1263 436 1259 1275 7177 1280 414 1275 445 410 1260 1274 450 1249 445 410 1259 430 1266 433 1262 437 1258 431 1264 435 1260 1274 # -name: SPEED+ +name: Speed_up type: raw frequency: 38000 duty_cycle: 0.330000 data: 1280 415 1274 447 407 1288 1256 442 1247 448 406 1288 411 1284 405 1291 408 1287 412 1283 1251 444 411 8009 1282 413 1276 445 409 1286 1248 450 1249 446 408 1286 403 1292 407 1262 437 1285 404 1291 1253 442 413 8007 1274 446 1253 442 402 1292 1252 447 1252 442 402 1292 407 1288 411 1284 405 1264 435 1286 1248 447 407 # -name: ROTATE +name: Rotate type: raw frequency: 38000 duty_cycle: 0.330000 data: 1278 444 1255 439 405 1289 1255 444 1255 439 405 1290 409 1259 1275 447 407 1288 411 1257 432 1263 436 8009 1282 440 1249 446 408 1286 1248 451 1248 446 408 1286 413 1256 1278 444 410 1284 405 1264 435 1261 438 8008 1283 439 1250 444 410 1284 1250 450 1249 445 409 1284 405 1265 1279 442 412 1282 407 1262 437 1258 431 8015 1276 445 1254 440 404 1292 1252 446 1253 441 403 1292 407 1288 1256 439 405 1290 409 1286 403 1292 407 8012 1279 416 1273 448 406 1289 1255 443 1246 449 405 1289 410 1285 1249 446 408 1287 412 1283 406 1289 410 # -name: TIMER +name: Timer type: raw frequency: 38000 duty_cycle: 0.330000 data: 1278 417 1282 439 405 1290 1254 444 1255 439 405 1289 410 1285 404 1292 1252 442 412 1283 406 1289 410 8010 1280 414 1275 446 408 1287 1247 451 1248 446 408 1286 413 1282 407 1263 1281 440 404 1291 408 1261 438 8007 1273 421 1278 443 411 1284 1249 449 1250 444 410 1258 431 1291 408 1288 1256 439 405 1289 410 1286 403 8017 1273 421 1278 443 411 1284 1249 449 1250 444 410 1285 404 1291 408 1262 1282 440 404 1264 435 1260 439 # -name: MODE +name: Mode type: raw frequency: 38000 duty_cycle: 0.330000 data: 1282 413 1276 445 409 1260 1274 450 1249 445 410 1259 430 1265 434 1261 438 1258 1276 445 409 1285 404 8017 1274 420 1279 442 412 1283 1251 448 1251 443 411 1283 406 1290 409 1260 439 1256 1278 443 411 1284 405 8015 1276 418 1281 440 404 1291 1253 446 1253 440 404 1291 408 1287 412 1283 406 1263 1281 440 404 1291 408 8011 1280 414 1275 446 408 1287 1247 452 1247 447 407 1261 438 1283 406 1289 410 1259 1275 447 407 1287 412 8006 1275 446 1253 441 403 1292 1252 447 1252 442 402 1292 407 1288 411 1284 405 1291 1253 442 402 1292 407 # -name: POWER +name: Power type: parsed protocol: NEC address: 30 00 00 00 command: 97 00 00 00 # -name: MODE +name: Mode type: parsed protocol: NEC address: 30 00 00 00 command: 87 00 00 00 # -name: SPEED+ +name: Speed_up type: parsed protocol: NEC address: 30 00 00 00 command: 86 00 00 00 # -name: TIMER +name: Timer type: parsed protocol: NEC address: 30 00 00 00 command: 9C 00 00 00 # -name: ROTATE +name: Rotate type: parsed protocol: NEC address: 30 00 00 00 command: 95 00 00 00 # -name: POWER +name: Power type: parsed protocol: NEC address: 00 00 00 00 command: 45 00 00 00 # -name: SPEED+ +name: Speed_up type: parsed protocol: NEC address: 00 00 00 00 command: 47 00 00 00 # -name: TIMER +name: Timer type: parsed protocol: NEC address: 00 00 00 00 command: 19 00 00 00 # -name: ROTATE +name: Rotate type: parsed protocol: NEC address: 00 00 00 00 command: 1C 00 00 00 # -name: POWER +name: Power type: raw frequency: 38000 duty_cycle: 0.330000 data: 2229 716 749 747 728 715 750 720 756 714 751 719 757 1447 751 719 756 714 751 1453 755 742 723 747 729 742 754 716 749 721 754 715 729 741 724 1454 754 1450 758 1445 753 1451 757 714 751 50967 2228 717 748 1455 753 51028 2198 746 730 1449 749 # -name: SPEED+ +name: Speed_up type: raw frequency: 38000 duty_cycle: 0.330000 data: 2225 719 756 741 724 720 755 715 750 720 755 716 749 1456 752 719 746 726 749 1456 731 741 755 1451 757 714 751 1455 753 718 757 1448 750 1456 752 720 755 715 750 721 754 1452 756 1449 759 51509 2201 743 732 1473 756 51069 2202 717 758 1448 750 # -name: SPEED- +name: Speed_dn type: raw frequency: 38000 duty_cycle: 0.330000 data: 2234 712 752 743 732 713 751 720 755 716 749 722 753 1453 754 716 759 712 752 1453 754 718 757 1449 758 713 751 1455 752 1454 753 718 757 741 723 748 727 745 730 1449 758 739 725 1455 752 51252 2234 713 751 1454 753 # -name: POWER +name: Power type: raw frequency: 38000 duty_cycle: 0.330000 data: 2229 714 750 747 727 717 757 713 751 719 755 715 749 1455 751 719 755 715 749 1455 751 1453 753 717 757 714 750 1454 752 718 756 714 750 746 728 742 722 722 752 1452 754 716 758 1445 751 50982 2229 716 727 1479 748 51048 2205 712 752 1450 756 # -name: POWER +name: Power type: raw frequency: 38000 duty_cycle: 0.330000 data: 2258 688 781 718 751 694 775 696 784 687 782 690 779 1427 782 690 779 693 776 1431 778 721 748 724 756 716 753 719 750 722 747 725 744 727 773 1407 781 1426 783 1425 774 1433 776 696 773 51015 2224 748 721 1458 783 51084 2249 697 783 1425 784 51089 2253 694 775 1432 756 # -name: POWER +name: Power type: raw frequency: 38000 duty_cycle: 0.330000 data: 2212 836 751 1591 749 825 752 817 750 1577 753 806 750 804 752 796 750 857 751 828 749 825 752 816 751 813 743 816 751 803 743 805 752 102392 2214 834 743 1599 751 823 744 825 752 1575 745 840 727 801 745 804 752 854 744 835 752 822 745 824 743 821 746 813 743 810 746 802 744 # -name: POWER +name: Power type: raw frequency: 38000 duty_cycle: 0.330000 data: 2214 838 748 1596 751 824 751 819 746 1584 753 807 747 807 747 803 751 857 750 830 745 830 745 825 750 814 751 810 745 1574 752 798 746 101740 2213 838 748 1597 750 824 751 819 746 1583 754 806 748 807 747 802 752 856 751 830 745 829 746 824 751 814 751 809 745 1574 753 797 747 # -name: ROTATE +name: Rotate type: raw frequency: 38000 duty_cycle: 0.330000 data: 2216 836 750 1594 754 821 754 816 749 1580 747 813 752 803 751 798 746 1626 753 827 748 1591 746 824 751 1578 749 811 754 1566 750 799 745 99411 2218 833 753 1591 746 829 746 823 752 1577 749 810 755 800 754 795 749 1623 745 835 751 1588 749 821 754 1574 752 807 747 1572 755 795 749 # -name: POWER +name: Power type: raw frequency: 38000 duty_cycle: 0.330000 data: 2219 732 750 729 753 722 749 1384 755 1374 755 705 746 708 753 697 754 754 749 731 751 723 749 721 750 715 746 713 748 1370 749 701 749 99627 2216 735 747 732 750 725 747 1387 753 1376 753 706 755 700 751 698 753 755 748 732 750 725 747 722 749 716 745 714 747 1372 747 702 749 # -name: TIMER +name: Timer type: raw frequency: 38000 duty_cycle: 0.330000 data: 2215 735 746 730 751 722 749 1383 745 1381 747 711 749 704 746 702 748 1422 748 730 751 722 749 720 751 712 748 1373 745 1372 746 702 748 102284 2218 732 749 729 752 720 751 1380 748 1378 750 709 751 701 749 700 750 1420 750 728 753 719 752 717 754 709 752 1370 748 1369 749 699 751 # -name: ROTATE +name: Rotate type: raw frequency: 38000 duty_cycle: 0.330000 data: 2221 729 752 725 746 727 754 1377 751 1375 753 706 755 699 751 697 753 753 749 729 752 1384 755 1377 751 713 747 711 749 1367 751 1361 746 101691 2216 734 747 731 750 723 748 1383 745 1381 747 711 749 705 745 703 747 759 754 725 746 1390 749 1383 756 708 752 706 754 1362 745 1366 752 # -name: POWER +name: Power type: raw frequency: 38000 duty_cycle: 0.330000 data: 2220 831 751 1618 729 820 751 818 753 1575 751 835 726 829 721 802 748 885 728 851 720 854 728 815 756 809 752 807 754 1565 750 825 725 101743 2220 830 752 1618 729 819 752 844 727 1574 752 835 726 802 748 801 749 884 729 850 721 827 755 815 746 845 726 806 755 1590 725 798 752 # -name: SPEED+ +name: Speed_up type: raw frequency: 38000 duty_cycle: 0.330000 data: 2218 857 725 1592 754 846 725 844 727 1574 752 834 727 827 723 826 724 883 720 1597 750 851 720 1586 750 840 721 1577 749 831 730 1557 748 99247 2221 854 728 1590 746 854 728 841 720 1583 753 832 729 825 725 824 726 881 722 1596 751 849 722 1585 751 839 722 1576 750 831 719 1568 747 # -name: SPEED- +name: Speed_dn type: raw frequency: 38000 duty_cycle: 0.330000 data: 2217 832 750 1594 753 821 750 819 752 1576 750 809 804 750 800 748 750 1622 756 1587 749 1589 747 1586 750 1578 748 1575 751 1568 747 802 748 101181 2218 831 751 1592 755 819 752 817 754 1574 752 808 753 801 749 800 751 1620 748 1596 751 1587 749 1584 752 1576 750 1574 752 1566 749 800 803 # -name: POWER +name: Power type: raw frequency: 38000 duty_cycle: 0.330000 data: 2274 662 756 711 749 718 752 715 797 669 801 1399 749 718 783 684 797 670 800 1400 748 720 750 716 754 713 747 720 750 718 752 714 777 718 752 1448 752 714 756 711 749 1450 750 1423 777 51569 2192 718 752 1447 753 50954 2223 712 748 1423 798 50911 2245 661 746 1451 749 50917 2218 715 755 1415 754 50965 2191 716 754 1445 755 50923 2223 710 750 1421 800 50893 2190 717 753 1445 776 50902 2242 664 796 1402 777 50907 2217 717 753 1418 803 50880 2223 710 750 1421 800 # -name: TIMER +name: Timer type: raw frequency: 38000 duty_cycle: 0.330000 data: 2225 712 747 719 751 716 754 713 757 711 748 1451 748 718 752 715 754 712 747 1451 748 718 752 716 754 1445 754 1444 724 1449 750 716 754 713 746 1453 746 720 749 1450 749 1451 727 1446 753 50693 2219 717 752 1445 754 50927 2194 714 756 1442 747 # -name: POWER +name: Power type: raw frequency: 38000 duty_cycle: 0.330000 data: 2216 733 744 734 754 1382 751 1381 752 712 744 714 753 700 746 702 754 753 745 733 755 719 748 720 747 717 750 709 747 706 750 1361 751 99476 2211 738 749 729 748 1389 754 1377 745 718 748 710 746 707 749 699 747 760 748 730 747 726 751 718 748 715 752 706 750 703 753 1359 753 49283 2217 670 745 1350 751 50661 2212 676 749 1345 746 # -name: TIMER +name: Timer type: raw frequency: 38000 duty_cycle: 0.330000 data: 2213 737 751 727 750 1387 746 1385 748 716 751 707 749 704 752 696 750 1420 754 724 753 720 747 721 746 718 749 1373 749 1367 745 703 753 102141 2215 735 753 726 751 1385 747 1384 748 715 752 706 750 704 752 695 751 1419 755 723 754 720 747 721 746 718 749 1399 723 1367 755 693 753 # -name: POWER +name: Power type: raw frequency: 38000 duty_cycle: 0.330000 data: 33 2223 753 725 720 748 750 728 743 725 746 722 1458 750 749 750 722 726 747 721 1460 748 724 755 744 724 721 747 724 754 744 724 747 752 720 748 1458 750 722 756 715 753 718 750 1456 752 51488 2221 727 721 1460 748 51156 2203 744 724 1456 752 # -name: TIMER +name: Timer type: raw frequency: 38000 duty_cycle: 0.330000 data: 33 2225 718 750 719 749 721 747 722 746 723 745 1458 750 720 748 722 726 744 724 1452 756 741 727 742 726 1451 746 1457 750 1454 754 716 752 717 720 1483 725 745 723 1454 754 1450 747 1456 752 50811 2199 744 745 1433 754 51049 2229 715 743 1435 752 # -name: SPEED+ +name: Speed_up type: raw frequency: 38000 duty_cycle: 0.330000 data: 2221 721 727 1450 779 1452 756 714 744 1487 721 723 756 714 754 715 774 774 726 1505 724 772 748 1482 726 770 751 1454 754 1477 721 1484 745 101867 2197 745 723 1453 776 1455 722 748 720 1483 756 713 755 714 744 725 775 774 726 1478 751 771 729 1475 754 769 720 1483 756 1448 750 1481 727 50476 2201 714 755 1448 781 50602 2221 720 748 1454 775 50604 2250 743 694 1456 773 50628 2226 715 743 1433 775 50652 2191 748 720 1430 778 # -name: SPEED- +name: Speed_dn type: raw frequency: 38000 duty_cycle: 0.330000 data: 2193 750 729 1421 777 1454 754 715 753 1478 751 719 728 715 753 716 773 1510 729 1501 728 1477 752 1505 755 1475 754 1477 721 749 751 772 696 102110 2246 748 720 1455 774 1430 747 723 746 1484 724 745 723 720 748 721 779 1477 752 1478 751 1480 749 1508 752 1478 751 1479 729 741 748 748 721 50743 2195 747 721 1454 775 # -name: TIMER +name: Timer type: raw frequency: 38000 duty_cycle: 0.330000 data: 2247 750 729 1447 782 1450 748 722 726 1506 723 720 748 722 757 713 776 772 728 769 751 1505 755 1476 753 1452 756 740 749 747 753 1452 756 101517 2220 749 719 1457 772 1433 754 715 753 1478 719 750 729 715 753 716 773 776 724 772 748 1508 752 1479 750 1481 727 769 731 739 750 1454 754 50114 2228 742 726 1450 779 50645 2197 746 722 1454 775 # -name: POWER +name: Power type: raw frequency: 38000 duty_cycle: 0.330000 data: 1275 434 1253 430 408 1275 1251 431 1257 427 411 1272 415 1241 436 1248 439 1244 433 1250 437 1247 1279 7142 1276 433 1255 428 410 1247 1279 430 1247 435 414 1269 408 1249 438 1272 415 1241 436 1248 439 1244 1282 8244 1274 434 1253 429 409 1274 1252 430 1247 435 414 1242 435 1275 412 1270 407 1277 411 1246 441 1242 1274 7146 1282 426 1251 431 407 1276 1250 432 1255 426 412 1271 406 1276 411 1272 415 1242 435 1248 439 1244 1282 8243 1275 433 1255 428 410 1272 1254 429 1248 434 415 1267 410 1273 414 1269 408 1275 412 1245 432 1251 1275 7144 1273 435 1252 430 408 1274 1252 430 1247 436 413 1269 408 1249 438 1245 442 1267 410 1274 413 1270 1256 8241 1277 431 1257 425 413 1270 1256 425 1252 430 408 1275 412 1270 407 1276 411 1246 441 1267 410 1247 1279 7140 1277 431 1256 426 412 1270 1256 425 1252 430 408 1274 413 1270 407 1276 411 1245 442 1267 410 1247 1279 8245 1273 435 1252 430 408 1274 1252 430 1247 435 414 1269 408 1275 412 1270 407 1277 410 1246 441 1268 1248 7145 1273 435 1252 430 408 1274 1252 430 1247 435 414 1242 435 1248 439 1244 433 1250 437 1246 441 1242 1274 8249 1279 403 1274 434 415 1242 1274 434 1253 429 409 1247 440 1242 435 1248 439 1244 433 1250 437 1246 1280 7138 1279 403 1274 434 415 1268 1247 434 1253 429 409 1246 441 1268 409 1248 439 1244 433 1250 437 1245 1281 8241 1277 405 1283 426 412 1270 1256 426 1251 430 408 1274 413 1270 407 1276 411 1271 416 1267 410 1246 1280 7138 1279 429 1248 434 415 1268 1247 434 1274 407 442 1240 416 1267 410 1247 440 1243 434 1249 438 1271 1255 # -name: MODE +name: Mode type: raw frequency: 38000 duty_cycle: 0.330000 data: 1279 430 1247 436 413 1270 1256 427 1250 432 406 1277 410 1273 414 1269 408 1275 1251 432 406 1277 410 7983 1284 425 1252 430 408 1275 1251 431 1256 426 412 1270 407 1250 437 1272 415 1242 1274 435 414 1270 407 9092 1275 433 1254 428 410 1273 1253 428 1249 434 415 1268 409 1274 413 1269 408 1276 1250 432 406 1277 410 7984 1283 425 1252 431 407 1275 1251 431 1256 426 412 1270 407 1276 411 1272 415 1241 1275 435 414 1269 408 9090 1277 431 1256 426 412 1270 1256 426 1251 431 407 1275 412 1270 407 1276 411 1272 1254 428 410 1273 414 7978 1278 430 1247 435 414 1269 1247 435 1252 430 408 1274 413 1243 434 1275 412 1271 1255 427 411 1272 415 9082 1275 434 1253 428 410 1273 1253 428 1249 433 405 1277 410 1272 415 1268 409 1274 1252 430 408 1275 412 7980 1276 432 1255 427 411 1271 1255 427 1250 432 406 1276 411 1271 416 1267 410 1247 1279 430 408 1275 412 9085 1282 426 1251 431 407 1276 1250 432 1255 426 412 1270 407 1276 411 1272 415 1268 1247 435 414 1269 408 7985 1282 427 1250 432 406 1277 1249 433 1254 428 410 1272 415 1267 410 1274 413 1269 1257 426 412 1271 406 # -name: POWER +name: Power type: raw frequency: 38000 duty_cycle: 0.330000 data: 9204 4469 604 562 604 562 604 562 604 563 603 564 602 565 601 567 599 568 598 1642 598 1643 607 1634 606 1634 606 1634 606 1635 605 1636 604 1637 603 1638 602 565 601 1641 599 568 598 569 607 560 606 1635 605 588 578 562 604 1637 603 563 603 1638 602 1639 601 1641 599 594 572 1643 607 39280 9217 2212 601 # -name: SPEED+ +name: Speed_up type: raw frequency: 38000 duty_cycle: 0.330000 data: 9225 4468 605 563 603 564 602 565 601 566 600 568 598 569 597 570 606 561 605 1636 604 1638 602 1640 600 1641 599 1643 607 1634 606 1636 603 1637 603 1639 601 1640 600 1641 599 595 571 568 598 569 597 1645 605 588 578 562 604 563 603 564 602 1639 601 1641 599 1643 597 596 580 1635 605 # -name: MODE +name: Mode type: raw frequency: 38000 duty_cycle: 0.330000 data: 9214 4475 598 568 598 597 579 560 606 588 578 589 577 563 603 590 576 564 602 1666 574 1667 573 1641 599 1669 571 1643 597 1644 606 1635 605 1663 577 563 603 564 602 591 575 592 574 592 574 593 573 1668 572 594 572 1669 571 1669 571 1670 570 1644 606 1635 605 1636 604 590 576 1637 603 # -name: TIMER +name: Timer type: raw frequency: 38000 duty_cycle: 0.330000 data: 9275 4475 608 560 606 563 603 565 601 568 598 570 606 563 603 565 601 567 599 1645 605 1638 602 1642 598 1645 605 1639 601 1642 598 1645 605 1637 603 1641 599 569 607 561 605 1639 601 1642 608 560 606 563 603 565 601 568 598 1644 606 1637 603 565 601 567 599 1644 606 1636 604 1639 601 # -name: POWER +name: Power type: raw frequency: 38000 duty_cycle: 0.330000 data: 1279 428 1246 434 413 1265 1246 434 1250 430 407 1271 413 1240 434 1245 439 1240 434 1245 439 1240 1271 7282 1276 430 1244 436 411 1267 1255 426 1248 432 405 1248 437 1243 431 1248 436 1243 431 1248 436 1243 1279 7276 1272 434 1250 430 407 1271 1251 430 1244 436 411 1267 407 1247 437 1241 433 1246 438 1241 433 1246 1276 7279 1279 427 1247 433 404 1248 1274 433 1251 429 408 1271 413 1239 435 1245 440 1239 435 1244 430 1249 1273 7282 1276 430 1244 436 411 1267 1244 436 1248 432 405 1273 411 1242 432 1247 437 1241 433 1247 437 1241 1281 7274 1274 432 1252 428 409 1270 1252 428 1246 434 413 1266 408 1244 441 1239 435 1244 440 1239 435 1244 1278 # -name: ROTATE +name: Rotate type: raw frequency: 38000 duty_cycle: 0.330000 data: 1275 405 1279 401 436 1243 1279 401 1273 407 440 1238 436 1244 1278 429 408 1244 440 1239 435 1244 440 8113 1272 434 1250 430 407 1246 1276 430 1254 426 411 1242 432 1247 1275 432 405 1247 437 1242 432 1247 437 8115 1280 426 1248 432 405 1248 1274 433 1251 428 409 1244 440 1239 1272 434 413 1239 435 1245 439 1239 435 8118 1277 429 1245 435 412 1240 1271 436 1248 431 406 1247 437 1242 1280 427 410 1242 432 1247 437 1242 432 8121 1274 406 1278 428 409 1244 1278 402 1272 408 439 1240 434 1245 1277 404 433 1246 438 1240 434 1245 439 8114 1281 399 1275 405 432 1247 1275 406 1278 401 436 1244 430 1249 1273 407 440 1240 434 1245 439 1239 435 # -name: SPEED+ +name: Speed_up type: raw frequency: 38000 duty_cycle: 0.330000 data: 1248 412 1274 438 405 1284 1245 445 1251 435 408 1281 405 1282 404 1285 411 1251 435 1253 1276 437 406 8011 1242 445 1251 435 408 1255 1274 442 1244 443 410 1278 408 1280 406 1282 435 1254 411 1277 1242 445 408 8011 1242 443 1243 444 409 1279 1250 440 1246 441 412 1277 409 1279 407 1281 405 1282 404 1286 1243 443 410 8008 1245 442 1244 443 410 1278 1251 440 1246 441 402 1286 410 1278 408 1280 406 1256 430 1284 1276 411 411 8006 1247 439 1247 439 404 1285 1244 446 1250 437 406 1282 404 1283 403 1285 411 1278 408 1254 1275 438 405 8013 1251 436 1250 410 433 1282 1247 443 1243 443 410 1279 407 1281 405 1282 404 1258 438 1276 1243 444 409 7981 1272 414 1272 441 412 1250 1269 448 1248 438 405 1257 429 1259 437 1277 429 1232 433 1281 1248 412 431 7986 1267 446 1250 436 407 1255 1274 443 1243 443 410 1253 433 1280 406 1282 404 1258 428 1287 1273 387 435 7981 1272 414 1272 415 438 1276 1243 447 1249 411 432 1282 435 1228 489 1198 436 1278 408 1280 1249 411 432 # -name: POWER +name: Power type: raw frequency: 38000 duty_cycle: 0.330000 data: 1281 410 1289 429 415 1276 1257 435 1264 428 416 1248 440 1250 438 1253 435 1282 1261 404 440 1277 411 8127 1288 404 1284 434 410 1281 1262 403 1285 432 412 1280 408 1256 443 1249 439 1278 1265 401 443 1275 413 8125 1289 429 1260 432 412 1253 1291 401 1287 431 413 1251 437 1253 446 1246 442 1249 1284 435 409 1256 443 8122 1282 437 1262 429 415 1277 1256 409 1290 428 416 1249 439 1251 437 1254 445 1247 1286 433 411 1254 445 8120 1283 409 1290 428 416 1275 1258 434 1254 437 418 1274 414 1249 439 1252 436 1281 1262 404 440 1251 437 8128 1286 432 1256 436 408 1257 1286 405 1283 435 409 1282 417 1247 441 1250 438 1253 1290 428 416 1249 439 # -name: ROTATE +name: Rotate type: raw frequency: 38000 duty_cycle: 0.330000 data: 1286 406 1282 438 416 1275 1257 435 1263 430 1258 434 410 1282 416 1276 412 1254 444 1248 1284 436 1262 7278 1288 403 1285 435 408 1257 1285 433 1255 438 1260 431 413 1279 409 1283 415 1250 438 1254 1288 405 1283 7285 1281 411 1287 432 412 1253 1289 430 1258 435 1263 429 415 1250 438 1254 444 1248 440 1252 1290 429 1259 7283 1283 408 1290 428 416 1249 1283 436 1262 431 1257 435 408 1256 442 1250 438 1255 443 1248 1284 436 1262 7278 1288 430 1258 435 408 1256 1286 433 1255 437 1261 431 413 1252 436 1282 416 1249 439 1254 1288 404 1284 7282 1284 408 1290 428 416 1249 1283 436 1262 430 1258 434 410 1255 443 1249 439 1253 445 1247 1285 408 1290 # -name: TIMER +name: Timer type: raw frequency: 38000 duty_cycle: 0.330000 data: 1276 403 1271 435 412 1241 1270 409 1276 431 1254 427 410 1242 1280 427 1247 433 404 1249 1273 407 430 8123 1273 433 1251 429 408 1245 1277 429 1245 435 1250 430 407 1272 1250 430 1255 426 411 1268 1254 426 411 8117 1279 401 1273 433 404 1249 1273 433 1251 429 1245 435 412 1240 1271 435 1249 431 406 1246 1276 431 406 8122 1274 406 1278 427 410 1270 1252 428 1246 434 1251 429 408 1271 1251 403 1271 436 411 1267 1244 436 411 8116 1279 427 1247 433 404 1275 1247 433 1251 429 1245 434 413 1266 1245 435 1250 430 407 1272 1250 431 406 8121 1274 431 1254 427 410 1269 1253 427 1247 433 1251 429 408 1271 1251 429 1245 434 413 1266 1245 435 412 # -name: POWER +name: Power type: raw frequency: 38000 duty_cycle: 0.330000 data: 1280 457 1229 426 468 1236 1282 456 1230 427 468 1236 470 1235 471 1235 471 1235 471 1235 492 1240 1289 7171 1290 422 1284 399 464 1238 1291 422 1284 399 464 1239 467 1238 468 1238 468 1238 489 1217 500 1233 1285 7176 1285 426 1280 403 471 1232 1286 426 1281 403 471 1232 464 1242 496 1210 496 1237 469 1236 470 1236 1282 7206 1286 399 1287 422 441 1262 1287 398 1288 449 435 1215 491 1241 465 1240 466 1240 466 1240 466 1240 1289 7199 1283 429 1257 426 469 1235 1283 428 1258 426 469 1234 473 1234 472 1234 472 1233 474 1233 463 1243 1306 7182 1289 448 1258 398 465 1238 1291 448 1258 425 438 1239 467 1238 468 1238 468 1237 490 1216 490 1242 1287 # -name: ROTATE +name: Rotate type: raw frequency: 38000 duty_cycle: 0.330000 data: 1289 448 1227 454 441 1238 1280 457 1228 454 441 1238 468 1239 1289 448 436 1215 491 1242 475 1233 473 8012 1281 457 1249 406 468 1237 1281 457 1260 396 467 1238 468 1239 1290 448 436 1242 475 1233 473 1234 472 8013 1291 421 1285 397 466 1238 1291 421 1285 398 465 1239 467 1240 1288 423 472 1233 473 1233 473 1234 472 8014 1289 449 1257 398 465 1239 1289 422 1284 398 465 1239 467 1240 1309 403 471 1233 473 1234 472 1235 471 8015 1309 402 1283 426 437 1241 1308 403 1283 427 436 1241 496 1237 1281 404 470 1235 471 1235 471 1236 491 8021 1282 402 1284 452 443 1235 1283 402 1284 452 443 1209 497 1236 1282 402 472 1233 463 1243 495 1212 494 8019 1284 427 1258 450 445 1233 1285 426 1259 450 444 1233 473 1233 1285 426 437 1240 497 1209 497 1236 470 8016 1288 450 1225 431 464 1241 1288 451 1255 402 472 1232 474 1232 1286 452 443 1235 523 1183 471 1235 471 # -name: SPEED+ +name: Speed_up type: raw frequency: 38000 duty_cycle: 0.330000 data: 1286 424 1251 430 465 1241 1287 423 1252 457 437 1241 465 1242 464 1243 474 1234 472 1235 1314 423 440 8017 1286 451 1255 401 462 1242 1286 452 1254 402 472 1232 474 1233 473 1234 472 1234 493 1241 1287 424 439 8014 1289 422 1284 426 437 1241 1287 451 1255 403 471 1234 472 1234 472 1235 492 1215 491 1242 1286 399 464 8018 1285 426 1280 403 471 1234 1284 454 1252 404 470 1235 471 1236 491 1215 491 1243 526 1181 1285 427 436 8019 1315 423 1262 395 468 1236 1313 400 1286 424 439 1238 489 1218 499 1235 471 1236 470 1236 1282 430 464 8019 1284 401 1284 426 468 1236 1282 404 1281 456 438 1240 466 1240 466 1241 465 1241 465 1242 1286 426 468 8015 1288 424 1261 448 436 1242 1286 426 1259 451 444 1234 472 1234 472 1235 471 1235 471 1236 1282 456 438 # -name: POWER +name: Power type: raw frequency: 38000 duty_cycle: 0.330000 data: 9090 4295 561 1708 570 561 563 569 565 567 567 565 569 563 561 570 564 568 566 565 569 1701 567 1702 566 1703 565 1705 563 1706 562 1707 561 1708 570 1699 569 1700 568 564 570 562 562 570 564 567 567 565 569 1700 568 563 591 563 561 1708 571 1699 569 1700 568 1702 566 1703 565 565 569 40667 9086 2139 562 97339 9092 2132 569 # -name: TIMER +name: Timer type: raw frequency: 38000 duty_cycle: 0.330000 data: 9092 4292 563 1732 536 569 565 567 567 591 543 589 534 597 537 595 539 566 568 564 570 1699 569 1700 568 1702 566 1703 565 1705 563 1707 561 1708 570 1700 568 1701 567 591 543 1700 568 564 570 588 535 570 564 1732 556 571 563 568 566 1703 565 567 567 1702 566 1703 565 1705 563 567 567 40657 9086 2135 566 # -name: SPEED+ +name: Speed_up type: raw frequency: 38000 duty_cycle: 0.330000 data: 9091 4292 564 1706 562 569 565 567 567 565 569 562 561 570 564 568 566 565 569 562 561 1708 570 1698 570 1700 568 1728 540 1703 565 1705 563 1706 562 1708 570 1699 569 1700 568 563 571 561 562 569 565 566 568 1701 587 566 568 563 571 561 562 1706 562 1707 561 1708 570 1699 569 562 561 # -name: POWER +name: Power type: raw frequency: 38000 duty_cycle: 0.330000 data: 9000 4466 564 1681 564 566 572 559 569 561 567 564 564 567 571 558 570 560 568 563 565 1678 567 1679 566 1681 564 1682 564 1679 566 1678 567 1686 570 1676 569 1674 571 559 569 563 565 1679 566 564 564 566 572 550 567 563 565 565 563 1679 566 1677 568 563 565 1678 567 1676 569 1681 564 1680 565 1680 565 565 563 569 569 1674 571 560 567 563 565 555 573 558 570 559 569 1674 571 1670 565 564 564 1678 567 1676 569 1675 570 12978 9003 2207 566 96147 9000 2203 570 # -name: TIMER +name: Timer type: raw frequency: 38000 duty_cycle: 0.330000 data: 9005 4459 570 1701 544 560 568 563 565 566 572 559 569 563 565 566 572 559 569 561 567 1678 567 1676 569 1675 570 1673 572 1671 564 1680 565 1685 571 1671 564 1677 568 561 567 562 566 564 564 565 563 565 563 557 571 557 571 557 571 1670 565 1678 567 1674 571 1668 567 1671 564 1686 570 1670 565 1675 570 559 569 560 568 561 567 562 566 563 565 553 564 563 565 564 564 1677 569 1673 573 1671 564 1678 567 1674 571 1671 564 13005 8998 2203 570 96194 8995 2204 569 # -name: ROTATE +name: Rotate type: raw frequency: 38000 duty_cycle: 0.330000 data: 9004 4451 568 1683 573 558 570 561 567 565 563 568 570 560 568 562 566 564 564 566 572 1680 565 1688 568 1685 571 1685 571 1684 572 1683 573 1674 571 1681 564 567 571 1679 566 1686 570 561 566 565 563 567 571 551 566 563 565 1690 566 565 563 569 569 1684 572 1682 563 1690 566 1681 564 1689 567 564 564 1689 567 1687 569 563 565 566 572 559 569 551 566 563 565 1684 572 558 570 560 567 1682 563 1687 569 1683 562 1688 568 12989 8992 2208 565 # -name: MODE +name: Mode type: raw frequency: 38000 duty_cycle: 0.330000 data: 9005 4457 572 1673 572 559 569 561 567 563 565 566 562 567 571 558 570 560 568 562 566 1676 569 1673 572 1698 537 1708 537 1704 541 1703 542 1708 537 567 571 1669 566 1701 544 558 570 560 568 561 567 564 564 557 571 1671 564 565 563 566 572 1670 565 1703 542 1673 562 1678 567 1683 562 566 562 1677 568 1701 544 559 569 561 567 563 565 565 563 557 571 1668 567 563 565 563 565 1676 569 1699 546 1669 566 1678 567 1676 569 # -name: POWER +name: Power type: parsed protocol: NEC address: 30 00 00 00 command: 8C 00 00 00 # -name: SPEED- +name: Speed_dn type: parsed protocol: NEC address: 30 00 00 00 command: 83 00 00 00 # -name: SPEED+ +name: Speed_up type: parsed protocol: NEC address: 30 00 00 00 command: 85 00 00 00 # -name: POWER +name: Power type: raw frequency: 38000 duty_cycle: 0.330000 data: 8958 4439 570 1663 563 561 562 563 560 564 569 556 567 557 566 558 565 559 564 560 563 1669 567 1663 563 1670 566 1665 561 1670 566 1666 560 1680 567 1665 561 1670 566 558 565 560 563 1669 567 557 566 559 564 552 561 563 560 565 568 1663 563 1668 568 556 567 1665 561 1670 566 1674 562 1668 568 1663 563 561 562 562 561 1670 566 558 565 559 564 552 561 563 560 564 569 1661 565 1667 569 555 568 1664 562 1668 568 1663 563 12896 8966 2197 565 95701 8962 2200 562 95719 8975 2194 568 95705 8970 2195 567 95693 8970 2196 566 # -name: TIMER +name: Timer type: raw frequency: 38000 duty_cycle: 0.330000 data: 8965 4443 566 1668 568 557 566 559 564 562 561 564 569 583 540 559 564 561 562 563 560 1673 563 1671 565 1669 567 1666 560 1673 563 1670 566 1676 560 1673 563 1670 566 558 565 561 562 564 569 556 567 559 564 553 560 565 568 558 565 1668 568 1666 570 1663 563 1670 566 1667 569 1671 565 1668 568 1665 561 564 569 557 566 559 564 562 561 564 569 547 566 560 563 562 561 1672 564 1669 567 1666 570 1664 562 1671 565 1668 568 12942 8972 2198 564 95779 8964 2201 561 # -name: MODE +name: Mode type: raw frequency: 38000 duty_cycle: 0.330000 data: 8970 4439 570 1665 561 564 569 556 567 558 565 561 562 563 560 566 567 557 566 559 564 1669 567 1667 569 1665 561 1672 564 1670 566 1668 569 1674 562 563 560 1673 563 1671 565 561 562 564 569 556 567 559 564 553 560 1673 563 563 560 566 567 1667 569 1664 562 1672 564 1669 567 1676 560 566 567 1667 569 1664 562 563 570 555 568 558 565 560 563 553 560 1674 562 563 560 565 569 1667 570 1664 562 1671 565 1667 569 1663 563 12935 8969 2204 568 # -name: ROTATE +name: Rotate type: raw frequency: 38000 duty_cycle: 0.330000 data: 8963 4430 569 1673 563 561 562 562 561 564 570 555 568 557 566 559 564 561 562 563 560 1680 567 1674 562 1680 567 1675 561 1681 566 1676 561 1671 565 1675 562 563 560 1682 565 1678 569 557 566 559 564 562 561 555 568 557 566 1675 562 564 569 555 568 1674 563 1678 569 1673 564 1670 566 1675 561 563 570 1672 564 1677 570 555 568 558 565 560 563 552 561 564 559 1682 565 560 563 563 560 1681 566 1675 561 1681 566 1676 561 12950 8975 2195 567 95870 8966 2201 561 # -name: SPEED+ +name: Speed_up type: raw frequency: 38000 duty_cycle: 0.330000 data: 8973 4429 570 1673 563 562 561 565 568 557 566 559 564 561 562 564 569 557 566 559 564 1679 568 1674 562 1680 567 1676 560 1682 565 1676 571 1663 563 1679 568 558 565 1677 570 1673 563 562 561 565 568 557 566 1667 559 565 568 1673 563 563 560 565 568 1674 562 1679 568 1675 561 556 567 1675 561 564 569 1672 564 1677 570 556 567 559 564 561 562 1670 566 559 564 1676 571 555 568 557 566 1675 562 1680 567 1675 561 564 569 12939 8975 2197 565 # -name: SPEED- +name: Speed_dn type: raw frequency: 38000 duty_cycle: 0.330000 data: 8972 4427 561 1681 566 560 563 562 561 565 568 557 566 559 564 561 562 563 560 565 568 1673 563 1676 571 1671 565 1676 571 1672 564 1677 570 1664 562 1679 568 1674 562 562 561 1680 567 558 565 560 563 562 561 555 568 556 567 558 565 1676 560 564 569 1670 566 1675 561 1680 567 1665 561 1680 567 1675 561 564 569 1673 563 562 561 564 569 556 567 548 565 561 562 562 561 1680 567 558 565 1677 570 1672 564 1678 569 1673 563 12942 8971 2195 567 # -name: POWER +name: Power type: raw frequency: 38000 duty_cycle: 0.330000 data: 9024 4477 566 1725 541 537 575 530 572 534 568 537 565 540 572 533 569 537 565 540 572 1690 566 1697 569 1720 546 1690 566 1697 569 1694 572 1691 565 1698 568 1694 572 533 569 537 565 540 572 533 569 536 566 540 572 532 570 536 566 1696 570 1692 574 1715 541 1696 570 1693 573 1689 567 1696 570 1693 573 532 570 536 566 539 573 532 570 535 567 538 574 531 571 534 568 1695 571 1691 565 1725 541 1695 571 1692 574 1688 568 11738 9017 2223 574 95995 9023 2216 570 95998 9020 2219 567 # -name: TIMER +name: Timer type: raw frequency: 38000 duty_cycle: 0.330000 data: 9025 4477 576 1687 569 564 548 531 571 534 568 537 565 540 572 533 569 536 566 539 573 1689 567 1696 570 1693 573 1689 567 1696 570 1693 573 1690 566 1697 569 1694 572 560 542 1694 572 560 542 537 565 540 572 533 569 536 566 539 573 1689 567 565 547 1689 567 1696 570 1692 574 1689 567 1696 570 1693 573 559 543 1693 573 559 543 536 566 539 573 532 570 535 567 538 574 1688 568 564 548 1688 568 1695 572 1691 575 1688 568 11738 9016 2223 574 95995 9022 2216 570 96000 9019 2219 630 # -name: SPEED+ +name: Speed_up type: raw frequency: 38000 duty_cycle: 0.330000 data: 9022 4480 573 1691 565 540 572 533 569 537 565 540 572 533 569 536 566 540 572 532 570 1693 573 1690 566 1697 569 1694 572 1717 539 1724 542 1721 545 1718 548 1715 541 1722 544 535 567 538 574 531 571 535 567 538 574 531 571 534 568 538 564 1698 568 1695 571 1692 574 1689 567 1722 544 1719 547 1716 540 1723 543 536 566 540 572 533 569 536 566 539 573 532 570 536 566 539 573 1689 567 1696 570 1693 573 1690 566 1724 542 11737 9015 2224 572 95995 9025 2215 571 95997 9020 2219 567 # -name: ROTATE +name: Rotate type: raw frequency: 38000 duty_cycle: 0.330000 data: 9021 4481 572 1692 574 531 571 535 567 538 574 531 571 534 568 538 564 541 571 534 568 1694 572 1691 575 1688 568 1722 544 1719 547 1690 566 1697 569 1694 572 1691 565 540 572 533 569 1694 572 533 569 537 565 540 572 533 569 537 565 1698 568 1694 572 533 569 1695 571 1692 574 1715 541 1722 544 1693 573 531 571 535 567 1696 570 535 567 539 573 532 570 535 567 538 574 1689 567 1696 570 535 567 1696 570 1693 573 1716 540 11739 9024 2216 570 95999 9020 2219 567 96001 9020 2220 566 # -name: POWER +name: Power type: parsed protocol: NEC address: 80 00 00 00 command: 92 00 00 00 # -name: SPEED+ +name: Speed_up type: parsed protocol: NEC address: 80 00 00 00 command: 89 00 00 00 # -name: SPEED- +name: Speed_dn type: parsed protocol: NEC address: 80 00 00 00 command: 9F 00 00 00 # -name: ROTATE +name: Rotate type: parsed protocol: NEC address: 80 00 00 00 command: 87 00 00 00 # -name: MODE +name: Mode type: parsed protocol: NEC address: 80 00 00 00 command: 81 00 00 00 # -name: POWER +name: Power type: raw frequency: 38000 duty_cycle: 0.330000 data: 1286 402 1289 426 414 1241 1280 408 1283 431 409 1245 435 1246 434 1247 433 1249 442 1239 441 1240 1281 7121 1281 404 1276 436 414 1239 1282 429 1251 433 407 1246 434 1246 434 1247 433 1247 433 1247 433 1247 1284 8216 1275 408 1283 428 412 1267 1253 430 1250 432 408 1245 435 1244 436 1244 436 1244 436 1244 436 1243 1277 7120 1282 401 1279 403 437 1243 1277 404 1276 407 433 1247 433 1246 434 1246 434 1246 434 1246 434 1245 1275 8224 1277 405 1275 407 433 1247 1273 409 1282 400 440 1240 440 1239 441 1239 441 1239 441 1238 442 1238 1282 7115 1276 405 1275 407 433 1247 1273 409 1281 400 440 1240 440 1239 441 1239 441 1239 441 1238 432 1248 1283 8216 1275 407 1283 399 441 1238 1282 400 1280 402 438 1241 439 1241 439 1240 440 1239 441 1239 441 1238 1282 7114 1277 405 1275 406 434 1246 1274 407 1273 408 432 1248 432 1247 433 1247 1246 434 1245 435 1245 1275 8223 1279 403 1277 404 436 1244 1276 406 1274 407 433 1247 433 1246 434 1245 435 1245 435 1244 436 1244 1276 7120 1282 400 1280 401 439 1241 1279 402 1278 404 436 1244 436 1243 437 1243 437 1242 438 1241 439 1241 1279 # -name: ROTATE +name: Rotate type: raw frequency: 38000 duty_cycle: 0.330000 data: 1286 401 1279 434 406 1249 1282 404 1276 436 414 1240 440 1241 1280 432 408 1247 433 1248 432 1248 443 7955 1277 408 1283 430 410 1244 1276 408 1283 429 411 1243 437 1243 1278 408 432 1248 432 1249 441 1265 415 9057 1286 400 1280 431 409 1271 1250 435 1256 429 411 1243 437 1243 1278 433 407 1248 432 1248 432 1248 432 7966 1277 407 1284 427 413 1241 1280 431 1249 435 405 1249 442 1239 1282 402 438 1243 437 1243 437 1243 437 9062 1280 404 1276 435 405 1248 1283 401 1279 432 408 1245 435 1246 1275 436 414 1239 441 1239 441 1239 441 7956 1276 407 1284 427 413 1241 1280 404 1276 434 406 1247 433 1247 1284 400 440 1240 440 1240 440 1240 440 9058 1284 399 1281 429 411 1243 1278 432 1248 435 405 1249 431 1248 1283 401 439 1241 439 1241 439 1241 439 7957 1275 408 1283 401 439 1241 1280 430 1250 406 434 1246 434 1246 1275 409 441 1238 432 1249 431 1248 432 # -name: TIMER +name: Timer type: raw frequency: 38000 duty_cycle: 0.330000 data: 1292 403 1288 431 409 1246 1285 406 1285 432 408 1247 433 1249 442 1240 1280 407 443 1239 441 1267 413 7957 1286 401 1279 434 406 1248 1283 404 1287 427 413 1241 439 1241 439 1241 1280 407 433 1248 432 1248 443 9055 1277 409 1282 431 409 1244 1276 409 1282 431 409 1244 436 1245 435 1245 1286 426 414 1267 413 1241 439 7956 1276 409 1282 430 410 1244 1277 408 1283 429 411 1269 411 1243 437 1243 1278 407 433 1248 432 1248 432 9065 1277 407 1284 428 412 1242 1278 406 1285 427 413 1241 439 1241 439 1241 1280 406 434 1247 433 1247 433 7962 1281 405 1275 436 414 1266 1254 431 1249 436 414 1265 415 1239 441 1240 1280 432 408 1246 434 1247 433 # -name: MODE +name: Mode type: raw frequency: 38000 duty_cycle: 0.330000 data: 1274 408 1283 426 414 1239 1282 427 1253 428 412 1241 439 1240 440 1240 440 1239 1281 427 413 1267 413 7957 1275 434 1246 436 404 1275 1256 427 1253 429 411 1267 413 1267 413 1240 440 1240 1280 428 412 1267 413 9060 1282 400 1280 428 412 1267 1253 429 1251 430 410 1243 437 1243 437 1242 438 1242 1278 429 411 1241 439 7958 1274 434 1246 436 414 1264 1256 426 1254 428 412 1266 414 1240 492 1188 440 1240 1280 428 412 1240 440 9059 1272 436 1254 426 414 1239 1281 426 1254 427 413 1240 440 1239 441 1239 441 1238 1282 426 414 1239 441 7955 1277 405 1275 407 433 1246 1274 408 1282 399 441 1239 441 1239 441 1239 441 1239 1281 400 440 1240 440 # -name: POWER +name: Power type: raw frequency: 38000 duty_cycle: 0.330000 data: 1309 376 1276 409 433 1252 1305 379 1273 410 463 1222 441 1244 460 1221 463 1221 442 1242 462 1222 1283 7692 1310 375 1309 377 464 1220 1305 379 1273 410 463 1223 460 1222 441 1242 462 1221 431 1252 463 1220 1305 7668 1281 401 1303 378 432 1252 1284 399 1305 378 464 1220 464 1217 466 1216 467 1215 468 1214 459 1223 1303 7665 1305 379 1304 381 440 1244 1282 405 1278 409 433 1254 440 1246 437 1248 467 1219 433 1252 463 1224 1312 7687 1304 385 1309 380 461 1227 1278 410 1305 382 439 1250 433 1253 462 1228 466 1222 461 1226 468 1219 1306 7689 1313 375 1308 380 441 1248 1309 379 1284 402 460 1228 466 1222 441 1248 467 1222 462 1227 467 1222 1304 7688 1283 403 1312 374 468 1219 1306 382 1312 377 464 1224 439 1249 434 1252 442 1245 459 1228 435 1253 1304 7683 1277 411 1304 383 438 1249 1308 380 1303 381 461 1225 438 1248 435 1252 442 1247 436 1252 442 1246 1311 # -name: TIMER +name: Timer type: raw frequency: 38000 duty_cycle: 0.330000 data: 1274 436 1247 436 406 1277 1249 437 1257 427 415 1269 415 1270 413 1272 1254 432 410 1274 410 1271 413 8525 1277 431 1253 430 412 1272 1254 430 1254 428 413 1270 414 1271 413 1272 1254 430 412 1271 413 1272 412 8537 1275 435 1249 437 415 1270 1256 427 1257 427 415 1268 405 1279 415 1268 1247 437 404 1279 415 1269 415 8528 1274 433 1251 432 410 1272 1254 430 1254 431 411 1273 411 1271 413 1244 1282 429 413 1271 413 1271 413 8532 1281 429 1255 430 412 1272 1254 429 1255 428 414 1271 413 1245 439 1273 1253 432 410 1274 410 1273 411 8539 1273 435 1249 433 409 1273 1253 429 1255 430 412 1271 413 1270 414 1267 1248 434 408 1274 410 1273 410 8532 1280 428 1256 427 414 1268 1247 436 1248 436 406 1250 434 1275 409 1272 1254 429 413 1270 414 1270 414 8534 1278 431 1253 433 409 1273 1253 429 1255 429 413 1269 415 1267 406 1277 1249 436 405 1277 407 1249 435 8531 1281 427 1246 436 406 1275 1251 434 1250 433 409 1272 412 1270 414 1269 1246 436 405 1277 407 1274 410 8537 1275 435 1249 435 407 1278 1248 437 1257 428 414 1268 405 1277 407 1276 1250 434 408 1274 410 1272 412 8531 1281 429 1255 429 413 1243 1283 427 1257 428 414 1271 413 1272 412 1272 1254 432 410 1273 411 1247 437 8536 1276 432 1252 432 410 1273 1253 432 1252 433 409 1275 409 1275 409 1275 1251 435 407 1278 405 1277 407 8535 1278 430 1254 428 414 1268 1247 436 1248 435 406 1276 408 1277 407 1277 1249 435 407 1277 407 1277 407 8540 1273 435 1249 434 408 1273 1253 429 1255 429 413 1271 413 1270 414 1270 1256 430 412 1271 413 1271 413 8538 1275 435 1249 435 407 1275 1251 432 1252 433 409 1275 409 1274 410 1274 1252 432 410 1275 409 1276 408 8542 1281 429 1255 431 411 1273 1253 431 1253 432 410 1273 411 1271 413 1271 1255 431 411 1273 411 1272 412 8529 1273 436 1258 427 415 1268 1258 427 1257 429 413 1272 412 1273 411 1249 1277 436 406 1279 415 1268 415 8536 1276 432 1252 430 412 1271 1255 431 1253 432 410 1275 409 1274 410 1273 1253 432 410 1274 410 1272 412 8527 1275 435 1249 435 407 1276 1250 433 1251 434 408 1277 407 1279 415 1269 1257 427 415 1271 413 1270 413 8556 1277 436 1258 431 411 1277 1259 430 1254 436 406 1280 414 1272 412 1275 1251 438 414 1272 412 1272 412 # -name: SPEED+ +name: Speed_up type: raw frequency: 38000 duty_cycle: 0.330000 data: 1280 431 1253 432 410 1275 1250 433 1251 434 408 1277 406 1280 414 1272 412 1274 410 1276 1250 436 405 8543 1331 352 1280 432 410 1275 1251 433 1251 435 407 1275 409 1272 412 1271 413 1272 412 1273 1253 432 410 8527 1275 435 1249 436 405 1276 1250 431 1253 429 413 1270 413 1270 413 1269 414 1269 415 1268 1247 436 405 8534 1278 430 1253 428 414 1268 1247 435 1248 435 407 1277 406 1276 408 1274 410 1274 410 1248 1277 436 405 8558 1275 438 1256 431 411 1277 1259 428 1256 431 411 1275 409 1278 416 1271 413 1273 411 1277 1259 429 413 8559 1285 428 1256 430 412 1273 1253 433 1251 434 408 1277 406 1280 414 1274 410 1279 415 1273 1253 437 415 8550 1283 430 1254 433 409 1279 1257 431 1253 434 408 1279 415 1274 410 1278 416 1274 410 1278 1258 431 411 8553 1280 432 1252 435 407 1279 1257 427 1256 427 404 1277 406 1276 408 1248 435 1274 410 1273 1253 430 412 8535 1277 433 1251 435 406 1279 1257 429 1255 431 411 1275 409 1277 406 1278 416 1271 413 1272 1254 431 411 8545 1278 433 1251 434 408 1278 1258 428 1255 432 410 1274 410 1279 415 1273 411 1278 416 1273 1253 437 415 8557 1286 429 1254 437 415 1274 1252 436 1258 430 412 1277 406 1283 411 1278 405 1282 412 1275 1250 438 414 8561 1282 433 1251 438 414 1274 1252 438 1256 433 409 1277 407 1280 414 1272 412 1275 409 1278 1258 429 413 8549 1284 430 1254 434 408 1279 1257 429 1255 433 409 1279 415 1273 411 1277 407 1280 414 1274 1252 436 405 8557 1276 436 1258 431 411 1274 1252 434 1250 437 415 1272 412 1275 408 1280 414 1275 409 1280 1256 433 409 8558 1285 428 1256 431 411 1276 1250 438 1256 432 410 1278 416 1272 412 1273 411 1273 411 1273 1253 432 410 8539 1273 437 1247 436 405 1277 1249 434 1250 435 406 1276 408 1275 409 1275 409 1275 409 1275 1251 435 406 8543 1280 430 1254 431 411 1274 1252 431 1253 431 411 1273 410 1272 412 1273 411 1274 410 1276 1250 434 408 8542 1280 432 1252 434 408 1279 1257 430 1254 433 408 1277 407 1278 416 1270 413 1272 412 1275 1251 435 406 8540 1283 427 1257 429 413 1272 1254 431 1253 432 410 1275 409 1276 408 1278 406 1277 406 1276 1250 435 407 8538 1274 434 1250 434 408 1277 1249 436 1258 428 414 1273 411 1272 412 1270 414 1271 412 1273 1253 433 409 8535 1277 433 1251 436 406 1282 1254 433 1250 438 414 1274 410 1278 405 1280 414 1271 413 1276 1260 429 412 # -name: MODE +name: Mode type: raw frequency: 38000 duty_cycle: 0.330000 data: 1280 433 1251 436 405 1281 1255 431 1253 434 408 1278 405 1279 1257 431 411 1277 407 1280 414 1274 410 8547 1275 437 1257 428 413 1270 1255 430 1254 430 412 1273 411 1275 1251 436 405 1280 414 1271 412 1273 410 8550 1283 431 1253 434 408 1278 1258 427 1256 428 414 1271 412 1272 1254 434 408 1279 415 1271 412 1247 436 8544 1279 433 1251 435 407 1279 1257 430 1254 434 407 1278 405 1277 1249 437 415 1269 414 1269 415 1269 415 8537 1275 435 1248 435 406 1276 1250 436 1248 436 406 1278 406 1277 1248 437 404 1280 414 1269 414 1271 412 8532 1280 428 1255 428 413 1269 1246 437 1246 435 406 1276 408 1277 1248 436 406 1278 406 1279 415 1268 416 8538 1274 436 1258 427 415 1269 1257 427 1257 430 412 1272 412 1273 1252 434 408 1277 407 1280 414 1272 412 8553 1280 405 1279 434 408 1276 1250 435 1259 429 413 1273 411 1274 1252 434 408 1277 407 1279 415 1270 414 8548 1275 436 1258 428 414 1272 1254 433 1250 435 406 1277 406 1278 1258 429 413 1272 412 1275 409 1277 406 8549 1284 427 1257 430 412 1274 1251 433 1251 434 407 1277 406 1278 1248 437 415 1269 415 1271 412 1273 410 # -name: POWER +name: Power type: raw frequency: 38000 duty_cycle: 0.330000 data: 8982 4433 598 1657 570 519 594 547 566 522 591 549 575 540 573 541 572 542 571 543 570 1659 568 1635 592 1637 600 1655 572 1657 570 1660 566 1636 601 1654 572 1630 597 517 596 545 568 520 593 547 566 548 576 539 574 540 573 540 573 1629 598 1631 596 1633 593 1635 592 1637 600 1629 597 1631 596 1633 593 521 592 522 591 549 575 540 573 514 599 542 571 543 570 544 569 1659 568 1635 592 1637 600 1628 598 1630 597 1632 595 # -name: TIMER +name: Timer type: raw frequency: 38000 duty_cycle: 0.330000 data: 8990 4430 601 1628 598 517 596 519 594 547 566 549 574 540 573 542 571 544 569 546 567 1663 574 1628 598 1658 568 1662 575 1654 572 1658 568 1660 566 1663 574 1656 570 544 569 1660 566 548 575 539 574 541 572 542 571 544 569 545 568 1662 575 539 574 1656 570 1658 568 1661 565 1664 573 1656 570 1659 567 548 565 1664 573 542 571 543 570 545 568 546 567 548 565 549 574 1655 571 543 570 1659 567 1661 576 1628 598 1658 568 # -name: SPEED+ +name: Speed_up type: parsed protocol: NEC address: 00 00 00 00 command: 11 00 00 00 # -name: ROTATE +name: Rotate type: parsed protocol: NEC address: 00 00 00 00 command: 0E 00 00 00 # -name: TIMER +name: Timer type: parsed protocol: NEC address: 00 00 00 00 command: 05 00 00 00 # -name: ROTATE +name: Rotate type: parsed protocol: NEC address: 00 00 00 00 command: 18 00 00 00 # -name: TIMER +name: Timer type: parsed protocol: NEC address: 00 00 00 00 command: 40 00 00 00 # -name: POWER +name: Power type: raw frequency: 38000 duty_cycle: 0.330000 data: 1313 407 1306 414 432 1273 1306 415 1308 447 409 1275 438 1275 437 1275 438 1273 1306 449 407 1278 434 7939 1307 438 1285 408 427 1278 1312 409 1304 424 484 1229 432 1280 433 1280 433 1277 1313 415 431 1282 430 7925 1310 408 1304 414 432 1274 1305 415 1308 420 426 1286 427 1285 428 1284 429 1282 1308 420 426 1286 427 7944 1312 407 1306 413 433 1272 1307 413 1310 418 428 1284 429 1283 481 1230 431 1279 1311 417 429 1283 430 7922 1313 406 1307 412 434 1271 1308 412 1311 416 430 1283 429 1282 431 1281 432 1277 1313 415 431 1281 431 7935 1310 409 1365 353 482 1222 1306 415 1308 420 426 1285 428 1284 429 1283 429 1280 1310 418 428 1284 429 7922 1303 415 1308 411 435 1270 1310 411 1312 415 431 1280 432 1279 433 1278 435 1274 1305 423 433 1278 435 7930 1305 413 1310 409 426 1277 1313 408 1305 422 434 1277 436 1275 427 1284 429 1280 1310 418 428 1283 430 7918 1307 411 1312 407 428 1275 1304 416 1307 420 436 1275 427 1283 430 1281 431 1277 1313 414 432 1279 433 7928 1307 411 1312 406 429 1274 1305 414 1309 419 427 1283 430 1281 432 1279 434 1275 1304 449 407 1277 435 7909 1305 412 1311 408 427 1276 1303 416 1307 421 435 1275 427 1283 430 1281 431 1277 1313 414 432 1279 433 7925 1310 408 1305 414 432 1271 1308 412 1311 417 429 1281 431 1279 433 1276 436 1272 1308 420 426 1284 429 7914 1311 407 1368 351 433 1271 1308 412 1311 416 430 1281 431 1278 434 1276 426 1281 1309 419 427 1283 430 7928 1307 410 1364 354 481 1221 1307 414 1309 418 428 1282 431 1280 433 1277 436 1272 1307 420 436 1274 428 7913 1312 406 1307 412 434 1269 1310 410 1313 414 432 1278 434 1275 427 1282 431 1277 1313 415 431 1279 433 7922 1313 405 1307 411 435 1268 1311 409 1304 423 433 1277 435 1274 428 1281 431 1276 1314 414 432 1278 434 7905 1310 409 1314 404 431 1271 1308 412 1311 417 429 1280 432 1277 436 1274 428 1279 1311 417 429 1280 432 7922 1313 432 1281 438 408 1267 1312 435 1288 440 406 1277 436 1273 429 1280 432 1275 1315 413 433 1278 434 7903 1311 409 1314 404 431 1269 1310 413 1310 418 428 1306 407 1276 437 1273 429 1278 1312 419 427 1306 407 7921 1315 406 1307 412 434 1292 1287 410 1313 415 431 1302 411 1298 404 1279 434 1274 1316 415 431 1302 411 7901 1314 407 1306 413 433 1294 1285 411 1312 417 429 1304 409 1300 402 1281 432 1275 1315 416 430 1303 410 7917 1308 412 1311 409 426 1274 1305 417 1306 422 434 1274 428 1280 432 1277 436 1297 1283 421 435 1273 429 7906 1309 411 1312 407 428 1274 1306 416 1307 422 434 1274 428 1280 433 1276 426 1281 1309 421 435 1273 429 7901 1313 407 1306 414 432 1270 1310 412 1311 418 428 1280 433 1276 426 1282 431 1276 1314 416 430 1278 435 # -name: SPEED+ +name: Speed_up type: raw frequency: 38000 duty_cycle: 0.330000 data: 1310 411 1312 407 428 1300 1279 417 1306 419 1304 423 433 1302 410 1302 400 1282 1307 421 1302 425 431 7882 1312 409 1304 414 432 1296 1283 413 1310 415 1308 445 401 1308 404 1280 432 1276 1314 414 1309 418 428 7849 1314 406 1306 412 434 1293 1286 410 1302 422 1311 416 430 1304 409 1276 437 1272 1307 420 1303 423 433 7876 1307 413 1309 408 427 1300 1279 416 1307 418 1305 421 435 1299 403 1281 431 1277 1313 415 1308 418 428 7844 1308 411 1302 416 430 1297 1282 413 1310 415 1308 418 428 1305 407 1303 409 1271 1308 419 1304 422 434 7869 1304 416 1307 411 424 1302 1277 418 1305 419 1304 422 434 1299 403 1306 407 1275 1304 422 1301 425 431 7837 1305 414 1309 408 427 1299 1280 414 1309 415 1307 418 428 1305 408 1301 401 1280 1309 416 1307 419 427 7874 1309 410 1303 414 432 1294 1285 409 1303 446 1277 423 433 1299 403 1305 407 1273 1306 420 1303 423 433 7830 1312 407 1305 412 434 1292 1277 417 1306 418 1305 421 425 1307 406 1303 409 1271 1308 417 1305 420 426 7871 1312 407 1306 411 424 1275 1304 416 1307 417 1306 419 427 1280 432 1275 427 1279 1311 415 1308 417 429 7833 1309 410 1303 414 432 1268 1311 408 1305 419 1304 421 425 1282 430 1277 436 1296 1283 416 1307 419 427 7868 1305 414 1309 408 427 1272 1307 412 1310 413 1310 416 430 1277 425 1282 430 1301 1278 421 1302 424 432 7829 1303 415 1308 409 426 1274 1305 414 1308 415 1308 418 428 1279 433 1274 428 1278 1311 413 1310 416 430 7866 1307 411 1301 415 431 1270 1309 410 1303 421 1302 423 433 1275 427 1279 433 1273 1306 419 1304 422 434 7826 1306 413 1310 407 428 1272 1307 412 1311 413 1310 416 430 1277 425 1282 430 1275 1304 421 1302 424 432 7844 1308 410 1302 415 430 1269 1310 410 1302 421 1302 424 432 1274 428 1279 433 1299 1280 419 1304 422 434 # -name: MODE +name: Mode type: raw frequency: 38000 duty_cycle: 0.330000 data: 1306 440 1282 436 410 1269 1310 437 1286 442 404 1283 429 1282 430 1282 430 1283 429 1281 1308 419 427 7925 1309 436 1286 406 429 1275 1304 417 1306 447 409 1277 435 1276 436 1276 426 1286 426 1284 1305 448 408 7898 1305 440 1283 435 411 1268 1311 435 1277 450 406 1279 433 1278 434 1277 435 1276 436 1273 1306 448 408 7914 1309 435 1277 440 406 1272 1307 440 1283 444 402 1283 429 1282 430 1281 431 1280 432 1277 1312 442 404 7898 1305 440 1283 436 410 1267 1312 435 1288 440 406 1278 434 1277 435 1276 436 1274 428 1282 1307 446 410 7910 1313 431 1281 437 409 1268 1311 436 1287 440 406 1278 434 1277 435 1275 427 1284 428 1281 1308 445 401 7899 1304 441 1282 436 410 1267 1312 435 1288 439 407 1278 434 1276 436 1275 427 1283 429 1280 1309 444 401 7914 1309 436 1287 431 404 1272 1307 439 1283 443 403 1281 431 1279 433 1277 435 1275 427 1281 1308 445 401 7898 1305 439 1284 434 401 1275 1304 442 1280 446 410 1273 429 1281 431 1279 433 1278 434 1273 1306 448 408 7905 1308 437 1286 432 403 1273 1306 440 1283 444 402 1281 431 1279 433 1276 436 1274 428 1280 1309 444 401 7894 1309 435 1288 430 405 1271 1308 438 1285 442 404 1278 434 1275 437 1273 429 1280 432 1276 1313 440 406 7905 1308 437 1286 431 404 1272 1307 439 1284 442 403 1279 433 1276 436 1273 429 1280 432 1275 1314 439 407 7885 1307 437 1286 431 404 1271 1308 438 1285 442 404 1278 434 1274 428 1282 430 1279 433 1274 1305 448 408 7901 1312 432 1280 436 410 1266 1313 432 1280 446 410 1272 430 1278 434 1275 427 1282 430 1276 1314 440 406 7906 1307 436 1286 431 404 1270 1309 437 1286 440 406 1276 436 1273 429 1279 433 1276 426 1280 1309 444 402 7882 1311 434 1278 438 408 1267 1312 434 1278 447 409 1273 429 1279 433 1275 427 1281 431 1276 1313 439 407 # -name: TIMER +name: Timer type: raw frequency: 38000 duty_cycle: 0.330000 data: 1316 405 1307 412 434 1270 1309 413 1310 416 1307 421 435 1276 436 1276 436 1275 427 1283 1307 421 1312 7037 1310 411 1312 407 428 1274 1305 418 1305 420 1303 425 431 1278 434 1277 435 1276 436 1274 1305 423 1310 7006 1310 411 1312 406 429 1274 1305 416 1306 419 1304 423 433 1303 409 1275 427 1284 428 1281 1308 420 1303 7043 1314 407 1305 412 434 1295 1284 412 1310 414 1309 419 427 1308 404 1280 432 1279 433 1275 1314 413 1310 7003 1313 407 1305 413 433 1294 1285 411 1301 424 1309 418 428 1306 406 1304 408 1276 436 1273 1306 421 1302 7041 1306 414 1309 410 425 1301 1278 418 1305 420 1303 424 432 1302 400 1310 402 1282 430 1277 1312 415 1307 7003 1313 407 1305 413 433 1294 1285 410 1302 423 1310 416 430 1304 408 1302 400 1284 428 1279 1310 417 1306 7033 1314 406 1307 412 434 1292 1287 408 1304 420 1303 424 432 1301 401 1308 404 1279 433 1274 1305 422 1311 6995 1311 410 1302 415 431 1295 1284 411 1301 423 1310 416 430 1303 409 1299 403 1280 432 1275 1304 422 1301 7034 1313 406 1307 411 424 1301 1278 417 1305 419 1303 423 433 1299 403 1305 407 1275 427 1281 1308 418 1304 6997 1309 411 1301 416 430 1295 1284 411 1301 422 1301 425 431 1301 401 1307 405 1277 435 1271 1308 418 1305 7028 1308 411 1301 415 431 1294 1285 410 1302 422 1301 425 431 1300 402 1306 406 1276 426 1280 1309 416 1307 6993 1312 407 1305 412 434 1291 1278 416 1307 417 1306 420 426 1306 406 1301 401 1281 431 1275 1304 422 1301 7029 1308 411 1301 415 431 1268 1311 409 1303 420 1303 423 433 1273 429 1278 434 1274 428 1277 1312 414 1309 6989 1306 412 1310 406 429 1270 1309 411 1301 422 1301 424 432 1274 428 1279 433 1275 427 1278 1311 414 1309 7019 1307 411 1301 415 431 1268 1311 408 1304 419 1304 421 435 1271 431 1276 426 1282 430 1275 1304 421 1302 6994 1312 406 1306 410 425 1274 1305 414 1309 414 1339 386 429 1277 425 1281 431 1276 426 1305 1284 414 1309 7018 1308 409 1303 413 433 1267 1302 417 1337 386 1337 388 458 1248 433 1273 429 1278 434 1271 1308 416 1338 6956 1308 410 1333 382 464 1236 1333 386 1337 386 1337 388 458 1248 454 1252 429 1277 435 1270 1340 384 1338 6949 1336 382 1330 386 460 1239 1330 388 1335 388 1335 391 455 1250 462 1244 458 1249 463 1241 1338 386 1336 # -name: POWER +name: Power type: raw frequency: 38000 duty_cycle: 0.330000 data: 1289 402 1282 405 442 1268 1263 400 1284 403 433 1276 418 1242 442 1245 439 1248 446 1240 444 1243 1288 7090 1288 402 1282 405 442 1268 1263 400 1284 402 434 1276 418 1241 443 1244 440 1247 447 1240 444 1243 1288 7090 1288 402 1282 405 442 1269 1262 400 1284 402 445 1267 417 1243 441 1246 438 1249 445 1242 442 1245 1286 7092 1286 403 1291 395 441 1244 1287 402 1282 404 443 1242 442 1245 439 1249 445 1242 442 1245 439 1248 1293 7086 1292 398 1286 401 435 1248 1283 407 1287 399 437 1247 437 1250 444 1243 441 1246 438 1249 445 1242 1289 7090 1288 402 1282 405 442 1269 1262 401 1283 403 444 1268 416 1244 440 1247 437 1250 444 1243 441 1247 1284 7096 1293 397 1287 401 435 1275 1256 407 1287 400 436 1274 410 1250 444 1243 441 1247 437 1250 444 1243 1288 7092 1286 404 1280 408 439 1272 1259 403 1281 406 441 1270 414 1246 438 1250 444 1243 441 1246 438 1250 1291 # -name: TIMER +name: Timer type: raw frequency: 38000 duty_cycle: 0.330000 data: 1291 399 1285 404 443 1243 1288 401 1283 404 443 1243 441 1245 439 1249 1282 407 440 1246 438 1249 445 7935 1291 401 1283 404 443 1268 1263 400 1284 403 444 1268 416 1245 439 1248 1283 408 439 1272 412 1249 445 7935 1291 400 1284 403 444 1268 1263 400 1284 403 433 1277 417 1244 440 1274 1257 407 440 1272 412 1248 446 7935 1290 401 1283 404 443 1242 1289 400 1284 404 443 1242 442 1245 439 1275 1256 407 440 1246 438 1249 445 7936 1290 400 1284 404 443 1243 1288 400 1284 404 443 1243 441 1245 439 1248 1283 407 440 1246 438 1249 445 7935 1290 401 1283 404 443 1268 1263 401 1283 404 443 1268 416 1245 439 1248 1283 408 439 1273 411 1250 444 7937 1288 403 1281 406 441 1271 1260 403 1281 406 441 1270 414 1247 447 1241 1290 400 436 1275 419 1241 443 7940 1286 405 1289 398 438 1273 1258 404 1280 408 439 1272 412 1249 445 1242 1289 402 435 1276 418 1242 442 # -name: MODE +name: Mode type: raw frequency: 38000 duty_cycle: 0.330000 data: 1293 395 1289 398 438 1248 1293 395 1289 398 438 1248 446 1241 443 1245 439 1249 1292 396 440 1245 439 7942 1294 395 1289 398 438 1247 1284 404 1290 397 439 1246 438 1250 444 1243 440 1247 1284 405 442 1244 440 7940 1285 404 1290 396 440 1246 1285 403 1291 396 440 1245 438 1249 445 1242 442 1245 1286 403 444 1242 442 7939 1286 402 1292 395 441 1245 1286 402 1292 394 442 1244 440 1248 446 1241 443 1245 1286 402 445 1242 442 7941 1284 404 1290 397 439 1248 1293 395 1289 398 438 1248 446 1242 442 1246 438 1250 1291 396 440 1247 447 7934 1291 398 1286 401 446 1241 1290 399 1285 402 445 1242 442 1246 438 1250 444 1244 1287 401 446 1241 443 7940 1285 403 1291 396 440 1247 1284 404 1290 397 439 1247 437 1251 443 1245 439 1249 1292 396 440 1246 438 7945 1291 398 1286 401 446 1240 1291 398 1286 401 446 1240 444 1244 439 1248 446 1242 1289 399 437 1249 445 # -name: POWER +name: Power type: parsed protocol: NEC address: 00 00 00 00 command: 46 00 00 00 # -name: SPEED+ +name: Speed_up type: parsed protocol: NEC address: 00 00 00 00 command: 44 00 00 00 # -name: ROTATE +name: Rotate type: parsed protocol: NEC address: 00 00 00 00 command: 43 00 00 00 # -name: TIMER +name: Timer type: parsed protocol: NEC address: 00 00 00 00 command: 16 00 00 00 # -name: MODE +name: Mode type: parsed protocol: NEC address: 00 00 00 00 command: 0D 00 00 00 # -name: POWER +name: Power type: raw frequency: 38000 duty_cycle: 0.330000 data: 1308 408 1311 402 442 1250 1314 412 1307 405 449 1242 446 1250 449 1246 453 1243 445 1250 449 1248 1316 7148 1306 411 1308 405 449 1242 1311 415 1304 408 446 1246 453 1244 444 1251 448 1247 451 1244 444 1252 1312 7154 1309 406 1303 410 444 1247 1306 420 1309 404 450 1241 447 1249 450 1247 451 1244 444 1252 447 1249 1315 7150 1314 403 1306 407 447 1245 1308 417 1302 412 442 1250 449 1248 450 1246 442 1254 444 1251 448 1249 1304 7160 1314 429 1280 433 421 1248 1305 445 1284 429 415 1252 447 1250 449 1247 441 1254 445 1252 447 1250 1303 7164 1310 404 1305 410 444 1251 1302 420 1309 404 440 1257 441 1255 443 1252 447 1250 449 1248 440 1256 1307 7159 1304 409 1310 403 441 1254 1309 413 1306 407 447 1248 440 1255 443 1252 446 1249 450 1246 442 1253 1362 7102 1310 404 1305 409 445 1251 1302 420 1310 403 441 1254 444 1251 447 1248 440 1255 443 1253 446 1250 1303 7163 1311 403 1306 408 446 1249 1304 418 1301 412 442 1253 446 1250 449 1248 440 1256 442 1254 445 1251 1302 7162 1302 413 1306 407 447 1248 1305 417 1302 412 442 1254 445 1251 448 1248 440 1256 442 1253 446 1249 1304 7155 1308 405 1304 409 445 1251 1302 420 1309 404 440 1255 443 1253 445 1250 448 1248 440 1255 495 1202 1310 # -name: MODE +name: Mode type: raw frequency: 38000 duty_cycle: 0.330000 data: 1317 406 1313 409 445 1250 1324 410 1319 403 451 1243 445 1252 447 1250 500 1196 1316 408 446 1248 451 7997 1311 408 1311 407 447 1245 1319 411 1308 408 446 1248 450 1247 452 1246 453 1244 1309 411 443 1251 448 8000 1308 411 1308 408 446 1247 1317 412 1307 410 444 1248 451 1246 442 1253 446 1251 1313 407 447 1246 452 7995 1313 406 1313 404 450 1244 1320 410 1309 409 445 1248 451 1245 454 1243 445 1251 1313 434 420 1245 453 7992 1317 430 1279 437 417 1251 1313 442 1277 439 415 1252 447 1250 449 1248 451 1247 1317 411 454 1241 447 8003 1315 402 1307 407 447 1244 1309 417 1302 411 443 1249 450 1246 442 1253 446 1251 1313 406 448 1272 416 8004 1315 404 1305 410 444 1277 1286 413 1306 408 446 1274 425 1272 416 1253 446 1278 1286 408 446 1274 425 7994 1314 406 1313 406 448 1273 1291 415 1314 406 448 1274 425 1273 415 1253 446 1252 1312 411 443 1278 421 7997 1312 410 1309 409 445 1275 1289 413 1306 412 442 1279 420 1277 422 1275 424 1273 1280 414 440 1253 446 7999 1309 411 1308 409 445 1250 1303 422 1308 409 445 1250 449 1247 441 1255 444 1252 1312 407 447 1248 440 8004 1315 404 1305 412 442 1253 1311 414 1305 410 444 1250 449 1246 442 1253 446 1250 1314 404 440 1257 442 8001 1307 411 1308 408 446 1248 1305 421 1308 407 447 1247 441 1254 445 1252 447 1250 1314 404 440 1257 442 8005 1314 404 1305 413 441 1254 1310 416 1303 413 441 1254 445 1251 448 1248 440 1257 1307 410 444 1252 447 7998 1310 407 1312 405 439 1255 1309 416 1303 411 443 1251 448 1248 440 1254 445 1250 1303 411 443 1251 448 7994 1304 414 1305 411 443 1251 1302 422 1308 408 446 1248 440 1254 445 1251 448 1248 1305 411 443 1253 446 7997 1312 406 1303 413 441 1253 1311 413 1306 408 446 1248 440 1255 444 1253 446 1251 1313 404 440 1256 443 8002 1307 411 1308 408 446 1248 1305 419 1300 414 440 1254 445 1250 449 1247 441 1255 1309 409 445 1249 450 # -name: SPEED+ +name: Speed_up type: raw frequency: 38000 duty_cycle: 0.330000 data: 1313 405 1314 405 449 1250 1313 420 1320 406 448 1252 447 1253 446 1254 445 1255 443 1255 1319 404 450 8002 1316 406 1313 409 445 1253 1311 422 1318 407 499 1202 445 1253 446 1253 445 1254 445 1254 1320 404 450 7999 1309 408 1311 406 448 1248 1305 421 1308 411 443 1253 446 1251 447 1249 449 1248 440 1257 1306 409 445 8000 1308 408 1311 405 449 1247 1306 418 1311 405 449 1248 440 1256 443 1253 446 1251 448 1250 1313 404 450 7996 1312 436 1283 407 447 1250 1313 414 1315 405 449 1250 448 1249 449 1248 450 1246 442 1255 1319 402 452 7991 1307 439 1280 412 442 1255 1308 420 1309 411 443 1255 444 1254 445 1253 446 1253 446 1253 1321 406 448 7998 1320 406 1323 403 451 1249 1314 421 1319 408 446 1254 444 1255 443 1255 443 1256 442 1256 1318 408 446 8004 1314 412 1317 409 445 1255 1318 417 1323 404 450 1250 448 1251 447 1252 447 1253 445 1255 1319 407 447 8003 1315 410 1319 407 447 1252 1322 414 1315 410 444 1256 453 1247 451 1248 450 1247 441 1256 1307 438 416 8002 1316 431 1288 429 415 1252 1311 444 1285 431 423 1241 447 1249 449 1247 451 1248 450 1246 1317 402 442 8002 1316 403 1306 411 443 1251 1312 416 1313 404 450 1244 444 1252 447 1251 447 1249 449 1247 1316 402 442 8002 1316 403 1306 410 444 1250 1313 414 1305 410 444 1249 450 1246 452 1244 444 1253 446 1252 1311 407 447 # -name: POWER +name: Power type: raw frequency: 38000 duty_cycle: 0.330000 data: 1292 433 1265 432 406 1261 1286 438 1260 436 413 1255 443 1253 444 1252 435 1260 438 1259 439 1257 1290 7192 1288 436 1262 434 415 1279 1257 440 1258 438 411 1284 414 1256 442 1254 444 1253 445 1252 435 1261 1286 7196 1284 440 1258 438 411 1257 1290 434 1264 432 417 1252 435 1260 438 1259 439 1257 441 1255 443 1253 1283 7198 1292 431 1256 440 409 1259 1288 436 1262 434 415 1253 434 1261 437 1259 439 1257 441 1255 443 1253 1283 7198 1292 431 1256 439 410 1258 1289 435 1263 433 416 1252 435 1261 437 1258 440 1256 442 1254 444 1252 1284 7198 1292 405 1282 440 409 1258 1289 435 1263 433 416 1252 435 1260 438 1258 440 1256 442 1254 444 1252 1284 7196 1284 440 1258 438 411 1257 1290 433 1265 431 407 1260 438 1284 414 1256 442 1254 444 1252 435 1260 1287 7195 1285 438 1260 436 413 1255 1292 405 1282 440 409 1259 439 1257 441 1255 443 1254 444 1252 435 1260 1287 # -name: SPEED+ +name: Speed_up type: raw frequency: 38000 duty_cycle: 0.330000 data: 1287 410 1288 435 414 1281 1255 414 1284 439 410 1259 439 1283 415 1254 444 1252 435 1261 1286 437 412 8042 1287 410 1288 434 415 1255 1281 440 1258 438 411 1258 440 1255 443 1253 434 1261 437 1259 1288 408 441 8039 1290 406 1292 431 407 1262 1285 411 1287 435 414 1256 442 1253 445 1251 436 1260 438 1258 1289 434 415 8039 1290 406 1281 441 408 1287 1260 409 1289 434 415 1254 433 1261 437 1259 439 1283 415 1255 1292 405 433 8046 1283 413 1285 438 411 1285 1262 434 1264 431 407 1288 410 1259 439 1257 441 441 1253 1283 413 436 8044 1285 412 1286 436 413 1257 1290 405 1282 440 409 1287 411 1284 414 1281 417 1253 434 1261 1286 437 412 8042 1287 436 1262 434 415 1281 1256 440 1258 411 438 1258 440 1255 443 1253 434 1261 437 1258 1289 434 415 8039 1290 406 1281 440 409 1287 1260 409 1289 433 416 1253 434 1261 437 1259 439 1256 442 1254 1293 404 434 8046 1283 413 1285 411 438 1257 1290 406 1281 414 435 1287 411 1257 441 1255 443 1253 434 1261 1286 438 411 8042 1287 409 1289 433 416 1280 1257 439 1259 436 413 1256 442 1253 445 1251 436 1286 412 1283 1264 433 416 8037 1292 404 1283 412 437 1285 1262 408 1290 432 417 1278 409 1259 439 1257 441 1255 443 1253 1283 439 410 8043 1285 437 1261 435 414 1281 1255 440 1258 438 411 1283 415 1254 444 1252 435 1260 438 1258 1289 434 414 8038 1291 432 1255 440 409 1286 1261 435 1263 433 416 1251 436 1259 439 1257 441 1255 443 1253 1283 440 409 8044 1284 411 1287 436 413 1254 1293 431 1256 439 410 1257 441 1281 417 1253 434 1261 437 1259 1288 435 413 # -name: ROTATE +name: Rotate type: raw frequency: 38000 duty_cycle: 0.330000 data: 1288 437 1260 435 414 1254 1292 431 1256 440 409 1259 438 1258 1288 435 413 1255 442 1253 444 1252 435 8046 1292 431 1256 440 409 1259 1288 436 1261 434 414 1254 443 1253 1283 440 409 1259 438 1258 439 1256 441 8040 1287 436 1261 434 414 1254 1292 431 1256 439 409 1258 491 1204 1291 433 415 1253 434 1261 436 1260 438 8044 1284 440 1257 438 410 1257 1290 434 1263 432 417 1251 436 1259 1287 436 412 1255 442 1254 443 1252 435 8045 1293 431 1256 439 410 1258 1289 435 1262 433 416 1253 434 1261 1285 439 410 1258 440 1256 442 1255 442 8038 1290 433 1264 431 407 1260 1287 437 1261 435 413 1254 443 1253 1283 440 408 1259 439 1257 440 1255 442 8038 1289 434 1263 432 417 1251 1285 438 1260 436 413 1255 442 1253 1283 441 408 1260 438 1258 440 1256 442 # -name: POWER +name: Power type: raw frequency: 38000 duty_cycle: 0.330000 data: 1289 408 1289 434 414 1245 1291 433 1264 432 416 1270 417 1243 444 1243 444 1243 444 1244 443 1244 1292 7134 1291 405 1292 431 417 1242 1294 429 1268 427 411 1248 439 1248 439 1274 413 1247 440 1247 440 1247 1289 8241 1295 400 1287 436 412 1247 1289 434 1263 432 416 1242 445 1242 445 1242 445 1241 446 1241 435 1251 1295 7130 1295 400 1287 436 412 1246 1290 406 1291 431 417 1268 419 1241 446 1241 435 1251 436 1277 410 1250 1286 # -name: SPEED+ +name: Speed_up type: raw frequency: 38000 duty_cycle: 0.330000 data: 1369 328 1296 427 411 1275 1261 436 1261 434 414 1245 442 1245 442 1244 443 1244 443 1244 1291 431 417 7972 1291 404 1293 429 409 1251 1295 400 1287 436 412 1273 414 1246 441 1245 442 1245 442 1245 1290 405 443 9076 1287 408 1289 433 415 1271 1264 430 1267 428 410 1276 411 1249 438 1248 439 1248 439 1274 1261 434 414 7974 1289 406 1291 431 417 1242 1294 428 1259 436 412 1273 414 1273 414 1245 442 1245 442 1244 1292 430 418 # -name: POWER +name: Power type: parsed protocol: NECext address: 00 FC 00 00 command: 80 7F 00 00 # -name: SPEED+ +name: Speed_up type: parsed protocol: NECext address: 00 FC 00 00 command: 85 7A 00 00 # -name: MODE +name: Mode type: parsed protocol: NECext address: 00 FC 00 00 command: 81 7E 00 00 # -name: TIMER +name: Timer type: parsed protocol: NECext address: 00 FC 00 00 command: 86 79 00 00 # -name: POWER +name: Power type: raw frequency: 38000 duty_cycle: 0.330000 data: 1299 409 1271 412 433 1211 1293 416 1274 409 436 1207 462 1207 462 1208 461 1208 461 1209 460 1209 1296 7131 1300 410 1270 386 459 1210 1294 389 1301 382 463 1206 464 1206 463 1207 463 1208 462 1208 461 1209 1295 8208 1302 382 1298 385 460 1208 1297 387 1293 390 455 1213 456 1214 466 1205 465 1205 464 1206 463 1206 1298 7129 1302 382 1298 385 460 1208 1297 387 1293 390 455 1213 457 1213 467 1204 465 1205 464 1205 464 1206 1298 8207 1293 391 1299 383 452 1218 1297 386 1294 388 457 1213 456 1214 455 1215 454 1216 454 1216 453 1217 1298 7130 1290 415 1275 406 429 1219 1296 409 1271 411 434 1212 457 1213 456 1213 456 1214 455 1188 481 1215 1299 # -name: SPEED+ +name: Speed_up type: raw frequency: 38000 duty_cycle: 0.330000 data: 1296 386 1294 414 431 1212 1292 416 1274 409 436 1206 463 1207 462 1207 463 1207 463 1208 1297 411 434 7953 1292 417 1273 408 437 1206 1298 411 1269 413 432 1210 459 1210 459 1211 458 1211 458 1211 1293 415 430 9123 1293 389 1301 407 438 1205 1299 410 1269 412 433 1209 460 1210 459 1210 459 1210 459 1210 1294 388 457 7957 1298 410 1270 413 432 1211 1293 389 1301 408 437 1205 464 1206 463 1206 463 1207 463 1207 1297 385 460 9120 1296 387 1293 416 429 1214 1301 381 1299 410 435 1208 461 1209 460 1209 460 1210 459 1210 1294 414 431 7958 1297 385 1295 414 431 1212 1303 380 1300 409 436 1207 462 1207 463 1207 462 1209 460 1208 1296 386 459 # -name: SPEED- +name: Speed_dn type: raw frequency: 38000 duty_cycle: 0.330000 data: 1295 410 1270 411 434 1210 1294 412 1268 414 431 1238 431 1212 1302 405 429 1214 455 1266 1249 406 428 7959 1296 410 1270 412 433 1210 1294 413 1267 414 431 1213 456 1213 1301 405 429 1214 455 1266 1249 406 428 9065 1299 406 1274 408 437 1207 1297 409 1271 411 434 1236 433 1210 1294 412 433 1211 458 1264 1240 414 431 7958 1297 409 1271 411 434 1209 1295 412 1268 414 431 1238 431 1212 1302 405 429 1214 455 1267 1248 407 427 9067 1298 383 1297 410 435 1209 1295 412 1268 414 431 1238 431 1212 1292 415 430 1214 455 1266 1249 407 427 7962 1293 414 1276 406 428 1215 1300 408 1272 410 435 1235 434 1209 1295 411 434 1210 459 1262 1242 413 432 # -name: MODE +name: Mode type: raw frequency: 38000 duty_cycle: 0.330000 data: 1300 381 1299 410 435 1208 1296 413 1267 415 430 1213 456 1213 456 1214 455 1214 1301 408 437 1207 462 7950 1295 413 1267 416 429 1214 1301 381 1299 410 435 1208 461 1208 461 1208 461 1208 1296 386 459 1211 458 9008 1296 387 1293 415 430 1213 1301 407 1273 410 435 1208 461 1208 461 1208 461 1208 1296 386 459 1210 459 7952 1293 416 1274 408 437 1206 1298 384 1296 413 432 1211 458 1211 458 1211 458 1211 1304 405 429 1214 455 9013 1301 407 1273 410 435 1259 1245 412 1268 415 430 1264 405 1213 456 1213 456 1213 1301 407 438 1256 403 7958 1297 410 1270 413 432 1262 1253 405 1275 407 427 1267 402 1216 453 1216 453 1216 1298 409 436 1259 410 # -name: ROTATE +name: Rotate type: raw frequency: 38000 duty_cycle: 0.330000 data: 1294 412 1268 415 430 1265 1250 408 1272 411 434 1260 409 1210 1294 413 432 1264 405 1213 456 1215 454 7959 1296 411 1269 415 430 1265 1250 408 1271 410 435 1260 409 1234 1270 413 432 1264 405 1238 431 1214 455 9016 1298 410 1270 414 431 1264 1251 407 1273 409 436 1260 409 1260 1244 413 432 1263 406 1237 433 1213 456 7959 1296 412 1268 415 430 1265 1250 407 1273 410 435 1260 409 1234 1270 414 431 1264 405 1214 455 1215 454 9017 1297 411 1269 414 431 1264 1251 407 1273 410 435 1260 409 1209 1295 387 458 1237 432 1213 456 1214 456 7959 1296 413 1267 416 429 1239 1276 409 1271 412 433 1235 434 1211 1304 379 455 1239 430 1215 454 1216 453 # -name: TIMER +name: Timer type: raw frequency: 38000 duty_cycle: 0.330000 data: 1294 388 1291 390 455 1215 1289 392 1298 384 451 1220 460 1210 459 1210 1294 388 457 1212 457 1212 457 7954 1301 382 1298 384 461 1207 1297 387 1293 389 456 1212 457 1212 457 1213 1291 392 463 1205 465 1205 464 9263 1295 414 1266 417 428 1214 1301 409 1271 412 433 1209 460 1209 460 1210 1294 415 430 1213 456 1213 456 7959 1296 413 1267 415 430 1213 1302 408 1271 411 434 1208 461 1209 460 1209 1295 414 431 1212 457 1213 456 9272 1297 412 1268 415 430 1212 1292 417 1273 410 435 1207 462 1208 461 1208 1296 413 432 1211 458 1211 458 7956 1299 410 1270 413 432 1210 1294 390 1300 409 436 1206 463 1207 463 1207 1298 387 458 1210 459 1211 458 # -name: POWER +name: Power type: raw frequency: 38000 duty_cycle: 0.330000 data: 1251 410 1245 415 407 1252 1246 415 1250 410 412 1247 408 1252 413 1247 408 1252 413 1247 408 1252 1246 7350 1248 438 1227 433 389 1245 1253 434 1221 439 383 1250 415 1245 410 1250 405 1255 410 1249 406 1255 1253 7340 1247 439 1226 407 415 1245 1253 433 1222 412 410 1250 405 1255 410 1249 406 1254 411 1249 406 1254 1254 7340 1247 412 1253 407 415 1245 1253 407 1248 412 410 1250 405 1255 410 1249 406 1254 411 1248 407 1253 1245 7349 1249 411 1254 406 405 1254 1254 406 1249 411 411 1248 407 1252 413 1246 409 1251 414 1245 410 1250 1248 # -name: TIMER +name: Timer type: raw frequency: 38000 duty_cycle: 0.330000 data: 1250 409 1246 441 381 1252 1246 414 1252 435 387 1246 409 1250 405 1255 1243 417 405 1281 384 1275 380 8188 1244 416 1249 437 385 1249 1249 437 1218 443 379 1253 412 1248 407 1253 1245 415 407 1252 413 1246 409 8186 1246 414 1251 435 387 1272 1226 408 1247 439 383 1276 379 1281 384 1249 1249 437 385 1248 407 1253 412 8181 1251 409 1246 440 382 1277 1221 439 1226 434 378 1255 410 1249 406 1254 1244 416 406 1253 412 1247 408 8187 1245 441 1225 435 387 1273 1225 435 1220 440 382 1251 414 1245 410 1250 1248 412 410 1249 406 1254 411 # -name: SPEED+ +name: Speed_up type: raw frequency: 38000 duty_cycle: 0.330000 data: 1243 444 1221 438 384 1276 1222 438 1217 443 379 1254 411 1274 381 1252 413 1246 409 1251 1247 413 409 8185 1247 440 1225 435 387 1246 1252 408 1247 440 382 1277 388 1245 410 1276 379 1280 385 1249 1249 411 411 8184 1248 412 1243 444 378 1282 1216 444 1221 439 383 1250 405 1254 411 1248 407 1253 412 1248 1250 410 412 8182 1250 410 1245 442 380 1253 1245 415 1250 437 385 1247 408 1252 413 1272 383 1251 414 1272 1226 408 414 8180 1252 409 1246 440 382 1252 1246 440 1225 435 387 1272 383 1250 405 1254 411 1249 406 1254 1244 416 406 8188 1244 416 1249 437 385 1249 1249 411 1244 443 379 1253 412 1273 382 1278 387 1246 409 1251 1247 413 409 # -name: SPEED+ +name: Speed_up type: raw frequency: 38000 duty_cycle: 0.330000 data: 1305 379 1283 402 434 1251 431 1253 1276 408 1275 411 435 1249 1280 404 432 1253 1276 408 438 1247 1282 7144 1281 404 1279 407 439 1247 435 1250 1310 375 1307 379 467 1218 1311 374 431 1254 1306 379 436 1249 1311 7119 1305 380 1302 382 464 1222 460 1224 1305 380 1302 382 464 1221 1308 377 469 1217 1302 383 463 1222 1307 7121 1303 380 1303 382 464 1221 462 1223 1306 378 1305 381 465 1220 1309 375 430 1254 1306 380 435 1250 1279 7148 1276 408 1274 411 435 1250 432 1252 1277 408 1274 410 436 1249 1280 404 432 1253 1276 408 438 1247 1282 # -name: POWER +name: Power type: raw frequency: 38000 duty_cycle: 0.330000 data: 1282 402 1281 404 432 1252 430 1254 1275 408 1275 410 436 1248 435 1249 434 1251 1278 405 431 1254 439 7984 1277 407 1276 408 438 1246 436 1248 1281 402 1281 403 433 1251 432 1253 430 1254 1275 408 438 1246 437 7985 1276 407 1276 408 438 1246 436 1248 1281 402 1281 403 433 1252 431 1253 440 1245 1274 409 437 1248 435 7990 1333 351 1332 352 433 1252 431 1254 1326 358 1335 349 436 1249 434 1250 433 1252 1328 355 440 1244 438 7984 1328 355 1328 356 439 1245 438 1247 1333 350 1333 351 434 1250 433 1252 431 1253 1327 357 438 1246 437 7988 1273 410 1273 411 435 1249 434 1250 1279 405 1278 406 440 1244 439 1246 436 1247 1282 402 434 1251 432 # -name: TIMER +name: Timer type: raw frequency: 38000 duty_cycle: 0.330000 data: 1282 403 1279 405 431 1254 439 1246 1273 412 434 1251 432 1254 1275 410 436 1249 433 1251 431 1254 1275 7152 1283 402 1281 405 431 1254 439 1246 1273 412 434 1251 432 1254 1305 379 436 1249 433 1252 430 1254 1306 7122 1302 382 1311 374 462 1223 459 1226 1303 381 465 1221 461 1223 1306 379 467 1218 464 1221 461 1224 1305 7123 1312 373 1310 375 461 1224 469 1216 1303 381 465 1221 461 1223 1306 379 467 1218 464 1221 461 1224 1305 7123 1312 374 1308 376 460 1225 468 1218 1311 374 462 1223 459 1226 1303 382 464 1222 460 1224 469 1217 1302 7128 1306 379 1303 382 464 1221 461 1224 1305 380 466 1219 463 1221 1277 408 469 1217 465 1219 463 1222 1307 7122 1282 403 1279 405 462 1223 459 1226 1283 402 465 1221 461 1224 1274 410 467 1218 464 1221 461 1224 1274 7155 1280 405 1278 408 438 1247 435 1250 1279 406 440 1245 437 1249 1280 405 431 1255 438 1249 433 1252 1277 # -name: ROTATE +name: Rotate type: raw frequency: 38000 duty_cycle: 0.330000 data: 1279 406 1307 377 438 1246 436 1249 1311 373 463 1221 462 1224 469 1216 466 1218 465 1220 463 1222 460 7967 1304 380 1303 382 464 1221 462 1223 1276 409 468 1217 466 1220 463 1223 459 1225 468 1217 465 1220 462 7966 1275 410 1303 382 464 1220 463 1222 1276 409 468 1218 465 1220 463 1223 459 1225 468 1217 435 1250 463 7965 1306 378 1304 381 465 1220 463 1222 1307 378 468 1217 465 1219 433 1253 440 1245 437 1248 434 1251 462 7966 1275 411 1282 404 432 1254 439 1248 1281 404 432 1254 439 1247 436 1250 433 1253 440 1246 437 1248 435 7995 1276 409 1284 402 434 1252 431 1255 1274 411 435 1251 431 1254 439 1247 436 1250 433 1253 440 1246 436 7992 1279 407 1276 410 436 1249 433 1252 1277 409 447 1238 434 1252 431 1254 439 1247 435 1250 433 1253 440 7990 1281 404 1278 406 440 1245 438 1249 1280 405 441 1245 437 1248 435 1251 432 1254 439 1247 435 1250 433 # -name: POWER +name: Power type: parsed protocol: NEC address: 80 00 00 00 command: 01 00 00 00 # -name: SPEED+ +name: Speed_up type: parsed protocol: NEC address: 80 00 00 00 command: 05 00 00 00 # -name: SPEED- +name: Speed_dn type: parsed protocol: NEC address: 80 00 00 00 command: 1B 00 00 00 -# TIMER DOWN -name: TIMER +# Timer DOWN +name: Timer type: parsed protocol: NEC address: 80 00 00 00 command: 09 00 00 00 -# ROTATE -name: ROTATE +# Rotate +name: Rotate type: parsed protocol: NEC address: 80 00 00 00 command: 03 00 00 00 # -name: POWER +name: Power type: raw frequency: 38000 duty_cycle: 0.330000 data: 1397 357 1370 357 500 1188 1427 331 1343 383 473 1240 476 1240 476 1240 475 1240 475 1240 475 1240 1370 7358 1367 361 1366 361 496 1220 1366 361 1366 361 496 1220 495 1220 495 1220 495 1221 494 1220 495 1220 1366 7361 1365 361 1366 361 495 1221 1365 362 1365 362 494 1221 494 1221 494 1220 495 1220 495 1221 494 1220 1365 7361 1364 361 1366 362 494 1221 1365 362 1365 362 494 1221 494 1221 494 1221 494 1221 494 1221 494 1221 1365 7361 1364 362 1364 362 494 1221 1364 362 1365 362 495 1221 494 1221 494 1221 494 1221 494 1221 494 1221 1364 7361 1364 363 1364 363 493 1222 1364 363 1363 363 493 1223 492 1223 492 1223 492 1247 468 1223 492 1247 1339 7386 1338 388 1338 388 468 1247 1339 388 1338 388 468 1248 467 1247 468 1247 468 1247 468 1248 467 1247 1338 7387 1337 389 1338 389 467 1248 1338 389 1337 389 467 1248 467 1248 467 1248 467 1248 467 1248 467 1248 1337 7388 1336 389 1337 389 467 1249 1336 390 1337 390 466 1249 466 1249 466 1249 466 1249 466 1249 466 1248 1337 7388 1312 414 1312 414 465 1251 1335 391 1337 390 441 1274 441 1274 465 1249 464 1250 442 1274 441 1273 1337 7388 1311 414 1312 415 441 1274 1311 415 1311 415 441 1274 441 1274 441 1274 441 1274 441 1274 441 1274 1311 7413 1311 415 1312 415 441 1274 1311 415 1311 416 440 1275 440 1275 440 1275 440 1275 440 1275 439 1275 1310 7414 1309 416 1310 417 439 1276 1310 417 1309 417 438 1277 438 1277 438 1277 438 1301 413 1301 414 1301 1285 7439 1284 442 1284 442 414 1301 1284 443 1283 443 413 1302 413 1302 413 1302 413 1302 412 1302 413 1302 1283 7441 1283 443 1284 443 412 1303 1283 444 1282 444 412 1303 411 1303 412 1303 412 1303 412 1303 412 1303 1283 7441 1282 445 1281 445 411 1304 1282 470 1256 471 385 1330 385 1330 385 1330 385 1330 385 1330 385 1330 1256 7468 1255 471 1256 471 384 1331 1255 471 1255 472 383 1331 384 1331 383 1332 383 1332 383 1331 383 1332 1254 7470 1253 498 1228 499 356 1358 1228 499 1227 499 356 1359 356 1359 356 1359 356 1359 355 1360 355 1359 1227 7497 1226 526 1200 527 327 1387 1200 527 1199 554 300 1414 301 1415 299 1415 299 1415 300 1416 299 1415 1172 7553 1170 609 1117 583 270 1471 1117 637 1089 692 118 10334 871 # Osc -name: ROTATE +name: Rotate type: raw frequency: 38000 duty_cycle: 0.330000 data: 1395 358 1369 358 499 1215 1399 331 1341 384 472 1241 474 1240 475 1240 1345 383 473 1240 474 1240 474 8239 1366 387 1339 387 469 1246 1339 388 1339 387 469 1246 469 1246 469 1246 1339 388 469 1246 469 1246 469 8242 1339 387 1339 387 469 1246 1339 387 1339 387 469 1246 469 1246 469 1246 1339 387 469 1246 469 1246 468 8243 1338 388 1338 388 469 1246 1339 388 1338 388 468 1246 468 1246 469 1247 1338 388 468 1246 468 1247 468 8243 1338 388 1338 388 468 1246 1338 388 1338 388 468 1246 469 1246 468 1246 1339 387 469 1246 468 1246 468 8218 1363 363 1363 363 493 1222 1363 363 1363 363 493 1222 493 1222 492 1222 1363 363 493 1221 493 1222 493 8217 1363 363 1363 363 493 1222 1363 363 1363 363 493 1246 468 1223 492 1223 1361 375 481 1247 467 1247 467 8243 1337 388 1338 388 468 1247 1337 389 1337 388 468 1247 468 1247 468 1247 1337 389 467 1248 466 1248 466 8243 1337 389 1337 389 467 1248 1336 389 1337 390 466 1248 466 1248 466 1248 1336 390 466 1248 466 1248 466 8244 1336 390 1311 415 465 1249 1336 390 1336 391 465 1250 465 1249 465 1250 1310 415 465 1250 464 1250 439 8270 1310 416 1310 416 440 1275 1310 417 1309 417 438 1300 414 1301 413 1301 1284 442 414 1301 413 1301 413 8297 1284 442 1284 442 413 1301 1284 443 1283 443 413 1302 412 1302 412 1302 1282 443 413 1302 412 1302 412 8298 1282 443 1283 443 413 1302 1283 443 1283 444 412 1303 411 1303 411 1303 1282 444 412 1303 411 1303 411 8299 1280 445 1281 470 385 1329 1255 470 1256 471 384 1330 384 1329 385 1329 1255 471 385 1330 384 1330 384 8326 1253 472 1254 472 384 1331 1253 473 1253 499 356 1357 357 1358 356 1358 1226 499 356 1358 356 1359 355 8355 1224 502 1224 501 355 1385 1199 527 1199 527 328 1386 328 1386 328 1386 1199 527 328 1387 327 1387 327 8409 1171 554 1172 555 300 1414 1172 555 1171 555 300 1416 299 1416 298 1415 1171 556 298 1442 272 1442 272 8438 1143 583 1143 583 271 1471 1115 611 1115 664 179 1536 178 1563 122 1619 1006 # -name: SPEED+ +name: Speed_up type: raw frequency: 38000 duty_cycle: 0.330000 data: 1395 359 1367 358 499 1213 1368 359 1366 359 473 1239 474 1239 474 1238 475 1238 1368 360 497 1215 497 8209 1362 364 1361 366 492 1221 1360 366 1359 366 491 1222 492 1222 491 1221 493 1245 1336 366 492 1222 492 8213 1360 366 1359 389 468 1222 1359 367 1358 390 467 1246 468 1246 468 1245 468 1246 1335 390 467 1246 467 8238 1335 390 1335 390 468 1246 1335 390 1335 390 467 1246 467 1246 468 1246 467 1246 1335 390 467 1246 467 8238 1334 390 1335 390 467 1247 1334 390 1335 391 466 1247 466 1247 466 1247 466 1247 1334 390 467 1247 466 8239 1334 391 1334 391 466 1247 1334 391 1334 391 467 1247 466 1247 466 1247 466 1248 1333 391 466 1248 465 8239 1333 392 1333 392 466 1248 1333 392 1333 392 465 1248 465 1248 465 1248 465 1248 1333 392 465 1248 465 8240 1332 392 1333 392 465 1248 1333 393 1332 393 464 1249 464 1249 464 1249 464 1249 1331 393 465 1249 464 8241 1331 393 1332 393 464 1250 1331 394 1331 394 463 1250 463 1251 462 1250 463 1251 1329 396 462 1251 462 8243 1305 420 1305 444 436 1277 1280 444 1281 445 435 1277 412 1301 436 1277 435 1277 1280 445 436 1277 436 8268 1280 445 1279 445 412 1301 1280 445 1280 445 411 1302 411 1302 411 1302 411 1302 1279 446 411 1302 411 8293 1278 446 1279 446 411 1303 1278 447 1277 447 410 1303 410 1304 409 1329 384 1329 1252 472 385 1329 384 8320 1252 473 1251 473 383 1330 1251 473 1252 473 384 1330 383 1330 383 1330 383 1330 1251 474 382 1330 383 8321 1250 474 1251 475 381 1331 1250 500 1224 500 356 1358 355 1358 355 1358 355 1358 1223 501 355 1358 355 8349 1223 502 1222 528 327 1386 1196 528 1196 530 326 1386 327 1387 326 1386 327 1413 1169 556 299 1414 299 8404 1169 556 1168 584 271 1441 1141 611 1113 637 216 1498 215 1524 178 1562 122 1564 1058 11171 970 # -name: TIMER +name: Timer type: raw frequency: 38000 duty_cycle: 0.330000 data: 1366 359 1366 360 496 1214 1367 360 1395 331 524 1185 474 1239 474 1238 475 1238 475 1238 1343 383 498 8205 1366 386 1338 386 470 1244 1338 386 1339 386 470 1243 470 1244 469 1244 469 1243 470 1244 1338 386 470 8234 1338 386 1339 386 469 1244 1338 386 1339 386 470 1243 470 1220 493 1219 494 1243 470 1244 1338 362 494 8233 1339 362 1363 386 469 1244 1338 386 1339 386 469 1244 469 1244 469 1244 469 1244 469 1244 1338 387 468 8234 1338 386 1338 387 468 1244 1338 387 1337 387 468 1244 469 1244 468 1245 469 1244 469 1244 1338 387 468 8234 1337 387 1338 387 465 1247 1338 387 1338 387 468 1245 468 1244 444 1269 468 1246 467 1245 1337 387 468 8235 1337 387 1337 388 468 1245 1336 388 1336 388 466 1246 467 1245 468 1245 467 1247 467 1245 1312 412 467 8235 1312 412 1312 412 443 1270 1335 390 1311 412 468 1246 466 1246 467 1246 467 1246 467 1246 1311 412 467 8236 1311 413 1311 413 442 1271 1311 413 1311 413 442 1271 466 1247 466 1246 442 1271 442 1271 1311 413 442 8260 1311 413 1311 413 442 1271 1311 413 1311 414 441 1271 442 1271 465 1248 464 1249 465 1247 1310 414 441 8261 1334 390 1310 414 466 1247 1335 390 1333 391 465 1248 465 1248 465 1248 465 1248 465 1248 1334 390 465 8237 1334 391 1333 390 465 1248 1309 415 1309 416 464 1249 464 1249 463 1250 462 1275 438 1274 1307 394 438 8287 1283 441 1283 441 438 1274 1283 441 1283 442 436 1276 414 1299 438 1275 413 1300 412 1300 1282 442 413 8289 1282 443 1281 443 412 1301 1281 443 1281 443 412 1301 411 1302 411 1302 410 1327 385 1327 1255 469 386 8316 1255 470 1254 470 385 1327 1255 470 1254 470 385 1327 385 1328 384 1328 385 1328 385 1328 1254 470 385 8317 1253 471 1253 470 385 1329 1253 471 1253 471 384 1329 383 1330 382 1330 382 1330 383 1330 1252 473 382 8344 1226 498 1226 498 357 1356 1226 498 1226 498 356 1356 356 1356 356 1356 356 1356 356 1356 1226 499 355 8346 1224 499 1225 525 329 1384 1198 526 1198 525 329 1384 328 1384 328 1384 328 1384 329 1384 1198 526 328 8373 1198 526 1198 527 327 1385 1197 553 1171 553 301 1412 300 1412 300 1412 300 1386 327 1412 1170 554 299 8401 1170 554 1170 555 298 1414 1169 581 1143 582 271 1440 272 1440 272 1440 272 1441 271 1441 1142 609 244 8458 1113 636 1088 663 178 1507 1088 691 1033 -# TIMER OFF -name: TIMER +# Timer OFF +name: Timer type: raw frequency: 38000 duty_cycle: 0.330000 data: 3583 1639 534 386 484 1208 534 386 484 386 485 386 484 387 483 386 484 386 485 386 457 394 476 394 451 419 452 419 476 1237 506 393 477 394 475 395 474 396 473 397 473 398 472 1270 472 399 471 1271 471 1270 471 399 470 401 469 1273 469 402 468 427 443 427 443 427 443 1299 443 427 443 427 444 427 444 427 444 1298 443 1299 442 427 444 427 445 426 445 425 446 425 447 424 447 399 472 398 473 1294 445 426 446 400 471 399 472 1294 446 425 447 398 473 1295 446 400 471 398 472 74544 3552 1672 472 399 471 1271 471 399 471 400 470 400 470 400 470 400 471 400 470 400 470 401 470 401 469 401 469 401 470 1273 470 400 470 401 469 401 469 401 470 401 469 401 470 1273 470 401 469 1273 470 1272 469 401 469 401 469 1274 468 401 469 401 469 401 470 402 469 1273 469 401 469 401 469 402 469 401 469 1273 469 1273 469 401 469 402 468 402 469 426 444 427 444 427 444 426 445 426 444 1274 468 402 469 426 444 427 443 1275 467 403 467 427 443 1275 467 402 468 427 443 # OFF -name: POWER +name: Power type: raw frequency: 38000 duty_cycle: 0.330000 data: 1366 388 1295 387 446 1164 1368 387 1296 387 448 1164 518 1164 493 1189 517 1165 492 1189 493 1189 493 7851 1365 387 1270 388 446 1190 1365 387 1295 387 447 1192 490 1193 489 1193 489 1194 488 1194 488 1193 489 7855 1337 386 1296 386 448 1193 1338 386 1296 386 448 1193 489 1193 489 1193 489 1193 489 1193 489 1193 489 7855 1337 386 1297 386 448 1194 1337 386 1296 386 448 1194 488 1194 488 1194 488 1194 488 1194 488 1194 488 8160 1336 387 1296 387 447 1194 1337 387 1296 386 448 1194 488 1194 488 1194 488 1194 488 1194 488 1194 488 7855 1336 386 1297 387 447 1195 1336 386 1297 386 448 1195 486 1195 487 1195 487 1195 487 1196 486 1196 486 7881 1310 387 1272 397 436 1245 1286 397 1285 397 436 1246 436 1246 436 1247 435 1247 435 1248 434 1248 434 7934 1259 424 1259 424 408 1274 1258 424 1259 424 408 1274 408 1274 408 1274 408 1274 408 1274 408 1274 408 8239 1258 425 1258 424 408 1274 1258 424 1258 425 407 1273 408 1273 409 1273 408 1273 408 1274 408 1273 408 7907 1283 424 1258 424 409 1248 1283 399 1283 400 433 1247 434 1247 434 1247 434 1247 434 1247 434 1247 434 7905 1282 424 1258 425 407 1273 1257 425 1257 425 407 1273 407 1274 407 1274 407 1274 407 1275 406 1275 406 7958 1230 478 1204 478 353 1328 1204 478 1204 453 378 1327 353 1328 353 1302 379 1301 380 1301 380 1300 381 # -name: POWER +name: Power type: raw frequency: 38000 duty_cycle: 0.330000 data: 1341 337 1339 338 496 1178 1395 305 1316 337 1339 338 496 1178 526 1151 526 1151 1366 335 1341 335 498 7888 1338 338 1337 339 495 1182 1336 340 1336 340 1336 340 494 1182 494 1182 494 1183 1336 340 1336 340 494 7892 1336 340 1336 340 494 1183 1336 340 1336 340 1336 340 494 1183 494 1183 494 1183 1335 341 1335 340 494 7893 1335 341 1335 341 493 1183 1336 341 1335 341 1335 341 493 1183 493 1183 494 1183 1335 341 1335 341 493 7893 1335 341 1335 341 493 1184 1334 341 1335 341 1335 341 493 1184 493 1184 493 1184 1335 341 1335 342 492 7894 1334 342 1334 342 492 1184 1334 342 1334 341 1335 342 492 1184 493 1184 492 1185 1334 342 1334 342 492 7894 1334 342 1334 342 492 1185 1333 343 1333 342 1334 342 492 1185 492 1185 492 1185 1333 343 1333 343 491 7895 1333 343 1333 343 491 1185 1333 343 1333 344 1332 344 490 1186 490 1186 491 1186 1333 344 1332 344 490 7897 1331 368 1308 368 466 1211 1308 368 1308 368 1308 368 466 1211 465 1211 466 1211 1307 368 1308 369 465 7921 1307 368 1308 368 466 1211 1308 368 1308 369 1307 368 466 1211 466 1211 465 1211 1308 369 1307 369 465 7921 1307 369 1307 369 465 1212 1307 369 1307 369 1307 369 465 1212 465 1212 465 1212 1307 369 1307 369 465 7922 1306 370 1306 370 464 1212 1307 370 1306 370 1306 370 464 1212 464 1213 464 1212 1306 370 1306 370 464 7922 1306 370 1306 371 463 1213 1306 370 1306 371 1305 371 463 1213 439 1238 439 1238 1305 371 1305 371 462 7924 1280 396 1280 396 438 1238 1281 396 1280 396 1280 396 438 1239 437 1239 438 1239 1280 396 1280 397 437 7949 1279 397 1279 397 437 1240 1279 398 1278 422 1254 422 412 1265 411 1265 412 1265 1254 422 1254 422 412 7974 1254 422 1254 422 412 1265 1254 423 1253 423 1253 449 384 1293 383 1293 383 1294 1225 451 1225 452 382 8056 1171 505 1171 532 188 1463 1169 # -name: MODE +name: Mode type: raw frequency: 38000 duty_cycle: 0.330000 data: 1349 364 1321 363 490 1219 1324 364 1294 389 463 1245 1324 363 462 1219 491 1221 462 1223 461 1226 484 8019 1292 393 1292 420 433 1252 1292 393 1292 420 433 1252 1292 393 460 1252 433 1252 460 1226 459 1252 433 8021 1317 393 1292 394 459 1226 1318 393 1292 394 458 1226 1318 394 432 1253 459 1226 459 1253 432 1253 459 # -name: TIMER +name: Timer type: raw frequency: 38000 duty_cycle: 0.330000 data: 1376 337 1348 363 462 1219 1325 390 1295 388 1322 363 490 1218 466 1219 465 1220 490 1222 1319 369 1316 7187 1292 393 1292 393 460 1252 1292 370 1315 393 1292 420 433 1252 433 1252 460 1252 433 1252 1292 393 1292 7188 1291 393 1318 393 433 1252 1292 393 1319 393 1291 393 460 1226 459 1252 432 1253 459 1225 1319 393 1292 # -name: POWER +name: Power type: parsed protocol: NECext address: 00 F3 00 00 command: 91 6E 00 00 # -name: TIMER +name: Timer type: parsed protocol: NECext address: 00 F3 00 00 command: 96 69 00 00 # -name: POWER +name: Power type: raw frequency: 38000 duty_cycle: 0.330000 data: 9253 4427 684 486 656 486 656 486 682 461 681 1573 680 1575 678 464 677 491 651 1604 650 1604 650 1604 650 1604 650 491 651 491 651 1604 650 1604 651 491 651 491 651 1604 650 1604 650 491 651 491 651 491 652 1604 650 1604 651 1604 650 491 651 491 652 1604 650 1604 650 1604 651 491 651 39948 9250 2183 651 # -name: SPEED+ +name: Speed_up type: raw frequency: 38000 duty_cycle: 0.330000 data: 9226 4450 657 484 657 484 658 484 657 485 657 1596 658 1597 681 487 653 488 653 1602 652 1602 652 1602 652 1602 652 490 652 490 652 1602 652 1602 652 490 652 490 652 490 652 1603 652 490 652 490 652 490 652 1602 652 1602 652 1602 653 1602 652 490 652 1602 652 1602 652 1602 653 489 653 39949 9250 2179 653 # OSC -name: ROTATE +name: Rotate type: raw frequency: 38000 duty_cycle: 0.330000 data: 9231 4449 657 484 658 483 659 483 659 483 659 1595 659 1595 659 485 681 461 680 1601 652 1602 653 1601 653 1601 653 488 654 488 654 1602 653 1601 653 488 654 488 654 1602 653 1602 652 1602 652 488 654 488 654 1602 653 1601 653 1602 652 488 654 488 654 488 654 1602 652 1602 653 488 654 39978 9229 2174 654 96468 9259 2146 679 # -name: TIMER +name: Timer type: raw frequency: 38000 duty_cycle: 0.330000 data: 9384 4452 658 485 657 484 658 484 659 485 657 1597 658 1597 682 487 655 488 654 1603 652 1603 653 1603 653 1604 653 491 653 491 653 1603 653 1603 653 1603 653 491 653 1604 652 490 654 1603 652 490 653 490 653 1603 652 490 653 1603 652 490 653 1603 652 490 653 1603 652 1603 652 490 653 39953 9263 2181 652 # -name: POWER +name: Power type: parsed protocol: NEC address: 01 00 00 00 command: 83 00 00 00 # -name: SPEED+ +name: Speed_up type: parsed protocol: NEC address: 01 00 00 00 command: 87 00 00 00 # -name: TIMER +name: Timer type: parsed protocol: NEC address: 01 00 00 00 command: 8B 00 00 00 # -name: POWER +name: Power type: raw frequency: 38000 duty_cycle: 0.330000 data: 2256 695 788 1354 789 1349 789 1340 792 702 762 697 763 692 789 661 788 720 786 693 786 689 785 685 784 681 784 676 784 1334 784 1330 783 102265 2255 695 787 1356 786 1352 785 1348 785 681 783 676 783 671 784 666 784 724 784 696 783 691 784 686 784 681 783 676 784 1335 783 1330 783 # OSC -name: ROTATE +name: Rotate type: raw frequency: 38000 duty_cycle: 0.330000 data: 2227 749 733 1382 761 1379 866 1292 841 566 898 591 868 588 866 582 760 1412 867 612 866 576 898 603 867 598 866 1256 759 695 867 1246 759 101611 2335 615 868 1245 899 1268 869 1266 867 566 898 591 760 694 761 689 760 1411 760 720 760 715 759 710 759 705 759 1363 760 696 758 1352 761 # -name: ROTATE +name: Rotate type: raw frequency: 38000 duty_cycle: 0.330000 data: 2224 708 755 1419 757 1443 756 685 756 1470 757 709 758 710 784 657 836 708 756 763 785 1468 782 1444 755 737 756 712 754 1471 781 1419 780 101298 2250 656 778 1420 809 1391 753 686 755 1472 779 687 779 687 752 688 831 714 778 741 750 1502 776 1422 752 740 752 741 751 1448 751 1475 749 # -name: POWER +name: Power type: raw frequency: 38000 duty_cycle: 0.330000 data: 2203 675 786 1388 867 1361 786 678 786 1444 758 708 759 707 760 707 786 735 757 760 786 735 757 736 781 711 757 734 759 733 785 734 758 101185 2198 708 757 1416 757 1442 756 685 755 1445 780 685 780 662 776 689 803 742 778 740 753 766 779 715 777 714 779 714 778 690 776 742 752 # StrengthUp -name: SPEED+ +name: Speed_up type: raw frequency: 38000 duty_cycle: 0.330000 data: 2224 685 782 1419 808 1418 779 687 757 1470 757 710 757 684 809 657 809 736 758 1469 758 736 756 1470 757 762 755 1446 782 1418 781 712 755 101352 2223 707 758 1417 834 1392 781 685 781 1446 780 687 754 687 754 713 804 741 779 1447 779 715 778 1447 779 740 752 1448 778 1422 779 690 775 # StrengthDown -name: SPEED- +name: Speed_dn type: raw frequency: 38000 duty_cycle: 0.330000 data: 2222 685 781 1419 808 1419 780 686 755 1447 781 684 783 686 780 686 807 1470 757 1470 756 1471 756 1497 756 1445 780 1447 780 1421 779 1421 754 101509 2250 684 777 1421 781 1444 754 687 754 1472 779 687 779 688 753 688 830 1448 777 1449 778 1448 752 1501 752 1450 773 1451 778 1422 778 1423 777 # -name: POWER +name: Power type: parsed protocol: NECext address: 41 59 00 00 command: 05 FA 00 00 # -name: SPEED+ +name: Speed_up type: parsed protocol: NECext address: 41 59 00 00 command: 44 BB 00 00 # OFF -name: POWER +name: Power type: raw frequency: 38000 duty_cycle: 0.330000 data: 1332 391 1303 359 485 1241 1304 391 1303 391 452 1242 452 1242 452 1243 451 1243 452 1243 452 1242 1303 7275 1303 391 1303 390 453 1240 1330 364 1328 366 477 1218 476 1218 476 1220 474 1220 474 1220 474 1220 1325 7252 1326 369 1325 369 475 1219 1325 369 1325 369 475 1219 475 1219 475 1219 475 1219 475 1219 475 1219 1326 7254 1326 369 1326 369 475 1219 1326 369 1326 369 475 1219 475 1220 475 1219 475 1219 475 1220 475 1220 1325 7256 1325 370 1325 370 474 1220 1325 370 1325 370 474 1220 475 1220 474 1220 474 1220 474 1221 474 1221 1324 7281 1301 370 1325 370 474 1220 1325 370 1324 370 474 1221 474 1221 473 1221 473 1221 473 1221 474 1220 1325 7256 1325 370 1324 371 473 1221 1324 370 1324 370 474 1221 473 1221 473 1220 474 1220 474 1220 474 1220 1324 7256 1324 371 1323 371 473 1221 1323 371 1323 371 473 1221 473 1221 473 1221 473 1221 473 1221 473 1221 1323 7256 1323 371 1323 371 473 1222 1322 372 1322 372 472 1222 472 1222 472 1222 472 1222 472 1222 472 1222 1322 7281 1297 372 1322 373 471 1246 1298 396 1298 397 447 1247 447 1247 447 1247 447 1247 447 1247 447 1247 1297 7281 1297 397 1297 397 447 1247 1297 397 1297 397 447 1247 447 1247 447 1247 447 1247 447 1248 446 1248 1296 7282 1296 398 1296 398 446 1248 1296 398 1296 398 447 1248 446 1248 446 1248 446 1247 447 1247 447 1248 1295 7281 1296 398 1296 398 446 1248 1296 399 1295 399 446 1248 446 1248 446 1248 446 1248 446 1248 446 1248 1296 7282 1296 399 1295 399 445 1248 1295 399 1295 399 445 1248 446 1249 444 1249 445 1249 445 1249 445 1249 1294 7282 1294 399 1295 400 444 1249 1295 399 1294 400 444 1250 444 1249 445 1250 444 1249 445 1250 444 1250 1294 7282 1294 400 1294 400 444 1250 1294 400 1294 401 443 1251 443 1250 444 1250 444 1250 444 1250 443 1251 1292 7284 1292 401 1293 402 442 1251 1292 402 1291 403 442 1276 418 1252 442 1276 418 1277 417 1277 417 1277 1242 7334 1268 427 1242 452 392 1302 1242 452 1242 452 392 1302 392 1302 392 1302 392 1302 391 1302 392 1302 1242 7335 1241 453 1240 453 391 1302 1241 453 1240 453 391 1303 390 1303 390 1303 390 1304 390 1303 391 1304 1240 7361 1216 479 1216 479 364 1330 1215 479 1215 480 363 1330 364 1330 364 1330 364 1330 364 1330 364 1330 1214 7362 1213 480 1214 480 363 1331 1213 481 1213 482 361 1332 362 1332 362 1331 363 1331 362 1332 362 1332 1212 7391 1185 508 1185 509 334 1359 1185 509 1184 509 334 1359 335 1359 334 1386 307 1386 307 1386 307 1386 1159 7445 1131 562 1131 616 196 1471 1104 # -name: POWER +name: Power type: raw frequency: 38000 duty_cycle: 0.330000 data: 2265 691 792 690 792 684 793 1342 821 1310 821 640 822 634 822 660 792 718 791 690 791 685 791 680 791 675 791 670 790 1330 789 662 788 99517 2230 723 760 721 760 715 761 1374 761 1368 762 699 762 694 762 689 762 747 761 719 761 715 761 710 761 705 761 701 760 1360 760 691 760 # -name: SPEED+ +name: Speed_up type: raw frequency: 38000 duty_cycle: 0.330000 data: 2312 617 867 641 840 577 899 1269 866 1265 865 622 839 593 864 612 838 670 839 1306 839 611 865 1271 864 627 839 1259 865 590 866 611 840 102129 2316 670 813 667 813 664 811 1323 810 1319 759 702 759 697 759 692 759 750 759 1386 758 717 759 1376 758 706 759 1365 759 696 759 691 760 # -name: SPEED- +name: Speed_dn type: raw frequency: 38000 duty_cycle: 0.330000 data: 2232 725 759 722 759 717 759 1375 760 1370 760 702 759 697 759 692 788 1384 788 1356 788 1351 788 1347 787 1342 787 1338 786 670 785 1330 784 99591 2229 724 760 721 785 690 785 1349 784 1345 784 677 783 673 782 669 781 1391 781 1363 781 1359 780 1353 781 1349 780 1343 781 675 780 1334 780 # -name: TIMER +name: Timer type: raw frequency: 38000 duty_cycle: 0.330000 data: 2230 724 760 720 761 715 761 1374 761 1370 760 701 760 696 760 691 786 1385 760 720 787 689 760 710 760 705 786 1339 785 670 785 665 784 98757 2224 729 754 726 755 721 754 1380 754 1375 754 706 754 701 754 696 754 1418 754 726 754 720 755 716 755 710 755 1369 755 700 755 696 755 # -name: ROTATE +name: Rotate type: raw frequency: 38000 duty_cycle: 0.330000 data: 2256 698 786 695 786 689 787 1348 787 1342 787 673 788 668 787 663 787 722 786 696 784 1353 786 1375 759 706 759 702 783 672 783 1332 782 102265 2310 645 838 668 812 664 811 1323 810 1319 810 651 809 647 808 642 808 701 807 673 807 1332 807 1327 807 658 808 653 807 648 807 1307 807 # -name: POWER +name: Power type: raw frequency: 38000 duty_cycle: 0.330000 data: 1356 337 1423 337 516 1157 1298 409 1296 416 448 1274 451 1276 452 1274 450 1274 449 1277 449 1275 1301 7091 1301 407 1300 405 450 1267 1302 407 1301 414 450 1274 451 1275 451 1275 451 1276 450 1275 451 1274 1302 7074 1303 406 1302 406 450 1268 1301 409 1299 416 449 1277 472 1254 473 1253 473 1254 472 1254 473 1252 1323 7069 1325 384 1300 408 470 1247 1324 387 1299 417 471 1253 472 1254 472 1254 472 1254 472 1254 472 1252 1324 7052 1324 384 1300 408 472 1246 1324 387 1299 417 472 1253 472 1254 472 1254 472 1254 473 1254 472 1252 1324 7064 1325 385 1323 385 471 1246 1324 387 1323 394 471 1254 471 1254 472 1254 472 1254 472 1254 472 1252 1324 7053 1324 385 1323 385 471 1247 1323 387 1322 394 471 1254 472 1254 472 1255 471 1255 471 1255 472 1253 1323 7070 1323 385 1323 385 471 1247 1323 388 1322 395 470 1254 472 1255 471 1255 471 1255 471 1255 471 1253 1323 7054 1323 386 1322 386 470 1248 1322 413 1297 396 470 1255 470 1256 470 1256 470 1256 470 1256 471 1254 1322 7071 1322 411 1297 387 469 1249 1321 414 1296 396 470 1280 445 1281 446 1281 445 1282 445 1282 445 1280 1296 7076 1296 412 1296 412 444 1274 1297 413 1297 421 445 1281 445 1282 444 1282 444 1282 445 1282 444 1280 1296 7098 1295 412 1296 412 445 1275 1296 414 1296 421 445 1282 444 1282 445 1282 444 1283 444 1282 445 1280 1296 7082 1296 412 1296 412 445 1275 1295 414 1296 421 444 1282 444 1282 444 1283 444 1283 444 1282 445 1280 1296 7098 1296 413 1295 413 444 1275 1295 415 1295 422 444 1283 443 1282 444 1283 443 1282 445 1282 444 1281 1295 7082 1295 413 1295 413 444 1275 1295 415 1294 423 443 1283 443 1283 443 1283 443 1283 443 1283 443 1281 1294 7093 1295 413 1295 414 443 1276 1294 415 1295 423 443 1283 443 1283 443 1283 443 1283 444 1283 444 1280 1295 7082 1295 414 1294 414 443 1276 1294 416 1294 423 443 1283 443 1283 443 1283 443 1283 444 1283 444 1281 1294 7098 1295 414 1294 414 443 1276 1294 416 1294 424 442 1284 443 1283 443 1283 443 1284 443 1283 443 1281 1294 7083 1294 414 1294 415 442 1277 1293 417 1293 425 441 1284 442 1284 442 1284 442 1284 442 1284 443 1282 1293 7099 1294 415 1293 416 441 1278 1292 418 1292 425 441 1285 441 1285 441 1285 442 1285 441 1285 441 1283 1292 7083 1293 417 1291 441 415 1279 1292 443 1267 451 415 1286 440 1286 441 1286 440 1285 441 1286 440 1284 1291 7096 1292 441 1267 442 415 1304 1266 444 1266 451 415 1311 415 1287 439 1287 440 1311 415 1286 440 1285 1290 7085 1291 442 1241 467 414 1304 1266 445 1241 476 414 1313 414 1312 415 1311 415 1312 415 1312 414 1310 1241 7151 1242 467 1241 467 415 1305 1241 469 1241 477 412 1314 414 1312 414 1312 414 1312 414 1312 414 1310 1241 7135 1241 467 1241 468 389 1330 1241 470 1240 477 389 1337 389 1337 414 1312 414 1313 413 1313 389 1335 1241 7151 1241 469 1239 470 386 1331 1240 496 1214 503 362 1338 388 1338 388 1338 388 1338 388 1338 388 1336 1240 7130 1241 494 1214 495 361 1357 1214 497 1213 504 362 1364 362 1364 362 1364 363 1364 362 1364 362 1362 1214 7153 1239 495 1213 496 360 1358 1213 498 1212 531 334 1365 362 1365 361 1365 361 1365 362 1364 362 1363 1213 7162 1213 496 1212 522 334 1359 1212 524 1186 532 333 1367 359 1366 360 1366 361 1365 361 1365 361 1364 1211 7180 1212 523 1185 550 306 1387 1185 552 1157 586 278 1395 332 1394 332 1394 332 1393 333 1393 334 1391 1184 7190 1185 576 1131 604 250 1415 1158 660 1049 2341 251 1448 278 1422 305 1448 278 1448 278 1447 1130 7229 1157 # -name: SPEED+ +name: Speed_up type: raw frequency: 38000 duty_cycle: 0.330000 data: 1357 353 1327 382 448 1239 1333 409 1301 416 477 1246 452 1274 452 1274 453 1273 479 1246 1330 416 448 7967 1300 409 1299 410 446 1273 1299 412 1298 419 446 1280 446 1281 446 1281 446 1281 446 1279 1298 419 446 7958 1298 411 1297 410 446 1273 1298 412 1298 419 446 1280 446 1281 445 1281 446 1281 445 1279 1298 419 446 7967 1298 410 1298 411 445 1274 1297 413 1297 420 445 1281 445 1281 445 1281 445 1282 445 1279 1298 420 445 7957 1297 411 1297 411 445 1274 1297 413 1297 420 445 1281 445 1281 445 1282 444 1282 444 1280 1296 420 445 7962 1297 411 1297 411 445 1274 1297 413 1297 420 445 1282 444 1282 444 1282 444 1282 444 1280 1297 421 444 7957 1296 412 1297 411 444 1275 1296 414 1296 421 444 1282 444 1283 443 1283 443 1282 444 1281 1296 421 444 7968 1296 412 1296 412 444 1275 1296 414 1296 421 444 1283 443 1283 443 1283 443 1283 443 1281 1296 422 443 7958 1295 413 1295 413 443 1276 1295 415 1295 422 443 1283 443 1284 442 1284 442 1284 442 1282 1294 422 443 7970 1293 414 1294 414 442 1277 1294 416 1294 423 442 1284 442 1309 417 1309 417 1309 417 1307 1269 424 441 7978 1270 416 1292 414 442 1302 1269 440 1270 424 441 1309 417 1309 417 1310 417 1309 417 1307 1270 448 417 7994 1269 439 1269 439 416 1302 1269 441 1269 448 416 1310 416 1310 416 1310 416 1310 416 1308 1269 448 416 7984 1269 439 1268 440 416 1303 1268 442 1267 449 415 1310 416 1310 416 1310 416 1310 416 1309 1268 449 416 7994 1268 440 1268 440 415 1303 1268 442 1268 449 415 1311 415 1311 415 1311 415 1311 415 1309 1267 450 415 7985 1267 441 1267 441 414 1304 1266 444 1267 450 414 1311 415 1312 413 1312 414 1312 414 1310 1265 452 414 7991 1266 442 1242 466 413 1306 1241 468 1242 475 414 1337 388 1338 388 1338 388 1338 388 1336 1217 501 386 8013 1215 492 1216 492 387 1331 1216 494 1216 501 363 1363 362 1363 363 1363 363 1363 387 1338 1215 502 362 8047 1215 493 1215 492 363 1356 1215 495 1215 502 362 1364 361 1364 362 1364 362 1364 362 1363 1214 503 361 8063 1189 494 1214 494 361 1382 1189 496 1214 503 361 1390 335 1391 335 1391 335 1391 335 1389 1188 529 335 8074 1188 520 1188 520 334 1385 1187 522 1187 529 334 1392 333 1417 308 1418 308 1419 307 1417 1161 556 307 8092 1160 547 1161 547 307 1412 1160 550 1160 557 306 1419 306 1446 279 1421 305 1446 279 1445 1133 584 279 8125 1133 575 1133 576 277 1466 1106 603 1107 611 251 1474 251 1501 224 1502 224 1528 186 1511 1079 638 224 8228 1025 735 972 2640 786 # -name: SPEED+ +name: Speed_up type: parsed protocol: NEC address: 01 00 00 00 command: 1A 00 00 00 # -name: POWER +name: Power type: parsed protocol: NEC address: 01 00 00 00 command: 1D 00 00 00 # -name: ROTATE +name: Rotate type: parsed protocol: NEC address: 01 00 00 00 command: 18 00 00 00 # -name: TIMER +name: Timer type: parsed protocol: NEC address: 01 00 00 00 command: 0D 00 00 00 # -name: POWER +name: Power type: parsed protocol: NECext address: 80 DE 00 00 command: 00 FF 00 00 # -name: SPEED+ +name: Speed_up type: parsed protocol: NECext address: 80 DE 00 00 command: 08 F7 00 00 # -name: SPEED- +name: Speed_dn type: parsed protocol: NECext address: 80 DE 00 00 command: 10 EF 00 00 # -name: POWER +name: Power type: raw frequency: 38000 duty_cycle: 0.330000 data: 4640 4393 562 1442 562 1443 562 1443 537 1470 535 1468 562 1444 562 2398 562 1444 562 1446 560 2424 535 1470 535 2425 534 1472 533 1473 533 2427 533 1474 531 1473 4577 4456 531 1473 531 1474 532 1474 531 1474 532 1474 531 1474 531 2429 531 1474 531 1474 531 2429 531 1474 531 2429 531 1474 531 1474 531 2429 531 1474 531 14007 9125 2259 530 # -name: SPEED+ +name: Speed_up type: raw frequency: 38000 duty_cycle: 0.330000 data: 4609 4425 563 1441 563 1442 563 1442 538 1469 537 1469 561 1444 562 2400 560 1470 535 1470 536 1470 536 2424 536 1470 535 1471 534 1472 533 2427 533 2427 533 1472 4580 4454 531 1472 533 1474 532 1474 531 1474 532 1474 532 1474 532 2428 532 1474 532 1474 532 1474 532 2428 532 1474 532 1474 532 1474 532 2428 532 2429 532 14008 9127 2258 528 50213 9131 2253 532 # -name: MODE +name: Mode type: raw frequency: 38000 duty_cycle: 0.330000 data: 4607 4424 563 1441 563 1443 563 1444 536 1469 537 1469 537 1496 534 2399 561 1470 535 2424 536 1470 536 1470 535 2424 535 1471 534 1472 534 1472 533 2427 533 1472 4579 4455 531 1472 532 1474 532 1474 532 1474 532 1474 532 1474 532 2429 531 1474 532 2428 532 1474 532 1474 532 2429 532 1474 532 1474 532 1474 532 2428 532 14007 9125 2258 530 # -name: TIMER +name: Timer type: raw frequency: 38000 duty_cycle: 0.330000 data: 4604 4427 561 1442 562 1443 561 1444 537 1469 536 1469 562 1445 561 2399 560 1446 559 2424 534 1472 533 2426 533 1473 532 2428 531 1475 531 1474 531 1474 531 1473 4575 4457 530 1473 531 1475 531 1475 530 1475 531 1475 531 1475 530 2429 531 1475 530 2429 530 1475 530 2430 530 1475 530 2429 531 1475 531 1475 531 1475 530 14008 9122 2260 530 # -name: ROTATE +name: Rotate type: raw frequency: 38000 duty_cycle: 0.330000 data: 4582 4424 562 1442 562 1471 534 1471 509 1496 510 1496 534 1472 534 2424 536 1470 536 1470 536 1470 536 1470 535 2424 535 2425 534 2426 534 1472 533 1473 533 1472 4581 4453 532 1472 532 1473 533 1473 533 1473 533 1473 533 1473 533 2428 532 1473 532 1473 532 1474 532 1474 532 2428 533 2428 532 2428 532 1474 532 1474 532 # -name: POWER +name: Power type: raw frequency: 38000 duty_cycle: 0.330000 data: 1369 311 1327 312 498 1162 1286 355 1285 362 457 1221 458 1221 458 1221 458 1222 457 1221 458 1219 1312 6796 1310 330 1282 356 454 1219 1281 360 1280 367 452 1227 452 1227 452 1227 452 1227 452 1227 452 1225 1280 6815 1280 359 1279 359 451 1220 1280 361 1279 368 451 1228 451 1228 451 1228 451 1228 451 1228 451 1226 1279 6827 1279 382 1256 382 428 1245 1255 384 1256 391 427 1251 428 1252 426 1252 427 1252 427 1252 427 1250 1255 6838 1255 383 1255 383 426 1245 1255 385 1255 392 426 1252 427 1252 426 1252 426 1252 427 1252 426 1250 1255 6849 1255 383 1255 383 426 1245 1255 385 1254 392 426 1252 426 1252 426 1252 426 1252 426 1252 426 1250 1254 6835 1254 383 1254 383 426 1245 1254 385 1254 392 426 1252 426 1252 426 1252 426 1252 426 1252 426 1250 1254 6852 1254 383 1254 384 425 1245 1254 386 1253 392 426 1253 425 1252 426 1252 426 1253 425 1253 425 1251 1253 6835 1253 384 1253 384 425 1245 1253 386 1253 393 425 1252 425 1253 425 1253 425 1253 425 1253 425 1251 1253 6852 1252 384 1253 384 425 1246 1252 386 1253 393 425 1253 424 1253 425 1253 425 1254 424 1253 425 1252 1252 6835 1253 385 1252 385 424 1247 1252 387 1252 394 424 1254 424 1254 424 1254 424 1254 424 1254 424 1252 1251 6850 1251 386 1251 386 423 1248 1251 388 1250 395 423 1255 422 1256 422 1279 399 1280 398 1279 399 1277 1227 6862 1226 411 1226 411 398 1273 1226 413 1226 420 397 1280 398 1279 398 1280 397 1280 398 1280 398 1278 1226 6892 1226 411 1225 411 397 1273 1225 413 1225 420 397 1280 397 1280 398 1280 397 1280 397 1280 397 1279 1224 # -name: SPEED+ +name: Speed_up type: raw frequency: 38000 duty_cycle: 0.330000 data: 1308 332 1305 332 479 1190 1309 333 1307 364 455 1199 479 1198 481 1198 480 1198 480 1197 1331 339 480 7657 1306 332 1305 332 479 1194 1304 335 1305 342 478 1201 477 1201 478 1201 477 1201 478 1199 1305 342 478 7647 1305 333 1304 333 478 1194 1304 335 1304 342 477 1201 477 1201 478 1201 477 1201 477 1199 1305 342 478 7660 1303 334 1304 333 478 1194 1304 336 1303 343 477 1202 477 1202 476 1202 477 1202 476 1200 1304 343 477 7647 1303 334 1304 334 476 1195 1303 336 1303 343 476 1202 476 1202 476 1202 476 1202 476 1200 1303 343 476 7659 1302 335 1302 335 476 1196 1302 337 1302 344 475 1203 475 1203 475 1203 475 1203 475 1201 1302 344 476 7646 1302 335 1300 338 474 1197 1300 338 1301 345 474 1204 474 1204 474 1204 449 1229 449 1227 1275 370 449 7690 1275 362 1275 361 449 1222 1275 364 1275 371 448 1230 448 1230 448 1231 447 1232 446 1229 1274 372 447 # -name: ROTATE +name: Rotate type: raw frequency: 38000 duty_cycle: 0.330000 data: 1338 312 1380 310 446 1133 1313 356 1284 362 457 1221 457 1219 1285 363 456 1221 457 1222 482 1196 482 7655 1282 356 1281 357 453 1219 1279 360 1279 367 452 1226 452 1224 1280 367 452 1226 452 1226 452 1226 452 7671 1279 358 1279 358 452 1219 1279 360 1279 367 452 1227 451 1225 1279 367 451 1227 451 1227 451 1227 451 7682 1279 359 1278 359 451 1220 1278 361 1278 368 451 1227 450 1225 1278 368 451 1227 451 1228 450 1228 450 7691 1277 360 1277 360 450 1221 1277 362 1277 368 450 1228 449 1226 1277 369 449 1229 449 1252 426 1252 426 # -name: TIMER +name: Timer type: raw frequency: 38000 duty_cycle: 0.330000 data: 1338 311 1326 312 497 1134 1364 311 1276 361 457 1221 457 1220 457 1218 1283 361 456 1221 456 1221 457 7676 1285 351 1285 351 457 1213 1286 353 1285 360 457 1220 457 1220 457 1219 1285 361 456 1221 456 1222 481 7639 1283 353 1284 353 455 1216 1283 356 1282 363 454 1223 455 1223 454 1221 1283 363 454 1223 454 1223 454 7676 1282 354 1282 354 454 1217 1282 356 1282 364 453 1223 454 1223 454 1221 1282 363 454 1224 453 1224 454 7681 1281 355 1281 355 453 1217 1281 357 1281 364 453 1225 452 1225 452 1222 1281 365 452 1225 452 1225 452 # -name: POWER +name: Power type: raw frequency: 38000 duty_cycle: 0.330000 data: 3565 3379 984 2506 984 2505 985 797 900 2590 900 2590 926 2572 926 826 925 829 922 858 894 859 894 858 895 2604 894 859 894 859 894 2596 894 859 894 859 894 867 894 2596 894 2596 894 2596 894 2596 894 2596 894 867 894 40343 3530 3468 895 2596 894 2596 894 859 894 2596 894 2596 894 2604 894 859 894 859 894 859 894 859 894 859 894 2604 894 859 894 859 894 2596 894 859 894 859 894 867 894 2596 894 2596 894 2596 894 2596 895 2596 894 866 895 # -name: SPEED+ +name: Speed_up type: raw frequency: 38000 duty_cycle: 0.330000 data: 3595 3377 930 2561 929 2561 929 853 900 2591 899 2590 900 2597 901 2590 925 2565 924 2567 922 2570 920 2596 894 866 895 858 895 858 895 2596 894 858 895 859 894 866 895 858 895 858 895 858 895 859 894 858 895 2604 894 40343 3533 3467 895 2595 895 2596 894 858 895 2596 894 2596 894 2604 895 2596 894 2596 894 2596 894 2596 894 2596 894 867 894 859 894 859 894 2596 894 859 894 859 894 867 894 859 894 859 894 859 894 859 894 859 894 2605 893 40319 3533 3442 920 2595 895 2596 894 858 895 2596 894 2596 894 2604 894 2596 894 2596 894 2596 894 2596 894 2596 894 867 894 859 894 859 894 2596 894 859 894 859 894 867 894 859 894 859 894 859 894 859 894 859 894 2604 894 # -name: ROTATE +name: Rotate type: raw frequency: 38000 duty_cycle: 0.330000 data: 3594 3380 981 2505 930 2560 930 853 900 2590 900 2590 900 2598 900 2589 900 853 924 2568 921 2571 919 2596 894 867 894 859 894 859 894 2596 894 859 894 859 894 867 894 859 894 2596 894 859 894 859 894 859 894 2604 894 40335 3532 3467 895 2596 894 2596 895 859 894 2596 894 2596 894 2605 894 2596 894 859 894 2596 894 2597 894 2596 894 867 894 859 894 859 894 2596 894 859 894 859 894 867 894 859 894 2597 894 859 894 859 894 859 894 2605 893 # -name: TIMER +name: Timer type: raw frequency: 38000 duty_cycle: 0.330000 data: 3534 3439 954 2505 985 2535 955 798 954 2535 899 2591 899 2599 899 853 925 2566 924 2567 922 2596 894 2596 894 867 894 859 894 860 893 2597 894 859 894 859 894 867 894 2597 893 859 894 859 894 860 893 859 894 2605 894 40336 3531 3469 894 2597 893 2597 893 859 894 2597 893 2597 893 2605 893 860 893 2597 893 2597 893 2597 894 2597 893 868 893 860 893 860 893 2597 893 860 893 860 893 868 893 2597 893 860 893 860 893 860 893 860 893 2605 893 # -name: POWER +name: Power type: parsed protocol: NEC address: 80 00 00 00 command: 1A 00 00 00 # -name: POWER +name: Power type: raw frequency: 38000 duty_cycle: 0.330000 data: 1370 314 1375 320 519 1167 1370 322 1339 350 465 1221 467 1222 467 1222 466 1221 467 1221 467 1221 1317 7067 1317 372 1341 349 491 1198 1340 352 1337 353 486 1202 486 1226 462 1226 462 1227 461 1227 462 1227 1311 7073 1312 378 1311 378 462 1227 1311 378 1312 378 462 1227 462 1227 461 1227 462 1227 461 1227 461 1227 1311 7074 1311 378 1311 378 462 1227 1311 379 1310 379 461 1228 461 1228 460 1228 460 1228 460 1229 459 1228 1310 7076 1309 381 1309 380 460 1229 1310 381 1309 381 458 1230 458 1230 459 1230 459 1230 459 1230 458 1230 1309 7077 1309 380 1310 380 460 1229 1310 380 1310 380 459 1229 460 1229 459 1229 460 1229 459 1229 459 1229 1310 7075 1310 379 1310 380 459 1229 1310 380 1310 379 460 1229 460 1229 459 1229 460 1228 460 1229 459 1229 1310 7074 1310 380 1310 379 460 1229 1310 379 1310 379 460 1229 459 1229 459 1229 460 1229 460 1229 460 1228 1311 # -name: SPEED+ +name: Speed_up type: raw frequency: 38000 duty_cycle: 0.330000 data: 1394 321 1369 321 520 1141 1397 321 1368 321 519 1142 495 1194 495 1194 494 1195 494 1195 1366 351 491 7891 1341 350 1337 353 487 1201 1337 354 1336 354 487 1202 487 1202 487 1202 487 1202 487 1202 1336 354 487 7900 1336 354 1337 354 486 1202 1337 354 1336 354 487 1202 487 1202 487 1203 486 1202 487 1202 1336 354 487 7901 1335 354 1336 354 487 1203 1335 354 1336 355 486 1203 486 1203 486 1203 486 1203 486 1203 1335 355 486 7900 1335 355 1335 355 486 1203 1335 355 1335 355 486 1203 486 1204 485 1204 485 1204 485 1203 1335 356 485 7900 1334 356 1334 356 485 1204 1334 356 1334 356 485 1204 485 1204 484 1204 485 1204 485 1204 1333 357 484 7901 1333 357 1333 380 460 1228 1310 380 1310 380 460 1228 460 1228 460 1228 460 1228 460 1228 1310 380 460 7924 1309 380 1310 380 460 1229 1309 380 1310 380 460 1229 459 1229 460 1229 459 1230 459 1230 1309 381 458 # -name: ROTATE +name: Rotate type: raw frequency: 38000 duty_cycle: 0.330000 data: 1343 372 1318 372 467 1194 1346 372 1318 372 467 1193 525 1164 1400 319 495 1166 523 1166 523 1167 521 7890 1344 347 1340 350 489 1200 1339 351 1339 351 488 1201 488 1201 1338 351 488 1201 488 1201 488 1201 488 7899 1338 352 1338 352 487 1201 1339 352 1338 352 488 1201 488 1201 1339 352 487 1202 487 1201 488 1201 488 7899 1338 352 1338 352 487 1201 1338 352 1338 352 487 1202 487 1202 1337 353 486 1202 487 1202 487 1202 487 7900 1337 353 1337 353 486 1202 1338 353 1337 353 486 1202 487 1202 1338 353 486 1202 487 1202 487 1202 487 7900 1337 353 1337 353 486 1203 1336 354 1336 354 485 1203 486 1204 1335 354 485 1203 485 1203 486 1203 486 7901 1336 378 1312 355 484 1205 1335 378 1312 378 461 1227 462 1227 1313 378 461 1228 461 1228 461 1228 461 7925 1312 378 1312 378 461 1228 1311 378 1312 378 461 1228 461 1228 1312 378 461 1228 461 1228 461 1228 461 # -name: TIMER +name: Timer type: raw frequency: 38000 duty_cycle: 0.330000 data: 1370 319 1371 321 519 1167 1371 322 1366 324 488 1198 466 1222 466 1222 1317 375 464 1221 467 1220 468 7915 1317 372 1341 350 490 1197 1340 376 1313 377 462 1226 462 1226 462 1226 1312 377 462 1226 462 1226 462 7921 1312 377 1313 377 462 1226 1312 377 1312 377 462 1226 462 1226 462 1226 1312 378 462 1226 462 1226 462 7922 1312 377 1313 377 462 1226 1313 377 1312 377 462 1226 462 1226 462 1226 1313 377 462 1226 462 1226 462 7921 1312 377 1312 377 462 1226 1312 377 1313 377 462 1226 462 1226 462 1226 1312 377 462 1226 462 1226 462 7921 1312 377 1313 377 462 1226 1313 377 1312 354 485 1202 486 1202 486 1202 1337 352 487 1202 487 1201 487 7897 1337 352 1337 351 488 1200 1339 351 1339 352 487 1201 487 1201 488 1201 1338 352 487 1201 487 1201 488 7896 1338 352 1337 352 487 1201 1337 352 1337 352 487 1201 487 1201 487 1201 1338 352 487 1201 487 1201 487 # -name: MODE +name: Mode type: raw frequency: 38000 duty_cycle: 0.330000 diff --git a/assets/resources/infrared/assets/projectors.ir b/assets/resources/infrared/assets/projectors.ir index 43c3723ef..673120e61 100644 --- a/assets/resources/infrared/assets/projectors.ir +++ b/assets/resources/infrared/assets/projectors.ir @@ -4,908 +4,908 @@ Version: 1 # Last Checked 17th May, 2023 # # ON -name: POWER +name: Power type: raw frequency: 38000 duty_cycle: 0.330000 data: 310 27591 171 27662 241 27731 307 27575 107 27749 306 27551 130 55520 243 27614 217 55584 129 27743 119 27756 115 27747 163 27712 308 27502 243 27650 217 27732 175 27693 167 27698 166 27689 171 27622 215 27712 133 27658 216 27716 129 27732 162 27698 305 27571 131 27753 310 27570 170 27707 162 27707 175 10960 9194 4518 618 542 618 543 725 434 672 1623 671 1647 646 514 592 568 592 568 592 1702 592 568 592 567 593 1702 592 568 618 1676 618 1676 618 1676 618 543 617 543 617 543 617 1677 617 544 616 544 616 544 616 544 616 1678 616 1678 616 1678 616 544 616 1678 616 1679 615 1678 616 1678 616 40239 9196 2250 617 # -name: VOL+ +name: Vol_up type: parsed protocol: NEC address: 08 00 00 00 command: 48 00 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NEC address: 08 00 00 00 command: 49 00 00 00 # -name: MUTE +name: Mute type: parsed protocol: NEC address: 08 00 00 00 command: 14 00 00 00 # -name: POWER +name: Power type: parsed protocol: NEC address: 08 00 00 00 command: 0B 00 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NEC address: 01 00 00 00 command: 40 00 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NEC address: 01 00 00 00 command: 48 00 00 00 # -name: MUTE +name: Mute type: parsed protocol: NEC address: 01 00 00 00 command: 44 00 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NECext address: 00 30 00 00 command: 83 7C 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NECext address: 00 30 00 00 command: 82 7D 00 00 # -name: POWER +name: Power type: parsed protocol: NECext address: 08 13 00 00 command: 87 78 00 00 # -name: POWER +name: Power type: raw frequency: 38000 duty_cycle: 0.330000 data: 9055 4338 672 1551 669 1553 618 1603 619 481 617 482 616 481 617 507 591 1605 645 479 619 1577 645 1578 644 1578 644 479 619 480 618 1581 641 480 617 1605 617 1606 616 1606 615 483 615 1608 614 484 614 484 614 484 614 484 614 484 614 484 614 1609 614 484 614 1609 614 1609 613 1609 613 40058 9000 2068 614 95467 9022 2068 614 # -name: MUTE +name: Mute type: parsed protocol: NECext address: 87 4E 00 00 command: 29 D6 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NECext address: 87 4E 00 00 command: 08 F7 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NECext address: 87 4E 00 00 command: 04 FB 00 00 # -name: MUTE +name: Mute type: parsed protocol: NECext address: 83 55 00 00 command: 93 6C 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NEC address: 02 00 00 00 command: 15 00 00 00 # -name: VOL+ +name: Vol_up type: raw frequency: 38000 duty_cycle: 0.330000 data: 9032 4462 598 501 627 1604 627 530 598 531 677 423 706 422 706 421 707 451 677 1554 677 451 598 1633 598 1634 597 1634 598 1634 598 1634 625 1606 681 1550 626 502 598 530 599 529 600 1632 600 528 600 528 601 528 601 528 601 1631 600 1631 625 1607 625 504 625 1607 624 1608 624 1608 623 # -name: MUTE +name: Mute type: parsed protocol: NEC address: 02 00 00 00 command: 02 00 00 00 # -name: POWER +name: Power type: parsed protocol: NEC address: 02 00 00 00 command: 1D 00 00 00 # # ON -name: POWER +name: Power type: raw frequency: 38000 duty_cycle: 0.330000 data: 9096 4436 620 505 647 478 648 501 623 1599 647 1624 623 502 623 503 621 504 619 1628 618 507 617 507 617 1630 617 508 616 1630 617 1630 617 1631 616 508 616 508 617 508 616 1631 616 508 617 508 617 508 616 508 616 1630 616 1630 616 1631 616 508 616 1630 617 1630 617 1630 617 1631 617 509 616 508 616 509 616 509 616 509 616 509 615 509 616 508 617 1631 616 1631 615 1631 616 1631 616 1631 616 1631 616 1631 615 1631 616 14435 9093 2186 615 96359 9095 2184 617 # -name: VOL+ +name: Vol_up type: raw frequency: 38000 duty_cycle: 0.330000 data: 9091 4465 594 530 595 530 594 530 594 1651 595 1652 595 529 621 504 620 504 619 1628 618 507 617 508 616 1631 616 509 615 1631 616 1631 616 1632 615 509 616 509 616 509 615 1631 616 509 616 508 616 1631 616 509 616 1631 615 1631 616 1631 617 508 616 1631 616 1631 616 508 616 1631 617 508 617 509 616 509 616 509 616 509 616 509 616 509 616 509 616 1631 616 1631 616 1631 616 1631 616 1631 615 1631 615 1631 615 1631 616 14435 9090 2190 615 # -name: VOL- +name: Vol_dn type: raw frequency: 38000 duty_cycle: 0.330000 data: 9092 4439 620 506 619 506 618 530 593 1627 620 1630 643 504 620 505 618 506 617 1630 617 508 616 508 616 1632 616 508 617 1631 616 1631 616 1631 616 1631 616 509 616 508 616 1631 616 509 616 509 615 1632 616 509 616 508 616 1631 616 1631 616 508 616 1631 615 1631 616 509 615 1632 615 509 616 509 616 509 616 509 616 509 616 510 615 509 616 509 616 1631 616 1631 615 1631 616 1631 615 1631 615 1631 615 1631 615 1631 615 14434 9088 2191 615 96339 9115 2189 616 96343 9117 2189 616 96343 9114 2189 616 -# AV-MUTE -name: MUTE +# AV-Mute +name: Mute type: raw frequency: 38000 duty_cycle: 0.330000 data: 9092 4439 620 506 618 506 618 530 594 1627 619 1629 643 505 619 505 619 506 617 1629 617 508 616 508 616 1631 616 508 616 1630 616 1630 616 1630 617 1630 616 1630 616 1631 616 508 616 508 616 508 616 1631 616 508 617 508 616 508 616 508 616 1630 616 1631 615 1631 616 508 616 1631 616 508 617 508 616 509 615 509 616 508 616 509 615 509 616 508 616 1631 615 1631 615 1631 616 1631 615 1631 615 1631 615 1631 615 1631 616 14433 9088 2191 615 # -name: POWER +name: Power type: raw frequency: 38000 duty_cycle: 0.330000 data: 9014 4332 661 1570 661 471 660 473 658 474 657 476 655 498 633 498 634 502 633 499 633 1599 632 1599 632 1599 632 1599 632 1599 632 1600 631 1603 632 500 632 501 631 501 631 501 631 501 631 501 631 1601 631 504 631 1601 631 1601 631 1601 631 1601 631 1601 630 1601 630 501 631 1601 631 38177 8983 2149 630 # -name: VOL+ +name: Vol_up type: parsed protocol: NEC address: 01 00 00 00 command: 11 00 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NEC address: 01 00 00 00 command: 4C 00 00 00 # -name: MUTE +name: Mute type: raw frequency: 38000 duty_cycle: 0.330000 data: 9042 4306 690 1541 665 468 664 468 664 469 663 470 662 471 660 495 636 499 636 497 634 1597 634 1598 633 1598 633 1599 633 1599 632 1599 633 1603 632 1599 633 499 633 499 633 500 632 499 633 500 632 1600 632 503 633 500 632 1600 632 1600 632 1600 633 1600 632 1600 632 500 632 1600 632 37912 8986 2145 633 # ON -name: POWER +name: Power type: raw frequency: 38000 duty_cycle: 0.330000 data: 3522 1701 472 426 444 1269 472 426 444 426 443 427 443 427 443 426 444 427 443 426 444 427 442 428 441 429 440 431 438 1304 437 433 437 433 438 433 437 433 437 434 436 434 436 434 436 434 436 434 436 1305 436 434 436 434 436 434 436 1305 436 434 436 434 436 1305 436 435 435 435 435 435 435 435 435 435 435 435 435 435 435 459 411 459 411 459 411 1330 411 1330 411 1330 411 1330 411 1330 411 460 410 459 411 459 411 1330 411 1330 411 460 410 1330 411 1330 411 1331 410 1330 411 74392 3516 1736 436 433 437 1304 437 433 437 433 437 433 437 433 437 433 437 434 436 433 437 434 436 434 436 434 436 434 436 1305 436 434 436 434 436 434 436 434 436 434 436 434 436 434 436 434 436 434 436 1305 436 434 436 434 436 435 435 1305 436 435 435 435 435 1306 435 435 435 435 435 435 435 436 434 436 434 436 434 435 435 436 434 436 434 436 434 1330 411 1331 410 1330 411 1330 411 1330 411 459 411 460 410 460 410 1331 410 1331 410 460 410 1331 410 1331 410 1331 410 1331 410 74392 3515 1736 437 433 437 1304 437 433 437 433 437 434 436 433 437 434 436 433 437 434 436 434 436 434 436 434 436 434 436 1305 436 434 436 434 436 434 436 434 436 434 436 434 436 434 436 434 436 434 436 1305 436 434 436 435 436 434 436 1306 435 435 435 435 435 1306 435 435 435 435 435 435 435 435 435 435 435 436 434 436 434 435 435 436 434 435 435 1306 435 1330 411 1307 434 1331 410 1308 433 436 434 436 434 460 410 1331 410 1331 410 460 410 1331 410 1331 410 1331 410 1331 410 74392 3515 1736 437 433 437 1304 437 434 436 433 437 434 436 433 437 434 436 434 436 434 436 434 436 434 436 434 436 434 436 1305 436 434 436 434 436 434 436 435 435 434 436 434 436 434 436 434 436 434 436 1306 435 435 435 435 435 435 435 1306 435 435 435 436 434 1306 435 435 435 436 434 436 434 435 435 436 434 436 434 460 410 460 410 460 410 460 410 1331 410 1331 410 1331 410 1331 410 1331 410 460 410 460 410 460 410 1331 410 1331 410 460 410 1331 410 1331 410 1331 410 1331 410 74392 3515 1736 437 433 437 1304 437 433 437 434 436 434 436 433 437 434 436 434 436 434 436 434 436 434 436 434 436 434 436 1305 436 434 436 434 436 434 436 434 436 434 436 434 436 435 435 435 435 434 436 1306 435 434 436 435 435 435 435 1306 435 436 434 435 435 1306 435 435 435 436 434 436 434 436 434 436 434 460 410 437 433 459 411 460 410 460 410 1331 410 1331 410 1331 410 1331 410 1331 410 460 410 460 410 460 410 1331 410 1331 410 460 410 1331 410 1331 410 1331 410 1331 410 74393 3514 1736 437 434 436 1304 437 433 437 434 436 433 437 434 436 433 437 434 436 434 436 434 436 434 436 434 436 434 436 1305 436 434 436 434 436 434 436 434 436 435 435 434 436 434 436 435 435 434 436 1305 436 435 435 435 435 435 435 1306 435 435 435 435 435 1306 435 435 435 436 434 435 435 459 411 436 434 435 435 459 411 459 411 459 411 459 411 1330 411 1306 435 1330 411 1330 411 1331 410 460 410 460 410 460 410 1331 410 1331 410 460 410 1331 410 1331 410 1331 410 1331 410 # ON -name: POWER +name: Power type: raw frequency: 38000 duty_cycle: 0.330000 data: 529 7218 126 6585 219 703 180 5362 427 18618 177 # -name: VOL+ +name: Vol_up type: raw frequency: 38000 duty_cycle: 0.330000 data: 9069 4362 622 486 621 487 621 491 622 1608 623 1603 622 487 621 487 621 491 622 1604 621 487 622 491 622 1604 621 491 622 1608 622 1609 621 1604 622 486 622 487 621 491 621 1605 621 487 621 491 622 1604 622 491 621 1609 621 1609 621 1604 622 491 621 1609 622 1604 621 491 621 1604 622 487 621 487 622 486 622 487 621 488 621 487 621 488 620 491 621 1609 622 1609 620 1609 621 1609 621 1609 621 1609 621 1609 621 1618 621 14330 9047 2137 620 # -name: VOL- +name: Vol_dn type: raw frequency: 38000 duty_cycle: 0.330000 data: 9047 4362 621 486 622 463 645 490 622 1609 622 1604 622 487 620 487 621 491 622 1604 622 484 625 490 621 1605 649 463 621 1609 620 1611 621 1608 622 1605 621 486 622 491 622 1604 621 487 621 492 620 1604 621 488 621 492 620 1609 622 1604 621 492 622 1609 620 1605 621 491 622 1603 622 488 621 488 620 488 620 488 621 488 620 487 622 485 621 492 596 1635 621 1609 622 1585 643 1611 620 1608 621 1610 619 1611 620 1619 619 14332 9074 2109 647 # -name: MUTE +name: Mute type: raw frequency: 38000 duty_cycle: 0.330000 data: 9073 4336 648 461 647 484 624 489 623 1607 623 1603 622 486 622 486 622 491 622 1604 621 487 621 491 622 1604 622 491 621 1609 621 1609 621 1609 621 1608 622 1609 621 1604 621 486 622 486 622 491 622 1604 622 486 622 487 621 487 621 491 622 1608 622 1609 621 1604 622 491 621 1604 621 487 621 486 622 487 621 487 621 487 621 487 621 487 621 491 622 1608 622 1608 622 1609 621 1608 622 1608 622 1608 622 1609 621 1617 622 14330 9047 2137 620 # ON -name: POWER +name: Power type: parsed protocol: NECext address: 83 F4 00 00 command: 4F B0 00 00 # -name: POWER +name: Power type: parsed protocol: NECext address: 80 19 00 00 command: 10 EF 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NECext address: 80 19 00 00 command: 1C E3 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NECext address: 80 19 00 00 command: 46 B9 00 00 # -name: POWER +name: Power type: parsed protocol: NEC address: 80 00 00 00 command: 51 00 00 00 # -name: POWER +name: Power type: parsed protocol: NECext address: 40 40 00 00 command: 0A F5 00 00 # -name: POWER +name: Power type: parsed protocol: NECext address: 00 30 00 00 command: 4E B1 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NECext address: 00 30 00 00 command: 0E F1 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NECext address: 00 30 00 00 command: 0D F2 00 00 # -name: POWER +name: Power type: parsed protocol: NECext address: 00 30 00 00 command: 4F B0 00 00 # -name: MUTE +name: Mute type: parsed protocol: NECext address: 00 30 00 00 command: 14 EB 00 00 # -name: POWER +name: Power type: parsed protocol: NECext address: 08 16 00 00 command: 87 78 00 00 # -name: MUTE +name: Mute type: parsed protocol: NECext address: 08 16 00 00 command: C8 37 00 00 # -name: POWER +name: Power type: parsed protocol: NEC address: 01 00 00 00 command: 01 00 00 00 # -name: MUTE +name: Mute type: parsed protocol: NEC address: 01 00 00 00 command: 02 00 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NEC address: 01 00 00 00 command: 28 00 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NEC address: 01 00 00 00 command: 29 00 00 00 # -name: POWER +name: Power type: parsed protocol: NECext address: 84 F4 00 00 command: 0B F4 00 00 # -name: POWER +name: Power type: parsed protocol: NECext address: 33 00 00 00 command: 00 FF 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NECext address: 33 00 00 00 command: 1E E1 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NECext address: 33 00 00 00 command: 1D E2 00 00 # -name: MUTE +name: Mute type: parsed protocol: NECext address: 33 00 00 00 command: 0B F4 00 00 # -name: POWER +name: Power type: parsed protocol: NECext address: 83 55 00 00 command: 90 6F 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NECext address: 83 55 00 00 command: 99 66 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NECext address: 83 55 00 00 command: 98 67 00 00 # -name: POWER +name: Power type: parsed protocol: NECext address: 00 DF 00 00 command: 1C E3 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NECext address: 00 DF 00 00 command: 4F B0 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NECext address: 00 DF 00 00 command: 4B B4 00 00 # -name: POWER +name: Power type: parsed protocol: NEC address: 32 00 00 00 command: 02 00 00 00 # -name: POWER +name: Power type: parsed protocol: NEC address: 32 00 00 00 command: 2E 00 00 00 # -name: MUTE +name: Mute type: parsed protocol: NEC address: 32 00 00 00 command: 52 00 00 00 # -name: POWER +name: Power type: parsed protocol: NEC address: 20 00 00 00 command: 41 00 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NEC address: 20 00 00 00 command: 51 00 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NEC address: 20 00 00 00 command: 56 00 00 00 # -name: MUTE +name: Mute type: parsed protocol: NEC address: 20 00 00 00 command: 5A 00 00 00 # -name: POWER +name: Power type: parsed protocol: SIRC15 address: 54 00 00 00 command: 15 00 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NECext address: 83 F4 00 00 command: 82 7D 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NECext address: 83 F4 00 00 command: 83 7C 00 00 # -name: MUTE +name: Mute type: parsed protocol: NECext address: 83 F4 00 00 command: 14 EB 00 00 # -name: POWER +name: Power type: parsed protocol: NEC address: 31 00 00 00 command: 91 00 00 00 # -name: POWER +name: Power type: parsed protocol: NEC address: 31 00 00 00 command: 90 00 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NEC address: 31 00 00 00 command: D0 00 00 00 # -name: MUTE +name: Mute type: parsed protocol: NEC address: 31 00 00 00 command: 89 00 00 00 # -name: POWER +name: Power type: parsed protocol: NECext address: 86 00 00 00 command: 00 00 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NECext address: 86 00 00 00 command: 30 00 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NECext address: 86 00 00 00 command: 31 00 00 00 # -name: MUTE +name: Mute type: parsed protocol: NECext address: 86 00 00 00 command: 32 00 00 00 # -name: POWER +name: Power type: parsed protocol: NECext address: 30 00 00 00 command: 00 00 00 00 # -name: POWER +name: Power type: parsed protocol: NECext address: 87 4E 00 00 command: 0D 00 00 00 # -name: POWER +name: Power type: raw frequency: 38000 duty_cycle: 0.330000 data: 9032 4479 597 560 572 558 564 566 566 1666 589 1671 594 562 570 560 562 568 564 1669 596 560 562 568 564 1669 596 560 562 1671 594 1666 588 1671 594 562 570 560 562 568 564 1669 596 560 562 568 564 566 566 563 569 1664 591 1669 596 1664 590 565 567 1667 598 1661 593 1666 588 1671 594 562 570 560 562 568 564 565 567 563 569 560 562 568 564 565 567 1666 588 1671 594 1665 589 1670 595 1665 590 1669 596 1664 590 1668 597 13983 9029 2222 599 96237 9030 2221 589 96244 9034 2217 594 96244 9033 2218 592 96249 9038 2213 597 96239 9037 2214 596 96238 9028 2223 598 96221 9032 2215 595 # -name: VOL+ +name: Vol_up type: raw frequency: 38000 duty_cycle: 0.330000 data: 9034 4482 593 563 569 561 571 559 563 1698 566 1694 570 559 563 568 564 566 566 1695 569 560 572 559 563 1671 593 563 569 1692 562 1671 593 1693 571 558 564 567 565 565 567 1693 571 532 590 567 565 1695 569 560 562 1698 566 1694 570 1663 591 539 593 1693 571 1688 566 564 568 1691 563 567 565 565 567 563 569 561 571 559 563 567 565 565 567 563 569 1690 564 1695 569 1691 563 1696 568 1691 563 1697 567 1692 562 1697 567 13988 9030 2223 597 96250 9035 2219 591 96245 9032 2221 589 96240 9038 2215 595 96235 9033 2220 590 # -name: VOL- +name: Vol_dn type: raw frequency: 38000 duty_cycle: 0.330000 data: 9028 4482 593 563 569 561 571 558 564 1696 568 1690 564 566 566 563 569 561 571 1688 566 563 569 561 571 1688 566 563 569 1690 564 1695 569 1689 565 1668 596 560 562 568 564 1695 569 560 562 568 564 1695 569 560 562 568 564 1695 569 1690 564 566 566 1692 572 1687 567 563 569 1690 564 566 566 564 568 562 570 559 563 567 565 565 567 562 570 560 562 1696 568 1665 589 1670 594 1665 589 1670 594 1664 590 1669 647 1612 590 13987 9031 2220 590 96223 9033 2217 593 96223 9034 2218 592 96225 9032 2219 591 96221 9087 2164 595 # -name: MUTE +name: Mute type: raw frequency: 38000 duty_cycle: 0.330000 data: 9031 4479 596 560 572 558 564 566 566 1693 571 1688 566 563 569 561 571 559 563 1696 568 561 571 559 563 1697 567 562 570 1689 565 1694 570 1688 566 1693 571 1661 593 1693 571 558 564 566 566 564 568 1691 563 541 591 564 568 562 570 560 562 1697 567 1692 562 1696 568 562 570 1689 565 564 568 561 571 559 563 567 565 564 568 562 570 560 562 567 565 1694 570 1689 565 1694 570 1688 566 1693 571 1688 566 1693 571 1662 592 13987 9031 2220 590 96231 9034 2217 593 96234 9030 2222 588 96247 9037 2215 595 # -name: VOL+ +name: Vol_up type: parsed protocol: NEC address: 32 00 00 00 command: 11 00 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NEC address: 32 00 00 00 command: 14 00 00 00 # OFF -name: POWER +name: Power type: parsed protocol: NECext address: 83 F4 00 00 command: 4E B1 00 00 # -name: POWER +name: Power type: parsed protocol: NEC address: 03 00 00 00 command: 1D 00 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NEC address: 03 00 00 00 command: 11 00 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NEC address: 03 00 00 00 command: 15 00 00 00 # OFF -name: POWER +name: Power type: raw frequency: 38000 duty_cycle: 0.330000 data: 9075 4307 677 433 675 456 651 461 651 1579 650 1576 649 459 649 460 648 465 648 1578 647 461 622 491 622 1604 647 465 647 1583 622 1608 647 1579 647 461 647 466 622 1604 647 465 647 1579 647 461 645 463 648 465 648 1583 646 1580 646 466 647 1579 622 491 647 1583 622 1608 647 1579 647 461 647 461 622 486 622 486 647 461 647 462 646 462 622 491 646 1584 622 1608 647 1584 621 1608 647 1583 646 1584 647 1584 646 1592 622 14330 9047 2137 621 # -name: POWER +name: Power type: parsed protocol: Samsung32 address: 07 00 00 00 command: E6 00 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: Samsung32 address: 07 00 00 00 command: 07 00 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: Samsung32 address: 07 00 00 00 command: 0B 00 00 00 # -name: MUTE +name: Mute type: parsed protocol: Samsung32 address: 07 00 00 00 command: 0F 00 00 00 # OFF -name: POWER +name: Power type: raw frequency: 38000 duty_cycle: 0.330000 data: 3523 1701 472 426 444 1269 472 426 444 426 442 429 443 427 443 426 444 426 444 426 443 427 442 429 440 430 439 432 438 1304 437 433 437 432 438 432 438 433 437 433 437 433 437 433 437 433 437 433 437 1304 437 433 437 433 437 433 437 1304 437 433 437 433 437 1304 437 433 437 434 436 433 437 434 436 434 436 434 436 433 437 433 437 434 436 1304 437 1305 436 1305 436 1305 436 1305 436 1305 436 434 436 434 436 1305 436 1305 436 1305 436 434 436 1305 436 1305 436 1306 435 1306 435 74393 3515 1736 437 433 437 1304 437 433 437 433 437 433 437 433 437 433 437 433 437 433 437 434 436 433 437 434 436 434 436 1304 437 434 436 434 436 434 436 434 436 434 436 434 436 434 436 434 436 434 436 1305 436 434 436 434 436 434 436 1305 436 434 436 434 436 1306 435 435 435 435 435 435 435 435 435 435 435 435 435 435 435 436 434 435 435 1307 434 1331 410 1307 434 1307 434 1330 411 1307 434 460 410 460 410 1331 410 1331 410 1331 410 460 410 1331 410 1331 410 1331 410 1331 410 74393 3515 1736 437 433 437 1304 437 433 437 433 437 433 437 433 437 433 437 433 437 433 437 434 436 434 436 433 437 433 437 1304 437 434 436 434 436 434 437 434 436 434 436 434 436 434 436 434 436 434 436 1305 436 434 436 434 436 434 436 1305 436 435 435 434 436 1305 436 434 436 435 435 435 435 435 435 435 435 435 435 435 435 435 435 435 435 1307 434 1306 435 1307 434 1307 434 1307 434 1331 410 460 410 460 410 1331 410 1331 410 1331 410 460 410 1331 410 1331 410 1331 410 1331 410 74393 3515 1736 437 433 437 1304 437 433 437 433 437 433 437 433 437 433 437 433 437 433 437 433 437 433 437 434 436 433 437 1304 437 433 437 434 436 434 436 434 436 434 436 434 436 434 436 434 436 434 437 1305 436 434 436 434 436 434 436 1305 436 434 436 434 436 1306 435 435 435 435 435 435 435 435 435 435 435 435 435 435 435 435 435 435 435 1307 434 1330 411 1330 411 1330 411 1330 411 1330 411 460 410 460 410 1331 410 1331 410 1331 410 460 410 1331 410 1331 410 1331 410 1331 410 # OFF -name: POWER +name: Power type: raw frequency: 38000 duty_cycle: 0.330000 data: 9093 4441 620 507 618 530 594 531 593 1652 595 1653 620 505 620 505 619 506 617 1630 616 508 616 508 616 1632 615 509 615 1631 616 1632 615 1632 615 510 615 509 615 1632 615 509 615 1632 615 510 615 510 614 509 615 1632 614 1633 614 509 615 1633 614 509 615 1632 615 1632 614 1633 614 510 614 510 615 510 615 510 614 510 614 510 615 510 615 510 614 1632 615 1632 614 1632 615 1632 615 1632 615 1632 615 1632 615 1633 614 14439 9088 2192 614 96349 9112 2190 616 # OFF -name: POWER +name: Power type: raw frequency: 38000 duty_cycle: 0.330000 data: 243 27700 170 27632 246 27694 282 27595 307 27497 241 27696 177 27710 164 27644 245 27629 246 27712 174 27638 211 27736 131 27741 306 27504 214 27727 135 27749 132 27761 126 27744 131 27753 127 27764 121 27767 132 27773 307 27577 131 27706 213 27761 129 27759 128 27770 125 27694 213 27751 307 27578 131 27737 131 27745 304 27575 335 27540 124 27752 132 27749 132 27747 134 27757 134 27758 127 27762 131 27748 131 27750 122 27749 130 27748 125 27772 131 27774 136 27762 135 27686 215 27742 131 27749 132 27756 133 27764 126 24073 9255 4460 672 488 618 541 619 541 619 1675 619 1676 618 542 618 542 618 542 618 1676 618 542 618 543 617 1678 616 568 592 1702 592 1702 592 1703 617 543 617 543 617 1677 617 543 617 1678 615 544 616 544 616 544 616 1678 616 1679 615 544 616 1679 615 545 615 1679 615 1679 615 1679 615 40240 9173 2273 591 # -name: VOL+ +name: Vol_up type: raw frequency: 38000 duty_cycle: 0.330000 data: 219 27658 217 27663 216 27658 216 27634 216 27642 215 27646 217 27662 217 27637 216 27649 216 27649 218 27656 217 27658 215 27640 214 27636 217 27649 216 27644 218 27635 217 27630 215 27645 216 27631 215 27632 216 27650 216 27628 217 27630 214 27627 217 27623 215 27632 215 27641 216 27634 214 27633 215 27648 215 27648 217 27651 215 27635 216 27629 216 27630 216 2021 9254 4461 618 542 618 542 618 542 618 1675 619 1676 618 541 619 541 619 542 618 1677 617 543 617 543 617 1678 616 568 592 1702 592 1702 618 1676 618 542 618 542 618 543 617 1677 617 543 617 544 616 1678 616 544 616 1678 616 1678 616 1678 616 544 616 1678 616 1678 616 544 616 1678 616 40239 9200 2247 617 99930 110 27739 119 27738 123 27750 126 27738 175 27617 214 27716 203 27604 213 27639 217 27631 214 27722 136 27753 119 27736 175 27618 246 27683 177 27619 245 27685 171 55486 244 27693 158 27635 241 27695 170 27693 129 27717 340 27530 113 27757 106 27751 124 27728 172 27707 126 27666 215 27708 123 27733 123 # -name: VOL- +name: Vol_dn type: parsed protocol: NECext address: 18 E9 00 00 command: 49 B6 00 00 # -name: POWER +name: Power type: parsed protocol: NEC address: 02 00 00 00 command: 14 00 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NEC address: 02 00 00 00 command: 48 00 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NEC address: 02 00 00 00 command: 40 00 00 00 # -name: MUTE +name: Mute type: parsed protocol: NEC address: 02 00 00 00 command: 18 00 00 00 # -name: POWER +name: Power type: parsed protocol: NECext address: B8 57 00 00 command: 0C F3 00 00 # -name: MUTE +name: Mute type: parsed protocol: NECext address: B8 57 00 00 command: 0D F2 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NECext address: B8 57 00 00 command: 1E E1 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NECext address: B8 57 00 00 command: 1F E0 00 00 # -name: POWER +name: Power type: parsed protocol: NEC address: 32 00 00 00 command: 81 00 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NEC address: 32 00 00 00 command: 8F 00 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NEC address: 32 00 00 00 command: 8C 00 00 00 # -name: MUTE +name: Mute type: raw frequency: 38000 duty_cycle: 0.330000 data: 9066 4428 608 507 609 1622 609 507 609 507 609 1623 608 1623 609 507 609 506 610 1623 609 507 609 1622 610 1623 608 507 609 506 610 1622 609 1623 609 506 610 1622 610 506 610 1623 637 478 690 425 638 478 637 1594 637 1594 664 451 636 1594 610 506 610 1621 611 1621 610 1621 610 505 611 40183 9065 2156 637 95953 9037 2185 608 # -name: POWER +name: Power type: parsed protocol: NEC address: 00 00 00 00 command: A8 00 00 00 # -name: MUTE +name: Mute type: parsed protocol: NEC address: 00 00 00 00 command: 88 00 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NEC address: 00 00 00 00 command: 9C 00 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NEC address: 00 00 00 00 command: 8C 00 00 00 # -name: POWER +name: Power type: parsed protocol: NECext address: 87 45 00 00 command: 17 E8 00 00 # -name: VOL+ +name: Vol_up type: raw frequency: 38000 duty_cycle: 0.330000 data: 9064 4354 666 1559 666 1562 662 1586 638 475 636 477 635 477 635 478 635 1590 635 1591 634 478 635 1591 634 478 634 478 635 478 634 1591 635 478 634 1591 634 478 635 478 634 478 635 1591 634 478 634 1591 635 478 634 478 634 1591 634 1591 635 1591 634 478 635 1591 634 478 634 1591 635 40957 9035 2144 634 95483 9047 2155 632 95484 9048 2153 633 # -name: VOL- +name: Vol_dn type: parsed protocol: NECext address: 87 45 00 00 command: 50 AF 00 00 # -name: MUTE +name: Mute type: raw frequency: 38000 duty_cycle: 0.330000 data: 9034 4385 638 1587 664 1562 663 1587 637 476 635 478 634 478 635 478 635 1591 634 1591 634 478 635 1591 635 478 634 478 635 478 635 1591 635 478 634 478 634 1591 634 478 635 479 634 1591 635 478 634 1591 635 478 634 1592 634 478 634 1591 635 1591 635 478 634 1592 634 478 634 1591 634 40958 9033 2144 635 # -name: POWER +name: Power type: parsed protocol: NECext address: FF FF 00 00 command: E8 17 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NECext address: FF FF 00 00 command: BD 42 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NECext address: FF FF 00 00 command: F2 0D 00 00 # -name: POWER +name: Power type: parsed protocol: Kaseikyo address: 41 54 32 00 command: 05 00 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: Kaseikyo address: 41 54 32 00 command: 70 01 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: Kaseikyo address: 41 54 32 00 command: 71 01 00 00 # -name: POWER +name: Power type: parsed protocol: NEC address: 31 00 00 00 command: 81 00 00 00 # -name: POWER +name: Power type: parsed protocol: NECext address: 83 F4 00 00 command: 17 E8 00 00 # -name: VOL+ +name: Vol_up type: raw frequency: 38000 duty_cycle: 0.33 data: 9010 4413 532 1617 532 1617 533 489 533 489 533 489 558 464 558 465 557 1593 557 465 557 466 556 1594 555 467 555 1595 529 1621 554 1595 581 1569 581 441 581 1569 581 441 581 441 581 441 581 441 581 441 581 1569 581 1569 581 441 581 1569 580 1569 580 1570 580 1595 554 1595 555 468 554 42156 8983 2135 556 # -name: VOL- +name: Vol_dn type: raw frequency: 38000 duty_cycle: 0.33 data: 9032 4390 556 1592 559 1591 559 463 559 463 558 464 557 465 556 465 557 1593 583 440 581 441 580 1569 581 441 581 1569 580 1569 581 1569 581 1570 580 1596 554 1596 554 468 554 468 554 468 554 442 580 442 580 1596 554 469 553 469 553 1596 554 1596 553 1597 550 1598 553 1598 552 469 551 42155 9008 2107 531 95218 9006 2108 582 # -name: MUTE +name: Mute type: raw frequency: 38000 duty_cycle: 0.33 data: 9011 4388 557 1617 532 1617 532 489 533 489 558 464 558 440 582 440 582 1593 556 466 556 466 556 1594 556 467 555 1595 555 1595 529 1620 554 1596 554 467 554 468 555 1595 579 443 581 1569 581 441 581 441 580 442 581 1569 581 1569 581 441 581 1569 580 441 581 1569 581 1569 581 1570 579 42152 8957 2159 556 # -name: POWER +name: Power type: parsed protocol: NECext address: 4F 50 00 00 command: 02 FD 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NECext address: 4F 50 00 00 command: 08 F7 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NECext address: 4F 50 00 00 command: 0B F4 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NECext address: 81 03 00 00 command: F0 0F 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NECext address: 87 45 00 00 command: 51 AE 00 00 # -name: MUTE +name: Mute type: parsed protocol: NECext address: 87 45 00 00 command: 52 AD 00 00 # -name: POWER +name: Power type: raw frequency: 38000 duty_cycle: 0.330000 data: 8811 4222 530 1580 531 1579 531 507 531 507 531 507 531 508 531 508 530 1582 528 1583 527 535 503 1608 502 536 501 1609 501 537 501 1610 500 538 500 1611 499 538 500 539 500 538 500 1611 500 539 499 538 500 1611 499 539 499 1611 499 1611 500 1611 499 539 499 1611 500 1611 500 539 499 35437 8784 4252 500 1611 500 1612 500 539 500 539 500 539 500 539 500 539 500 1611 500 1612 499 539 500 1612 500 539 500 1612 499 539 500 1612 500 539 500 1612 499 539 500 539 500 539 499 1612 499 540 499 539 500 1612 499 539 500 1612 499 1613 499 1612 499 539 500 1612 500 1612 500 539 500 # -name: VOL+ +name: Vol_up type: parsed protocol: NEC address: 01 00 00 00 command: 06 00 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NEC address: 01 00 00 00 command: 09 00 00 00 # -name: MUTE +name: Mute type: parsed protocol: NEC address: 01 00 00 00 command: 1A 00 00 00 # -name: POWER +name: Power type: parsed protocol: NEC address: 01 00 00 00 command: 00 00 00 00 # -name: MUTE +name: Mute type: raw frequency: 38000 duty_cycle: 0.330000 data: 9035 4437 563 548 563 548 563 522 594 1645 591 1639 592 518 593 548 563 552 563 1640 592 548 563 553 562 1668 564 524 592 1642 594 1674 562 1673 563 1639 593 548 563 552 564 1669 562 548 563 520 615 529 586 1645 587 529 587 1650 586 1646 586 529 586 1650 586 1649 587 1646 586 524 587 524 587 524 587 524 587 525 643 467 644 440 671 467 644 472 643 1592 644 1593 643 1593 642 1594 641 1594 587 1649 585 1651 563 1682 562 14430 9008 2205 562 # -name: VOL+ +name: Vol_up type: parsed protocol: NECext address: 84 F4 00 00 command: 2C D3 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NECext address: 84 F4 00 00 command: 2F D0 00 00 # -name: MUTE +name: Mute type: parsed protocol: NECext address: 4F 50 00 00 command: 0F F0 00 00 # -name: POWER +name: Power type: parsed protocol: NEC address: 02 00 00 00 command: 12 00 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NEC address: 02 00 00 00 command: 06 00 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NEC address: 02 00 00 00 diff --git a/assets/resources/infrared/assets/tv.ir b/assets/resources/infrared/assets/tv.ir index a0fe73bd9..ab608cf1b 100755 --- a/assets/resources/infrared/assets/tv.ir +++ b/assets/resources/infrared/assets/tv.ir @@ -3,1898 +3,1898 @@ Version: 1 # Last Updated 17th May, 2023 # Last Checked 17th May, 2023 # -name: POWER +name: Power type: parsed protocol: SIRC address: 01 00 00 00 command: 15 00 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: SIRC address: 01 00 00 00 command: 12 00 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: SIRC address: 01 00 00 00 command: 13 00 00 00 # -name: CH+ +name: Ch_next type: parsed protocol: SIRC address: 01 00 00 00 command: 10 00 00 00 # -name: CH- +name: Ch_prev type: parsed protocol: SIRC address: 01 00 00 00 command: 11 00 00 00 # -name: MUTE +name: Mute type: parsed protocol: SIRC address: 01 00 00 00 command: 14 00 00 00 # -name: POWER +name: Power type: parsed protocol: NEC address: 40 00 00 00 command: 0B 00 00 00 # -name: CH+ +name: Ch_next type: parsed protocol: NEC address: 40 00 00 00 command: 11 00 00 00 # -name: CH- +name: Ch_prev type: parsed protocol: NEC address: 40 00 00 00 command: 10 00 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NEC address: 40 00 00 00 command: 13 00 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NEC address: 40 00 00 00 command: 12 00 00 00 # -name: MUTE +name: Mute type: parsed protocol: NEC address: 40 00 00 00 command: 14 00 00 00 # -name: POWER +name: Power type: parsed protocol: Kaseikyo address: 80 02 20 00 command: D0 03 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: Kaseikyo address: 80 02 20 00 command: 00 02 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: Kaseikyo address: 80 02 20 00 command: 10 02 00 00 # -name: MUTE +name: Mute type: parsed protocol: Kaseikyo address: 80 02 20 00 command: 20 03 00 00 # -name: CH+ +name: Ch_next type: parsed protocol: Kaseikyo address: 80 02 20 00 command: 40 03 00 00 # -name: CH- +name: Ch_prev type: parsed protocol: Kaseikyo address: 80 02 20 00 command: 50 03 00 00 # -name: POWER +name: Power type: parsed protocol: NEC address: 04 00 00 00 command: 40 00 00 00 # -name: MUTE +name: Mute type: parsed protocol: NEC address: 04 00 00 00 command: 12 00 00 00 # -name: POWER +name: Power type: parsed protocol: NECext address: 00 7F 00 00 command: 15 EA 00 00 # -name: MUTE +name: Mute type: parsed protocol: NECext address: 00 7F 00 00 command: 16 E9 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NECext address: 00 7F 00 00 command: 1B E4 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NECext address: 00 7F 00 00 command: 1A E5 00 00 # -name: CH+ +name: Ch_next type: parsed protocol: NECext address: 00 7F 00 00 command: 19 E6 00 00 # -name: CH- +name: Ch_prev type: parsed protocol: NECext address: 00 7F 00 00 command: 18 E7 00 00 # -name: MUTE +name: Mute type: parsed protocol: NECext address: 00 FB 00 00 command: 0F F0 00 00 # -name: POWER +name: Power type: parsed protocol: NECext address: 00 FB 00 00 command: 0A F5 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NECext address: 00 FB 00 00 command: 58 A7 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NECext address: 00 FB 00 00 command: 4B B4 00 00 # -name: CH+ +name: Ch_next type: parsed protocol: NECext address: 00 FB 00 00 command: 1F E0 00 00 # -name: CH- +name: Ch_prev type: parsed protocol: NECext address: 00 FB 00 00 command: 1E E1 00 00 # -name: POWER +name: Power type: parsed protocol: NECext address: 00 DF 00 00 command: 1C E3 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NECext address: 00 DF 00 00 command: 4B B4 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NECext address: 00 DF 00 00 command: 4F B0 00 00 # -name: MUTE +name: Mute type: parsed protocol: NECext address: 00 DF 00 00 command: 08 F7 00 00 # -name: CH+ +name: Ch_next type: parsed protocol: NECext address: 00 DF 00 00 command: 09 F6 00 00 # -name: CH- +name: Ch_prev type: parsed protocol: NECext address: 00 DF 00 00 command: 05 FA 00 00 # -name: POWER +name: Power type: parsed protocol: NEC address: 01 00 00 00 command: 03 00 00 00 # -name: CH+ +name: Ch_next type: parsed protocol: RC5 address: 00 00 00 00 command: 20 00 00 00 # -name: CH- +name: Ch_prev type: parsed protocol: RC5 address: 00 00 00 00 command: 21 00 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: RC5 address: 00 00 00 00 command: 11 00 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: RC5 address: 00 00 00 00 command: 10 00 00 00 # -name: POWER +name: Power type: parsed protocol: NEC address: 03 00 00 00 command: 1D 00 00 00 # -name: MUTE +name: Mute type: parsed protocol: NECext address: 00 7F 00 00 command: 4E B1 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NEC address: 03 00 00 00 command: 11 00 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NEC address: 03 00 00 00 command: 15 00 00 00 # -name: POWER +name: Power type: parsed protocol: NEC address: 19 00 00 00 command: 18 00 00 00 # -name: MUTE +name: Mute type: parsed protocol: NEC address: 19 00 00 00 command: 56 00 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NEC address: 19 00 00 00 command: 4F 00 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NEC address: 19 00 00 00 command: 0D 00 00 00 # -name: CH+ +name: Ch_next type: parsed protocol: NEC address: 19 00 00 00 command: 4C 00 00 00 # -name: CH- +name: Ch_prev type: parsed protocol: NEC address: 19 00 00 00 command: 0F 00 00 00 # -name: POWER +name: Power type: parsed protocol: NECext address: BA A0 00 00 command: 4C B3 00 00 # -name: MUTE +name: Mute type: parsed protocol: NECext address: BA A0 00 00 command: 01 FE 00 00 # -name: POWER +name: Power type: parsed protocol: NECext address: AD ED 00 00 command: B5 4A 00 00 # # ON -name: POWER +name: Power type: parsed protocol: NEC address: 01 00 00 00 command: 40 00 00 00 # ON -name: POWER +name: Power type: parsed protocol: NECext address: A0 B7 00 00 command: E9 16 00 00 # -name: POWER +name: Power type: parsed protocol: SIRC address: 10 00 00 00 command: 15 00 00 00 # -name: POWER +name: Power type: parsed protocol: NEC address: 08 00 00 00 command: 05 00 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NEC address: 08 00 00 00 command: 00 00 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NEC address: 08 00 00 00 command: 01 00 00 00 # -name: CH+ +name: Ch_next type: parsed protocol: NEC address: 08 00 00 00 command: 02 00 00 00 # -name: CH- +name: Ch_prev type: parsed protocol: NEC address: 08 00 00 00 command: 03 00 00 00 # -name: MUTE +name: Mute type: parsed protocol: NEC address: 08 00 00 00 command: 0B 00 00 00 # -name: POWER +name: Power type: parsed protocol: NECext address: 00 DF 00 00 command: 1C 00 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NECext address: 00 DF 00 00 command: 4B 00 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NECext address: 00 DF 00 00 command: 4F 00 00 00 # -name: CH+ +name: Ch_next type: parsed protocol: NECext address: 00 DF 00 00 command: 09 00 00 00 # -name: CH- +name: Ch_prev type: parsed protocol: NECext address: 00 DF 00 00 command: 05 00 00 00 # -name: MUTE +name: Mute type: parsed protocol: NECext address: 00 DF 00 00 command: 08 00 00 00 # -name: POWER +name: Power type: parsed protocol: Samsung32 address: 0E 00 00 00 command: 0C 00 00 00 # -name: MUTE +name: Mute type: parsed protocol: Samsung32 address: 0E 00 00 00 command: 0D 00 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: Samsung32 address: 0E 00 00 00 command: 14 00 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: Samsung32 address: 0E 00 00 00 command: 15 00 00 00 # -name: CH+ +name: Ch_next type: parsed protocol: Samsung32 address: 0E 00 00 00 command: 12 00 00 00 # -name: CH- +name: Ch_prev type: parsed protocol: Samsung32 address: 0E 00 00 00 command: 13 00 00 00 # -name: POWER +name: Power type: parsed protocol: RC6 address: 00 00 00 00 command: 0C 00 00 00 # -name: POWER +name: Power type: parsed protocol: Samsung32 address: 07 00 00 00 command: 02 00 00 00 # -name: POWER +name: Power type: parsed protocol: NEC address: 50 00 00 00 command: 17 00 00 00 # -name: POWER +name: Power type: parsed protocol: NECext address: 31 49 00 00 command: 63 00 00 00 # -name: POWER +name: Power type: parsed protocol: NEC address: AA 00 00 00 command: 1C 00 00 00 # -name: POWER +name: Power type: parsed protocol: NEC address: 38 00 00 00 command: 1C 00 00 00 # -name: POWER +name: Power type: parsed protocol: NECext address: 83 7A 00 00 command: 08 00 00 00 # -name: POWER +name: Power type: parsed protocol: NEC address: 53 00 00 00 command: 17 00 00 00 # -name: POWER +name: Power type: parsed protocol: NECext address: 18 18 00 00 command: C0 00 00 00 # -name: POWER +name: Power type: parsed protocol: NEC address: 38 00 00 00 command: 10 00 00 00 # -name: POWER +name: Power type: parsed protocol: NEC address: AA 00 00 00 command: C5 00 00 00 # -name: POWER +name: Power type: parsed protocol: NEC address: 04 00 00 00 command: 08 00 00 00 # -name: POWER +name: Power type: parsed protocol: NEC address: 18 00 00 00 command: 08 00 00 00 # -name: POWER +name: Power type: parsed protocol: NEC address: 71 00 00 00 command: 08 00 00 00 # -name: POWER +name: Power type: parsed protocol: NECext address: 80 6F 00 00 command: 0A 00 00 00 # -name: POWER +name: Power type: parsed protocol: NEC address: 48 00 00 00 command: 00 00 00 00 # -name: POWER +name: Power type: parsed protocol: NECext address: 80 7B 00 00 command: 13 00 00 00 # -name: POWER +name: Power type: parsed protocol: NECext address: 80 7E 00 00 command: 18 00 00 00 # -name: POWER +name: Power type: parsed protocol: NEC address: 50 00 00 00 command: 08 00 00 00 # -name: POWER +name: Power type: parsed protocol: NECext address: 80 75 00 00 command: 0A 00 00 00 # -name: POWER +name: Power type: parsed protocol: NECext address: 80 57 00 00 command: 0A 00 00 00 # -name: POWER +name: Power type: parsed protocol: Samsung32 address: 0B 00 00 00 command: 0A 00 00 00 # -name: POWER +name: Power type: parsed protocol: NEC address: AA 00 00 00 command: 1B 00 00 00 # -name: POWER +name: Power type: parsed protocol: NECext address: 85 46 00 00 command: 12 00 00 00 # -name: POWER +name: Power type: parsed protocol: Samsung32 address: 05 00 00 00 command: 02 00 00 00 # -name: POWER +name: Power type: parsed protocol: Samsung32 address: 08 00 00 00 command: 0F 00 00 00 # -name: POWER +name: Power type: parsed protocol: NEC address: 00 00 00 00 command: 01 00 00 00 # -name: POWER +name: Power type: parsed protocol: Samsung32 address: 07 00 00 00 command: E6 00 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: Samsung32 address: 07 00 00 00 command: 07 00 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: Samsung32 address: 07 00 00 00 command: 0B 00 00 00 # -name: CH+ +name: Ch_next type: parsed protocol: Samsung32 address: 07 00 00 00 command: 12 00 00 00 # -name: CH- +name: Ch_prev type: parsed protocol: Samsung32 address: 07 00 00 00 command: 10 00 00 00 # -name: MUTE +name: Mute type: parsed protocol: Samsung32 address: 07 00 00 00 command: 0F 00 00 00 # -name: POWER +name: Power type: parsed protocol: NEC address: 71 00 00 00 command: 4A 00 00 00 # -name: POWER +name: Power type: parsed protocol: NEC address: 60 00 00 00 command: 03 00 00 00 # -name: POWER +name: Power type: parsed protocol: NEC address: 60 00 00 00 command: 00 00 00 00 # -name: POWER +name: Power type: parsed protocol: NEC address: 42 00 00 00 command: 01 00 00 00 # -name: POWER +name: Power type: parsed protocol: NECext address: 50 AD 00 00 command: 00 00 00 00 # -name: POWER +name: Power type: parsed protocol: NECext address: 50 AD 00 00 command: 02 00 00 00 # -name: POWER +name: Power type: parsed protocol: NEC address: 50 00 00 00 command: 3F 00 00 00 # -name: POWER +name: Power type: parsed protocol: Samsung32 address: 06 00 00 00 command: 0F 00 00 00 # -name: POWER +name: Power type: parsed protocol: NEC address: 08 00 00 00 command: 12 00 00 00 # -name: POWER +name: Power type: parsed protocol: Samsung32 address: 08 00 00 00 command: 0B 00 00 00 # -name: POWER +name: Power type: parsed protocol: NECext address: 83 55 00 00 command: C2 00 00 00 # -name: POWER +name: Power type: parsed protocol: NEC address: 00 00 00 00 command: 51 00 00 00 # -name: POWER +name: Power type: parsed protocol: NECext address: 00 BD 00 00 command: 01 00 00 00 # -name: POWER +name: Power type: parsed protocol: Samsung32 address: 00 00 00 00 command: 0F 00 00 00 # -name: POWER +name: Power type: parsed protocol: Samsung32 address: 16 00 00 00 command: 0F 00 00 00 # -name: POWER +name: Power type: parsed protocol: NEC address: 01 00 00 00 command: 01 00 00 00 # -name: POWER +name: Power type: parsed protocol: NECext address: 80 68 00 00 command: 49 00 00 00 # -name: POWER +name: Power type: parsed protocol: NECext address: 86 02 00 00 command: 49 00 00 00 # -name: POWER +name: Power type: parsed protocol: NECext address: 00 7F 00 00 command: 0A F5 00 00 # -name: POWER +name: Power type: parsed protocol: NECext address: 01 72 00 00 command: 1E E1 00 00 # -name: CH+ +name: Ch_next type: parsed protocol: NECext address: 01 72 00 00 command: 48 B7 00 00 # -name: CH- +name: Ch_prev type: parsed protocol: NECext address: 01 72 00 00 command: 44 BB 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NECext address: 01 72 00 00 command: 0A F5 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NECext address: 01 72 00 00 command: 06 F9 00 00 # -name: MUTE +name: Mute type: parsed protocol: NECext address: 01 72 00 00 command: 5C A3 00 00 # -name: POWER +name: Power type: parsed protocol: NECext address: 86 05 00 00 command: 0F F0 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NECext address: 86 05 00 00 command: 0C F3 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NECext address: 86 05 00 00 command: 0D F2 00 00 # -name: CH+ +name: Ch_next type: parsed protocol: NECext address: 86 05 00 00 command: 0A F5 00 00 # -name: CH- +name: Ch_prev type: parsed protocol: NECext address: 86 05 00 00 command: 0B F4 00 00 # -name: MUTE +name: Mute type: parsed protocol: NECext address: 86 05 00 00 command: 0E F1 00 00 # -name: POWER +name: Power type: parsed protocol: NECext address: 02 7D 00 00 command: 46 B9 00 00 # -name: MUTE +name: Mute type: parsed protocol: NECext address: 02 7D 00 00 command: 4C B3 00 00 # -name: CH+ +name: Ch_next type: parsed protocol: NECext address: 02 7D 00 00 command: 0F F0 00 00 # -name: CH- +name: Ch_prev type: parsed protocol: NECext address: 02 7D 00 00 command: 5A A5 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NECext address: 02 7D 00 00 command: 0C F3 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NECext address: 02 7D 00 00 command: 19 E6 00 00 # -name: CH- +name: Ch_prev type: parsed protocol: NECext address: 02 7D 00 00 command: 41 BE 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NECext address: 02 7D 00 00 command: 42 BD 00 00 # -name: CH- +name: Ch_prev type: parsed protocol: NECext address: 02 7D 00 00 command: 57 A8 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NECext address: 02 7D 00 00 command: 15 EA 00 00 # -name: POWER +name: Power type: parsed protocol: NECext address: 84 E0 00 00 command: 20 DF 00 00 # -name: CH+ +name: Ch_next type: parsed protocol: NECext address: 84 E0 00 00 command: 50 AF 00 00 # -name: CH- +name: Ch_prev type: parsed protocol: NECext address: 84 E0 00 00 command: 51 AE 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NECext address: 84 E0 00 00 command: 60 9F 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NECext address: 84 E0 00 00 command: 61 9E 00 00 # -name: MUTE +name: Mute type: parsed protocol: NECext address: 84 E0 00 00 command: 64 9B 00 00 # -name: CH- +name: Ch_prev type: parsed protocol: NECext address: 84 E0 00 00 command: 57 A8 00 00 # -name: POWER +name: Power type: parsed protocol: NEC address: 6E 00 00 00 command: 02 00 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NEC address: 6E 00 00 00 command: 06 00 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NEC address: 6E 00 00 00 command: 0C 00 00 00 # -name: CH+ +name: Ch_next type: parsed protocol: NEC address: 6E 00 00 00 command: 08 00 00 00 # -name: CH- +name: Ch_prev type: parsed protocol: NEC address: 6E 00 00 00 command: 0E 00 00 00 # -name: MUTE +name: Mute type: parsed protocol: NEC address: 6E 00 00 00 command: 04 00 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NEC address: 04 00 00 00 command: 02 00 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NEC address: 04 00 00 00 command: 03 00 00 00 # -name: MUTE +name: Mute type: parsed protocol: NEC address: 04 00 00 00 command: 09 00 00 00 # -name: CH+ +name: Ch_next type: parsed protocol: NEC address: 04 00 00 00 command: 00 00 00 00 # -name: CH- +name: Ch_prev type: parsed protocol: NEC address: 04 00 00 00 command: 01 00 00 00 # -name: MUTE +name: Mute type: parsed protocol: NEC address: 50 00 00 00 command: 0B 00 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NEC address: 50 00 00 00 command: 12 00 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NEC address: 50 00 00 00 command: 15 00 00 00 # -name: CH+ +name: Ch_next type: parsed protocol: NEC address: 50 00 00 00 command: 19 00 00 00 # -name: CH- +name: Ch_prev type: parsed protocol: NEC address: 50 00 00 00 command: 18 00 00 00 # -name: POWER +name: Power type: parsed protocol: NECext address: 85 7C 00 00 command: 80 7F 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NECext address: 85 7C 00 00 command: 8F 70 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NECext address: 85 7C 00 00 command: 93 6C 00 00 # -name: CH+ +name: Ch_next type: parsed protocol: NECext address: 85 7C 00 00 command: 8D 72 00 00 # -name: CH- +name: Ch_prev type: parsed protocol: NECext address: 85 7C 00 00 command: 91 6E 00 00 # -name: MUTE +name: Mute type: parsed protocol: NECext address: 85 7C 00 00 command: 97 68 00 00 # -name: CH- +name: Ch_prev type: parsed protocol: NECext address: 85 7C 00 00 command: 96 69 00 00 # -name: POWER +name: Power type: parsed protocol: NECext address: EA C7 00 00 command: 17 E8 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NECext address: EA C7 00 00 command: 0F F0 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NECext address: EA C7 00 00 command: 10 EF 00 00 # -name: MUTE +name: Mute type: parsed protocol: NECext address: EA C7 00 00 command: 20 DF 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: RC6 address: 00 00 00 00 command: 10 00 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: RC6 address: 00 00 00 00 command: 11 00 00 00 # -name: CH+ +name: Ch_next type: parsed protocol: RC6 address: 00 00 00 00 command: 4C 00 00 00 # -name: CH- +name: Ch_prev type: parsed protocol: RC6 address: 00 00 00 00 command: 4D 00 00 00 # -name: MUTE +name: Mute type: parsed protocol: RC6 address: 00 00 00 00 command: 0D 00 00 00 # Samsung Standby -name: POWER +name: Power type: parsed protocol: Samsung32 address: 07 00 00 00 command: E0 00 00 00 # Samsung Power Off -name: POWER +name: Power type: parsed protocol: Samsung32 address: 07 00 00 00 command: 98 00 00 00 # -name: POWER +name: Power type: parsed protocol: SIRC address: 01 00 00 00 command: 6D 00 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: SIRC address: 01 00 00 00 command: 73 00 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: SIRC address: 01 00 00 00 command: 72 00 00 00 # -name: CH- +name: Ch_prev type: parsed protocol: SIRC15 address: 97 00 00 00 command: 3C 00 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NEC address: 02 00 00 00 command: 1F 00 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NEC address: 02 00 00 00 command: 1E 00 00 00 # -name: MUTE +name: Mute type: parsed protocol: NEC address: 02 00 00 00 command: 1C 00 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NEC address: 40 00 00 00 command: 1A 00 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NEC address: 40 00 00 00 command: 1E 00 00 00 # -name: CH+ +name: Ch_next type: parsed protocol: NEC address: 40 00 00 00 command: 1B 00 00 00 # -name: CH- +name: Ch_prev type: parsed protocol: NEC address: 40 00 00 00 command: 1F 00 00 00 # -name: CH- +name: Ch_prev type: parsed protocol: NEC address: 04 00 00 00 command: 1A 00 00 00 # -name: POWER +name: Power type: parsed protocol: NEC address: 01 00 00 00 command: 10 00 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NEC address: 01 00 00 00 command: 0E 00 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NEC address: 01 00 00 00 command: 0F 00 00 00 # -name: CH+ +name: Ch_next type: parsed protocol: NEC address: 01 00 00 00 command: 0C 00 00 00 # -name: CH- +name: Ch_prev type: parsed protocol: NEC address: 01 00 00 00 command: 0D 00 00 00 # -name: MUTE +name: Mute type: parsed protocol: NEC address: 01 00 00 00 command: 17 00 00 00 # -name: POWER +name: Power type: parsed protocol: NEC address: 08 00 00 00 command: D7 00 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NEC address: 08 00 00 00 command: 80 00 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NEC address: 08 00 00 00 command: 8E 00 00 00 # -name: CH+ +name: Ch_next type: parsed protocol: NEC address: 08 00 00 00 command: 83 00 00 00 # -name: CH- +name: Ch_prev type: parsed protocol: NEC address: 08 00 00 00 command: 86 00 00 00 # -name: MUTE +name: Mute type: parsed protocol: NEC address: 08 00 00 00 command: DF 00 00 00 # -name: POWER +name: Power type: parsed protocol: RC5 address: 01 00 00 00 command: 0C 00 00 00 # -name: MUTE +name: Mute type: parsed protocol: RC5 address: 01 00 00 00 command: 0D 00 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: RC5 address: 01 00 00 00 command: 10 00 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: RC5 address: 01 00 00 00 command: 11 00 00 00 # -name: CH+ +name: Ch_next type: parsed protocol: RC5 address: 01 00 00 00 command: 20 00 00 00 # -name: CH- +name: Ch_prev type: parsed protocol: RC5 address: 01 00 00 00 command: 21 00 00 00 # -name: MUTE +name: Mute type: parsed protocol: NECext address: 00 7F 00 00 command: 50 AF 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NECext address: 00 7F 00 00 command: 1E E1 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NECext address: 00 7F 00 00 command: 5F A0 00 00 # -name: CH+ +name: Ch_next type: parsed protocol: NECext address: 00 7F 00 00 command: 1F E0 00 00 # -name: CH- +name: Ch_prev type: parsed protocol: NECext address: 00 7F 00 00 command: 5C A3 00 00 # -name: POWER +name: Power type: parsed protocol: NECext address: 64 46 00 00 command: 5D A2 00 00 # -name: CH+ +name: Ch_next type: parsed protocol: NECext address: 64 46 00 00 command: DE 21 00 00 # -name: CH- +name: Ch_prev type: parsed protocol: NECext address: 64 46 00 00 command: DB 24 00 00 # -name: POWER +name: Power type: parsed protocol: NEC address: 20 00 00 00 command: 52 00 00 00 # -name: MUTE +name: Mute type: parsed protocol: NEC address: 20 00 00 00 command: 53 00 00 00 # -name: CH+ +name: Ch_next type: parsed protocol: NEC address: 20 00 00 00 command: 02 00 00 00 # -name: CH- +name: Ch_prev type: parsed protocol: NEC address: 20 00 00 00 command: 09 00 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NEC address: 20 00 00 00 command: 03 00 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NEC address: 20 00 00 00 command: 41 00 00 00 # -name: POWER +name: Power type: parsed protocol: NECext address: 00 BF 00 00 command: 0D F2 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NECext address: 00 BF 00 00 command: 44 BB 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NECext address: 00 BF 00 00 command: 43 BC 00 00 # -name: MUTE +name: Mute type: parsed protocol: NECext address: 00 BF 00 00 command: 0E F1 00 00 # -name: CH+ +name: Ch_next type: parsed protocol: NECext address: 00 BF 00 00 command: 4A B5 00 00 # -name: CH- +name: Ch_prev type: parsed protocol: NECext address: 00 BF 00 00 command: 4B B4 00 00 # -name: POWER +name: Power type: parsed protocol: RC5 address: 03 00 00 00 command: 0C 00 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: RC5 address: 03 00 00 00 command: 10 00 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: RC5 address: 03 00 00 00 command: 11 00 00 00 # -name: CH+ +name: Ch_next type: parsed protocol: RC5 address: 03 00 00 00 command: 20 00 00 00 # -name: CH- +name: Ch_prev type: parsed protocol: RC5 address: 03 00 00 00 command: 21 00 00 00 # -name: MUTE +name: Mute type: parsed protocol: RC5 address: 03 00 00 00 command: 0D 00 00 00 # -name: POWER +name: Power type: parsed protocol: NECext address: 00 BF 00 00 command: 00 FF 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NECext address: 00 BF 00 00 command: 48 B7 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NECext address: 00 BF 00 00 command: 49 B6 00 00 # -name: MUTE +name: Mute type: parsed protocol: NECext address: 00 BF 00 00 command: 01 FE 00 00 # -name: POWER +name: Power type: parsed protocol: Samsung32 address: 17 00 00 00 command: 14 00 00 00 # -name: CH- +name: Ch_prev type: parsed protocol: Samsung32 address: 17 00 00 00 command: 11 00 00 00 # -name: CH+ +name: Ch_next type: parsed protocol: Samsung32 address: 17 00 00 00 command: 10 00 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: Samsung32 address: 17 00 00 00 command: 13 00 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: Samsung32 address: 17 00 00 00 command: 12 00 00 00 # -name: MUTE +name: Mute type: parsed protocol: Samsung32 address: 17 00 00 00 command: 15 00 00 00 # -name: POWER +name: Power type: parsed protocol: RC5 address: 00 00 00 00 command: 0C 00 00 00 # -name: CH+ +name: Ch_next type: parsed protocol: RC5X address: 00 00 00 00 command: 10 00 00 00 # -name: CH- +name: Ch_prev type: parsed protocol: RC5X address: 00 00 00 00 command: 11 00 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: RC5X address: 00 00 00 00 command: 16 00 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: RC5X address: 00 00 00 00 command: 15 00 00 00 # -name: MUTE +name: Mute type: parsed protocol: RC5 address: 00 00 00 00 command: 0D 00 00 00 # -name: CH+ +name: Ch_next type: parsed protocol: RC6 address: 00 00 00 00 command: 20 00 00 00 # -name: CH- +name: Ch_prev type: parsed protocol: RC6 address: 00 00 00 00 command: 21 00 00 00 # -name: POWER +name: Power type: parsed protocol: NEC address: A0 00 00 00 command: 5F 00 00 00 # -name: MUTE +name: Mute type: parsed protocol: NEC address: A0 00 00 00 command: 1C 00 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NEC address: A0 00 00 00 command: 40 00 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NEC address: A0 00 00 00 command: 5D 00 00 00 # -name: CH+ +name: Ch_next type: parsed protocol: NEC address: A0 00 00 00 command: 03 00 00 00 # -name: CH- +name: Ch_prev type: parsed protocol: NEC address: A0 00 00 00 command: 1F 00 00 00 # -name: POWER +name: Power type: parsed protocol: NEC address: 38 00 00 00 command: 12 00 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NEC address: 38 00 00 00 command: 0E 00 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NEC address: 38 00 00 00 command: 0F 00 00 00 # -name: MUTE +name: Mute type: parsed protocol: NEC address: 38 00 00 00 command: 18 00 00 00 # -name: CH+ +name: Ch_next type: parsed protocol: NEC address: 38 00 00 00 command: 0A 00 00 00 # -name: CH- +name: Ch_prev type: parsed protocol: NEC address: 38 00 00 00 command: 0B 00 00 00 # -name: POWER +name: Power type: parsed protocol: SIRC address: 01 00 00 00 command: 2E 00 00 00 # -name: POWER +name: Power type: parsed protocol: SIRC address: 01 00 00 00 command: 2F 00 00 00 # -name: POWER +name: Power type: parsed protocol: NECext address: EA C7 00 00 command: 97 68 00 00 # -name: POWER +name: Power type: parsed protocol: NECext address: 40 40 00 00 command: 0A F5 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NECext address: 40 40 00 00 command: 15 EA 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NECext address: 40 40 00 00 command: 1C E3 00 00 # -name: CH+ +name: Ch_next type: parsed protocol: NECext address: 40 40 00 00 command: 1F E0 00 00 # -name: CH- +name: Ch_prev type: parsed protocol: NECext address: 40 40 00 00 command: 1E E1 00 00 # -name: MUTE +name: Mute type: parsed protocol: NECext address: 40 40 00 00 command: 0F F0 00 00 # -name: MUTE +name: Mute type: parsed protocol: NEC address: 01 00 00 00 command: 41 00 00 00 # -name: MUTE +name: Mute type: parsed protocol: NECext address: A0 B7 00 00 command: AF 50 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NECext address: AD ED 00 00 command: BA 45 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NECext address: AD ED 00 00 command: BB 44 00 00 # -name: CH+ +name: Ch_next type: parsed protocol: NECext address: AD ED 00 00 command: B0 4F 00 00 # -name: CH- +name: Ch_prev type: parsed protocol: NECext address: AD ED 00 00 command: B1 4E 00 00 # -name: MUTE +name: Mute type: parsed protocol: NECext address: AD ED 00 00 command: C5 3A 00 00 # -name: POWER +name: Power type: parsed protocol: NEC address: 00 00 00 00 command: 1A 00 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NEC address: 00 00 00 00 command: 11 00 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NEC address: 00 00 00 00 command: 33 00 00 00 # -name: POWER +name: Power type: parsed protocol: NEC address: 28 00 00 00 command: 0B 00 00 00 # -name: CH+ +name: Ch_next type: parsed protocol: NEC address: 28 00 00 00 command: 0C 00 00 00 # -name: CH- +name: Ch_prev type: parsed protocol: NEC address: 28 00 00 00 command: 0D 00 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NEC address: 28 00 00 00 command: 0E 00 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NEC address: 28 00 00 00 command: 0F 00 00 00 # -name: MUTE +name: Mute type: parsed protocol: NEC address: 28 00 00 00 command: 10 00 00 00 # -name: CH+ +name: Ch_next type: parsed protocol: RC5 address: 01 00 00 00 command: 14 00 00 00 # -name: CH+ +name: Ch_next type: parsed protocol: SIRC20 address: 5A 0E 00 00 command: 10 00 00 00 # -name: CH- +name: Ch_prev type: parsed protocol: SIRC20 address: 5A 0E 00 00 command: 11 00 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: RC5 address: 00 00 00 00 command: 15 00 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: RC5 address: 00 00 00 00 command: 14 00 00 00 # -name: CH+ +name: Ch_next type: parsed protocol: RC5 address: 00 00 00 00 command: 18 00 00 00 # -name: CH- +name: Ch_prev type: parsed protocol: RC5 address: 00 00 00 00 command: 17 00 00 00 # -name: POWER +name: Power type: parsed protocol: NEC address: 80 00 00 00 command: 12 00 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NEC address: 80 00 00 00 command: 1A 00 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NEC address: 80 00 00 00 command: 1E 00 00 00 # -name: MUTE +name: Mute type: parsed protocol: NEC address: 80 00 00 00 command: 10 00 00 00 # -name: CH+ +name: Ch_next type: parsed protocol: SIRC20 address: 10 01 00 00 command: 34 00 00 00 # -name: CH- +name: Ch_prev type: parsed protocol: SIRC20 address: 10 01 00 00 @@ -1902,73 +1902,73 @@ command: 33 00 00 00 # # Sharp TV # -name: POWER +name: Power type: parsed protocol: NECext address: 00 BD 00 00 command: 01 FE 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: NECext address: 00 BD 00 00 command: 0C F3 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: NECext address: 00 BD 00 00 command: 10 EF 00 00 # -name: CH+ +name: Ch_next type: parsed protocol: NECext address: 00 BD 00 00 command: 18 E7 00 00 # -name: CH- +name: Ch_prev type: parsed protocol: NECext address: 00 BD 00 00 command: 1C E3 00 00 # -name: MUTE +name: Mute type: parsed protocol: NECext address: 00 BD 00 00 command: 04 FB 00 00 # -name: POWER +name: Power type: raw frequency: 38000 duty_cycle: 0.330000 data: 278 1811 277 788 246 794 250 764 280 786 248 792 252 1813 275 1815 273 791 253 1812 276 789 255 785 249 791 253 1812 276 789 255 45322 280 1809 279 786 248 766 278 788 246 794 250 1815 273 792 252 788 246 1819 280 785 249 1817 271 1819 280 1810 278 787 247 1818 281 43217 274 1818 270 794 250 764 280 786 248 792 252 788 256 1809 279 1811 277 788 246 1819 280 785 249 766 278 762 272 1819 280 785 248 # -name: MUTE +name: Mute type: raw frequency: 38000 duty_cycle: 0.330000 data: 278 1812 276 762 282 758 276 765 279 761 273 1818 281 1809 279 1811 277 762 282 1809 279 760 274 766 278 762 282 1809 279 760 274 44279 276 1813 275 763 281 759 275 766 278 762 272 768 276 764 280 760 274 1817 271 768 276 1815 273 1817 271 1819 280 759 275 1816 272 44276 279 1812 276 763 281 758 276 765 279 761 273 1818 281 1810 278 1811 277 762 272 1819 279 760 274 766 278 762 282 1809 279 760 274 # -name: VOL+ +name: Vol_up type: raw frequency: 38000 duty_cycle: 0.330000 data: 272 1817 271 794 250 790 254 786 248 792 252 762 272 794 250 1815 273 792 252 1813 275 790 254 785 249 766 278 1813 275 789 255 46372 273 1817 271 794 250 763 281 785 248 792 252 1813 275 1814 274 791 253 1812 276 789 255 1810 278 1812 276 1813 275 790 254 1811 277 42170 277 1814 274 791 253 787 247 793 251 763 281 759 275 791 253 1812 276 789 255 1810 278 787 247 793 251 789 255 1810 278 787 247 # -name: VOL- +name: Vol_dn type: raw frequency: 38000 duty_cycle: 0.330000 data: 275 1814 274 791 253 787 247 793 251 789 255 1810 278 787 247 1818 281 785 249 1816 272 793 251 789 255 785 249 1816 272 766 278 45325 274 1815 273 792 252 762 272 794 250 790 254 786 247 1818 270 794 250 1815 273 792 252 1813 275 1815 273 1816 272 793 251 1814 274 43224 277 1814 274 764 280 786 248 792 252 788 246 1820 279 786 247 1817 271 768 276 1815 273 792 252 761 273 794 250 1815 273 791 253 # -name: CH+ +name: Ch_next type: raw frequency: 38000 duty_cycle: 0.330000 data: 272 1817 271 794 250 790 254 786 248 792 252 1813 275 790 254 759 275 792 252 1813 275 789 255 785 248 792 252 1813 275 789 255 46372 273 1817 271 793 251 763 281 759 275 791 253 787 247 1818 281 1810 278 1812 276 789 255 1809 279 1811 277 1813 275 790 254 1811 277 42169 277 1815 273 792 252 787 247 794 250 789 255 1810 278 787 247 794 250 789 255 1810 278 761 273 793 251 789 255 1810 278 787 247 # -name: CH- +name: Ch_prev type: raw frequency: 38000 duty_cycle: 0.330000 @@ -1976,73 +1976,73 @@ data: 273 1816 272 767 277 789 255 785 249 791 253 787 246 1818 281 785 248 765 # # Brandt TV # -name: POWER +name: Power type: raw frequency: 38000 duty_cycle: 0.330000 data: 9346 4516 657 502 659 502 688 473 687 475 634 527 635 527 634 1662 633 528 662 1634 662 1658 635 1660 608 1687 609 1687 633 1662 634 527 634 1662 634 528 633 1663 632 529 632 530 631 1665 630 531 630 531 631 531 630 1666 630 531 630 1666 630 1666 630 532 630 1666 630 1666 630 1666 630 # -name: VOL+ +name: Vol_up type: raw frequency: 38000 duty_cycle: 0.330000 data: 9348 4542 631 529 632 503 659 502 688 474 634 527 634 527 634 1661 635 528 661 1636 660 1659 634 1637 632 1687 608 1687 609 1687 609 552 632 1664 633 528 633 1663 633 529 632 1664 631 1665 631 531 630 531 631 531 631 1665 631 531 631 1666 630 531 631 531 630 1666 630 1666 630 1666 631 # -name: VOL- +name: Vol_dn type: raw frequency: 38000 duty_cycle: 0.330000 data: 9376 4512 660 475 684 475 635 527 634 528 633 527 634 527 634 1662 662 525 636 1658 637 1658 637 1658 636 1659 636 1660 635 1660 635 526 635 1661 634 527 634 1662 633 1663 632 1664 631 1665 630 531 631 531 630 531 630 1666 630 531 630 531 631 531 630 531 631 1666 630 1666 630 1667 630 # -name: CH+ +name: Ch_next type: raw frequency: 38000 duty_cycle: 0.330000 data: 9315 4513 657 501 660 501 659 500 661 502 688 499 661 474 634 1660 634 527 634 1660 634 1686 608 1687 607 1686 608 1686 608 1686 608 552 608 1686 608 1687 607 1687 632 530 631 1664 630 1665 630 531 630 531 630 531 630 531 630 531 630 1665 630 531 630 531 630 1665 630 1665 630 1665 630 # -name: CH- +name: Ch_prev type: raw frequency: 38000 duty_cycle: 0.330000 data: 9345 4540 631 503 658 529 661 475 683 476 635 526 635 527 634 1661 634 527 662 1658 636 1659 634 1660 608 1686 609 1686 634 1661 634 527 634 1661 634 1662 633 1662 633 1663 632 1664 630 1665 630 531 630 531 630 531 630 531 631 531 630 531 630 531 630 532 629 1666 630 1666 629 1666 629 # -name: MUTE +name: Mute type: raw frequency: 38000 duty_cycle: 0.330000 data: 9348 4516 657 501 660 502 659 502 659 502 688 474 634 527 634 1662 634 528 633 1687 634 1660 608 1664 631 1687 608 1687 609 1686 609 552 609 1687 608 553 632 529 633 529 632 530 631 1665 630 531 630 531 631 531 630 1666 630 1666 630 1666 630 1666 630 531 631 1666 630 1666 630 1666 630 # -name: POWER +name: Power type: parsed protocol: Samsung32 address: 3E 00 00 00 command: 0C 00 00 00 # -name: VOL+ +name: Vol_up type: parsed protocol: Samsung32 address: 3E 00 00 00 command: 14 00 00 00 # -name: VOL- +name: Vol_dn type: parsed protocol: Samsung32 address: 3E 00 00 00 command: 15 00 00 00 # -name: CH+ +name: Ch_next type: parsed protocol: Samsung32 address: 3E 00 00 00 command: 12 00 00 00 # -name: CH- +name: Ch_prev type: parsed protocol: Samsung32 address: 3E 00 00 00 command: 13 00 00 00 # -name: MUTE +name: Mute type: parsed protocol: Samsung32 address: 3E 00 00 00 From 48a2b0ab49c2f2afbc2142d61a6fb60c93b205a1 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Tue, 30 May 2023 01:25:15 +0300 Subject: [PATCH 23/52] New audio buttons by @amec0e --- assets/resources/infrared/assets/audio.ir | 396 +++++++++++++++++++++- 1 file changed, 394 insertions(+), 2 deletions(-) diff --git a/assets/resources/infrared/assets/audio.ir b/assets/resources/infrared/assets/audio.ir index cfb89f911..75d897007 100644 --- a/assets/resources/infrared/assets/audio.ir +++ b/assets/resources/infrared/assets/audio.ir @@ -1,7 +1,7 @@ Filetype: IR library file Version: 1 -# Last Updated 14th Apr, 2023 -# Last Checked 17th May, 2023 +# Last Updated 29th May, 2023 +# Last Checked 29th May, 2023 # name: Power type: parsed @@ -2176,3 +2176,395 @@ type: parsed protocol: NEC address: 00 00 00 00 command: 46 00 00 00 +# +# Soundbars +# +name: Play +type: parsed +protocol: NECext +address: 86 FF 00 00 +command: 2A D5 00 00 +# +name: Prev +type: parsed +protocol: NECext +address: 86 FF 00 00 +command: 13 EC 00 00 +# +name: Pause +type: parsed +protocol: NECext +address: BA A0 00 00 +command: 56 A9 00 00 +# +name: Prev +type: parsed +protocol: NECext +address: 83 22 00 00 +command: 07 F8 00 00 +# +name: Play +type: parsed +protocol: Samsung32 +address: 2C 00 00 00 +command: 4F 00 00 00 +# +name: Pause +type: parsed +protocol: NECext +address: C8 91 00 00 +command: 21 DE 00 00 +# +name: Next +type: raw +frequency: 38000 +duty_cycle: 0.33 +data: 4582 4465 551 454 550 455 550 455 549 456 549 1460 550 1460 549 457 548 456 549 1461 549 1461 548 1461 549 1460 549 457 549 456 548 457 548 457 548 4461 549 456 548 457 548 457 548 457 548 457 548 457 548 1462 548 1461 547 457 549 457 548 456 549 1460 549 1461 547 1461 549 457 547 457 548 1461 549 1461 548 1461 548 457 548 55436 4578 4464 549 455 549 456 549 455 549 456 550 1460 549 1460 549 456 550 455 550 1460 550 1460 549 1460 550 1460 549 456 549 457 548 457 548 457 549 4461 548 457 548 457 548 457 548 457 547 457 549 457 547 1462 548 1461 549 457 548 457 548 457 548 1461 548 1461 548 1462 548 457 548 457 549 1461 549 1461 548 1461 548 457 548 +# +name: Play +type: parsed +protocol: SIRC20 +address: 3A 07 00 00 +command: 32 00 00 00 +# +name: Pause +type: parsed +protocol: SIRC20 +address: 3A 07 00 00 +command: 39 00 00 00 +# +name: Play +type: parsed +protocol: SIRC20 +address: 10 01 00 00 +command: 32 00 00 00 +# +name: Pause +type: parsed +protocol: SIRC20 +address: 10 01 00 00 +command: 39 00 00 00 +# +name: Play +type: parsed +protocol: NEC +address: 00 00 00 00 +command: 8E 00 00 00 +# +name: Prev +type: parsed +protocol: NEC +address: 00 00 00 00 +command: 8A 00 00 00 +# +# CDPlayers +# +name: Play +type: parsed +protocol: NEC42 +address: 6E 00 00 00 +command: 40 00 00 00 +# +name: Pause +type: parsed +protocol: NEC42 +address: 6E 00 00 00 +command: 44 00 00 00 +# +name: Prev +type: parsed +protocol: Kaseikyo +address: 51 54 32 01 +command: 47 00 00 00 +# +name: Play +type: parsed +protocol: RC5 +address: 14 00 00 00 +command: 35 00 00 00 +# +name: Pause +type: parsed +protocol: RC5 +address: 14 00 00 00 +command: 30 00 00 00 +# +name: Prev +type: parsed +protocol: RC5 +address: 14 00 00 00 +command: 21 00 00 00 +# +name: Play +type: raw +frequency: 38000 +duty_cycle: 0.33 +data: 8546 4227 563 511 563 1558 566 511 563 483 566 508 567 1558 566 509 566 1558 566 1586 564 483 566 1561 588 1558 566 1560 564 536 539 1558 566 535 539 1558 566 1586 564 1557 567 486 589 1560 564 511 563 510 539 508 567 485 589 484 565 508 567 1559 565 509 566 1560 564 1560 590 1585 539 25430 8575 4251 538 485 590 1557 567 486 588 511 538 536 539 1557 567 509 566 1558 566 1560 590 483 566 1560 589 1559 565 1562 562 536 539 1560 564 509 566 1558 566 1564 586 1586 538 484 590 1559 565 487 588 482 567 509 566 511 563 483 566 508 567 1558 566 509 566 1560 564 1559 591 1586 538 +# +name: Pause +type: raw +frequency: 38000 +duty_cycle: 0.33 +data: 8571 4226 564 509 540 1587 563 510 539 510 565 510 564 1558 566 510 565 1584 540 1585 539 535 540 1587 537 1586 564 1585 539 510 564 1584 540 511 563 482 567 535 539 485 590 1584 540 1585 539 509 566 510 564 510 539 1586 564 1585 539 1585 539 536 539 510 564 1585 539 1557 567 1558 592 25434 8571 4199 591 510 539 1586 564 509 540 535 540 485 590 1585 539 484 591 1561 563 1584 540 507 568 1585 539 1586 564 1585 539 486 589 1585 539 484 591 425 624 535 540 486 589 1585 539 1585 539 511 564 511 563 486 563 1586 564 1558 566 1558 566 508 567 486 589 1560 564 1558 566 1561 589 +# +name: Pause +type: parsed +protocol: NEC +address: 4D 00 00 00 +command: 0F 00 00 00 +# +name: Play +type: parsed +protocol: SIRC15 +address: 64 00 00 00 +command: 32 00 00 00 +# +name: Pause +type: parsed +protocol: SIRC15 +address: 64 00 00 00 +command: 39 00 00 00 +# +name: Play +type: parsed +protocol: SIRC +address: 0F 00 00 00 +command: 2A 00 00 00 +# +name: Pause +type: parsed +protocol: SIRC +address: 0F 00 00 00 +command: 29 00 00 00 +# +name: Play +type: parsed +protocol: NECext +address: 86 61 00 00 +command: 08 F7 00 00 +# +name: Pause +type: parsed +protocol: NECext +address: 86 61 00 00 +command: 05 FA 00 00 +# +name: Prev +type: parsed +protocol: NECext +address: 00 EF 00 00 +command: 01 FE 00 00 +# +# Speakers +# +name: Prev +type: raw +frequency: 38000 +duty_cycle: 0.33 +data: 1046 1457 543 1458 542 454 546 450 539 1461 539 456 544 1458 542 1458 542 454 546 451 539 1461 539 1462 538 458 542 1459 541 454 546 451 539 1454 546 50538 1043 1461 539 1461 539 456 544 453 547 1454 546 449 541 1461 539 1462 538 457 543 453 547 1455 545 1455 545 451 539 1462 538 458 542 454 546 1447 543 50526 1044 1459 541 1459 541 455 545 451 539 1463 537 458 542 1459 541 1460 540 455 545 452 538 1463 537 1464 536 460 540 1461 539 456 544 453 536 1456 544 +# +name: Prev +type: parsed +protocol: NEC +address: 00 00 00 00 +command: 07 00 00 00 +# +name: Pause +type: parsed +protocol: NEC +address: 00 00 00 00 +command: 15 00 00 00 +# +name: Prev +type: parsed +protocol: NEC +address: 00 00 00 00 +command: 10 00 00 00 +# +name: Next +type: parsed +protocol: NEC +address: 00 00 00 00 +command: 13 00 00 00 +# +name: Prev +type: parsed +protocol: NEC +address: 00 00 00 00 +command: 0B 00 00 00 +# +name: Prev +type: parsed +protocol: NECext +address: 40 AF 00 00 +command: 12 ED 00 00 +# +name: Play +type: parsed +protocol: NECext +address: 02 BD 00 00 +command: 0D F2 00 00 +# +name: Prev +type: parsed +protocol: NECext +address: 02 BD 00 00 +command: 25 DA 00 00 +# +name: Play +type: raw +frequency: 38000 +duty_cycle: 0.33 +data: 9175 4433 644 1605 645 442 669 466 646 445 666 438 673 466 645 440 671 466 673 410 700 365 720 465 675 367 742 367 744 438 645 1604 675 1574 674 1549 702 1575 673 1576 646 1604 675 1574 676 1574 675 1576 644 1604 645 1606 672 1576 645 466 645 466 645 465 646 1575 675 1605 645 466 645 467 644 467 644 1605 644 1605 645 1606 644 467 644 467 644 1606 643 1578 672 1607 643 +# +name: Prev +type: raw +frequency: 38000 +duty_cycle: 0.33 +data: 9144 4405 671 1607 642 469 642 469 642 469 642 470 641 365 747 469 641 443 669 469 642 468 643 446 665 469 642 469 642 470 642 1580 669 1607 643 1607 642 1608 641 1578 672 1580 670 1608 641 1608 641 1609 590 1660 590 1635 615 1660 590 1660 590 1632 618 1633 617 521 590 1660 590 521 590 521 618 493 590 521 590 520 591 519 592 1657 592 519 592 1658 617 1633 616 1633 615 23844 9114 4461 615 +# +name: Play +type: parsed +protocol: SIRC +address: 10 00 00 00 +command: 0C 00 00 00 +# +name: Prev +type: parsed +protocol: NECext +address: 2D D3 00 00 +command: 07 F8 00 00 +# +# Audio Receivers +# +name: Pause +type: parsed +protocol: NEC +address: 00 00 00 00 +command: 09 00 00 00 +# +name: Play +type: parsed +protocol: NEC +address: 04 00 00 00 +command: 12 00 00 00 +# +name: Prev +type: parsed +protocol: NEC +address: 04 00 00 00 +command: 04 00 00 00 +# +name: Play +type: parsed +protocol: NEC +address: 00 00 00 00 +command: 00 00 00 00 +# +name: Play +type: parsed +protocol: NECext +address: D2 03 00 00 +command: 1B E4 00 00 +# +name: Pause +type: parsed +protocol: NECext +address: D2 03 00 00 +command: 1F E0 00 00 +# +name: Pause +type: parsed +protocol: NECext +address: D2 02 00 00 +command: 91 6E 00 00 +# +name: Play +type: parsed +protocol: NECext +address: D2 02 00 00 +command: 8D 72 00 00 +# +name: Prev +type: parsed +protocol: NECext +address: D2 02 00 00 +command: 90 6F 00 00 +# +name: Next +type: parsed +protocol: NECext +address: D2 02 00 00 +command: 8F 70 00 00 +# +name: Prev +type: parsed +protocol: Kaseikyo +address: AC 02 20 01 +command: 91 00 00 00 +# +name: Play +type: raw +frequency: 38000 +duty_cycle: 0.33 +data: 3467 1720 449 450 419 1296 443 455 425 446 423 447 422 449 420 451 418 452 417 454 426 445 424 447 422 448 421 450 419 1296 443 455 425 446 423 447 422 449 420 450 419 452 417 454 426 1290 449 448 421 1294 445 453 416 455 425 1291 448 1294 445 1297 453 418 451 447 422 448 421 423 446 1296 443 1300 450 448 421 422 447 424 445 425 444 427 453 418 451 1292 447 450 419 1297 442 1300 450 1292 447 451 418 1297 453 74912 3466 1722 447 424 445 1297 453 418 451 420 449 421 448 423 446 425 444 427 453 418 451 420 449 421 448 423 446 424 445 1297 453 419 450 420 449 422 447 424 445 425 444 427 453 418 451 1291 448 423 446 1296 443 428 452 419 450 1292 447 1295 444 1298 452 420 449 421 448 423 446 425 444 1298 452 1290 449 422 447 424 445 425 444 427 453 418 451 420 449 1293 446 425 444 1298 452 1290 449 1294 445 425 444 1298 452 +# +name: Prev +type: parsed +protocol: Kaseikyo +address: AC 02 20 00 +command: 21 00 00 00 +# +name: Play +type: parsed +protocol: Kaseikyo +address: AC 02 20 00 +command: 61 00 00 00 +# +name: Prev +type: parsed +protocol: NEC +address: 00 00 00 00 +command: 4D 00 00 00 +# +name: Play +type: parsed +protocol: NEC +address: 40 00 00 00 +command: 59 00 00 00 +# +name: Pause +type: parsed +protocol: NEC +address: 40 00 00 00 +command: 18 00 00 00 +# +name: Play +type: parsed +protocol: RC5X +address: 0A 00 00 00 +command: 31 00 00 00 +# +name: Pause +type: parsed +protocol: RC5X +address: 0A 00 00 00 +command: 0F 00 00 00 +# +name: Play +type: parsed +protocol: NEC +address: 78 00 00 00 +command: 02 00 00 00 +# +name: Play +type: parsed +protocol: NECext +address: 7F 01 00 00 +command: 68 97 00 00 +# +name: Pause +type: parsed +protocol: NECext +address: 7F 01 00 00 +command: 67 98 00 00 From 81023875d5b73447a142598f0081b6c4529b12f4 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Tue, 30 May 2023 14:33:35 +0300 Subject: [PATCH 24/52] Update audio ir by @amec0e --- assets/resources/infrared/assets/audio.ir | 1154 +++++++++++++++------ 1 file changed, 862 insertions(+), 292 deletions(-) diff --git a/assets/resources/infrared/assets/audio.ir b/assets/resources/infrared/assets/audio.ir index 75d897007..72d07c82b 100644 --- a/assets/resources/infrared/assets/audio.ir +++ b/assets/resources/infrared/assets/audio.ir @@ -1,7 +1,7 @@ Filetype: IR library file Version: 1 -# Last Updated 29th May, 2023 -# Last Checked 29th May, 2023 +# Last Updated 30th May, 2023 +# Last Checked 30th May, 2023 # name: Power type: parsed @@ -2176,395 +2176,965 @@ type: parsed protocol: NEC address: 00 00 00 00 command: 46 00 00 00 -# -# Soundbars # -name: Play -type: parsed -protocol: NECext -address: 86 FF 00 00 -command: 2A D5 00 00 -# -name: Prev -type: parsed -protocol: NECext -address: 86 FF 00 00 -command: 13 EC 00 00 -# -name: Pause -type: parsed -protocol: NECext -address: BA A0 00 00 -command: 56 A9 00 00 -# -name: Prev -type: parsed -protocol: NECext -address: 83 22 00 00 -command: 07 F8 00 00 -# -name: Play -type: parsed -protocol: Samsung32 -address: 2C 00 00 00 -command: 4F 00 00 00 -# -name: Pause -type: parsed -protocol: NECext -address: C8 91 00 00 -command: 21 DE 00 00 -# -name: Next -type: raw -frequency: 38000 -duty_cycle: 0.33 -data: 4582 4465 551 454 550 455 550 455 549 456 549 1460 550 1460 549 457 548 456 549 1461 549 1461 548 1461 549 1460 549 457 549 456 548 457 548 457 548 4461 549 456 548 457 548 457 548 457 548 457 548 457 548 1462 548 1461 547 457 549 457 548 456 549 1460 549 1461 547 1461 549 457 547 457 548 1461 549 1461 548 1461 548 457 548 55436 4578 4464 549 455 549 456 549 455 549 456 550 1460 549 1460 549 456 550 455 550 1460 550 1460 549 1460 550 1460 549 456 549 457 548 457 548 457 549 4461 548 457 548 457 548 457 548 457 547 457 549 457 547 1462 548 1461 549 457 548 457 548 457 548 1461 548 1461 548 1462 548 457 548 457 549 1461 549 1461 548 1461 548 457 548 -# -name: Play -type: parsed -protocol: SIRC20 -address: 3A 07 00 00 -command: 32 00 00 00 -# -name: Pause -type: parsed -protocol: SIRC20 -address: 3A 07 00 00 -command: 39 00 00 00 -# -name: Play -type: parsed -protocol: SIRC20 -address: 10 01 00 00 -command: 32 00 00 00 -# -name: Pause -type: parsed -protocol: SIRC20 -address: 10 01 00 00 -command: 39 00 00 00 -# -name: Play -type: parsed -protocol: NEC -address: 00 00 00 00 -command: 8E 00 00 00 -# -name: Prev -type: parsed -protocol: NEC -address: 00 00 00 00 -command: 8A 00 00 00 -# -# CDPlayers -# -name: Play -type: parsed -protocol: NEC42 -address: 6E 00 00 00 -command: 40 00 00 00 -# -name: Pause -type: parsed -protocol: NEC42 -address: 6E 00 00 00 -command: 44 00 00 00 -# -name: Prev -type: parsed -protocol: Kaseikyo -address: 51 54 32 01 -command: 47 00 00 00 -# -name: Play -type: parsed -protocol: RC5 -address: 14 00 00 00 -command: 35 00 00 00 -# -name: Pause -type: parsed -protocol: RC5 -address: 14 00 00 00 -command: 30 00 00 00 -# -name: Prev -type: parsed -protocol: RC5 -address: 14 00 00 00 -command: 21 00 00 00 -# -name: Play -type: raw -frequency: 38000 -duty_cycle: 0.33 -data: 8546 4227 563 511 563 1558 566 511 563 483 566 508 567 1558 566 509 566 1558 566 1586 564 483 566 1561 588 1558 566 1560 564 536 539 1558 566 535 539 1558 566 1586 564 1557 567 486 589 1560 564 511 563 510 539 508 567 485 589 484 565 508 567 1559 565 509 566 1560 564 1560 590 1585 539 25430 8575 4251 538 485 590 1557 567 486 588 511 538 536 539 1557 567 509 566 1558 566 1560 590 483 566 1560 589 1559 565 1562 562 536 539 1560 564 509 566 1558 566 1564 586 1586 538 484 590 1559 565 487 588 482 567 509 566 511 563 483 566 508 567 1558 566 509 566 1560 564 1559 591 1586 538 -# -name: Pause -type: raw -frequency: 38000 -duty_cycle: 0.33 -data: 8571 4226 564 509 540 1587 563 510 539 510 565 510 564 1558 566 510 565 1584 540 1585 539 535 540 1587 537 1586 564 1585 539 510 564 1584 540 511 563 482 567 535 539 485 590 1584 540 1585 539 509 566 510 564 510 539 1586 564 1585 539 1585 539 536 539 510 564 1585 539 1557 567 1558 592 25434 8571 4199 591 510 539 1586 564 509 540 535 540 485 590 1585 539 484 591 1561 563 1584 540 507 568 1585 539 1586 564 1585 539 486 589 1585 539 484 591 425 624 535 540 486 589 1585 539 1585 539 511 564 511 563 486 563 1586 564 1558 566 1558 566 508 567 486 589 1560 564 1558 566 1561 589 -# -name: Pause -type: parsed -protocol: NEC -address: 4D 00 00 00 -command: 0F 00 00 00 -# -name: Play -type: parsed -protocol: SIRC15 -address: 64 00 00 00 -command: 32 00 00 00 -# -name: Pause -type: parsed -protocol: SIRC15 -address: 64 00 00 00 -command: 39 00 00 00 -# -name: Play -type: parsed -protocol: SIRC -address: 0F 00 00 00 -command: 2A 00 00 00 -# -name: Pause -type: parsed -protocol: SIRC -address: 0F 00 00 00 -command: 29 00 00 00 -# -name: Play -type: parsed -protocol: NECext -address: 86 61 00 00 -command: 08 F7 00 00 -# -name: Pause -type: parsed -protocol: NECext -address: 86 61 00 00 -command: 05 FA 00 00 -# -name: Prev -type: parsed -protocol: NECext -address: 00 EF 00 00 -command: 01 FE 00 00 -# -# Speakers -# -name: Prev -type: raw -frequency: 38000 -duty_cycle: 0.33 -data: 1046 1457 543 1458 542 454 546 450 539 1461 539 456 544 1458 542 1458 542 454 546 451 539 1461 539 1462 538 458 542 1459 541 454 546 451 539 1454 546 50538 1043 1461 539 1461 539 456 544 453 547 1454 546 449 541 1461 539 1462 538 457 543 453 547 1455 545 1455 545 451 539 1462 538 458 542 454 546 1447 543 50526 1044 1459 541 1459 541 455 545 451 539 1463 537 458 542 1459 541 1460 540 455 545 452 538 1463 537 1464 536 460 540 1461 539 456 544 453 536 1456 544 -# -name: Prev -type: parsed -protocol: NEC -address: 00 00 00 00 -command: 07 00 00 00 -# -name: Pause -type: parsed -protocol: NEC -address: 00 00 00 00 -command: 15 00 00 00 -# -name: Prev -type: parsed -protocol: NEC -address: 00 00 00 00 -command: 10 00 00 00 -# -name: Next -type: parsed -protocol: NEC -address: 00 00 00 00 -command: 13 00 00 00 -# -name: Prev -type: parsed -protocol: NEC -address: 00 00 00 00 -command: 0B 00 00 00 -# -name: Prev -type: parsed -protocol: NECext -address: 40 AF 00 00 -command: 12 ED 00 00 -# -name: Play -type: parsed -protocol: NECext -address: 02 BD 00 00 -command: 0D F2 00 00 -# -name: Prev -type: parsed -protocol: NECext -address: 02 BD 00 00 -command: 25 DA 00 00 -# -name: Play -type: raw -frequency: 38000 -duty_cycle: 0.33 -data: 9175 4433 644 1605 645 442 669 466 646 445 666 438 673 466 645 440 671 466 673 410 700 365 720 465 675 367 742 367 744 438 645 1604 675 1574 674 1549 702 1575 673 1576 646 1604 675 1574 676 1574 675 1576 644 1604 645 1606 672 1576 645 466 645 466 645 465 646 1575 675 1605 645 466 645 467 644 467 644 1605 644 1605 645 1606 644 467 644 467 644 1606 643 1578 672 1607 643 -# -name: Prev -type: raw -frequency: 38000 -duty_cycle: 0.33 -data: 9144 4405 671 1607 642 469 642 469 642 469 642 470 641 365 747 469 641 443 669 469 642 468 643 446 665 469 642 469 642 470 642 1580 669 1607 643 1607 642 1608 641 1578 672 1580 670 1608 641 1608 641 1609 590 1660 590 1635 615 1660 590 1660 590 1632 618 1633 617 521 590 1660 590 521 590 521 618 493 590 521 590 520 591 519 592 1657 592 519 592 1658 617 1633 616 1633 615 23844 9114 4461 615 -# -name: Play -type: parsed -protocol: SIRC -address: 10 00 00 00 -command: 0C 00 00 00 -# -name: Prev -type: parsed -protocol: NECext -address: 2D D3 00 00 -command: 07 F8 00 00 -# -# Audio Receivers +# Audio_Receivers # name: Pause type: parsed protocol: NEC address: 00 00 00 00 command: 09 00 00 00 -# +# +name: Next +type: parsed +protocol: NEC +address: 00 00 00 00 +command: 15 00 00 00 +# +name: Prev +type: parsed +protocol: NEC +address: 00 00 00 00 +command: 07 00 00 00 +# name: Play type: parsed protocol: NEC address: 04 00 00 00 command: 12 00 00 00 -# +# name: Prev type: parsed protocol: NEC address: 04 00 00 00 command: 04 00 00 00 -# +# +name: Next +type: parsed +protocol: NEC +address: 04 00 00 00 +command: 5E 00 00 00 +# +name: Pause +type: parsed +protocol: RC5 +address: 14 00 00 00 +command: 30 00 00 00 +# +name: Play +type: parsed +protocol: NECext +address: 10 E7 00 00 +command: 5F A0 00 00 +# +name: Pause +type: parsed +protocol: NECext +address: 10 E7 00 00 +command: 5F A0 00 00 +# +name: Next +type: parsed +protocol: NEC +address: 00 00 00 00 +command: 02 00 00 00 +# name: Play type: parsed protocol: NEC address: 00 00 00 00 command: 00 00 00 00 -# +# +name: Play +type: parsed +protocol: NECext +address: 30 FC 00 00 +command: 02 FD 00 00 +# +name: Pause +type: parsed +protocol: NECext +address: 30 FC 00 00 +command: 02 FD 00 00 +# name: Play type: parsed protocol: NECext address: D2 03 00 00 command: 1B E4 00 00 -# +# name: Pause type: parsed protocol: NECext address: D2 03 00 00 command: 1F E0 00 00 -# -name: Pause -type: parsed -protocol: NECext -address: D2 02 00 00 -command: 91 6E 00 00 -# -name: Play -type: parsed -protocol: NECext -address: D2 02 00 00 -command: 8D 72 00 00 -# +# name: Prev type: parsed protocol: NECext address: D2 02 00 00 command: 90 6F 00 00 -# +# name: Next type: parsed protocol: NECext address: D2 02 00 00 command: 8F 70 00 00 -# +# +name: Pause +type: parsed +protocol: NECext +address: D2 02 00 00 +command: 91 6E 00 00 +# +name: Play +type: parsed +protocol: NECext +address: D2 02 00 00 +command: 8D 72 00 00 +# +name: Play +type: parsed +protocol: NECext +address: D2 19 00 00 +command: 5C A3 00 00 +# +name: Play +type: parsed +protocol: Kaseikyo +address: AA 02 20 00 +command: A0 00 00 00 +# +name: Pause +type: parsed +protocol: NECext +address: D2 19 00 00 +command: 5C A3 00 00 +# +name: Pause +type: parsed +protocol: Kaseikyo +address: AA 02 20 00 +command: A0 00 00 00 +# +name: Next +type: parsed +protocol: Kaseikyo +address: AC 02 20 01 +command: A1 00 00 00 +# name: Prev type: parsed protocol: Kaseikyo address: AC 02 20 01 command: 91 00 00 00 -# +# name: Play type: raw frequency: 38000 duty_cycle: 0.33 data: 3467 1720 449 450 419 1296 443 455 425 446 423 447 422 449 420 451 418 452 417 454 426 445 424 447 422 448 421 450 419 1296 443 455 425 446 423 447 422 449 420 450 419 452 417 454 426 1290 449 448 421 1294 445 453 416 455 425 1291 448 1294 445 1297 453 418 451 447 422 448 421 423 446 1296 443 1300 450 448 421 422 447 424 445 425 444 427 453 418 451 1292 447 450 419 1297 442 1300 450 1292 447 451 418 1297 453 74912 3466 1722 447 424 445 1297 453 418 451 420 449 421 448 423 446 425 444 427 453 418 451 420 449 421 448 423 446 424 445 1297 453 419 450 420 449 422 447 424 445 425 444 427 453 418 451 1291 448 423 446 1296 443 428 452 419 450 1292 447 1295 444 1298 452 420 449 421 448 423 446 425 444 1298 452 1290 449 422 447 424 445 425 444 427 453 418 451 420 449 1293 446 425 444 1298 452 1290 449 1294 445 425 444 1298 452 -# +# +name: Next +type: parsed +protocol: Kaseikyo +address: AC 02 20 00 +command: 31 00 00 00 +# name: Prev type: parsed protocol: Kaseikyo address: AC 02 20 00 command: 21 00 00 00 -# +# name: Play type: parsed protocol: Kaseikyo address: AC 02 20 00 command: 61 00 00 00 -# +# +name: Play +type: parsed +protocol: RC5 +address: 14 00 00 00 +command: 35 00 00 00 +# +name: Prev +type: parsed +protocol: RC5 +address: 14 00 00 00 +command: 21 00 00 00 +# +name: Next +type: parsed +protocol: RC5 +address: 14 00 00 00 +command: 20 00 00 00 +# name: Prev type: parsed protocol: NEC address: 00 00 00 00 command: 4D 00 00 00 -# +# +name: Next +type: parsed +protocol: NEC +address: 00 00 00 00 +command: 54 00 00 00 +# name: Play type: parsed protocol: NEC address: 40 00 00 00 command: 59 00 00 00 -# +# name: Pause type: parsed protocol: NEC address: 40 00 00 00 command: 18 00 00 00 -# +# +name: Prev +type: parsed +protocol: NEC +address: 40 00 00 00 +command: 58 00 00 00 +# +name: Next +type: parsed +protocol: NEC +address: 40 00 00 00 +command: 5B 00 00 00 +# +name: Play +type: parsed +protocol: SIRC20 +address: 3A 07 00 00 +command: 32 00 00 00 +# +name: Pause +type: parsed +protocol: SIRC20 +address: 3A 07 00 00 +command: 39 00 00 00 +# +name: Play +type: parsed +protocol: SIRC20 +address: 10 01 00 00 +command: 3A 00 00 00 +# +name: Pause +type: parsed +protocol: SIRC20 +address: 10 01 00 00 +command: 3A 00 00 00 +# name: Play type: parsed protocol: RC5X address: 0A 00 00 00 command: 31 00 00 00 -# +# name: Pause type: parsed protocol: RC5X address: 0A 00 00 00 command: 0F 00 00 00 -# +# name: Play type: parsed protocol: NEC address: 78 00 00 00 command: 02 00 00 00 -# +# name: Play type: parsed protocol: NECext address: 7F 01 00 00 command: 68 97 00 00 -# +# name: Pause type: parsed protocol: NECext address: 7F 01 00 00 command: 67 98 00 00 +# +# CD Players +# +name: Play +type: parsed +protocol: NEC42 +address: 6E 00 00 00 +command: 40 00 00 00 +# +name: Pause +type: parsed +protocol: NEC42 +address: 6E 00 00 00 +command: 44 00 00 00 +# +name: Prev +type: parsed +protocol: Kaseikyo +address: 51 54 32 01 +command: 47 00 00 00 +# +name: Next +type: parsed +protocol: Kaseikyo +address: 51 54 32 01 +command: 46 00 00 00 +# +name: Play +type: parsed +protocol: Samsung32 +address: 81 00 00 00 +command: 01 00 00 00 +# +name: Pause +type: parsed +protocol: Samsung32 +address: 81 00 00 00 +command: 01 00 00 00 +# +name: Play +type: raw +frequency: 38000 +duty_cycle: 0.33 +data: 8546 4227 563 511 563 1558 566 511 563 483 566 508 567 1558 566 509 566 1558 566 1586 564 483 566 1561 588 1558 566 1560 564 536 539 1558 566 535 539 1558 566 1586 564 1557 567 486 589 1560 564 511 563 510 539 508 567 485 589 484 565 508 567 1559 565 509 566 1560 564 1560 590 1585 539 25430 8575 4251 538 485 590 1557 567 486 588 511 538 536 539 1557 567 509 566 1558 566 1560 590 483 566 1560 589 1559 565 1562 562 536 539 1560 564 509 566 1558 566 1564 586 1586 538 484 590 1559 565 487 588 482 567 509 566 511 563 483 566 508 567 1558 566 509 566 1560 564 1559 591 1586 538 +# +name: Pause +type: raw +frequency: 38000 +duty_cycle: 0.33 +data: 8571 4226 564 509 540 1587 563 510 539 510 565 510 564 1558 566 510 565 1584 540 1585 539 535 540 1587 537 1586 564 1585 539 510 564 1584 540 511 563 482 567 535 539 485 590 1584 540 1585 539 509 566 510 564 510 539 1586 564 1585 539 1585 539 536 539 510 564 1585 539 1557 567 1558 592 25434 8571 4199 591 510 539 1586 564 509 540 535 540 485 590 1585 539 484 591 1561 563 1584 540 507 568 1585 539 1586 564 1585 539 486 589 1585 539 484 591 425 624 535 540 486 589 1585 539 1585 539 511 564 511 563 486 563 1586 564 1558 566 1558 566 508 567 486 589 1560 564 1558 566 1561 589 +# +name: Pause +type: parsed +protocol: NEC +address: 4D 00 00 00 +command: 0F 00 00 00 +# +name: Next +type: parsed +protocol: NEC +address: 4D 00 00 00 +command: 10 00 00 00 +# +name: Play +type: parsed +protocol: SIRC15 +address: 64 00 00 00 +command: 32 00 00 00 +# +name: Pause +type: parsed +protocol: SIRC15 +address: 64 00 00 00 +command: 39 00 00 00 +# +name: Play +type: parsed +protocol: SIRC +address: 0F 00 00 00 +command: 2A 00 00 00 +# +name: Pause +type: parsed +protocol: SIRC +address: 0F 00 00 00 +command: 29 00 00 00 +# +name: Play +type: parsed +protocol: NECext +address: 86 61 00 00 +command: 08 F7 00 00 +# +name: Pause +type: parsed +protocol: NECext +address: 86 61 00 00 +command: 05 FA 00 00 +# +name: Play +type: parsed +protocol: NECext +address: 00 EF 00 00 +command: 03 FC 00 00 +# +name: Pause +type: parsed +protocol: NECext +address: 00 EF 00 00 +command: 03 FC 00 00 +# +name: Next +type: parsed +protocol: NECext +address: 00 EF 00 00 +command: 02 FD 00 00 +# +name: Prev +type: parsed +protocol: NECext +address: 00 EF 00 00 +command: 01 FE 00 00 +# +# SoundBars +# +name: Play +type: parsed +protocol: NECext +address: 86 FF 00 00 +command: 2A D5 00 00 +# +name: Prev +type: parsed +protocol: NECext +address: 86 FF 00 00 +command: 13 EC 00 00 +# +name: Next +type: parsed +protocol: NECext +address: 86 FF 00 00 +command: 14 EB 00 00 +# +name: Next +type: parsed +protocol: NECext +address: BA A0 00 00 +command: 5A A5 00 00 +# +name: Prev +type: parsed +protocol: NECext +address: BA A0 00 00 +command: 59 A6 00 00 +# +name: Pause +type: parsed +protocol: NECext +address: BA A0 00 00 +command: 56 A9 00 00 +# +name: Play +type: parsed +protocol: NECext +address: BA 4B 00 00 +command: 55 AA 00 00 +# +name: Play +type: parsed +protocol: NEC +address: 35 00 00 00 +command: 46 00 00 00 +# +name: Play +type: parsed +protocol: NECext +address: 83 22 00 00 +command: 09 F6 00 00 +# +name: Pause +type: parsed +protocol: NECext +address: BA 4B 00 00 +command: 55 AA 00 00 +# +name: Pause +type: parsed +protocol: NEC +address: 35 00 00 00 +command: 46 00 00 00 +# +name: Pause +type: parsed +protocol: NECext +address: 83 22 00 00 +command: 09 F6 00 00 +# +name: Prev +type: parsed +protocol: NECext +address: 83 22 00 00 +command: 07 F8 00 00 +# +name: Next +type: parsed +protocol: NECext +address: 83 22 00 00 +command: 06 F9 00 00 +# +name: Play +type: parsed +protocol: NECext +address: 00 FB 00 00 +command: 1C E3 00 00 +# +name: Play +type: parsed +protocol: NEC +address: 00 00 00 00 +command: 1B 00 00 00 +# +name: Play +type: parsed +protocol: NEC +address: 00 00 00 00 +command: 06 00 00 00 +# +name: Pause +type: parsed +protocol: NECext +address: 00 FB 00 00 +command: 1C E3 00 00 +# +name: Pause +type: parsed +protocol: NEC +address: 00 00 00 00 +command: 1B 00 00 00 +# +name: Pause +type: parsed +protocol: NEC +address: 00 00 00 00 +command: 06 00 00 00 +# +name: Play +type: parsed +protocol: Samsung32 +address: 2C 00 00 00 +command: 4F 00 00 00 +# +name: Prev +type: parsed +protocol: NEC +address: 20 00 00 00 +command: 1A 00 00 00 +# +name: Next +type: parsed +protocol: NEC +address: 20 00 00 00 +command: 4F 00 00 00 +# +name: Pause +type: parsed +protocol: NECext +address: C8 91 00 00 +command: 21 DE 00 00 +# +name: Play +type: raw +frequency: 38000 +duty_cycle: 0.33 +data: 4583 4441 575 454 550 455 549 457 548 456 549 1461 550 1460 549 456 549 457 549 1461 548 1462 549 1461 549 1461 548 457 548 457 549 457 547 457 549 4462 548 458 548 457 548 457 548 457 548 457 548 1462 548 457 548 1461 549 457 548 457 548 457 548 1462 548 1461 549 457 548 1461 549 457 548 1461 549 1461 548 1462 547 458 547 55448 4580 4465 550 456 549 456 549 456 550 456 549 1461 549 1460 549 457 549 456 549 1461 549 1461 549 1461 548 1461 549 457 548 457 549 457 548 457 548 4462 549 457 548 457 548 458 548 457 548 457 548 1462 549 457 547 1462 549 457 548 457 548 457 548 1462 548 1462 549 457 548 1462 548 457 548 1462 548 1461 549 1462 548 457 548 +# +name: Pause +type: raw +frequency: 38000 +duty_cycle: 0.33 +data: 4583 4441 575 454 550 455 549 457 548 456 549 1461 550 1460 549 456 549 457 549 1461 548 1462 549 1461 549 1461 548 457 548 457 549 457 547 457 549 4462 548 458 548 457 548 457 548 457 548 457 548 1462 548 457 548 1461 549 457 548 457 548 457 548 1462 548 1461 549 457 548 1461 549 457 548 1461 549 1461 548 1462 547 458 547 55448 4580 4465 550 456 549 456 549 456 550 456 549 1461 549 1460 549 457 549 456 549 1461 549 1461 549 1461 548 1461 549 457 548 457 549 457 548 457 548 4462 549 457 548 457 548 458 548 457 548 457 548 1462 549 457 547 1462 549 457 548 457 548 457 548 1462 548 1462 549 457 548 1462 548 457 548 1462 548 1461 549 1462 548 457 548 +# +name: Next +type: raw +frequency: 38000 +duty_cycle: 0.33 +data: 4582 4465 551 454 550 455 550 455 549 456 549 1460 550 1460 549 457 548 456 549 1461 549 1461 548 1461 549 1460 549 457 549 456 548 457 548 457 548 4461 549 456 548 457 548 457 548 457 548 457 548 457 548 1462 548 1461 547 457 549 457 548 456 549 1460 549 1461 547 1461 549 457 547 457 548 1461 549 1461 548 1461 548 457 548 55436 4578 4464 549 455 549 456 549 455 549 456 550 1460 549 1460 549 456 550 455 550 1460 550 1460 549 1460 550 1460 549 456 549 457 548 457 548 457 549 4461 548 457 548 457 548 457 548 457 547 457 549 457 547 1462 548 1461 549 457 548 457 548 457 548 1461 548 1461 548 1462 548 457 548 457 549 1461 549 1461 548 1461 548 457 548 +# +name: Prev +type: raw +frequency: 38000 +duty_cycle: 0.33 +data: 4554 4466 540 469 547 490 515 495 521 490 494 1478 522 1477 544 466 539 471 513 1512 488 1484 516 1483 570 1429 540 497 519 465 540 470 546 491 493 4490 548 462 543 467 549 488 517 493 491 1481 519 1480 541 495 489 1510 522 462 543 494 521 489 495 1476 545 466 539 471 513 1485 547 464 520 1505 495 1477 513 1487 545 465 540 +# +name: Next +type: raw +frequency: 38000 +duty_cycle: 0.33 +data: 4555 4464 542 468 548 462 543 467 549 488 496 1477 523 1476 545 465 551 459 525 1475 515 1484 516 1483 517 1482 550 486 519 465 551 459 546 464 520 4490 547 488 517 467 549 462 543 467 548 462 543 467 517 1482 518 1481 540 496 520 464 541 469 515 1484 516 1483 517 1482 550 460 545 465 519 1480 520 1479 521 1478 543 493 522 +# +name: Play +type: raw +frequency: 38000 +duty_cycle: 0.33 +data: 4549 4471 546 464 541 469 547 463 542 469 515 1484 516 1483 549 461 544 466 518 1481 519 1480 520 1479 521 1477 544 466 550 461 544 467 549 461 523 4486 541 469 546 464 541 469 547 464 541 469 515 1483 549 462 522 1477 544 465 540 471 545 465 572 1428 520 1479 542 468 569 1430 549 462 522 1476 514 1486 514 1485 547 463 542 +# +name: Play +type: raw +frequency: 38000 +duty_cycle: 0.33 +data: 4552 4464 586 420 584 420 584 420 612 392 529 1478 531 1478 531 476 553 451 553 1455 554 1479 528 1480 528 1481 527 478 526 478 526 478 526 478 526 4497 526 478 526 478 526 478 526 478 526 478 526 1483 526 478 526 1483 526 478 526 478 526 478 526 1483 526 1483 526 478 526 1483 526 479 525 1483 526 1483 526 1483 526 478 526 +# +name: Play +type: raw +frequency: 38000 +duty_cycle: 0.33 +data: 4548 4471 540 471 541 468 544 467 545 465 516 1482 512 1488 537 473 539 472 519 1479 514 1484 520 1479 515 1485 539 470 542 468 544 466 546 464 517 4493 538 472 540 470 542 468 544 466 546 464 517 1482 543 468 513 544 471 469 574 436 514 1485 519 1480 545 465 547 1452 573 438 543 1456 548 1451 543 1456 569 442 570 +# +name: Pause +type: raw +frequency: 38000 +duty_cycle: 0.33 +data: 4549 4471 546 464 541 469 547 463 542 469 515 1484 516 1483 549 461 544 466 518 1481 519 1480 520 1479 521 1477 544 466 550 461 544 467 549 461 523 4486 541 469 546 464 541 469 547 464 541 469 515 1483 549 462 522 1477 544 465 540 471 545 465 572 1428 520 1479 542 468 569 1430 549 462 522 1476 514 1486 514 1485 547 463 542 +# +name: Pause +type: raw +frequency: 38000 +duty_cycle: 0.33 +data: 4552 4464 586 420 584 420 584 420 612 392 529 1478 531 1478 531 476 553 451 553 1455 554 1479 528 1480 528 1481 527 478 526 478 526 478 526 478 526 4497 526 478 526 478 526 478 526 478 526 478 526 1483 526 478 526 1483 526 478 526 478 526 478 526 1483 526 1483 526 478 526 1483 526 479 525 1483 526 1483 526 1483 526 478 526 +# +name: Pause +type: raw +frequency: 38000 +duty_cycle: 0.33 +data: 4548 4471 540 471 541 468 544 467 545 465 516 1482 512 1488 537 473 539 472 519 1479 514 1484 520 1479 515 1485 539 470 542 468 544 466 546 464 517 4493 538 472 540 470 542 468 544 466 546 464 517 1482 543 468 513 544 471 469 574 436 514 1485 519 1480 545 465 547 1452 573 438 543 1456 548 1451 543 1456 569 442 570 +# +name: Play +type: parsed +protocol: SIRC20 +address: 10 01 00 00 +command: 32 00 00 00 +# +name: Pause +type: parsed +protocol: SIRC20 +address: 10 01 00 00 +command: 39 00 00 00 +# +name: Play +type: parsed +protocol: NEC +address: 00 00 00 00 +command: 8E 00 00 00 +# +name: Pause +type: parsed +protocol: NEC +address: 00 00 00 00 +command: 8E 00 00 00 +# +name: Next +type: parsed +protocol: NEC +address: 00 00 00 00 +command: 8B 00 00 00 +# +name: Prev +type: parsed +protocol: NEC +address: 00 00 00 00 +command: 8A 00 00 00 +# +name: Play +type: parsed +protocol: NEC +address: 20 00 00 00 +command: 1B 00 00 00 +# +name: Pause +type: parsed +protocol: NEC +address: 20 00 00 00 +command: 1B 00 00 00 +# +# Speakers +# +name: Play +type: raw +frequency: 38000 +duty_cycle: 0.33 +data: 1041 1461 540 457 543 453 537 459 541 1459 541 1459 542 1459 541 1459 542 1458 542 1458 543 1458 542 1458 542 453 537 459 541 455 545 451 539 450 540 50518 1041 1461 540 457 543 452 538 459 541 1459 541 1459 542 1459 541 1458 543 1458 542 1458 542 1458 542 1457 544 453 537 459 541 455 545 451 539 449 541 50534 1036 1467 544 452 538 458 542 454 546 1455 545 1454 546 1454 536 1464 537 1464 536 1463 537 1463 537 1463 537 459 541 454 546 450 540 457 543 445 545 +# +name: Pause +type: raw +frequency: 38000 +duty_cycle: 0.33 +data: 1041 1461 540 457 543 453 537 459 541 1459 541 1459 542 1459 541 1459 542 1458 542 1458 543 1458 542 1458 542 453 537 459 541 455 545 451 539 450 540 50518 1041 1461 540 457 543 452 538 459 541 1459 541 1459 542 1459 541 1458 543 1458 542 1458 542 1458 542 1457 544 453 537 459 541 455 545 451 539 449 541 50534 1036 1467 544 452 538 458 542 454 546 1455 545 1454 546 1454 536 1464 537 1464 536 1463 537 1463 537 1463 537 459 541 454 546 450 540 457 543 445 545 +# +name: Next +type: raw +frequency: 38000 +duty_cycle: 0.33 +data: 1044 1460 540 456 544 1457 543 1457 543 453 536 1465 545 450 539 457 543 1458 542 1458 542 454 546 451 539 1462 538 458 542 1459 541 1460 540 448 542 50525 1042 1462 538 458 542 1458 542 1459 541 455 545 1456 544 452 537 459 541 1460 540 1460 540 456 544 452 537 1464 536 460 540 1461 539 1461 539 449 540 50542 1046 1458 542 480 520 1455 545 1455 545 477 512 1463 547 474 515 481 519 1456 544 1457 543 478 522 475 514 1460 540 482 518 1457 543 1458 542 445 544 +# +name: Prev +type: raw +frequency: 38000 +duty_cycle: 0.33 +data: 1046 1457 543 1458 542 454 546 450 539 1461 539 456 544 1458 542 1458 542 454 546 451 539 1461 539 1462 538 458 542 1459 541 454 546 451 539 1454 546 50538 1043 1461 539 1461 539 456 544 453 547 1454 546 449 541 1461 539 1462 538 457 543 453 547 1455 545 1455 545 451 539 1462 538 458 542 454 546 1447 543 50526 1044 1459 541 1459 541 455 545 451 539 1463 537 458 542 1459 541 1460 540 455 545 452 538 1463 537 1464 536 460 540 1461 539 456 544 453 536 1456 544 +# +name: Play +type: raw +frequency: 38000 +duty_cycle: 0.33 +data: 1013 1488 512 486 514 486 514 1485 515 484 516 484 516 1483 517 1482 518 1481 509 1490 510 1488 512 488 512 1487 513 1485 515 484 516 483 517 481 519 50939 1010 1489 511 488 512 488 512 1486 514 486 514 486 514 1485 515 1483 517 1482 518 1481 509 1489 511 489 511 1487 513 1485 515 484 516 484 516 482 518 50958 1013 1488 512 487 513 487 513 1485 515 485 515 485 515 1484 516 1483 517 1482 518 1481 509 1490 510 490 572 1426 512 1487 513 486 514 486 514 485 566 50908 1011 1490 510 489 511 489 511 1487 513 486 514 487 513 1485 515 1484 516 1483 517 1482 518 1480 510 491 571 1427 511 1488 512 488 512 487 513 486 565 50905 1013 1488 512 488 512 488 512 1486 514 486 514 486 514 1485 515 1484 516 1483 517 1481 509 1489 511 489 511 1488 512 1486 514 485 515 485 515 484 516 +# +name: Pause +type: raw +frequency: 38000 +duty_cycle: 0.33 +data: 1013 1488 512 486 514 486 514 1485 515 484 516 484 516 1483 517 1482 518 1481 509 1490 510 1488 512 488 512 1487 513 1485 515 484 516 483 517 481 519 50939 1010 1489 511 488 512 488 512 1486 514 486 514 486 514 1485 515 1483 517 1482 518 1481 509 1489 511 489 511 1487 513 1485 515 484 516 484 516 482 518 50958 1013 1488 512 487 513 487 513 1485 515 485 515 485 515 1484 516 1483 517 1482 518 1481 509 1490 510 490 572 1426 512 1487 513 486 514 486 514 485 566 50908 1011 1490 510 489 511 489 511 1487 513 486 514 487 513 1485 515 1484 516 1483 517 1482 518 1480 510 491 571 1427 511 1488 512 488 512 487 513 486 565 50905 1013 1488 512 488 512 488 512 1486 514 486 514 486 514 1485 515 1484 516 1483 517 1481 509 1489 511 489 511 1488 512 1486 514 485 515 485 515 484 516 +# +name: Next +type: parsed +protocol: NEC +address: 00 00 00 00 +command: 19 00 00 00 +# +name: Play +type: parsed +protocol: NEC +address: 77 00 00 00 +command: F8 00 00 00 +# +name: Play +type: parsed +protocol: NECext +address: 10 E7 00 00 +command: 14 EB 00 00 +# +name: Pause +type: parsed +protocol: NEC +address: 77 00 00 00 +command: F8 00 00 00 +# +name: Pause +type: parsed +protocol: NECext +address: 10 E7 00 00 +command: 14 EB 00 00 +# +name: Prev +type: parsed +protocol: NECext +address: 10 E7 00 00 +command: 1E E1 00 00 +# +name: Play +type: parsed +protocol: NECext +address: 3F 5C 00 00 +command: 07 F8 00 00 +# +name: Play +type: parsed +protocol: NEC +address: 00 00 00 00 +command: 12 00 00 00 +# +name: Pause +type: parsed +protocol: NECext +address: 3F 5C 00 00 +command: 07 F8 00 00 +# +name: Pause +type: parsed +protocol: NEC +address: 00 00 00 00 +command: 12 00 00 00 +# +name: Prev +type: parsed +protocol: NEC +address: 00 00 00 00 +command: 10 00 00 00 +# +name: Next +type: parsed +protocol: NEC +address: 00 00 00 00 +command: 13 00 00 00 +# +name: Play +type: parsed +protocol: NEC +address: 00 00 00 00 +command: 0A 00 00 00 +# +name: Pause +type: parsed +protocol: NEC +address: 00 00 00 00 +command: 0A 00 00 00 +# +name: Next +type: parsed +protocol: NEC +address: 00 00 00 00 +command: 0C 00 00 00 +# +name: Prev +type: parsed +protocol: NEC +address: 00 00 00 00 +command: 0B 00 00 00 +# +name: Play +type: parsed +protocol: NECext +address: 40 AF 00 00 +command: 02 FD 00 00 +# +name: Pause +type: parsed +protocol: NECext +address: 40 AF 00 00 +command: 02 FD 00 00 +# +name: Prev +type: parsed +protocol: NECext +address: 40 AF 00 00 +command: 12 ED 00 00 +# +name: Next +type: parsed +protocol: NECext +address: 40 AF 00 00 +command: 05 FA 00 00 +# +name: Play +type: parsed +protocol: NECext +address: 02 BD 00 00 +command: 0D F2 00 00 +# +name: Next +type: parsed +protocol: NECext +address: 02 BD 00 00 +command: 27 D8 00 00 +# +name: Prev +type: parsed +protocol: NECext +address: 02 BD 00 00 +command: 25 DA 00 00 +# +name: Play +type: parsed +protocol: NEC +address: 80 00 00 00 +command: 18 00 00 00 +# +name: Pause +type: parsed +protocol: NEC +address: 80 00 00 00 +command: 18 00 00 00 +# +name: Prev +type: parsed +protocol: NEC +address: 80 00 00 00 +command: 4B 00 00 00 +# +name: Next +type: parsed +protocol: NEC +address: 80 00 00 00 +command: 4A 00 00 00 +# +name: Play +type: parsed +protocol: NEC +address: 80 00 00 00 +command: 21 00 00 00 +# +name: Play +type: parsed +protocol: NEC +address: 02 00 00 00 +command: 1E 00 00 00 +# +name: Pause +type: parsed +protocol: NEC +address: 80 00 00 00 +command: 21 00 00 00 +# +name: Pause +type: parsed +protocol: NEC +address: 02 00 00 00 +command: 1E 00 00 00 +# +name: Next +type: raw +frequency: 38000 +duty_cycle: 0.33 +data: 3303 1908 408 1179 410 1177 412 442 409 444 407 446 405 448 414 1173 405 448 414 1173 416 1172 406 447 415 439 412 1175 414 440 411 1175 414 440 411 1175 414 440 411 442 409 444 407 447 415 438 413 440 411 442 409 444 407 446 405 1182 407 447 415 438 413 440 411 442 409 444 407 1180 409 1178 411 443 408 445 406 1180 409 445 406 447 415 438 413 440 411 442 409 444 407 1180 409 444 407 446 405 448 414 440 411 41789 3301 3346 362 42926 3307 3341 357 +# +name: Prev +type: raw +frequency: 38000 +duty_cycle: 0.33 +data: 3301 1910 406 1155 434 1180 409 419 432 421 441 439 412 441 410 1178 411 416 435 1152 437 1177 412 442 409 417 434 1180 409 418 433 1180 409 445 406 1155 434 419 432 447 415 413 438 442 409 444 407 419 432 448 414 439 412 442 409 1177 412 442 409 444 407 420 431 448 414 413 438 1176 413 1174 415 413 438 1175 414 1173 405 422 440 440 411 416 435 418 433 447 415 439 412 441 410 1177 412 415 436 417 434 446 405 41164 3301 3321 387 42935 3307 3316 381 42941 3311 3312 385 +# +name: Play +type: raw +frequency: 38000 +duty_cycle: 0.33 +data: 9175 4433 644 1605 645 442 669 466 646 445 666 438 673 466 645 440 671 466 673 410 700 365 720 465 675 367 742 367 744 438 645 1604 675 1574 674 1549 702 1575 673 1576 646 1604 675 1574 676 1574 675 1576 644 1604 645 1606 672 1576 645 466 645 466 645 465 646 1575 675 1605 645 466 645 467 644 467 644 1605 644 1605 645 1606 644 467 644 467 644 1606 643 1578 672 1607 643 +# +name: Next +type: raw +frequency: 38000 +duty_cycle: 0.33 +data: 9146 4435 642 1577 673 449 662 454 658 451 661 469 642 468 644 469 642 453 659 470 642 470 642 469 643 469 642 469 642 469 642 1608 642 1606 643 1607 642 1607 642 1607 642 1577 673 1607 643 1607 642 1607 642 1607 642 1606 643 1576 674 1606 643 468 643 439 672 1607 642 1607 642 448 663 469 642 439 672 469 642 1577 672 1607 642 468 643 469 642 1607 642 1608 641 1608 640 +# +name: Prev +type: raw +frequency: 38000 +duty_cycle: 0.33 +data: 9144 4405 671 1607 642 469 642 469 642 469 642 470 641 365 747 469 641 443 669 469 642 468 643 446 665 469 642 469 642 470 642 1580 669 1607 643 1607 642 1608 641 1578 672 1580 670 1608 641 1608 641 1609 590 1660 590 1635 615 1660 590 1660 590 1632 618 1633 617 521 590 1660 590 521 590 521 618 493 590 521 590 520 591 519 592 1657 592 519 592 1658 617 1633 616 1633 615 23844 9114 4461 615 +# +name: Play +type: parsed +protocol: SIRC +address: 10 00 00 00 +command: 0C 00 00 00 +# +name: Play +type: parsed +protocol: NEC +address: FD 00 00 00 +command: BD 00 00 00 +# +name: Play +type: parsed +protocol: NECext +address: 2D D3 00 00 +command: 00 FF 00 00 +# +name: Pause +type: parsed +protocol: NEC +address: FD 00 00 00 +command: BD 00 00 00 +# +name: Pause +type: parsed +protocol: NECext +address: 2D D3 00 00 +command: 00 FF 00 00 +# +name: Prev +type: parsed +protocol: NECext +address: 2D D3 00 00 +command: 07 F8 00 00 +# +name: Next +type: parsed +protocol: NECext +address: 2D D3 00 00 +command: 06 F9 00 00 From a76c189ca52871aa4fa9c94882202e19f008d202 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=82=E3=81=8F?= Date: Tue, 30 May 2023 20:47:28 +0900 Subject: [PATCH 25/52] [FL-3335] Dolphin: new animation (#2713) --- .../external/L1_Kaiju_128x64/frame_0.png | Bin 0 -> 1312 bytes .../external/L1_Kaiju_128x64/frame_1.png | Bin 0 -> 1302 bytes .../external/L1_Kaiju_128x64/frame_10.png | Bin 0 -> 1332 bytes .../external/L1_Kaiju_128x64/frame_11.png | Bin 0 -> 1228 bytes .../external/L1_Kaiju_128x64/frame_12.png | Bin 0 -> 1152 bytes .../external/L1_Kaiju_128x64/frame_13.png | Bin 0 -> 1152 bytes .../external/L1_Kaiju_128x64/frame_14.png | Bin 0 -> 1162 bytes .../external/L1_Kaiju_128x64/frame_15.png | Bin 0 -> 1209 bytes .../external/L1_Kaiju_128x64/frame_16.png | Bin 0 -> 1158 bytes .../external/L1_Kaiju_128x64/frame_17.png | Bin 0 -> 1161 bytes .../external/L1_Kaiju_128x64/frame_18.png | Bin 0 -> 828 bytes .../external/L1_Kaiju_128x64/frame_19.png | Bin 0 -> 817 bytes .../external/L1_Kaiju_128x64/frame_2.png | Bin 0 -> 1288 bytes .../external/L1_Kaiju_128x64/frame_20.png | Bin 0 -> 1222 bytes .../external/L1_Kaiju_128x64/frame_21.png | Bin 0 -> 1494 bytes .../external/L1_Kaiju_128x64/frame_22.png | Bin 0 -> 1685 bytes .../external/L1_Kaiju_128x64/frame_23.png | Bin 0 -> 1680 bytes .../external/L1_Kaiju_128x64/frame_24.png | Bin 0 -> 1690 bytes .../external/L1_Kaiju_128x64/frame_25.png | Bin 0 -> 1658 bytes .../external/L1_Kaiju_128x64/frame_26.png | Bin 0 -> 1716 bytes .../external/L1_Kaiju_128x64/frame_27.png | Bin 0 -> 1741 bytes .../external/L1_Kaiju_128x64/frame_28.png | Bin 0 -> 1686 bytes .../external/L1_Kaiju_128x64/frame_29.png | Bin 0 -> 1626 bytes .../external/L1_Kaiju_128x64/frame_3.png | Bin 0 -> 1305 bytes .../external/L1_Kaiju_128x64/frame_30.png | Bin 0 -> 1677 bytes .../external/L1_Kaiju_128x64/frame_31.png | Bin 0 -> 1639 bytes .../external/L1_Kaiju_128x64/frame_32.png | Bin 0 -> 1618 bytes .../external/L1_Kaiju_128x64/frame_33.png | Bin 0 -> 1595 bytes .../external/L1_Kaiju_128x64/frame_34.png | Bin 0 -> 1591 bytes .../external/L1_Kaiju_128x64/frame_35.png | Bin 0 -> 1560 bytes .../external/L1_Kaiju_128x64/frame_36.png | Bin 0 -> 1592 bytes .../external/L1_Kaiju_128x64/frame_37.png | Bin 0 -> 1494 bytes .../external/L1_Kaiju_128x64/frame_38.png | Bin 0 -> 1489 bytes .../external/L1_Kaiju_128x64/frame_39.png | Bin 0 -> 1438 bytes .../external/L1_Kaiju_128x64/frame_4.png | Bin 0 -> 1284 bytes .../external/L1_Kaiju_128x64/frame_40.png | Bin 0 -> 1438 bytes .../external/L1_Kaiju_128x64/frame_41.png | Bin 0 -> 1412 bytes .../external/L1_Kaiju_128x64/frame_42.png | Bin 0 -> 1425 bytes .../external/L1_Kaiju_128x64/frame_43.png | Bin 0 -> 1397 bytes .../external/L1_Kaiju_128x64/frame_44.png | Bin 0 -> 1217 bytes .../external/L1_Kaiju_128x64/frame_45.png | Bin 0 -> 1177 bytes .../external/L1_Kaiju_128x64/frame_46.png | Bin 0 -> 1300 bytes .../external/L1_Kaiju_128x64/frame_47.png | Bin 0 -> 1268 bytes .../external/L1_Kaiju_128x64/frame_5.png | Bin 0 -> 1318 bytes .../external/L1_Kaiju_128x64/frame_6.png | Bin 0 -> 1312 bytes .../external/L1_Kaiju_128x64/frame_7.png | Bin 0 -> 1301 bytes .../external/L1_Kaiju_128x64/frame_8.png | Bin 0 -> 1308 bytes .../external/L1_Kaiju_128x64/frame_9.png | Bin 0 -> 1336 bytes .../dolphin/external/L1_Kaiju_128x64/meta.txt | 50 ++++++++++++++++++ assets/dolphin/external/manifest.txt | 7 +++ 50 files changed, 57 insertions(+) create mode 100644 assets/dolphin/external/L1_Kaiju_128x64/frame_0.png create mode 100644 assets/dolphin/external/L1_Kaiju_128x64/frame_1.png create mode 100644 assets/dolphin/external/L1_Kaiju_128x64/frame_10.png create mode 100644 assets/dolphin/external/L1_Kaiju_128x64/frame_11.png create mode 100644 assets/dolphin/external/L1_Kaiju_128x64/frame_12.png create mode 100644 assets/dolphin/external/L1_Kaiju_128x64/frame_13.png create mode 100644 assets/dolphin/external/L1_Kaiju_128x64/frame_14.png create mode 100644 assets/dolphin/external/L1_Kaiju_128x64/frame_15.png create mode 100644 assets/dolphin/external/L1_Kaiju_128x64/frame_16.png create mode 100644 assets/dolphin/external/L1_Kaiju_128x64/frame_17.png create mode 100644 assets/dolphin/external/L1_Kaiju_128x64/frame_18.png create mode 100644 assets/dolphin/external/L1_Kaiju_128x64/frame_19.png create mode 100644 assets/dolphin/external/L1_Kaiju_128x64/frame_2.png create mode 100644 assets/dolphin/external/L1_Kaiju_128x64/frame_20.png create mode 100644 assets/dolphin/external/L1_Kaiju_128x64/frame_21.png create mode 100644 assets/dolphin/external/L1_Kaiju_128x64/frame_22.png create mode 100644 assets/dolphin/external/L1_Kaiju_128x64/frame_23.png create mode 100644 assets/dolphin/external/L1_Kaiju_128x64/frame_24.png create mode 100644 assets/dolphin/external/L1_Kaiju_128x64/frame_25.png create mode 100644 assets/dolphin/external/L1_Kaiju_128x64/frame_26.png create mode 100644 assets/dolphin/external/L1_Kaiju_128x64/frame_27.png create mode 100644 assets/dolphin/external/L1_Kaiju_128x64/frame_28.png create mode 100644 assets/dolphin/external/L1_Kaiju_128x64/frame_29.png create mode 100644 assets/dolphin/external/L1_Kaiju_128x64/frame_3.png create mode 100644 assets/dolphin/external/L1_Kaiju_128x64/frame_30.png create mode 100644 assets/dolphin/external/L1_Kaiju_128x64/frame_31.png create mode 100644 assets/dolphin/external/L1_Kaiju_128x64/frame_32.png create mode 100644 assets/dolphin/external/L1_Kaiju_128x64/frame_33.png create mode 100644 assets/dolphin/external/L1_Kaiju_128x64/frame_34.png create mode 100644 assets/dolphin/external/L1_Kaiju_128x64/frame_35.png create mode 100644 assets/dolphin/external/L1_Kaiju_128x64/frame_36.png create mode 100644 assets/dolphin/external/L1_Kaiju_128x64/frame_37.png create mode 100644 assets/dolphin/external/L1_Kaiju_128x64/frame_38.png create mode 100644 assets/dolphin/external/L1_Kaiju_128x64/frame_39.png create mode 100644 assets/dolphin/external/L1_Kaiju_128x64/frame_4.png create mode 100644 assets/dolphin/external/L1_Kaiju_128x64/frame_40.png create mode 100644 assets/dolphin/external/L1_Kaiju_128x64/frame_41.png create mode 100644 assets/dolphin/external/L1_Kaiju_128x64/frame_42.png create mode 100644 assets/dolphin/external/L1_Kaiju_128x64/frame_43.png create mode 100644 assets/dolphin/external/L1_Kaiju_128x64/frame_44.png create mode 100644 assets/dolphin/external/L1_Kaiju_128x64/frame_45.png create mode 100644 assets/dolphin/external/L1_Kaiju_128x64/frame_46.png create mode 100644 assets/dolphin/external/L1_Kaiju_128x64/frame_47.png create mode 100644 assets/dolphin/external/L1_Kaiju_128x64/frame_5.png create mode 100644 assets/dolphin/external/L1_Kaiju_128x64/frame_6.png create mode 100644 assets/dolphin/external/L1_Kaiju_128x64/frame_7.png create mode 100644 assets/dolphin/external/L1_Kaiju_128x64/frame_8.png create mode 100644 assets/dolphin/external/L1_Kaiju_128x64/frame_9.png create mode 100644 assets/dolphin/external/L1_Kaiju_128x64/meta.txt diff --git a/assets/dolphin/external/L1_Kaiju_128x64/frame_0.png b/assets/dolphin/external/L1_Kaiju_128x64/frame_0.png new file mode 100644 index 0000000000000000000000000000000000000000..8b8dc80bce09adfd26988d9021687d77b536961a GIT binary patch literal 1312 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 literal 0 HcmV?d00001 diff --git a/assets/dolphin/external/L1_Kaiju_128x64/frame_16.png b/assets/dolphin/external/L1_Kaiju_128x64/frame_16.png new file mode 100644 index 0000000000000000000000000000000000000000..fc7b76696c1140ed9f17af4fcccc840e8a07b32b GIT binary patch literal 1158 zcmV;11bO?3P)%JcTp? zv{oW`0;vKh&L>>}6$Q?wBEZL4B7lkl=TZ^i<17#h&}*D43Q5 ztaiR+Bf<%sjqyIQ2q4*b)e?|})&bP-S%W;Qqe4ch;l~r zASch7RY1pQh>!KmS2wa$jm*8CyVB4ljV zTCR;<3)+hu*ZR{iC1a9FJsa$RT05e!oa~=7bDXpYkby`2vk`!s{n-CK`vII?s~s!# zN|+J2rdy&M7ddwA3A|bWSxb;r1l;c)=SMEDk7)(ZK5+D`f==+f_po#3ca9f8L>8X` z*Z+sd!Q-*>DO=i?OuS=rqyR9dpIlLB*7otUlt^+msNcLoI7R@c&U9}>%X*Au3BZmW z_e3n?w^aaIr;lN@AB(NO8e1o#T}~`Ev}3SL0Nf^t7AgD9+T0D*ez=Wwf3ADtp(Qp z+QiNh_NnhiTiZH;vvurO;ns0&-QPcBc9(4i&2C^oo*Moou<%S}@*S*G$aOsX@m3Lp zz7$G5r1re1T|Mv4nCChpTpplt4CibJ)$XRE3q@!S;E4#)4wCi{qKULW8{WCnlp-Yw zv~GxSzhkz&_MU{d#vetXiaL=?z<-8~2@U+sixh^Vu!QxfjU#L0ND~Rf2w+)*v}i+_ zl~uD};{>i%JcCsP(ml8%fRt!p7qqs0IU5)&mIrU58$rgk-8lePl3-*cO3}8x*Iz}( zwWqg($7G`e*B_6AqMhnpR^Con6@Zl>{rlov!utRbjyH9(UR3(+ApDJ>S!b+h+7$oz Y1sh6G!Jt?Yg#Z8m07*qoM6N<$g7uaj0ssI2 literal 0 HcmV?d00001 diff --git a/assets/dolphin/external/L1_Kaiju_128x64/frame_17.png b/assets/dolphin/external/L1_Kaiju_128x64/frame_17.png new file mode 100644 index 0000000000000000000000000000000000000000..013e2008a2f51e46a24ea78341d0916c5c7483fb GIT binary patch literal 1161 zcmV;41a|w0P)3~9W2H_#2~le4-xjm4|1^Uy6C#DKO!8|2b2Ie4hi-_3IT`?33fpm z0f-I>c0eit4(cPF0LKc{#<2h|2c!-#!fge1uMf1AEV>uuSP?8Cz_*|kRD{r#lwp|* z__kPJc0ZMbPjq5{5WFO)CVZkpfH15is3?4*Lx9)ggJ=i;4c5^FK73V8h(g;}R5iDFi@o(rRI(>#7}kC4_@Oez;EwKYNVXIjXzI z^dJxkZJyCVXPMtN$khsA70o|U@fg4pTxnIf-I4jc#WVqU2C$mlQr+PREz`6=az6aC z8CJwi0IlRJy{~Dn1kXk*nATg^JS#v5zI_i3Hvyy#c{Xi1lxn8iVr5zqv_E@D&`TZL zInh=C9s}^8Xf_Y7R9g1#197X^D%YC&Xc#I*tZ+M7PqTa1poA|4w&=4skA@A<3WEoA zmM$oF3)&p~^$Mgv8ipLJ0-<^&u($+^)p(*-aBc~kfH%F8N2JgoWmlG1q=%9O z=n4I)0C2XRF}lX$0<6M}#1dr)u!E)}Ve$W?8%(74Jb07K3SZOy$Xe0~5KUFuP4bPdbQPn6_6ou(d}+LPt_TUz34qX& zb}TLZ(a452vsrF|&q1VT6Vbhv2?9B!f(ZZ4f8PUANLI}o5oDH-()_c8ELjRhXlqtr z#hW`?gGgGJMMzqq2-%5*J{^pJrxa=(Cu@tnwf5YSX39O#K3g^jw8EoBmCzGP&njqU z+S5?t^R(}k3<5_$G&G)uR>0vkj27ITNYH}ZZ3{sb!S6(h*0?J6O-jWS?04oJ^-}DV#zBd5c3*afpEIitOQok7Bb%3ZaG6j0v b!2kFKs(*8sivuK+00000NkvXXu0mjf#}Wg} literal 0 HcmV?d00001 diff --git a/assets/dolphin/external/L1_Kaiju_128x64/frame_18.png b/assets/dolphin/external/L1_Kaiju_128x64/frame_18.png new file mode 100644 index 0000000000000000000000000000000000000000..795120e772fed8932017fd12c20a30b2fc3ab5be GIT binary patch literal 828 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 yLdN#b4ZO4o3>$ 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 literal 0 HcmV?d00001 diff --git a/assets/dolphin/external/L1_Kaiju_128x64/frame_22.png b/assets/dolphin/external/L1_Kaiju_128x64/frame_22.png new file mode 100644 index 0000000000000000000000000000000000000000..d23ee492b07b731fde5b3b7f4847ea499e4e23c1 GIT binary patch literal 1685 zcmV;G25R|&qnJ%ymHr^`B z9Ai8qf#>->ea@L#2E$GM7H{bpTGkzVf59mIV4P6?F8nuuCcd-s#~9Bdz_`9^fWlPbTZuX`k-CDV;gzpAY?A z^Z?wNwUIK6%twzBe+?+UoZkA`17Dk&>&ZjULXuOXDW22wJWu6NBq7k_7h!`+unZ%5 z$oxPlUF{sab(TC5{fzNja#;M|*&9gV9bQ%GmD@w-X=^06Y2A2@egu{wTYJ#LfyQ4` zJf&yhU2(&lfyF4RbW3^s8Re-RfcCp|$aGFbah6d;l~3XAQQ~bqkMM_i04fw0u%h(n z;YB@(BwyyhEo9wphMwomx_EVBG8KfnFZ%Hk7Je(K3tZ1E_h%U^A2s@#!Q22hN-8e} zKRf;`x|fy*Sj?oKC4r5VcM;$huZmU2UseH{KEMw5t zMfP$Mk#Ho<$%e6Z72pXt#@Bkixg?9_xkh0PE1{;Y&Av zjVKQwLAvGiJ1Pe^7Bmp_t*|R4vRQ1c0;ElJJV0inUd)%|+vOE99@I)qDKxK|1;hhL zo1j8c!A>Y&lE*q6Eqrv*HK@$`>KQ?D0LqxpoHuC-8vSV?|y_AHYhsxHs^Gr*63G0d5%1 z7`>!SN=PI7ubxx;&jfntB#<{f0F_}k_&&3H_Cl_O_ab1y6NECA=2i~!w(`4(%3i&> zsPlPegtVS%nSWJ4zPXd}SdwE0w6lqx8RBxhGHxacY7mI{jZ^@-*0-ST9VtVX)@u>5 z#xZ(Ljj9LWG9Yo<2&9S!i7MUqZswhAxa;1e7+LX1-7uh4MOKrnB44Qtqyknme=k3% zHgR_0c2bG(0#<`<8AD{B5D(xXd*J9!+Koy=Ym8~ha_9C--$l>xPZ`+hz)8$#BB%*- zLMfkCPTs0!G(bFn6#_cXJ!H$JlSZKNLzl}OSvrs$KoTOdp0|&+ma>&gM0s%+7`VCq?~|`o~Nwv@BqmH5Vwi*U2-j0wLzMyy?mnEREwZPJN)MXP*_UcQU08S zX84w&?lyvomxTOV!Sq%m6+!7C+oY15XahoAqU_qrS-j}Ns@tNsn!5Q8xTipd04ito zRz|84Y5X*_J%FU}j*G7*b%+~`pmDpgrJbMleY+2!HEuZb3Qko4Ram^OMo^XqQZ5eY z{}+%+in8=}RRL%qqe2I1@EUe{xOb;%;k9TZO`hA0 zpk3uz)e|6<&BM49*56$PR1>yrZsBF!{CBGi)7~G@gf?4MaDH9GMCCSKE@!?A@LIbI z89{g5xCl*&x7SavqOyLMtGA4x6#~Z4ZzsCW_6`Tdzk2h~)yS#JCL97Z@c5#A$LB|( z&5wi-I`Z$e`TV<6i7XEtoJxhyTCbua>!M-i03C4UN|wFzkWnGv z1m9|2RPh!(KbsF&3(~F5Djoe!;UrEPP6b>(SPoz*{zeja3y2qAJ9+UnZ3FNWf9p-% fcS9$RcX<5*G3~Up?wLwo00000NkvXXu0mjfNd6$@ literal 0 HcmV?d00001 diff --git a/assets/dolphin/external/L1_Kaiju_128x64/frame_23.png b/assets/dolphin/external/L1_Kaiju_128x64/frame_23.png new file mode 100644 index 0000000000000000000000000000000000000000..9d368900c94f1a6dd069d22c2a5f79cc5ce0d497 GIT binary patch literal 1680 zcmV;B251O}g^0MJHLB< z3T^4WCj4FWt?PVoT;n$fXw$y$dyC~q*A)f*J%``>(H`JQbouva{v!LPR(@UA$4m17 zuX!_am6*uP?_N*Rw}hZs*Gl@@eM#UN|6_c602C9ug>X{&qR3c!R{7~w61=6n6K}Ky zdiT*DpmV5ErIYAO{789#Hdfn5RtYul6A}IxV_f%r-<3n5ge5m5eeSqhzOHqs-o`WZ zC828P;LWr6@y2O;*XBeO0OkQWV{}sy3)40ewH}GKHrBE@iT?;660N8ZxMD?UMU}udAv*Q6eN?=+2uEZ}wLkeA)wX)k+WnBB|1lIlGlKIG{OzS8iFGqt=HKem8-v z2*a9N6>enz)v5sYGl3G(itwyzVJCKY9Ewh*(m9{^T);vmagms*RuNs{pDOnxFBnC1 zEXp|Ekp(J5v>H5$&LN_J^gdqrlkz4H2;N>9H=}_jd0J+l#cAPp(Mg&!@RDl}uepeI z9m9U$Gw*wOLIzI}{>oec8KSB@zE=~kZt_(8MnVfA-JDCKL)VR--6LCUhMw)3&?`pTo0lZ5|!V->*Q{cp-g&RmfHW zokS_SS9(5@!XiA3#h0g0$2x(P5)etZI=7P4cl5}b$3e%e(4cY_vq_8svOE2;nlyb40%do_<0BZ2e*GT@~U3SC~SRe;s# z>0(E}0@4S_)YO%A=X(j2O;_C|r)%w%^Zk^vkK;84=H~(E3!w1-ZU<~;w*G}u~^zxDD8UT_XsZqt(e`osW9A1ky(&Rba2tur- zb>p4@w-eYEKs8~DDi?ikJqzHUt=vJficE*nc06>mdn z-S_?VKZ8=#9Y|K475Y!>`%~;xoC^Nw1fmy~1b-rlJB6K(e-Y=}Rsc`%Pi>Ao4HaP` ayv-jxa^1*R%sztv00001vA}yFDaTPfG_w8 zsoK{V;~EKE*Vpvd>y=rS#^fXMdcD5!x904W?Ue2(`G07Xn(z!B!5Y7=>vlu^Cfw=( z+USwNuIu_SZW((1{Lc|EyyqsNPmS#QX&7mo`I0pCD}pso($wQ!ojbaBo*DkpOX4*S z_5j*I-dIFG;*ZepWCN@JIGJ4#p57kF3@Yaw$pBWwdt>ui;ja~z(8_o9?$X<_?|P5r z{>t~?^!Qr)|Ago%86xu|Zr6s{8i2!HRX)1#CLbykbF*3F`eKC}Hq zWcWG0a;#6s2%ho14Pm6gh(8ixk`9tqGw`yLH`j7151#H_&@zA)YPaz<|Be$#IT@Jr z!`j>AYh@r!AEEv3)+ogIQsBO`7e*9p4i<4z}NX8;K+%Dg#uX8?;<7uo2y z)}IEw2Us})GXqHe^652xQcjN+!x1Ww@?{*s(kJ7Hty2KPP_JcX052%JKoz=Fjqn#*zm79F%9 z&6YP0lpbK#Eh&($$$CDsfm>}*gsgL)MAVb4GA#R=>a^iTQzUivupfnEoSxuQ;tdZ$!KQ)1hP+v=E%8!N(MljYKP;Y zpxpyRV>;3!8nd7H?Z&UjY|YO&hTLn^sXkFU)=y8NYzaV=xWfrLWx!gC(9yc-hB;a% z=U3(atQcvbDyT*SyDmQsk#4Bo-CpB^Fj~z)OF#zN_^1PQo#wYXT{#1wi?aDLGv%|?MG~aV!^c;ipyKBx!6lO-#oHGew7p1GN5x#MBz#v zy#|#F$ucWYdVp2xL)KfVT5nLawhBvDFB4@^y#TZ1+LcKt_W%r7&6>;#NEz8B%WCsI zhnezwFOLo*6Qc4{dVnW>F#ZkDLOkV3YtWm7?>rPL0-nZ%qcC zY+3%49)JbSGkXd^qcnSLMXq+O9%jXV=l-Il@#xsc-IDO;hZD=KHGUdtAe#||91sPdU3Fy+T8U!g{nPBRoQV!p9Vf0)< zra_jXx|}de05fB)dLZwZwhNIHSYuo60e0NZtx&yoWypx$99DT{b<1Reb`KyMA^BM+ ztxEnoNfvJ1j?(??0J) zbd4x7SL=~J;p9aS3sy<2g4s~JH-TLP>}tNO+pVYs==WY`%AS`i`Z3b~DW?v5fJkub z3KYSvFF-Qo>I9yene;xjO28O?bXISs^m@r>B?pr~!gGbH6YO#v^Bw>#0TEG6-1UJbyC>a5Z4zE$ktwBuy4<=a3>*fRVbP262LdFRjA*R}(! k4F9CdkSF8hZK34#AGJsPjXYbvdH?_b07*qoM6N<$f=y#C>i_@% literal 0 HcmV?d00001 diff --git a/assets/dolphin/external/L1_Kaiju_128x64/frame_25.png b/assets/dolphin/external/L1_Kaiju_128x64/frame_25.png new file mode 100644 index 0000000000000000000000000000000000000000..b40333654f83c6ccda04cbb4020621e79e7dfbdb GIT binary patch literal 1658 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 KMNUMnLSTZld>|zN literal 0 HcmV?d00001 diff --git a/assets/dolphin/external/L1_Kaiju_128x64/frame_27.png b/assets/dolphin/external/L1_Kaiju_128x64/frame_27.png new file mode 100644 index 0000000000000000000000000000000000000000..0291dfb5830a140e9604c82b66e0fead0a9d8577 GIT binary patch literal 1741 zcmV;;1~U1HP)$@V{Y{3g8ONZp?cAc^=h3_`0oJ ze!%-ZVw~TKw-`Xwl05_A9%?;H*GT-SvNc2ajd<-X!rt{;a=@6p$Wr2wut zjRt*QTC+b(a%sq(UH2WqpTDkks0QGNOKD~3W%z3b5S78I0lMj{g6`fo==viO!1FA6 zph*5w2$y(kQH0;8*w?LSf_%^Ho6Anmfz~_E^Q?Pch`dWec3~6A>V@c}k}Xlt*Sz-7m!}qXbI`O%SU1{kduc90=uq0xGo! z3a^d_Qbg0iR0OC1b?Dz{bQ|pmu$Da|kR1ik+&9IDja_^7`5KRG=cWxTA zpvfwqM}gB30l}|JBWoz_-vsV^(re$#2t^G6(FL528Wn!1u4k{yocU`nv|e3wHj_OJ zy7}oGDz&(i{3y6?sz!517JAQQx_~I8a9&w^x+u)@LwJ3K@5UWni0lHQ{Hh*>NF662 z$=414S^P@@*85t${Hpiqfg{L?fTa5q3xyKh&NNKoQ<+U@_oQf*;Z;#S%3vT7z)Atp z`;y|PLL@ctPKztil+ZQ646=p+sR1M*BI|j9Hm!Jxe|5yopF^~}NJOJJvQEbsZX?*P0`A}WW(N4xLQ zl#0Ks(^Q>6Tl`%1$^FM`aJMz0i7(Fs83)AsD4;$&wkM@bn|`$QE&0y3ypG?y9nTXmH<94 z=%Ea!Uj@3Zp{aWB+5E$hhytpIpBc1d=I&k{6E#+CsN_K!{8S9=RPA8S0iqRcMp$I8 zt;v(+Kb1Zvr+-;!#@tE)Yw6zE9jtJg-a$?ecCzRwe|lt05l#UXQBK?%tYj5pjW#V< zxj1sIIvnDdGQh5J@Ac&ru!(r+wt>}+b`L%qaZd5&&sH3YI>%f8$!~Z@&h4@pc|Fhb_kRsbad#kjbyn#o=l*D%G@J_l>jKb(t*=Hi_y%Q5I63o2oGaufVVp3% j_9=sqPshn=A?5W4au)}*O&X|=00000NkvXXu0mjf^msif literal 0 HcmV?d00001 diff --git a/assets/dolphin/external/L1_Kaiju_128x64/frame_28.png b/assets/dolphin/external/L1_Kaiju_128x64/frame_28.png new file mode 100644 index 0000000000000000000000000000000000000000..54a889d8151209f012e5b42e1da564793606c3a7 GIT binary patch literal 1686 zcmV;H25I?;P)wUdPS!FH+Q14MrQ7gCtMTXN!pCPM8V$s7-M{BD=lCN>$uj7JR8QwhAmKV@?)%GEc;faQT`gqR=-n+G+cDGI( z3M@-MGFM*6pX5y&y8@1t`@^-gE4%l|e&zGY-}g0|asVxUGEPMFbY)z#CUDFFc4IsF zT8-D%m9jtL0gzFRf$ZHwU*p3%mAFn6Rw&t>dM#|M#(VaS`<>6^&xnsaox8in1dc;N z$jy4`ROoAbNI|WH8G*)=RvoP9c|4<3qD4!SvzMn&MG3p{$W%r75&GWEugX3TBDAde zQ64SY_{_^wn+HI~*vjA0kDkT~GRpTt3mKBG9FyVc9Z`Zs#AC$_BkVW6fN&^d}j{e z!5xD3BD0rD1yt$-NT8dS%xFm(!voCqGI+ArKsk1z)Cru-V#beP!JBjKK&b*|rjOTrCpW^(0e%at{q1Bff6jV?auwjg zDGxAdVa{

Fc87HT~&L9^=BZz|H0U{wlGOFDf9!RT5 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 literal 0 HcmV?d00001 diff --git a/assets/dolphin/external/L1_Kaiju_128x64/frame_3.png b/assets/dolphin/external/L1_Kaiju_128x64/frame_3.png new file mode 100644 index 0000000000000000000000000000000000000000..bedf366c6ccf988ca20807c9062e7e7f7b70d9b9 GIT binary patch literal 1305 zcmV+!1?KvRP)td%uS!`N3?sl70Tq=Y_f8vQs0;XV zED)XBPReiX#sDdJNwAypTe}2E!%Bi3mEYPWz|Z5!90#}7NcLlqyRyF$(j0f5e<};0 zCiXnf))PJj@VgcxQ^qg>IOU%TJa%s#gKO{I4ERen`2OlI;e-hACFOGq+UGdanpyhd zh!MrGLQwU>SqPTdX_8FqT&Rq|IwonSQ)8_nr<(vPcE43V*Un>>xuDj1kF+*XGW7m2 z5h_SfY5_)6{wn0bMdEf^hqv5|WpkfN@}%+Map534OM)^2-~o+*G)b*bD!9^Q!o?jG z4_K5>jj4(RWdwjhQ>Dxf&9qw0b0&(G7Mh#)i249W;)uM`O5n^)per5j2#Xbv$inqQ znRfg+C)4VBBFd}C2tIKf?8()m@+)>*2NgG1+?y5~M8@T^0I-u&^ZqFCqGD1=*@Nci zB^QBX5NUkFVgRXF(ywdzZ*?BO0@&PBB;b@yt)UiANG?MfqX#AeSo~X5281<_UjaBa zOagcf=j&Rfk?Myl2ub%vQ4#}S3*gPAx%+kjr4+7MBl&4g9(6sFt$0xSXc&CO*Q4@w z0ab~M#6q585J#rU&2b+MQvj7gnRH8V2Gi7NC2$mmJQ}u(tPy0S0zV50;42>ED&@EK zLthE2CMHD!jtD#M{Ekl)f>wYdffZW12>X#_Xl*oXO@Q6w2`UA&KvMqfj3MO$Mk(lo zN+S;Jv|UVtw!h?qVOR2=~qUvR(D`zla#?~1=3FjjX;$@uZ{~Oa}A+I^}UTn`J627{ZTOhg(`EX z`O_@4V2@LRXV+`W*W8i?TM=NCPpmX@aM3L!kTQm<{-N9P&UKqo@TyX%7ciLX?>S_M zEY%7;j(!ogX#iY9~!cz8q4sMj3sPQ2dGy5OmJhgzk@Z?a zfZ6HVXhc&v>`pjHY3}kukOyB=JVewIaLT0oz2*WUWEf6>(@eStmeMb7-&$@bOJ^Vv z3?V>N=_^a3Goc;)Sn~U-R50{-xCZY|_g2R&@+=j*S&+^LIw<8@&rmWXa1)?=1ibFXJXvWloWgxRI<@+<&e+sR~C zVdb1g^j)3>RPD0r-G4!&{Fg&#D&LE$O5>Ms9}oX=Z1u~b-raxAe;)q;>SwfYfJwge P00000NkvXXu0mjfKQdP` literal 0 HcmV?d00001 diff --git a/assets/dolphin/external/L1_Kaiju_128x64/frame_30.png b/assets/dolphin/external/L1_Kaiju_128x64/frame_30.png new file mode 100644 index 0000000000000000000000000000000000000000..0731760dffbaa07d4e1f50c1fd65bd0eb1f6ef19 GIT binary patch literal 1677 zcmV;826Fj{P)Pk0p{ai`))_7(%Z%c13qA~ z?!K<;z5d{Rf4{x&Tl`!542k!Bulv6L%Aug2Yxj7;$MZEuWOG|s-&N3I`;Rtxx1%Lk z&hL^%|Guu=df)f`dfoT^Wyclk$>O;#+4(CS|F1!^rxjqc0O|C_N89<@m1A~)^m+nN z2Dcc2zJ^TcHO6Rj)9*9aM^c;`V7%9i!oROvPYVK+J|2d(Y7a|4UT@Ge>aqEUE5;T2 z9~oc(O}&&6Bo?s7NT1JY4Uf$~Qbo(7NUI67`?A+4R@5mSGEg-Z4JZj7n?JnrjyMVF z{M`&-9X)pz#Iw}PS%t!5^N%!fg#n@pR2ZNFZ_v#sx)V~KAK<&6zo++EHvdWi(H-j9 z!9RroqUdIZNPtQ~Ky`C5KxT(>=TW2Z0_7wI(CVHD=njnPjt+Rqemoe=8h{SS)Bx6^ zD2<^RATtKxd`Sns<7VDqyvj;F9{pHGAV zvhXrMrWhOJ#%n~lWB^pbH`C=5$7_HyKqLip1X(lz#|7? z7*Bm5t%2)mjX`52dyMsbs?PTy!T<g*NrmcQKtaJ zt{*Zad0rj8vbt-EEUZ%q{|>?c(vBKJrLpuoex*uBjLXx9lydf&f);WthOC<_u;w zwsd^>Ko31j0xZQURBo|H#9%XqLBYddU9vNHu4_(3JMx@F-&vaN*!dJc!ReZgkH;XM zDmpt>1H$=SzfLFcTpL+;CnHfv^}rKR(wbNsQz?)T&L8Ne{#}T!iKo`D-vwybF))iP z18^O7!K*{%7`p@StNb!3ijEY3+^s8j|4Lbi^!oMVQ0?lO&{8n76aEFN_5{POwDgq% zRtSrplV^>ii0o)VhLXwOBZ2Bdx@&-$GW<0JXy2cjAGyO2rw?tO6Knvf0jw0@{l3yG z=tf32t8;l$p$Mq~IK1a>$`CwF@MEB6EKAnzqu;E3UDXY-Hs~oJYjA|4I+{IQyAxGs zjJYanhSUJjB2Sw`l0VZ0y}P*_#JUjkSo2o`3VI6gwv}f^AT`>|fY#1Gt@C$c5PZf2 z)^&!+X<;}OT>v5H@}A$L^NsiPa}=`ngfM_-A<|PhdL8rdqtogXz;)?3vaZnC3rG#n zg=z{w$+u1zk-4(=jLM0~f_DPF5r`-pxm-GTCjV=Cqc_6JX9Y8q`v6*g)9%yG`Vu@H zIdm<-^{G71kkHMlQWuu~%~56msfnY3=T%Rms5=Ez9Fj=`QAFmKd@)N2%WD8DuU3%N z)iTa$$4CvH4W+HK<=+FKjJ6{MbR(j#=e|ggN@=*|-vb~jbE#ICJqxG=LbN`idhTF~ ztc|(8Wd@Lnz^db`6?|lT=P|Mq-Xf2KZzkxo09xQ7nkcIpL5PP?(RI%5_kQm^_wzbo zjDz+8q~fm120I!--IU(dw30R)b-X0ETmxwNc~?&C9y6OSTQ~7}yz=OLJT1)RT-To; zhGdi+f~?}qv&bEdAWnrDtSbB@r_#@@F?5`Ezxl%uj{~wh&l_Cyy>$wRfX|h2rdF(0 z0|U)UvtrRa1w^CFgRY&EnNu25rSV1Pwuv5187CM(s~0L zESuji*b7p0MxEZ-_wUBaz{!B?2de=r$L}cOcA?T)Tp=se2=ZX&_|uD^Q;=~cf^B{Q X1UzU}jMrLx00000NkvXXu0mjfn1~uQ literal 0 HcmV?d00001 diff --git a/assets/dolphin/external/L1_Kaiju_128x64/frame_31.png b/assets/dolphin/external/L1_Kaiju_128x64/frame_31.png new file mode 100644 index 0000000000000000000000000000000000000000..898efdc4b8fe693c99eb9613e82bb5762b1d1645 GIT binary patch literal 1639 zcmV-t2AKJYP)OFJ=4bXJY&xJ?|e>!-lyPvB>sHvdZy8o=pu-&y$T)tzh#s*&p5yYF#~-|i5fwP5th5uK;OYkVpP zYOG~w{+VFsE0k%WHMxQeU9e>V=H`=#DuT_pjmc_=bFwHwmnW+=3Q1Z}6s|PJl)NiH2l+em#-{@b4L9=pb`XIDy4uJGysIFFVH za0`g>rKCx72L3E62MS3(ME9Bu+RqZ*R0PnNMiFr+kMS+ul*Sv9SdZ>KM**e#$r^t# zmpDWVcj~?N4Q?*wC5k*!i{>?cIipmYhZP{K0R7H_U zc}V5!j9?WGCeesgFS{%MKE^mx1)w1pP4rNnRwjKLZ;-1b0xaY4&w6HoCOZ<{><;cs zqN<=df=70)bHoN;D{Syk?h&3FPfJLu>s*hF8G3Kn!C8FAz+Warp*fGFK(53fPi*b`BpGl~78!dq2=i|2qP#i5V}{oPY~2EocYCK+?i3IT6`1xanA&Z^_>V zRyTrBctbYoFtjS!RUvPS5TP6(I#FWGQBlHG;tgT_Hh+%K2_{mFzr(I6R3Qse_3+a5 zCm_@ZSOYR0K&`B@&flBoptZJ+Xz{k)KSogwusZ@W&pD6Eo#-*J#QTlLj2z{k=)@gp z3)k9ZQngVbM}@OgI^7!`W{jd7fcO5rXa23^3^i~?*Y5-(Ilw16k-}?mjRtq3s8e_p zZaG1fQ+6F;S(H`*Xj|FJ@~f0yrEp0ePY1Q4nTFt6AHY*BNIN}4vjT7E4@3~@T=HkF zRRCwq$94AKy}RvX+1Kf8-s7_*2k^qm89WMlRK;j`BLy_@PiyKJ{=`{*;o!`t` zx!s~HuYYSuj6izHC0)nxC59)G!tEc1AUmw9R*o(n>1A}~0vbIoi&QB{^Rsdy^S7Nq ztF^n}ae_{-z7b8L=R1E-fXs=&a)Q(mFou2%RC%ulXsE4_FAMsD2z_VJ0r&{ez!M$q z9v_b)`n~{7rZT0g*MYR-$%+P@y@Bu%fC`q`VVPZ;-PzG>9SP@BRiO0?s#?XGE|2}c zff=0Y;Gy%QQ4_5a=)KA#N^De(;rnmnvI0xSzDt63Cc%o_6Ip}=&-v`Jrp+8IB z-hm8l{%+$0U(Y3U{({Q;LY;FKIu5$6B^002ovPDHLkV1lXu4UYf- literal 0 HcmV?d00001 diff --git a/assets/dolphin/external/L1_Kaiju_128x64/frame_32.png b/assets/dolphin/external/L1_Kaiju_128x64/frame_32.png new file mode 100644 index 0000000000000000000000000000000000000000..39f5db8a0131b28046b4450ce84eda9d9f519ba9 GIT binary patch literal 1618 zcmV-Y2CeytP)d$G==M{J<5M|M zV+}*|tM~rxqHQ%gJMSy__qI3(&}N~8Sv&e(o7u=S6x0bg?-M}yQ&|x?mq&n|@I(QW zo<&oOB=j2XD((`0s~tl3O}%AymjsygLy?)Ot09daNi?;)N9PgU4I7&ckZ4H8=l3l+0RNmph7QtqhZD?rjQ1HQ(B4Z9u{;8B zhP;hOan<1bd+(yMs(?5c)hjn%CIZZ4S`q<45-mH zx*2|DIRF&~Wf*OP&H`&zc@-9k9@X&h=edoP>+rTEIe^z_)&R7yHp_%H{ua%dEL^Ug zkP^a540ETN%MB9897S*}YhI{<*cbXBU8mTr|-`dCoHF)3`ydk_a%2$FK2j2Ab?hbh9&f zWfD~d%@I7ZbDbkLc+bKH59J==x$(4wqh8dj2yEXhUAqvfTBn47u$?(%? zXtHoeogo_mRydER4lwXW1VQ%OXkSgyS;HgI$>QNP$Y{GG3am_G->C4jU4Yg{5`H|B z_WRzV&8%kNsVVSU!Ka0IB#Ec`=)M120%jdEUZ^<%7hW2W1;jwoz-MwIvSo16u{ht7 z-v*+}t%f&bqYguNCDtzFwg?f*0iqox#u~i4hgG;Cte@u3@mfio?&GD4<^g=&UzPMA zOPREF{RBkn0Iz6A&X^|`T5*ShI>PwA170Vn!fms^wW0_>4UHIH>OXUWRfQb1Eys<< zj4b7^Xvbfg2sBwW0{%IdtJ?1t)%ps+CklOFL6QWvD2oAvjhCh}O|7X=ZRkeISBJ<&wWEsRT-4 z{j@T@vu%YFX!KS(n^eZPkj?>UL5CK3w04rP+8_|zxUNdzI;vcrJV`i5ItTFV`>C^3 z%>u5>Y)(;S9DV}Fb#zOGu_OoZV8_yMdimi8NLF#HVj^VdEIAFV7*GYg>mlWzHO!|Z zm1T7R?T}|DZpa6s&Xz@#PC5sW4DLM(km#Y1q7U+Hg)H8_G#5JM1f_oupfUf1P-ww( zD$3V>bfm#RqNn& zfLrj&CV*O7bp5NsO-hw?=~+&zq5y&y&)|7A&vJ;U5s{gI(A5e+7NW(WNPBumlfB3U z)MP+tm~{Ya;8Oh`!KdtxJ>bT*qNyh_+@Y(tWjutr=Gob-HnR_x?v=7>(CBelq@9A) zzeV7*^RE% z{Il0_JZA zxyBgJaNv3VcE7G`JkRsfLR{DNtFQK)0yi&QpOTB4s{-8GU0AXHof%9W(irq%aD6#& z#>K6}Ddl+{))4!2!zv@7*4Jp?vTh3lWXD>JugVCl>%l}1 zek3DU#Q;!tuHD7}E4>pcey+7UBuLJ(iUH==a}B5yZQY}D0E^*K8<%L=vR-zt90kLF zuV4VnzFw09aP&s?(Y(NG3|Q%v;RViL!2lNdX1^^A5HTDsv7zSX8BDDX*FtFiT|*p9+&)i^ruIKvRyEKX8YFJ=Q~mQk>Psc4MXPt?Rbr z0F>}lc)(sC*(B`W#b91wMyk?16%Jub^<9<&a2w_XqUek|Ob@smz+zMydsSgq2%ht` zpwtH{9VdNN6mJ1{<-u!GimsOH)SQFD9q|$l5&Ft1 zi!(Ug&3$@qrJe0zyP#t7AW|6;OcebSgS)6;NN#^VIxqVAR92oA!*w zIl`N0+KNyP5FJP@j8T=`RN-3>K7&ukB3wae$3d(%$ejje3FR0+*T75#kgLQ|iANNb zhjtPxP3&T)k{m$G{-fWA{i+X5Q}}5HV!^f?0Km2cTZ)L^AYl zz~U8rNwq76XY~-t0nBv(2^C7CHlOuk>$!1{E|8_w=?Lz=Jdc zc<#>l-rW&zqbva1jx|@#BcVM9n8vc=@K4AGpmD#!2udq~-SK~}4M8a^szmQN%!Y3W zAD=O5ejWgRb{GQ2uF^8~EGx^(P?=@`>cBG;pP}9r^G0hNZ$at102~T-GC^f1SRu

A_%cY^nB~nLryOmg z7U49U=22AfNPGVgMYdEvpNqd3VkwD66E>@HMdrqGRj_~tkC#`hpViMCE4~fXHi0L# z3a~0XNUxTuz7?`aZ#gBItR?g;=G@#`sSq$HmNM?n>mcMM`hxI|h z90DXkpg`O+O%QE<>+=aIDWdv$=eL6Mba;5xM&MzVa0q}4W#-VvMm@KJ+O6N$JPosf z6gHwpK&@v%%ij&mVpRn%IzGdiTumSos#3}17`{Inmw}b4D(=oF*WW34*t9ZvH2?nq zUSJ_9%kRj3qlg+%Ch7I|tzgFMDLw@*;o$_3=D;|mx+tOBaJ<0smE{1^!S6`ob|ETv tSDy1v9l$*Uf_Ctym1|E$rmB}&>kp8-&f}bY-Pr&D002ovPDHLkV1goI?@a&z literal 0 HcmV?d00001 diff --git a/assets/dolphin/external/L1_Kaiju_128x64/frame_34.png b/assets/dolphin/external/L1_Kaiju_128x64/frame_34.png new file mode 100644 index 0000000000000000000000000000000000000000..969b91193d409a832d6d33a097670ca00399d371 GIT binary patch literal 1591 zcmV-72FUq|P)N{wWzs0r^zh-ZRrN*TD7s&hj5Nyx;{jwADBgsG+(0nsZ^C+HrpYADRK4=SlBA&5=9|AUP4f*WGgRceWk! z=kxi_vKwg(_Be<1yk{IK2go?7hh2U`4j|=n5IaV@{lGJl z{GF{;zDK{;*aT0^kBmKr|AevHNzii7(Vf=adgSBzt;RJufQM2}!W*8nXDCC^x$iW- zM?Rh3YTOUg$~NOh$C3<>@88A%5j~d-&_&y)zf+uaNRuPyo?V}MnnqD`8MaTa)XNCeWZ+{pkIz3_WZ zzjg@C&#+l*4j_4DCQ({V<^)#yNz{z5S2#b_No%=hO%7mD zLfiHDbyXI8E3_mGUyI}l9eSD>KvF_7JiSK8sW85U9cVo6awtzS2G4t(z%%A*9kH&d z5Wp=a-Sr^Is^m{%0Bv!t*v$ZRy!S7KMi$z#>#6dQtT=<+PUK+#cz$ONK=mt00xeWM zr(VqiI>gW4&H!V4*EPxjFqYI-=Kz40Wq~!}D=+0HsL7~~*If%IA;JLkS`?8m`mz|G z#&qr;H%=seRfYlX6w=KqnH*pYdx^IS?+_p*G!|;NX5$`Y4CT$pvxw;0p`#@Spb$fV zXF`?`;YD;o$5+F_B0cB`0Up_&@pl|CEn{Aj16UrkB!gPN z-AAz%x^=pl0VuZoMo=ZANY8r{#!e?V#Q>o?K(r$_84Mgsq=k-9cLrU>CO{+)_!SJW zDqdLbON*vCk#(VW*99!HuFe509W_`d$5rX@81z`Wau6!-gyE@d%X2@T0jQC@6XN=L z$KvSs#KKzj{#7|Z#U!|bMTH}E^s(Z$(+`KzQ-H_w$A}+0HSDPNRp>yAZB=r$mP1(% z;7P_{?9M{WX(s@jU;%6Se2fAHupWK5XQ-hn4R?Dk(B&B3@LiGvc+ipbtYn=qL{x@$ z(y{dQu5bF!!>Q1Y*p>yyPM~KeJ8%paX*-e10X)Ypj!|~TX)gR|y8RWTa)9Vr9lzg+ z6Nct;ByZb^_xA+uQUEG`r*@mQeB2@P#t=~Q6)_M`cgO#zF;6(btuW;PD^EOGgRd+< zcOnxCI+6a07?==^?b%9RcOS0bE>^fM1Xw(AmEmJYI296ZcY+&3kIDcMTBUtyl%5AU$shA>3<^T+O(&v|Hf>+}PbGfp7>I!=G??kzLpfEDl7k zS26+JOkIv}^#27|5#7NVMCmtk1kJ?tDCQVr+u>I_->#Ck$j-{{nB6r251Uqg*0TJH zm?$I)+vVk5^@T3Eo_?9I@NKg_#a7_FGjmSGI8j;j;`S;e)vqiE&DR5;S@p!S{sCONsyh002ovPDHLkV1kQQ?b84N literal 0 HcmV?d00001 diff --git a/assets/dolphin/external/L1_Kaiju_128x64/frame_35.png b/assets/dolphin/external/L1_Kaiju_128x64/frame_35.png new file mode 100644 index 0000000000000000000000000000000000000000..a72cf1823ee1ad46ad72a8b4e1e9156c0dedcc88 GIT binary patch literal 1560 zcmV+z2Iu*SP)#en?wbq{JX}$ONb>MlP_v`U|ytY95QH*}ta|<5%J8)9=F8MDyFcma}&_&l2lAsxy zPJ%m|hKRHL0mEy&;D$zxqk$V*dTu!v#iZ92oYWItz5@r)xSWQMF(6|6+c0*2@BNE@VhDlk+2Ex8^@#%y!baO6~Yg+kN%Or}LYQ3ps!%q@08|Jy~sdgy3_p zG`>eZpWkfU4`^jK<3`8Q3{Rim76Br9P9wmsuzgC7Bv*sw1h+*1>%KK^83&M{O{!A% zEDdN*a8m@}bE4PTxL2eAir%|8;cOYhuokQoP#pm*`Q!c2na}Nt2%t@b-;*YE5}q7< zIs#}&i2&KV67k^i+!Gb7MWfF>um~2vR!4yG8qxn)1eg&OYtmAVL*UsV5oo)zG6Eoa z(f5*m+Z`Zkd}I;mm;;ux_%*}$ zQiRm5ydM++BB50B%3V8v%eeuw+?+B0m1wq=1882kLX>8cIf0peT4<*CGn}96WL>4U zkOLq}Si7FS&SJs0!XjbxUW6;`&=ZaTni87f`8_^PhVhZ;!1M7ghw_lI(ca?(o-t?Z zNOfIG0n%dfT|We&N`9vZU@b0+>IlHcd;g=*$U-B#o+}?=#Ve?GB2NSu?JGF|*Dr+x zBB8o>yP7w`A#Hzq1ZeGlU850TjHO+(Il#aRSzt@}%uA&SS~9Zp^{$1}5QzZ%UKEiu z`a+D)bGr0Q8Yhy!GSh%`3fUc1RyaUwc!@U)?-ZaB8YHx%Y}|ttLwOnbDk8e>&=KJP z9BK;iObAI4UPKqPwfXV0;yCDOf0E;TNda0YnoY_ITTud|r5!&0Ob0&Z?gd}r0INVa z09~`*KR*kQiY3zGM)OeA36MUwoDiaC_UZ^=9s_BJ^x&kSybD-y#6-rth65lC5i)2& zbC6TJcjvjfHD9DW&H;7~jvj3&F{AfAa=e6brxTot0HHcSw4*f{baL7mU2B_BD4}w* z(?Em={D=tPsU2wjH7BqLD7w(qbpb@y)f@onm<{cmP8UjZg4Xm;CTW{W{Hh4xNg3$b z-5Z`Yr>TZ_9exA{h*S(`EMU2Q*4lhG^*sS)qf(aU$29SmFSY-E%50YXv6y>;}$Ijim@cLoEHf6{iba z{Id@9x)bl;30zTNqySpQyVViU^6?ItH>QAP4j>sEMG&09U`pw-hMPr5JZg^tQ8jWrDJ6d5{Be;^_X zuA~%FcbAA)5OtsxQs`})5gFhAZCn;4?_6Q26xF*jf@;U{g6o&Y0W8CxAaSP<)w_!4 z@IK29Ff;sZweMRIF=mF-gdHFw)c;`(8BXJN03_7^?fQGco#r3AcOtGYWHw&_0000< KMNUMnLSTX%)YRDk literal 0 HcmV?d00001 diff --git a/assets/dolphin/external/L1_Kaiju_128x64/frame_36.png b/assets/dolphin/external/L1_Kaiju_128x64/frame_36.png new file mode 100644 index 0000000000000000000000000000000000000000..9a13e7c67db281d96949e0be75aa7ee4197dfa96 GIT binary patch literal 1592 zcmV-82FLk{P)PbXFRCt{2UE6ZqAPmGE|Nk$$Po#>DgjN?WZn85O5*vg-Vp%v% zdOgqcv;nT`YQ2i~z4WtWM*?r7)#LT8dNZ)I?^*rdNT*hC5oqn{V4ml3B@s`+U-)4r zKx_Y!U_~z`ls_^*)2%`?%=8L8uO89;1H zljGedExV^MK*Z0o1mF&Ir&lC`h0!FTex1$$qvs_Ipsf_H%saG%klu~#&e~40wohV! z4!-CRyQxzE4}RZQC8y}S>$=22NyyOj3_BgG8DP|Z|GAHo#~{rBS|;*m2ut*K+-cr^ z<(3gij1w7PG`_F~KswRhOAH~EQew@(XwS5u1%a2VHGt-u=BJARX6(PC!L3~NS!fBd zk^vCEIIBVoAO&QUW!5`s#hns-50&zE98?FbNP^y{<`3fEhX|yV`p?z`QQ^Tw2zMS4 zIBy3X*Ql%rzO+cSlDGTD0NSdr2oN0vIykNU8({6t)fyn;-J zVgbunFPnLjz++P@C0}pa5HaKhdI~`7oCsvaTkTge0JnE%9T*87>D_2wLYDD0Hgo)umh2FL=@ z035fqGNLO-OM)GN&WwTDK>PAw*PL{GTm(^MokN4ZGdZfUlK~J7Koj)3uJ88%ykdoO z)b5Tz@9584f2DsP$3Usl45yGJIE4i=iTXMXz$?xOf~53U1bat9oz4IpW&bSP8VD*1 zwP$a^=^B7T)c}>?!lT1V0zOHeM93yh^f>q<89*Df=W>Hjbj8F}CAIes1i^6{pfVHD z!SNFZKX+@#7o`6RT@z{hBN>1qG9YQ9`?K8>z|4V=DhMaTR;p%;0dgnE`7r_Lej8r|Ob~ zp5-N*(u7-q_N;28jwTGN@TTKxM~VR`l_GwCw-b;-z1)x06LrFyruYDUIJ!U?(L(Hut+6>gsXQTvh@)x_LNhUDOVo4*)hA$o~o z4Lo`ah$?9`5j;s|F-AqwXTcZsa0@^$Ya++38Hgm6mI%>cNl9=*;3YiIgKq&EMj9X+ zY%jZTdh^~VP#YP)`Fxxfc#8BEARSvqM;UZ7tN5PEgg2+$wn3v{FPb{)C z>Gyr#?Js)oZS3~m8wKfnHg?MY#%I5D2tTLaAH!!)kZ^CJRS6`~@=5KKh` z?GJq5Z=Qh}@-6z2HGmgT0Z0P4uN{L7S7;2#^z1FA=c)27_6a2bR&Xc*_a#W}Cq8C1 zCLGI@D>stQBHwDCGy*^+pu*bgF(_hqoX?GA#fcHXqbExMt-~TQoBfm_R*br;+i4MC zcHA8Ssz@NEi4}&gIDLkbA^@}#-b&+sbO998GBK2yIfyd?B#y_35qei`XY#QvusxS+ zfGiSNW~P(^esT>U!CV92L9?U43Opo;r~%+Onp~Sz18}-=dQKw%9uymHri5g?tX$lh zo&=HL2vHdUGs4KeR+6cr5Y)_g>Hf+Ih{p?w0Jx6W ziCG$`lCOca7O=>k)c{z(kO*K!WfZ6`1icZUHQVm`r^eKb`(*5l0Gb*A`lNU8HjrB=kU$k&)R;d7r$>N~Hjul> z@*q_29Su+3&S+sZGBr4+2AB=@&7nFAr$+#c={JEE5@`EQ&jau396UI^2EY(M3iXhH zQjFT)mHRS@^wiYqm>`oaz@}u#p*yv4WKoqmN3@wP9i~T z^1souZZq-r7eZhGmL>eYKmUS-7pJ`>!UgOTQot+95%8x9E9(Rq#Cc-9^3esr-z~KO z#Og9K!${ zq)T?I2W3Hc<#FpFv+Ln`s&3Gvq)QT_0X2qXe2sF{djpLwxI3^cYH0}+0 zyI3~ErF8)3WDm3v#X9?`alIsv^7-zTFDk-`Uj=K*{1`zHZLNsq17DL_(yTMzJtPRU{3zTMJEJPFAvKYk(DCC8>pqsvg>d>X~f0&$?DIvpM-6N3MWkr`72v=2tCtrvM39zpxr$=J*{& w+%9TB?jEFXW0F?irG_|vx-T(jq07*qoM6N<$f*O#b7XSbN literal 0 HcmV?d00001 diff --git a/assets/dolphin/external/L1_Kaiju_128x64/frame_38.png b/assets/dolphin/external/L1_Kaiju_128x64/frame_38.png new file mode 100644 index 0000000000000000000000000000000000000000..93da7f4f94b06909289dcbdc89181a3c10a2f39d GIT binary patch literal 1489 zcmV;?1upuDP)1ZUZe~C;v8JmN$l)F2__2&N)} z^#yMgWdi9ag^HljB`=k;8D>#&ZpEYRhCqCyj zCY;NaD>stQBj0PEG6Fy)pu*Pi7!)xg&gbUx;=~9L(UT>B)nS>CRzGEk8KchXc3K3G z&W9twDiUaEVus-}PM2^}1b}wJM{VAZE`VZMC5AGRgE%8V;zW#?q4%nzBp=%X+jF`G zs3L)9WojwlH`f3f+%*86v^omRAVPwS8UW5?$+cBA0H+(Lrx*e7q}Xth5}NUR z5@doS#L5U@(F=a2^t<3d&iR}Hxv(rLP)!C-PPRNLFRvoOkjd#|(eDMnfbXpe;DV#~ z{^Mm;E(=iR3bJuJQ0W05Gn`M=Hrx?k*L!a-tMj#x!+pQX@RY$UMy%4Mwa>)>7lk(h zV9b#EM-5_j@Csmjs?UwKM{Cy;fJEE6KE?5VWj#?fR7q5YLwq0dO6$ z6H*#jCEo&XE#Q$Y)c{z(lnCI($|$h95R68E)_l(+WFaL2oK_z|z3&hK@VO|wtz>KM ze;YW%LT`1wnlN{W09qYY76CK?+2LnbSCP5Wta2n&?3Z}<0R}D$^SBl6$*&bZSOS&4 zEC%6F72S3h&KKoeYgMl~pPJJ$@13zT0$6GQ=#$>T-9T=mKm%29QFHzloE`x_+CXlQ z=Z8?ecQzt?8bF#Xi=CA5pPB|vj{q3rGl3owNP7objbJGtcXSRBoL&Q9 zs1JokNC1`5##_hEVpSV>+X#@Uh<6@|WV3ovb62*3kEsFh#1;e0tgO{rwpF-o1khk5 zfptU3JN7PkTn&&3?0jpTP>}|za5vKadn9ZetBgcd^48pcmkyvcUj)ehO=UGeCT6yl zXXUPl0w)mFbL&2x02#RrJ1To0;H0~O+3?(;Yfbn&fnH(bdJfdw*1L$A?P+wrRnIz5 z*L(fp!7D@IaU)2>aKLzR*T8XiYzwtq>^)ZEH3UTpu84v|mUOL^R5Le-DsV@#PW_p< z0l2C&jB7Py)S1;?1?;Laj+OX90GP|Yw}auUqQ#+b+D#%{3*90G%nG3#ZmkKV`K)8T z*F@xa=DZs|x&Zjza~H5R`N7g^L@Io|U7CeErGS#Z6zbXU=Md=tX4<@rf-`duWL0_- z|8=m(pjgqY)S^Wf?Yivo+FTIcI*K}0@IQB2%9Uw0swFj&&@QXU)U7JMipMS_zkt z?=3oEdGK>2HDg>F%PayY=VY%yF3m_fdG)~ck0fh%%a>(eQwq=&feLZw@OaC-+Wi6v z)QYhJ%RObI34^k^7vU7pnvWn6RJL^*tSKN{t`{(6MPx63AS8n5e*X-t^$$igT4cA) zR`k}|GRks!l{$|@u=|HihV9iW*%M8ru8Iq^2zI3aE3kfPHGt&!9Yx$O%-s7}Aq!tKO#sdDr?yb1A>zyo(u4_+ r5$eB~Lk4Nw1h9nq@2Wo+m^6O?V_bGuj^r&O00000NkvXXu0mjfe?7R4 literal 0 HcmV?d00001 diff --git a/assets/dolphin/external/L1_Kaiju_128x64/frame_39.png b/assets/dolphin/external/L1_Kaiju_128x64/frame_39.png new file mode 100644 index 0000000000000000000000000000000000000000..7510931b44bb100b314d9bc617843bd51a2cf164 GIT binary patch literal 1438 zcmV;P1!4M$P)$~B7-|wG(!YA*5C(dt?@6`<69HDoHRyL1<=sgX#!|F#% z?fe-fru-e}x9aC31oR!D7xe?e-#J7p0nR__L|VYLH(6#nfo6WnPE>hei-ksqb?`NA z46KaW30~tz#PA&%z#}K>0C0d(aHVlOic<1@->FK-VuDfUi*^FexnaGT0WeTT;M#MF z^fCgcge>}}*0&1-K;8D`FavlX?f$-vg%PmvRyo0L3;;J4)bTI_Xq5tmz=ZDGw7QuL zU|})}J2C);DGZre2=El}GlL0hx z^?zgXrQ`q}NK8QWp~`G0z{awMvr#8#b5inX{n|o7Zpb^iq;4bg;5%`FiA9|*c_b$c;x%a0ie*cSpg!#XsZ~Y&0Pw; zks=rXLSh}P?bU>W)P!}&bP9|bM~z1@K;}BQB&@IV!o$VbKupgDk6S(!?WG}`VA0PDQa<^Vk|j3zR%f@Mx%04a$~V*oh# zP9Y%jE+BHJaTsBMsJS)w01elUaX%VR*%`+`YrDSvO8s9?H~ws_WB^SL&^u_Y_46h$ z+Z#ROXJ)_|*qs5sj)9s^)S`au@r~nh0ICC)7@o8fS7CPsfMAorjQHfiNnv338~_5% z0kWPv!Esl4{>-O=n)b_20hrKHXYe+b=k+XP9s`ff0kAu14=k5T)~n|ea2x})Um}lz z-lHDZFCsL}$Rm!-0U9tSusFqtf_HryX~ikYYD4(j!X*Rl`rIK3mdz6FEFsSVMp=LZ zH2xEIJj4zRz{vn#yD&p!7zaCIj?Sa$3t!LJdE9&yvShGc>ysg%A0+Z_K$GZYv%*eK z12z3EPGw!&`(xsw44l2gdhB{bD8*uHnThuYMPkbA>o{SW(HmP}ZL#s6mIIu)mXA*g zm7D+r_Kq70ZLHp5MzJFcz^m`kG7~S&gwZ*G)?rQq_0FRsLO_GZ*!`|vu^V?`ffJpY zeLnzpG{k@%wXph3SWXbx&T?D`z@Xh#eO&MByvCogoBJ@N{n6mW5J0{kz%qGjt7V8R ztiD~`B@|h}eqVrfLD+7YZH(DQz*yp>5J2Vt4cc9W9Uq?p%n(+#lOEM#r8F1T2CL(2 zadBP-lR^rVf~3nMNjNVeLV>jVI74G?y>XoiuhzVT0{f34QfDtkX&Gh2fYfekWB2V~ zU0;v&k>-WK#@2+48DQTJz!?BrfCe*@Gz}BXII?oi)H@*Ov{_Jv01lMEGicZnzIM2) zfU>QYqm;oAPzs(WaJhqap^^hxlTuA0Wf?yTFa*s$#kfO2DK-c3V1z|R4d`W`kqfXk zu5_;wiETbAmV-wTqYj|We;~X@lR{P&YALp_jvawE4nqZa6f(MdX2)a;n_BV)Nq1?V z4*-S4jyN+jZ!1Q3a%Mkkh~RXNerwnWFz>V)eRX0sg4vE^1(YxJ3nNO2JK~&RYz$tx sXXQDt&#(hXhCl7;*eZB(oCv4+1L}9b5t%S*1^@s607*qoM6N<$f(+J@S^xk5 literal 0 HcmV?d00001 diff --git a/assets/dolphin/external/L1_Kaiju_128x64/frame_4.png b/assets/dolphin/external/L1_Kaiju_128x64/frame_4.png new file mode 100644 index 0000000000000000000000000000000000000000..f99454b164c598c8b5e6ae11d8d9864b7e3077a6 GIT binary patch literal 1284 zcmV+f1^fDmP)#PQ8w{{HVu407ihiAtVW;!`7}vtu(r>w;lzx{D>EzvbeHm z=LIkV&}3)^cp@f!-vX`xq--vq|D0We&S?z^&=9by974z37NtkLfTnypKk5NcL>g8F zoCaFc&nhP+L_>&nJsV0=jUakRCpSMNRLkvAel!GX$z>#u(n6G0k$4Ds0L`sPF^FzJ z8f#%>?41qEk}V}>EMH0>>F0nr47~bZOWs;6KU;!#5dh(uDk2%I zXH7fh1X=GTDNZW?r19Q9x;ufR(Ayx{N#PV)EuWdIbrY>MwCmQ`ZURKyZ%g~rYIRDD z4sFhCWV3W>ZbW(3xQthZcmSzv(XRKdf$li=!U}^K59cX=RE`4=0qA@HA!7wOq}H#O zGewk7KU>xx^#a?y8+c;r$LoCU9-^VpQoaQ`FIs+X)d!Gz+9mSh}WX z`P+8_NA(m+S<@HrJb{$MWG!D(I{h381zUuG8OhEpcs=_FJmpIkFXai5JuD?a??LT~ zmiS%gMJ=Dpr^KUs@USEV>`<@IfE9~9;%9sRk-mw9sRa0n;-kr|l?z0}0GE>up~DG~ zZHD|Byo_8UfplFfH6y(P4MPaf(&MjVQB9!MIE-9dyH3G-2pL&i=9E@&l literal 0 HcmV?d00001 diff --git a/assets/dolphin/external/L1_Kaiju_128x64/frame_40.png b/assets/dolphin/external/L1_Kaiju_128x64/frame_40.png new file mode 100644 index 0000000000000000000000000000000000000000..a17a14044a94054ff24eff8c1b51bac31c273251 GIT binary patch literal 1438 zcmV;P1!4M$P)kKQKvOJQ80A_|Ne}^p9Gsmcu&^)qeHk^&j-j0Un{- ztN*$#I*#MFweV$t57ZyB@A~`K6=~aR?eiJADE$>J*S)%}(*M)bh1E(P$omofqbRRj zq<*V)?+l^sfqX8n-5&kX`8lPB^)7;CM8#xe7NH-P#mdExY`&?c|?LK@#*S2{uUqHEZR0r;Hvt;qmfs07V1`aaTluP3fz z02Fp(0KVZ`A8VdY-dURDCRFMp?fTJVS;nklfRUXM?8pEks0<)^jx^Ys3~OxlBt)EG zh6zUcdAphcMz)RYd}9F5;v(sD2L?c3f^Z}8}S zZGt04qG<3=C$M5OItQ4s55fQ(T9}ZOSI6$V7@+AUdUw+P{VW4;Sga%Ug*t%ru>1j# zIe^C=Nsf0yXP_lv{d+UHLWP|W2k<0ovz}kU05dYJ1&AbLy=}^4 z>&LEif>{P2ir>Z}01p8~@Am^*Hp<6HPJpmyX9nQ!&0;2u!cPG_+m3oKIuVrYszfFS zAd26}X5n&xY$7r<7PV-780g=tLWTiQy0sjD10DiKED!~9$4cR4RtBnH-+xtjl2DQZ z^q6Ii-hrNkI~l-}1MvK;+yRK@o#1JUPqaS+gpYwU2CgW;?27+B2at?<;!d8$?hL@O zECfXGWQW;32jEa009l70^|=F;4)!q&u%Zf=-36I4@r*8{?2pa?ybmW;45j*k#v~OJ znZZXe0OA%d0>o*-;|MEqi;v0yRzk`dc+o-|w+nW%#e+8o$eiCjW2El}a6~SZ_`Ukw zh%f-!UT6+bQN-c$D(d}rV+T7l8~A4@|F9|{kz|jY3>g9>**o0^q7h~Amwz1UU7)Oi zO*V&ifq@JGJKY9)#z&kg`fTd&1kQX9pn8XCdUt^pi=%BNP9oWJ`u8j+@EmC*HnBYR zX{UglZ1Lih7KP}2F*OSIdMcMOQz(-3Yxdm%p2K9@O8ka^M%~wSl~PZWkJhon;`7b( z=nxPApZtoW-8Tf(;6xZbI>u!kp(+GaFVd4jz)6%l?)4Lopsq|6GNL02k9_WosJ0R> zAwZjWPq9U#=^1=OKs{dS0NG4mO7603V6h4++#vC!5b*MA;q7%h5%ebm3w{44XXT=J zD`=HAp-%x^uB18HFxH( zh0lT;DS3P4B(DeoNWGD9R_UEXoAcuWuY%;A(M3n!DXhe5$BBa52g?Dpg})<-y9h($07*qoM6N<$f~i@aj{pDw literal 0 HcmV?d00001 diff --git a/assets/dolphin/external/L1_Kaiju_128x64/frame_41.png b/assets/dolphin/external/L1_Kaiju_128x64/frame_41.png new file mode 100644 index 0000000000000000000000000000000000000000..f763540c917b48c20a54984132b516ab47935de5 GIT binary patch literal 1412 zcmV-~1$+95P)hLzz;{h#>kuQEvwZiy!V{y1I$Kh&bN6xMN7?W4b5{{c@8a0}g5 z{pWeYaU9>RhKB(@P`}H*^XsS6(~j@b{fOKu{T(gUy}Iqv|H5>kwOjD4%Nc(VOvd-gHAhx$N z2sl|o$EqM0I%oD+>@x*`Gzrqga>iFVf5@NN)y)7BxO9_E7m}WF-#U+O2EYc-u1gc_ zF|vvVuM7e$H&@pH5&KFQfI>^H090OC0BF@F?l)^IozJbX74R^?=)bZCp!S&qAQOS(AtV{YS-5}3d3fx~ zAc!&mfd4eM0_7)voizGYf(hfX!% zWV0{@K(-KxjIDASP6PN_7cvY`rCX{2D9Tg7j0L=?T(MkwiOQ(zhx@NePaIlm0E{Se z-~hT4u4Dj94M6L&_5c8g2f^K(53oN2xL*S!2CmqE*%g1j2H=bu4@+0aCkDpu3_#Hu z0M=Iae1UN$~54ZF?M(0Uc1UuPc!LI=5dVlBS&GdK< zmFT(p)$lMtwY{Y^K-VUYM12{ZJ2)R;4?83q=)E_+S#kOXkjrhADS+E!*y%K|8eRtf z?;nR+DVkF{`p>}0n#t}?0Xv-rTE=^V%KL2M-wCw*9sqaVKEseTJ{@lXJ3!0D-nJ8O z06uc?waNm^^H6tt3)smPD_$He&(gsRcvV+U0A?2NdBT;THB7ec#CHn7j*o2R;!k&> z#bJk)M}zU!DZmO$dliObc~1)H$GgI4?Nl!lTtjZ=meV(^~{$LXSNR+k$qXt@c7o&Ry z1G8PmF3@@;+e*(yuS zb+9OzRp?qxQH9wgSF=Zj{GF(Oz?=eR;I@mUEoAG&X#r$OAsKWyA({d@5l#UBz5t0J z!y;MciKc*^ict%;`K3?^k=2lOgth*mh|~sGrho&$_n$^(Fw3jlby{S0ZVYi)y^=j_ z>Us6m=1%=v!BJ2nx#;ek|`=|f$13@63_$6Fk5UBk>stGx zC~Lmx=#g)Y?v){o6v*fD>g|yqwa=3p_B_v!6D%bvj4|T`dfzNoIzO`bqIy0h!;Ba~ zo1ET9&m)b6bV3xf!B-vp+Hq~($8j7lj_)VwF^h)i=YAjkeb!k~8bmo=!%hr9?J*in z29Q>AKc*=`gHWj*Xl^k4fjLvX(LkBY2!Y(lde`8DIpJ z0jxw4Kx2W3 zG3Yr?zuA>5={g##gFu>#r_1Uf=rTw8c=U5KfTo0%0(canR<5Q`H3Mjn(#>qT(B$;< zUOTD`P=Sb&C>p#n2&~+Ut^qRoL2H0W3P3V|N3Sawpv!LUJxJ;CSq9*+SVy`R5&)4D zfUE&LdP(zm4Vr;ggwbP}TA@PE zcvif1|4Ihn^N9=)HB=-8WUAr}q!qRT5eDejudD&MeoIq;_8{F^^!gd+(R)`0L6!kp zvlmANUIHL%ByS4P=H@vR>9pM$fFH{ulSY^C0xX~l!LHx#3}6+JOBf&uuTe7;hH@HB z1N2xGW*7h^TdM&$mN$YTbE1qRrI+j+sO#wUtJ0H%-vG!cVy)7dEli)Ya+Z3R|Ql_d9)aHt&ikU83WPUXD zk8CepBOOy;26?GnTWzD_%+uuYH~^Jer0cc7)okNAhgiv@^on}tpr!yT3bPLu-C9~T z#tcR~7=CVs;dZ3{4mAZ>t=*1@!V%iOqPr(O7fO$vs{amG3eaE`Xfwu()*W2_EGn62 z7r0Zv2z1LO^#iih>FGacm~|SRAGIPsDh0F_3y=(ESY(y~vg~7}O^f;?Iv}w8yMi;w z7y{LXj-Jcx4tTM>vi3Pzi~YB8Gw{AM;6}(81(^a?Ai}26EwtJPsCrPYq!jIyMy^f) zXt|O5qQ$9Z^Wy}2L5j|()6wq~R$_JFM8Wlg)c~5~uPEZK0^-G2r7V8WbO2b6|KvS1 f5}6tY5j6h*`5Py|3n0fx00000NkvXXu0mjfU$&E9 literal 0 HcmV?d00001 diff --git a/assets/dolphin/external/L1_Kaiju_128x64/frame_43.png b/assets/dolphin/external/L1_Kaiju_128x64/frame_43.png new file mode 100644 index 0000000000000000000000000000000000000000..7eadf75185ece2ac3ebd0906c97d054942ac276d GIT binary patch literal 1397 zcmV-*1&aEKP)RCt{2UE6Z&APj_z|NobL9y**7Rp`bF7P77K z&+{y`*8io3hXFoNzDvLJ=iBKi+h?ghGA>GfMoDF_F0FL3a3@}0(1N6#Bf;A;pGeCq1BnCt|cf|Qex{dUNGk_O6FaQE0 zhgit~7QOoKoPH1n(CR4tMpy1=5%Yp44}cIB#H*Fbb=;Fa!^$Gi|Pku08a=&GJuAw7@)~6<*$?W&(Vud zV;!#Tl3hUG7nuWCCWISjhRrl^E0t>#$rUp6JiIX}g1+w#3=kPpd-u_b*K|Y9yC(-| zy54#hpkYN0U|I26|CJ0t$2(fZj1ry@AjK)9@wpYY0v-lv?N{aiRKK?*Fv|m5e=U!Y zoFOW6wG%`cpcH*^WZ<9=B2Hip0g?e|3`H7kcLt!(qKJgiqbZ?zB5D^9eTf;|fdRB6 zav1|~f_fT_Akr6Qv_1^<&$2MX04Ui~4nV;sft<1y`X1FqUJ|)tx$qJl1J$l?zbZU& z_`?7rtO@~i%*@rAfh!rnk^}VfS!;cF0Io426OH!0oAFE8p8@`C0}+E}gn+x^wmCpQ z2$win1XG|-vF?D~8Gr)902;h6cxQ*%JqMs*9l*N<(~gL}N66X8bg-{v0PXN1TCZW| zm^dN}Irg?WKtI^b9$pjN*N?U-)=lxe>2R*cd zxgI74h+YR%!L;4TxsV}%8+)hQKs3D9=t~ZQdPvESbb)~k0Xy9WTKapO%KL8SzY{3M zYpTQ*G`IuxHfXWfTV?{j4IF`^CC~2+?yw8kNf#@o9l%37bb=xWMVx$Y>?=WYnAtKD z%l}ktyJbYv+YZL3O!##npdn*x_k@5Pq+AA}jybbJK(>+Y6auCkfEortU0kwgJ!kO9 z@WL`acPD}=VCE){_T?NQY9y{7o!n9Gu`-F`aJvwI za02dmHb%L}N*y@)XzCw10@sFnCSC?ff@UVrddPz`lH?FxmeN+ARF7QAqwtElb2uzU ziq=d0v=>0;CT%?WOq0d+=jt@tIzIE zW>BkqtsOb@uw?%h8AvSuK}ZCVi9jZhp1R2HfbPUrhNoJJ@88DFzu+iX`qTMD<>k=g>ZopM=qY>6!Qg9g!Rd;WYmMkIM6+eyIw200000NkvXXu0mjf DE2n)B literal 0 HcmV?d00001 diff --git a/assets/dolphin/external/L1_Kaiju_128x64/frame_44.png b/assets/dolphin/external/L1_Kaiju_128x64/frame_44.png new file mode 100644 index 0000000000000000000000000000000000000000..5241195d32bc160a3f8f6e1f04eda860211538bd GIT binary patch literal 1217 zcmV;y1U~zTP)z1 zai;(_V&x3?A_cG!Q8PSJNGX5=5t%Cfg)zMlGcyrAyx~1eg1#>WU;qzzZ-7T9n9!hl zXFDpc6aWD9I2r{#UiMVfTC)Zip;_t7Ol)Tq??mncI1qW56A{5mk>oyr5i3sejzoaw z?HS~GfSWO!4lE+!SE>CJfP!5=m(axE6$y1N`uhkf23nw|02o$SKL-s6vP`syfv-OJ zk7Rh;DS!t-3$$fP$%UmkKzp15aN@eIUw<<^4N`qDdYwZHwsw7m0MI;Z-JYd?RuOP( zmS%46@u+X;^%Vk`-HxTuL^4y|k8E0cticle*Em2FMh@W-f%I!;BzP#_i1&2@h}dn5 z$o-{Yg_?HlaccLc1C+nE&x@=(V6|<;0Z`r}1rWJsepk>bqJm$FZ52?;q2~dtLF)}1 z6%(4{dt4qtMFpSs0p&ST01|owBt5S!tB@T!sV#5t>3e5`&-;h)e2f6JAX}c-c%*xH z8uA9eaYY2b6wLN1jurr7+5Fy_nW}L|AR_o4o+FFE2Fu_)q1fv|tKPjlsECdhfEN*K z_-IJgyO)RZjd+d}01sX-n9}xXt^fD$pCX2+6lE3Bku?DSU`QPx-NS1Hlye2FOT8$b zBORc@;sg!aR%&wv?hdA=c3!v?w-vwBBwhAC>R%wBk zxak_3-h0D;wbdLkj`}li!LHIO5tO|Z9n^pm|K`Mk9F3HlZeV~xG zcAp@KmBBA1NC3znaVz#>wAansMEC4R!n{KWTF|Wh=i zM;3szZAF*6IM?zXre(1B*(M00000NkvXXu0mjf=Jgy8 literal 0 HcmV?d00001 diff --git a/assets/dolphin/external/L1_Kaiju_128x64/frame_45.png b/assets/dolphin/external/L1_Kaiju_128x64/frame_45.png new file mode 100644 index 0000000000000000000000000000000000000000..2a3ea8e23af713aa1210d6e19693e576aea86d6e GIT binary patch literal 1177 zcmV;K1ZMk*P)Y8+afiT?l%M3TOcp1*+Q}B7m0ov{wHCARx)QRU}^y zDG{JI8m0bO#(Cla_nTl`xsni8G5oidK!B{!uO(MnGP*M|6Y6OK+>4?X*OP!E1R|julPl|e8IX2= z#ChYr8BxSd0M4NC_tK&*MtF8^h0uCCd#nl&j_-emhMNGKK^CJu4`hY$9$2DGPlEnu z4+*H!v7Zwi1=4Z=%J|uZKdmNu>v_bhVylF-)Q^T$2+b%^JDa)&<$Nx&MZa3N%}2wY zdZ(~=hLqe&B2-TvX^!#x6-fVR*xNvnz;Yy5qQ(uzJMTv*ZI=!kE|vAoj_#U7S&srf%c%ij<7o4(pZa-07?L@ z9EqOuqoGu%jGG@FW>@q(xWrD|`5s##1h6D4BP8Rb>&LI--=%vIu zb_C3jq2&7jJB5Fbpwk}%GnLbQU8MUrqErOf#qm*SjUP*Wk17Qp?FEc@S{Kg(XP2gu zYMRJ6{tOAi{~y2uZBcJ_zC}vDVRbw=j|U+Fc$vz9DxV^dTC7MQnlThOk;giZ=UPY- zc!!=D^q~s@s$ulT$U=eAA2dL70Pn7|$fn#JGvj>&+|qQG6l~SRxxdXq8Z)CQz{@~{ r<2}3olzuV5yMa+>WIFU51OMX}ZL*z$)XYxz00000NkvXXu0mjfwJRcX literal 0 HcmV?d00001 diff --git a/assets/dolphin/external/L1_Kaiju_128x64/frame_46.png b/assets/dolphin/external/L1_Kaiju_128x64/frame_46.png new file mode 100644 index 0000000000000000000000000000000000000000..f4b263b199c8402088ad99c4dc27ab3c38f0bf2e GIT binary patch literal 1300 zcmV+v1?&2WP)W2D-85p<^O-V?-LPnye~A&P*RkfIgD9c7`y0J zKF{+!ki_Tn0RVskQx}Wzr^3i^{3XJ9_^;B~^E~i8&tD>3?2l3c3|tbNgBAh+ToRmu zHUa=#5}bfm0$l8mb^_ceus3c5_;Hlz02)RVI9(r@BUyGXm9{ciLV$0|FFAK((;=kcky4*qM5*a_JDt~((MX(7Ka6%66%u8}l@6alov2Vl>~!z|;Tp^-p3qa)`x?rZcvuW3~z zXo&#xq^s0Fiyg~Ca665%VOiX{4Yoz~r6tN-oB8*1n{0$FCjghdR@jWTqZZc^q2|Ty zI?620r^Zx8f;J&&weu}D@ZxzFOd_@S^YOcg(`G_uqwP_*fzo1WlaJ;k)b8STpCp87 zM^A(dn9y4gpeyui$yFplvx3URtFD7B#FW}#JKk}H2{3nv2ZtA|;~JRTOChE9BU;dIhRXBHMj{N)ui+1(x9s{`bgUh@Nqy9olEMdb(5+Bs;za59=Hi$VW3sb zlF$(~GQi0eM|51Tdqo^g`mL@++HwFbd9v7(9qADQ3rV)UWcHc?>t$KzfA>_m)jyzVvXL5;c2(UuW?}j9T zQEdS92TJhI)+54-R|#Ns`W!w-Tk2xQVk-j4p;lc$x+{3Iyj?~BZc#k2*4wLqL;4tl zG|q~|5r3A60__CICUE$Yg-U)_z*6r6z&~xM`vUxLtzW4hJT@cHu&4^IV_R zVb($d@As&-ls#?dd*)jDZeS%UO23Zsk#YuytdlI|VpdJuQU|EmtzC)Ld>oCRJH{Y6 z-y=6`*e(Kiq)@A!t|@vPTyZQ(k!RZ^&jc!_#2`F8$R-)oEhC=qz$J4gu{|xeA4qX+HE?~YLk;|sG7eg%2SUPIt`A^2)FThKJ zHYwQR+>TPva(!9>Ygn#2CcJj6mqcm~5J^ZpgX3&RNU&=6TbzKU+p4j7NuZ4(904>X zkLu7X`${$_L?ey|RhKZk^c}7OBvp$-l><0|WR)Y{%rQFpPA7r0_%MLapNNAxN~>R~ z20SQ}g7Mk(4Yz#1fYQ4FT!KX5+5NZl%b{Ec$U39bq4ya07ykon_@I`j=(wH$0000< KMNUMnLSTZO1z`dJ literal 0 HcmV?d00001 diff --git a/assets/dolphin/external/L1_Kaiju_128x64/frame_47.png b/assets/dolphin/external/L1_Kaiju_128x64/frame_47.png new file mode 100644 index 0000000000000000000000000000000000000000..1563ff39b27a83826ad84e5eb30d17b8d216a971 GIT binary patch literal 1268 zcmV6ZXSuAvd3*nNy%ItPdd9U0;0d7i&NS!1k1c?I~Od5L9!C@=fQ z>HGTn9vNe|_qR4dfNaU_`=@=oQfdj?Hude28xpzn(sd-eLk1n|Vu zlSx459vx!({^{@DG5R*6Aps_UC5PO#hy`0oq&}nfj*qB-WcCvvA zgnmz-O*(Cz&=4YB_l6RP01~U{|5NGYn5kiB*oaaqWZ}8E0kouMv~ZINssP*; zjY4_`YIw<$tsG1W0i_Ax$!04Uo}xFtR!c$Uf94sb^_wCio3U>8hE$EoZ-B?25BDJ zz0(9hk}!?^5@wWTcTyNV1b$2iq(u}V`syb>Y zQwYlP{FRFG8Nj>u|6pbQ^xl3yla` zwF3#^?*{f0()t)Fmqu)@vf(8*O&UFY(LR@yf@k9^68lCCT?vR0`l8L(=KHK=^&E*t z=P>>E0X&n@uG2oa$?s0;ER2M;9&}B$wT&Wt$Z>FM`ol#@uvI*%0&Px6NSfI_coF(y z2n9W~KoR|rQCmz6i1&}?BQtF+mKpA0RwedaAfL2(SB!T}MxW$!rED_d@I2|W&; zVY#>MuH+Kk_GTbs?9fv1uG;%b?0mM2u}ge$1=;$EP)YOFbE}8|NocMCsz~!X0uIheWdDkG7eriteMd~ z@B6+`faiIjNYuqf{HhZ4zArq_Qzh~%sUJ1+ox}HHQ2jDjKJWu&%Emqd?aKC^s0VL&D!zxo6 zw}Tk7YNxC90|aw`ZpvRR;{=8$#s6Qimt|#OHS0B5vxBk5XgZ%~57Kz=IgE9Td+7c2 z{Vd!BIAQ(TeDC|JuGcz`q_~~#+cK9#j3`Pyz^?v3XA$)J3|33>kbv92bxoS3b8D?4 zXBh#;LUum{iX6Z!VdLho-ZS%7k@b!FDG@42P(}dkGCM=Ev;l9s7muN`xVboaR0cN& zzmLacNl@Ae{F3tVLE?WH)cvl?bv$vMBU@%|?OVZB2^jWJSn=MqNC)k`j@RVHSUW8Z zBP4JUfYzm7LqzeM(mCssWX{Stx;76gDgsjupp{DF`YikH(9Vs@=Q8oC$HA6rL>oip zc-LhjfQ8*r85k?QN|s!dFxf)v!ugU8)VP6Bnt5Jk219OqFMHKNLEF)Xl>dKTFPL;mF$zs>CM#C`Ys`J_!0yM=}g#fLt zUI8shlh$RGA<2`@v1Kb*v&L%oueD%TB3jDPa3VqL`L}BX0oYvdY~kLH;^|x>>Io!e za`Ao^0=7I0$keV_hSny{%q_`WK@LmnmyQR>Su!O=Hq5!JfKhTpG23WV_SY&2?EWne zo5po4WBkqJQQ;6EC0a9AXi=18QD15kV`$F@1~}zP`<40%k$ynQ<6rJSM9Qv!Hn zde#~|_jh;yC*UPPI0Vp47GIBIr9!L2fYtq1gb8mL@Kgp{lE9w^i!y2Jwu;yuGFjHp z=G(#Edru{ol@F~t%zeKd>_o?Qa|SJbIC6*eU+_5oyMb4kXYsk8jk|=Y#nO+2ab+UL cRpxp80Znqgg|Y|Bf&c&j07*qoM6N<$g7rsmoB#j- literal 0 HcmV?d00001 diff --git a/assets/dolphin/external/L1_Kaiju_128x64/frame_6.png b/assets/dolphin/external/L1_Kaiju_128x64/frame_6.png new file mode 100644 index 0000000000000000000000000000000000000000..3f84ad47e3ded623ecc0323b5d64af350fd1e61a GIT binary patch literal 1312 zcmV+*1>gFKP)%Q;16>(ix1Bf|z0Dlld?)z@nbsKnc*=A;H@KC&0nG zFogie3%m!%1N=Cq5#V@%ci?z{1inPb;jt5BMDJ zQUE;}>`FSPg?pkz0BK{d>w4veb0WWO{#m36pl$x!(C4hJWfl>r{3pqmBES=y?~$KT zoHnMvKJsRn5J#`qbh(NI z$Yqb>J{`-6Fp~r@0#J9h0^F5KuaCep@zGeTV(=!79%w|EK>}z9c&ZGHDur((C2z%o zyG$+CkH$)}_?*!s__E7ZrO;j(MC=-u1Dl+&n*&+yhOIK;~}TCjw)OP@N~MG(!^0f}^or zlAVeDsGK1KND|1c!m_lH96HVdf4`E&YjcrYuqSLp?vovd0`#k4^pU@wm4}4YFX-<} z#FEHOU*rGt`)K5pEM3yy%<5`NCvcbKFrzrCaLFUl#*CD-NptXS{u7w;)vy(^qMjx) zFD?0#Hr|@Y?wjA*#M8hPn58)0)znHcj|}T|@8-|+tgj}(Y)G4J#bk{%9XnZm$JPXR zstK-6lr-Z&Z(u{}whG@d{5F(Vz!t|ZC?@VMXT0SX->b>g(n z*%O_#D6IJJ^)Sm1gGLx7Nr=hvP9v)0Xx&eX(exVaI?eheIT}_}3h)qs&Ib@OP)gJ+ z*2;w>S6#_tEK+5#-3LN;Dg9dWe>~e0;yjzrWm**i>WpBkK0s7S5xLdz)ZI%!Sf!^t zv^-4)+Yn%8yhDX0iv-#R@mwG?N6GT7{3C)bLO`S}dJ0|Ho|?SUztGCh$Vp=aTl4{T z+Gq<}`9?9y2S!~^{#=Xss4)2m0p7Op6eADdxh~QHM&X+0)8uGp z5%hgJzCwa90V3|pD-RhGtTGG@uWXHsmM7r%kj5ZN!s||Irqa%&GNL_lZ@uh!y#h~5 z*7AfJ8MG48yY8@e$`XLyoT9S%n#>4BH986&rF%EVV@$J1P;LZu_Y=Wrg4vB)SzUPY zl}N^~{dtW+N*+Cce=)?usFNni;|kdksN}VJj|>Tx^#M>WcvXy#VD>piM1C|e91>vE z+VqY`hlwcA)qqFVQ)`HjU`T*b;-V!UU+VgCcoRVSSkXha-1D@ip;Z8nK^2*ZYNB$j zC4*um!6k28UQd+({{?|8KGS7;vhnnGEUf|#_QO`c9D1yIJ! WF~&y6@>K)?0000&-uL|>!o_*$B0#|vZP;8qkLkA=s$H*W}iFLX*Ifg?b$?O@I~F zAC-@^7VYrs_-~DEMbzUU0DmC_4FtKeGOXm5=-<1L1-#=K>3(uq{CmFktlR(=0?LL* zwtuZdi5z<5Q0sA$#rJ^AufNZ(A(1Y-M;HNkHjI>6V1*saVlw-Yo*{amJpOCBfTnyt zzlEqhM1m%PGb;hKm2#In+WlJR6iFnl&$D^SN3?>A)%7S2C8M=k;R>_lXdz0gNIawn zpd~IB{{x}K=sX^Fq%Ng}PzccCik11cl!~jnVhGeOJZjnAvs=oq*Ou1Q zI7WB9Mx!=}ED5-rXvI?#A)QRVpwrb7vDTz2lGvffAmC-<+UF7(yz0RlBaPGa0R7W2 zX=AO29&w4*&nv(!Pbw!RrSQ+|Bvfh=)${q9T9?uSv@7#5dfL>dnJt3;>_j)qamG1ln|Qoqq&3hd3Psp6tYV5;^}I|6X}PY z=>SHQXN}7kWj6sL*4NVFmF7gssoAi+V20qH@<(|%hzE!?BoMN-xahS>S3qj+cp)>Q zeEzd#{ZTKlWh2NU5xV7!06%cc)kiA2$q2nj5BnSVW&ujyI7 zO3HT!fB6^IrACXaUKy?HW)#>mx6Id+o=FI|c_nOAPhmE^o_z!@%9lJ|WDi>q;8T=e z&=SAPyvUp~M(TxR6X7lT09qAsIw`DJ?2$g(`}}8%d!h(pl8d^ylFovX*W=Tnkz|X~=c8&n?t@wiJ!>rfCA84;EblN*6}6 z%S>y%$bNdNhb)>yfJTI@%ga)PyWLzi0xO?s z#M%Wiz|IeW_m7fKw)A&ia|2g!_vDJSL&07C;|NZy_mhDl>rw^mi00000 LNkvXXu0mjfjhAve literal 0 HcmV?d00001 diff --git a/assets/dolphin/external/L1_Kaiju_128x64/frame_8.png b/assets/dolphin/external/L1_Kaiju_128x64/frame_8.png new file mode 100644 index 0000000000000000000000000000000000000000..2c8cf3f5d7c34f1eedec4def10bb28095f2e1c4a GIT binary patch literal 1308 zcmV+%1>^dOP)2$7fJ|lyuf>K zJiw2mi~z?AyaUGr{5VPp@KrDHr9B-FkieISeF%`mS4eOO@Z-2gFM~KM=tX|{qUh~= z`#Un2+x&gs@I&#q+BYjG%2vq(` z@(qOm4d^i7QDSB-*6*!-GzCWXN}rdEX%-2>1XyAH+I-LRh=+w(7qw7?Qas8<|G z0cO?4^iVXSpywO4%zk`(&Fuj-rv>O+!syRgXdYn3yhwsm#nSb+Dym{m4lobEvH6RT z_Gr0mEAG>=lmv|&Rh|GE0^X+lJ`=YNSgRP2E?Xi(1qsTk02C@%-z$=OuMrDwGNo8= zjpbzZYethGlmpO3thV;HhUhxl0ZJ}7yD#KwHuoUYF4-%;&`2{zw66Jk>tTL_kYjh5-w6f;sNaP6{ksHzMI24B85AdHr;08uy zNs5ZhDRmjSSlwPnLV!0vs3Zlv3`8yzRr^N9Q!AI0-ky<&KryQPYHZ&JSOKl7vF;u` z`OhxOzpj@MKqg+#%W71zP;~ zdYI{#K@p(yfmP7Ddh{9TIm!AtITB`63fp})a0lf};4HT98E|8IS3OeBdSpbf6#>vC z&M2(9zQL2@L=|UM2q+S4(+H}ve1zO~@SY~n2ys2-p_UY8umu6oZjA!vNh}gb3hHx# z%sM&C*Yb}DmWF^xGi5cTjwFSo=!o*A^3&=rW&wXcfNN4Fu0~s;9{HnkJn|)IB#EH9 z#GV=gG{vJrfL3QCV0i$~bCC{U|NqFnga_pW(5w;d{JxA+J2~r;qx8QANaN{)j8JCCl0vUNyFTpwo$=&ya z8QEjF3TP8%VJ$Q(dqpJ?ap$y(;HnAjf=KeHoVSPq{#U{*ml#QaBK`B(;lXOmv}dIC zN#`b&kly`8_X@cVZWBvDDM0Fgt?VOM3X&AlTfaqaYmRI z5!^rTy0hWH^Z;7#+ZywR4j%%QwpV`vi zXEEa-QShvFRVa&ugW((?8mqnlPu5KvL8C;-#&>F*(irGv(8xwJ&6O3&rMK*@K(ssR zLCN0<+#xPkVRgxg#ui^3Im7x7cr5?kz@yByc-_~=9l~HSPbXFRCt{2UD=M?Fbt%N{r_KfU#hJj@E9Jlr9=Z1-6S?8i^D_X z9M^r{H#u=#7ZDK!PCZx*KarD~;|~$`$Dho}_kGiS-@imS*bgZJG#nD_ixL759TMz{ zG6E1C66}al0uUV%?1pjz9PEWD1UOk>AB1#(Z$(e)toBi9D>aXZ5(pc=u8$RoGS{}! zx||*$h-jHx$@xT+3GnH?fcN@Vb3W0@0BN8kSkd`JhX7xXLx2KUSzy)ZCwhPYpWX+| z!gXE0>(>6Bv5rRv_=jtU6S=sfx{GmW8J2e9^|Pwn}e)BA`(vVcYwX&f%KkFQHM z(b5xfUd4_8&HyXl^ziJ}qxLJJt%2(skn(2r29bHe1n{K2$V67hmJX?QuU{@*UIt=-{zAvm)K z!`QyFx1e?AGr%cv$j*bagNi{CnJTY!`X_@jo%agpox!Da%OT@76?OhonDWV>RWKtf zaE%{Ag8u(;j&C`iXz_OhX^Y|QF)9~UB7wIIzU_RXP3{Itcr)8bBtT(p7yEHE8`d!v zwkE*a7#)a~9L@Pp?--UY0V@kjV`FDUF(=hVN&vS*h^l}@$qX>7Zb@~tK@(is<0^3J zU6OOHOwd1%lmPTPGQC9lJA$gBbc`rOP~l!*p)b(Zh07LF1aptk5`p5?9>B|XPJMd< zT9b$B0=*s(?Hy(yO#meQYSAD;l9#pS=PCJgoZ~pQl>yrE(Z+FnE|UeyKOQczKWZm4 zz3RR|OV>TDuD%_EIA5|QJ@%5JyaZG&bhVA@G;1|`(mHse-g3TGmJlqb1I&_dtI#hx zLIQ2aP&IyEcD&cRln(Hg9O^;e%(cf7GGx}Y0*~BmVd_`Jc#z!-bM~?}JY!hMrs~m# zM>5v1LI-O@(CRyPj5dx3ZUR(BmNjATeTAnT zU2!vpL-wYR=h*c314IM~tuL_3K!kX2XMv{>DFtaMxDAG)pP*(lI+t%pA3#V?Rr;Gj z8k*pNI;rn+`+utdP0JN!V(cT(pT&1;%5cFB7JiT*piD$1&(|A0sN4@W-f ud@rh$#!tfe;m9w?Qa>E&jsBDV^Y{yo;l5Q`AXJb50000 Date: Tue, 30 May 2023 15:16:17 +0300 Subject: [PATCH 26/52] Add new ac --- assets/resources/infrared/assets/ac.ir | 37 ++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/assets/resources/infrared/assets/ac.ir b/assets/resources/infrared/assets/ac.ir index 142c49243..cfbe0ea02 100644 --- a/assets/resources/infrared/assets/ac.ir +++ b/assets/resources/infrared/assets/ac.ir @@ -470,3 +470,40 @@ type: raw frequency: 38000 duty_cycle: 0.330000 data: 4467 4390 571 1583 572 505 595 1560 572 1583 572 505 572 505 596 1559 596 482 596 481 597 1559 626 451 655 422 625 1529 596 1559 596 481 572 1582 573 1583 571 505 572 1583 595 1560 594 1561 592 1562 594 1561 593 1562 593 484 593 1563 592 485 592 485 592 485 592 485 593 484 593 485 592 485 592 1562 593 485 592 1563 592 1562 593 1562 594 483 593 485 593 1562 592 485 593 1561 593 484 593 484 593 484 593 1562 593 1562 592 5163 4462 4370 592 1563 593 484 592 1563 592 1563 592 485 592 485 593 1562 593 484 593 485 592 1562 593 484 593 485 592 1562 593 1562 593 485 592 1563 592 1563 592 485 592 1563 592 1562 593 1562 593 1563 592 1563 592 1562 592 485 593 1562 592 485 592 485 592 485 592 485 592 485 592 485 592 485 592 1563 592 485 592 1563 591 1563 592 1563 593 485 592 485 592 1563 592 485 592 1563 591 485 593 485 592 485 592 1563 592 1563 591 +# +# Model: Chigo AC +name: Off +type: raw +frequency: 38000 +duty_cycle: 0.330000 +data: 6069 7329 602 533 605 506 602 508 576 533 604 507 603 507 603 507 602 508 601 510 599 511 598 512 573 537 597 514 573 537 573 537 573 537 573 537 573 538 572 537 573 538 572 538 572 538 572 538 572 538 572 537 573 537 573 538 572 537 573 538 572 1638 573 538 572 538 572 538 572 538 572 538 572 538 572 538 572 538 572 538 572 538 572 538 572 538 572 538 572 538 572 538 572 538 572 538 572 538 572 538 572 538 572 538 572 538 572 538 572 538 572 538 572 538 572 538 572 538 572 1639 571 538 572 538 572 1639 572 538 572 538 572 538 572 538 572 538 572 539 571 538 572 538 572 538 572 1639 571 538 572 539 571 538 572 538 572 539 571 1639 572 539 571 539 571 1639 572 539 571 1639 571 539 571 539 571 1639 572 539 571 1639 571 1639 572 539 571 539 571 1639 571 539 571 539 571 539 571 1639 571 7361 598 +# +name: Cool_hi +type: raw +frequency: 38000 +duty_cycle: 0.330000 +data: 6073 7299 631 504 632 478 632 478 606 504 606 504 605 504 605 505 604 506 603 508 601 509 600 510 600 511 599 511 599 511 599 511 599 511 599 511 599 511 599 511 599 511 599 511 599 511 599 511 599 511 599 511 599 511 599 511 599 511 599 511 599 1612 598 512 598 511 599 511 599 511 599 512 598 512 598 512 598 512 598 512 598 512 598 1612 598 1612 599 512 598 512 598 511 599 512 598 512 598 512 598 512 598 512 598 512 598 512 598 512 598 512 598 512 598 512 598 512 598 1612 598 1613 597 512 598 512 598 1613 598 512 598 512 598 512 598 512 598 512 598 512 598 513 597 512 598 512 598 1613 597 513 597 513 597 513 597 513 597 513 597 1613 597 513 597 513 597 1614 597 513 597 1614 596 513 597 513 597 1614 597 513 597 1614 597 513 597 1614 596 1614 596 1614 597 514 596 513 597 513 597 1614 596 7336 623 +# +name: Heat_hi +type: raw +frequency: 38000 +duty_cycle: 0.330000 +data: 6098 7325 631 478 606 504 606 504 606 504 606 504 606 505 604 505 604 507 602 508 601 510 600 510 600 511 599 511 599 511 599 512 598 511 599 511 599 511 599 512 598 511 599 511 599 512 598 512 598 511 599 511 599 511 599 512 598 511 599 512 598 1612 599 512 598 512 598 512 598 512 598 512 598 512 598 512 598 512 598 512 598 512 598 512 598 1612 598 512 598 512 598 512 598 512 598 512 598 512 598 512 598 512 598 512 598 512 598 512 598 512 598 512 598 512 598 512 598 1613 597 1613 598 512 598 512 598 1613 598 513 597 513 597 512 598 512 598 513 597 513 597 513 597 513 597 513 597 1613 598 513 597 1614 597 1613 597 1613 598 513 597 513 597 513 597 1614 597 1614 597 513 597 1614 596 514 596 513 597 1614 596 513 597 1614 597 1614 596 1614 597 514 596 1614 596 1614 597 1614 596 1614 596 1615 596 7336 623 +# +name: Heat_lo +type: raw +frequency: 38000 +duty_cycle: 0.330000 +data: 6071 7300 630 504 605 505 605 505 604 505 605 505 605 506 603 507 602 508 601 509 601 510 600 511 599 511 599 511 599 512 598 512 598 512 598 511 599 511 599 511 599 512 598 512 598 512 598 512 598 512 598 512 598 512 598 512 598 512 598 512 598 1612 599 512 598 512 598 512 598 512 598 512 598 512 598 512 598 512 598 512 598 512 598 1613 598 1612 598 512 598 512 598 512 598 512 598 512 598 512 598 512 598 512 598 512 598 512 598 512 599 512 598 512 598 512 598 513 597 1613 598 1613 597 512 598 513 597 1613 598 513 597 512 598 513 597 513 597 513 597 513 597 513 597 513 597 513 597 1613 597 513 598 513 597 513 597 513 597 513 597 513 597 513 597 1613 598 1613 597 513 597 1614 596 513 597 514 596 1613 597 513 597 1614 597 513 597 1614 597 1614 596 1614 596 514 596 1614 597 1614 596 1614 597 7336 623 +# +name: Cool_lo +type: raw +frequency: 38000 +duty_cycle: 0.330000 +data: 6068 7327 603 509 600 534 604 506 576 533 577 533 603 506 603 507 602 507 601 509 600 510 599 511 597 513 573 537 573 537 573 537 573 537 573 537 573 538 572 537 573 538 572 538 572 538 572 538 572 538 572 538 572 538 572 538 572 538 572 538 572 1638 572 538 572 538 572 538 572 538 572 538 572 538 572 538 572 538 572 538 572 538 572 538 572 1638 572 538 572 538 572 538 572 538 572 538 572 538 572 538 572 538 572 538 572 538 572 538 572 538 572 538 572 538 572 538 572 1638 572 1638 572 538 572 538 572 1638 572 538 572 538 572 538 572 538 572 538 572 538 572 538 572 538 572 538 572 1639 571 538 572 1639 571 1639 571 1639 571 538 572 1639 571 539 571 539 571 1639 571 539 571 1639 571 539 571 539 571 1639 571 539 571 1639 571 1639 571 1639 571 539 571 1639 571 1639 571 539 571 539 571 1639 571 7360 597 +# +name: Dh +type: raw +frequency: 38000 +duty_cycle: 0.330000 +data: 6094 7326 630 479 630 480 605 505 605 505 604 506 603 506 603 507 602 509 600 510 599 511 599 512 598 512 598 512 598 512 598 512 598 512 598 512 598 512 598 512 598 512 598 512 598 512 598 512 598 512 598 512 598 512 598 512 598 512 598 512 598 1613 597 512 598 512 598 512 598 512 598 512 598 512 598 512 598 512 598 513 597 512 598 1613 598 512 598 512 598 513 597 512 598 512 598 513 597 513 597 513 597 513 597 512 598 513 597 513 597 513 597 513 597 513 597 513 597 1614 597 1613 597 513 597 513 597 1614 597 513 597 513 597 513 597 513 597 513 597 513 597 513 597 513 597 513 597 1614 597 513 597 513 597 513 597 513 597 513 597 1614 597 1614 596 514 596 1614 597 513 597 1614 597 514 596 514 596 1614 596 514 596 1614 596 514 596 514 596 1614 596 1614 596 514 596 514 596 1615 596 1615 595 7336 623 From 4609d7ed93ae218cc1ba9533d19ca56e1f1977da Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Tue, 30 May 2023 17:14:27 +0300 Subject: [PATCH 27/52] Update FlipperNested https://github.com/AloneLiberty/FlipperNested --- .../external/mifare_nested/application.fam | 2 +- .../mifare_nested/lib/nested/nested.c | 22 ----- .../external/mifare_nested/mifare_nested.c | 1 + .../external/mifare_nested/mifare_nested_i.h | 3 +- .../mifare_nested/mifare_nested_worker.c | 83 ++++++++++++---- .../mifare_nested/mifare_nested_worker.h | 10 +- .../scenes/mifare_nested_scene_about.c | 2 +- .../scenes/mifare_nested_scene_check.c | 9 +- .../scenes/mifare_nested_scene_check_keys.c | 7 -- .../scenes/mifare_nested_scene_collecting.c | 4 + .../scenes/mifare_nested_scene_config.h | 3 +- .../mifare_nested_scene_no_nonces_collected.c | 94 +++++++++++++++++++ 12 files changed, 178 insertions(+), 62 deletions(-) create mode 100644 applications/external/mifare_nested/scenes/mifare_nested_scene_no_nonces_collected.c diff --git a/applications/external/mifare_nested/application.fam b/applications/external/mifare_nested/application.fam index 236abf6d1..5b2c0b466 100644 --- a/applications/external/mifare_nested/application.fam +++ b/applications/external/mifare_nested/application.fam @@ -21,5 +21,5 @@ App( fap_author="AloneLiberty", fap_description="Recover Mifare Classic keys", fap_weburl="https://github.com/AloneLiberty/FlipperNested", - fap_version=(1, 4) + fap_version="1.5.0" ) diff --git a/applications/external/mifare_nested/lib/nested/nested.c b/applications/external/mifare_nested/lib/nested/nested.c index 4d04b99d5..b289b74fb 100644 --- a/applications/external/mifare_nested/lib/nested/nested.c +++ b/applications/external/mifare_nested/lib/nested/nested.c @@ -5,28 +5,6 @@ #include "../../lib/crypto1/crypto1.h" #define TAG "Nested" -void nfc_util_num2bytes(uint64_t src, uint8_t len, uint8_t* dest) { - furi_assert(dest); - furi_assert(len <= 8); - - while(len--) { - dest[len] = (uint8_t)src; - src >>= 8; - } -} - -uint64_t nfc_util_bytes2num(const uint8_t* src, uint8_t len) { - furi_assert(src); - furi_assert(len <= 8); - - uint64_t res = 0; - while(len--) { - res = (res << 8) | (*src); - src++; - } - return res; -} - uint16_t nfca_get_crc16(uint8_t* buff, uint16_t len) { uint16_t crc = 0x6363; // NFCA_CRC_INIT uint8_t byte = 0; diff --git a/applications/external/mifare_nested/mifare_nested.c b/applications/external/mifare_nested/mifare_nested.c index 237eaef9a..bb6947a91 100644 --- a/applications/external/mifare_nested/mifare_nested.c +++ b/applications/external/mifare_nested/mifare_nested.c @@ -396,6 +396,7 @@ void mifare_nested_blink_stop(MifareNested* mifare_nested) { int32_t mifare_nested_app(void* p) { UNUSED(p); + MifareNested* mifare_nested = mifare_nested_alloc(); scene_manager_next_scene(mifare_nested->scene_manager, MifareNestedSceneStart); diff --git a/applications/external/mifare_nested/mifare_nested_i.h b/applications/external/mifare_nested/mifare_nested_i.h index 59aab5825..69907dcd0 100644 --- a/applications/external/mifare_nested/mifare_nested_i.h +++ b/applications/external/mifare_nested/mifare_nested_i.h @@ -21,7 +21,7 @@ #include #include "mifare_nested_icons.h" -#define NESTED_VERSION_APP "1.4.6" +#define NESTED_VERSION_APP "1.5.0" #define NESTED_GITHUB_LINK "https://github.com/AloneLiberty/FlipperNested" #define NESTED_RECOVER_KEYS_GITHUB_LINK "https://github.com/AloneLiberty/FlipperNestedRecovery" #define NESTED_NONCE_FORMAT_VERSION "3" @@ -99,6 +99,7 @@ struct MifareNested { NestedState* nested_state; CheckKeysState* keys_state; + SaveNoncesResult_t* save_state; MifareNestedWorkerState collecting_type; diff --git a/applications/external/mifare_nested/mifare_nested_worker.c b/applications/external/mifare_nested/mifare_nested_worker.c index 56d2f2427..7598d28c9 100644 --- a/applications/external/mifare_nested/mifare_nested_worker.c +++ b/applications/external/mifare_nested/mifare_nested_worker.c @@ -296,7 +296,7 @@ uint32_t mifare_nested_worker_predict_delay( } // This part of attack is my attempt to implement it on Flipper. - // Proxmark can do this in 2 fucking steps, but idk how. + // Check README.md for more info // First, we find RPNG rounds per 1000 us for(uint32_t rtr = 0; rtr < 25; rtr++) { @@ -448,7 +448,7 @@ uint32_t mifare_nested_worker_predict_delay( return 1; } -void mifare_nested_worker_write_nonces( +SaveNoncesResult_t* mifare_nested_worker_write_nonces( FuriHalNfcDevData* data, Storage* storage, NonceList_t* nonces, @@ -459,6 +459,11 @@ void mifare_nested_worker_write_nonces( uint32_t distance) { FuriString* path = furi_string_alloc(); Stream* file_stream = file_stream_alloc(storage); + SaveNoncesResult_t* result = malloc(sizeof(SaveNoncesResult_t)); + result->saved = 0; + result->invalid = 0; + result->skipped = 0; + mifare_nested_worker_get_nonces_file_path(data, path); file_stream_open(file_stream, furi_string_get_cstr(path), FSAM_READ_WRITE, FSOM_CREATE_ALWAYS); @@ -472,23 +477,26 @@ void mifare_nested_worker_write_nonces( for(uint8_t tries = 0; tries < tries_count; tries++) { for(uint8_t sector = 0; sector < sector_count; sector++) { for(uint8_t key_type = 0; key_type < 2; key_type++) { - if(nonces->nonces[sector][key_type][tries]->collected && - !nonces->nonces[sector][key_type][tries]->skipped) { + if(nonces->nonces[sector][key_type][tries]->invalid) { + result->invalid++; + } else if(nonces->nonces[sector][key_type][tries]->skipped) { + result->skipped++; + } else if(nonces->nonces[sector][key_type][tries]->collected) { if(nonces->nonces[sector][key_type][tries]->hardnested) { - FuriString* path = furi_string_alloc(); + FuriString* hardnested_path = furi_string_alloc(); mifare_nested_worker_get_hardnested_file_path( - data, path, sector, key_type); + data, hardnested_path, sector, key_type); FuriString* str = furi_string_alloc_printf( "HardNested: Key %c cuid 0x%08lx file %s sec %u\n", !key_type ? 'A' : 'B', nonces->cuid, - furi_string_get_cstr(path), + furi_string_get_cstr(hardnested_path), sector); stream_write_string(file_stream, str); - furi_string_free(path); + furi_string_free(hardnested_path); furi_string_free(str); } else { FuriString* str = furi_string_alloc_printf( @@ -515,6 +523,8 @@ void mifare_nested_worker_write_nonces( stream_write_string(file_stream, str); furi_string_free(str); } + + result->saved++; } } } @@ -529,10 +539,20 @@ void mifare_nested_worker_write_nonces( } free_nonces(nonces, sector_count, free_tries_count); - furi_string_free(path); file_stream_close(file_stream); free(file_stream); + + if(!result->saved) { + FURI_LOG_E(TAG, "No nonces collected, removing file..."); + if(!storage_simply_remove(storage, furi_string_get_cstr(path))) { + FURI_LOG_E(TAG, "Failed to remove .nonces file"); + } + } + + furi_string_free(path); furi_record_close(RECORD_STORAGE); + + return result; } bool mifare_nested_worker_check_initial_keys( @@ -759,7 +779,7 @@ void mifare_nested_worker_collect_nonces_static(MifareNestedWorker* mifare_neste mifare_nested_worker_get_block_by_sector(sector), key_type); - info->skipped = true; + info->invalid = true; nonces.nonces[sector][key_type][0] = info; @@ -818,12 +838,20 @@ void mifare_nested_worker_collect_nonces_static(MifareNestedWorker* mifare_neste break; } - mifare_nested_worker_write_nonces(&data, storage, &nonces, 1, 1, sector_count, 0, 0); + SaveNoncesResult_t* result = + mifare_nested_worker_write_nonces(&data, storage, &nonces, 1, 1, sector_count, 0, 0); free(mf_data); - mifare_nested_worker->callback( - MifareNestedWorkerEventNoncesCollected, mifare_nested_worker->context); + if(result->saved) { + mifare_nested_worker->callback( + MifareNestedWorkerEventNoncesCollected, mifare_nested_worker->context); + } else { + mifare_nested_worker->context->save_state = result; + + mifare_nested_worker->callback( + MifareNestedWorkerEventNoNoncesCollected, mifare_nested_worker->context); + } nfc_deactivate(); } @@ -930,7 +958,7 @@ void mifare_nested_worker_collect_nonces_hard(MifareNestedWorker* mifare_nested_ mifare_nested_worker_get_block_by_sector(sector), key_type); - info->skipped = true; + info->invalid = true; nonces.nonces[sector][key_type][0] = info; mifare_nested_worker->context->nonces = &nonces; @@ -1059,12 +1087,20 @@ void mifare_nested_worker_collect_nonces_hard(MifareNestedWorker* mifare_nested_ } } - mifare_nested_worker_write_nonces(&data, storage, &nonces, 1, 1, sector_count, 0, 0); + SaveNoncesResult_t* result = + mifare_nested_worker_write_nonces(&data, storage, &nonces, 1, 1, sector_count, 0, 0); free(mf_data); - mifare_nested_worker->callback( - MifareNestedWorkerEventNoncesCollected, mifare_nested_worker->context); + if(result->saved) { + mifare_nested_worker->callback( + MifareNestedWorkerEventNoncesCollected, mifare_nested_worker->context); + } else { + mifare_nested_worker->context->save_state = result; + + mifare_nested_worker->callback( + MifareNestedWorkerEventNoNoncesCollected, mifare_nested_worker->context); + } nfc_deactivate(); } @@ -1368,13 +1404,20 @@ void mifare_nested_worker_collect_nonces(MifareNestedWorker* mifare_nested_worke break; } - mifare_nested_worker_write_nonces( + SaveNoncesResult_t* result = mifare_nested_worker_write_nonces( &data, storage, &nonces, tries_count, 3, sector_count, delay, distance); free(mf_data); - mifare_nested_worker->callback( - MifareNestedWorkerEventNoncesCollected, mifare_nested_worker->context); + if(result->saved) { + mifare_nested_worker->callback( + MifareNestedWorkerEventNoncesCollected, mifare_nested_worker->context); + } else { + mifare_nested_worker->context->save_state = result; + + mifare_nested_worker->callback( + MifareNestedWorkerEventNoNoncesCollected, mifare_nested_worker->context); + } nfc_deactivate(); } diff --git a/applications/external/mifare_nested/mifare_nested_worker.h b/applications/external/mifare_nested/mifare_nested_worker.h index 561620676..2421b35eb 100644 --- a/applications/external/mifare_nested/mifare_nested_worker.h +++ b/applications/external/mifare_nested/mifare_nested_worker.h @@ -22,6 +22,7 @@ typedef enum { MifareNestedWorkerEventReserved = 1000, MifareNestedWorkerEventNoTagDetected, + MifareNestedWorkerEventNoNoncesCollected, MifareNestedWorkerEventNoncesCollected, MifareNestedWorkerEventCollecting, @@ -64,8 +65,9 @@ typedef struct { uint32_t target_nt[2]; uint32_t target_ks[2]; uint8_t parity[2][4]; - bool collected; bool skipped; + bool invalid; + bool collected; bool hardnested; } Nonces; @@ -87,3 +89,9 @@ typedef struct { uint32_t sector_keys; bool tag_lost; } KeyInfo_t; + +typedef struct { + uint32_t saved; + uint32_t invalid; + uint32_t skipped; +} SaveNoncesResult_t; \ No newline at end of file diff --git a/applications/external/mifare_nested/scenes/mifare_nested_scene_about.c b/applications/external/mifare_nested/scenes/mifare_nested_scene_about.c index cb07f81a3..9aa46f698 100644 --- a/applications/external/mifare_nested/scenes/mifare_nested_scene_about.c +++ b/applications/external/mifare_nested/scenes/mifare_nested_scene_about.c @@ -51,7 +51,7 @@ void mifare_nested_scene_about_on_enter(void* context) { 14, AlignCenter, AlignBottom, - "\e#\e! Flipper (Mifare) Nested \e!\n", + "\e#\e! Flipper Nested \e!\n", false); widget_add_text_scroll_element( mifare_nested->widget, 0, 16, 128, 50, furi_string_get_cstr(temp_str)); diff --git a/applications/external/mifare_nested/scenes/mifare_nested_scene_check.c b/applications/external/mifare_nested/scenes/mifare_nested_scene_check.c index 4eb344703..45837ff92 100644 --- a/applications/external/mifare_nested/scenes/mifare_nested_scene_check.c +++ b/applications/external/mifare_nested/scenes/mifare_nested_scene_check.c @@ -56,14 +56,7 @@ bool mifare_nested_scene_check_on_event(void* context, SceneManagerEvent event) bool consumed = false; if(event.type == SceneManagerEventTypeCustom) { - if(event.event == MifareNestedWorkerEventNoncesCollected) { - scene_manager_next_scene( - mifare_nested->scene_manager, MifareNestedSceneNoncesCollected); - consumed = true; - } else if(event.event == MifareNestedWorkerEventAttackFailed) { - scene_manager_next_scene(mifare_nested->scene_manager, MifareNestedSceneFailed); - consumed = true; - } else if(event.event == MifareNestedWorkerEventCollecting) { + if(event.event == MifareNestedWorkerEventCollecting) { if(mifare_nested->run == NestedRunAttack) { if(mifare_nested->settings->only_hardnested) { FURI_LOG_I("MifareNested", "Using Hard Nested because user settings"); diff --git a/applications/external/mifare_nested/scenes/mifare_nested_scene_check_keys.c b/applications/external/mifare_nested/scenes/mifare_nested_scene_check_keys.c index f0071b7aa..b06953eeb 100644 --- a/applications/external/mifare_nested/scenes/mifare_nested_scene_check_keys.c +++ b/applications/external/mifare_nested/scenes/mifare_nested_scene_check_keys.c @@ -84,13 +84,6 @@ bool mifare_nested_scene_check_keys_on_event(void* context, SceneManagerEvent ev if(event.event == GuiButtonTypeCenter) { scene_manager_search_and_switch_to_previous_scene(mifare_nested->scene_manager, 0); consumed = true; - } else if(event.event == MifareNestedWorkerEventNoncesCollected) { - scene_manager_next_scene( - mifare_nested->scene_manager, MifareNestedSceneNoncesCollected); - consumed = true; - } else if(event.event == MifareNestedWorkerEventNeedKey) { - scene_manager_next_scene(mifare_nested->scene_manager, MifareNestedSceneNoKeys); - consumed = true; } else if(event.event == MifareNestedWorkerEventKeysFound) { scene_manager_next_scene(mifare_nested->scene_manager, MifareNestedSceneAddedKeys); consumed = true; diff --git a/applications/external/mifare_nested/scenes/mifare_nested_scene_collecting.c b/applications/external/mifare_nested/scenes/mifare_nested_scene_collecting.c index 05c96d97d..281210107 100644 --- a/applications/external/mifare_nested/scenes/mifare_nested_scene_collecting.c +++ b/applications/external/mifare_nested/scenes/mifare_nested_scene_collecting.c @@ -120,6 +120,10 @@ bool mifare_nested_scene_collecting_on_event(void* context, SceneManagerEvent ev scene_manager_next_scene( mifare_nested->scene_manager, MifareNestedSceneNoncesCollected); consumed = true; + } else if(event.event == MifareNestedWorkerEventNoNoncesCollected) { + scene_manager_next_scene( + mifare_nested->scene_manager, MifareNestedSceneNoNoncesCollected); + consumed = true; } else if(event.event == MifareNestedWorkerEventAttackFailed) { scene_manager_next_scene(mifare_nested->scene_manager, MifareNestedSceneFailed); consumed = true; diff --git a/applications/external/mifare_nested/scenes/mifare_nested_scene_config.h b/applications/external/mifare_nested/scenes/mifare_nested_scene_config.h index 14cf52c4e..648f0bd73 100644 --- a/applications/external/mifare_nested/scenes/mifare_nested_scene_config.h +++ b/applications/external/mifare_nested/scenes/mifare_nested_scene_config.h @@ -10,4 +10,5 @@ ADD_SCENE(mifare_nested, about, About) ADD_SCENE(mifare_nested, static_encrypted_nonce, StaticEncryptedNonce) ADD_SCENE(mifare_nested, need_key_recovery, NeedKeyRecovery) ADD_SCENE(mifare_nested, need_collection, NeedCollection) -ADD_SCENE(mifare_nested, settings, Settings) \ No newline at end of file +ADD_SCENE(mifare_nested, settings, Settings) +ADD_SCENE(mifare_nested, no_nonces_collected, NoNoncesCollected) \ No newline at end of file diff --git a/applications/external/mifare_nested/scenes/mifare_nested_scene_no_nonces_collected.c b/applications/external/mifare_nested/scenes/mifare_nested_scene_no_nonces_collected.c new file mode 100644 index 000000000..74e2459e8 --- /dev/null +++ b/applications/external/mifare_nested/scenes/mifare_nested_scene_no_nonces_collected.c @@ -0,0 +1,94 @@ +#include "../mifare_nested_i.h" + +void mifare_nested_scene_no_nonces_collected_widget_callback( + GuiButtonType result, + InputType type, + void* context) { + MifareNested* mifare_nested = context; + if(type == InputTypeShort) { + view_dispatcher_send_custom_event(mifare_nested->view_dispatcher, result); + } +} + +void mifare_nested_scene_no_nonces_collected_on_enter(void* context) { + MifareNested* mifare_nested = context; + Widget* widget = mifare_nested->widget; + SaveNoncesResult_t* save_state = mifare_nested->save_state; + + notification_message(mifare_nested->notifications, &sequence_error); + + widget_add_icon_element(widget, 73, 12, &I_DolphinCry); + widget_add_string_element( + widget, 0, 0, AlignLeft, AlignTop, FontPrimary, "No nonces collected"); + + uint32_t index = 12; + + if(save_state->skipped) { + char append_skipped[8] = {'s', 'e', 'c', 't', 'o', 'r', ' ', '\0'}; + if(save_state->skipped != 1) { + append_skipped[6] = 's'; + } + + char draw_str[32] = {}; + snprintf( + draw_str, sizeof(draw_str), "Skipped: %lu %s", save_state->skipped, append_skipped); + + widget_add_string_element(widget, 0, index, AlignLeft, AlignTop, FontSecondary, draw_str); + + widget_add_string_element( + widget, 0, index + 10, AlignLeft, AlignTop, FontSecondary, "(already has keys)"); + + index += 20; + } + + if(save_state->invalid) { + char append_invalid[8] = {'s', 'e', 'c', 't', 'o', 'r', ' ', '\0'}; + if(save_state->invalid != 1) { + append_invalid[6] = 's'; + } + + char draw_str[32] = {}; + snprintf( + draw_str, sizeof(draw_str), "Invalid: %lu %s", save_state->invalid, append_invalid); + + widget_add_string_element(widget, 0, index, AlignLeft, AlignTop, FontSecondary, draw_str); + + widget_add_string_element( + widget, 0, index + 10, AlignLeft, AlignTop, FontSecondary, "(can't auth)"); + } + + free(save_state); + + widget_add_button_element( + widget, + GuiButtonTypeLeft, + "Back", + mifare_nested_scene_no_nonces_collected_widget_callback, + mifare_nested); + + // Setup and start worker + view_dispatcher_switch_to_view(mifare_nested->view_dispatcher, MifareNestedViewWidget); +} + +bool mifare_nested_scene_no_nonces_collected_on_event(void* context, SceneManagerEvent event) { + MifareNested* mifare_nested = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + if(event.event == GuiButtonTypeCenter || event.event == GuiButtonTypeLeft) { + scene_manager_search_and_switch_to_previous_scene(mifare_nested->scene_manager, 0); + consumed = true; + } + } else if(event.type == SceneManagerEventTypeBack) { + scene_manager_search_and_switch_to_previous_scene(mifare_nested->scene_manager, 0); + consumed = true; + } + + return consumed; +} + +void mifare_nested_scene_no_nonces_collected_on_exit(void* context) { + MifareNested* mifare_nested = context; + + widget_reset(mifare_nested->widget); +} From 15a33a58d32758a34d5475d72e968daa40f76311 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Tue, 30 May 2023 19:33:29 +0300 Subject: [PATCH 28/52] Upd ofw anim list --- .ci_files/anims_ofw.txt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.ci_files/anims_ofw.txt b/.ci_files/anims_ofw.txt index a9a6fd241..4fa369f82 100644 --- a/.ci_files/anims_ofw.txt +++ b/.ci_files/anims_ofw.txt @@ -85,6 +85,13 @@ Min level: 1 Max level: 3 Weight: 3 +Name: L1_Kaiju_128x64 +Min butthurt: 0 +Max butthurt: 10 +Min level: 1 +Max level: 3 +Weight: 4 + Name: L2_Wake_up_128x64 Min butthurt: 0 Max butthurt: 12 From b3e8b2c487da17fdda1a78740967f1c5e1e955ee Mon Sep 17 00:00:00 2001 From: gid9798 <30450294+gid9798@users.noreply.github.com> Date: Tue, 30 May 2023 16:51:07 +0300 Subject: [PATCH 29/52] upd_subrem_main --- .../main/subghz_remote/application.fam | 2 +- .../helpers/subrem_custom_event.h | 10 +- .../subghz_remote/helpers/subrem_presets.c | 7 +- .../subghz_remote/helpers/subrem_presets.h | 5 +- .../main/subghz_remote/helpers/subrem_types.h | 11 +- .../main/subghz_remote/helpers/txrx/Readme.md | 4 + .../subghz_remote/helpers/txrx/subghz_txrx.h | 3 + .../scenes/subrem_scene_config.h | 2 +- .../scenes/subrem_scene_open_map_file.c | 56 ++++++ .../scenes/subrem_scene_openmapfile.c | 42 ----- .../scenes/subrem_scene_remote.c | 16 +- .../subghz_remote/scenes/subrem_scene_start.c | 10 +- .../main/subghz_remote/subghz_remote_app.c | 14 +- .../main/subghz_remote/subghz_remote_app_i.c | 65 +++---- .../main/subghz_remote/subghz_remote_app_i.h | 24 +-- .../main/subghz_remote/views/remote.c | 162 +++++++++--------- .../main/subghz_remote/views/remote.h | 6 +- assets/icons/Archive/subrem_10px.png | Bin 0 -> 5000 bytes 18 files changed, 215 insertions(+), 224 deletions(-) create mode 100644 applications/main/subghz_remote/helpers/txrx/Readme.md create mode 100644 applications/main/subghz_remote/helpers/txrx/subghz_txrx.h create mode 100644 applications/main/subghz_remote/scenes/subrem_scene_open_map_file.c delete mode 100644 applications/main/subghz_remote/scenes/subrem_scene_openmapfile.c create mode 100644 assets/icons/Archive/subrem_10px.png diff --git a/applications/main/subghz_remote/application.fam b/applications/main/subghz_remote/application.fam index e785043e6..65095573f 100644 --- a/applications/main/subghz_remote/application.fam +++ b/applications/main/subghz_remote/application.fam @@ -12,6 +12,6 @@ App( "dialogs", ], icon="A_SubGHzRemote_14", - stack_size=4 * 1024, + stack_size=3 * 1024, order=11, ) \ No newline at end of file diff --git a/applications/main/subghz_remote/helpers/subrem_custom_event.h b/applications/main/subghz_remote/helpers/subrem_custom_event.h index 46ab8ad54..e4bd95143 100644 --- a/applications/main/subghz_remote/helpers/subrem_custom_event.h +++ b/applications/main/subghz_remote/helpers/subrem_custom_event.h @@ -1,12 +1,14 @@ #pragma once typedef enum { - //SubmenuIndex - SubmenuIndexSubRemOpenMapFile, + // SubmenuIndex + SubmenuIndexSubRemOpenMapFile = 0, +#if FURI_DEBUG SubmenuIndexSubRemRemoteView, - SubmenuIndexSubRemAbout, +#endif + // SubmenuIndexSubRemAbout, - //SubRemCustomEvent + // SubRemCustomEvent SubRemCustomEventViewRemoteStartUP = 100, SubRemCustomEventViewRemoteStartDOWN, SubRemCustomEventViewRemoteStartLEFT, diff --git a/applications/main/subghz_remote/helpers/subrem_presets.c b/applications/main/subghz_remote/helpers/subrem_presets.c index 9601aae6c..dc298c069 100644 --- a/applications/main/subghz_remote/helpers/subrem_presets.c +++ b/applications/main/subghz_remote/helpers/subrem_presets.c @@ -8,7 +8,7 @@ SubRemSubFilePreset* subrem_sub_file_preset_alloc() { sub_preset->fff_data = flipper_format_string_alloc(); sub_preset->file_path = furi_string_alloc(); sub_preset->protocaol_name = furi_string_alloc(); - sub_preset->label = furi_string_alloc_set_str("N/A"); + sub_preset->label = furi_string_alloc(); sub_preset->freq_preset.name = furi_string_alloc(); @@ -34,7 +34,7 @@ void subrem_sub_file_preset_free(SubRemSubFilePreset* sub_preset) { void subrem_sub_file_preset_reset(SubRemSubFilePreset* sub_preset) { furi_assert(sub_preset); - furi_string_set_str(sub_preset->label, "N/A"); + furi_string_set_str(sub_preset->label, ""); furi_string_reset(sub_preset->protocaol_name); furi_string_reset(sub_preset->file_path); @@ -77,7 +77,7 @@ SubRemLoadSubState subrem_sub_preset_load( break; } - SubGhzSetting* setting = subghz_txrx_get_setting(txrx); // txrx->setting; + SubGhzSetting* setting = subghz_txrx_get_setting(txrx); //Load frequency or using default from settings ret = SubRemLoadSubStateErrorFreq; @@ -175,5 +175,6 @@ SubRemLoadSubState subrem_sub_preset_load( } while(false); furi_string_free(temp_str); + sub_preset->load_state = ret; return ret; } diff --git a/applications/main/subghz_remote/helpers/subrem_presets.h b/applications/main/subghz_remote/helpers/subrem_presets.h index fd4a2d780..d66181b90 100644 --- a/applications/main/subghz_remote/helpers/subrem_presets.h +++ b/applications/main/subghz_remote/helpers/subrem_presets.h @@ -1,9 +1,10 @@ #pragma once #include "subrem_types.h" +#include "txrx/subghz_txrx.h" + #include -#include -#include "../../subghz/helpers/subghz_txrx.h" +#include typedef struct { FuriString* name; diff --git a/applications/main/subghz_remote/helpers/subrem_types.h b/applications/main/subghz_remote/helpers/subrem_types.h index def807898..b392de17e 100644 --- a/applications/main/subghz_remote/helpers/subrem_types.h +++ b/applications/main/subghz_remote/helpers/subrem_types.h @@ -3,9 +3,8 @@ #include #include -// TODO: File version/type logic -// #define SUBREM_APP_APP_FILE_VERSION 1 -// #define SUBREM_APP_APP_FILE_TYPE "Flipper SubRem Map file" +#define SUBREM_APP_APP_FILE_VERSION 1 +#define SUBREM_APP_APP_FILE_TYPE "Flipper SubRem Map file" #define SUBREM_APP_EXTENSION ".txt" typedef enum { @@ -18,10 +17,7 @@ typedef enum { } SubRemSubKeyName; typedef enum { - SubRemViewSubmenu, - SubRemViewWidget, - SubRemViewPopup, - SubRemViewTextInput, + SubRemViewIDSubmenu, SubRemViewIDRemote, } SubRemViewID; @@ -29,6 +25,7 @@ typedef enum { SubRemLoadSubStateNotSet = 0, SubRemLoadSubStatePreloaded, SubRemLoadSubStateError, + SubRemLoadSubStateErrorIncorectPath, SubRemLoadSubStateErrorNoFile, SubRemLoadSubStateErrorFreq, SubRemLoadSubStateErrorMod, diff --git a/applications/main/subghz_remote/helpers/txrx/Readme.md b/applications/main/subghz_remote/helpers/txrx/Readme.md new file mode 100644 index 000000000..918160198 --- /dev/null +++ b/applications/main/subghz_remote/helpers/txrx/Readme.md @@ -0,0 +1,4 @@ +This is part of the official `SubGhz` app from [flipperzero-firmware](https://github.com/flipperdevices/flipperzero-firmware/tree/3217f286f03da119398586daf94c0723d28b872a/applications/main/subghz) + +With changes from [unleashed-firmware +](https://github.com/DarkFlippers/unleashed-firmware/tree/3eac6ccd48a3851cf5d63bf7899b387a293e5319/applications/main/subghz) \ No newline at end of file diff --git a/applications/main/subghz_remote/helpers/txrx/subghz_txrx.h b/applications/main/subghz_remote/helpers/txrx/subghz_txrx.h new file mode 100644 index 000000000..5241f402f --- /dev/null +++ b/applications/main/subghz_remote/helpers/txrx/subghz_txrx.h @@ -0,0 +1,3 @@ +#pragma once + +#include "../../../subghz/helpers/subghz_txrx.h" \ No newline at end of file diff --git a/applications/main/subghz_remote/scenes/subrem_scene_config.h b/applications/main/subghz_remote/scenes/subrem_scene_config.h index 93d4de642..68b205169 100644 --- a/applications/main/subghz_remote/scenes/subrem_scene_config.h +++ b/applications/main/subghz_remote/scenes/subrem_scene_config.h @@ -1,3 +1,3 @@ ADD_SCENE(subrem, start, Start) -ADD_SCENE(subrem, openmapfile, OpenMapFile) +ADD_SCENE(subrem, open_map_file, OpenMapFile) ADD_SCENE(subrem, remote, Remote) \ No newline at end of file diff --git a/applications/main/subghz_remote/scenes/subrem_scene_open_map_file.c b/applications/main/subghz_remote/scenes/subrem_scene_open_map_file.c new file mode 100644 index 000000000..f1b8b2ec2 --- /dev/null +++ b/applications/main/subghz_remote/scenes/subrem_scene_open_map_file.c @@ -0,0 +1,56 @@ +#include "../subghz_remote_app_i.h" + +void subrem_scene_open_map_file_on_enter(void* context) { + furi_assert(context); + SubGhzRemoteApp* app = context; + + SubRemLoadMapState load_state = subrem_load_from_file(app); + uint32_t start_scene_state = + scene_manager_get_scene_state(app->scene_manager, SubRemSceneStart); + + // TODO if optimization + + if(load_state == SubRemLoadMapStateBack) { + if(!scene_manager_previous_scene(app->scene_manager)) { + scene_manager_stop(app->scene_manager); + view_dispatcher_stop(app->view_dispatcher); + } + } else if(start_scene_state == SubmenuIndexSubRemOpenMapFile) { + if(load_state != SubRemLoadMapStateOK && load_state != SubRemLoadMapStateNotAllOK && + load_state != SubRemLoadMapStateBack) { +#ifdef SUBREM_LIGHT + dialog_message_show_storage_error(app->dialogs, "Can't load\nMap file"); +#else + DialogMessage* message = dialog_message_alloc(); + + dialog_message_set_header(message, "Map File Error", 64, 8, AlignCenter, AlignCenter); + dialog_message_set_text( + message, "Can't load\nMap file", 64, 32, AlignCenter, AlignCenter); + dialog_message_set_buttons(message, "Back", NULL, NULL); + dialog_message_show(app->dialogs, message); + + dialog_message_free(message); +#endif + } + if(load_state == SubRemLoadMapStateOK || load_state == SubRemLoadMapStateNotAllOK) { + scene_manager_next_scene(app->scene_manager, SubRemSceneRemote); + } else { + // TODO: Map Preset Reset + if(!scene_manager_search_and_switch_to_previous_scene( + app->scene_manager, SubRemSceneStart)) { + scene_manager_stop(app->scene_manager); + view_dispatcher_stop(app->view_dispatcher); + } + } + } +} + +bool subrem_scene_open_map_file_on_event(void* context, SceneManagerEvent event) { + UNUSED(context); + UNUSED(event); + return false; +} + +void subrem_scene_open_map_file_on_exit(void* context) { + UNUSED(context); +} diff --git a/applications/main/subghz_remote/scenes/subrem_scene_openmapfile.c b/applications/main/subghz_remote/scenes/subrem_scene_openmapfile.c deleted file mode 100644 index 796699c83..000000000 --- a/applications/main/subghz_remote/scenes/subrem_scene_openmapfile.c +++ /dev/null @@ -1,42 +0,0 @@ -#include "../subghz_remote_app_i.h" - -void subrem_scene_openmapfile_on_enter(void* context) { - SubGhzRemoteApp* app = context; - SubRemLoadMapState load_state = subrem_load_from_file(app); - - if(load_state != SubRemLoadMapStateOK && load_state != SubRemLoadMapStateNotAllOK && - load_state != SubRemLoadMapStateBack) { -#ifdef SUBREM_LIGHT - dialog_message_show_storage_error(app->dialogs, "Can't load\nMap file"); -#else - DialogMessage* message = dialog_message_alloc(); - - dialog_message_set_header(message, "Map File Error", 64, 8, AlignCenter, AlignCenter); - dialog_message_set_text(message, "Can't load\nMap file", 64, 32, AlignCenter, AlignCenter); - dialog_message_set_buttons(message, "Back", NULL, NULL); - dialog_message_show(app->dialogs, message); - - dialog_message_free(message); -#endif - } - if(load_state == SubRemLoadMapStateOK || load_state == SubRemLoadMapStateNotAllOK) { - scene_manager_next_scene(app->scene_manager, SubRemSceneRemote); - } else { - // TODO: Map Preset Reset - if(!scene_manager_search_and_switch_to_previous_scene( - app->scene_manager, SubRemSceneStart)) { - scene_manager_stop(app->scene_manager); - view_dispatcher_stop(app->view_dispatcher); - } - } -} - -bool subrem_scene_openmapfile_on_event(void* context, SceneManagerEvent event) { - UNUSED(context); - UNUSED(event); - return false; -} - -void subrem_scene_openmapfile_on_exit(void* context) { - UNUSED(context); -} diff --git a/applications/main/subghz_remote/scenes/subrem_scene_remote.c b/applications/main/subghz_remote/scenes/subrem_scene_remote.c index eaa1c41d9..644f8daac 100644 --- a/applications/main/subghz_remote/scenes/subrem_scene_remote.c +++ b/applications/main/subghz_remote/scenes/subrem_scene_remote.c @@ -35,24 +35,10 @@ static uint8_t subrem_scene_remote_event_to_index(SubRemCustomEvent event_id) { return ret; } -static bool subrem_scene_remote_update_data_show(void* context) { - SubGhzRemoteApp* app = context; - - const char* labels[SubRemSubKeyNameMaxCount]; - - for(uint8_t i = 0; i < SubRemSubKeyNameMaxCount; i++) { - labels[i] = furi_string_get_cstr(app->map_preset->subs_preset[i]->label); - } - - subrem_view_remote_add_data_to_show(app->subrem_remote_view, labels); - - return true; -} - void subrem_scene_remote_on_enter(void* context) { SubGhzRemoteApp* app = context; - subrem_scene_remote_update_data_show(app); + subrem_view_remote_update_data_labels(app->subrem_remote_view, app->map_preset->subs_preset); subrem_view_remote_set_callback(app->subrem_remote_view, subrem_scene_remote_callback, app); diff --git a/applications/main/subghz_remote/scenes/subrem_scene_start.c b/applications/main/subghz_remote/scenes/subrem_scene_start.c index a4bfa5047..dd840c40d 100644 --- a/applications/main/subghz_remote/scenes/subrem_scene_start.c +++ b/applications/main/subghz_remote/scenes/subrem_scene_start.c @@ -34,12 +34,10 @@ void subrem_scene_start_on_enter(void* context) { // subrem_scene_start_submenu_callback, // app); - // TODO: set scene state in subrem alloc - // submenu_set_selected_item( - // submenu, scene_manager_get_scene_state(app->scene_manager, SubRemSceneStart)); - submenu_set_selected_item(submenu, SubmenuIndexSubRemOpenMapFile); + submenu_set_selected_item( + submenu, scene_manager_get_scene_state(app->scene_manager, SubRemSceneStart)); - view_dispatcher_switch_to_view(app->view_dispatcher, SubRemViewSubmenu); + view_dispatcher_switch_to_view(app->view_dispatcher, SubRemViewIDSubmenu); } bool subrem_scene_start_on_event(void* context, SceneManagerEvent event) { @@ -50,6 +48,8 @@ bool subrem_scene_start_on_event(void* context, SceneManagerEvent event) { if(event.type == SceneManagerEventTypeCustom) { if(event.event == SubmenuIndexSubRemOpenMapFile) { + scene_manager_set_scene_state( + app->scene_manager, SubRemSceneStart, SubmenuIndexSubRemOpenMapFile); scene_manager_next_scene(app->scene_manager, SubRemSceneOpenMapFile); consumed = true; } diff --git a/applications/main/subghz_remote/subghz_remote_app.c b/applications/main/subghz_remote/subghz_remote_app.c index e57b1ac2d..624a602ae 100644 --- a/applications/main/subghz_remote/subghz_remote_app.c +++ b/applications/main/subghz_remote/subghz_remote_app.c @@ -1,7 +1,5 @@ #include "subghz_remote_app_i.h" -#include - static bool subghz_remote_app_custom_event_callback(void* context, uint32_t event) { furi_assert(context); SubGhzRemoteApp* app = context; @@ -70,9 +68,9 @@ SubGhzRemoteApp* subghz_remote_app_alloc() { // SubMenu app->submenu = submenu_alloc(); view_dispatcher_add_view( - app->view_dispatcher, SubRemViewSubmenu, submenu_get_view(app->submenu)); + app->view_dispatcher, SubRemViewIDSubmenu, submenu_get_view(app->submenu)); - //Dialog + // Dialog app->dialogs = furi_record_open(RECORD_DIALOGS); // Remote view @@ -91,12 +89,12 @@ SubGhzRemoteApp* subghz_remote_app_alloc() { subghz_txrx_set_need_save_callback(app->txrx, subrem_save_active_sub, app); - app->tx_running = false; - #ifdef SUBREM_LIGHT scene_manager_next_scene(app->scene_manager, SubRemSceneOpenMapFile); #else scene_manager_next_scene(app->scene_manager, SubRemSceneStart); + scene_manager_set_scene_state( + app->scene_manager, SubRemSceneStart, SubmenuIndexSubRemOpenMapFile); #endif return app; @@ -113,10 +111,10 @@ void subghz_remote_app_free(SubGhzRemoteApp* app) { furi_hal_subghz_init_radio_type(SubGhzRadioInternal); // Submenu - view_dispatcher_remove_view(app->view_dispatcher, SubRemViewSubmenu); + view_dispatcher_remove_view(app->view_dispatcher, SubRemViewIDSubmenu); submenu_free(app->submenu); - //Dialog + // Dialog furi_record_close(RECORD_DIALOGS); // Remote view diff --git a/applications/main/subghz_remote/subghz_remote_app_i.c b/applications/main/subghz_remote/subghz_remote_app_i.c index fb34b59f7..82c2efbf5 100644 --- a/applications/main/subghz_remote/subghz_remote_app_i.c +++ b/applications/main/subghz_remote/subghz_remote_app_i.c @@ -2,23 +2,18 @@ #include #include -#include - -#include "../subghz/helpers/subghz_txrx_i.h" +#include "helpers/txrx/subghz_txrx.h" // #include // #include +#ifdef APP_SUBGHZREMOTE +#include #include +#endif #define TAG "SubGhzRemote" -// XXX Using TxRx -// [x] use TxRx preset subrem_sub_preset_load & subrem_tx_start_sub -// [x] subrem_sub_preset_load & drop subrem_set_preset_data -// [x] subrem_tx_start_sub -// [x] subrem_tx_stop_sub - static const char* map_file_labels[SubRemSubKeyNameMaxCount][2] = { [SubRemSubKeyNameUp] = {"UP", "ULABEL"}, [SubRemSubKeyNameDown] = {"DOWN", "DLABEL"}, @@ -45,30 +40,25 @@ static SubRemLoadMapState subrem_map_preset_check( bool all_loaded = true; SubRemLoadMapState ret = SubRemLoadMapStateErrorBrokenFile; - SubRemLoadSubState sub_preset_loaded; + SubRemLoadSubState sub_loadig_state; SubRemSubFilePreset* sub_preset; for(uint8_t i = 0; i < SubRemSubKeyNameMaxCount; i++) { sub_preset = map_preset->subs_preset[i]; - sub_preset_loaded = SubRemLoadSubStateErrorNoFile; + sub_loadig_state = SubRemLoadSubStateErrorNoFile; if(furi_string_empty(sub_preset->file_path)) { // FURI_LOG_I(TAG, "Empty file path"); } else if(!flipper_format_file_open_existing( fff_data_file, furi_string_get_cstr(sub_preset->file_path))) { + sub_preset->load_state = SubRemLoadSubStateErrorNoFile; FURI_LOG_W(TAG, "Error open file %s", furi_string_get_cstr(sub_preset->file_path)); } else { - sub_preset_loaded = subrem_sub_preset_load(sub_preset, txrx, fff_data_file); + sub_loadig_state = subrem_sub_preset_load(sub_preset, txrx, fff_data_file); } - // TODO: - // Load file state logic - // Label depending on the state - // Move to remote scene - - if(sub_preset_loaded != SubRemLoadSubStateOK) { - furi_string_set_str(sub_preset->label, "N/A"); + if(sub_loadig_state != SubRemLoadSubStateOK) { all_loaded = false; } else { ret = SubRemLoadMapStateNotAllOK; @@ -96,6 +86,9 @@ static bool subrem_map_preset_load(SubRemMapPreset* map_preset, FlipperFormat* f FURI_LOG_W(TAG, "No file patch for %s", map_file_labels[i][0]); #endif sub_preset->type = SubGhzProtocolTypeUnknown; + } else if(!path_contains_only_ascii(furi_string_get_cstr(sub_preset->file_path))) { + FURI_LOG_E(TAG, "Incorrect characters in [%s] file path", map_file_labels[i][0]); + sub_preset->type = SubGhzProtocolTypeUnknown; } else if(!flipper_format_rewind(fff_data_file)) { // Rewind error } else if(!flipper_format_read_string( @@ -103,8 +96,6 @@ static bool subrem_map_preset_load(SubRemMapPreset* map_preset, FlipperFormat* f #if FURI_DEBUG FURI_LOG_W(TAG, "No Label for %s", map_file_labels[i][0]); #endif - // TODO move to remote scene - path_extract_filename(sub_preset->file_path, sub_preset->label, true); ret = true; } else { ret = true; @@ -237,17 +228,17 @@ bool subrem_tx_start_sub(SubGhzRemoteApp* app, SubRemSubFilePreset* sub_preset) NULL, 0); +#ifdef APP_SUBGHZREMOTE subghz_custom_btn_set(SUBGHZ_CUSTOM_BTN_OK); keeloq_reset_original_btn(); subghz_custom_btns_reset(); +#endif if(subghz_txrx_tx_start(app->txrx, sub_preset->fff_data) == SubGhzTxRxStartTxStateOk) { ret = true; } } - app->tx_running = ret; - return ret; } @@ -256,22 +247,18 @@ bool subrem_tx_stop_sub(SubGhzRemoteApp* app, bool forced) { SubRemSubFilePreset* sub_preset = app->map_preset->subs_preset[app->chusen_sub]; if(forced || (sub_preset->type != SubGhzProtocolTypeRAW)) { - // XXX drop app->tx_running - if(app->tx_running) { - subghz_txrx_stop(app->txrx); - - if(sub_preset->type == SubGhzProtocolTypeDynamic) { - keeloq_reset_mfname(); - keeloq_reset_kl_type(); - keeloq_reset_original_btn(); - subghz_custom_btns_reset(); - star_line_reset_mfname(); - star_line_reset_kl_type(); - } - - app->tx_running = false; - return true; + subghz_txrx_stop(app->txrx); +#ifdef APP_SUBGHZREMOTE + if(sub_preset->type == SubGhzProtocolTypeDynamic) { + keeloq_reset_mfname(); + keeloq_reset_kl_type(); + keeloq_reset_original_btn(); + subghz_custom_btns_reset(); + star_line_reset_mfname(); + star_line_reset_kl_type(); } +#endif + return true; } return false; @@ -284,7 +271,7 @@ SubRemLoadMapState subrem_load_from_file(SubGhzRemoteApp* app) { SubRemLoadMapState ret = SubRemLoadMapStateBack; DialogsFileBrowserOptions browser_options; - dialog_file_browser_set_basic_options(&browser_options, SUBREM_APP_EXTENSION, &I_sub1_10px); + dialog_file_browser_set_basic_options(&browser_options, SUBREM_APP_EXTENSION, &I_subrem_10px); browser_options.base_path = SUBREM_APP_FOLDER; // Input events and views are managed by file_select diff --git a/applications/main/subghz_remote/subghz_remote_app_i.h b/applications/main/subghz_remote/subghz_remote_app_i.h index 50e2bae9f..ff01ba12a 100644 --- a/applications/main/subghz_remote/subghz_remote_app_i.h +++ b/applications/main/subghz_remote/subghz_remote_app_i.h @@ -2,34 +2,31 @@ #include "helpers/subrem_types.h" #include "helpers/subrem_presets.h" +#include "scenes/subrem_scene.h" -#include "../subghz/helpers/subghz_txrx.h" +#include "helpers/txrx/subghz_txrx.h" +#ifdef APP_SUBGHZREMOTE #include +#elif +#include +#endif #include "views/remote.h" -#include "scenes/subrem_scene.h" - #include #include #include #include #include -#include #include -#include -#include #include +#include +#include +#include #include -#include - -#include -#include -#include - #define SUBREM_APP_FOLDER EXT_PATH("subghz_remote") #define SUBREM_MAX_LEN_NAME 64 @@ -42,7 +39,6 @@ typedef struct { Submenu* submenu; FuriString* file_path; - // char file_name_tmp[SUBREM_MAX_LEN_NAME]; SubRemViewRemote* subrem_remote_view; @@ -50,8 +46,6 @@ typedef struct { SubGhzTxRx* txrx; - bool tx_running; - uint8_t chusen_sub; } SubGhzRemoteApp; diff --git a/applications/main/subghz_remote/views/remote.c b/applications/main/subghz_remote/views/remote.c index e062f11b1..c2b41cfd6 100644 --- a/applications/main/subghz_remote/views/remote.c +++ b/applications/main/subghz_remote/views/remote.c @@ -4,7 +4,11 @@ #include #include -#define SUBREM_VIEW_REMOTE_MAX_LABEL_LENGTH 12 +#include + +#define SUBREM_VIEW_REMOTE_MAX_LABEL_LENGTH 30 +#define SUBREM_VIEW_REMOTE_LEFT_OFFSET 10 +#define SUBREM_VIEW_REMOTE_RIGHT_OFFSET 22 struct SubRemViewRemote { View* view; @@ -12,19 +16,8 @@ struct SubRemViewRemote { void* context; }; -// TODO: model typedef struct { - // FuriString* up_label; - // FuriString* down_label; - // FuriString* left_label; - // FuriString* right_label; - // FuriString* ok_label; - - char* up_label; - char* down_label; - char* left_label; - char* right_label; - char* ok_label; + char* labels[SubRemSubKeyNameMaxCount]; SubRemViewRemoteState state; @@ -41,26 +34,61 @@ void subrem_view_remote_set_callback( subrem_view_remote->context = context; } -void subrem_view_remote_add_data_to_show(SubRemViewRemote* subrem_view_remote, const char** labels) { +void subrem_view_remote_update_data_labels( + SubRemViewRemote* subrem_view_remote, + SubRemSubFilePreset** subs_presets) { furi_assert(subrem_view_remote); + furi_assert(subs_presets); + + FuriString* labels[SubRemSubKeyNameMaxCount]; + SubRemSubFilePreset* sub_preset; + + for(uint8_t i = 0; i < SubRemSubKeyNameMaxCount; i++) { + sub_preset = subs_presets[i]; + switch(sub_preset->load_state) { + case SubRemLoadSubStateOK: + if(!furi_string_empty(sub_preset->label)) { + labels[i] = furi_string_alloc_set(sub_preset->label); + } else if(!furi_string_empty(sub_preset->file_path)) { + labels[i] = furi_string_alloc(); + path_extract_filename(sub_preset->file_path, labels[i], true); + } else { + labels[i] = furi_string_alloc_set("Empty Label"); + } + break; + + case SubRemLoadSubStateErrorNoFile: + labels[i] = furi_string_alloc_set("[X] Can't open file"); + break; + + case SubRemLoadSubStateErrorFreq: + case SubRemLoadSubStateErrorMod: + case SubRemLoadSubStateErrorProtocol: + labels[i] = furi_string_alloc_set("[X] Error in .sub file"); + break; + + default: + labels[i] = furi_string_alloc_set(""); + break; + } + } with_view_model( subrem_view_remote->view, SubRemViewRemoteModel * model, { - strncpy(model->up_label, labels[0], SUBREM_VIEW_REMOTE_MAX_LABEL_LENGTH); - strncpy(model->down_label, labels[1], SUBREM_VIEW_REMOTE_MAX_LABEL_LENGTH); - strncpy(model->left_label, labels[2], SUBREM_VIEW_REMOTE_MAX_LABEL_LENGTH); - strncpy(model->right_label, labels[3], SUBREM_VIEW_REMOTE_MAX_LABEL_LENGTH); - strncpy(model->ok_label, labels[4], SUBREM_VIEW_REMOTE_MAX_LABEL_LENGTH); - - // furi_string_set(model->up_label, up_label); - // furi_string_set(model->down_label, down_label); - // furi_string_set(model->left_label, left_label); - // furi_string_set(model->right_label, right_label); - // furi_string_set(model->ok_label, ok_label); + for(uint8_t i = 0; i < SubRemSubKeyNameMaxCount; i++) { + strncpy( + model->labels[i], + furi_string_get_cstr(labels[i]), + SUBREM_VIEW_REMOTE_MAX_LABEL_LENGTH); + } }, true); + + for(uint8_t i = 0; i < SubRemSubKeyNameMaxCount; i++) { + furi_string_free(labels[i]); + } } void subrem_view_remote_set_state( @@ -95,24 +123,32 @@ void subrem_view_remote_draw(Canvas* canvas, SubRemViewRemoteModel* model) { //Labels canvas_set_font(canvas, FontSecondary); - canvas_draw_str(canvas, 10, 10, model->up_label); - canvas_draw_str(canvas, 10, 20, model->down_label); - canvas_draw_str(canvas, 10, 30, model->left_label); - canvas_draw_str(canvas, 10, 40, model->right_label); - canvas_draw_str(canvas, 10, 50, model->ok_label); + uint8_t y = 0; + for(uint8_t i = 0; i < SubRemSubKeyNameMaxCount; i++) { + elements_text_box( + canvas, + SUBREM_VIEW_REMOTE_LEFT_OFFSET, + y + 2, + 126 - SUBREM_VIEW_REMOTE_LEFT_OFFSET - SUBREM_VIEW_REMOTE_RIGHT_OFFSET, + 12, + AlignLeft, + AlignBottom, + model->labels[i], + false); + y += 10; + } - // canvas_draw_str(canvas, 10, 10, furi_string_get_cstr(model->up_label)); - // canvas_draw_str(canvas, 10, 10, furi_string_get_cstr(model->up_label)); - // canvas_draw_str(canvas, 10, 10, furi_string_get_cstr(model->up_label)); - // canvas_draw_str(canvas, 10, 10, furi_string_get_cstr(model->up_label)); - // canvas_draw_str(canvas, 10, 10, furi_string_get_cstr(model->up_label)); - - canvas_draw_str_aligned(canvas, 11, 62, AlignLeft, AlignBottom, "Hold=Exit."); + if(model->state == SubRemViewRemoteStateOFF) { + elements_button_left(canvas, "Back"); + elements_button_right(canvas, "Save"); + } else { + canvas_draw_str_aligned(canvas, 11, 62, AlignLeft, AlignBottom, "Hold=Exit."); + } //Status text and indicator canvas_draw_icon(canvas, 113, 15, &I_Pin_cell_13x13); - if(model->state == SubRemViewRemoteStateIdle) { + if(model->state == SubRemViewRemoteStateIdle || model->state == SubRemViewRemoteStateOFF) { canvas_draw_str_aligned(canvas, 126, 10, AlignRight, AlignBottom, "Idle"); } else { switch(model->state) { @@ -147,10 +183,6 @@ void subrem_view_remote_draw(Canvas* canvas, SubRemViewRemoteModel* model) { break; } } - //Repeat indicator - //canvas_draw_str_aligned(canvas, 125, 40, AlignRight, AlignBottom, "Repeat:"); - //canvas_draw_icon(canvas, 115, 39, &I_SubGHzRemote_Repeat_12x14); - //canvas_draw_str_aligned(canvas, 125, 62, AlignRight, AlignBottom, int_to_char(app->repeat)); } bool subrem_view_remote_input(InputEvent* event, void* context) { @@ -158,17 +190,6 @@ bool subrem_view_remote_input(InputEvent* event, void* context) { SubRemViewRemote* subrem_view_remote = context; if(event->key == InputKeyBack && event->type == InputTypeLong) { - with_view_model( - subrem_view_remote->view, - SubRemViewRemoteModel * model, - { - strcpy(model->up_label, "N/A"); - strcpy(model->down_label, "N/A"); - strcpy(model->left_label, "N/A"); - strcpy(model->right_label, "N/A"); - strcpy(model->ok_label, "N/A"); - }, - false); subrem_view_remote->callback(SubRemCustomEventViewRemoteBack, subrem_view_remote->context); return true; } else if(event->key == InputKeyBack && event->type == InputTypeShort) { @@ -240,23 +261,10 @@ SubRemViewRemote* subrem_view_remote_alloc() { { model->state = SubRemViewRemoteStateIdle; - model->up_label = malloc(sizeof(char) * SUBREM_VIEW_REMOTE_MAX_LABEL_LENGTH + 1); - model->down_label = malloc(sizeof(char) * SUBREM_VIEW_REMOTE_MAX_LABEL_LENGTH + 1); - model->left_label = malloc(sizeof(char) * SUBREM_VIEW_REMOTE_MAX_LABEL_LENGTH + 1); - model->right_label = malloc(sizeof(char) * SUBREM_VIEW_REMOTE_MAX_LABEL_LENGTH + 1); - model->ok_label = malloc(sizeof(char) * SUBREM_VIEW_REMOTE_MAX_LABEL_LENGTH + 1); - - strcpy(model->up_label, "N/A"); - strcpy(model->down_label, "N/A"); - strcpy(model->left_label, "N/A"); - strcpy(model->right_label, "N/A"); - strcpy(model->ok_label, "N/A"); - - // model->up_label = furi_string_alloc_set_str("N/A"); - // model->down_label = furi_string_alloc_set_str("N/A"); - // model->left_label = furi_string_alloc_set_str("N/A"); - // model->right_label = furi_string_alloc_set_str("N/A"); - // model->ok_label = furi_string_alloc_set_str("N/A"); + for(uint8_t i = 0; i < SubRemSubKeyNameMaxCount; i++) { + model->labels[i] = malloc(sizeof(char) * SUBREM_VIEW_REMOTE_MAX_LABEL_LENGTH + 1); + strcpy(model->labels[i], ""); + } model->pressed_btn = 0; }, @@ -271,17 +279,9 @@ void subrem_view_remote_free(SubRemViewRemote* subghz_remote) { subghz_remote->view, SubRemViewRemoteModel * model, { - free(model->up_label); - free(model->down_label); - free(model->left_label); - free(model->right_label); - free(model->ok_label); - - // furi_string_free(model->up_label); - // furi_string_free(model->down_label); - // furi_string_free(model->left_label); - // furi_string_free(model->right_label); - // furi_string_free(model->ok_label); + for(uint8_t i = 0; i < SubRemSubKeyNameMaxCount; i++) { + free(model->labels[i]); + } }, true); view_free(subghz_remote->view); diff --git a/applications/main/subghz_remote/views/remote.h b/applications/main/subghz_remote/views/remote.h index ea274fca4..5b1e8153a 100644 --- a/applications/main/subghz_remote/views/remote.h +++ b/applications/main/subghz_remote/views/remote.h @@ -2,11 +2,13 @@ #include #include "../helpers/subrem_custom_event.h" +#include "../helpers/subrem_presets.h" typedef enum { SubRemViewRemoteStateIdle, SubRemViewRemoteStateLoading, SubRemViewRemoteStateSending, + SubRemViewRemoteStateOFF, } SubRemViewRemoteState; typedef struct SubRemViewRemote SubRemViewRemote; @@ -24,7 +26,9 @@ void subrem_view_remote_free(SubRemViewRemote* subrem_view_remote); View* subrem_view_remote_get_view(SubRemViewRemote* subrem_view_remote); -void subrem_view_remote_add_data_to_show(SubRemViewRemote* subrem_view_remote, const char** labels); +void subrem_view_remote_update_data_labels( + SubRemViewRemote* subrem_view_remote, + SubRemSubFilePreset** subs_presets); void subrem_view_remote_set_state( SubRemViewRemote* subrem_view_remote, diff --git a/assets/icons/Archive/subrem_10px.png b/assets/icons/Archive/subrem_10px.png new file mode 100644 index 0000000000000000000000000000000000000000..c6b410f4c598d6b241b851826875a568c74f4d20 GIT binary patch literal 5000 zcmeHLeQXow8NVhhfsmvNbWJE`yEq*mNzeCX`_4BziDT!(3JxJLO+Xvv_1$~UEw<0t zm)N1})-a|4OCbE6;07#-3sX@sAxkg$U?hnu$6%_P+PX_Jv(ud zLf1xG|CwUz?7R1Up5OC4zxVgNce*W&4YheW_vK(1mglK+H=%$1JZE+m`hA@F<1zI2 zyA8fptqH{ONK}=TAjGw<2*hDRkufZBKGgVD-U({Lf_l{mhyV1gGrhn5dOvmG&rb;X|2#O* z`;Gdu`y8=lFC6>o;MdlzEhu;(gUPC_z|AEGi;B+`t?Ze5z3-kKC+@xe!rsi0?9s|K zy?-daKNrL9+N8K#jUJb4ydqS`GmmU@)cv;7aPpz%>TUZsFY*}}-;x*iZ59ty6_jpT zvujoMQ}z8jJ+AG;!%Gj}Yq-_gD;(ypTplW&z40q}pQ&N1scCq0d(~q_cR%sbwf8Sv zdVdlA`l;oI1plLZ-jYiT3faL`zr6A#=Lo=7=AJsu{N?^-b1q)%coKW)>T~u}qi^rn z-7>H`clPEJwEVR7TGqAGdqR;5OY#pr*E?^={1s1Y&f(g=vM=|qHywW9AEyugs9|9K z_qUv^T38l3y>(BG-D_BB`RVoV^}JI09`V|mBd`AW<~wBWyCXky1n0|1Nlg+*V)QGN;EdcVFdq|MubW(V_Tn9{lz<&(!Cf?0&8A zl@E$Ck9Ky~46J|Y$whnDXUy8sU3Tos>?t>Un9|+}sNpj`p?cz$4F;W6I^yu1td=)j zwphHBH{ybAO5KJiY~Ik|6F0PrHpy5~o?}l42p|MCfG0x1a7;)zj7eMpo$JG-5l@?` zHXBJXB*PHMf{1m6HIN{}u@W63h2e%VF{(r~MGfORCh)5rn!{*B^Z0mvp@`R;h7ZTa zSU`M`2@oM^6GetXP{HeN+v@{V%k5_5e+8G zkwg*(VF;PVP*i$K$XbuLG3}vK5Kuyqq!%K4ie;ot)zny<8cCZ^NiaQ~ENpU0nj%lI zJjF+!xy>BKy>oC09YBCl_0@MKq5HSOc8#H zHxrPt@G@uPXxUw}=@F^kKtO1=<+RE`fZLx72 zM^h}%PZ&K2qcJ389h0U^tT{O|!J$hHs!^{hL5Gn|PU-6=pgIxrK<@yAog7DH3a%&w z8g!!r!BMD#C>udrd^9VVErOXZqga7TC7!lcqdrv)I*fX4xSm29%!}Gu0vbreA!k;g z%|4nF%vOQs$|!0w97;_$K_%JJIG$`y z0f?!B#blXMGE;<>npEzfp3l7GX_S~MYjF^T&H&=qVRY(yC*C;TeK^CKEcntEB`m4& z*s`e!#M_|0il0b3`57vUflm0by2LgR4nVX&k8KG5wO*Mw+x#3L%ravoDAo)K9*8VK z`z@R#$`oXol=A*h>SY-g(0){rAj zX|i`eX-Qc`CULv;$ClJi>UW`W?b^xP)oq_>=<%(|iFP_&{;^5&uL6OoA}L2u$;}G@ zRN$B(Zj5Yq}83M;=f=r9w8MiVD2l{4`U z0fy0oX&k*FI5pSMi{36|`Ri-l*r@*9d2H`fXk<>LZgmX9OeOkpSK|4KPBfUUdA!xx z?`7r}mf Date: Tue, 30 May 2023 17:41:49 +0300 Subject: [PATCH 30/52] Same codebase as fap --- .../main/subghz_remote/application.fam | 2 +- .../scenes/subrem_scene_config.h | 2 ++ .../scenes/subrem_scene_open_map_file.c | 29 +++++-------------- .../scenes/subrem_scene_remote.c | 10 ++----- .../subghz_remote/scenes/subrem_scene_start.c | 6 ++-- .../main/subghz_remote/subghz_remote_app_i.c | 4 +-- .../main/subghz_remote/subghz_remote_app_i.h | 2 +- 7 files changed, 21 insertions(+), 34 deletions(-) diff --git a/applications/main/subghz_remote/application.fam b/applications/main/subghz_remote/application.fam index 65095573f..804ac0b7c 100644 --- a/applications/main/subghz_remote/application.fam +++ b/applications/main/subghz_remote/application.fam @@ -12,6 +12,6 @@ App( "dialogs", ], icon="A_SubGHzRemote_14", - stack_size=3 * 1024, + stack_size=2 * 1024, order=11, ) \ No newline at end of file diff --git a/applications/main/subghz_remote/scenes/subrem_scene_config.h b/applications/main/subghz_remote/scenes/subrem_scene_config.h index 68b205169..45e55850a 100644 --- a/applications/main/subghz_remote/scenes/subrem_scene_config.h +++ b/applications/main/subghz_remote/scenes/subrem_scene_config.h @@ -1,3 +1,5 @@ +#ifndef SUBREM_LIGHT ADD_SCENE(subrem, start, Start) +#endif ADD_SCENE(subrem, open_map_file, OpenMapFile) ADD_SCENE(subrem, remote, Remote) \ No newline at end of file diff --git a/applications/main/subghz_remote/scenes/subrem_scene_open_map_file.c b/applications/main/subghz_remote/scenes/subrem_scene_open_map_file.c index f1b8b2ec2..1e917580c 100644 --- a/applications/main/subghz_remote/scenes/subrem_scene_open_map_file.c +++ b/applications/main/subghz_remote/scenes/subrem_scene_open_map_file.c @@ -5,19 +5,11 @@ void subrem_scene_open_map_file_on_enter(void* context) { SubGhzRemoteApp* app = context; SubRemLoadMapState load_state = subrem_load_from_file(app); - uint32_t start_scene_state = - scene_manager_get_scene_state(app->scene_manager, SubRemSceneStart); - // TODO if optimization - - if(load_state == SubRemLoadMapStateBack) { - if(!scene_manager_previous_scene(app->scene_manager)) { - scene_manager_stop(app->scene_manager); - view_dispatcher_stop(app->view_dispatcher); - } - } else if(start_scene_state == SubmenuIndexSubRemOpenMapFile) { - if(load_state != SubRemLoadMapStateOK && load_state != SubRemLoadMapStateNotAllOK && - load_state != SubRemLoadMapStateBack) { + if(load_state == SubRemLoadMapStateOK || load_state == SubRemLoadMapStateNotAllOK) { + scene_manager_next_scene(app->scene_manager, SubRemSceneRemote); + } else { + if(load_state != SubRemLoadMapStateBack) { #ifdef SUBREM_LIGHT dialog_message_show_storage_error(app->dialogs, "Can't load\nMap file"); #else @@ -32,15 +24,10 @@ void subrem_scene_open_map_file_on_enter(void* context) { dialog_message_free(message); #endif } - if(load_state == SubRemLoadMapStateOK || load_state == SubRemLoadMapStateNotAllOK) { - scene_manager_next_scene(app->scene_manager, SubRemSceneRemote); - } else { - // TODO: Map Preset Reset - if(!scene_manager_search_and_switch_to_previous_scene( - app->scene_manager, SubRemSceneStart)) { - scene_manager_stop(app->scene_manager); - view_dispatcher_stop(app->view_dispatcher); - } + // TODO: Map Preset Reset + if(!scene_manager_previous_scene(app->scene_manager)) { + scene_manager_stop(app->scene_manager); + view_dispatcher_stop(app->view_dispatcher); } } } diff --git a/applications/main/subghz_remote/scenes/subrem_scene_remote.c b/applications/main/subghz_remote/scenes/subrem_scene_remote.c index 644f8daac..a2e307fd9 100644 --- a/applications/main/subghz_remote/scenes/subrem_scene_remote.c +++ b/applications/main/subghz_remote/scenes/subrem_scene_remote.c @@ -49,13 +49,9 @@ bool subrem_scene_remote_on_event(void* context, SceneManagerEvent event) { SubGhzRemoteApp* app = context; if(event.type == SceneManagerEventTypeCustom) { if(event.event == SubRemCustomEventViewRemoteBack) { - if(!scene_manager_search_and_switch_to_previous_scene( - app->scene_manager, SubRemSceneOpenMapFile)) { - if(!scene_manager_search_and_switch_to_previous_scene( - app->scene_manager, SubRemSceneStart)) { - scene_manager_stop(app->scene_manager); - view_dispatcher_stop(app->view_dispatcher); - } + if(!scene_manager_previous_scene(app->scene_manager)) { + scene_manager_stop(app->scene_manager); + view_dispatcher_stop(app->view_dispatcher); } return true; } else if( diff --git a/applications/main/subghz_remote/scenes/subrem_scene_start.c b/applications/main/subghz_remote/scenes/subrem_scene_start.c index dd840c40d..e780b54ce 100644 --- a/applications/main/subghz_remote/scenes/subrem_scene_start.c +++ b/applications/main/subghz_remote/scenes/subrem_scene_start.c @@ -33,10 +33,10 @@ void subrem_scene_start_on_enter(void* context) { // SubmenuIndexSubGhzRemoteAbout, // subrem_scene_start_submenu_callback, // app); - +#ifndef SUBREM_LIGHT submenu_set_selected_item( submenu, scene_manager_get_scene_state(app->scene_manager, SubRemSceneStart)); - +#endif view_dispatcher_switch_to_view(app->view_dispatcher, SubRemViewIDSubmenu); } @@ -48,8 +48,10 @@ bool subrem_scene_start_on_event(void* context, SceneManagerEvent event) { if(event.type == SceneManagerEventTypeCustom) { if(event.event == SubmenuIndexSubRemOpenMapFile) { +#ifndef SUBREM_LIGHT scene_manager_set_scene_state( app->scene_manager, SubRemSceneStart, SubmenuIndexSubRemOpenMapFile); +#endif scene_manager_next_scene(app->scene_manager, SubRemSceneOpenMapFile); consumed = true; } diff --git a/applications/main/subghz_remote/subghz_remote_app_i.c b/applications/main/subghz_remote/subghz_remote_app_i.c index 82c2efbf5..121fbf787 100644 --- a/applications/main/subghz_remote/subghz_remote_app_i.c +++ b/applications/main/subghz_remote/subghz_remote_app_i.c @@ -252,11 +252,11 @@ bool subrem_tx_stop_sub(SubGhzRemoteApp* app, bool forced) { if(sub_preset->type == SubGhzProtocolTypeDynamic) { keeloq_reset_mfname(); keeloq_reset_kl_type(); - keeloq_reset_original_btn(); - subghz_custom_btns_reset(); star_line_reset_mfname(); star_line_reset_kl_type(); } + keeloq_reset_original_btn(); + subghz_custom_btns_reset(); #endif return true; } diff --git a/applications/main/subghz_remote/subghz_remote_app_i.h b/applications/main/subghz_remote/subghz_remote_app_i.h index ff01ba12a..1ced74d11 100644 --- a/applications/main/subghz_remote/subghz_remote_app_i.h +++ b/applications/main/subghz_remote/subghz_remote_app_i.h @@ -8,7 +8,7 @@ #ifdef APP_SUBGHZREMOTE #include -#elif +#else #include #endif From c70a13015b6e7d1346434474938c8e0424ae854c Mon Sep 17 00:00:00 2001 From: gid9798 <30450294+gid9798@users.noreply.github.com> Date: Tue, 30 May 2023 20:27:15 +0300 Subject: [PATCH 31/52] Allow BinRaw & some clean --- .../helpers/subrem_custom_event.h | 10 ++++------ .../helpers/subrem_presets.c | 3 +-- .../subghz_remote_configurator/subghz_remote_app_i.h | 4 ---- .../main/subghz_remote/helpers/subrem_custom_event.h | 2 +- .../main/subghz_remote/helpers/subrem_presets.c | 3 +-- 5 files changed, 7 insertions(+), 15 deletions(-) diff --git a/applications/external/subghz_remote_configurator/helpers/subrem_custom_event.h b/applications/external/subghz_remote_configurator/helpers/subrem_custom_event.h index 779458c20..da3de2aae 100644 --- a/applications/external/subghz_remote_configurator/helpers/subrem_custom_event.h +++ b/applications/external/subghz_remote_configurator/helpers/subrem_custom_event.h @@ -9,11 +9,13 @@ typedef enum { } SubRemEditMenuState; typedef enum { - // SubmenuIndex + // StartSubmenuIndex SubmenuIndexSubRemEditMapFile = 0, SubmenuIndexSubRemNewMapFile, +#if FURI_DEBUG SubmenuIndexSubRemRemoteView, - SubmenuIndexSubRemAbout, +#endif + // SubmenuIndexSubRemAbout, // EditSubmenuIndex EditSubmenuIndexEditLabel, @@ -45,8 +47,4 @@ typedef enum { SubRemCustomEventSceneEditPreviewSaved, SubRemCustomEventSceneNewName, - - // // SceneStates - // SubRemSceneOpenMapFileStateOpen, - // SubRemSceneOpenMapFileStateEdit, } SubRemCustomEvent; \ No newline at end of file diff --git a/applications/external/subghz_remote_configurator/helpers/subrem_presets.c b/applications/external/subghz_remote_configurator/helpers/subrem_presets.c index dc298c069..e5823b721 100644 --- a/applications/external/subghz_remote_configurator/helpers/subrem_presets.c +++ b/applications/external/subghz_remote_configurator/helpers/subrem_presets.c @@ -147,8 +147,7 @@ SubRemLoadSubState subrem_sub_preset_load( if(protocol->flag & SubGhzProtocolFlag_Send) { if((protocol->type == SubGhzProtocolTypeStatic) || (protocol->type == SubGhzProtocolTypeDynamic) || - // TODO: BINRAW It probably works, but checks are needed. - // (protocol->type == SubGhzProtocolTypeBinRAW) || + (protocol->type == SubGhzProtocolTypeBinRAW) || (protocol->type == SubGhzProtocolTypeRAW)) { sub_preset->type = protocol->type; } else { diff --git a/applications/external/subghz_remote_configurator/subghz_remote_app_i.h b/applications/external/subghz_remote_configurator/subghz_remote_app_i.h index ce5f31009..a84e1ba50 100644 --- a/applications/external/subghz_remote_configurator/subghz_remote_app_i.h +++ b/applications/external/subghz_remote_configurator/subghz_remote_app_i.h @@ -23,10 +23,6 @@ #include -#include -#include -#include - #define SUBREM_APP_FOLDER EXT_PATH("subghz_remote") #define SUBREM_MAX_LEN_NAME 64 diff --git a/applications/main/subghz_remote/helpers/subrem_custom_event.h b/applications/main/subghz_remote/helpers/subrem_custom_event.h index e4bd95143..8d93ab1fd 100644 --- a/applications/main/subghz_remote/helpers/subrem_custom_event.h +++ b/applications/main/subghz_remote/helpers/subrem_custom_event.h @@ -1,7 +1,7 @@ #pragma once typedef enum { - // SubmenuIndex + // StartSubmenuIndex SubmenuIndexSubRemOpenMapFile = 0, #if FURI_DEBUG SubmenuIndexSubRemRemoteView, diff --git a/applications/main/subghz_remote/helpers/subrem_presets.c b/applications/main/subghz_remote/helpers/subrem_presets.c index dc298c069..e5823b721 100644 --- a/applications/main/subghz_remote/helpers/subrem_presets.c +++ b/applications/main/subghz_remote/helpers/subrem_presets.c @@ -147,8 +147,7 @@ SubRemLoadSubState subrem_sub_preset_load( if(protocol->flag & SubGhzProtocolFlag_Send) { if((protocol->type == SubGhzProtocolTypeStatic) || (protocol->type == SubGhzProtocolTypeDynamic) || - // TODO: BINRAW It probably works, but checks are needed. - // (protocol->type == SubGhzProtocolTypeBinRAW) || + (protocol->type == SubGhzProtocolTypeBinRAW) || (protocol->type == SubGhzProtocolTypeRAW)) { sub_preset->type = protocol->type; } else { From a260465721171f5c4ed0e97276fbbbbde58289e9 Mon Sep 17 00:00:00 2001 From: gid9798 <30450294+gid9798@users.noreply.github.com> Date: Tue, 30 May 2023 22:18:54 +0300 Subject: [PATCH 32/52] Prog_mode to custom_btn --- .../main/subghz/helpers/subghz_txrx.c | 2 +- .../scenes/subghz_scene_receiver_info.c | 1 - .../subghz/scenes/subghz_scene_transmitter.c | 1 - .../main/subghz_remote/subghz_remote_app_i.c | 3 - firmware/targets/f7/api_symbols.csv | 8 --- lib/subghz/blocks/custom_btn.c | 13 ++++- lib/subghz/blocks/custom_btn.h | 4 -- lib/subghz/blocks/custom_btn_i.h | 17 ++++++ lib/subghz/protocols/alutech_at_4n.c | 2 +- lib/subghz/protocols/came_atomo.c | 2 +- lib/subghz/protocols/keeloq.c | 56 +++++++++---------- lib/subghz/protocols/keeloq.h | 4 -- lib/subghz/protocols/nice_flor_s.c | 2 +- lib/subghz/protocols/secplus_v2.c | 2 +- lib/subghz/protocols/somfy_telis.c | 2 +- 15 files changed, 61 insertions(+), 58 deletions(-) create mode 100644 lib/subghz/blocks/custom_btn_i.h diff --git a/applications/main/subghz/helpers/subghz_txrx.c b/applications/main/subghz/helpers/subghz_txrx.c index 9d957cd29..79d05b5be 100644 --- a/applications/main/subghz/helpers/subghz_txrx.c +++ b/applications/main/subghz/helpers/subghz_txrx.c @@ -1,5 +1,6 @@ #include "subghz_txrx_i.h" #include +#include #define TAG "SubGhz" @@ -561,7 +562,6 @@ void subghz_txrx_reset_dynamic(SubGhzTxRx* instance) { furi_assert(instance); subghz_environment_reset_keeloq(instance->environment); - keeloq_reset_original_btn(); subghz_custom_btns_reset(); } diff --git a/applications/main/subghz/scenes/subghz_scene_receiver_info.c b/applications/main/subghz/scenes/subghz_scene_receiver_info.c index d9ba5bd84..b0c538a58 100644 --- a/applications/main/subghz/scenes/subghz_scene_receiver_info.c +++ b/applications/main/subghz/scenes/subghz_scene_receiver_info.c @@ -108,7 +108,6 @@ void subghz_scene_receiver_info_draw_widget(SubGhz* subghz) { void subghz_scene_receiver_info_on_enter(void* context) { SubGhz* subghz = context; - keeloq_reset_original_btn(); subghz_custom_btns_reset(); subghz_scene_receiver_info_draw_widget(subghz); diff --git a/applications/main/subghz/scenes/subghz_scene_transmitter.c b/applications/main/subghz/scenes/subghz_scene_transmitter.c index 933f619f0..dba8d13c7 100644 --- a/applications/main/subghz/scenes/subghz_scene_transmitter.c +++ b/applications/main/subghz/scenes/subghz_scene_transmitter.c @@ -46,7 +46,6 @@ bool subghz_scene_transmitter_update_data_show(void* context) { void subghz_scene_transmitter_on_enter(void* context) { SubGhz* subghz = context; - keeloq_reset_original_btn(); subghz_custom_btns_reset(); if(!subghz_scene_transmitter_update_data_show(subghz)) { diff --git a/applications/main/subghz_remote/subghz_remote_app_i.c b/applications/main/subghz_remote/subghz_remote_app_i.c index 6086b4c25..6ed8978de 100644 --- a/applications/main/subghz_remote/subghz_remote_app_i.c +++ b/applications/main/subghz_remote/subghz_remote_app_i.c @@ -179,8 +179,6 @@ bool subrem_tx_start_sub( FURI_LOG_I(TAG, "Send %s", furi_string_get_cstr(sub_preset->label)); - subghz_custom_btn_set(SUBGHZ_CUSTOM_BTN_OK); - keeloq_reset_original_btn(); subghz_custom_btns_reset(); do { @@ -257,7 +255,6 @@ bool subrem_tx_stop_sub(SubGhzRemoteApp* app, bool forced) { sub_preset->fff_data, furi_string_get_cstr(sub_preset->file_path)); subghz_environment_reset_keeloq(app->environment); - keeloq_reset_original_btn(); subghz_custom_btns_reset(); } diff --git a/firmware/targets/f7/api_symbols.csv b/firmware/targets/f7/api_symbols.csv index 1e00e181c..a7470a0b9 100644 --- a/firmware/targets/f7/api_symbols.csv +++ b/firmware/targets/f7/api_symbols.csv @@ -1825,7 +1825,6 @@ Function,-,j1f,float,float Function,-,jn,double,"int, double" Function,-,jnf,float,"int, float" Function,-,jrand48,long,unsigned short[3] -Function,-,keeloq_reset_original_btn,void, Function,-,l64a,char*,long Function,-,labs,long,long Function,-,lcong48,void,unsigned short[7] @@ -2712,13 +2711,6 @@ Function,+,subghz_block_generic_deserialize,SubGhzProtocolStatus,"SubGhzBlockGen Function,+,subghz_block_generic_deserialize_check_count_bit,SubGhzProtocolStatus,"SubGhzBlockGeneric*, FlipperFormat*, uint16_t" Function,+,subghz_block_generic_get_preset_name,void,"const char*, FuriString*" Function,+,subghz_block_generic_serialize,SubGhzProtocolStatus,"SubGhzBlockGeneric*, FlipperFormat*, SubGhzRadioPreset*" -Function,-,subghz_custom_btn_get,uint8_t, -Function,-,subghz_custom_btn_get_original,uint8_t, -Function,-,subghz_custom_btn_is_allowed,_Bool, -Function,-,subghz_custom_btn_set,_Bool,uint8_t -Function,-,subghz_custom_btn_set_max,void,uint8_t -Function,-,subghz_custom_btn_set_original,void,uint8_t -Function,-,subghz_custom_btns_reset,void, Function,+,subghz_environment_alloc,SubGhzEnvironment*, Function,+,subghz_environment_free,void,SubGhzEnvironment* Function,+,subghz_environment_get_alutech_at_4n_rainbow_table_file_name,const char*,SubGhzEnvironment* diff --git a/lib/subghz/blocks/custom_btn.c b/lib/subghz/blocks/custom_btn.c index 275a4c930..1919fc5e4 100644 --- a/lib/subghz/blocks/custom_btn.c +++ b/lib/subghz/blocks/custom_btn.c @@ -1,8 +1,9 @@ -#include "custom_btn.h" +#include "custom_btn_i.h" static uint8_t custom_btn_id = SUBGHZ_CUSTOM_BTN_OK; static uint8_t custom_btn_original = 0; static uint8_t custom_btn_max_btns = 0; +static uint8_t controller_programming_mode = PROG_MODE_OFF; bool subghz_custom_btn_set(uint8_t btn_id) { if(btn_id > custom_btn_max_btns) { @@ -33,8 +34,18 @@ void subghz_custom_btn_set_max(uint8_t b) { void subghz_custom_btns_reset() { custom_btn_original = 0; custom_btn_max_btns = 0; + controller_programming_mode = PROG_MODE_OFF; + custom_btn_id = SUBGHZ_CUSTOM_BTN_OK; } bool subghz_custom_btn_is_allowed() { return custom_btn_max_btns != 0; +} + +void subghz_custom_btn_set_prog_mode(ProgMode prog_mode) { + controller_programming_mode = prog_mode; +} + +ProgMode subghz_custom_btn_get_prog_mode() { + return controller_programming_mode; } \ No newline at end of file diff --git a/lib/subghz/blocks/custom_btn.h b/lib/subghz/blocks/custom_btn.h index c13842fa8..e06457ccd 100644 --- a/lib/subghz/blocks/custom_btn.h +++ b/lib/subghz/blocks/custom_btn.h @@ -15,12 +15,8 @@ bool subghz_custom_btn_set(uint8_t btn_id); uint8_t subghz_custom_btn_get(); -void subghz_custom_btn_set_original(uint8_t btn_code); - uint8_t subghz_custom_btn_get_original(); -void subghz_custom_btn_set_max(uint8_t b); - void subghz_custom_btns_reset(); bool subghz_custom_btn_is_allowed(); \ No newline at end of file diff --git a/lib/subghz/blocks/custom_btn_i.h b/lib/subghz/blocks/custom_btn_i.h new file mode 100644 index 000000000..f75ba4068 --- /dev/null +++ b/lib/subghz/blocks/custom_btn_i.h @@ -0,0 +1,17 @@ +#pragma once + +#include "custom_btn.h" + +#define PROG_MODE_OFF (0U) +#define PROG_MODE_KEELOQ_BFT (1U) +#define PROG_MODE_KEELOQ_APRIMATIC (2U) + +typedef uint8_t ProgMode; + +void subghz_custom_btn_set_original(uint8_t btn_code); + +void subghz_custom_btn_set_max(uint8_t b); + +void subghz_custom_btn_set_prog_mode(ProgMode prog_mode); + +ProgMode subghz_custom_btn_get_prog_mode(); \ No newline at end of file diff --git a/lib/subghz/protocols/alutech_at_4n.c b/lib/subghz/protocols/alutech_at_4n.c index 281e820f0..1a35550c6 100644 --- a/lib/subghz/protocols/alutech_at_4n.c +++ b/lib/subghz/protocols/alutech_at_4n.c @@ -5,7 +5,7 @@ #include "../blocks/generic.h" #include "../blocks/math.h" -#include "../blocks/custom_btn.h" +#include "../blocks/custom_btn_i.h" #define TAG "SubGhzProtocoAlutech_at_4n" diff --git a/lib/subghz/protocols/came_atomo.c b/lib/subghz/protocols/came_atomo.c index 4723ec99f..cea7ebf6f 100644 --- a/lib/subghz/protocols/came_atomo.c +++ b/lib/subghz/protocols/came_atomo.c @@ -7,7 +7,7 @@ #include "../blocks/generic.h" #include "../blocks/math.h" -#include "../blocks/custom_btn.h" +#include "../blocks/custom_btn_i.h" #define TAG "SubGhzProtocoCameAtomo" diff --git a/lib/subghz/protocols/keeloq.c b/lib/subghz/protocols/keeloq.c index df7ae748d..2163c0500 100644 --- a/lib/subghz/protocols/keeloq.c +++ b/lib/subghz/protocols/keeloq.c @@ -10,15 +10,11 @@ #include "../blocks/generic.h" #include "../blocks/math.h" -#include "../blocks/custom_btn.h" +#include "../blocks/custom_btn_i.h" #include "../subghz_keystore_i.h" #define TAG "SubGhzProtocolKeeloq" -#define KEELOQ_PROG_MODE_OFF (0U) -#define KEELOQ_PROG_MODE_BFT (1U) -#define KEELOQ_PROG_MODE_APRIMATIC (2U) - static const SubGhzBlockConst subghz_protocol_keeloq_const = { .te_short = 400, .te_long = 800, @@ -91,15 +87,6 @@ const SubGhzProtocol subghz_protocol_keeloq = { .encoder = &subghz_protocol_keeloq_encoder, }; -static uint8_t klq_prog_mode; -static uint16_t temp_counter; - -void keeloq_reset_original_btn() { - subghz_custom_btns_reset(); - temp_counter = 0; - klq_prog_mode = KEELOQ_PROG_MODE_OFF; -} - /** * Analysis of received data * @param instance Pointer to a SubGhzBlockGeneric* instance @@ -156,29 +143,32 @@ static bool subghz_protocol_keeloq_gen_data( } // programming mode on / off conditions + ProgMode prog_mode = subghz_custom_btn_get_prog_mode(); if(strcmp(instance->manufacture_name, "BFT") == 0) { // BFT programming mode on / off conditions if(btn == 0xF) { - klq_prog_mode = KEELOQ_PROG_MODE_BFT; - } else if(klq_prog_mode == KEELOQ_PROG_MODE_BFT) { - klq_prog_mode = KEELOQ_PROG_MODE_OFF; + prog_mode = PROG_MODE_KEELOQ_BFT; + } else if(prog_mode == PROG_MODE_KEELOQ_BFT) { + prog_mode = PROG_MODE_OFF; } } else if(strcmp(instance->manufacture_name, "Aprimatic") == 0) { // Aprimatic programming mode on / off conditions if(btn == 0xF) { - klq_prog_mode = KEELOQ_PROG_MODE_APRIMATIC; - } else if(klq_prog_mode == KEELOQ_PROG_MODE_APRIMATIC) { - klq_prog_mode = KEELOQ_PROG_MODE_OFF; + prog_mode = PROG_MODE_KEELOQ_APRIMATIC; + } else if(prog_mode == PROG_MODE_KEELOQ_APRIMATIC) { + prog_mode = PROG_MODE_OFF; } } + subghz_custom_btn_set_prog_mode(prog_mode); + // If we using BFT programming mode we will trasmit its seed in hop part like original remote - if(klq_prog_mode == KEELOQ_PROG_MODE_BFT) { + if(prog_mode == PROG_MODE_KEELOQ_BFT) { hop = instance->generic.seed; - } else if(klq_prog_mode == KEELOQ_PROG_MODE_APRIMATIC) { + } else if(prog_mode == PROG_MODE_KEELOQ_APRIMATIC) { // If we using Aprimatic programming mode we will trasmit some strange looking hop value, why? cuz manufacturer did it this way :) hop = 0x1A2B3C4D; } - if(counter_up && klq_prog_mode == KEELOQ_PROG_MODE_OFF) { + if(counter_up && prog_mode == PROG_MODE_OFF) { if(instance->generic.cnt < 0xFFFF) { if((instance->generic.cnt + furi_hal_subghz_get_rolling_counter_mult()) >= 0xFFFF) { instance->generic.cnt = 0; @@ -189,7 +179,7 @@ static bool subghz_protocol_keeloq_gen_data( instance->generic.cnt = 0; } } - if(klq_prog_mode == KEELOQ_PROG_MODE_OFF) { + if(prog_mode == PROG_MODE_OFF) { // Protocols that do not use encryption if(strcmp(instance->manufacture_name, "Unknown") == 0) { code_found_reverse = subghz_protocol_blocks_reverse_key( @@ -390,9 +380,10 @@ static bool if(instance->manufacture_name == 0x0) { instance->manufacture_name = ""; } - if(klq_prog_mode == KEELOQ_PROG_MODE_BFT) { + ProgMode prog_mode = subghz_custom_btn_get_prog_mode(); + if(prog_mode == PROG_MODE_KEELOQ_BFT) { instance->manufacture_name = "BFT"; - } else if(klq_prog_mode == KEELOQ_PROG_MODE_APRIMATIC) { + } else if(prog_mode == PROG_MODE_KEELOQ_APRIMATIC) { instance->manufacture_name = "Aprimatic"; } uint8_t klq_last_custom_btn = 0xA; @@ -570,7 +561,7 @@ void* subghz_protocol_decoder_keeloq_alloc(SubGhzEnvironment* environment) { instance->keystore = subghz_environment_get_keystore(environment); instance->manufacture_from_file = furi_string_alloc(); - klq_prog_mode = KEELOQ_PROG_MODE_OFF; + subghz_custom_btn_set_prog_mode(PROG_MODE_OFF); return instance; } @@ -930,9 +921,11 @@ static void subghz_protocol_keeloq_check_remote_controller( uint64_t key = subghz_protocol_blocks_reverse_key(instance->data, instance->data_count_bit); uint32_t key_fix = key >> 32; uint32_t key_hop = key & 0x00000000ffffffff; + static uint16_t temp_counter = 0; // Be careful with prog_mode // If we are in BFT / Aprimatic programming mode we will set previous remembered counter and skip mf keys check - if(klq_prog_mode == KEELOQ_PROG_MODE_OFF) { + ProgMode prog_mode = subghz_custom_btn_get_prog_mode(); + if(prog_mode == PROG_MODE_OFF) { // Check key AN-Motors if((key_hop >> 24) == ((key_hop >> 16) & 0x00ff) && (key_fix >> 28) == ((key_hop >> 12) & 0x0f) && (key_hop & 0xFFF) == 0x404) { @@ -949,14 +942,17 @@ static void subghz_protocol_keeloq_check_remote_controller( } temp_counter = instance->cnt; - } else if(klq_prog_mode == KEELOQ_PROG_MODE_BFT) { + } else if(prog_mode == PROG_MODE_KEELOQ_BFT) { *manufacture_name = "BFT"; keystore->mfname = *manufacture_name; instance->cnt = temp_counter; - } else if(klq_prog_mode == KEELOQ_PROG_MODE_APRIMATIC) { + } else if(prog_mode == PROG_MODE_KEELOQ_APRIMATIC) { *manufacture_name = "Aprimatic"; keystore->mfname = *manufacture_name; instance->cnt = temp_counter; + } else { + // Counter protection + furi_crash("Unsuported Prog Mode"); } instance->serial = key_fix & 0x0FFFFFFF; diff --git a/lib/subghz/protocols/keeloq.h b/lib/subghz/protocols/keeloq.h index 26f569e8c..a757e82d5 100644 --- a/lib/subghz/protocols/keeloq.h +++ b/lib/subghz/protocols/keeloq.h @@ -2,8 +2,6 @@ #include "base.h" -#include "../blocks/custom_btn.h" - #define SUBGHZ_PROTOCOL_KEELOQ_NAME "KeeLoq" typedef struct SubGhzProtocolDecoderKeeloq SubGhzProtocolDecoderKeeloq; @@ -13,8 +11,6 @@ extern const SubGhzProtocolDecoder subghz_protocol_keeloq_decoder; extern const SubGhzProtocolEncoder subghz_protocol_keeloq_encoder; extern const SubGhzProtocol subghz_protocol_keeloq; -void keeloq_reset_original_btn(); - /** * Allocate SubGhzProtocolEncoderKeeloq. * @param environment Pointer to a SubGhzEnvironment instance diff --git a/lib/subghz/protocols/nice_flor_s.c b/lib/subghz/protocols/nice_flor_s.c index 5eaa21274..eca9c4e95 100644 --- a/lib/subghz/protocols/nice_flor_s.c +++ b/lib/subghz/protocols/nice_flor_s.c @@ -6,7 +6,7 @@ #include "../blocks/generic.h" #include "../blocks/math.h" -#include "../blocks/custom_btn.h" +#include "../blocks/custom_btn_i.h" /* * https://phreakerclub.com/1615 diff --git a/lib/subghz/protocols/secplus_v2.c b/lib/subghz/protocols/secplus_v2.c index d39f794ab..607c929ea 100644 --- a/lib/subghz/protocols/secplus_v2.c +++ b/lib/subghz/protocols/secplus_v2.c @@ -7,7 +7,7 @@ #include "../blocks/generic.h" #include "../blocks/math.h" -#include "../blocks/custom_btn.h" +#include "../blocks/custom_btn_i.h" /* * Help diff --git a/lib/subghz/protocols/somfy_telis.c b/lib/subghz/protocols/somfy_telis.c index 6a159a7ea..5fbd90275 100644 --- a/lib/subghz/protocols/somfy_telis.c +++ b/lib/subghz/protocols/somfy_telis.c @@ -7,7 +7,7 @@ #include "../blocks/generic.h" #include "../blocks/math.h" -#include "../blocks/custom_btn.h" +#include "../blocks/custom_btn_i.h" #define TAG "SubGhzProtocolSomfyTelis" From 6ad58276f89cbf92a86800e94d9b7bd007ce99ac Mon Sep 17 00:00:00 2001 From: gid9798 <30450294+gid9798@users.noreply.github.com> Date: Tue, 30 May 2023 22:21:47 +0300 Subject: [PATCH 33/52] Cleanup and rename --- applications/main/subghz/helpers/subghz_txrx.c | 2 +- applications/main/subghz/helpers/subghz_txrx.h | 2 +- applications/main/subghz/scenes/subghz_scene_receiver_info.c | 4 +--- applications/main/subghz/scenes/subghz_scene_rpc.c | 4 +--- applications/main/subghz/scenes/subghz_scene_transmitter.c | 4 +--- 5 files changed, 5 insertions(+), 11 deletions(-) diff --git a/applications/main/subghz/helpers/subghz_txrx.c b/applications/main/subghz/helpers/subghz_txrx.c index 79d05b5be..3275b7288 100644 --- a/applications/main/subghz/helpers/subghz_txrx.c +++ b/applications/main/subghz/helpers/subghz_txrx.c @@ -558,7 +558,7 @@ bool subghz_txrx_get_debug_pin_state(SubGhzTxRx* instance) { return instance->debug_pin_state; } -void subghz_txrx_reset_dynamic(SubGhzTxRx* instance) { +void subghz_txrx_reset_dynamic_and_custom_btns(SubGhzTxRx* instance) { furi_assert(instance); subghz_environment_reset_keeloq(instance->environment); diff --git a/applications/main/subghz/helpers/subghz_txrx.h b/applications/main/subghz/helpers/subghz_txrx.h index 6c28cc5f0..6ad5d97bd 100644 --- a/applications/main/subghz/helpers/subghz_txrx.h +++ b/applications/main/subghz/helpers/subghz_txrx.h @@ -293,6 +293,6 @@ void subghz_txrx_set_raw_file_encoder_worker_callback_end( void subghz_txrx_set_debug_pin_state(SubGhzTxRx* instance, bool state); bool subghz_txrx_get_debug_pin_state(SubGhzTxRx* instance); -void subghz_txrx_reset_dynamic(SubGhzTxRx* instance); +void subghz_txrx_reset_dynamic_and_custom_btns(SubGhzTxRx* instance); SubGhzReceiver* subghz_txrx_get_receiver(SubGhzTxRx* instance); // TODO use only in DecodeRaw diff --git a/applications/main/subghz/scenes/subghz_scene_receiver_info.c b/applications/main/subghz/scenes/subghz_scene_receiver_info.c index b0c538a58..e3ff485d2 100644 --- a/applications/main/subghz/scenes/subghz_scene_receiver_info.c +++ b/applications/main/subghz/scenes/subghz_scene_receiver_info.c @@ -1,7 +1,5 @@ #include "../subghz_i.h" #include "../helpers/subghz_custom_event.h" -#include -#include #include @@ -190,5 +188,5 @@ void subghz_scene_receiver_info_on_exit(void* context) { SubGhz* subghz = context; widget_reset(subghz->widget); - subghz_txrx_reset_dynamic(subghz->txrx); + subghz_txrx_reset_dynamic_and_custom_btns(subghz->txrx); } diff --git a/applications/main/subghz/scenes/subghz_scene_rpc.c b/applications/main/subghz/scenes/subghz_scene_rpc.c index edadc89bb..7b3c940a5 100644 --- a/applications/main/subghz/scenes/subghz_scene_rpc.c +++ b/applications/main/subghz/scenes/subghz_scene_rpc.c @@ -1,6 +1,4 @@ #include "../subghz_i.h" -#include -#include #include @@ -110,5 +108,5 @@ void subghz_scene_rpc_on_exit(void* context) { popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignTop); popup_set_icon(popup, 0, 0, NULL); - subghz_txrx_reset_dynamic(subghz->txrx); + subghz_txrx_reset_dynamic_and_custom_btns(subghz->txrx); } diff --git a/applications/main/subghz/scenes/subghz_scene_transmitter.c b/applications/main/subghz/scenes/subghz_scene_transmitter.c index dba8d13c7..ab5605f95 100644 --- a/applications/main/subghz/scenes/subghz_scene_transmitter.c +++ b/applications/main/subghz/scenes/subghz_scene_transmitter.c @@ -1,8 +1,6 @@ #include "../subghz_i.h" #include "../views/transmitter.h" #include -#include -#include #include @@ -107,5 +105,5 @@ void subghz_scene_transmitter_on_exit(void* context) { SubGhz* subghz = context; subghz->state_notifications = SubGhzNotificationStateIDLE; - subghz_txrx_reset_dynamic(subghz->txrx); + subghz_txrx_reset_dynamic_and_custom_btns(subghz->txrx); } From fabbfc3979ca10412a8cdfdac74539a55933e8f1 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Wed, 31 May 2023 10:29:57 +0300 Subject: [PATCH 34/52] Update audio ir asset by @amec0e --- assets/resources/infrared/assets/audio.ir | 399 +++++++++++++++++++++- 1 file changed, 392 insertions(+), 7 deletions(-) diff --git a/assets/resources/infrared/assets/audio.ir b/assets/resources/infrared/assets/audio.ir index 72d07c82b..0aa0dcebe 100644 --- a/assets/resources/infrared/assets/audio.ir +++ b/assets/resources/infrared/assets/audio.ir @@ -2178,7 +2178,55 @@ address: 00 00 00 00 command: 46 00 00 00 # # Audio_Receivers -# +# +name: Prev +type: parsed +protocol: RC5 +address: 14 00 00 00 +command: 2C 00 00 00 +# +name: Next +type: parsed +protocol: RC5 +address: 14 00 00 00 +command: 2B 00 00 00 +# +name: Next +type: parsed +protocol: NECext +address: D2 03 00 00 +command: 1D E2 00 00 +# +name: Next +type: parsed +protocol: RC5 +address: 14 00 00 00 +command: 34 00 00 00 +# +name: Prev +type: parsed +protocol: SIRC20 +address: 10 01 00 00 +command: 30 00 00 00 +# +name: Next +type: parsed +protocol: SIRC20 +address: 10 01 00 00 +command: 31 00 00 00 +# +name: Next +type: parsed +protocol: NEC +address: 78 00 00 00 +command: 03 00 00 00 +# +name: Next +type: parsed +protocol: NECext +address: 7F 01 00 00 +command: 6B 94 00 00 +# name: Pause type: parsed protocol: NEC @@ -2329,12 +2377,6 @@ protocol: Kaseikyo address: AC 02 20 01 command: 91 00 00 00 # -name: Play -type: raw -frequency: 38000 -duty_cycle: 0.33 -data: 3467 1720 449 450 419 1296 443 455 425 446 423 447 422 449 420 451 418 452 417 454 426 445 424 447 422 448 421 450 419 1296 443 455 425 446 423 447 422 449 420 450 419 452 417 454 426 1290 449 448 421 1294 445 453 416 455 425 1291 448 1294 445 1297 453 418 451 447 422 448 421 423 446 1296 443 1300 450 448 421 422 447 424 445 425 444 427 453 418 451 1292 447 450 419 1297 442 1300 450 1292 447 451 418 1297 453 74912 3466 1722 447 424 445 1297 453 418 451 420 449 421 448 423 446 425 444 427 453 418 451 420 449 421 448 423 446 424 445 1297 453 419 450 420 449 422 447 424 445 425 444 427 453 418 451 1291 448 423 446 1296 443 428 452 419 450 1292 447 1295 444 1298 452 420 449 421 448 423 446 425 444 1298 452 1290 449 422 447 424 445 425 444 427 453 418 451 420 449 1293 446 425 444 1298 452 1290 449 1294 445 425 444 1298 452 -# name: Next type: parsed protocol: Kaseikyo @@ -2463,6 +2505,54 @@ command: 67 98 00 00 # # CD Players # +name: Next +type: parsed +protocol: Kaseikyo +address: 51 54 32 01 +command: 0E 00 00 00 +# +name: Play +type: parsed +protocol: Kaseikyo +address: 51 54 32 01 +command: 0A 00 00 00 +# +name: Play +type: parsed +protocol: Samsung32 +address: 10 00 00 00 +command: 07 00 00 00 +# +name: Pause +type: parsed +protocol: Kaseikyo +address: 51 54 32 01 +command: 0A 00 00 00 +# +name: Pause +type: parsed +protocol: Samsung32 +address: 10 00 00 00 +command: 07 00 00 00 +# +name: Play +type: raw +frequency: 38000 +duty_cycle: 0.330000 +data: 8546 4227 563 511 563 1558 566 511 563 483 566 508 567 1558 566 509 566 1558 566 1586 564 483 566 1561 588 1558 566 1560 564 536 539 1558 566 535 539 1558 566 1586 564 1557 567 486 589 1560 564 511 563 510 539 508 567 485 589 484 565 508 567 1559 565 509 566 1560 564 1560 590 1585 539 25430 8575 4251 538 485 590 1557 567 486 588 511 538 536 539 1557 567 509 566 1558 566 1560 590 483 566 1560 589 1559 565 1562 562 536 539 1560 564 509 566 1558 566 1564 586 1586 538 484 590 1559 565 487 588 482 567 509 566 511 563 483 566 508 567 1558 566 509 566 1560 564 1559 591 1586 538 +# +name: Pause +type: raw +frequency: 38000 +duty_cycle: 0.330000 +data: 8571 4226 564 509 540 1587 563 510 539 510 565 510 564 1558 566 510 565 1584 540 1585 539 535 540 1587 537 1586 564 1585 539 510 564 1584 540 511 563 482 567 535 539 485 590 1584 540 1585 539 509 566 510 564 510 539 1586 564 1585 539 1585 539 536 539 510 564 1585 539 1557 567 1558 592 25434 8571 4199 591 510 539 1586 564 509 540 535 540 485 590 1585 539 484 591 1561 563 1584 540 507 568 1585 539 1586 564 1585 539 486 589 1585 539 484 591 425 624 535 540 486 589 1585 539 1585 539 511 564 511 563 486 563 1586 564 1558 566 1558 566 508 567 486 589 1560 564 1558 566 1561 589 +# +name: Next +type: parsed +protocol: SIRC15 +address: 64 00 00 00 +command: 3B 00 00 00 +# name: Play type: parsed protocol: NEC42 @@ -2585,6 +2675,169 @@ command: 01 FE 00 00 # # SoundBars # +# +name: Play +type: parsed +protocol: NECext +address: 29 A1 00 00 +command: 9A 65 00 00 +# +name: Pause +type: parsed +protocol: NECext +address: 29 A1 00 00 +command: 9A 65 00 00 +# +name: Next +type: parsed +protocol: Samsung32 +address: 2C 00 00 00 +command: 07 00 00 00 +# +name: Prev +type: parsed +protocol: Samsung32 +address: 2C 00 00 00 +command: 06 00 00 00 +# +name: Next +type: parsed +protocol: NECext +address: C8 91 00 00 +command: 24 DB 00 00 +# +name: Play +type: raw +frequency: 38000 +duty_cycle: 0.330000 +data: 4572 4451 552 478 526 478 526 478 500 503 501 1483 525 1482 551 478 525 478 525 1481 526 1482 524 1483 523 1485 522 482 521 482 522 482 522 469 521 4486 521 482 522 482 522 483 521 483 521 483 521 1487 521 483 521 1487 521 483 521 483 521 483 521 1487 521 1487 521 483 520 1487 521 483 521 1488 520 1487 521 1487 521 483 521 55487 4544 4482 522 482 522 482 522 482 522 482 522 1487 521 1487 521 482 522 482 522 1487 521 1487 521 1487 521 1487 521 482 522 483 521 483 521 469 522 4486 521 483 521 483 520 483 521 483 521 483 521 1487 521 483 521 1487 521 483 521 483 521 483 521 1488 521 1487 521 483 521 1488 520 483 521 1488 521 1488 521 1488 520 483 521 +# +name: Play +type: raw +frequency: 38000 +duty_cycle: 0.330000 +data: 4497 4438 513 508 492 503 487 509 491 504 486 1479 512 1479 511 510 490 505 485 1481 510 1481 510 1481 509 1482 509 512 488 507 483 513 487 508 482 4457 515 506 484 511 489 506 484 512 488 507 483 1482 509 513 487 1478 513 508 482 513 487 509 491 1473 518 1474 517 504 486 1479 512 510 490 1475 515 1475 516 1476 514 480 510 55019 4494 4442 509 511 489 507 483 512 488 507 483 1508 483 1508 483 513 487 508 482 1482 509 1483 508 1509 492 1499 492 504 486 510 490 505 485 510 490 4449 513 508 482 487 513 508 482 488 512 483 517 1499 492 504 486 1505 486 510 490 479 511 510 490 1501 490 1501 490 506 484 1506 485 511 489 1502 489 1476 515 1476 515 507 483 +# +name: Pause +type: raw +frequency: 38000 +duty_cycle: 0.330000 +data: 4572 4451 552 478 526 478 526 478 500 503 501 1483 525 1482 551 478 525 478 525 1481 526 1482 524 1483 523 1485 522 482 521 482 522 482 522 469 521 4486 521 482 522 482 522 483 521 483 521 483 521 1487 521 483 521 1487 521 483 521 483 521 483 521 1487 521 1487 521 483 520 1487 521 483 521 1488 520 1487 521 1487 521 483 521 55487 4544 4482 522 482 522 482 522 482 522 482 522 1487 521 1487 521 482 522 482 522 1487 521 1487 521 1487 521 1487 521 482 522 483 521 483 521 469 522 4486 521 483 521 483 520 483 521 483 521 483 521 1487 521 483 521 1487 521 483 521 483 521 483 521 1488 521 1487 521 483 521 1488 520 483 521 1488 521 1488 521 1488 520 483 521 +# +name: Pause +type: raw +frequency: 38000 +duty_cycle: 0.330000 +data: 4497 4438 513 508 492 503 487 509 491 504 486 1479 512 1479 511 510 490 505 485 1481 510 1481 510 1481 509 1482 509 512 488 507 483 513 487 508 482 4457 515 506 484 511 489 506 484 512 488 507 483 1482 509 513 487 1478 513 508 482 513 487 509 491 1473 518 1474 517 504 486 1479 512 510 490 1475 515 1475 516 1476 514 480 510 55019 4494 4442 509 511 489 507 483 512 488 507 483 1508 483 1508 483 513 487 508 482 1482 509 1483 508 1509 492 1499 492 504 486 510 490 505 485 510 490 4449 513 508 482 487 513 508 482 488 512 483 517 1499 492 504 486 1505 486 510 490 479 511 510 490 1501 490 1501 490 506 484 1506 485 511 489 1502 489 1476 515 1476 515 507 483 +# +name: Next +type: raw +frequency: 38000 +duty_cycle: 0.330000 +data: 4503 4434 517 504 486 510 490 505 485 510 490 1475 515 1476 514 507 483 512 488 1477 513 1477 513 1478 512 1479 511 483 517 479 511 484 516 479 511 4455 516 478 512 483 517 479 511 485 515 480 510 486 514 1477 513 1477 513 482 518 477 513 483 517 1474 516 1474 516 1475 515 480 510 485 515 1476 514 1477 513 1477 513 483 517 55012 4497 4440 511 484 516 480 510 485 515 480 510 1481 509 1482 509 487 513 482 518 1473 517 1474 516 1474 516 1475 515 480 510 486 514 481 509 486 514 4451 510 485 567 428 510 486 514 481 509 487 565 430 570 1421 518 1473 518 478 512 483 517 478 512 1479 511 1480 510 1480 510 486 514 481 509 1481 510 1481 509 1482 509 487 513 +# +name: Play +type: raw +frequency: 38000 +duty_cycle: 0.330000 +data: 4583 4441 575 454 550 455 549 457 548 456 549 1461 550 1460 549 456 549 457 549 1461 548 1462 549 1461 549 1461 548 457 548 457 549 457 547 457 549 4462 548 458 548 457 548 457 548 457 548 457 548 1462 548 457 548 1461 549 457 548 457 548 457 548 1462 548 1461 549 457 548 1461 549 457 548 1461 549 1461 548 1462 547 458 547 55448 4580 4465 550 456 549 456 549 456 550 456 549 1461 549 1460 549 457 549 456 549 1461 549 1461 549 1461 548 1461 549 457 548 457 549 457 548 457 548 4462 549 457 548 457 548 458 548 457 548 457 548 1462 549 457 547 1462 549 457 548 457 548 457 548 1462 548 1462 549 457 548 1462 548 457 548 1462 548 1461 549 1462 548 457 548 +# +name: Pause +type: raw +frequency: 38000 +duty_cycle: 0.330000 +data: 4583 4441 575 454 550 455 549 457 548 456 549 1461 550 1460 549 456 549 457 549 1461 548 1462 549 1461 549 1461 548 457 548 457 549 457 547 457 549 4462 548 458 548 457 548 457 548 457 548 457 548 1462 548 457 548 1461 549 457 548 457 548 457 548 1462 548 1461 549 457 548 1461 549 457 548 1461 549 1461 548 1462 547 458 547 55448 4580 4465 550 456 549 456 549 456 550 456 549 1461 549 1460 549 457 549 456 549 1461 549 1461 549 1461 548 1461 549 457 548 457 549 457 548 457 548 4462 549 457 548 457 548 458 548 457 548 457 548 1462 549 457 547 1462 549 457 548 457 548 457 548 1462 548 1462 549 457 548 1462 548 457 548 1462 548 1461 549 1462 548 457 548 +# +name: Next +type: raw +frequency: 38000 +duty_cycle: 0.330000 +data: 4582 4465 551 454 550 455 550 455 549 456 549 1460 550 1460 549 457 548 456 549 1461 549 1461 548 1461 549 1460 549 457 549 456 548 457 548 457 548 4461 549 456 548 457 548 457 548 457 548 457 548 457 548 1462 548 1461 547 457 549 457 548 456 549 1460 549 1461 547 1461 549 457 547 457 548 1461 549 1461 548 1461 548 457 548 55436 4578 4464 549 455 549 456 549 455 549 456 550 1460 549 1460 549 456 550 455 550 1460 550 1460 549 1460 550 1460 549 456 549 457 548 457 548 457 549 4461 548 457 548 457 548 457 548 457 547 457 549 457 547 1462 548 1461 549 457 548 457 548 457 548 1461 548 1461 548 1462 548 457 548 457 549 1461 549 1461 548 1461 548 457 548 +# +name: Prev +type: raw +frequency: 38000 +duty_cycle: 0.330000 +data: 4554 4466 540 469 547 490 515 495 521 490 494 1478 522 1477 544 466 539 471 513 1512 488 1484 516 1483 570 1429 540 497 519 465 540 470 546 491 493 4490 548 462 543 467 549 488 517 493 491 1481 519 1480 541 495 489 1510 522 462 543 494 521 489 495 1476 545 466 539 471 513 1485 547 464 520 1505 495 1477 513 1487 545 465 540 +# +name: Next +type: raw +frequency: 38000 +duty_cycle: 0.330000 +data: 4555 4464 542 468 548 462 543 467 549 488 496 1477 523 1476 545 465 551 459 525 1475 515 1484 516 1483 517 1482 550 486 519 465 551 459 546 464 520 4490 547 488 517 467 549 462 543 467 548 462 543 467 517 1482 518 1481 540 496 520 464 541 469 515 1484 516 1483 517 1482 550 460 545 465 519 1480 520 1479 521 1478 543 493 522 +# +name: Play +type: raw +frequency: 38000 +duty_cycle: 0.330000 +data: 4549 4471 546 464 541 469 547 463 542 469 515 1484 516 1483 549 461 544 466 518 1481 519 1480 520 1479 521 1477 544 466 550 461 544 467 549 461 523 4486 541 469 546 464 541 469 547 464 541 469 515 1483 549 462 522 1477 544 465 540 471 545 465 572 1428 520 1479 542 468 569 1430 549 462 522 1476 514 1486 514 1485 547 463 542 +# +name: Play +type: raw +frequency: 38000 +duty_cycle: 0.330000 +data: 4552 4464 586 420 584 420 584 420 612 392 529 1478 531 1478 531 476 553 451 553 1455 554 1479 528 1480 528 1481 527 478 526 478 526 478 526 478 526 4497 526 478 526 478 526 478 526 478 526 478 526 1483 526 478 526 1483 526 478 526 478 526 478 526 1483 526 1483 526 478 526 1483 526 479 525 1483 526 1483 526 1483 526 478 526 +# +name: Play +type: raw +frequency: 38000 +duty_cycle: 0.330000 +data: 4548 4471 540 471 541 468 544 467 545 465 516 1482 512 1488 537 473 539 472 519 1479 514 1484 520 1479 515 1485 539 470 542 468 544 466 546 464 517 4493 538 472 540 470 542 468 544 466 546 464 517 1482 543 468 513 544 471 469 574 436 514 1485 519 1480 545 465 547 1452 573 438 543 1456 548 1451 543 1456 569 442 570 +# +name: Pause +type: raw +frequency: 38000 +duty_cycle: 0.330000 +data: 4549 4471 546 464 541 469 547 463 542 469 515 1484 516 1483 549 461 544 466 518 1481 519 1480 520 1479 521 1477 544 466 550 461 544 467 549 461 523 4486 541 469 546 464 541 469 547 464 541 469 515 1483 549 462 522 1477 544 465 540 471 545 465 572 1428 520 1479 542 468 569 1430 549 462 522 1476 514 1486 514 1485 547 463 542 +# +name: Pause +type: raw +frequency: 38000 +duty_cycle: 0.330000 +data: 4552 4464 586 420 584 420 584 420 612 392 529 1478 531 1478 531 476 553 451 553 1455 554 1479 528 1480 528 1481 527 478 526 478 526 478 526 478 526 4497 526 478 526 478 526 478 526 478 526 478 526 1483 526 478 526 1483 526 478 526 478 526 478 526 1483 526 1483 526 478 526 1483 526 479 525 1483 526 1483 526 1483 526 478 526 +# +name: Pause +type: raw +frequency: 38000 +duty_cycle: 0.330000 +data: 4548 4471 540 471 541 468 544 467 545 465 516 1482 512 1488 537 473 539 472 519 1479 514 1484 520 1479 515 1485 539 470 542 468 544 466 546 464 517 4493 538 472 540 470 542 468 544 466 546 464 517 1482 543 468 513 544 471 469 574 436 514 1485 519 1480 545 465 547 1452 573 438 543 1456 548 1451 543 1456 569 442 570 +# +name: Next +type: parsed +protocol: SIRC20 +address: 10 01 00 00 +command: 34 00 00 00 +# +name: Play +type: parsed +protocol: NEC +address: 80 00 00 00 +command: 1B 00 00 00 +# +name: Pause +type: parsed +protocol: NEC +address: 80 00 00 00 +command: 1B 00 00 00 +# +name: Next +type: parsed +protocol: NEC +address: 80 00 00 00 +command: 1F 00 00 00 +# +name: Play +type: parsed +protocol: NEC +address: 00 00 00 00 +command: 41 00 00 00 +# +name: Pause +type: parsed +protocol: NEC +address: 00 00 00 00 +command: 41 00 00 00 +# name: Play type: parsed protocol: NECext @@ -3138,3 +3391,135 @@ type: parsed protocol: NECext address: 2D D3 00 00 command: 06 F9 00 00 +# +name: Play +type: raw +frequency: 38000 +duty_cycle: 0.330000 +data: 1041 1461 540 457 543 453 537 459 541 1459 541 1459 542 1459 541 1459 542 1458 542 1458 543 1458 542 1458 542 453 537 459 541 455 545 451 539 450 540 50518 1041 1461 540 457 543 452 538 459 541 1459 541 1459 542 1459 541 1458 543 1458 542 1458 542 1458 542 1457 544 453 537 459 541 455 545 451 539 449 541 50534 1036 1467 544 452 538 458 542 454 546 1455 545 1454 546 1454 536 1464 537 1464 536 1463 537 1463 537 1463 537 459 541 454 546 450 540 457 543 445 545 +# +name: Pause +type: raw +frequency: 38000 +duty_cycle: 0.330000 +data: 1041 1461 540 457 543 453 537 459 541 1459 541 1459 542 1459 541 1459 542 1458 542 1458 543 1458 542 1458 542 453 537 459 541 455 545 451 539 450 540 50518 1041 1461 540 457 543 452 538 459 541 1459 541 1459 542 1459 541 1458 543 1458 542 1458 542 1458 542 1457 544 453 537 459 541 455 545 451 539 449 541 50534 1036 1467 544 452 538 458 542 454 546 1455 545 1454 546 1454 536 1464 537 1464 536 1463 537 1463 537 1463 537 459 541 454 546 450 540 457 543 445 545 +# +name: Next +type: raw +frequency: 38000 +duty_cycle: 0.330000 +data: 1044 1460 540 456 544 1457 543 1457 543 453 536 1465 545 450 539 457 543 1458 542 1458 542 454 546 451 539 1462 538 458 542 1459 541 1460 540 448 542 50525 1042 1462 538 458 542 1458 542 1459 541 455 545 1456 544 452 537 459 541 1460 540 1460 540 456 544 452 537 1464 536 460 540 1461 539 1461 539 449 540 50542 1046 1458 542 480 520 1455 545 1455 545 477 512 1463 547 474 515 481 519 1456 544 1457 543 478 522 475 514 1460 540 482 518 1457 543 1458 542 445 544 +# +name: Prev +type: raw +frequency: 38000 +duty_cycle: 0.330000 +data: 1046 1457 543 1458 542 454 546 450 539 1461 539 456 544 1458 542 1458 542 454 546 451 539 1461 539 1462 538 458 542 1459 541 454 546 451 539 1454 546 50538 1043 1461 539 1461 539 456 544 453 547 1454 546 449 541 1461 539 1462 538 457 543 453 547 1455 545 1455 545 451 539 1462 538 458 542 454 546 1447 543 50526 1044 1459 541 1459 541 455 545 451 539 1463 537 458 542 1459 541 1460 540 455 545 452 538 1463 537 1464 536 460 540 1461 539 456 544 453 536 1456 544 +# +name: Play +type: raw +frequency: 38000 +duty_cycle: 0.330000 +data: 1013 1488 512 486 514 486 514 1485 515 484 516 484 516 1483 517 1482 518 1481 509 1490 510 1488 512 488 512 1487 513 1485 515 484 516 483 517 481 519 50939 1010 1489 511 488 512 488 512 1486 514 486 514 486 514 1485 515 1483 517 1482 518 1481 509 1489 511 489 511 1487 513 1485 515 484 516 484 516 482 518 50958 1013 1488 512 487 513 487 513 1485 515 485 515 485 515 1484 516 1483 517 1482 518 1481 509 1490 510 490 572 1426 512 1487 513 486 514 486 514 485 566 50908 1011 1490 510 489 511 489 511 1487 513 486 514 487 513 1485 515 1484 516 1483 517 1482 518 1480 510 491 571 1427 511 1488 512 488 512 487 513 486 565 50905 1013 1488 512 488 512 488 512 1486 514 486 514 486 514 1485 515 1484 516 1483 517 1481 509 1489 511 489 511 1488 512 1486 514 485 515 485 515 484 516 +# +name: Pause +type: raw +frequency: 38000 +duty_cycle: 0.330000 +data: 1013 1488 512 486 514 486 514 1485 515 484 516 484 516 1483 517 1482 518 1481 509 1490 510 1488 512 488 512 1487 513 1485 515 484 516 483 517 481 519 50939 1010 1489 511 488 512 488 512 1486 514 486 514 486 514 1485 515 1483 517 1482 518 1481 509 1489 511 489 511 1487 513 1485 515 484 516 484 516 482 518 50958 1013 1488 512 487 513 487 513 1485 515 485 515 485 515 1484 516 1483 517 1482 518 1481 509 1490 510 490 572 1426 512 1487 513 486 514 486 514 485 566 50908 1011 1490 510 489 511 489 511 1487 513 486 514 487 513 1485 515 1484 516 1483 517 1482 518 1480 510 491 571 1427 511 1488 512 488 512 487 513 486 565 50905 1013 1488 512 488 512 488 512 1486 514 486 514 486 514 1485 515 1484 516 1483 517 1481 509 1489 511 489 511 1488 512 1486 514 485 515 485 515 484 516 +# +name: Next +type: parsed +protocol: NEC +address: 77 00 00 00 +command: F7 00 00 00 +# +name: Next +type: parsed +protocol: NECext +address: 10 E7 00 00 +command: 08 F7 00 00 +# +name: Play +type: parsed +protocol: NECext +address: 10 E7 00 00 +command: 5E A1 00 00 +# +name: Pause +type: parsed +protocol: NECext +address: 10 E7 00 00 +command: 5E A1 00 00 +# +name: Next +type: parsed +protocol: NECext +address: 3F 5C 00 00 +command: 16 E9 00 00 +# +name: Prev +type: parsed +protocol: NECext +address: 3F 5C 00 00 +command: 17 E8 00 00 +# +name: Prev +type: parsed +protocol: NEC +address: 02 00 00 00 +command: 02 00 00 00 +# +name: Next +type: parsed +protocol: NEC +address: 02 00 00 00 +command: 05 00 00 00 +# +name: Next +type: raw +frequency: 38000 +duty_cycle: 0.330000 +data: 3303 1908 408 1179 410 1177 412 442 409 444 407 446 405 448 414 1173 405 448 414 1173 416 1172 406 447 415 439 412 1175 414 440 411 1175 414 440 411 1175 414 440 411 442 409 444 407 447 415 438 413 440 411 442 409 444 407 446 405 1182 407 447 415 438 413 440 411 442 409 444 407 1180 409 1178 411 443 408 445 406 1180 409 445 406 447 415 438 413 440 411 442 409 444 407 1180 409 444 407 446 405 448 414 440 411 41789 3301 3346 362 42926 3307 3341 357 +# +name: Prev +type: raw +frequency: 38000 +duty_cycle: 0.330000 +data: 3301 1910 406 1155 434 1180 409 419 432 421 441 439 412 441 410 1178 411 416 435 1152 437 1177 412 442 409 417 434 1180 409 418 433 1180 409 445 406 1155 434 419 432 447 415 413 438 442 409 444 407 419 432 448 414 439 412 442 409 1177 412 442 409 444 407 420 431 448 414 413 438 1176 413 1174 415 413 438 1175 414 1173 405 422 440 440 411 416 435 418 433 447 415 439 412 441 410 1177 412 415 436 417 434 446 405 41164 3301 3321 387 42935 3307 3316 381 42941 3311 3312 385 +# +name: Play +type: raw +frequency: 38000 +duty_cycle: 0.330000 +data: 3309 1901 415 1173 405 1182 407 420 442 412 439 441 410 443 408 1179 410 444 407 1180 409 1179 410 444 407 420 431 1183 406 447 415 1147 442 412 439 1148 441 439 412 441 410 443 408 446 405 448 414 440 411 415 436 444 407 446 405 1182 407 447 415 412 439 440 411 443 408 418 433 1181 408 1180 409 418 433 447 415 439 412 441 410 443 408 445 406 1181 408 1180 409 1178 411 417 434 445 406 421 441 439 412 415 436 41161 3303 3320 388 42939 3301 3347 361 +# +name: Pause +type: raw +frequency: 38000 +duty_cycle: 0.330000 +data: 3309 1901 415 1173 405 1182 407 420 442 412 439 441 410 443 408 1179 410 444 407 1180 409 1179 410 444 407 420 431 1183 406 447 415 1147 442 412 439 1148 441 439 412 441 410 443 408 446 405 448 414 440 411 415 436 444 407 446 405 1182 407 447 415 412 439 440 411 443 408 418 433 1181 408 1180 409 418 433 447 415 439 412 441 410 443 408 445 406 1181 408 1180 409 1178 411 417 434 445 406 421 441 439 412 415 436 41161 3303 3320 388 42939 3301 3347 361 +# +name: Play +type: raw +frequency: 38000 +duty_cycle: 0.330000 +data: 9175 4433 644 1605 645 442 669 466 646 445 666 438 673 466 645 440 671 466 673 410 700 365 720 465 675 367 742 367 744 438 645 1604 675 1574 674 1549 702 1575 673 1576 646 1604 675 1574 676 1574 675 1576 644 1604 645 1606 672 1576 645 466 645 466 645 465 646 1575 675 1605 645 466 645 467 644 467 644 1605 644 1605 645 1606 644 467 644 467 644 1606 643 1578 672 1607 643 +# +name: Next +type: raw +frequency: 38000 +duty_cycle: 0.330000 +data: 9146 4435 642 1577 673 449 662 454 658 451 661 469 642 468 644 469 642 453 659 470 642 470 642 469 643 469 642 469 642 469 642 1608 642 1606 643 1607 642 1607 642 1607 642 1577 673 1607 643 1607 642 1607 642 1607 642 1606 643 1576 674 1606 643 468 643 439 672 1607 642 1607 642 448 663 469 642 439 672 469 642 1577 672 1607 642 468 643 469 642 1607 642 1608 641 1608 640 +# +name: Prev +type: raw +frequency: 38000 +duty_cycle: 0.330000 +data: 9144 4405 671 1607 642 469 642 469 642 469 642 470 641 365 747 469 641 443 669 469 642 468 643 446 665 469 642 469 642 470 642 1580 669 1607 643 1607 642 1608 641 1578 672 1580 670 1608 641 1608 641 1609 590 1660 590 1635 615 1660 590 1660 590 1632 618 1633 617 521 590 1660 590 521 590 521 618 493 590 521 590 520 591 519 592 1657 592 519 592 1658 617 1633 616 1633 615 23844 9114 4461 615 +# +name: Next +type: parsed +protocol: NEC +address: FD 00 00 00 +command: EA 00 00 00 From 6374474b259c3ad18edc8e9778121f7d2152febb Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Wed, 31 May 2023 10:39:11 +0300 Subject: [PATCH 35/52] fmt --- applications/main/subghz_remote/subghz_remote_app_i.c | 4 ++-- lib/subghz/subghz_keystore.c | 2 -- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/applications/main/subghz_remote/subghz_remote_app_i.c b/applications/main/subghz_remote/subghz_remote_app_i.c index f530a4356..543c39d08 100644 --- a/applications/main/subghz_remote/subghz_remote_app_i.c +++ b/applications/main/subghz_remote/subghz_remote_app_i.c @@ -221,7 +221,7 @@ bool subrem_tx_start_sub(SubGhzRemoteApp* app, SubRemSubFilePreset* sub_preset) subghz_txrx_load_decoder_by_name_protocol( app->txrx, furi_string_get_cstr(sub_preset->protocaol_name)); - subghz_custom_btns_reset(); + subghz_custom_btns_reset(); subghz_txrx_set_preset( app->txrx, furi_string_get_cstr(sub_preset->freq_preset.name), @@ -251,7 +251,7 @@ bool subrem_tx_stop_sub(SubGhzRemoteApp* app, bool forced) { subghz_txrx_stop(app->txrx); #ifdef APP_SUBGHZREMOTE if(sub_preset->type == SubGhzProtocolTypeDynamic) { - subghz_environment_reset_keeloq(app->environment); + subghz_environment_reset_keeloq(app->environment); } keeloq_reset_original_btn(); subghz_custom_btns_reset(); diff --git a/lib/subghz/subghz_keystore.c b/lib/subghz/subghz_keystore.c index d8f83fc89..54ed15a99 100644 --- a/lib/subghz/subghz_keystore.c +++ b/lib/subghz/subghz_keystore.c @@ -27,8 +27,6 @@ typedef enum { SubGhzKeystoreEncryptionAES256, } SubGhzKeystoreEncryption; - - SubGhzKeystore* subghz_keystore_alloc() { SubGhzKeystore* instance = malloc(sizeof(SubGhzKeystore)); From e60707d7ef9160af73f5d28590b6aa62b3043f1e Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Wed, 31 May 2023 12:18:24 +0300 Subject: [PATCH 36/52] need to fix that --- applications/main/subghz_remote/subghz_remote_app_i.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/applications/main/subghz_remote/subghz_remote_app_i.c b/applications/main/subghz_remote/subghz_remote_app_i.c index 543c39d08..6d23427eb 100644 --- a/applications/main/subghz_remote/subghz_remote_app_i.c +++ b/applications/main/subghz_remote/subghz_remote_app_i.c @@ -231,7 +231,6 @@ bool subrem_tx_start_sub(SubGhzRemoteApp* app, SubRemSubFilePreset* sub_preset) #ifdef APP_SUBGHZREMOTE subghz_custom_btn_set(SUBGHZ_CUSTOM_BTN_OK); - keeloq_reset_original_btn(); subghz_custom_btns_reset(); #endif @@ -251,9 +250,8 @@ bool subrem_tx_stop_sub(SubGhzRemoteApp* app, bool forced) { subghz_txrx_stop(app->txrx); #ifdef APP_SUBGHZREMOTE if(sub_preset->type == SubGhzProtocolTypeDynamic) { - subghz_environment_reset_keeloq(app->environment); + //subghz_environment_reset_keeloq(&app->txrx->environment); } - keeloq_reset_original_btn(); subghz_custom_btns_reset(); #endif return true; From 53dbf8de726ea942300253d39bb8d44e874a3490 Mon Sep 17 00:00:00 2001 From: gid9798 <30450294+gid9798@users.noreply.github.com> Date: Wed, 31 May 2023 12:25:45 +0300 Subject: [PATCH 37/52] fix --- applications/main/subghz_remote/subghz_remote_app_i.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/applications/main/subghz_remote/subghz_remote_app_i.c b/applications/main/subghz_remote/subghz_remote_app_i.c index 6d23427eb..26659ccb1 100644 --- a/applications/main/subghz_remote/subghz_remote_app_i.c +++ b/applications/main/subghz_remote/subghz_remote_app_i.c @@ -221,7 +221,6 @@ bool subrem_tx_start_sub(SubGhzRemoteApp* app, SubRemSubFilePreset* sub_preset) subghz_txrx_load_decoder_by_name_protocol( app->txrx, furi_string_get_cstr(sub_preset->protocaol_name)); - subghz_custom_btns_reset(); subghz_txrx_set_preset( app->txrx, furi_string_get_cstr(sub_preset->freq_preset.name), @@ -230,7 +229,6 @@ bool subrem_tx_start_sub(SubGhzRemoteApp* app, SubRemSubFilePreset* sub_preset) 0); #ifdef APP_SUBGHZREMOTE - subghz_custom_btn_set(SUBGHZ_CUSTOM_BTN_OK); subghz_custom_btns_reset(); #endif @@ -250,7 +248,7 @@ bool subrem_tx_stop_sub(SubGhzRemoteApp* app, bool forced) { subghz_txrx_stop(app->txrx); #ifdef APP_SUBGHZREMOTE if(sub_preset->type == SubGhzProtocolTypeDynamic) { - //subghz_environment_reset_keeloq(&app->txrx->environment); + subghz_txrx_reset_dynamic_and_custom_btns(app->txrx); } subghz_custom_btns_reset(); #endif From 87aca2874f2bd8769e5ed6250a03d4e21f969041 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Wed, 31 May 2023 13:34:52 +0300 Subject: [PATCH 38/52] Update TOTP https://github.com/akopachov/flipper-zero_authenticator --- applications/external/totp/features_config.h | 3 + .../external/totp/ui/fonts/active_font.h | 3 + .../external/totp/ui/fonts/dpcomic/dpcomic.c | 1114 ++++++++++++++++ .../external/totp/ui/fonts/dpcomic/dpcomic.h | 7 + .../totp/ui/fonts/funclimbing/funclimbing.c | 1172 +++++++++++++++++ .../totp/ui/fonts/funclimbing/funclimbing.h | 7 + .../totp/ui/fonts/pixelflag/pixelflag.c | 1114 ++++++++++++++++ .../totp/ui/fonts/pixelflag/pixelflag.h | 7 + .../scenes/app_settings/totp_app_settings.c | 4 +- .../totp_scene_generate_token.c | 18 + 10 files changed, 3447 insertions(+), 2 deletions(-) create mode 100644 applications/external/totp/ui/fonts/dpcomic/dpcomic.c create mode 100644 applications/external/totp/ui/fonts/dpcomic/dpcomic.h create mode 100644 applications/external/totp/ui/fonts/funclimbing/funclimbing.c create mode 100644 applications/external/totp/ui/fonts/funclimbing/funclimbing.h create mode 100644 applications/external/totp/ui/fonts/pixelflag/pixelflag.c create mode 100644 applications/external/totp/ui/fonts/pixelflag/pixelflag.h diff --git a/applications/external/totp/features_config.h b/applications/external/totp/features_config.h index c789af27b..15e81b28a 100644 --- a/applications/external/totp/features_config.h +++ b/applications/external/totp/features_config.h @@ -12,3 +12,6 @@ // Target firmware to build for #define TOTP_TARGET_FIRMWARE TOTP_FIRMWARE_UL_XFW + +// Max custom fonts value +#define MAX_CUSTOM_FONTS (9) \ No newline at end of file diff --git a/applications/external/totp/ui/fonts/active_font.h b/applications/external/totp/ui/fonts/active_font.h index 054fa4a55..c873ce200 100644 --- a/applications/external/totp/ui/fonts/active_font.h +++ b/applications/external/totp/ui/fonts/active_font.h @@ -10,3 +10,6 @@ #include "712serif/712serif.h" #include "graph35pix/graph35pix.h" #include "karma_future/karma_future.h" +#include "funclimbing/funclimbing.h" +#include "dpcomic/dpcomic.h" +#include "pixelflag/pixelflag.h" diff --git a/applications/external/totp/ui/fonts/dpcomic/dpcomic.c b/applications/external/totp/ui/fonts/dpcomic/dpcomic.c new file mode 100644 index 000000000..e9c5ea1de --- /dev/null +++ b/applications/external/totp/ui/fonts/dpcomic/dpcomic.c @@ -0,0 +1,1114 @@ +#include "dpcomic.h" + +/* GENERATED BY https://github.com/pavius/the-dot-factory */ + +/* +** Font data for DPComic 18pt +*/ + +/* Character bitmaps for DPComic 18pt */ +const uint8_t dPComic_18ptBitmaps[] = { + /* @0 '-' (15 pixels wide) */ + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xE0, + 0x3F, + 0xF8, + 0x0F, + 0xF8, + 0x0F, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + + /* @34 '0' (15 pixels wide) */ + 0x00, + 0x00, + 0xC0, + 0x01, + 0xC0, + 0x01, + 0xE0, + 0x07, + 0x38, + 0x0E, + 0x38, + 0x0E, + 0x38, + 0x0E, + 0x38, + 0x0E, + 0x38, + 0x0E, + 0x38, + 0x0E, + 0x38, + 0x0E, + 0x38, + 0x0E, + 0xE0, + 0x07, + 0xC0, + 0x01, + 0xC0, + 0x01, + 0x00, + 0x00, + 0x00, + 0x00, + + /* @68 '1' (15 pixels wide) */ + 0x00, + 0x00, + 0xC0, + 0x01, + 0xC0, + 0x01, + 0xE0, + 0x01, + 0xF8, + 0x01, + 0xF8, + 0x01, + 0xC0, + 0x01, + 0xC0, + 0x01, + 0xC0, + 0x01, + 0xC0, + 0x01, + 0xC0, + 0x01, + 0xC0, + 0x01, + 0xE0, + 0x0F, + 0xF8, + 0x07, + 0xF8, + 0x07, + 0x00, + 0x00, + 0x00, + 0x00, + + /* @102 '2' (15 pixels wide) */ + 0x00, + 0x00, + 0xC0, + 0x07, + 0xC0, + 0x07, + 0xE0, + 0x0F, + 0x38, + 0x0E, + 0x38, + 0x0E, + 0x00, + 0x0E, + 0x00, + 0x0E, + 0x00, + 0x0E, + 0x00, + 0x07, + 0xC0, + 0x01, + 0xC0, + 0x01, + 0xE0, + 0x3F, + 0xF8, + 0x0F, + 0xF8, + 0x0F, + 0x00, + 0x00, + 0x00, + 0x00, + + /* @136 '3' (15 pixels wide) */ + 0x00, + 0x00, + 0xC0, + 0x3F, + 0xC0, + 0x3F, + 0xE0, + 0x3F, + 0x00, + 0x0E, + 0x00, + 0x0E, + 0x00, + 0x07, + 0xC0, + 0x07, + 0xC0, + 0x07, + 0x00, + 0x0F, + 0x00, + 0x0E, + 0x00, + 0x0E, + 0xE0, + 0x0F, + 0xF8, + 0x07, + 0xF8, + 0x07, + 0x00, + 0x00, + 0x00, + 0x00, + + /* @170 '4' (15 pixels wide) */ + 0x00, + 0x00, + 0x00, + 0x0E, + 0x00, + 0x0E, + 0x00, + 0x0F, + 0xC0, + 0x0F, + 0xC0, + 0x0F, + 0xE0, + 0x0E, + 0x38, + 0x0E, + 0x38, + 0x0E, + 0xF8, + 0x0F, + 0xF8, + 0x0F, + 0xF8, + 0x0F, + 0x00, + 0x0E, + 0x00, + 0x0E, + 0x00, + 0x0E, + 0x00, + 0x00, + 0x00, + 0x00, + + /* @204 '5' (15 pixels wide) */ + 0x00, + 0x00, + 0xC0, + 0x3F, + 0xC0, + 0x3F, + 0xC0, + 0x0F, + 0xE0, + 0x00, + 0xE0, + 0x00, + 0xE0, + 0x07, + 0xE0, + 0x0F, + 0xE0, + 0x0F, + 0x00, + 0x0E, + 0x00, + 0x0F, + 0x00, + 0x0F, + 0xE0, + 0x07, + 0xF8, + 0x01, + 0xF8, + 0x01, + 0x00, + 0x00, + 0x00, + 0x00, + + /* @238 '6' (15 pixels wide) */ + 0x00, + 0x00, + 0x00, + 0x0F, + 0x00, + 0x0F, + 0xC0, + 0x07, + 0xE0, + 0x00, + 0xE0, + 0x00, + 0xE0, + 0x07, + 0x38, + 0x0E, + 0x38, + 0x0E, + 0x38, + 0x0E, + 0x38, + 0x0F, + 0x38, + 0x0F, + 0xF8, + 0x07, + 0xE0, + 0x01, + 0xE0, + 0x01, + 0x00, + 0x00, + 0x00, + 0x00, + + /* @272 '7' (15 pixels wide) */ + 0x00, + 0x00, + 0xE0, + 0x0F, + 0xE0, + 0x0F, + 0xF8, + 0x0F, + 0x00, + 0x0E, + 0x00, + 0x0E, + 0x00, + 0x07, + 0xC0, + 0x01, + 0xC0, + 0x01, + 0xE0, + 0x00, + 0xF8, + 0x00, + 0xF8, + 0x00, + 0x38, + 0x00, + 0x38, + 0x00, + 0x38, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + + /* @306 '8' (15 pixels wide) */ + 0x00, + 0x00, + 0xC0, + 0x0F, + 0xC0, + 0x0F, + 0xE0, + 0x38, + 0xE0, + 0x3E, + 0xE0, + 0x3E, + 0xC0, + 0x0F, + 0xE0, + 0x07, + 0xE0, + 0x07, + 0x38, + 0x0E, + 0x38, + 0x0E, + 0x38, + 0x0E, + 0x38, + 0x0F, + 0xE0, + 0x07, + 0xE0, + 0x07, + 0x00, + 0x00, + 0x00, + 0x00, + + /* @340 '9' (15 pixels wide) */ + 0x00, + 0x00, + 0xC0, + 0x07, + 0xC0, + 0x07, + 0xE0, + 0x0E, + 0x38, + 0x0E, + 0x38, + 0x0E, + 0x38, + 0x0E, + 0xF8, + 0x0F, + 0xF8, + 0x0F, + 0xE0, + 0x07, + 0x00, + 0x07, + 0x00, + 0x07, + 0xE0, + 0x01, + 0xF8, + 0x00, + 0xF8, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + + /* @374 'B' (15 pixels wide) */ + 0xC0, + 0x0F, + 0xE0, + 0x3F, + 0xE0, + 0x3F, + 0xF8, + 0x38, + 0x38, + 0x3E, + 0x38, + 0x3E, + 0xF8, + 0x0F, + 0xF8, + 0x3F, + 0xF8, + 0x3F, + 0x38, + 0x38, + 0x38, + 0x3E, + 0x38, + 0x3E, + 0xF8, + 0x0F, + 0xF8, + 0x07, + 0xF8, + 0x07, + 0x00, + 0x00, + 0x00, + 0x00, + + /* @408 'C' (15 pixels wide) */ + 0x00, + 0x0F, + 0xC0, + 0x3F, + 0xC0, + 0x3F, + 0xE0, + 0x39, + 0xE0, + 0x00, + 0xE0, + 0x00, + 0xF8, + 0x00, + 0x38, + 0x00, + 0x38, + 0x00, + 0x38, + 0x38, + 0x38, + 0x3E, + 0x38, + 0x3E, + 0xF8, + 0x0F, + 0xE0, + 0x07, + 0xE0, + 0x07, + 0x00, + 0x00, + 0x00, + 0x00, + + /* @442 'D' (15 pixels wide) */ + 0xC0, + 0x07, + 0xE0, + 0x0F, + 0xE0, + 0x0F, + 0xF8, + 0x3E, + 0x38, + 0x38, + 0x38, + 0x38, + 0x38, + 0x38, + 0x38, + 0x38, + 0x38, + 0x38, + 0x38, + 0x3E, + 0x38, + 0x0F, + 0x38, + 0x0F, + 0xF8, + 0x07, + 0xF8, + 0x01, + 0xF8, + 0x01, + 0x00, + 0x00, + 0x00, + 0x00, + + /* @476 'F' (15 pixels wide) */ + 0x80, + 0x1F, + 0xC0, + 0x0F, + 0xC0, + 0x0F, + 0xF0, + 0x01, + 0x70, + 0x00, + 0x70, + 0x00, + 0xF0, + 0x0F, + 0xF0, + 0x03, + 0xF0, + 0x03, + 0x70, + 0x00, + 0x70, + 0x00, + 0x70, + 0x00, + 0x70, + 0x00, + 0x70, + 0x00, + 0x70, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + + /* @510 'G' (15 pixels wide) */ + 0x00, + 0x0F, + 0xC0, + 0x3F, + 0xC0, + 0x3F, + 0xE0, + 0x39, + 0xE0, + 0x00, + 0xE0, + 0x00, + 0xF8, + 0x00, + 0x38, + 0x3E, + 0x38, + 0x3E, + 0x38, + 0x38, + 0x38, + 0x3E, + 0x38, + 0x3E, + 0xF8, + 0x0F, + 0xE0, + 0x07, + 0xE0, + 0x07, + 0x00, + 0x00, + 0x00, + 0x00, + + /* @544 'H' (15 pixels wide) */ + 0x00, + 0x30, + 0x20, + 0x38, + 0x20, + 0x38, + 0x38, + 0x38, + 0x38, + 0x38, + 0x38, + 0x38, + 0xF8, + 0x3F, + 0xF8, + 0x3F, + 0xF8, + 0x3F, + 0x38, + 0x38, + 0x38, + 0x38, + 0x38, + 0x38, + 0x38, + 0x38, + 0x38, + 0x38, + 0x38, + 0x38, + 0x00, + 0x00, + 0x00, + 0x00, + + /* @578 'J' (15 pixels wide) */ + 0x00, + 0x08, + 0x00, + 0x0E, + 0x00, + 0x0E, + 0x00, + 0x0E, + 0x00, + 0x0E, + 0x00, + 0x0E, + 0x00, + 0x0E, + 0x00, + 0x0E, + 0x00, + 0x0E, + 0x00, + 0x0E, + 0x00, + 0x0E, + 0x00, + 0x0E, + 0x18, + 0x0F, + 0xF8, + 0x07, + 0xF8, + 0x07, + 0xE0, + 0x01, + 0xE0, + 0x01, + + /* @612 'K' (15 pixels wide) */ + 0x20, + 0x30, + 0x38, + 0x38, + 0x38, + 0x38, + 0x38, + 0x3E, + 0x38, + 0x0F, + 0x38, + 0x0F, + 0xF8, + 0x07, + 0xF8, + 0x07, + 0xF8, + 0x07, + 0x38, + 0x0F, + 0x38, + 0x3E, + 0x38, + 0x3E, + 0x38, + 0x38, + 0x38, + 0x38, + 0x38, + 0x38, + 0x00, + 0x00, + 0x00, + 0x00, + + /* @646 'M' (15 pixels wide) */ + 0x08, + 0x10, + 0x3E, + 0x1C, + 0x3E, + 0x1C, + 0x7E, + 0x1E, + 0xFE, + 0x1F, + 0xFE, + 0x1F, + 0xCE, + 0x1D, + 0x0E, + 0x1C, + 0x0E, + 0x1C, + 0x0E, + 0x1C, + 0x0E, + 0x1C, + 0x0E, + 0x1C, + 0x0E, + 0x1C, + 0x0E, + 0x1C, + 0x0E, + 0x1C, + 0x00, + 0x00, + 0x00, + 0x00, + + /* @680 'N' (15 pixels wide) */ + 0x20, + 0x30, + 0xF8, + 0x38, + 0xF8, + 0x38, + 0xF8, + 0x38, + 0xF8, + 0x39, + 0xF8, + 0x39, + 0xF8, + 0x39, + 0x38, + 0x3F, + 0x38, + 0x3F, + 0x38, + 0x3F, + 0x38, + 0x3E, + 0x38, + 0x3E, + 0x38, + 0x3E, + 0x38, + 0x38, + 0x38, + 0x38, + 0x00, + 0x00, + 0x00, + 0x00, + + /* @714 'P' (15 pixels wide) */ + 0xC0, + 0x07, + 0xE0, + 0x0F, + 0xE0, + 0x0F, + 0xF8, + 0x0E, + 0x38, + 0x0E, + 0x38, + 0x0E, + 0x38, + 0x0F, + 0xF8, + 0x07, + 0xF8, + 0x07, + 0xF8, + 0x01, + 0x38, + 0x00, + 0x38, + 0x00, + 0x38, + 0x00, + 0x38, + 0x00, + 0x38, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + + /* @748 'Q' (15 pixels wide) */ + 0x00, + 0x0F, + 0xC0, + 0x3F, + 0xC0, + 0x3F, + 0xE0, + 0x39, + 0xE0, + 0x38, + 0xE0, + 0x38, + 0xF8, + 0x38, + 0x38, + 0x38, + 0x38, + 0x38, + 0x38, + 0x38, + 0x38, + 0x3E, + 0x38, + 0x3E, + 0xF8, + 0x0F, + 0xE0, + 0x3F, + 0xE0, + 0x3F, + 0x00, + 0x38, + 0x00, + 0x38, + + /* @782 'R' (15 pixels wide) */ + 0xC0, + 0x07, + 0xE0, + 0x0F, + 0xE0, + 0x0F, + 0xF8, + 0x0E, + 0x38, + 0x0E, + 0x38, + 0x0E, + 0x38, + 0x0F, + 0xF8, + 0x07, + 0xF8, + 0x07, + 0xF8, + 0x01, + 0x38, + 0x07, + 0x38, + 0x07, + 0x38, + 0x0F, + 0x38, + 0x0E, + 0x38, + 0x0E, + 0x00, + 0x00, + 0x00, + 0x00, + + /* @816 'T' (15 pixels wide) */ + 0x00, + 0x7E, + 0xE0, + 0x3F, + 0xE0, + 0x3F, + 0xF8, + 0x07, + 0x00, + 0x07, + 0x00, + 0x07, + 0x00, + 0x07, + 0x00, + 0x07, + 0x00, + 0x07, + 0x00, + 0x07, + 0x00, + 0x07, + 0x00, + 0x07, + 0x00, + 0x07, + 0x00, + 0x07, + 0x00, + 0x07, + 0x00, + 0x00, + 0x00, + 0x00, + + /* @850 'V' (15 pixels wide) */ + 0x20, + 0x30, + 0x38, + 0x38, + 0x38, + 0x38, + 0x38, + 0x38, + 0x38, + 0x38, + 0x38, + 0x38, + 0x38, + 0x38, + 0x38, + 0x0E, + 0x38, + 0x0E, + 0x38, + 0x0E, + 0x38, + 0x07, + 0x38, + 0x07, + 0xE0, + 0x07, + 0xC0, + 0x01, + 0xC0, + 0x01, + 0x00, + 0x00, + 0x00, + 0x00, + + /* @884 'W' (15 pixels wide) */ + 0x04, + 0x40, + 0x07, + 0x70, + 0x07, + 0x70, + 0x07, + 0x71, + 0xC7, + 0x71, + 0xC7, + 0x71, + 0xC7, + 0x71, + 0xC7, + 0x71, + 0xC7, + 0x71, + 0xC7, + 0x71, + 0xE7, + 0x39, + 0xE7, + 0x39, + 0x3C, + 0x0F, + 0x1C, + 0x07, + 0x1C, + 0x07, + 0x00, + 0x00, + 0x00, + 0x00, + + /* @918 'X' (15 pixels wide) */ + 0x18, + 0x30, + 0x38, + 0x38, + 0x38, + 0x38, + 0xF8, + 0x3E, + 0xE0, + 0x0F, + 0xE0, + 0x0F, + 0xC0, + 0x07, + 0xC0, + 0x01, + 0xC0, + 0x01, + 0xE0, + 0x07, + 0x38, + 0x0F, + 0x38, + 0x0F, + 0x38, + 0x3E, + 0x18, + 0x38, + 0x18, + 0x38, + 0x00, + 0x00, + 0x00, + 0x00, + + /* @952 'Y' (15 pixels wide) */ + 0x18, + 0x08, + 0x38, + 0x0E, + 0x38, + 0x0E, + 0x38, + 0x0E, + 0xF8, + 0x0F, + 0xF8, + 0x0F, + 0xE0, + 0x07, + 0xE0, + 0x01, + 0xE0, + 0x01, + 0xC0, + 0x01, + 0xC0, + 0x01, + 0xC0, + 0x01, + 0xC0, + 0x01, + 0xC0, + 0x01, + 0xC0, + 0x01, + 0x00, + 0x00, + 0x00, + 0x00, +}; + +/* Character descriptors for DPComic 18pt */ +/* { [Char width in bits], [Offset into dPComic_18ptCharBitmaps in bytes] } */ +const FONT_CHAR_INFO dPComic_18ptDescriptors[] = { + {15, 0}, /* - */ + {0, 0}, /* . */ + {0, 0}, /* / */ + {15, 34}, /* 0 */ + {15, 68}, /* 1 */ + {15, 102}, /* 2 */ + {15, 136}, /* 3 */ + {15, 170}, /* 4 */ + {15, 204}, /* 5 */ + {15, 238}, /* 6 */ + {15, 272}, /* 7 */ + {15, 306}, /* 8 */ + {15, 340}, /* 9 */ + {0, 0}, /* : */ + {0, 0}, /* ; */ + {0, 0}, /* < */ + {0, 0}, /* = */ + {0, 0}, /* > */ + {0, 0}, /* ? */ + {0, 0}, /* @ */ + {0, 0}, /* A */ + {15, 374}, /* B */ + {15, 408}, /* C */ + {15, 442}, /* D */ + {0, 0}, /* E */ + {15, 476}, /* F */ + {15, 510}, /* G */ + {15, 544}, /* H */ + {0, 0}, /* I */ + {15, 578}, /* J */ + {15, 612}, /* K */ + {0, 0}, /* L */ + {15, 646}, /* M */ + {15, 680}, /* N */ + {0, 0}, /* O */ + {15, 714}, /* P */ + {15, 748}, /* Q */ + {15, 782}, /* R */ + {0, 0}, /* S */ + {15, 816}, /* T */ + {0, 0}, /* U */ + {15, 850}, /* V */ + {15, 884}, /* W */ + {15, 918}, /* X */ + {15, 952}, /* Y */ +}; + +/* Font information for DPComic 18pt */ +const FONT_INFO dPComic_18ptFontInfo = { + 17, /* Character height */ + '-', /* Start character */ + 'Y', /* End character */ + 2, /* Width, in pixels, of space character */ + dPComic_18ptDescriptors, /* Character descriptor array */ + dPComic_18ptBitmaps, /* Character bitmap array */ +}; diff --git a/applications/external/totp/ui/fonts/dpcomic/dpcomic.h b/applications/external/totp/ui/fonts/dpcomic/dpcomic.h new file mode 100644 index 000000000..bac49b4d6 --- /dev/null +++ b/applications/external/totp/ui/fonts/dpcomic/dpcomic.h @@ -0,0 +1,7 @@ +#pragma once + +/* GENERATED BY https://github.com/pavius/the-dot-factory */ + +#include "../font_info.h" + +extern const FONT_INFO dPComic_18ptFontInfo; \ No newline at end of file diff --git a/applications/external/totp/ui/fonts/funclimbing/funclimbing.c b/applications/external/totp/ui/fonts/funclimbing/funclimbing.c new file mode 100644 index 000000000..d6b1a0c97 --- /dev/null +++ b/applications/external/totp/ui/fonts/funclimbing/funclimbing.c @@ -0,0 +1,1172 @@ +#include "funclimbing.h" + +/* GENERATED BY https://github.com/pavius/the-dot-factory */ + +/* +** Font data for fun climbing (Demo) 18pt +*/ + +/* Character bitmaps for fun climbing (Demo) 18pt */ +const uint8_t funclimbingDemo_18ptBitmaps[] = { + /* @0 '-' (16 pixels wide) */ + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xE0, + 0x03, + 0xE0, + 0x03, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + + /* @36 '0' (16 pixels wide) */ + 0x00, + 0x00, + 0x80, + 0x00, + 0xE0, + 0x03, + 0x20, + 0x02, + 0x10, + 0x04, + 0x10, + 0x04, + 0x10, + 0x04, + 0x08, + 0x04, + 0x08, + 0x08, + 0x08, + 0x08, + 0x08, + 0x04, + 0x10, + 0x04, + 0x10, + 0x04, + 0x10, + 0x04, + 0x20, + 0x02, + 0xE0, + 0x01, + 0x00, + 0x00, + 0x00, + 0x00, + + /* @72 '1' (16 pixels wide) */ + 0x00, + 0x02, + 0x00, + 0x03, + 0x80, + 0x03, + 0xC0, + 0x02, + 0x60, + 0x02, + 0x00, + 0x02, + 0x00, + 0x02, + 0x00, + 0x02, + 0x00, + 0x02, + 0x00, + 0x02, + 0x00, + 0x02, + 0x00, + 0x02, + 0x00, + 0x02, + 0x00, + 0x02, + 0x00, + 0x02, + 0x00, + 0x02, + 0x00, + 0x02, + 0x00, + 0x00, + + /* @108 '2' (16 pixels wide) */ + 0x00, + 0x00, + 0xC0, + 0x07, + 0x60, + 0x04, + 0x20, + 0x04, + 0x10, + 0x04, + 0x10, + 0x04, + 0x10, + 0x04, + 0x08, + 0x02, + 0x08, + 0x02, + 0x00, + 0x01, + 0x00, + 0x01, + 0x80, + 0x00, + 0x80, + 0x00, + 0x40, + 0x00, + 0x60, + 0x00, + 0xC0, + 0x03, + 0x00, + 0x1C, + 0x00, + 0x00, + + /* @144 '3' (16 pixels wide) */ + 0x00, + 0x02, + 0x80, + 0x05, + 0x40, + 0x08, + 0x40, + 0x08, + 0x40, + 0x10, + 0x40, + 0x10, + 0x00, + 0x10, + 0x00, + 0x08, + 0x00, + 0x08, + 0x00, + 0x0C, + 0x00, + 0x06, + 0x00, + 0x03, + 0x80, + 0x0F, + 0x00, + 0x10, + 0x00, + 0x10, + 0x30, + 0x08, + 0xC0, + 0x07, + 0x00, + 0x00, + + /* @180 '4' (16 pixels wide) */ + 0x00, + 0x10, + 0x00, + 0x10, + 0x40, + 0x10, + 0x40, + 0x10, + 0x40, + 0x10, + 0x40, + 0x10, + 0x40, + 0x10, + 0x20, + 0x10, + 0x20, + 0x10, + 0x20, + 0x10, + 0x20, + 0x10, + 0x30, + 0x10, + 0xF0, + 0x1F, + 0x00, + 0x10, + 0x00, + 0x10, + 0x00, + 0x10, + 0x00, + 0x10, + 0x00, + 0x10, + + /* @216 '5' (16 pixels wide) */ + 0x00, + 0x00, + 0x60, + 0x00, + 0xA0, + 0x03, + 0x20, + 0x04, + 0x20, + 0x00, + 0x30, + 0x00, + 0x10, + 0x00, + 0x10, + 0x00, + 0xF0, + 0x00, + 0x80, + 0x03, + 0x00, + 0x04, + 0x00, + 0x08, + 0x00, + 0x08, + 0x00, + 0x08, + 0x00, + 0x04, + 0x80, + 0x03, + 0xF0, + 0x00, + 0x00, + 0x00, + + /* @252 '6' (16 pixels wide) */ + 0x00, + 0x00, + 0x40, + 0x00, + 0x20, + 0x00, + 0x20, + 0x00, + 0x10, + 0x00, + 0x10, + 0x00, + 0x10, + 0x00, + 0x18, + 0x03, + 0xC8, + 0x06, + 0x28, + 0x0C, + 0x18, + 0x08, + 0x18, + 0x08, + 0x08, + 0x08, + 0x08, + 0x08, + 0x10, + 0x08, + 0x30, + 0x0C, + 0xC0, + 0x07, + 0x00, + 0x00, + + /* @288 '7' (16 pixels wide) */ + 0x00, + 0x00, + 0x00, + 0x0F, + 0xF0, + 0x09, + 0x00, + 0x04, + 0x00, + 0x04, + 0x00, + 0x04, + 0x00, + 0x04, + 0x00, + 0x04, + 0x00, + 0x06, + 0x00, + 0x02, + 0x00, + 0x02, + 0x00, + 0x02, + 0x00, + 0x02, + 0x00, + 0x03, + 0x00, + 0x01, + 0x00, + 0x01, + 0x00, + 0x01, + 0x00, + 0x00, + + /* @324 '8' (16 pixels wide) */ + 0x80, + 0x01, + 0x60, + 0x02, + 0x30, + 0x04, + 0x10, + 0x08, + 0x10, + 0x08, + 0x08, + 0x08, + 0x08, + 0x08, + 0x10, + 0x0C, + 0x10, + 0x04, + 0x60, + 0x03, + 0xC0, + 0x01, + 0x40, + 0x03, + 0x20, + 0x04, + 0x20, + 0x04, + 0x20, + 0x04, + 0x20, + 0x04, + 0xC0, + 0x03, + 0x00, + 0x00, + + /* @360 '9' (16 pixels wide) */ + 0x00, + 0x00, + 0xC0, + 0x01, + 0x20, + 0x02, + 0x10, + 0x04, + 0x10, + 0x04, + 0x10, + 0x04, + 0x10, + 0x04, + 0x10, + 0x04, + 0x10, + 0x04, + 0xE0, + 0x03, + 0x00, + 0x02, + 0x00, + 0x02, + 0x00, + 0x01, + 0x00, + 0x01, + 0x80, + 0x00, + 0x80, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + + /* @396 'B' (16 pixels wide) */ + 0x10, + 0x00, + 0x10, + 0x00, + 0x10, + 0x00, + 0x10, + 0x00, + 0x10, + 0x00, + 0x10, + 0x00, + 0x18, + 0x00, + 0x18, + 0x00, + 0x08, + 0x00, + 0x08, + 0x00, + 0xE8, + 0x0F, + 0x38, + 0x10, + 0x10, + 0x10, + 0x10, + 0x30, + 0x10, + 0x10, + 0x10, + 0x18, + 0xF0, + 0x07, + 0x20, + 0x00, + + /* @432 'C' (16 pixels wide) */ + 0x00, + 0x03, + 0x80, + 0x06, + 0x40, + 0x04, + 0x40, + 0x04, + 0x40, + 0x08, + 0x40, + 0x00, + 0x20, + 0x00, + 0x20, + 0x00, + 0x20, + 0x00, + 0x20, + 0x00, + 0x40, + 0x00, + 0x40, + 0x08, + 0x40, + 0x08, + 0x40, + 0x08, + 0xC0, + 0x08, + 0x80, + 0x04, + 0x80, + 0x05, + 0x00, + 0x02, + + /* @468 'D' (16 pixels wide) */ + 0x00, + 0x04, + 0x00, + 0x04, + 0x00, + 0x04, + 0x00, + 0x04, + 0x00, + 0x04, + 0x00, + 0x04, + 0x80, + 0x07, + 0x40, + 0x04, + 0x20, + 0x04, + 0x20, + 0x04, + 0x10, + 0x04, + 0x10, + 0x04, + 0x30, + 0x04, + 0x20, + 0x04, + 0x20, + 0x04, + 0x40, + 0x04, + 0x80, + 0x05, + 0x00, + 0x07, + + /* @504 'F' (16 pixels wide) */ + 0x00, + 0x02, + 0x80, + 0x0D, + 0xC0, + 0x08, + 0x40, + 0x10, + 0x60, + 0x10, + 0x20, + 0x00, + 0x20, + 0x00, + 0x20, + 0x00, + 0x20, + 0x00, + 0x20, + 0x00, + 0x20, + 0x00, + 0x20, + 0x00, + 0xF8, + 0x01, + 0x20, + 0x00, + 0x20, + 0x00, + 0x20, + 0x00, + 0x20, + 0x00, + 0x40, + 0x00, + + /* @540 'G' (16 pixels wide) */ + 0x80, + 0x00, + 0x60, + 0x01, + 0x20, + 0x03, + 0x30, + 0x02, + 0x10, + 0x02, + 0x10, + 0x02, + 0x10, + 0x02, + 0x10, + 0x02, + 0x10, + 0x00, + 0x10, + 0x00, + 0x10, + 0x00, + 0x10, + 0x00, + 0xD0, + 0x0F, + 0x10, + 0x02, + 0x10, + 0x01, + 0x20, + 0x01, + 0xE0, + 0x00, + 0x40, + 0x00, + + /* @576 'H' (16 pixels wide) */ + 0x00, + 0x00, + 0x08, + 0x00, + 0x08, + 0x00, + 0x08, + 0x00, + 0x18, + 0x00, + 0x10, + 0x00, + 0x10, + 0x00, + 0x10, + 0x00, + 0x10, + 0x00, + 0x10, + 0x00, + 0x10, + 0x0F, + 0x90, + 0x09, + 0xD0, + 0x18, + 0x50, + 0x10, + 0x30, + 0x10, + 0x30, + 0x10, + 0x10, + 0x10, + 0x00, + 0x00, + + /* @612 'J' (16 pixels wide) */ + 0x00, + 0x00, + 0x00, + 0x04, + 0x00, + 0x04, + 0x00, + 0x04, + 0x00, + 0x04, + 0x00, + 0x04, + 0x00, + 0x04, + 0x00, + 0x04, + 0x00, + 0x04, + 0x10, + 0x04, + 0x10, + 0x04, + 0x10, + 0x04, + 0x20, + 0x04, + 0x20, + 0x02, + 0x20, + 0x02, + 0x60, + 0x03, + 0xC0, + 0x01, + 0x00, + 0x00, + + /* @648 'K' (16 pixels wide) */ + 0x00, + 0x00, + 0x00, + 0x00, + 0x10, + 0x00, + 0x10, + 0x00, + 0x10, + 0x08, + 0x10, + 0x0C, + 0x10, + 0x02, + 0xB0, + 0x01, + 0xE0, + 0x00, + 0x60, + 0x00, + 0x60, + 0x00, + 0xA0, + 0x00, + 0x20, + 0x01, + 0x20, + 0x02, + 0x20, + 0x0C, + 0x20, + 0x08, + 0x00, + 0x00, + 0x00, + 0x00, + + /* @684 'M' (16 pixels wide) */ + 0x00, + 0x00, + 0x00, + 0x00, + 0x10, + 0x10, + 0x30, + 0x18, + 0x30, + 0x18, + 0x50, + 0x34, + 0x50, + 0x24, + 0xC8, + 0x22, + 0x88, + 0x22, + 0x88, + 0x21, + 0x08, + 0x21, + 0x04, + 0x60, + 0x04, + 0x40, + 0x04, + 0x40, + 0x04, + 0x40, + 0x02, + 0x40, + 0x00, + 0x00, + 0x00, + 0x00, + + /* @720 'N' (16 pixels wide) */ + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x02, + 0x01, + 0x86, + 0x07, + 0x44, + 0x04, + 0x24, + 0x08, + 0x24, + 0x08, + 0x14, + 0x18, + 0x14, + 0x10, + 0x1C, + 0x10, + 0x0C, + 0x10, + 0x0C, + 0x10, + 0x08, + 0x10, + 0x00, + 0x10, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + + /* @756 'P' (16 pixels wide) */ + 0x00, + 0x00, + 0x00, + 0x00, + 0xE0, + 0x01, + 0x20, + 0x02, + 0x20, + 0x04, + 0x60, + 0x04, + 0x40, + 0x04, + 0x40, + 0x04, + 0x40, + 0x04, + 0x40, + 0x06, + 0x40, + 0x02, + 0xC0, + 0x01, + 0xC0, + 0x00, + 0x40, + 0x00, + 0x40, + 0x00, + 0x40, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + + /* @792 'Q' (16 pixels wide) */ + 0x00, + 0x00, + 0xC0, + 0x03, + 0x30, + 0x06, + 0x18, + 0x08, + 0x08, + 0x10, + 0x04, + 0x10, + 0x04, + 0x20, + 0x04, + 0x20, + 0x04, + 0x20, + 0x08, + 0x21, + 0x08, + 0x33, + 0x10, + 0x12, + 0x30, + 0x0E, + 0xC0, + 0x07, + 0x00, + 0x08, + 0x00, + 0x08, + 0x00, + 0x10, + 0x00, + 0x00, + + /* @828 'R' (16 pixels wide) */ + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x07, + 0x88, + 0x0D, + 0x48, + 0x08, + 0x68, + 0x00, + 0x28, + 0x00, + 0x28, + 0x00, + 0x18, + 0x00, + 0x18, + 0x00, + 0x10, + 0x00, + 0x10, + 0x00, + 0x10, + 0x00, + 0x10, + 0x00, + 0x10, + 0x00, + 0x10, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + + /* @864 'T' (16 pixels wide) */ + 0x00, + 0x00, + 0x00, + 0x00, + 0x80, + 0x00, + 0x80, + 0x00, + 0x80, + 0x00, + 0x80, + 0x00, + 0xE0, + 0x03, + 0x80, + 0x00, + 0x80, + 0x00, + 0x80, + 0x00, + 0x80, + 0x04, + 0x80, + 0x04, + 0x80, + 0x04, + 0x80, + 0x04, + 0x80, + 0x05, + 0x00, + 0x07, + 0x00, + 0x00, + 0x00, + 0x00, + + /* @900 'V' (16 pixels wide) */ + 0x00, + 0x00, + 0x00, + 0x00, + 0x08, + 0x10, + 0x10, + 0x10, + 0x10, + 0x18, + 0x10, + 0x08, + 0x10, + 0x08, + 0x10, + 0x04, + 0x10, + 0x04, + 0x20, + 0x04, + 0x20, + 0x02, + 0x20, + 0x02, + 0x20, + 0x01, + 0x40, + 0x01, + 0xC0, + 0x01, + 0xC0, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + + /* @936 'W' (16 pixels wide) */ + 0x00, + 0x00, + 0x00, + 0x00, + 0x03, + 0x80, + 0x02, + 0x80, + 0x02, + 0x40, + 0x02, + 0x40, + 0x02, + 0x41, + 0x86, + 0x42, + 0x84, + 0x42, + 0x44, + 0x44, + 0x44, + 0x64, + 0x24, + 0x28, + 0x28, + 0x28, + 0x18, + 0x30, + 0x18, + 0x30, + 0x18, + 0x20, + 0x00, + 0x00, + 0x00, + 0x00, + + /* @972 'X' (16 pixels wide) */ + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x08, + 0x08, + 0x10, + 0x04, + 0x20, + 0x04, + 0x40, + 0x02, + 0x80, + 0x03, + 0x80, + 0x01, + 0x80, + 0x03, + 0x40, + 0x02, + 0x30, + 0x04, + 0x18, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + + /* @1008 'Y' (16 pixels wide) */ + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x08, + 0x08, + 0x08, + 0x08, + 0x08, + 0x0C, + 0x08, + 0x0C, + 0x08, + 0x0A, + 0x10, + 0x0A, + 0xF0, + 0x09, + 0x00, + 0x0C, + 0x10, + 0x04, + 0x10, + 0x04, + 0x20, + 0x02, + 0xE0, + 0x03, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, +}; + +/* Character descriptors for fun climbing (Demo) 18pt */ +/* { [Char width in bits], [Offset into funclimbingDemo_18ptCharBitmaps in bytes] } */ +const FONT_CHAR_INFO funclimbingDemo_18ptDescriptors[] = { + {16, 0}, /* - */ + {0, 0}, /* . */ + {0, 0}, /* / */ + {16, 36}, /* 0 */ + {16, 72}, /* 1 */ + {16, 108}, /* 2 */ + {16, 144}, /* 3 */ + {16, 180}, /* 4 */ + {16, 216}, /* 5 */ + {16, 252}, /* 6 */ + {16, 288}, /* 7 */ + {16, 324}, /* 8 */ + {16, 360}, /* 9 */ + {0, 0}, /* : */ + {0, 0}, /* ; */ + {0, 0}, /* < */ + {0, 0}, /* = */ + {0, 0}, /* > */ + {0, 0}, /* ? */ + {0, 0}, /* @ */ + {0, 0}, /* A */ + {16, 396}, /* B */ + {16, 432}, /* C */ + {16, 468}, /* D */ + {0, 0}, /* E */ + {16, 504}, /* F */ + {16, 540}, /* G */ + {16, 576}, /* H */ + {0, 0}, /* I */ + {16, 612}, /* J */ + {16, 648}, /* K */ + {0, 0}, /* L */ + {16, 684}, /* M */ + {16, 720}, /* N */ + {0, 0}, /* O */ + {16, 756}, /* P */ + {16, 792}, /* Q */ + {16, 828}, /* R */ + {0, 0}, /* S */ + {16, 864}, /* T */ + {0, 0}, /* U */ + {16, 900}, /* V */ + {16, 936}, /* W */ + {16, 972}, /* X */ + {16, 1008}, /* Y */ +}; + +/* Font information for fun climbing (Demo) 18pt */ +const FONT_INFO funclimbingDemo_18ptFontInfo = { + 18, /* Character height */ + '-', /* Start character */ + 'Y', /* End character */ + 2, /* Width, in pixels, of space character */ + funclimbingDemo_18ptDescriptors, /* Character descriptor array */ + funclimbingDemo_18ptBitmaps, /* Character bitmap array */ +}; diff --git a/applications/external/totp/ui/fonts/funclimbing/funclimbing.h b/applications/external/totp/ui/fonts/funclimbing/funclimbing.h new file mode 100644 index 000000000..26614adf1 --- /dev/null +++ b/applications/external/totp/ui/fonts/funclimbing/funclimbing.h @@ -0,0 +1,7 @@ +#pragma once + +/* GENERATED BY https://github.com/pavius/the-dot-factory */ + +#include "../font_info.h" + +extern const FONT_INFO funclimbingDemo_18ptFontInfo; \ No newline at end of file diff --git a/applications/external/totp/ui/fonts/pixelflag/pixelflag.c b/applications/external/totp/ui/fonts/pixelflag/pixelflag.c new file mode 100644 index 000000000..2b7be9eb8 --- /dev/null +++ b/applications/external/totp/ui/fonts/pixelflag/pixelflag.c @@ -0,0 +1,1114 @@ +#include "pixelflag.h" + +/* GENERATED BY https://github.com/pavius/the-dot-factory */ + +/* +** Font data for {PixelFlag} 18pt +*/ + +/* Character bitmaps for {PixelFlag} 18pt */ +const uint8_t pixelFlag_18ptBitmaps[] = { + /* @0 '-' (13 pixels wide) */ + 0xFE, + 0x07, + 0xFE, + 0x07, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xF8, + 0x07, + 0xF8, + 0x07, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xFE, + 0x07, + 0xFE, + 0x07, + + /* @34 '0' (13 pixels wide) */ + 0xFF, + 0x1F, + 0xFF, + 0x1F, + 0x00, + 0x00, + 0xF8, + 0x07, + 0xF8, + 0x07, + 0x0C, + 0x18, + 0x0C, + 0x18, + 0x0C, + 0x18, + 0x0C, + 0x18, + 0x0C, + 0x18, + 0x0C, + 0x18, + 0x0C, + 0x18, + 0xFC, + 0x1F, + 0xF8, + 0x07, + 0x00, + 0x00, + 0xFF, + 0x1F, + 0xFF, + 0x1F, + + /* @68 '1' (13 pixels wide) */ + 0xff, + 0xff, + 0xff, + 0xff, + 0x00, + 0xe0, + 0xc0, + 0xe0, + 0xc0, + 0xe0, + 0xe0, + 0xe0, + 0xe0, + 0xe0, + 0xc0, + 0xe0, + 0xc0, + 0xe0, + 0xc0, + 0xe0, + 0xc0, + 0xe0, + 0xc0, + 0xe0, + 0xe0, + 0xe3, + 0xe0, + 0xe3, + 0x00, + 0xe0, + 0xff, + 0xff, + 0xff, + 0xff, + + /* @102 '2' (13 pixels wide) */ + 0xFF, + 0x1F, + 0xFF, + 0x1F, + 0x00, + 0x00, + 0xFC, + 0x07, + 0xFC, + 0x07, + 0x00, + 0x18, + 0x00, + 0x18, + 0x00, + 0x18, + 0xF8, + 0x07, + 0xFC, + 0x07, + 0x0C, + 0x00, + 0x0C, + 0x00, + 0xFC, + 0x1F, + 0xFC, + 0x1F, + 0x00, + 0x00, + 0xFF, + 0x1F, + 0xFF, + 0x1F, + + /* @136 '3' (13 pixels wide) */ + 0xFF, + 0x1F, + 0xFF, + 0x1F, + 0x00, + 0x00, + 0xFC, + 0x07, + 0xFC, + 0x07, + 0x00, + 0x18, + 0x00, + 0x18, + 0x00, + 0x18, + 0xE0, + 0x07, + 0xE0, + 0x1F, + 0x00, + 0x18, + 0x00, + 0x18, + 0xFC, + 0x1F, + 0xFC, + 0x07, + 0x00, + 0x00, + 0xFF, + 0x1F, + 0xFF, + 0x1F, + + /* @170 '4' (13 pixels wide) */ + 0xFF, + 0x1F, + 0xFF, + 0x1F, + 0x00, + 0x00, + 0x00, + 0x06, + 0x00, + 0x06, + 0x00, + 0x07, + 0xC0, + 0x07, + 0xC0, + 0x06, + 0x60, + 0x06, + 0x78, + 0x06, + 0x18, + 0x06, + 0xFC, + 0x1F, + 0xFC, + 0x1F, + 0x00, + 0x06, + 0x00, + 0x00, + 0xFF, + 0x1F, + 0xFF, + 0x1F, + + /* @204 '5' (13 pixels wide) */ + 0xFF, + 0x1F, + 0xFF, + 0x1F, + 0x00, + 0x00, + 0xFC, + 0x1F, + 0xFC, + 0x1F, + 0x0C, + 0x00, + 0x0C, + 0x00, + 0x0C, + 0x00, + 0xFC, + 0x07, + 0xFC, + 0x1F, + 0x00, + 0x18, + 0x00, + 0x18, + 0xFC, + 0x1F, + 0xFC, + 0x07, + 0x00, + 0x00, + 0xFF, + 0x1F, + 0xFF, + 0x1F, + + /* @238 '6' (13 pixels wide) */ + 0xFF, + 0x1F, + 0xFF, + 0x1F, + 0x00, + 0x00, + 0xF8, + 0x07, + 0xF8, + 0x07, + 0x0C, + 0x18, + 0x0C, + 0x18, + 0x0C, + 0x00, + 0xFC, + 0x07, + 0xFC, + 0x1F, + 0x0C, + 0x18, + 0x0C, + 0x18, + 0xFC, + 0x1F, + 0xF8, + 0x07, + 0x00, + 0x00, + 0xFF, + 0x1F, + 0xFF, + 0x1F, + + /* @272 '7' (13 pixels wide) */ + 0xFF, + 0x1F, + 0xFF, + 0x1F, + 0x00, + 0x00, + 0xFC, + 0x1F, + 0xFC, + 0x1F, + 0x00, + 0x06, + 0x00, + 0x07, + 0x00, + 0x03, + 0xC0, + 0x00, + 0xE0, + 0x00, + 0x60, + 0x00, + 0x18, + 0x00, + 0x1C, + 0x00, + 0x0C, + 0x00, + 0x00, + 0x00, + 0xFF, + 0x1F, + 0xFF, + 0x1F, + + /* @306 '8' (13 pixels wide) */ + 0xFF, + 0x1F, + 0xFF, + 0x1F, + 0x00, + 0x00, + 0xF8, + 0x07, + 0xF8, + 0x07, + 0x0C, + 0x18, + 0x0C, + 0x18, + 0x0C, + 0x18, + 0xF8, + 0x07, + 0xFC, + 0x1F, + 0x0C, + 0x18, + 0x0C, + 0x18, + 0xFC, + 0x1F, + 0xF8, + 0x07, + 0x00, + 0x00, + 0xFF, + 0x1F, + 0xFF, + 0x1F, + + /* @340 '9' (13 pixels wide) */ + 0xFF, + 0x1F, + 0xFF, + 0x1F, + 0x00, + 0x00, + 0xF8, + 0x07, + 0xF8, + 0x07, + 0x0C, + 0x18, + 0x0C, + 0x18, + 0x0C, + 0x18, + 0xF8, + 0x1F, + 0xF8, + 0x1F, + 0x00, + 0x18, + 0x0C, + 0x18, + 0xFC, + 0x1F, + 0xF8, + 0x07, + 0x00, + 0x00, + 0xFF, + 0x1F, + 0xFF, + 0x1F, + + /* @374 'B' (13 pixels wide) */ + 0xFF, + 0x1F, + 0xFF, + 0x1F, + 0x00, + 0x00, + 0xFC, + 0x07, + 0xFC, + 0x07, + 0x0C, + 0x18, + 0x0C, + 0x18, + 0x0C, + 0x18, + 0xFC, + 0x07, + 0xFC, + 0x1F, + 0x0C, + 0x18, + 0x0C, + 0x18, + 0xFC, + 0x1F, + 0xFC, + 0x07, + 0x00, + 0x00, + 0xFF, + 0x1F, + 0xFF, + 0x1F, + + /* @408 'C' (13 pixels wide) */ + 0xFF, + 0x1F, + 0xFF, + 0x1F, + 0x00, + 0x00, + 0xF8, + 0x07, + 0xF8, + 0x07, + 0x0C, + 0x18, + 0x0C, + 0x18, + 0x0C, + 0x00, + 0x0C, + 0x00, + 0x0C, + 0x00, + 0x0C, + 0x00, + 0x0C, + 0x18, + 0xFC, + 0x1F, + 0xF8, + 0x07, + 0x00, + 0x00, + 0xFF, + 0x1F, + 0xFF, + 0x1F, + + /* @442 'D' (13 pixels wide) */ + 0xFF, + 0x1F, + 0xFF, + 0x1F, + 0x00, + 0x00, + 0xFC, + 0x07, + 0xFC, + 0x07, + 0x0C, + 0x18, + 0x0C, + 0x18, + 0x0C, + 0x18, + 0x0C, + 0x18, + 0x0C, + 0x18, + 0x0C, + 0x18, + 0x0C, + 0x18, + 0xFC, + 0x1F, + 0xFC, + 0x07, + 0x00, + 0x00, + 0xFF, + 0x1F, + 0xFF, + 0x1F, + + /* @476 'F' (13 pixels wide) */ + 0xFF, + 0x1F, + 0xFF, + 0x1F, + 0x00, + 0x00, + 0xFC, + 0x1F, + 0xFC, + 0x1F, + 0x0C, + 0x00, + 0x0C, + 0x00, + 0x0C, + 0x00, + 0xFC, + 0x03, + 0xFC, + 0x03, + 0x0C, + 0x00, + 0x0C, + 0x00, + 0x0C, + 0x00, + 0x0C, + 0x00, + 0x00, + 0x00, + 0xFF, + 0x1F, + 0xFF, + 0x1F, + + /* @510 'G' (13 pixels wide) */ + 0xFF, + 0x1F, + 0xFF, + 0x1F, + 0x00, + 0x00, + 0xF8, + 0x07, + 0xF8, + 0x07, + 0x0C, + 0x18, + 0x0C, + 0x18, + 0x0C, + 0x00, + 0xCC, + 0x1F, + 0xCC, + 0x1F, + 0x0C, + 0x18, + 0x0C, + 0x18, + 0xFC, + 0x1F, + 0xF8, + 0x07, + 0x00, + 0x00, + 0xFF, + 0x1F, + 0xFF, + 0x1F, + + /* @544 'H' (13 pixels wide) */ + 0xFF, + 0x1F, + 0xFF, + 0x1F, + 0x00, + 0x00, + 0x0C, + 0x18, + 0x0C, + 0x18, + 0x0C, + 0x18, + 0x0C, + 0x18, + 0x0C, + 0x18, + 0xFC, + 0x1F, + 0xFC, + 0x1F, + 0x0C, + 0x18, + 0x0C, + 0x18, + 0x0C, + 0x18, + 0x0C, + 0x18, + 0x00, + 0x00, + 0xFF, + 0x1F, + 0xFF, + 0x1F, + + /* @578 'J' (13 pixels wide) */ + 0xFF, + 0x1F, + 0xFF, + 0x1F, + 0x00, + 0x00, + 0x00, + 0x18, + 0x00, + 0x18, + 0x00, + 0x18, + 0x00, + 0x18, + 0x00, + 0x18, + 0x00, + 0x18, + 0x00, + 0x18, + 0x00, + 0x18, + 0x0C, + 0x18, + 0xFC, + 0x1F, + 0xF8, + 0x07, + 0x00, + 0x00, + 0xFF, + 0x1F, + 0xFF, + 0x1F, + + /* @612 'K' (13 pixels wide) */ + 0xFF, + 0x1F, + 0xFF, + 0x1F, + 0x00, + 0x00, + 0x0C, + 0x18, + 0x0C, + 0x18, + 0x0C, + 0x06, + 0x0C, + 0x07, + 0x0C, + 0x03, + 0xFC, + 0x00, + 0xFC, + 0x03, + 0x0C, + 0x03, + 0x0C, + 0x06, + 0x0C, + 0x1E, + 0x0C, + 0x18, + 0x00, + 0x00, + 0xFF, + 0x1F, + 0xFF, + 0x1F, + + /* @646 'M' (13 pixels wide) */ + 0xFF, + 0x1F, + 0xFF, + 0x1F, + 0x00, + 0x00, + 0x0C, + 0x18, + 0x0C, + 0x18, + 0x1C, + 0x1E, + 0x7C, + 0x1F, + 0x6C, + 0x1B, + 0xCC, + 0x18, + 0xCC, + 0x18, + 0x0C, + 0x18, + 0x0C, + 0x18, + 0x0C, + 0x18, + 0x0C, + 0x18, + 0x00, + 0x00, + 0xFF, + 0x1F, + 0xFF, + 0x1F, + + /* @680 'N' (13 pixels wide) */ + 0xFF, + 0x1F, + 0xFF, + 0x1F, + 0x00, + 0x00, + 0x0C, + 0x18, + 0x0C, + 0x18, + 0x1C, + 0x18, + 0x7C, + 0x18, + 0x6C, + 0x18, + 0xCC, + 0x18, + 0xCC, + 0x1B, + 0x0C, + 0x1B, + 0x0C, + 0x1E, + 0x0C, + 0x1E, + 0x0C, + 0x18, + 0x00, + 0x00, + 0xFF, + 0x1F, + 0xFF, + 0x1F, + + /* @714 'P' (13 pixels wide) */ + 0xFF, + 0x1F, + 0xFF, + 0x1F, + 0x00, + 0x00, + 0xFC, + 0x07, + 0xFC, + 0x07, + 0x0C, + 0x18, + 0x0C, + 0x18, + 0x0C, + 0x18, + 0xFC, + 0x07, + 0xFC, + 0x07, + 0x0C, + 0x00, + 0x0C, + 0x00, + 0x0C, + 0x00, + 0x0C, + 0x00, + 0x00, + 0x00, + 0xFF, + 0x1F, + 0xFF, + 0x1F, + + /* @748 'Q' (13 pixels wide) */ + 0xFF, + 0x1F, + 0xFF, + 0x1F, + 0x00, + 0x00, + 0xF8, + 0x07, + 0xF8, + 0x07, + 0x0C, + 0x18, + 0x0C, + 0x18, + 0x0C, + 0x18, + 0xCC, + 0x18, + 0xCC, + 0x1B, + 0x0C, + 0x1B, + 0x0C, + 0x1E, + 0xFC, + 0x1F, + 0xF8, + 0x07, + 0x00, + 0x00, + 0xFF, + 0x1F, + 0xFF, + 0x1F, + + /* @782 'R' (13 pixels wide) */ + 0xFF, + 0x1F, + 0xFF, + 0x1F, + 0x00, + 0x00, + 0xFC, + 0x07, + 0xFC, + 0x07, + 0x0C, + 0x18, + 0x0C, + 0x18, + 0x0C, + 0x18, + 0xFC, + 0x07, + 0xFC, + 0x1F, + 0x0C, + 0x18, + 0x0C, + 0x18, + 0x0C, + 0x18, + 0x0C, + 0x18, + 0x00, + 0x00, + 0xFF, + 0x1F, + 0xFF, + 0x1F, + + /* @816 'T' (13 pixels wide) */ + 0xFF, + 0x1F, + 0xFF, + 0x1F, + 0x00, + 0x00, + 0xFC, + 0x1F, + 0xFC, + 0x1F, + 0xC0, + 0x00, + 0xC0, + 0x00, + 0xC0, + 0x00, + 0xC0, + 0x00, + 0xC0, + 0x00, + 0xC0, + 0x00, + 0xC0, + 0x00, + 0xC0, + 0x00, + 0xC0, + 0x00, + 0x00, + 0x00, + 0xFF, + 0x1F, + 0xFF, + 0x1F, + + /* @850 'V' (13 pixels wide) */ + 0xFF, + 0x1F, + 0xFF, + 0x1F, + 0x00, + 0x00, + 0x0C, + 0x18, + 0x0C, + 0x18, + 0x0C, + 0x18, + 0x0C, + 0x18, + 0x0C, + 0x18, + 0x0C, + 0x18, + 0x1C, + 0x1E, + 0x18, + 0x06, + 0x60, + 0x03, + 0xE0, + 0x03, + 0xC0, + 0x00, + 0x00, + 0x00, + 0xFF, + 0x1F, + 0xFF, + 0x1F, + + /* @884 'W' (13 pixels wide) */ + 0xFF, + 0x1F, + 0xFF, + 0x1F, + 0x00, + 0x00, + 0x0C, + 0x18, + 0x0C, + 0x18, + 0x0C, + 0x18, + 0xCC, + 0x18, + 0xCC, + 0x18, + 0xCC, + 0x18, + 0xCC, + 0x18, + 0xCC, + 0x18, + 0xCC, + 0x18, + 0xFC, + 0x1F, + 0x78, + 0x07, + 0x00, + 0x00, + 0xFF, + 0x1F, + 0xFF, + 0x1F, + + /* @918 'X' (13 pixels wide) */ + 0xFF, + 0x1F, + 0xFF, + 0x1F, + 0x00, + 0x00, + 0x0C, + 0x18, + 0x0C, + 0x18, + 0x18, + 0x06, + 0x78, + 0x07, + 0x60, + 0x03, + 0xC0, + 0x00, + 0xE0, + 0x03, + 0x60, + 0x03, + 0x18, + 0x06, + 0x1C, + 0x1E, + 0x0C, + 0x18, + 0x00, + 0x00, + 0xFF, + 0x1F, + 0xFF, + 0x1F, + + /* @952 'Y' (13 pixels wide) */ + 0xFF, + 0x1F, + 0xFF, + 0x1F, + 0x00, + 0x00, + 0x0C, + 0x18, + 0x0C, + 0x18, + 0x18, + 0x06, + 0x78, + 0x07, + 0x60, + 0x03, + 0xC0, + 0x00, + 0xC0, + 0x00, + 0xC0, + 0x00, + 0xC0, + 0x00, + 0xC0, + 0x00, + 0xC0, + 0x00, + 0x00, + 0x00, + 0xFF, + 0x1F, + 0xFF, + 0x1F, +}; + +/* Character descriptors for {PixelFlag} 18pt */ +/* { [Char width in bits], [Offset into pixelFlag_18ptCharBitmaps in bytes] } */ +const FONT_CHAR_INFO pixelFlag_18ptDescriptors[] = { + {13, 0}, /* - */ + {0, 0}, /* . */ + {0, 0}, /* / */ + {13, 34}, /* 0 */ + {13, 68}, /* 1 */ + {13, 102}, /* 2 */ + {13, 136}, /* 3 */ + {13, 170}, /* 4 */ + {13, 204}, /* 5 */ + {13, 238}, /* 6 */ + {13, 272}, /* 7 */ + {13, 306}, /* 8 */ + {13, 340}, /* 9 */ + {0, 0}, /* : */ + {0, 0}, /* ; */ + {0, 0}, /* < */ + {0, 0}, /* = */ + {0, 0}, /* > */ + {0, 0}, /* ? */ + {0, 0}, /* @ */ + {0, 0}, /* A */ + {13, 374}, /* B */ + {13, 408}, /* C */ + {13, 442}, /* D */ + {0, 0}, /* E */ + {13, 476}, /* F */ + {13, 510}, /* G */ + {13, 544}, /* H */ + {0, 0}, /* I */ + {13, 578}, /* J */ + {13, 612}, /* K */ + {0, 0}, /* L */ + {13, 646}, /* M */ + {13, 680}, /* N */ + {0, 0}, /* O */ + {13, 714}, /* P */ + {13, 748}, /* Q */ + {13, 782}, /* R */ + {0, 0}, /* S */ + {13, 816}, /* T */ + {0, 0}, /* U */ + {13, 850}, /* V */ + {13, 884}, /* W */ + {13, 918}, /* X */ + {13, 952}, /* Y */ +}; + +/* Font information for {PixelFlag} 18pt */ +const FONT_INFO pixelFlag_18ptFontInfo = { + 17, /* Character height */ + '-', /* Start character */ + 'Y', /* End character */ + 0, /* Width, in pixels, of space character */ + pixelFlag_18ptDescriptors, /* Character descriptor array */ + pixelFlag_18ptBitmaps, /* Character bitmap array */ +}; diff --git a/applications/external/totp/ui/fonts/pixelflag/pixelflag.h b/applications/external/totp/ui/fonts/pixelflag/pixelflag.h new file mode 100644 index 000000000..dc339c84d --- /dev/null +++ b/applications/external/totp/ui/fonts/pixelflag/pixelflag.h @@ -0,0 +1,7 @@ +#pragma once + +/* GENERATED BY https://github.com/pavius/the-dot-factory */ + +#include "../font_info.h" + +extern const FONT_INFO pixelFlag_18ptFontInfo; \ No newline at end of file diff --git a/applications/external/totp/ui/scenes/app_settings/totp_app_settings.c b/applications/external/totp/ui/scenes/app_settings/totp_app_settings.c index 0bdc7aee3..bf76b7c82 100644 --- a/applications/external/totp/ui/scenes/app_settings/totp_app_settings.c +++ b/applications/external/totp/ui/scenes/app_settings/totp_app_settings.c @@ -250,7 +250,7 @@ bool totp_scene_app_settings_handle_event( #endif else if(scene_state->selected_control == FontSelector) { totp_roll_value_uint8_t( - &scene_state->selected_font, 1, 0, 6, RollOverflowBehaviorStop); + &scene_state->selected_font, 1, 0, MAX_CUSTOM_FONTS, RollOverflowBehaviorStop); } break; case InputKeyLeft: @@ -274,7 +274,7 @@ bool totp_scene_app_settings_handle_event( #endif else if(scene_state->selected_control == FontSelector) { totp_roll_value_uint8_t( - &scene_state->selected_font, -1, 0, 6, RollOverflowBehaviorStop); + &scene_state->selected_font, -1, 0, MAX_CUSTOM_FONTS, RollOverflowBehaviorStop); } break; case InputKeyOk: diff --git a/applications/external/totp/ui/scenes/generate_token/totp_scene_generate_token.c b/applications/external/totp/ui/scenes/generate_token/totp_scene_generate_token.c index e55f34ea2..da99623fd 100644 --- a/applications/external/totp/ui/scenes/generate_token/totp_scene_generate_token.c +++ b/applications/external/totp/ui/scenes/generate_token/totp_scene_generate_token.c @@ -165,6 +165,15 @@ static void draw_totp_code(Canvas* const canvas, const PluginState* const plugin case 6: current_font = &karmaFuture_14ptFontInfo; break; + case 7: + current_font = &funclimbingDemo_18ptFontInfo; + break; + case 8: + current_font = &dPComic_18ptFontInfo; + break; + case 9: + current_font = &pixelFlag_18ptFontInfo; + break; default: current_font = &modeNine_15ptFontInfo; break; @@ -222,6 +231,15 @@ static void on_new_token_code_generated(bool time_left, void* context) { case 6: current_font = &karmaFuture_14ptFontInfo; break; + case 7: + current_font = &funclimbingDemo_18ptFontInfo; + break; + case 8: + current_font = &dPComic_18ptFontInfo; + break; + case 9: + current_font = &pixelFlag_18ptFontInfo; + break; default: current_font = &modeNine_15ptFontInfo; break; From d09c59fd2f90ebfc6404a0a89453d05c7847436d Mon Sep 17 00:00:00 2001 From: Skorpionm <85568270+Skorpionm@users.noreply.github.com> Date: Wed, 31 May 2023 16:59:12 +0400 Subject: [PATCH 39/52] [FL-3340] SubGhz: fix flipper crashes after exiting broadcast blocking message and crash cli (#2714) --- .../main/subghz/helpers/subghz_error_type.h | 1 + .../main/subghz/scenes/subghz_scene_rpc.c | 33 ++++++++++++------- applications/main/subghz/subghz_cli.c | 17 ++++++---- 3 files changed, 33 insertions(+), 18 deletions(-) diff --git a/applications/main/subghz/helpers/subghz_error_type.h b/applications/main/subghz/helpers/subghz_error_type.h index e481aa4be..0f86d6ea7 100644 --- a/applications/main/subghz/helpers/subghz_error_type.h +++ b/applications/main/subghz/helpers/subghz_error_type.h @@ -10,4 +10,5 @@ typedef enum { 1, /** File parsing error, or wrong file structure, or missing required parameters. more accurate data can be obtained through the debug port */ SubGhzErrorTypeOnlyRX = 2, /** Transmission on this frequency is blocked by regional settings */ + SubGhzErrorTypeParserOthers = 3, /** Error in protocol parameters description */ } SubGhzErrorType; diff --git a/applications/main/subghz/scenes/subghz_scene_rpc.c b/applications/main/subghz/scenes/subghz_scene_rpc.c index aa6f132d7..d4bf3e808 100644 --- a/applications/main/subghz/scenes/subghz_scene_rpc.c +++ b/applications/main/subghz/scenes/subghz_scene_rpc.c @@ -40,15 +40,26 @@ bool subghz_scene_rpc_on_event(void* context, SceneManagerEvent event) { } else if(event.event == SubGhzCustomEventSceneRpcButtonPress) { bool result = false; if((state == SubGhzRpcStateLoaded)) { - result = subghz_tx_start(subghz, subghz_txrx_get_fff_data(subghz->txrx)); - state = SubGhzRpcStateTx; - if(result) subghz_blink_start(subghz); - } - if(!result) { - rpc_system_app_set_error_code(subghz->rpc_ctx, SubGhzErrorTypeOnlyRX); - rpc_system_app_set_error_text( - subghz->rpc_ctx, - "Transmission on this frequency is restricted in your region"); + switch( + subghz_txrx_tx_start(subghz->txrx, subghz_txrx_get_fff_data(subghz->txrx))) { + case SubGhzTxRxStartTxStateErrorOnlyRx: + rpc_system_app_set_error_code(subghz->rpc_ctx, SubGhzErrorTypeOnlyRX); + rpc_system_app_set_error_text( + subghz->rpc_ctx, + "Transmission on this frequency is restricted in your region"); + break; + case SubGhzTxRxStartTxStateErrorParserOthers: + rpc_system_app_set_error_code(subghz->rpc_ctx, SubGhzErrorTypeParserOthers); + rpc_system_app_set_error_text( + subghz->rpc_ctx, "Error in protocol parameters description"); + break; + + default: //if(SubGhzTxRxStartTxStateOk) + result = true; + subghz_blink_start(subghz); + state = SubGhzRpcStateTx; + break; + } } rpc_system_app_confirm(subghz->rpc_ctx, RpcAppEventButtonPress, result); } else if(event.event == SubGhzCustomEventSceneRpcButtonRelease) { @@ -56,9 +67,9 @@ bool subghz_scene_rpc_on_event(void* context, SceneManagerEvent event) { if(state == SubGhzRpcStateTx) { subghz_txrx_stop(subghz->txrx); subghz_blink_stop(subghz); - state = SubGhzRpcStateIdle; result = true; } + state = SubGhzRpcStateIdle; rpc_system_app_confirm(subghz->rpc_ctx, RpcAppEventButtonRelease, result); } else if(event.event == SubGhzCustomEventSceneRpcLoad) { bool result = false; @@ -95,7 +106,7 @@ bool subghz_scene_rpc_on_event(void* context, SceneManagerEvent event) { void subghz_scene_rpc_on_exit(void* context) { SubGhz* subghz = context; SubGhzRpcState state = scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneRpc); - if(state != SubGhzRpcStateIdle) { + if(state == SubGhzRpcStateTx) { subghz_txrx_stop(subghz->txrx); subghz_blink_stop(subghz); } diff --git a/applications/main/subghz/subghz_cli.c b/applications/main/subghz/subghz_cli.c index ac19d65b4..60845ac99 100644 --- a/applications/main/subghz/subghz_cli.c +++ b/applications/main/subghz/subghz_cli.c @@ -176,16 +176,19 @@ void subghz_cli_command_tx(Cli* cli, FuriString* args, void* context) { furi_hal_power_suppress_charge_enter(); - furi_hal_subghz_start_async_tx(subghz_transmitter_yield, transmitter); + if(furi_hal_subghz_start_async_tx(subghz_transmitter_yield, transmitter)) { + while(!(furi_hal_subghz_is_async_tx_complete() || cli_cmd_interrupt_received(cli))) { + printf("."); + fflush(stdout); + furi_delay_ms(333); + } + furi_hal_subghz_stop_async_tx(); - while(!(furi_hal_subghz_is_async_tx_complete() || cli_cmd_interrupt_received(cli))) { - printf("."); - fflush(stdout); - furi_delay_ms(333); + } else { + printf("Transmission on this frequency is restricted in your region\r\n"); } - furi_hal_subghz_stop_async_tx(); - furi_hal_subghz_sleep(); + furi_hal_subghz_sleep(); furi_hal_power_suppress_charge_exit(); flipper_format_free(flipper_format); From 86a64487cb1f7b43fcf46b73735ff032c4f23e6f Mon Sep 17 00:00:00 2001 From: AloneLiberty <111039319+AloneLiberty@users.noreply.github.com> Date: Wed, 31 May 2023 13:56:04 +0000 Subject: [PATCH 40/52] NFC: Fix gen1 writing with invalid BCC (lost fix from PR #2511) (#2710) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: あく --- .../nfc_magic/lib/magic/classic_gen1.c | 30 --- .../nfc_magic/lib/magic/classic_gen1.h | 2 - .../external/nfc_magic/lib/magic/magic.c | 175 ------------------ .../external/nfc_magic/nfc_magic_worker.c | 66 ++++--- 4 files changed, 45 insertions(+), 228 deletions(-) delete mode 100644 applications/external/nfc_magic/lib/magic/magic.c diff --git a/applications/external/nfc_magic/lib/magic/classic_gen1.c b/applications/external/nfc_magic/lib/magic/classic_gen1.c index ebd2b0805..8d87d6316 100644 --- a/applications/external/nfc_magic/lib/magic/classic_gen1.c +++ b/applications/external/nfc_magic/lib/magic/classic_gen1.c @@ -5,7 +5,6 @@ #define TAG "Magic" #define MAGIC_CMD_WUPA (0x40) -#define MAGIC_CMD_WIPE (0x41) #define MAGIC_CMD_ACCESS (0x43) #define MAGIC_MIFARE_READ_CMD (0x30) @@ -144,32 +143,3 @@ bool magic_gen1_write_blk(uint8_t block_num, MfClassicBlock* data) { return write_success; } - -bool magic_gen1_wipe() { - bool wipe_success = false; - uint8_t tx_data[MAGIC_BUFFER_SIZE] = {}; - uint8_t rx_data[MAGIC_BUFFER_SIZE] = {}; - uint16_t rx_len = 0; - FuriHalNfcReturn ret = 0; - - do { - tx_data[0] = MAGIC_CMD_WIPE; - ret = furi_hal_nfc_ll_txrx_bits( - tx_data, - 8, - rx_data, - sizeof(rx_data), - &rx_len, - FURI_HAL_NFC_LL_TXRX_FLAGS_CRC_TX_MANUAL | FURI_HAL_NFC_LL_TXRX_FLAGS_AGC_ON | - FURI_HAL_NFC_LL_TXRX_FLAGS_CRC_RX_KEEP, - furi_hal_nfc_ll_ms2fc(2000)); - - if(ret != FuriHalNfcReturnIncompleteByte) break; - if(rx_len != 4) break; - if(rx_data[0] != MAGIC_ACK) break; - - wipe_success = true; - } while(false); - - return wipe_success; -} \ No newline at end of file diff --git a/applications/external/nfc_magic/lib/magic/classic_gen1.h b/applications/external/nfc_magic/lib/magic/classic_gen1.h index 6d4ff6dcd..98de12302 100644 --- a/applications/external/nfc_magic/lib/magic/classic_gen1.h +++ b/applications/external/nfc_magic/lib/magic/classic_gen1.h @@ -9,5 +9,3 @@ bool magic_gen1_read_block(uint8_t block_num, MfClassicBlock* data); bool magic_gen1_data_access_cmd(); bool magic_gen1_write_blk(uint8_t block_num, MfClassicBlock* data); - -bool magic_gen1_wipe(); \ No newline at end of file diff --git a/applications/external/nfc_magic/lib/magic/magic.c b/applications/external/nfc_magic/lib/magic/magic.c deleted file mode 100644 index ebd2b0805..000000000 --- a/applications/external/nfc_magic/lib/magic/magic.c +++ /dev/null @@ -1,175 +0,0 @@ -#include "classic_gen1.h" - -#include - -#define TAG "Magic" - -#define MAGIC_CMD_WUPA (0x40) -#define MAGIC_CMD_WIPE (0x41) -#define MAGIC_CMD_ACCESS (0x43) - -#define MAGIC_MIFARE_READ_CMD (0x30) -#define MAGIC_MIFARE_WRITE_CMD (0xA0) - -#define MAGIC_ACK (0x0A) - -#define MAGIC_BUFFER_SIZE (32) - -bool magic_gen1_wupa() { - bool magic_activated = false; - uint8_t tx_data[MAGIC_BUFFER_SIZE] = {}; - uint8_t rx_data[MAGIC_BUFFER_SIZE] = {}; - uint16_t rx_len = 0; - FuriHalNfcReturn ret = 0; - - do { - // Start communication - tx_data[0] = MAGIC_CMD_WUPA; - ret = furi_hal_nfc_ll_txrx_bits( - tx_data, - 7, - rx_data, - sizeof(rx_data), - &rx_len, - FURI_HAL_NFC_LL_TXRX_FLAGS_CRC_TX_MANUAL | FURI_HAL_NFC_LL_TXRX_FLAGS_AGC_ON | - FURI_HAL_NFC_LL_TXRX_FLAGS_CRC_RX_KEEP, - furi_hal_nfc_ll_ms2fc(20)); - if(ret != FuriHalNfcReturnIncompleteByte) break; - if(rx_len != 4) break; - if(rx_data[0] != MAGIC_ACK) break; - magic_activated = true; - } while(false); - - return magic_activated; -} - -bool magic_gen1_data_access_cmd() { - bool write_cmd_success = false; - uint8_t tx_data[MAGIC_BUFFER_SIZE] = {}; - uint8_t rx_data[MAGIC_BUFFER_SIZE] = {}; - uint16_t rx_len = 0; - FuriHalNfcReturn ret = 0; - - do { - tx_data[0] = MAGIC_CMD_ACCESS; - ret = furi_hal_nfc_ll_txrx_bits( - tx_data, - 8, - rx_data, - sizeof(rx_data), - &rx_len, - FURI_HAL_NFC_LL_TXRX_FLAGS_CRC_TX_MANUAL | FURI_HAL_NFC_LL_TXRX_FLAGS_AGC_ON | - FURI_HAL_NFC_LL_TXRX_FLAGS_CRC_RX_KEEP, - furi_hal_nfc_ll_ms2fc(20)); - if(ret != FuriHalNfcReturnIncompleteByte) break; - if(rx_len != 4) break; - if(rx_data[0] != MAGIC_ACK) break; - - write_cmd_success = true; - } while(false); - - return write_cmd_success; -} - -bool magic_gen1_read_block(uint8_t block_num, MfClassicBlock* data) { - furi_assert(data); - - bool read_success = false; - - uint8_t tx_data[MAGIC_BUFFER_SIZE] = {}; - uint8_t rx_data[MAGIC_BUFFER_SIZE] = {}; - uint16_t rx_len = 0; - FuriHalNfcReturn ret = 0; - - do { - tx_data[0] = MAGIC_MIFARE_READ_CMD; - tx_data[1] = block_num; - ret = furi_hal_nfc_ll_txrx_bits( - tx_data, - 2 * 8, - rx_data, - sizeof(rx_data), - &rx_len, - FURI_HAL_NFC_LL_TXRX_FLAGS_AGC_ON, - furi_hal_nfc_ll_ms2fc(20)); - - if(ret != FuriHalNfcReturnOk) break; - if(rx_len != 16 * 8) break; - memcpy(data->value, rx_data, sizeof(data->value)); - read_success = true; - } while(false); - - return read_success; -} - -bool magic_gen1_write_blk(uint8_t block_num, MfClassicBlock* data) { - furi_assert(data); - - bool write_success = false; - uint8_t tx_data[MAGIC_BUFFER_SIZE] = {}; - uint8_t rx_data[MAGIC_BUFFER_SIZE] = {}; - uint16_t rx_len = 0; - FuriHalNfcReturn ret = 0; - - do { - tx_data[0] = MAGIC_MIFARE_WRITE_CMD; - tx_data[1] = block_num; - ret = furi_hal_nfc_ll_txrx_bits( - tx_data, - 2 * 8, - rx_data, - sizeof(rx_data), - &rx_len, - FURI_HAL_NFC_LL_TXRX_FLAGS_AGC_ON | FURI_HAL_NFC_LL_TXRX_FLAGS_CRC_RX_KEEP, - furi_hal_nfc_ll_ms2fc(20)); - if(ret != FuriHalNfcReturnIncompleteByte) break; - if(rx_len != 4) break; - if(rx_data[0] != MAGIC_ACK) break; - - memcpy(tx_data, data->value, sizeof(data->value)); - ret = furi_hal_nfc_ll_txrx_bits( - tx_data, - 16 * 8, - rx_data, - sizeof(rx_data), - &rx_len, - FURI_HAL_NFC_LL_TXRX_FLAGS_AGC_ON | FURI_HAL_NFC_LL_TXRX_FLAGS_CRC_RX_KEEP, - furi_hal_nfc_ll_ms2fc(20)); - if(ret != FuriHalNfcReturnIncompleteByte) break; - if(rx_len != 4) break; - if(rx_data[0] != MAGIC_ACK) break; - - write_success = true; - } while(false); - - return write_success; -} - -bool magic_gen1_wipe() { - bool wipe_success = false; - uint8_t tx_data[MAGIC_BUFFER_SIZE] = {}; - uint8_t rx_data[MAGIC_BUFFER_SIZE] = {}; - uint16_t rx_len = 0; - FuriHalNfcReturn ret = 0; - - do { - tx_data[0] = MAGIC_CMD_WIPE; - ret = furi_hal_nfc_ll_txrx_bits( - tx_data, - 8, - rx_data, - sizeof(rx_data), - &rx_len, - FURI_HAL_NFC_LL_TXRX_FLAGS_CRC_TX_MANUAL | FURI_HAL_NFC_LL_TXRX_FLAGS_AGC_ON | - FURI_HAL_NFC_LL_TXRX_FLAGS_CRC_RX_KEEP, - furi_hal_nfc_ll_ms2fc(2000)); - - if(ret != FuriHalNfcReturnIncompleteByte) break; - if(rx_len != 4) break; - if(rx_data[0] != MAGIC_ACK) break; - - wipe_success = true; - } while(false); - - return wipe_success; -} \ No newline at end of file diff --git a/applications/external/nfc_magic/nfc_magic_worker.c b/applications/external/nfc_magic/nfc_magic_worker.c index dc22b5d3e..9ee7fd3ee 100644 --- a/applications/external/nfc_magic/nfc_magic_worker.c +++ b/applications/external/nfc_magic/nfc_magic_worker.c @@ -92,51 +92,49 @@ void nfc_magic_worker_write(NfcMagicWorker* nfc_magic_worker) { while(nfc_magic_worker->state == NfcMagicWorkerStateWrite) { do { - if(furi_hal_nfc_detect(&nfc_data, 200)) { - if(nfc_data.cuid != magic_dev->cuid) break; - if(!card_found_notified) { - nfc_magic_worker->callback( - NfcMagicWorkerEventCardDetected, nfc_magic_worker->context); - card_found_notified = true; - } - furi_hal_nfc_sleep(); - - magic_activate(); - if(magic_dev->type == MagicTypeClassicGen1) { - if(dev_protocol != NfcDeviceProtocolMifareClassic) break; - MfClassicData* mfc_data = &dev_data->mf_classic_data; - - if(mfc_data->type != MfClassicType1k) break; + if(magic_dev->type == MagicTypeClassicGen1) { + if(furi_hal_nfc_detect(&nfc_data, 200)) { + magic_deactivate(); + magic_activate(); if(!magic_gen1_wupa()) { - FURI_LOG_E(TAG, "Not Magic card"); + FURI_LOG_E(TAG, "No card response to WUPA (not a magic card)"); nfc_magic_worker->callback( NfcMagicWorkerEventWrongCard, nfc_magic_worker->context); done = true; break; } + magic_deactivate(); + } + magic_activate(); + if(magic_gen1_wupa()) { if(!magic_gen1_data_access_cmd()) { - FURI_LOG_E(TAG, "Not Magic card"); + FURI_LOG_E( + TAG, "No card response to data access command (not a magic card)"); nfc_magic_worker->callback( NfcMagicWorkerEventWrongCard, nfc_magic_worker->context); done = true; break; } + + MfClassicData* mfc_data = &dev_data->mf_classic_data; for(size_t i = 0; i < 64; i++) { FURI_LOG_D(TAG, "Writing block %d", i); if(!magic_gen1_write_blk(i, &mfc_data->block[i])) { FURI_LOG_E(TAG, "Failed to write %d block", i); + done = true; nfc_magic_worker->callback( NfcMagicWorkerEventFail, nfc_magic_worker->context); - done = true; break; } } + done = true; nfc_magic_worker->callback( NfcMagicWorkerEventSuccess, nfc_magic_worker->context); - done = true; break; - } else if(magic_dev->type == MagicTypeGen4) { + } + } else if(magic_dev->type == MagicTypeGen4) { + if(furi_hal_nfc_detect(&nfc_data, 200)) { uint8_t gen4_config[28]; uint32_t password = magic_dev->password; @@ -196,6 +194,7 @@ void nfc_magic_worker_write(NfcMagicWorker* nfc_magic_worker) { gen4_config[25] = dev_data->nfc_data.atqa[1]; gen4_config[26] = dev_data->nfc_data.sak; + furi_hal_nfc_sleep(); furi_hal_nfc_activate_nfca(200, &cuid); if(!magic_gen4_set_cfg(password, gen4_config, sizeof(gen4_config), false)) { nfc_magic_worker->callback( @@ -394,6 +393,11 @@ void nfc_magic_worker_wipe(NfcMagicWorker* nfc_magic_worker) { MfClassicBlock block; memset(&block, 0, sizeof(MfClassicBlock)); + MfClassicBlock empty_block; + memset(&empty_block, 0, sizeof(MfClassicBlock)); + MfClassicBlock trailer_block; + memset(&trailer_block, 0xff, sizeof(MfClassicBlock)); + block.value[0] = 0x01; block.value[1] = 0x02; block.value[2] = 0x03; @@ -402,6 +406,10 @@ void nfc_magic_worker_wipe(NfcMagicWorker* nfc_magic_worker) { block.value[5] = 0x08; block.value[6] = 0x04; + trailer_block.value[7] = 0x07; + trailer_block.value[8] = 0x80; + trailer_block.value[9] = 0x69; + while(nfc_magic_worker->state == NfcMagicWorkerStateWipe) { do { magic_deactivate(); @@ -415,10 +423,26 @@ void nfc_magic_worker_wipe(NfcMagicWorker* nfc_magic_worker) { card_found_notified = true; } - if(!magic_gen1_wipe()) break; if(!magic_gen1_data_access_cmd()) break; if(!magic_gen1_write_blk(0, &block)) break; + for(size_t i = 1; i < 64; i++) { + FURI_LOG_D(TAG, "Wiping block %d", i); + bool success = false; + if((i | 0x03) == i) { + success = magic_gen1_write_blk(i, &trailer_block); + } else { + success = magic_gen1_write_blk(i, &empty_block); + } + + if(!success) { + FURI_LOG_E(TAG, "Failed to write %d block", i); + nfc_magic_worker->callback( + NfcMagicWorkerEventFail, nfc_magic_worker->context); + break; + } + } + card_wiped = true; nfc_magic_worker->callback(NfcMagicWorkerEventSuccess, nfc_magic_worker->context); } else if(magic_dev->type == MagicTypeGen4) { From b18bf3eddb5f52519e3a35afcc38f523a1d5645d Mon Sep 17 00:00:00 2001 From: Tiernan Messmer Date: Wed, 31 May 2023 23:28:46 +1000 Subject: [PATCH 41/52] nfcv code review fixes --- .../main/nfc/scenes/nfc_scene_nfc_data_info.c | 67 ++++++++----------- .../main/nfc/scenes/nfc_scene_nfcv_emulate.c | 1 - lib/nfc/nfc_worker.c | 21 +++--- lib/nfc/protocols/nfcv.h | 2 +- 4 files changed, 39 insertions(+), 52 deletions(-) diff --git a/applications/main/nfc/scenes/nfc_scene_nfc_data_info.c b/applications/main/nfc/scenes/nfc_scene_nfc_data_info.c index 711dc39ee..1c1e3e4b4 100644 --- a/applications/main/nfc/scenes/nfc_scene_nfc_data_info.c +++ b/applications/main/nfc/scenes/nfc_scene_nfc_data_info.c @@ -7,17 +7,6 @@ void nfc_scene_nfc_data_info_widget_callback(GuiButtonType result, InputType typ } } -uint32_t nfc_scene_nfc_data_info_get_key(uint8_t* data) { - uint32_t value = 0; - - for(uint32_t pos = 0; pos < 4; pos++) { - value <<= 8; - value |= data[pos]; - } - - return value; -} - void nfc_scene_nfc_data_info_on_enter(void* context) { Nfc* nfc = context; Widget* widget = nfc->widget; @@ -129,72 +118,72 @@ void nfc_scene_nfc_data_info_on_enter(void* context) { furi_string_cat_printf(temp_str, "Keys:\n"); furi_string_cat_printf( temp_str, - " EAS %08lX\n", - nfc_scene_nfc_data_info_get_key(nfcv_data->sub_data.slix.key_eas)); + " EAS %08llX\n", + nfc_util_bytes2num(nfcv_data->sub_data.slix.key_eas, 4)); break; case NfcVTypeSlixS: furi_string_cat_printf(temp_str, "Type: SLIX-S\n"); furi_string_cat_printf(temp_str, "Keys:\n"); furi_string_cat_printf( temp_str, - " Read %08lX\n", - nfc_scene_nfc_data_info_get_key(nfcv_data->sub_data.slix.key_read)); + " Read %08llX\n", + nfc_util_bytes2num(nfcv_data->sub_data.slix.key_read, 4)); furi_string_cat_printf( temp_str, - " Write %08lX\n", - nfc_scene_nfc_data_info_get_key(nfcv_data->sub_data.slix.key_write)); + " Write %08llX\n", + nfc_util_bytes2num(nfcv_data->sub_data.slix.key_write, 4)); furi_string_cat_printf( temp_str, - " Privacy %08lX\n", - nfc_scene_nfc_data_info_get_key(nfcv_data->sub_data.slix.key_privacy)); + " Privacy %08llX\n", + nfc_util_bytes2num(nfcv_data->sub_data.slix.key_privacy, 4)); furi_string_cat_printf( temp_str, - " Destroy %08lX\n", - nfc_scene_nfc_data_info_get_key(nfcv_data->sub_data.slix.key_destroy)); + " Destroy %08llX\n", + nfc_util_bytes2num(nfcv_data->sub_data.slix.key_destroy, 4)); furi_string_cat_printf( temp_str, - " EAS %08lX\n", - nfc_scene_nfc_data_info_get_key(nfcv_data->sub_data.slix.key_eas)); + " EAS %08llX\n", + nfc_util_bytes2num(nfcv_data->sub_data.slix.key_eas, 4)); break; case NfcVTypeSlixL: furi_string_cat_printf(temp_str, "Type: SLIX-L\n"); furi_string_cat_printf(temp_str, "Keys:\n"); furi_string_cat_printf( temp_str, - " Privacy %08lX\n", - nfc_scene_nfc_data_info_get_key(nfcv_data->sub_data.slix.key_privacy)); + " Privacy %08llX\n", + nfc_util_bytes2num(nfcv_data->sub_data.slix.key_privacy, 4)); furi_string_cat_printf( temp_str, - " Destroy %08lX\n", - nfc_scene_nfc_data_info_get_key(nfcv_data->sub_data.slix.key_destroy)); + " Destroy %08llX\n", + nfc_util_bytes2num(nfcv_data->sub_data.slix.key_destroy, 4)); furi_string_cat_printf( temp_str, - " EAS %08lX\n", - nfc_scene_nfc_data_info_get_key(nfcv_data->sub_data.slix.key_eas)); + " EAS %08llX\n", + nfc_util_bytes2num(nfcv_data->sub_data.slix.key_eas, 4)); break; case NfcVTypeSlix2: furi_string_cat_printf(temp_str, "Type: SLIX2\n"); furi_string_cat_printf(temp_str, "Keys:\n"); furi_string_cat_printf( temp_str, - " Read %08lX\n", - nfc_scene_nfc_data_info_get_key(nfcv_data->sub_data.slix.key_read)); + " Read %08llX\n", + nfc_util_bytes2num(nfcv_data->sub_data.slix.key_read, 4)); furi_string_cat_printf( temp_str, - " Write %08lX\n", - nfc_scene_nfc_data_info_get_key(nfcv_data->sub_data.slix.key_write)); + " Write %08llX\n", + nfc_util_bytes2num(nfcv_data->sub_data.slix.key_write, 4)); furi_string_cat_printf( temp_str, - " Privacy %08lX\n", - nfc_scene_nfc_data_info_get_key(nfcv_data->sub_data.slix.key_privacy)); + " Privacy %08llX\n", + nfc_util_bytes2num(nfcv_data->sub_data.slix.key_privacy, 4)); furi_string_cat_printf( temp_str, - " Destroy %08lX\n", - nfc_scene_nfc_data_info_get_key(nfcv_data->sub_data.slix.key_destroy)); + " Destroy %08llX\n", + nfc_util_bytes2num(nfcv_data->sub_data.slix.key_destroy, 4)); furi_string_cat_printf( temp_str, - " EAS %08lX\n", - nfc_scene_nfc_data_info_get_key(nfcv_data->sub_data.slix.key_eas)); + " EAS %08llX\n", + nfc_util_bytes2num(nfcv_data->sub_data.slix.key_eas, 4)); break; default: furi_string_cat_printf(temp_str, "\e#ISO15693 (unknown)\n"); diff --git a/applications/main/nfc/scenes/nfc_scene_nfcv_emulate.c b/applications/main/nfc/scenes/nfc_scene_nfcv_emulate.c index ca10f5d6e..3f2a860e0 100644 --- a/applications/main/nfc/scenes/nfc_scene_nfcv_emulate.c +++ b/applications/main/nfc/scenes/nfc_scene_nfcv_emulate.c @@ -8,7 +8,6 @@ enum { }; bool nfc_scene_nfcv_emulate_worker_callback(NfcWorkerEvent event, void* context) { - UNUSED(event); furi_assert(context); Nfc* nfc = context; diff --git a/lib/nfc/nfc_worker.c b/lib/nfc/nfc_worker.c index 745e89b9c..f2d07e4c2 100644 --- a/lib/nfc/nfc_worker.c +++ b/lib/nfc/nfc_worker.c @@ -248,13 +248,13 @@ void nfc_worker_nfcv_unlock(NfcWorker* nfc_worker) { furi_hal_nfc_ll_set_error_handling(FuriHalNfcErrorHandlingNfc); furi_hal_nfc_ll_set_guard_time(FURI_HAL_NFC_LL_GT_NFCV); - furi_hal_console_printf("Detect presence\r\n"); + FURI_LOG_D(TAG, "Detect presence"); ReturnCode ret = slix_get_random(nfcv_data); if(ret == ERR_NONE) { /* there is some chip, responding with a RAND */ nfc_worker->dev_data->protocol = NfcDeviceProtocolNfcV; - furi_hal_console_printf(" Chip detected. In privacy?\r\n"); + FURI_LOG_D(TAG, " Chip detected. In privacy?"); ret = nfcv_inventory(NULL); if(ret == ERR_NONE) { @@ -263,15 +263,15 @@ void nfc_worker_nfcv_unlock(NfcWorker* nfc_worker) { NfcVReader reader = {}; if(!nfcv_read_card(&reader, &nfc_worker->dev_data->nfc_data, nfcv_data)) { - furi_hal_console_printf(" => failed, wait for chip to disappear.\r\n"); + FURI_LOG_D(TAG, " => failed, wait for chip to disappear."); snprintf(nfcv_data->error, sizeof(nfcv_data->error), "Read card\nfailed"); nfc_worker->callback(NfcWorkerEventWrongCardDetected, nfc_worker->context); } else { - furi_hal_console_printf(" => success, wait for chip to disappear.\r\n"); + FURI_LOG_D(TAG, " => success, wait for chip to disappear."); nfc_worker->callback(NfcWorkerEventCardDetected, nfc_worker->context); } } else { - furi_hal_console_printf(" => success, wait for chip to disappear.\r\n"); + FURI_LOG_D(TAG, " => success, wait for chip to disappear."); nfc_worker->callback(NfcWorkerEventCardDetected, nfc_worker->context); } @@ -279,8 +279,7 @@ void nfc_worker_nfcv_unlock(NfcWorker* nfc_worker) { furi_delay_ms(100); } - furi_hal_console_printf( - " => chip is already visible, wait for chip to disappear.\r\n"); + FURI_LOG_D(TAG, " => chip is already visible, wait for chip to disappear.\r\n"); nfc_worker->callback(NfcWorkerEventAborted, nfc_worker->context); while(slix_get_random(NULL) == ERR_NONE) { furi_delay_ms(100); @@ -293,7 +292,7 @@ void nfc_worker_nfcv_unlock(NfcWorker* nfc_worker) { } else { /* chip is invisible, try to unlock */ - furi_hal_console_printf(" chip is invisible, unlocking\r\n"); + FURI_LOG_D(TAG, " chip is invisible, unlocking"); if(nfcv_data->auth_method == NfcVAuthMethodManual) { key |= key_data[0] << 24; @@ -312,7 +311,7 @@ void nfc_worker_nfcv_unlock(NfcWorker* nfc_worker) { if(ret != ERR_NONE) { /* main key failed, trying second one */ - furi_hal_console_printf(" trying second key after resetting\r\n"); + FURI_LOG_D(TAG, " trying second key after resetting"); /* reset chip */ furi_hal_nfc_ll_txrx_off(); @@ -320,7 +319,7 @@ void nfc_worker_nfcv_unlock(NfcWorker* nfc_worker) { furi_hal_nfc_ll_txrx_on(); if(slix_get_random(nfcv_data) != ERR_NONE) { - furi_hal_console_printf(" reset failed\r\n"); + FURI_LOG_D(TAG, " reset failed"); } key = 0x0F0F0F0F; @@ -333,7 +332,7 @@ void nfc_worker_nfcv_unlock(NfcWorker* nfc_worker) { } if(ret != ERR_NONE) { /* unlock failed */ - furi_hal_console_printf(" => failed, wait for chip to disappear.\r\n"); + FURI_LOG_D(TAG, " => failed, wait for chip to disappear."); snprintf( nfcv_data->error, sizeof(nfcv_data->error), "Passwords not\naccepted"); nfc_worker->callback(NfcWorkerEventWrongCardDetected, nfc_worker->context); diff --git a/lib/nfc/protocols/nfcv.h b/lib/nfc/protocols/nfcv.h index 8ca6955d1..87a696737 100644 --- a/lib/nfc/protocols/nfcv.h +++ b/lib/nfc/protocols/nfcv.h @@ -15,7 +15,7 @@ extern "C" { /* true: modulating releases load, false: modulating adds load resistor to field coil */ #define NFCV_LOAD_MODULATION_POLARITY (false) -#define NFCV_FC (13560000.0f / 0.9998f) /* MHz */ +#define NFCV_FC (13560000.0f) /* MHz */ #define NFCV_RESP_SUBC1_PULSE_32 (1.0f / (NFCV_FC / 32) / 2.0f) /* 1.1799 µs */ #define NFCV_RESP_SUBC1_UNMOD_256 (256.0f / NFCV_FC) /* 18.8791 µs */ #define NFCV_PULSE_DURATION_NS (128.0f * 1000000000.0f / NFCV_FC) From f5692ea1f0341828e3180dd6c5b5c571ae236fc7 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Wed, 31 May 2023 17:16:24 +0300 Subject: [PATCH 42/52] fix message --- applications/main/subghz/scenes/subghz_scene_rpc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/applications/main/subghz/scenes/subghz_scene_rpc.c b/applications/main/subghz/scenes/subghz_scene_rpc.c index e13a61944..724abaf3e 100644 --- a/applications/main/subghz/scenes/subghz_scene_rpc.c +++ b/applications/main/subghz/scenes/subghz_scene_rpc.c @@ -48,7 +48,7 @@ bool subghz_scene_rpc_on_event(void* context, SceneManagerEvent event) { rpc_system_app_set_error_code(subghz->rpc_ctx, SubGhzErrorTypeOnlyRX); rpc_system_app_set_error_text( subghz->rpc_ctx, - "Transmission on this frequency is restricted in your region"); + "Transmission on this frequency is restricted in your settings"); break; case SubGhzTxRxStartTxStateErrorParserOthers: rpc_system_app_set_error_code(subghz->rpc_ctx, SubGhzErrorTypeParserOthers); From 3a7203e32e2058e5234ae82b2fa33d2f06fc055c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zo=C3=AB=20Prosvetova?= <109866245+ZoeMeetAgain@users.noreply.github.com> Date: Thu, 1 Jun 2023 11:59:41 +0200 Subject: [PATCH 43/52] Update dolphin.py (#2717) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: あく --- scripts/flipper/assets/dolphin.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/flipper/assets/dolphin.py b/scripts/flipper/assets/dolphin.py index ebe9fd889..b4a53a62d 100644 --- a/scripts/flipper/assets/dolphin.py +++ b/scripts/flipper/assets/dolphin.py @@ -49,11 +49,11 @@ class DolphinBubbleAnimation: def load(self, animation_directory: str): if not os.path.isdir(animation_directory): - raise Exception(f"Animation folder doesn't exists: { animation_directory }") + raise Exception(f"Animation folder doesn't exist: { animation_directory }") meta_filename = os.path.join(animation_directory, "meta.txt") if not os.path.isfile(meta_filename): - raise Exception(f"Animation meta file doesn't exists: { meta_filename }") + raise Exception(f"Animation meta file doesn't exist: { meta_filename }") self.logger.info(f"Loading meta from {meta_filename}") file = FlipperFormatFile() From 1d7966f74ef1b7ba04b536619b3b7d48804d3bd8 Mon Sep 17 00:00:00 2001 From: gornekich Date: Thu, 1 Jun 2023 16:37:47 +0400 Subject: [PATCH 44/52] NFC: fix MFC timings (#2719) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * digital signal: add optimization * nfc test: more restrict tests * digital signal: build as separate library * digital signal: remove unused flags, format sources * digital signal: fix cflag name * target: fix build for f18 target Co-authored-by: あく --- applications/debug/unit_tests/nfc/nfc_test.c | 61 +++++++++++++++++--- firmware/targets/f18/api_symbols.csv | 21 ++++++- firmware/targets/f7/api_symbols.csv | 3 +- firmware/targets/f7/target.json | 1 + lib/ReadMe.md | 1 + lib/SConscript | 2 +- lib/digital_signal/SConscript | 20 +++++++ lib/digital_signal/digital_signal.c | 3 +- lib/misc.scons | 2 - 9 files changed, 98 insertions(+), 16 deletions(-) create mode 100644 lib/digital_signal/SConscript diff --git a/applications/debug/unit_tests/nfc/nfc_test.c b/applications/debug/unit_tests/nfc/nfc_test.c index 54bdd5909..bc2f7887b 100644 --- a/applications/debug/unit_tests/nfc/nfc_test.c +++ b/applications/debug/unit_tests/nfc/nfc_test.c @@ -27,6 +27,12 @@ static const uint32_t nfc_test_file_version = 1; #define NFC_TEST_DATA_MAX_LEN 18 #define NFC_TETS_TIMINGS_MAX_LEN 1350 +// Maximum allowed time for buffer preparation to fit 500us nt message timeout +#define NFC_TEST_4_BYTE_BUILD_BUFFER_TIM_MAX (150) +#define NFC_TEST_16_BYTE_BUILD_BUFFER_TIM_MAX (640) +#define NFC_TEST_4_BYTE_BUILD_SIGNAL_TIM_MAX (110) +#define NFC_TEST_16_BYTE_BUILD_SIGNAL_TIM_MAX (440) + typedef struct { Storage* storage; NfcaSignal* signal; @@ -89,13 +95,13 @@ static bool nfc_test_read_signal_from_file(const char* file_name) { static bool nfc_test_digital_signal_test_encode( const char* file_name, - uint32_t encode_max_time, + uint32_t build_signal_max_time_us, + uint32_t build_buffer_max_time_us, uint32_t timing_tolerance, uint32_t timings_sum_tolerance) { furi_assert(nfc_test); bool success = false; - uint32_t time = 0; uint32_t dut_timings_sum = 0; uint32_t ref_timings_sum = 0; uint8_t parity[10] = {}; @@ -109,17 +115,37 @@ static bool nfc_test_digital_signal_test_encode( // Encode signal FURI_CRITICAL_ENTER(); - time = DWT->CYCCNT; + uint32_t time_start = DWT->CYCCNT; + nfca_signal_encode( nfc_test->signal, nfc_test->test_data, nfc_test->test_data_len * 8, parity); + + uint32_t time_signal = + (DWT->CYCCNT - time_start) / furi_hal_cortex_instructions_per_microsecond(); + + time_start = DWT->CYCCNT; + digital_signal_prepare_arr(nfc_test->signal->tx_signal); - time = (DWT->CYCCNT - time) / furi_hal_cortex_instructions_per_microsecond(); + + uint32_t time_buffer = + (DWT->CYCCNT - time_start) / furi_hal_cortex_instructions_per_microsecond(); FURI_CRITICAL_EXIT(); // Check timings - if(time > encode_max_time) { + if(time_signal > build_signal_max_time_us) { FURI_LOG_E( - TAG, "Encoding time: %ld us while accepted value: %ld us", time, encode_max_time); + TAG, + "Build signal time: %ld us while accepted value: %ld us", + time_signal, + build_signal_max_time_us); + break; + } + if(time_buffer > build_buffer_max_time_us) { + FURI_LOG_E( + TAG, + "Build buffer time: %ld us while accepted value: %ld us", + time_buffer, + build_buffer_max_time_us); break; } @@ -156,7 +182,16 @@ static bool nfc_test_digital_signal_test_encode( break; } - FURI_LOG_I(TAG, "Encoding time: %ld us. Acceptable time: %ld us", time, encode_max_time); + FURI_LOG_I( + TAG, + "Build signal time: %ld us. Acceptable time: %ld us", + time_signal, + build_signal_max_time_us); + FURI_LOG_I( + TAG, + "Build buffer time: %ld us. Acceptable time: %ld us", + time_buffer, + build_buffer_max_time_us); FURI_LOG_I( TAG, "Timings sum difference: %ld [1/64MHZ]. Acceptable difference: %ld [1/64MHz]", @@ -171,11 +206,19 @@ static bool nfc_test_digital_signal_test_encode( MU_TEST(nfc_digital_signal_test) { mu_assert( nfc_test_digital_signal_test_encode( - NFC_TEST_RESOURCES_DIR NFC_TEST_SIGNAL_SHORT_FILE, 500, 1, 37), + NFC_TEST_RESOURCES_DIR NFC_TEST_SIGNAL_SHORT_FILE, + NFC_TEST_4_BYTE_BUILD_SIGNAL_TIM_MAX, + NFC_TEST_4_BYTE_BUILD_BUFFER_TIM_MAX, + 1, + 37), "NFC short digital signal test failed\r\n"); mu_assert( nfc_test_digital_signal_test_encode( - NFC_TEST_RESOURCES_DIR NFC_TEST_SIGNAL_LONG_FILE, 2000, 1, 37), + NFC_TEST_RESOURCES_DIR NFC_TEST_SIGNAL_LONG_FILE, + NFC_TEST_16_BYTE_BUILD_SIGNAL_TIM_MAX, + NFC_TEST_16_BYTE_BUILD_BUFFER_TIM_MAX, + 1, + 37), "NFC long digital signal test failed\r\n"); } diff --git a/firmware/targets/f18/api_symbols.csv b/firmware/targets/f18/api_symbols.csv index 7f0dcebd5..3c075e0d1 100644 --- a/firmware/targets/f18/api_symbols.csv +++ b/firmware/targets/f18/api_symbols.csv @@ -1,5 +1,5 @@ entry,status,name,type,params -Version,+,28.1,, +Version,+,28.2,, Header,+,applications/services/bt/bt_service/bt.h,, Header,+,applications/services/cli/cli.h,, Header,+,applications/services/cli/cli_vcp.h,, @@ -80,6 +80,7 @@ Header,+,firmware/targets/furi_hal_include/furi_hal_usb_hid.h,, Header,+,firmware/targets/furi_hal_include/furi_hal_usb_hid_u2f.h,, Header,+,firmware/targets/furi_hal_include/furi_hal_version.h,, Header,+,firmware/targets/furi_hal_include/furi_hal_vibro.h,, +Header,+,lib/digital_signal/digital_signal.h,, Header,+,lib/flipper_application/api_hashtable/api_hashtable.h,, Header,+,lib/flipper_application/api_hashtable/compilesort.hpp,, Header,+,lib/flipper_application/flipper_application.h,, @@ -617,6 +618,24 @@ Function,+,dialog_message_set_text,void,"DialogMessage*, const char*, uint8_t, u Function,+,dialog_message_show,DialogMessageButton,"DialogsApp*, const DialogMessage*" Function,+,dialog_message_show_storage_error,void,"DialogsApp*, const char*" Function,-,difftime,double,"time_t, time_t" +Function,-,digital_sequence_add,void,"DigitalSequence*, uint8_t" +Function,-,digital_sequence_alloc,DigitalSequence*,"uint32_t, const GpioPin*" +Function,-,digital_sequence_clear,void,DigitalSequence* +Function,-,digital_sequence_free,void,DigitalSequence* +Function,-,digital_sequence_send,_Bool,DigitalSequence* +Function,-,digital_sequence_set_sendtime,void,"DigitalSequence*, uint32_t" +Function,-,digital_sequence_set_signal,void,"DigitalSequence*, uint8_t, DigitalSignal*" +Function,-,digital_sequence_timebase_correction,void,"DigitalSequence*, float" +Function,-,digital_signal_add,void,"DigitalSignal*, uint32_t" +Function,-,digital_signal_add_pulse,void,"DigitalSignal*, uint32_t, _Bool" +Function,-,digital_signal_alloc,DigitalSignal*,uint32_t +Function,-,digital_signal_append,_Bool,"DigitalSignal*, DigitalSignal*" +Function,-,digital_signal_free,void,DigitalSignal* +Function,-,digital_signal_get_edge,uint32_t,"DigitalSignal*, uint32_t" +Function,-,digital_signal_get_edges_cnt,uint32_t,DigitalSignal* +Function,-,digital_signal_get_start_level,_Bool,DigitalSignal* +Function,-,digital_signal_prepare_arr,void,DigitalSignal* +Function,-,digital_signal_send,void,"DigitalSignal*, const GpioPin*" Function,-,diprintf,int,"int, const char*, ..." Function,+,dir_walk_alloc,DirWalk*,Storage* Function,+,dir_walk_close,void,DirWalk* diff --git a/firmware/targets/f7/api_symbols.csv b/firmware/targets/f7/api_symbols.csv index 1259f0fce..a9ce0c26a 100644 --- a/firmware/targets/f7/api_symbols.csv +++ b/firmware/targets/f7/api_symbols.csv @@ -1,5 +1,5 @@ entry,status,name,type,params -Version,+,28.1,, +Version,+,28.2,, Header,+,applications/services/bt/bt_service/bt.h,, Header,+,applications/services/cli/cli.h,, Header,+,applications/services/cli/cli_vcp.h,, @@ -86,6 +86,7 @@ Header,+,firmware/targets/furi_hal_include/furi_hal_usb_hid.h,, Header,+,firmware/targets/furi_hal_include/furi_hal_usb_hid_u2f.h,, Header,+,firmware/targets/furi_hal_include/furi_hal_version.h,, Header,+,firmware/targets/furi_hal_include/furi_hal_vibro.h,, +Header,+,lib/digital_signal/digital_signal.h,, Header,+,lib/flipper_application/api_hashtable/api_hashtable.h,, Header,+,lib/flipper_application/api_hashtable/compilesort.hpp,, Header,+,lib/flipper_application/flipper_application.h,, diff --git a/firmware/targets/f7/target.json b/firmware/targets/f7/target.json index c50364453..e3dc78325 100644 --- a/firmware/targets/f7/target.json +++ b/firmware/targets/f7/target.json @@ -28,6 +28,7 @@ "flipperformat", "toolbox", "nfc", + "digital_signal", "pulse_reader", "microtar", "usb_stm32", diff --git a/lib/ReadMe.md b/lib/ReadMe.md index 93236b267..138bef2b3 100644 --- a/lib/ReadMe.md +++ b/lib/ReadMe.md @@ -27,6 +27,7 @@ - `nfc` - NFC library, used by NFC application - `one_wire` - OneWire library, used by iButton application - `print` - Tiny printf implementation +- `digital_signal` - Digital Signal library used by NFC for software implemented protocols - `pulse_reader` - Pulse Reader library used by NFC for software implemented protocols - `qrcode` - QR-Code library - `stm32wb_cmsis` - STM32WB series CMSIS headers, extends CMSIS Core diff --git a/lib/SConscript b/lib/SConscript index 8727746d8..495ba4bfe 100644 --- a/lib/SConscript +++ b/lib/SConscript @@ -15,7 +15,6 @@ env.Append( Dir("u8g2"), Dir("update_util"), Dir("print"), - Dir("pulse_reader"), ], ) @@ -95,6 +94,7 @@ libs = env.BuildModules( "mbedtls", "subghz", "nfc", + "digital_signal", "pulse_reader", "appframe", "misc", diff --git a/lib/digital_signal/SConscript b/lib/digital_signal/SConscript new file mode 100644 index 000000000..2ddf7a58b --- /dev/null +++ b/lib/digital_signal/SConscript @@ -0,0 +1,20 @@ +Import("env") + +env.Append( + CPPPATH=[ + "#/lib/digital_signal", + ], + SDK_HEADERS=[ + File("digital_signal.h"), + ], +) + +libenv = env.Clone(FW_LIB_NAME="digital_signal") +libenv.ApplyLibFlags() +libenv.Append(CCFLAGS=["-O3", "-funroll-loops", "-Ofast"]) + +sources = libenv.GlobRecursive("*.c*") + +lib = libenv.StaticLibrary("${FW_LIB_NAME}", sources) +libenv.Install("${LIB_DIST_DIR}", lib) +Return("lib") diff --git a/lib/digital_signal/digital_signal.c b/lib/digital_signal/digital_signal.c index ab25458b5..94dbeeab9 100644 --- a/lib/digital_signal/digital_signal.c +++ b/lib/digital_signal/digital_signal.c @@ -212,8 +212,7 @@ void digital_signal_prepare_arr(DigitalSignal* signal) { internals->reload_reg_entries = 0; for(size_t pos = 0; pos < signal->edge_cnt; pos++) { - uint32_t edge_scaled = (internals->factor * signal->edge_timings[pos]) / (1024 * 1024); - uint32_t pulse_duration = edge_scaled + internals->reload_reg_remainder; + uint32_t pulse_duration = signal->edge_timings[pos] + internals->reload_reg_remainder; if(pulse_duration < 10 || pulse_duration > 10000000) { FURI_LOG_D( TAG, diff --git a/lib/misc.scons b/lib/misc.scons index 1ff6e2fb0..10aa3f9d5 100644 --- a/lib/misc.scons +++ b/lib/misc.scons @@ -4,7 +4,6 @@ Import("env") env.Append( CPPPATH=[ - "#/lib/digital_signal", "#/lib/fnv1a_hash", "#/lib/heatshrink", "#/lib/micro-ecc", @@ -26,7 +25,6 @@ libenv.ApplyLibFlags() sources = [] libs_recurse = [ - "digital_signal", "micro-ecc", "u8g2", "update_util", From ca49da3c83940759d2f349c9e1cc2599108c7b97 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Fri, 2 Jun 2023 13:42:44 +0300 Subject: [PATCH 45/52] Fix APP_IDs to match new regex regex check will be added in OFW soon --- applications/debug/uart_echo/application.fam | 2 +- applications/debug/usb_mouse/application.fam | 2 +- applications/external/arkanoid/application.fam | 2 +- .../external/barcode_generator/application.fam | 2 +- applications/external/blackjack/application.fam | 2 +- applications/external/doom/application.fam | 2 +- applications/external/esp8266_deauth/application.fam | 2 +- applications/external/flappy_bird/application.fam | 2 +- applications/external/flipfrid/application.fam | 2 +- applications/external/flipper_i2ctools/application.fam | 2 +- applications/external/ibtn_fuzzer/application.fam | 2 +- applications/external/metronome/application.fam | 2 +- applications/external/minesweeper/application.fam | 2 +- applications/external/mousejacker/application.fam | 2 +- applications/external/multi_converter/application.fam | 2 +- applications/external/music_player/application.fam | 2 +- applications/external/nrfsniff/application.fam | 2 +- applications/external/picopass/application.fam | 2 +- applications/external/playlist/application.fam | 2 +- applications/external/sentry_safe/application.fam | 2 +- applications/external/signal_generator/application.fam | 2 +- applications/external/snake_game/application.fam | 2 +- applications/external/solitaire/application.fam | 2 +- .../external/spectrum_analyzer/application.fam | 2 +- applications/external/subbrute | 2 +- applications/external/tetris_game/application.fam | 2 +- applications/external/tictactoe_game/application.fam | 2 +- applications/external/wav_player/application.fam | 2 +- .../external/wifi_marauder_companion/application.fam | 2 +- applications/external/wifi_scanner/application.fam | 2 +- applications/external/zombiez/application.fam | 2 +- .../services/desktop/scenes/desktop_scene_main.c | 10 +++++----- 32 files changed, 36 insertions(+), 36 deletions(-) diff --git a/applications/debug/uart_echo/application.fam b/applications/debug/uart_echo/application.fam index fce9ac809..b7cff991d 100644 --- a/applications/debug/uart_echo/application.fam +++ b/applications/debug/uart_echo/application.fam @@ -1,5 +1,5 @@ App( - appid="UART_Echo", + appid="uart_echo", name="UART Echo", apptype=FlipperAppType.DEBUG, entry_point="uart_echo_app", diff --git a/applications/debug/usb_mouse/application.fam b/applications/debug/usb_mouse/application.fam index 38ba55425..ab91e7aa2 100644 --- a/applications/debug/usb_mouse/application.fam +++ b/applications/debug/usb_mouse/application.fam @@ -1,5 +1,5 @@ App( - appid="USB_Mouse", + appid="usb_mouse", name="USB Mouse", apptype=FlipperAppType.DEBUG, entry_point="usb_mouse_app", diff --git a/applications/external/arkanoid/application.fam b/applications/external/arkanoid/application.fam index 5cfec8862..9092c32c6 100644 --- a/applications/external/arkanoid/application.fam +++ b/applications/external/arkanoid/application.fam @@ -1,5 +1,5 @@ App( - appid="Arkanoid", + appid="arkanoid", name="Arkanoid", apptype=FlipperAppType.EXTERNAL, entry_point="arkanoid_game_app", diff --git a/applications/external/barcode_generator/application.fam b/applications/external/barcode_generator/application.fam index c92498005..4f9f234cc 100644 --- a/applications/external/barcode_generator/application.fam +++ b/applications/external/barcode_generator/application.fam @@ -1,5 +1,5 @@ App( - appid="Barcode_Generator", + appid="barcode_generator", name="Barcode Generator", apptype=FlipperAppType.EXTERNAL, entry_point="barcode_generator_app", diff --git a/applications/external/blackjack/application.fam b/applications/external/blackjack/application.fam index f0645f003..139d94f2e 100644 --- a/applications/external/blackjack/application.fam +++ b/applications/external/blackjack/application.fam @@ -1,5 +1,5 @@ App( - appid="Blackjack", + appid="blackjack", name="Blackjack", apptype=FlipperAppType.EXTERNAL, entry_point="blackjack_app", diff --git a/applications/external/doom/application.fam b/applications/external/doom/application.fam index 4ff7b12f3..94fa9ab67 100644 --- a/applications/external/doom/application.fam +++ b/applications/external/doom/application.fam @@ -1,5 +1,5 @@ App( - appid="DOOM", + appid="doom", name="DOOM", apptype=FlipperAppType.EXTERNAL, entry_point="doom_app", diff --git a/applications/external/esp8266_deauth/application.fam b/applications/external/esp8266_deauth/application.fam index 780c51c53..5db7bb40e 100644 --- a/applications/external/esp8266_deauth/application.fam +++ b/applications/external/esp8266_deauth/application.fam @@ -1,5 +1,5 @@ App( - appid="ESP8266_Deauther", + appid="esp8266_deauther", name="[ESP8266] Deauther", apptype=FlipperAppType.EXTERNAL, entry_point="esp8266_deauth_app", diff --git a/applications/external/flappy_bird/application.fam b/applications/external/flappy_bird/application.fam index f9fe85fa2..9bfab454f 100644 --- a/applications/external/flappy_bird/application.fam +++ b/applications/external/flappy_bird/application.fam @@ -1,5 +1,5 @@ App( - appid="FlappyBird", + appid="flappy_bird", name="Flappy Bird", apptype=FlipperAppType.EXTERNAL, entry_point="flappy_game_app", diff --git a/applications/external/flipfrid/application.fam b/applications/external/flipfrid/application.fam index 343d4f62d..1ddd6ba50 100644 --- a/applications/external/flipfrid/application.fam +++ b/applications/external/flipfrid/application.fam @@ -1,5 +1,5 @@ App( - appid="RFID_Fuzzer", + appid="rfid_fuzzer", name="RFID Fuzzer", apptype=FlipperAppType.EXTERNAL, entry_point="flipfrid_start", diff --git a/applications/external/flipper_i2ctools/application.fam b/applications/external/flipper_i2ctools/application.fam index 5a00aa045..a6bab122a 100644 --- a/applications/external/flipper_i2ctools/application.fam +++ b/applications/external/flipper_i2ctools/application.fam @@ -1,5 +1,5 @@ App( - appid="i2cTools", + appid="i2c_tools", name="[GPIO] i2c Tools", apptype=FlipperAppType.EXTERNAL, entry_point="i2ctools_app", diff --git a/applications/external/ibtn_fuzzer/application.fam b/applications/external/ibtn_fuzzer/application.fam index 00c244c41..87c02a913 100644 --- a/applications/external/ibtn_fuzzer/application.fam +++ b/applications/external/ibtn_fuzzer/application.fam @@ -1,5 +1,5 @@ App( - appid="iBtn_Fuzzer", + appid="ibtn_fuzzer", name="iButton Fuzzer", apptype=FlipperAppType.EXTERNAL, entry_point="ibtnfuzzer_start", diff --git a/applications/external/metronome/application.fam b/applications/external/metronome/application.fam index 67411c5f2..8acd4b3b0 100644 --- a/applications/external/metronome/application.fam +++ b/applications/external/metronome/application.fam @@ -1,5 +1,5 @@ App( - appid="Metronome", + appid="metronome", name="Metronome", apptype=FlipperAppType.EXTERNAL, entry_point="metronome_app", diff --git a/applications/external/minesweeper/application.fam b/applications/external/minesweeper/application.fam index c0211282c..0a4066279 100644 --- a/applications/external/minesweeper/application.fam +++ b/applications/external/minesweeper/application.fam @@ -1,5 +1,5 @@ App( - appid="Minesweeper", + appid="minesweeper", name="Minesweeper", apptype=FlipperAppType.EXTERNAL, entry_point="minesweeper_app", diff --git a/applications/external/mousejacker/application.fam b/applications/external/mousejacker/application.fam index f65b06cc2..3b8ae7104 100644 --- a/applications/external/mousejacker/application.fam +++ b/applications/external/mousejacker/application.fam @@ -1,5 +1,5 @@ App( - appid="NRF24_Mouse_Jacker", + appid="nrf24_mouse_jacker", name="[NRF24] Mouse Jacker", apptype=FlipperAppType.EXTERNAL, entry_point="mousejacker_app", diff --git a/applications/external/multi_converter/application.fam b/applications/external/multi_converter/application.fam index 9f49f18ad..8d5e7bb44 100644 --- a/applications/external/multi_converter/application.fam +++ b/applications/external/multi_converter/application.fam @@ -1,5 +1,5 @@ App( - appid="Multi_Converter", + appid="multi_converter", name="Multi Converter", apptype=FlipperAppType.EXTERNAL, entry_point="multi_converter_app", diff --git a/applications/external/music_player/application.fam b/applications/external/music_player/application.fam index e0254250e..3414c0a48 100644 --- a/applications/external/music_player/application.fam +++ b/applications/external/music_player/application.fam @@ -1,5 +1,5 @@ App( - appid="Music_Player", + appid="music_player", name="Music Player", apptype=FlipperAppType.EXTERNAL, entry_point="music_player_app", diff --git a/applications/external/nrfsniff/application.fam b/applications/external/nrfsniff/application.fam index c99b9bf22..1ec1718c1 100644 --- a/applications/external/nrfsniff/application.fam +++ b/applications/external/nrfsniff/application.fam @@ -1,5 +1,5 @@ App( - appid="NRF24_Sniffer", + appid="nrf24_sniffer", name="[NRF24] Sniffer", apptype=FlipperAppType.EXTERNAL, entry_point="nrfsniff_app", diff --git a/applications/external/picopass/application.fam b/applications/external/picopass/application.fam index 34c3f785c..94d328a09 100644 --- a/applications/external/picopass/application.fam +++ b/applications/external/picopass/application.fam @@ -1,5 +1,5 @@ App( - appid="Picopass", + appid="picopass", name="[iClass] PicoPass", apptype=FlipperAppType.EXTERNAL, targets=["f7"], diff --git a/applications/external/playlist/application.fam b/applications/external/playlist/application.fam index e137cdb39..6f74f2b55 100644 --- a/applications/external/playlist/application.fam +++ b/applications/external/playlist/application.fam @@ -1,5 +1,5 @@ App( - appid="SubGHz_Playlist", + appid="subghz_playlist", name="Sub-GHz Playlist", apptype=FlipperAppType.EXTERNAL, entry_point="playlist_app", diff --git a/applications/external/sentry_safe/application.fam b/applications/external/sentry_safe/application.fam index 8958dc8bc..b9254c58d 100644 --- a/applications/external/sentry_safe/application.fam +++ b/applications/external/sentry_safe/application.fam @@ -1,5 +1,5 @@ App( - appid="GPIO_Sentry_Safe", + appid="gpio_sentry_safe", name="[GPIO] Sentry Safe", apptype=FlipperAppType.EXTERNAL, entry_point="sentry_safe_app", diff --git a/applications/external/signal_generator/application.fam b/applications/external/signal_generator/application.fam index bcf7d20b6..094e784cc 100644 --- a/applications/external/signal_generator/application.fam +++ b/applications/external/signal_generator/application.fam @@ -1,5 +1,5 @@ App( - appid="Signal_Generator", + appid="signal_generator", name="Signal Generator", apptype=FlipperAppType.EXTERNAL, entry_point="signal_gen_app", diff --git a/applications/external/snake_game/application.fam b/applications/external/snake_game/application.fam index 4c15c309b..b05426e9d 100644 --- a/applications/external/snake_game/application.fam +++ b/applications/external/snake_game/application.fam @@ -1,5 +1,5 @@ App( - appid="Snake", + appid="snake", name="Snake Game", apptype=FlipperAppType.EXTERNAL, entry_point="snake_game_app", diff --git a/applications/external/solitaire/application.fam b/applications/external/solitaire/application.fam index 44152a038..7b5910c49 100644 --- a/applications/external/solitaire/application.fam +++ b/applications/external/solitaire/application.fam @@ -1,5 +1,5 @@ App( - appid="Solitaire", + appid="solitaire", name="Solitaire", apptype=FlipperAppType.EXTERNAL, entry_point="solitaire_app", diff --git a/applications/external/spectrum_analyzer/application.fam b/applications/external/spectrum_analyzer/application.fam index 286aa64ba..79effb3a7 100644 --- a/applications/external/spectrum_analyzer/application.fam +++ b/applications/external/spectrum_analyzer/application.fam @@ -1,5 +1,5 @@ App( - appid="Spectrum_Analyzer", + appid="spectrum_analyzer", name="Spectrum Analyzer", apptype=FlipperAppType.EXTERNAL, entry_point="spectrum_analyzer_app", diff --git a/applications/external/subbrute b/applications/external/subbrute index d1317392a..16f94c118 160000 --- a/applications/external/subbrute +++ b/applications/external/subbrute @@ -1 +1 @@ -Subproject commit d1317392a4a7dadd34157e66c73fee6990fd2100 +Subproject commit 16f94c1186e6b7dc1758e6ae9c1fbe9a55f69da6 diff --git a/applications/external/tetris_game/application.fam b/applications/external/tetris_game/application.fam index 998345c0e..a6c433b9e 100644 --- a/applications/external/tetris_game/application.fam +++ b/applications/external/tetris_game/application.fam @@ -1,5 +1,5 @@ App( - appid="Tetris", + appid="tetris", name="Tetris", apptype=FlipperAppType.EXTERNAL, entry_point="tetris_game_app", diff --git a/applications/external/tictactoe_game/application.fam b/applications/external/tictactoe_game/application.fam index 8b67be874..4d50bc1a2 100644 --- a/applications/external/tictactoe_game/application.fam +++ b/applications/external/tictactoe_game/application.fam @@ -1,5 +1,5 @@ App( - appid="TicTacToe", + appid="tictactoe", name="Tic Tac Toe", apptype=FlipperAppType.EXTERNAL, entry_point="tictactoe_game_app", diff --git a/applications/external/wav_player/application.fam b/applications/external/wav_player/application.fam index f76c1cd39..c71527c9d 100644 --- a/applications/external/wav_player/application.fam +++ b/applications/external/wav_player/application.fam @@ -1,5 +1,5 @@ App( - appid="WAV_Player", + appid="wav_player", name="WAV Player", apptype=FlipperAppType.EXTERNAL, entry_point="wav_player_app", diff --git a/applications/external/wifi_marauder_companion/application.fam b/applications/external/wifi_marauder_companion/application.fam index d7bde185e..59e53b725 100644 --- a/applications/external/wifi_marauder_companion/application.fam +++ b/applications/external/wifi_marauder_companion/application.fam @@ -1,5 +1,5 @@ App( - appid="ESP32_WiFi_Marauder", + appid="esp32_wifi_marauder", name="[ESP32] WiFi Marauder", apptype=FlipperAppType.EXTERNAL, entry_point="wifi_marauder_app", diff --git a/applications/external/wifi_scanner/application.fam b/applications/external/wifi_scanner/application.fam index c160e8aa9..144354b0f 100644 --- a/applications/external/wifi_scanner/application.fam +++ b/applications/external/wifi_scanner/application.fam @@ -1,5 +1,5 @@ App( - appid="WiFi_Scanner", + appid="wifi_scanner", name="[WiFi] Scanner", apptype=FlipperAppType.EXTERNAL, entry_point="wifi_scanner_app", diff --git a/applications/external/zombiez/application.fam b/applications/external/zombiez/application.fam index 069e591bc..69f5a9379 100644 --- a/applications/external/zombiez/application.fam +++ b/applications/external/zombiez/application.fam @@ -1,5 +1,5 @@ App( - appid="Zombiez", + appid="zombiez", name="Zombiez", apptype=FlipperAppType.EXTERNAL, entry_point="zombiez_game_app", diff --git a/applications/services/desktop/scenes/desktop_scene_main.c b/applications/services/desktop/scenes/desktop_scene_main.c index 3d1b16c57..ab3422b7f 100644 --- a/applications/services/desktop/scenes/desktop_scene_main.c +++ b/applications/services/desktop/scenes/desktop_scene_main.c @@ -200,23 +200,23 @@ bool desktop_scene_main_on_event(void* context, SceneManagerEvent event) { break; } case DesktopMainEventOpenGameMenu: { - desktop_scene_main_open_app_or_profile(desktop, EXT_PATH("/apps/Games/Snake.fap")); + desktop_scene_main_open_app_or_profile(desktop, EXT_PATH("/apps/Games/snake.fap")); break; } case DesktopMainEventOpenTetris: { - desktop_scene_main_open_app_or_profile(desktop, EXT_PATH("/apps/Games/Tetris.fap")); + desktop_scene_main_open_app_or_profile(desktop, EXT_PATH("/apps/Games/tetris.fap")); break; } case DesktopMainEventOpenArkanoid: { - desktop_scene_main_open_app_or_profile(desktop, EXT_PATH("/apps/Games/Arkanoid.fap")); + desktop_scene_main_open_app_or_profile(desktop, EXT_PATH("/apps/Games/arkanoid.fap")); break; } case DesktopMainEventOpenDOOM: { - desktop_scene_main_open_app_or_profile(desktop, EXT_PATH("/apps/Games/DOOM.fap")); + desktop_scene_main_open_app_or_profile(desktop, EXT_PATH("/apps/Games/doom.fap")); break; } case DesktopMainEventOpenZombiez: { - desktop_scene_main_open_app_or_profile(desktop, EXT_PATH("/apps/Games/Zombiez.fap")); + desktop_scene_main_open_app_or_profile(desktop, EXT_PATH("/apps/Games/zombiez.fap")); break; } case DesktopMainEventOpenHeap: { From b0c322ec9045cbb5e93622314353ea25af081c02 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Fri, 2 Jun 2023 15:03:01 +0300 Subject: [PATCH 46/52] Fix crash on second emulation NFC V --- lib/nfc/protocols/nfcv.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/lib/nfc/protocols/nfcv.c b/lib/nfc/protocols/nfcv.c index 6b0928ea7..f9848ae06 100644 --- a/lib/nfc/protocols/nfcv.c +++ b/lib/nfc/protocols/nfcv.c @@ -410,6 +410,9 @@ void nfcv_emu_free(NfcVData* nfcv_data) { digital_sequence_free(nfcv_data->emu_air.nfcv_signal); } if(nfcv_data->emu_air.reader_signal) { + // Stop pulse reader and disable bus before free + pulse_reader_stop(nfcv_data->emu_air.reader_signal); + // Free pulse reader pulse_reader_free(nfcv_data->emu_air.reader_signal); } @@ -1372,13 +1375,15 @@ bool nfcv_emu_loop( pulse_reader_start(nfcv_data->emu_air.reader_signal); ret = true; - } else { - if(frame_state != NFCV_FRAME_STATE_SOF1) { + + } #ifdef NFCV_VERBOSE + else { + if(frame_state != NFCV_FRAME_STATE_SOF1) { FURI_LOG_T(TAG, "leaving while in state: %lu", frame_state); -#endif } } +#endif #ifdef NFCV_DIAGNOSTIC_DUMPS if(period_buffer_pos) { From a5bf97fbb2e3e99c814d74daf631b7505c9f5b56 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Fri, 2 Jun 2023 15:14:32 +0300 Subject: [PATCH 47/52] Fix appid's pt2 --- applications/debug/application.fam | 4 ++-- applications/external/blackjack/blackjack.c | 2 +- applications/external/flappy_bird/flappy_bird.c | 2 +- applications/external/flipfrid/flipfrid.h | 2 +- applications/external/flipper_i2ctools/views/main_view.h | 2 +- applications/external/flipper_i2ctools/views/scanner_view.h | 2 +- applications/external/flipper_i2ctools/views/sender_view.h | 2 +- applications/external/flipper_i2ctools/views/sniffer_view.h | 2 +- applications/external/ibtn_fuzzer/ibtnfuzzer.h | 2 +- applications/external/metronome/gui_extensions.c | 2 +- applications/external/mousejacker/mousejacker.c | 2 +- applications/external/music_player/music_player.c | 2 +- applications/external/picopass/picopass_device.c | 2 +- applications/external/picopass/picopass_i.h | 2 +- applications/external/playlist/playlist.c | 2 +- applications/external/signal_generator/views/signal_gen_pwm.c | 2 +- applications/external/solitaire/solitaire.c | 2 +- applications/external/subbrute | 2 +- applications/external/wav_player/wav_player.c | 2 +- .../external/wifi_marauder_companion/wifi_marauder_app_i.h | 2 +- .../wifi_marauder_companion/wifi_marauder_text_input.c | 2 +- 21 files changed, 22 insertions(+), 22 deletions(-) diff --git a/applications/debug/application.fam b/applications/debug/application.fam index c52907002..a33b3693d 100644 --- a/applications/debug/application.fam +++ b/applications/debug/application.fam @@ -7,8 +7,8 @@ App( "vibro_test", "keypad_test", "usb_test", - "USB_Mouse", - "UART_Echo", + "usb_mouse", + "uart_echo", "display_test", "text_box_test", "file_browser_test", diff --git a/applications/external/blackjack/blackjack.c b/applications/external/blackjack/blackjack.c index 95f9c72bb..44db29087 100644 --- a/applications/external/blackjack/blackjack.c +++ b/applications/external/blackjack/blackjack.c @@ -14,7 +14,7 @@ #include "util.h" #include "ui.h" -#include "Blackjack_icons.h" +#include "blackjack_icons.h" #define DEALER_MAX 17 diff --git a/applications/external/flappy_bird/flappy_bird.c b/applications/external/flappy_bird/flappy_bird.c index b264d1b70..709219bb5 100644 --- a/applications/external/flappy_bird/flappy_bird.c +++ b/applications/external/flappy_bird/flappy_bird.c @@ -1,6 +1,6 @@ #include -#include +#include #include #include #include diff --git a/applications/external/flipfrid/flipfrid.h b/applications/external/flipfrid/flipfrid.h index 0ee8aa320..b95f9f75f 100644 --- a/applications/external/flipfrid/flipfrid.h +++ b/applications/external/flipfrid/flipfrid.h @@ -15,7 +15,7 @@ #include #include -#include +#include #include #include diff --git a/applications/external/flipper_i2ctools/views/main_view.h b/applications/external/flipper_i2ctools/views/main_view.h index 050e41130..dc6ca4fd0 100644 --- a/applications/external/flipper_i2ctools/views/main_view.h +++ b/applications/external/flipper_i2ctools/views/main_view.h @@ -1,7 +1,7 @@ #include #include #include -#include +#include #define APP_NAME "I2C Tools" #define SCAN_MENU_TEXT "Scan" diff --git a/applications/external/flipper_i2ctools/views/scanner_view.h b/applications/external/flipper_i2ctools/views/scanner_view.h index 02bc8fb1c..4c59f8836 100644 --- a/applications/external/flipper_i2ctools/views/scanner_view.h +++ b/applications/external/flipper_i2ctools/views/scanner_view.h @@ -1,7 +1,7 @@ #include #include #include -#include +#include #include "../i2cscanner.h" #define SCAN_TEXT "SCAN" diff --git a/applications/external/flipper_i2ctools/views/sender_view.h b/applications/external/flipper_i2ctools/views/sender_view.h index 5f48081dd..c5192d0b6 100644 --- a/applications/external/flipper_i2ctools/views/sender_view.h +++ b/applications/external/flipper_i2ctools/views/sender_view.h @@ -1,7 +1,7 @@ #include #include #include -#include +#include #include "../i2csender.h" #define SEND_TEXT "SEND" diff --git a/applications/external/flipper_i2ctools/views/sniffer_view.h b/applications/external/flipper_i2ctools/views/sniffer_view.h index 80c92f7fc..db4dbd1ff 100644 --- a/applications/external/flipper_i2ctools/views/sniffer_view.h +++ b/applications/external/flipper_i2ctools/views/sniffer_view.h @@ -1,7 +1,7 @@ #include #include #include -#include +#include #include "../i2csniffer.h" #define SNIFF_TEXT "SNIFF" diff --git a/applications/external/ibtn_fuzzer/ibtnfuzzer.h b/applications/external/ibtn_fuzzer/ibtnfuzzer.h index 3a3a1d21f..7a9e2b537 100644 --- a/applications/external/ibtn_fuzzer/ibtnfuzzer.h +++ b/applications/external/ibtn_fuzzer/ibtnfuzzer.h @@ -15,7 +15,7 @@ #include #include -#include +#include #include #include diff --git a/applications/external/metronome/gui_extensions.c b/applications/external/metronome/gui_extensions.c index 458eb137b..f33c5f651 100644 --- a/applications/external/metronome/gui_extensions.c +++ b/applications/external/metronome/gui_extensions.c @@ -1,6 +1,6 @@ #include #include -#include +#include //lib can only do bottom left/right void elements_button_top_left(Canvas* canvas, const char* str) { diff --git a/applications/external/mousejacker/mousejacker.c b/applications/external/mousejacker/mousejacker.c index 606e092ca..ce93aa996 100644 --- a/applications/external/mousejacker/mousejacker.c +++ b/applications/external/mousejacker/mousejacker.c @@ -10,7 +10,7 @@ #include #include #include "mousejacker_ducky.h" -#include +#include #define TAG "mousejacker" #define LOGITECH_MAX_CHANNEL 85 diff --git a/applications/external/music_player/music_player.c b/applications/external/music_player/music_player.c index 71840ff92..28127a575 100644 --- a/applications/external/music_player/music_player.c +++ b/applications/external/music_player/music_player.c @@ -3,7 +3,7 @@ #include #include -#include +#include #include #include #include diff --git a/applications/external/picopass/picopass_device.c b/applications/external/picopass/picopass_device.c index b5ba8ba78..53778cfb3 100644 --- a/applications/external/picopass/picopass_device.c +++ b/applications/external/picopass/picopass_device.c @@ -2,7 +2,7 @@ #include #include -#include +#include #define TAG "PicopassDevice" diff --git a/applications/external/picopass/picopass_i.h b/applications/external/picopass/picopass_i.h index 23da3056e..9147cfa0c 100644 --- a/applications/external/picopass/picopass_i.h +++ b/applications/external/picopass/picopass_i.h @@ -25,7 +25,7 @@ #include #include -#include +#include #define PICOPASS_TEXT_STORE_SIZE 128 diff --git a/applications/external/playlist/playlist.c b/applications/external/playlist/playlist.c index 1ecfda02a..5bf376ccd 100644 --- a/applications/external/playlist/playlist.c +++ b/applications/external/playlist/playlist.c @@ -6,7 +6,7 @@ #include #include -#include +#include #include #include diff --git a/applications/external/signal_generator/views/signal_gen_pwm.c b/applications/external/signal_generator/views/signal_gen_pwm.c index 928be7916..d625ed5a9 100644 --- a/applications/external/signal_generator/views/signal_gen_pwm.c +++ b/applications/external/signal_generator/views/signal_gen_pwm.c @@ -1,7 +1,7 @@ #include "../signal_gen_app_i.h" #include #include -#include +#include typedef enum { LineIndexChannel, diff --git a/applications/external/solitaire/solitaire.c b/applications/external/solitaire/solitaire.c index c9de533d3..7d39ae636 100644 --- a/applications/external/solitaire/solitaire.c +++ b/applications/external/solitaire/solitaire.c @@ -4,7 +4,7 @@ #include #include "defines.h" #include "common/ui.h" -#include "Solitaire_icons.h" +#include "solitaire_icons.h" #include #include void init(GameState* game_state); diff --git a/applications/external/subbrute b/applications/external/subbrute index 16f94c118..c55814712 160000 --- a/applications/external/subbrute +++ b/applications/external/subbrute @@ -1 +1 @@ -Subproject commit 16f94c1186e6b7dc1758e6ae9c1fbe9a55f69da6 +Subproject commit c55814712d07cb5983c0c46dfc1386ab973358c3 diff --git a/applications/external/wav_player/wav_player.c b/applications/external/wav_player/wav_player.c index 9c1b4e5b6..8f3273131 100644 --- a/applications/external/wav_player/wav_player.c +++ b/applications/external/wav_player/wav_player.c @@ -12,7 +12,7 @@ #include "wav_player_view.h" #include -#include +#include #define TAG "WavPlayer" diff --git a/applications/external/wifi_marauder_companion/wifi_marauder_app_i.h b/applications/external/wifi_marauder_companion/wifi_marauder_app_i.h index 2a16522bb..d6a0d37c7 100644 --- a/applications/external/wifi_marauder_companion/wifi_marauder_app_i.h +++ b/applications/external/wifi_marauder_companion/wifi_marauder_app_i.h @@ -21,7 +21,7 @@ #include #include "wifi_marauder_text_input.h" -#include +#include #include #include #include diff --git a/applications/external/wifi_marauder_companion/wifi_marauder_text_input.c b/applications/external/wifi_marauder_companion/wifi_marauder_text_input.c index 663d0130e..d087f268d 100644 --- a/applications/external/wifi_marauder_companion/wifi_marauder_text_input.c +++ b/applications/external/wifi_marauder_companion/wifi_marauder_text_input.c @@ -1,6 +1,6 @@ #include "wifi_marauder_text_input.h" #include -#include "ESP32_WiFi_Marauder_icons.h" +#include "esp32_wifi_marauder_icons.h" #include "wifi_marauder_app_i.h" #include From ad83095959fee346523eecbe9fb43772bf58a7ed Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Fri, 2 Jun 2023 15:18:05 +0300 Subject: [PATCH 48/52] Final --- applications/external/flipper_i2ctools/views/main_view.h | 2 +- applications/external/flipper_i2ctools/views/scanner_view.h | 2 +- applications/external/flipper_i2ctools/views/sender_view.h | 2 +- applications/external/flipper_i2ctools/views/sniffer_view.h | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/applications/external/flipper_i2ctools/views/main_view.h b/applications/external/flipper_i2ctools/views/main_view.h index dc6ca4fd0..f0ce5e8ad 100644 --- a/applications/external/flipper_i2ctools/views/main_view.h +++ b/applications/external/flipper_i2ctools/views/main_view.h @@ -1,7 +1,7 @@ #include #include #include -#include +#include #define APP_NAME "I2C Tools" #define SCAN_MENU_TEXT "Scan" diff --git a/applications/external/flipper_i2ctools/views/scanner_view.h b/applications/external/flipper_i2ctools/views/scanner_view.h index 4c59f8836..52f30a7bf 100644 --- a/applications/external/flipper_i2ctools/views/scanner_view.h +++ b/applications/external/flipper_i2ctools/views/scanner_view.h @@ -1,7 +1,7 @@ #include #include #include -#include +#include #include "../i2cscanner.h" #define SCAN_TEXT "SCAN" diff --git a/applications/external/flipper_i2ctools/views/sender_view.h b/applications/external/flipper_i2ctools/views/sender_view.h index c5192d0b6..c4fdd98a2 100644 --- a/applications/external/flipper_i2ctools/views/sender_view.h +++ b/applications/external/flipper_i2ctools/views/sender_view.h @@ -1,7 +1,7 @@ #include #include #include -#include +#include #include "../i2csender.h" #define SEND_TEXT "SEND" diff --git a/applications/external/flipper_i2ctools/views/sniffer_view.h b/applications/external/flipper_i2ctools/views/sniffer_view.h index db4dbd1ff..8f2140bba 100644 --- a/applications/external/flipper_i2ctools/views/sniffer_view.h +++ b/applications/external/flipper_i2ctools/views/sniffer_view.h @@ -1,7 +1,7 @@ #include #include #include -#include +#include #include "../i2csniffer.h" #define SNIFF_TEXT "SNIFF" From 2dc0059b1cf8c5824a6b27b2641cc52bee6a427c Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Fri, 2 Jun 2023 16:47:54 +0300 Subject: [PATCH 49/52] NFC V, review gui fixes, disable debug output in digital signal --- .../main/nfc/scenes/nfc_scene_config.h | 1 + .../main/nfc/scenes/nfc_scene_nfc_data_info.c | 40 ++++---- .../main/nfc/scenes/nfc_scene_nfcv_emulate.c | 26 +++-- .../main/nfc/scenes/nfc_scene_nfcv_menu.c | 5 + .../nfc/scenes/nfc_scene_nfcv_read_success.c | 94 +++++++++++++++++++ applications/main/nfc/scenes/nfc_scene_read.c | 2 +- lib/digital_signal/digital_signal.c | 2 +- 7 files changed, 138 insertions(+), 32 deletions(-) create mode 100644 applications/main/nfc/scenes/nfc_scene_nfcv_read_success.c diff --git a/applications/main/nfc/scenes/nfc_scene_config.h b/applications/main/nfc/scenes/nfc_scene_config.h index 445c4436a..aea59957d 100644 --- a/applications/main/nfc/scenes/nfc_scene_config.h +++ b/applications/main/nfc/scenes/nfc_scene_config.h @@ -20,6 +20,7 @@ ADD_SCENE(nfc, nfcv_key_input, NfcVKeyInput) ADD_SCENE(nfc, nfcv_unlock, NfcVUnlock) ADD_SCENE(nfc, nfcv_emulate, NfcVEmulate) ADD_SCENE(nfc, nfcv_sniff, NfcVSniff) +ADD_SCENE(nfc, nfcv_read_success, NfcVReadSuccess) ADD_SCENE(nfc, mf_ultralight_read_success, MfUltralightReadSuccess) ADD_SCENE(nfc, mf_ultralight_data, MfUltralightData) ADD_SCENE(nfc, mf_ultralight_menu, MfUltralightMenu) diff --git a/applications/main/nfc/scenes/nfc_scene_nfc_data_info.c b/applications/main/nfc/scenes/nfc_scene_nfc_data_info.c index 1c1e3e4b4..eb2f939c6 100644 --- a/applications/main/nfc/scenes/nfc_scene_nfc_data_info.c +++ b/applications/main/nfc/scenes/nfc_scene_nfc_data_info.c @@ -15,7 +15,7 @@ void nfc_scene_nfc_data_info_on_enter(void* context) { NfcProtocol protocol = dev_data->protocol; uint8_t text_scroll_height = 0; if((protocol == NfcDeviceProtocolMifareDesfire) || (protocol == NfcDeviceProtocolMifareUl) || - (protocol == NfcDeviceProtocolMifareClassic) || (protocol == NfcDeviceProtocolNfcV)) { + (protocol == NfcDeviceProtocolMifareClassic)) { widget_add_button_element( widget, GuiButtonTypeRight, "More", nfc_scene_nfc_data_info_widget_callback, nfc); text_scroll_height = 52; @@ -90,25 +90,6 @@ void nfc_scene_nfc_data_info_on_enter(void* context) { furi_string_cat_printf(temp_str, "Blocks: %02X\n", nfcv_data->block_num); furi_string_cat_printf(temp_str, "Blocksize: %02X\n", nfcv_data->block_size); - furi_string_cat_printf( - temp_str, "Data (%d byte)\n", nfcv_data->block_num * nfcv_data->block_size); - - int maxBlocks = nfcv_data->block_num; - if(maxBlocks > 32) { - maxBlocks = 32; - furi_string_cat_printf(temp_str, "(truncated to %d blocks)\n", maxBlocks); - } - - for(int block = 0; block < maxBlocks; block++) { - const char* status = (nfcv_data->security_status[block] & 0x01) ? "(lck)" : ""; - for(int pos = 0; pos < nfcv_data->block_size; pos++) { - furi_string_cat_printf( - temp_str, " %02X", nfcv_data->data[block * nfcv_data->block_size + pos]); - } - furi_string_cat_printf(temp_str, " %s\n", status); - } - furi_string_cat_printf(temp_str, "\n"); - switch(dev_data->nfcv_data.sub_type) { case NfcVTypePlain: furi_string_cat_printf(temp_str, "Type: Plain\n"); @@ -189,6 +170,25 @@ void nfc_scene_nfc_data_info_on_enter(void* context) { furi_string_cat_printf(temp_str, "\e#ISO15693 (unknown)\n"); break; } + + furi_string_cat_printf( + temp_str, "Data (%d byte)\n", nfcv_data->block_num * nfcv_data->block_size); + + int maxBlocks = nfcv_data->block_num; + if(maxBlocks > 32) { + maxBlocks = 32; + furi_string_cat_printf(temp_str, "(truncated to %d blocks)\n", maxBlocks); + } + + for(int block = 0; block < maxBlocks; block++) { + const char* status = (nfcv_data->security_status[block] & 0x01) ? "(lck)" : ""; + for(int pos = 0; pos < nfcv_data->block_size; pos++) { + furi_string_cat_printf( + temp_str, " %02X", nfcv_data->data[block * nfcv_data->block_size + pos]); + } + furi_string_cat_printf(temp_str, " %s\n", status); + } + } else { char iso_type = FURI_BIT(nfc_data->sak, 5) ? '4' : '3'; furi_string_cat_printf(temp_str, "ISO 14443-%c (NFC-A)\n", iso_type); diff --git a/applications/main/nfc/scenes/nfc_scene_nfcv_emulate.c b/applications/main/nfc/scenes/nfc_scene_nfcv_emulate.c index 3f2a860e0..3dd7c460b 100644 --- a/applications/main/nfc/scenes/nfc_scene_nfcv_emulate.c +++ b/applications/main/nfc/scenes/nfc_scene_nfcv_emulate.c @@ -13,7 +13,9 @@ bool nfc_scene_nfcv_emulate_worker_callback(NfcWorkerEvent event, void* context) switch(event) { case NfcWorkerEventNfcVCommandExecuted: - view_dispatcher_send_custom_event(nfc->view_dispatcher, NfcCustomEventUpdateLog); + if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)) { + view_dispatcher_send_custom_event(nfc->view_dispatcher, NfcCustomEventUpdateLog); + } break; case NfcWorkerEventNfcVContentChanged: view_dispatcher_send_custom_event(nfc->view_dispatcher, NfcCustomEventSaveShadow); @@ -45,9 +47,9 @@ static void nfc_scene_nfcv_emulate_widget_config(Nfc* nfc, bool data_received) { FuriString* info_str; info_str = furi_string_alloc(); - widget_add_icon_element(widget, 0, 3, &I_RFIDDolphinSend_97x61); - widget_add_string_element( - widget, 89, 32, AlignCenter, AlignTop, FontPrimary, "Emulating NfcV"); + widget_add_icon_element(widget, 0, 3, &I_NFC_dolphin_emulation_47x61); + widget_add_string_multiline_element( + widget, 87, 13, AlignCenter, AlignTop, FontPrimary, "Emulating\nNFC V"); if(strcmp(nfc->dev->dev_name, "")) { furi_string_printf(info_str, "%s", nfc->dev->dev_name); } else { @@ -57,11 +59,13 @@ static void nfc_scene_nfcv_emulate_widget_config(Nfc* nfc, bool data_received) { } furi_string_trim(info_str); widget_add_text_box_element( - widget, 56, 43, 70, 21, AlignCenter, AlignTop, furi_string_get_cstr(info_str), true); + widget, 52, 40, 70, 21, AlignCenter, AlignTop, furi_string_get_cstr(info_str), true); furi_string_free(info_str); if(data_received) { - widget_add_button_element( - widget, GuiButtonTypeCenter, "Log", nfc_scene_nfcv_emulate_widget_callback, nfc); + if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)) { + widget_add_button_element( + widget, GuiButtonTypeCenter, "Log", nfc_scene_nfcv_emulate_widget_callback, nfc); + } } } @@ -126,9 +130,11 @@ bool nfc_scene_nfcv_emulate_on_event(void* context, SceneManagerEvent event) { } consumed = true; } else if(event.event == GuiButtonTypeCenter && state == NfcSceneNfcVEmulateStateWidget) { - view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewTextBox); - scene_manager_set_scene_state( - nfc->scene_manager, NfcSceneNfcVEmulate, NfcSceneNfcVEmulateStateTextBox); + if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)) { + view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewTextBox); + scene_manager_set_scene_state( + nfc->scene_manager, NfcSceneNfcVEmulate, NfcSceneNfcVEmulateStateTextBox); + } consumed = true; } else if(event.event == NfcCustomEventViewExit && state == NfcSceneNfcVEmulateStateTextBox) { view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewWidget); diff --git a/applications/main/nfc/scenes/nfc_scene_nfcv_menu.c b/applications/main/nfc/scenes/nfc_scene_nfcv_menu.c index 44d677513..7c6780b7c 100644 --- a/applications/main/nfc/scenes/nfc_scene_nfcv_menu.c +++ b/applications/main/nfc/scenes/nfc_scene_nfcv_menu.c @@ -4,6 +4,7 @@ enum SubmenuIndex { SubmenuIndexSave, SubmenuIndexEmulate, + SubmenuIndexInfo, }; void nfc_scene_nfcv_menu_submenu_callback(void* context, uint32_t index) { @@ -19,6 +20,7 @@ void nfc_scene_nfcv_menu_on_enter(void* context) { submenu_add_item( submenu, "Emulate", SubmenuIndexEmulate, nfc_scene_nfcv_menu_submenu_callback, nfc); submenu_add_item(submenu, "Save", SubmenuIndexSave, nfc_scene_nfcv_menu_submenu_callback, nfc); + submenu_add_item(submenu, "Info", SubmenuIndexInfo, nfc_scene_nfcv_menu_submenu_callback, nfc); submenu_set_selected_item( nfc->submenu, scene_manager_get_scene_state(nfc->scene_manager, NfcSceneNfcVMenu)); @@ -45,6 +47,9 @@ bool nfc_scene_nfcv_menu_on_event(void* context, SceneManagerEvent event) { DOLPHIN_DEED(DolphinDeedNfcEmulate); } consumed = true; + } else if(event.event == SubmenuIndexInfo) { + scene_manager_next_scene(nfc->scene_manager, NfcSceneNfcDataInfo); + consumed = true; } scene_manager_set_scene_state(nfc->scene_manager, NfcSceneNfcVMenu, event.event); diff --git a/applications/main/nfc/scenes/nfc_scene_nfcv_read_success.c b/applications/main/nfc/scenes/nfc_scene_nfcv_read_success.c new file mode 100644 index 000000000..bdf7692cc --- /dev/null +++ b/applications/main/nfc/scenes/nfc_scene_nfcv_read_success.c @@ -0,0 +1,94 @@ +#include "../nfc_i.h" + +void nfc_scene_nfcv_read_success_widget_callback( + GuiButtonType result, + InputType type, + void* context) { + furi_assert(context); + Nfc* nfc = context; + + if(type == InputTypeShort) { + view_dispatcher_send_custom_event(nfc->view_dispatcher, result); + } +} + +void nfc_scene_nfcv_read_success_on_enter(void* context) { + Nfc* nfc = context; + NfcDeviceData* dev_data = &nfc->dev->dev_data; + FuriHalNfcDevData* nfc_data = &nfc->dev->dev_data.nfc_data; + NfcVData* nfcv_data = &nfc->dev->dev_data.nfcv_data; + // Setup view + Widget* widget = nfc->widget; + widget_add_button_element( + widget, GuiButtonTypeLeft, "Retry", nfc_scene_nfcv_read_success_widget_callback, nfc); + widget_add_button_element( + widget, GuiButtonTypeRight, "More", nfc_scene_nfcv_read_success_widget_callback, nfc); + + FuriString* temp_str = furi_string_alloc(); + + switch(dev_data->nfcv_data.sub_type) { + case NfcVTypePlain: + furi_string_cat_printf(temp_str, "\e#ISO15693\n"); + break; + case NfcVTypeSlix: + furi_string_cat_printf(temp_str, "\e#ISO15693 SLIX\n"); + break; + case NfcVTypeSlixS: + furi_string_cat_printf(temp_str, "\e#ISO15693 SLIX-S\n"); + break; + case NfcVTypeSlixL: + furi_string_cat_printf(temp_str, "\e#ISO15693 SLIX-L\n"); + break; + case NfcVTypeSlix2: + furi_string_cat_printf(temp_str, "\e#ISO15693 SLIX2\n"); + break; + default: + furi_string_cat_printf(temp_str, "\e#ISO15693 (unknown)\n"); + break; + } + furi_string_cat_printf(temp_str, "UID:"); + for(size_t i = 0; i < nfc_data->uid_len; i++) { + furi_string_cat_printf(temp_str, " %02X", nfc_data->uid[i]); + } + furi_string_cat_printf(temp_str, "\n"); + furi_string_cat_printf(temp_str, "Blocks: %02X\n", nfcv_data->block_num); + furi_string_cat_printf(temp_str, "Blocksize: %02X\n", nfcv_data->block_size); + + widget_add_text_scroll_element(widget, 0, 0, 128, 52, furi_string_get_cstr(temp_str)); + furi_string_free(temp_str); + + notification_message_block(nfc->notifications, &sequence_set_green_255); + + view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewWidget); +} + +bool nfc_scene_nfcv_read_success_on_event(void* context, SceneManagerEvent event) { + Nfc* nfc = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + if(event.event == GuiButtonTypeLeft) { + scene_manager_next_scene(nfc->scene_manager, NfcSceneRetryConfirm); + consumed = true; + } else if(event.event == GuiButtonTypeRight) { + // Clear device name + nfc_device_set_name(nfc->dev, ""); + scene_manager_next_scene(nfc->scene_manager, NfcSceneNfcVMenu); + consumed = true; + } + } else if(event.type == SceneManagerEventTypeBack) { + scene_manager_next_scene(nfc->scene_manager, NfcSceneExitConfirm); + consumed = true; + } + + return consumed; +} + +void nfc_scene_nfcv_read_success_on_exit(void* context) { + Nfc* nfc = context; + + notification_message_block(nfc->notifications, &sequence_reset_green); + + // Clear view + widget_reset(nfc->widget); +} diff --git a/applications/main/nfc/scenes/nfc_scene_read.c b/applications/main/nfc/scenes/nfc_scene_read.c index d30706c5b..2f2f9ac01 100644 --- a/applications/main/nfc/scenes/nfc_scene_read.c +++ b/applications/main/nfc/scenes/nfc_scene_read.c @@ -70,7 +70,7 @@ bool nfc_scene_read_on_event(void* context, SceneManagerEvent event) { consumed = true; } else if(event.event == NfcWorkerEventReadNfcV) { notification_message(nfc->notifications, &sequence_success); - scene_manager_next_scene(nfc->scene_manager, NfcSceneNfcDataInfo); + scene_manager_next_scene(nfc->scene_manager, NfcSceneNfcVReadSuccess); DOLPHIN_DEED(DolphinDeedNfcReadSuccess); consumed = true; } else if(event.event == NfcWorkerEventReadMfUltralight) { diff --git a/lib/digital_signal/digital_signal.c b/lib/digital_signal/digital_signal.c index 61f025ce6..6ccfcf280 100644 --- a/lib/digital_signal/digital_signal.c +++ b/lib/digital_signal/digital_signal.c @@ -9,7 +9,7 @@ #include /* must be on bank B */ -#define DEBUG_OUTPUT gpio_ext_pb3 +//#define DEBUG_OUTPUT gpio_ext_pb3 struct ReloadBuffer { uint32_t* buffer; /* DMA ringbuffer */ From 05b6ae7b2055cf78954c98cfe57b65d9d2530dca Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Fri, 2 Jun 2023 17:03:03 +0300 Subject: [PATCH 50/52] Deauther crash fix, Fixes issue #497 --- applications/external/esp8266_deauth/esp8266_deauth.c | 6 +++--- applications/external/wifi_scanner/wifi_scanner.c | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/applications/external/esp8266_deauth/esp8266_deauth.c b/applications/external/esp8266_deauth/esp8266_deauth.c index e0a966975..cb79cf651 100644 --- a/applications/external/esp8266_deauth/esp8266_deauth.c +++ b/applications/external/esp8266_deauth/esp8266_deauth.c @@ -371,8 +371,8 @@ int32_t esp8266_deauth_app(void* p) { view_port_input_callback_set(view_port, esp8266_deauth_module_input_callback, event_queue); // Open GUI and register view_port - Gui* gui = furi_record_open(RECORD_GUI); - gui_add_view_port(gui, view_port, GuiLayerFullscreen); + app->m_gui = furi_record_open(RECORD_GUI); + gui_add_view_port(app->m_gui, view_port, GuiLayerFullscreen); //notification_message(app->notification, &sequence_set_only_blue_255); @@ -513,7 +513,7 @@ int32_t esp8266_deauth_app(void* p) { view_port_enabled_set(view_port, false); - gui_remove_view_port(gui, view_port); + gui_remove_view_port(app->m_gui, view_port); // Close gui record furi_record_close(RECORD_GUI); diff --git a/applications/external/wifi_scanner/wifi_scanner.c b/applications/external/wifi_scanner/wifi_scanner.c index 127bee0cd..1eb60fd00 100644 --- a/applications/external/wifi_scanner/wifi_scanner.c +++ b/applications/external/wifi_scanner/wifi_scanner.c @@ -889,8 +889,8 @@ int32_t wifi_scanner_app(void* p) { view_port_input_callback_set(view_port, wifi_module_input_callback, event_queue); // Open GUI and register view_port - Gui* gui = furi_record_open(RECORD_GUI); - gui_add_view_port(gui, view_port, GuiLayerFullscreen); + app->m_gui = furi_record_open(RECORD_GUI); + gui_add_view_port(app->m_gui, view_port, GuiLayerFullscreen); //notification_message(app->notification, &sequence_set_only_blue_255); @@ -1040,7 +1040,7 @@ int32_t wifi_scanner_app(void* p) { view_port_enabled_set(view_port, false); - gui_remove_view_port(gui, view_port); + gui_remove_view_port(app->m_gui, view_port); // Close gui record furi_record_close(RECORD_GUI); From 7c86e53bd2ba00add02817b9ccb1be3d903fa739 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Fri, 2 Jun 2023 19:09:43 +0300 Subject: [PATCH 51/52] Update changelog --- CHANGELOG.md | 58 ++++++++++++++++++++++------------------------------ 1 file changed, 24 insertions(+), 34 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 425ba6300..1843697bb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,40 +1,30 @@ ### New changes -* !!! **Warning! After installing, Desktop settings (Favoutite apps, PIN Code, AutoLock time..) will be resetted to default due to settings changes, Please set your PIN code, Favourite apps again in Settings->Desktop** !!! * If you have copied any apps manually into `apps` folder - remove `apps` folder or that specific apps you copied on your microSD before installing this release to avoid issues due to OFW API version update! If you using regular builds or extra pack builds (e) without your manually added apps, all included apps will be installed automatically, no extra actions needed! ----- -* Desktop: **Show clock on main screen** (Enable in Settings->Desktop->Show Clock) (by @gid9798 | PR #484) -* SubGHz Remote: New plugin - Configurator (Remote Maker) - Now you can create and edit map files on flipper! (by @gid9798 | PR #487) -* SubGHz Remote: Full refactoring, app was re-made from scratch (by @gid9798) -* Archive: Fix rename, show error message to user -* API: Cleanup, mini refactoring of some apps (+6k of free flash space) -* LFRFID: Debug: Allow PSK RAW emulation in gui -* SubGHz: Security+ 2.0 -> add extra custom button `0x78` - Fixes issue #469 -* SubGHz: Various fixes (by @gid9798) -* SubGHz: Fix counter settings in debug -* SubGHz: Move dangerous_settings check (by @gid9798 | PR #475) -* Misc: Move NFC plugins into NFC folder -* Misc: Name changer code moved to proper place, load after system startup + extra checks -* Plugins: Merge tiktok and ytshorts remote into one (by @Willy-JL) -* Plugins: NMEA GPS UART - stability fix -* Plugins: Port XFW keyboard with extra symbols to WiFi Marauder instead of using UART Term keyboard (thanks to @Willy-JL) -* Plugins: Moved from extra pack to main FW: Mifare Nested [(by AloneLiberty)](https://github.com/AloneLiberty/FlipperNested) - Works with PC and python app `FlipperNested` -* Plugins: Update TOTP (Authenticator) [(by akopachov)](https://github.com/akopachov/flipper-zero_authenticator) (+ Add option to set custom fonts) -* Plugins: Update NMEA GPS UART [(by ezod)](https://github.com/ezod/flipperzero-gps) (GLL support) -* Plugins: Update WiFi Marauder [(by 0xchocolate)](https://github.com/0xchocolate/flipperzero-firmware-with-wifi-marauder-companion) -* OFW PR 2680: RFID - Add support for Nexkey/Nexwatch (by @mauimauer) -* OFW: nfc: Mifare Ultralight C detection -* OFW: api: added toolbox/api_lock.h -* OFW: NFC: Add support for Gen4 "ultimate card" in Magic app -* OFW: desktop: Refactor favorites settings and allow app browser in selection -* OFW: Infrared: respect carrier frequency and duty cycle settings -> **Breaking API change, API version was changed from 26.x to 27.x** -* OFW: Desktop,Rpc: desktop status subscription -* OFW: Storage, common_rename: check that old path is exists -* OFW: Services: remove deallocator for persistent services -* OFW: Storage: common_rename is now POSIX compliant -* OFW: Removed user-specific data from tar artifacts -* OFW: fbt: Fix tar uid overflow when packaging -* OFW: fbt: Use union for old py (Fix builds if using older python versions) -* OFW: USB HID report timeout +* SubGHz Remote: Fixed BinRAW support, + many other fixes (by @gid9798 | PR #492) +* SubGHz: Keeloq mfname refactoring (by @gid9798 | PR #479) +* Desktop Clock: Some improvements and fixes (by @gid9798 | PR #490) +* LF RFID: Cleanup duplicated code (by @gid9798 | PR #493) +* NFC V: Code review fixes + some GUI rework (by @nvx & @xMasterX) +* NFC V: Fixed crash when exiting emulation and starting it again +* Infrared: Use Universal AC Remote from OFW, same for Audio remote, and rename buttons in OFW naming scheme +* Infrared: Update universal remote assets (by @amec0e) +* GUI Keyboard: Fix crash when renaming files with long file name (Fixed issue #489) +* Misc: Fix APP_IDs to match new regex (regex check will be added in OFW soon) +* Plugins: ESP8266 Deauther - Crash fix (Fixed issue #497) +* Plugins: Update -> TOTP (Authenticator) [(by akopachov)](https://github.com/akopachov/flipper-zero_authenticator) +* Plugins: Update -> ESP32: WiFi Marauder companion plugin [(by 0xchocolate)](https://github.com/0xchocolate/flipperzero-wifi-marauder) +* Plugins: Update -> UART Terminal [(by cool4uma)](https://github.com/cool4uma/UART_Terminal/tree/main) +* OFW: NFC: fix MFC timings -> **Fixes issues with Mifare Classic emulation that could happen after unlshd-049 release** +* OFW: Update dolphin.py +* OFW: NFC Magic: Fix gen1 writing with invalid BCC (lost fix from PR 2511) +* OFW: SubGhz: fix flipper crashes after exiting broadcast blocking message and crash cli +* OFW: Dolphin: new animation +* OFW: fbt: added hooks for build & dist environments; added FW_ORIGIN_* macro for apps & SDK +* OFW: FuriHal: add bus abstraction -> **Breaking API change, API version was changed from 27.x to 28.x** +* OFW: Implement support for reading Opal card (Sydney, Australia) +* OFW: BadUSB: script execution pause +* OFW: IR Universal AC: Add Carrier 42QHB12D8S #### [🎲 Download latest extra apps pack](https://github.com/xMasterX/all-the-plugins/archive/refs/heads/main.zip) From 0aba59501a33b28a163a546876bf68bb72c2ae21 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Fri, 2 Jun 2023 19:18:16 +0300 Subject: [PATCH 52/52] Fix link --- CHANGELOG.md | 1 + ReadMe.md | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1843697bb..e4d511dcd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ * GUI Keyboard: Fix crash when renaming files with long file name (Fixed issue #489) * Misc: Fix APP_IDs to match new regex (regex check will be added in OFW soon) * Plugins: ESP8266 Deauther - Crash fix (Fixed issue #497) +* Plugins: Update -> Mifare Nested [(by AloneLiberty)](https://github.com/AloneLiberty/FlipperNested) * Plugins: Update -> TOTP (Authenticator) [(by akopachov)](https://github.com/akopachov/flipper-zero_authenticator) * Plugins: Update -> ESP32: WiFi Marauder companion plugin [(by 0xchocolate)](https://github.com/0xchocolate/flipperzero-wifi-marauder) * Plugins: Update -> UART Terminal [(by cool4uma)](https://github.com/cool4uma/UART_Terminal/tree/main) diff --git a/ReadMe.md b/ReadMe.md index 9b6947e90..4917d784c 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -143,7 +143,7 @@ You can support us by using links or addresses below: - WAV Player [(OFW: DrZlo13)](https://github.com/flipperdevices/flipperzero-firmware/tree/zlo/wav-player) - Fixed and improved by [LTVA1](https://github.com/LTVA1/wav_player) -> Also outputs audio on `PA6` - `3(A6)` pin - Barcode generator plugin [(original by McAzzaMan)](https://github.com/McAzzaMan/flipperzero-firmware/tree/UPC-A_Barcode_Generator/applications/barcode_generator) - [EAN-8 and refactoring](https://github.com/DarkFlippers/unleashed-firmware/pull/154) by @msvsergey - GPIO: Sentry Safe plugin [(by H4ckd4ddy)](https://github.com/H4ckd4ddy/flipperzero-sentry-safe-plugin) -- ESP32: WiFi Marauder companion plugin [(by 0xchocolate)](https://github.com/0xchocolate/flipperzero-firmware-with-wifi-marauder-companion) - Saving .pcap on flipper microSD [by tcpassos](https://github.com/tcpassos/flipperzero-firmware-with-wifi-marauder-companion) -> Only with custom marauder build (It is necessary to uncomment "#define WRITE_PACKETS_SERIAL" in configs.h (in marauder fw) and compile the firmware for the wifi board.) Or download precompiled build -> [Download esp32_marauder_ver_flipper_sd_serial.bin](https://github.com/justcallmekoko/ESP32Marauder/releases/latest) +- ESP32: WiFi Marauder companion plugin [(by 0xchocolate)](https://github.com/0xchocolate/flipperzero-wifi-marauder) - Saving .pcap on flipper microSD [by tcpassos](https://github.com/tcpassos/flipperzero-firmware-with-wifi-marauder-companion) -> Only with custom marauder build (It is necessary to uncomment "#define WRITE_PACKETS_SERIAL" in configs.h (in marauder fw) and compile the firmware for the wifi board.) Or download precompiled build -> [Download esp32_marauder_ver_flipper_sd_serial.bin](https://github.com/justcallmekoko/ESP32Marauder/releases/latest) - NRF24: Sniffer & MouseJacker (with changes) [(by mothball187)](https://github.com/mothball187/flipperzero-nrf24/tree/main/mousejacker) - Simple Clock (timer by GMMan) [(original by CompaqDisc)](https://gist.github.com/CompaqDisc/4e329c501bd03c1e801849b81f48ea61) - **Sub-GHz Remote** [(by @gid9798)](https://github.com/gid9798)