From 3e3a167764132a426752cb5bed52afeaf3e93f3e Mon Sep 17 00:00:00 2001 From: Georgii Surkov <37121527+gsurkov@users.noreply.github.com> Date: Mon, 26 Sep 2022 16:49:18 +0300 Subject: [PATCH 01/47] [FL-2852] Update Universal Remote documentation (#1786) * Update Universal Remote documentation * Change formatting --- documentation/UniversalRemotes.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/documentation/UniversalRemotes.md b/documentation/UniversalRemotes.md index ac98d451f..6ecf3b11b 100644 --- a/documentation/UniversalRemotes.md +++ b/documentation/UniversalRemotes.md @@ -32,5 +32,7 @@ Finally, record the `Off` signal: The resulting remote file should now contain 6 signals. Any of them can be omitted, but that will mean that this functionality will not be used. Test the file against the actual device. Every signal must do what it's supposed to. -If everything checks out, add these signals to the [A/C universal remote file](/assets/resources/infrared/assets/ac.ir) -and open a pull request. + +If everything checks out, add these signals to the [A/C universal remote file](/assets/resources/infrared/assets/ac.ir). +Keep the signals of the same type grouped together (e.g. an `Off` signal must follow a previous `Off` one). +When done, open a pull request containing the changed file. From cdcf80ed05299c68eb58cc6b0fca8f3e677eaa5f Mon Sep 17 00:00:00 2001 From: derskythe Date: Mon, 26 Sep 2022 18:27:58 +0400 Subject: [PATCH 02/47] speed-up linear to 07:10 --- applications/main/application.fam | 14 +-- .../subbrute/helpers/subbrute_worker.c | 26 +++-- .../subbrute/helpers/subbrute_worker.h | 1 + .../scenes/subbrute_scene_run_attack.c | 97 ++++++++++++++++--- .../scenes/subbrute_scene_setup_attack.c | 12 ++- applications/plugins/subbrute/subbrute.c | 3 +- .../plugins/subbrute/subbrute_custom_event.h | 2 +- .../plugins/subbrute/subbrute_device.c | 55 +++++++---- .../plugins/subbrute/subbrute_device.h | 2 +- .../subbrute/views/subbrute_attack_view.c | 2 +- 10 files changed, 157 insertions(+), 57 deletions(-) diff --git a/applications/main/application.fam b/applications/main/application.fam index a3d310093..639640b72 100644 --- a/applications/main/application.fam +++ b/applications/main/application.fam @@ -4,17 +4,17 @@ App( apptype=FlipperAppType.METAPACKAGE, provides=[ "gpio", - "ibutton", - "infrared", - "lfrfid", - "nfc", + #"ibutton", + #"infrared", + #"lfrfid", + #"nfc", "subghz", - "bad_usb", - "u2f", + #"bad_usb", + #"u2f", "fap_loader", "archive", "clock", - "unirfremix", + #"unirfremix", ], ) diff --git a/applications/plugins/subbrute/helpers/subbrute_worker.c b/applications/plugins/subbrute/helpers/subbrute_worker.c index 22e0e7ec4..0b8441df5 100644 --- a/applications/plugins/subbrute/helpers/subbrute_worker.c +++ b/applications/plugins/subbrute/helpers/subbrute_worker.c @@ -7,7 +7,7 @@ #define TAG "SubBruteWorker" struct SubBruteWorker { - FuriThread* thread; +// FuriThread* thread; volatile bool worker_running; volatile bool worker_manual_mode; bool is_manual_init; @@ -31,7 +31,7 @@ struct SubBruteWorker { #define SUBBRUTE_TXRX_WORKER_BUF_SIZE 2048 #define SUBBRUTE_TXRX_WORKER_MAX_TXRX_SIZE 60 #define SUBBRUTE_TXRX_WORKER_TIMEOUT_READ_WRITE_BUF 40 -#define SUBBRUTE_TX_TIMEOUT 50 +#define SUBBRUTE_TX_TIMEOUT 10 #define SUBBRUTE_SEND_DELAY 260 /** @@ -92,11 +92,11 @@ int32_t subbrute_worker_thread(void* context) { SubBruteWorker* subbrute_worker_alloc() { SubBruteWorker* instance = malloc(sizeof(SubBruteWorker)); - instance->thread = furi_thread_alloc(); - furi_thread_set_name(instance->thread, "SubBruteAttackWorker"); - furi_thread_set_stack_size(instance->thread, 2048); - furi_thread_set_context(instance->thread, instance); - furi_thread_set_callback(instance->thread, subbrute_worker_thread); +// instance->thread = furi_thread_alloc(); +// furi_thread_set_name(instance->thread, "SubBruteAttackWorker"); +// furi_thread_set_stack_size(instance->thread, 2048); +// furi_thread_set_context(instance->thread, instance); +// furi_thread_set_callback(instance->thread, subbrute_worker_thread); //instance->status = SubBruteWorkerStatusIDLE; instance->worker_running = false; @@ -122,7 +122,7 @@ void subbrute_worker_free(SubBruteWorker* instance) { instance->environment = NULL; } - furi_thread_free(instance->thread); +// furi_thread_free(instance->thread); flipper_format_free(instance->flipper_format); string_clear(instance->protocol_name); @@ -167,7 +167,7 @@ bool subbrute_worker_start( #endif instance->preset = preset; - furi_thread_start(instance->thread); +// furi_thread_start(instance->thread); return res; } @@ -177,7 +177,7 @@ void subbrute_worker_stop(SubBruteWorker* instance) { instance->worker_running = false; - furi_thread_join(instance->thread); +// furi_thread_join(instance->thread); furi_hal_subghz_set_path(FuriHalSubGhzPathIsolate); furi_hal_subghz_sleep(); @@ -195,6 +195,12 @@ bool subbrute_worker_can_transmit(SubBruteWorker* instance) { return (furi_get_tick() - instance->last_time_tx_data) > SUBBRUTE_SEND_DELAY; } +bool subbrute_worker_can_manual_transmit(SubBruteWorker* instance) { + furi_assert(instance); + + return !instance->worker_manual_mode; +} + bool subbrute_worker_transmit(SubBruteWorker* instance, const char* payload) { furi_assert(instance); furi_assert(instance->worker_running); diff --git a/applications/plugins/subbrute/helpers/subbrute_worker.h b/applications/plugins/subbrute/helpers/subbrute_worker.h index 37875fa12..be22b69ee 100644 --- a/applications/plugins/subbrute/helpers/subbrute_worker.h +++ b/applications/plugins/subbrute/helpers/subbrute_worker.h @@ -26,6 +26,7 @@ void subbrute_worker_stop(SubBruteWorker* instance); //bool subbrute_worker_write(SubBruteWorker* instance, uint8_t* data, size_t size); bool subbrute_worker_is_running(SubBruteWorker* instance); bool subbrute_worker_can_transmit(SubBruteWorker* instance); +bool subbrute_worker_can_manual_transmit(SubBruteWorker* instance); bool subbrute_worker_transmit(SubBruteWorker* instance, const char* payload); bool subbrute_worker_init_manual_transmit(SubBruteWorker* instance, uint32_t frequency, diff --git a/applications/plugins/subbrute/scenes/subbrute_scene_run_attack.c b/applications/plugins/subbrute/scenes/subbrute_scene_run_attack.c index 36a9e86f9..af174dd27 100644 --- a/applications/plugins/subbrute/scenes/subbrute_scene_run_attack.c +++ b/applications/plugins/subbrute/scenes/subbrute_scene_run_attack.c @@ -3,6 +3,8 @@ #include "../views/subbrute_attack_view.h" #include "../helpers/subbrute_worker.h" +#define TAG "SubBruteSceneRunAttack" + static void subbrute_scene_run_attack_callback(SubBruteCustomEvent event, void* context) { furi_assert(context); @@ -10,10 +12,53 @@ static void subbrute_scene_run_attack_callback(SubBruteCustomEvent event, void* view_dispatcher_send_custom_event(instance->view_dispatcher, event); } +//static void subbrute_scene_run_attack_worker_callback(void* context) { +// SubBruteState* instance = (SubBruteState*)context; +// +// if(instance->locked || instance->device->key_index + 1 > instance->device->max_value) { +// return; +// } +// instance->locked = true; +// +// if(subbrute_worker_can_manual_transmit(instance->worker)) { +// // Blink +// notification_message(instance->notifications, &sequence_blink_yellow_100); +// subbrute_device_create_packet_parsed(instance->device, instance->device->key_index, true); +// +//#ifdef FURI_DEBUG +// FURI_LOG_I(TAG, "subbrute_worker_manual_transmit"); +//#endif +// if(subbrute_worker_manual_transmit(instance->worker, instance->device->payload)) { +//#ifdef FURI_DEBUG +// FURI_LOG_I(TAG, "transmit ok"); +//#endif +// // Make payload for new iteration or exit +// if(instance->device->key_index + 1 <= instance->device->max_value) { +// instance->device->key_index++; +// } else { +// view_dispatcher_send_custom_event( +// instance->view_dispatcher, SubBruteCustomEventTypeTransmitFinished); +// } +// } +// +// // Stop +// notification_message(instance->notifications, &sequence_blink_stop); +// } +// +// instance->locked = false; +// subbrute_attack_view_set_current_step(instance->view_attack, instance->device->key_index); +//} + void subbrute_scene_run_attack_on_exit(void* context) { furi_assert(context); - SubBruteState* instance = (SubBruteState*)context; + // SubBruteAttackState* state = (SubBruteAttackState*)scene_manager_get_scene_state( + // instance->scene_manager, SubBruteSceneRunAttack); + // furi_assert(state); + // + // furi_timer_free(state->timer); + // free(state); + notification_message(instance->notifications, &sequence_blink_stop); } @@ -21,6 +66,10 @@ void subbrute_scene_run_attack_on_enter(void* context) { furi_assert(context); SubBruteState* instance = (SubBruteState*)context; SubBruteAttackView* view = instance->view_attack; + // + // SubBruteAttackState* state = malloc(sizeof(SubBruteAttackState)); + // scene_manager_set_scene_state( + // instance->scene_manager, SubBruteSceneRunAttack, (uint32_t)state); instance->current_view = SubBruteViewAttack; subbrute_attack_view_set_callback(view, subbrute_scene_run_attack_callback, instance); @@ -33,42 +82,62 @@ void subbrute_scene_run_attack_on_enter(void* context) { instance->device->key_index, true); - // Start worker if not started - subbrute_worker_init_manual_transmit( - instance->worker, - instance->device->frequency, - instance->device->preset, - string_get_cstr(instance->device->protocol_name)); + // Init worker with values + if(!subbrute_worker_init_manual_transmit( + instance->worker, + instance->device->frequency, + instance->device->preset, + string_get_cstr(instance->device->protocol_name))) { + FURI_LOG_W(TAG, "Worker init failed!"); + } + + // state->timer = furi_timer_alloc( + // subbrute_scene_run_attack_worker_callback, FuriTimerTypePeriodic, instance); + // furi_timer_start(state->timer, pdMS_TO_TICKS(100)); // 20 ms } bool subbrute_scene_run_attack_on_event(void* context, SceneManagerEvent event) { SubBruteState* instance = (SubBruteState*)context; - SubBruteAttackView* view = instance->view_attack; + // SubBruteAttackState* state = (SubBruteAttackState*)scene_manager_get_scene_state( + // instance->scene_manager, SubBruteSceneRunAttack); + // furi_assert(state); + bool consumed = false; if(event.type == SceneManagerEventTypeCustom) { + SubBruteAttackView* view = instance->view_attack; + if(event.event == SubBruteCustomEventTypeTransmitNotStarted || event.event == SubBruteCustomEventTypeTransmitFinished || event.event == SubBruteCustomEventTypeBackPressed) { + // furi_timer_stop(state->timer); // Stop transmit - scene_manager_next_scene(instance->scene_manager, SubBruteSceneSetupAttack); + subbrute_attack_view_set_current_step(view, instance->device->key_index); + scene_manager_search_and_switch_to_previous_scene( + instance->scene_manager, SubBruteSceneSetupAttack); consumed = true; + } else if (event.event == SubBruteCustomEventTypeUpdateView) { + subbrute_attack_view_set_current_step(view, instance->device->key_index); } } else if(event.type == SceneManagerEventTypeTick) { - if(subbrute_worker_can_transmit(instance->worker)) { + if(subbrute_worker_can_manual_transmit(instance->worker)) { // Blink notification_message(instance->notifications, &sequence_blink_yellow_100); + subbrute_device_create_packet_parsed( + instance->device, instance->device->key_index, true); + if(subbrute_worker_manual_transmit(instance->worker, instance->device->payload)) { // Make payload for new iteration or exit if(instance->device->key_index + 1 > instance->device->max_value) { // End of list - scene_manager_next_scene(instance->scene_manager, SubBruteSceneSetupAttack); + view_dispatcher_send_custom_event( + instance->view_dispatcher, SubBruteCustomEventTypeTransmitFinished); } else { instance->device->key_index++; - subbrute_attack_view_set_current_step(view, instance->device->key_index); - subbrute_device_create_packet_parsed( - instance->device, instance->device->key_index); + view_dispatcher_send_custom_event( + instance->view_dispatcher, SubBruteCustomEventTypeUpdateView); + //subbrute_attack_view_set_current_step(view, instance->device->key_index); } } diff --git a/applications/plugins/subbrute/scenes/subbrute_scene_setup_attack.c b/applications/plugins/subbrute/scenes/subbrute_scene_setup_attack.c index 22d0a3a5f..e2186ce49 100644 --- a/applications/plugins/subbrute/scenes/subbrute_scene_setup_attack.c +++ b/applications/plugins/subbrute/scenes/subbrute_scene_setup_attack.c @@ -27,11 +27,13 @@ void subbrute_scene_setup_attack_on_enter(void* context) { instance->device->key_index, false); - subbrute_worker_init_manual_transmit( + if(!subbrute_worker_init_manual_transmit( instance->worker, instance->device->frequency, instance->device->preset, - string_get_cstr(instance->device->protocol_name)); + string_get_cstr(instance->device->protocol_name))) { + FURI_LOG_W(TAG, "Worker init failed!"); + } instance->current_view = SubBruteViewAttack; subbrute_attack_view_set_callback(view, subbrute_scene_setup_attack_callback, instance); @@ -55,7 +57,7 @@ bool subbrute_scene_setup_attack_on_event(void* context, SceneManagerEvent event if(event.type == SceneManagerEventTypeCustom) { if(event.event == SubBruteCustomEventTypeTransmitStarted) { - subbrute_device_create_packet_parsed(instance->device, instance->device->key_index); + subbrute_device_create_packet_parsed(instance->device, instance->device->key_index, false); scene_manager_next_scene(instance->scene_manager, SubBruteSceneRunAttack); } else if(event.event == SubBruteCustomEventTypeSaveFile) { subbrute_worker_manual_transmit_stop(instance->worker); @@ -127,7 +129,7 @@ bool subbrute_scene_setup_attack_on_event(void* context, SceneManagerEvent event } subbrute_attack_view_set_current_step(view, instance->device->key_index); } else if(event.event == SubBruteCustomEventTypeTransmitCustom) { - if(subbrute_worker_can_transmit(instance->worker)) { + if(subbrute_worker_can_manual_transmit(instance->worker)) { // Blink notification_message(instance->notifications, &sequence_blink_green_100); @@ -139,7 +141,7 @@ bool subbrute_scene_setup_attack_on_event(void* context, SceneManagerEvent event // string_get_cstr(instance->device->protocol_name)); // } subbrute_device_create_packet_parsed( - instance->device, instance->device->key_index); + instance->device, instance->device->key_index, false); subbrute_worker_manual_transmit(instance->worker, instance->device->payload); // Stop diff --git a/applications/plugins/subbrute/subbrute.c b/applications/plugins/subbrute/subbrute.c index fb6e15882..cacb2e68c 100644 --- a/applications/plugins/subbrute/subbrute.c +++ b/applications/plugins/subbrute/subbrute.c @@ -81,7 +81,7 @@ SubBruteState* subbrute_alloc() { view_dispatcher_set_navigation_event_callback( instance->view_dispatcher, subbrute_back_event_callback); view_dispatcher_set_tick_event_callback( - instance->view_dispatcher, subbrute_tick_event_callback, 100); + instance->view_dispatcher, subbrute_tick_event_callback, 10); //Dialog instance->dialogs = furi_record_open(RECORD_DIALOGS); @@ -297,6 +297,7 @@ int32_t subbrute_app(void* p) { scene_manager_next_scene(instance->scene_manager, SubBruteSceneStart); furi_hal_power_suppress_charge_enter(); + notification_message(instance->notifications, &sequence_display_backlight_on); view_dispatcher_run(instance->view_dispatcher); furi_hal_power_suppress_charge_exit(); subbrute_free(instance); diff --git a/applications/plugins/subbrute/subbrute_custom_event.h b/applications/plugins/subbrute/subbrute_custom_event.h index 5ddab7fa1..8be1a4469 100644 --- a/applications/plugins/subbrute/subbrute_custom_event.h +++ b/applications/plugins/subbrute/subbrute_custom_event.h @@ -14,7 +14,7 @@ typedef enum { SubBruteCustomEventTypeTransmitNotStarted, SubBruteCustomEventTypeTransmitCustom, SubBruteCustomEventTypeSaveFile, - SubBruteCustomEventTypeSaveSuccess, + SubBruteCustomEventTypeUpdateView, SubBruteCustomEventTypeChangeStepUp, SubBruteCustomEventTypeChangeStepDown, SubBruteCustomEventTypeChangeStepUpMore, diff --git a/applications/plugins/subbrute/subbrute_device.c b/applications/plugins/subbrute/subbrute_device.c index 28b47562b..6262eeff4 100644 --- a/applications/plugins/subbrute/subbrute_device.c +++ b/applications/plugins/subbrute/subbrute_device.c @@ -37,6 +37,8 @@ static const char* subbrute_key_file_start = "Filetype: Flipper SubGhz Key File\nVersion: 1\nFrequency: %u\nPreset: %s\nProtocol: %s\nBit: %d"; static const char* subbrute_key_file_key = "%s\nKey: %s\n"; static const char* subbrute_key_file_princeton_end = "%s\nKey: %s\nTE: %d\n"; +static const char* subbrute_key_small_no_tail = "Bit: %d\nKey: %s\n"; +static const char* subbrute_key_small_with_tail = "Bit: %d\nKey: %s\nTE: %d\n"; // Why nobody set in as const in all codebase? static const char* preset_ook270_async = "FuriHalSubGhzPresetOok270Async"; @@ -107,7 +109,7 @@ bool subbrute_device_save_file(SubBruteDevice* instance, const char* dev_file_na #ifdef FURI_DEBUG FURI_LOG_D(TAG, "subbrute_device_save_file: %s", dev_file_name); #endif - bool result = subbrute_device_create_packet_parsed(instance, instance->key_index); + bool result = subbrute_device_create_packet_parsed(instance, instance->key_index, false); if(!result) { FURI_LOG_E(TAG, "subbrute_device_create_packet_parsed failed!"); @@ -191,7 +193,7 @@ const char* subbrute_device_error_get_desc(SubBruteFileResult error_id) { return result; } -bool subbrute_device_create_packet_parsed(SubBruteDevice* instance, uint64_t step) { +bool subbrute_device_create_packet_parsed(SubBruteDevice* instance, uint64_t step, bool small) { furi_assert(instance); //char step_payload[32]; @@ -234,21 +236,40 @@ bool subbrute_device_create_packet_parsed(SubBruteDevice* instance, uint64_t ste FURI_LOG_D(TAG, "candidate: %s, step: %d", string_get_cstr(candidate), step); #endif - if(instance->has_tail) { - snprintf( - instance->payload, - sizeof(instance->payload), - subbrute_key_file_princeton_end, - instance->file_template, - string_get_cstr(candidate), - instance->te); + if (small) { + if(instance->has_tail) { + snprintf( + instance->payload, + sizeof(instance->payload), + subbrute_key_small_with_tail, + instance->bit, + string_get_cstr(candidate), + instance->te); + } else { + snprintf( + instance->payload, + sizeof(instance->payload), + subbrute_key_small_no_tail, + instance->bit, + string_get_cstr(candidate)); + } } else { - snprintf( - instance->payload, - sizeof(instance->payload), - subbrute_key_file_key, - instance->file_template, - string_get_cstr(candidate)); + if(instance->has_tail) { + snprintf( + instance->payload, + sizeof(instance->payload), + subbrute_key_file_princeton_end, + instance->file_template, + string_get_cstr(candidate), + instance->te); + } else { + snprintf( + instance->payload, + sizeof(instance->payload), + subbrute_key_file_key, + instance->file_template, + string_get_cstr(candidate)); + } } #ifdef FURI_DEBUG @@ -407,7 +428,7 @@ SubBruteFileResult subbrute_device_attack_set(SubBruteDevice* instance, SubBrute #endif // Init payload - subbrute_device_create_packet_parsed(instance, instance->key_index); + subbrute_device_create_packet_parsed(instance, instance->key_index, false); return SubBruteFileResultOk; } diff --git a/applications/plugins/subbrute/subbrute_device.h b/applications/plugins/subbrute/subbrute_device.h index 625c53d2a..008e022a8 100644 --- a/applications/plugins/subbrute/subbrute_device.h +++ b/applications/plugins/subbrute/subbrute_device.h @@ -92,7 +92,7 @@ SubBruteDevice* subbrute_device_alloc(); void subbrute_device_free(SubBruteDevice* instance); bool subbrute_device_save_file(SubBruteDevice* instance, const char* key_name); const char* subbrute_device_error_get_desc(SubBruteFileResult error_id); -bool subbrute_device_create_packet_parsed(SubBruteDevice* context, uint64_t step); +bool subbrute_device_create_packet_parsed(SubBruteDevice* context, uint64_t step, bool small); SubBruteFileResult subbrute_device_attack_set(SubBruteDevice* context, SubBruteAttacks type); uint8_t subbrute_device_load_from_file(SubBruteDevice* context, string_t file_path); FuriHalSubGhzPreset subbrute_device_convert_preset(const char* preset); diff --git a/applications/plugins/subbrute/views/subbrute_attack_view.c b/applications/plugins/subbrute/views/subbrute_attack_view.c index 4f43f786d..97eca6a66 100644 --- a/applications/plugins/subbrute/views/subbrute_attack_view.c +++ b/applications/plugins/subbrute/views/subbrute_attack_view.c @@ -198,7 +198,7 @@ View* subbrute_attack_view_get_view(SubBruteAttackView* instance) { void subbrute_attack_view_set_current_step(SubBruteAttackView* instance, uint64_t current_step) { furi_assert(instance); #ifdef FURI_DEBUG - FURI_LOG_D(TAG, "Set step: %d", current_step); + //FURI_LOG_D(TAG, "Set step: %d", current_step); #endif with_view_model( instance->view, (SubBruteAttackViewModel * model) { From 7bd0c8ff2c57f6b9d33435799c3511ca1c96f218 Mon Sep 17 00:00:00 2001 From: derskythe Date: Mon, 26 Sep 2022 18:30:04 +0400 Subject: [PATCH 03/47] application.fam revert --- applications/main/application.fam | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/applications/main/application.fam b/applications/main/application.fam index 639640b72..a3d310093 100644 --- a/applications/main/application.fam +++ b/applications/main/application.fam @@ -4,17 +4,17 @@ App( apptype=FlipperAppType.METAPACKAGE, provides=[ "gpio", - #"ibutton", - #"infrared", - #"lfrfid", - #"nfc", + "ibutton", + "infrared", + "lfrfid", + "nfc", "subghz", - #"bad_usb", - #"u2f", + "bad_usb", + "u2f", "fap_loader", "archive", "clock", - #"unirfremix", + "unirfremix", ], ) From 9f501034c3240c3d9506cf07270aa4b0818e5e02 Mon Sep 17 00:00:00 2001 From: Shane Synan Date: Mon, 26 Sep 2022 11:34:59 -0400 Subject: [PATCH 04/47] Power: Also ask charger if charge done (#1378) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * power: Also ask charger if charge done * F7: bump API Symbols version * Lib: remove double include in bq25896.c Co-authored-by: あく --- applications/services/power/power_service/power.c | 2 +- firmware/targets/f7/api_symbols.csv | 3 ++- firmware/targets/f7/furi_hal/furi_hal_power.c | 7 +++++++ firmware/targets/furi_hal_include/furi_hal_power.h | 6 ++++++ lib/drivers/bq25896.c | 14 +++++++++++--- lib/drivers/bq25896.h | 8 ++++++++ 6 files changed, 35 insertions(+), 5 deletions(-) diff --git a/applications/services/power/power_service/power.c b/applications/services/power/power_service/power.c index 757d7718a..89886b0f8 100644 --- a/applications/services/power/power_service/power.c +++ b/applications/services/power/power_service/power.c @@ -96,7 +96,7 @@ void power_free(Power* power) { static void power_check_charging_state(Power* power) { if(furi_hal_power_is_charging()) { - if(power->info.charge == 100) { + if((power->info.charge == 100) || (furi_hal_power_is_charging_done())) { if(power->state != PowerStateCharged) { notification_internal_message(power->notification, &sequence_charged); power->state = PowerStateCharged; diff --git a/firmware/targets/f7/api_symbols.csv b/firmware/targets/f7/api_symbols.csv index c8e6a6cf4..c18780acb 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,+,1.11,, +Version,+,1.12,, Header,+,applications/services/bt/bt_service/bt.h,, Header,+,applications/services/cli/cli.h,, Header,+,applications/services/cli/cli_vcp.h,, @@ -1141,6 +1141,7 @@ Function,+,furi_hal_power_insomnia_enter,void, Function,+,furi_hal_power_insomnia_exit,void, Function,-,furi_hal_power_insomnia_level,uint16_t, Function,+,furi_hal_power_is_charging,_Bool, +Function,+,furi_hal_power_is_charging_done,_Bool, Function,+,furi_hal_power_is_otg_enabled,_Bool, Function,+,furi_hal_power_off,void, Function,+,furi_hal_power_reset,void, diff --git a/firmware/targets/f7/furi_hal/furi_hal_power.c b/firmware/targets/f7/furi_hal/furi_hal_power.c index 246383921..524fae0b1 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_power.c +++ b/firmware/targets/f7/furi_hal/furi_hal_power.c @@ -266,6 +266,13 @@ bool furi_hal_power_is_charging() { return ret; } +bool furi_hal_power_is_charging_done() { + furi_hal_i2c_acquire(&furi_hal_i2c_handle_power); + bool ret = bq25896_is_charging_done(&furi_hal_i2c_handle_power); + furi_hal_i2c_release(&furi_hal_i2c_handle_power); + return ret; +} + void furi_hal_power_shutdown() { furi_hal_power_insomnia_enter(); diff --git a/firmware/targets/furi_hal_include/furi_hal_power.h b/firmware/targets/furi_hal_include/furi_hal_power.h index 3ab30c424..f8eaa5c3a 100644 --- a/firmware/targets/furi_hal_include/furi_hal_power.h +++ b/firmware/targets/furi_hal_include/furi_hal_power.h @@ -85,6 +85,12 @@ uint8_t furi_hal_power_get_bat_health_pct(); */ bool furi_hal_power_is_charging(); +/** Get charge complete status + * + * @return true if done charging and connected to charger + */ +bool furi_hal_power_is_charging_done(); + /** Switch MCU to SHUTDOWN */ void furi_hal_power_shutdown(); diff --git a/lib/drivers/bq25896.c b/lib/drivers/bq25896.c index 73135d93a..1fb9d53e7 100644 --- a/lib/drivers/bq25896.c +++ b/lib/drivers/bq25896.c @@ -1,5 +1,4 @@ #include "bq25896.h" -#include "bq25896_reg.h" #include @@ -81,7 +80,7 @@ void bq25896_poweroff(FuriHalI2cBusHandle* handle) { handle, BQ25896_ADDRESS, 0x09, *(uint8_t*)&bq25896_regs.r09, BQ25896_I2C_TIMEOUT); } -bool bq25896_is_charging(FuriHalI2cBusHandle* handle) { +ChrgStat bq25896_get_charge_status(FuriHalI2cBusHandle* handle) { furi_hal_i2c_read_mem( handle, BQ25896_ADDRESS, @@ -91,7 +90,16 @@ bool bq25896_is_charging(FuriHalI2cBusHandle* handle) { BQ25896_I2C_TIMEOUT); furi_hal_i2c_read_reg_8( handle, BQ25896_ADDRESS, 0x0B, (uint8_t*)&bq25896_regs.r0B, BQ25896_I2C_TIMEOUT); - return bq25896_regs.r0B.CHRG_STAT != ChrgStatNo; + return bq25896_regs.r0B.CHRG_STAT; +} + +bool bq25896_is_charging(FuriHalI2cBusHandle* handle) { + // Include precharge, fast charging, and charging termination done as "charging" + return bq25896_get_charge_status(handle) != ChrgStatNo; +} + +bool bq25896_is_charging_done(FuriHalI2cBusHandle* handle) { + return bq25896_get_charge_status(handle) == ChrgStatDone; } void bq25896_enable_charging(FuriHalI2cBusHandle* handle) { diff --git a/lib/drivers/bq25896.h b/lib/drivers/bq25896.h index 39d343c33..c8da0a064 100644 --- a/lib/drivers/bq25896.h +++ b/lib/drivers/bq25896.h @@ -1,5 +1,7 @@ #pragma once +#include "bq25896_reg.h" + #include #include #include @@ -10,9 +12,15 @@ void bq25896_init(FuriHalI2cBusHandle* handle); /** Send device into shipping mode */ void bq25896_poweroff(FuriHalI2cBusHandle* handle); +/** Get charging status */ +ChrgStat bq25896_get_charge_status(FuriHalI2cBusHandle* handle); + /** Is currently charging */ bool bq25896_is_charging(FuriHalI2cBusHandle* handle); +/** Is charging completed while connected to charger */ +bool bq25896_is_charging_done(FuriHalI2cBusHandle* handle); + /** Enable charging */ void bq25896_enable_charging(FuriHalI2cBusHandle* handle); From f201062819d75035e4e5529e6cb33015e652f59e Mon Sep 17 00:00:00 2001 From: phreakocious Date: Mon, 26 Sep 2022 10:42:29 -0500 Subject: [PATCH 05/47] Add Hisense A/C IR signals.. (#1773) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * add Hisense A/C IR signals.. note that using any will toggle the power and apply the settings * re-order the entries to be grouped by function 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 b1075b2f3..49586b555 100644 --- a/assets/resources/infrared/assets/ac.ir +++ b/assets/resources/infrared/assets/ac.ir @@ -7,32 +7,68 @@ frequency: 38000 duty_cycle: 0.33 data: 502 3436 510 475 509 476 508 477 507 477 507 479 505 480 504 480 504 490 504 481 502 482 501 483 563 420 511 474 510 475 509 476 508 485 561 423 508 476 508 477 507 478 506 479 505 480 504 481 503 517 508 476 508 478 506 479 505 479 505 481 503 483 521 1456 501 498 507 479 505 480 504 481 503 482 501 483 563 421 562 422 509 499 506 479 505 480 504 481 503 482 502 484 510 1451 506 479 505 1542 562 1396 509 471 502 476 508 469 504 3425 511 # +name: Off +type: raw +frequency: 38000 +duty_cycle: 0.330000 +data: 8974 4505 598 1647 595 1651 591 539 592 542 600 537 594 547 595 549 593 1662 591 532 599 1649 593 1659 594 540 602 538 593 548 594 552 600 535 596 528 593 535 596 536 595 540 602 538 593 548 593 551 601 532 599 525 596 1651 591 539 592 543 599 1660 593 1669 594 1672 601 533 598 526 595 533 598 533 598 536 595 543 599 543 599 547 595 540 602 524 597 530 601 530 601 534 597 541 601 541 601 545 597 522 599 7938 591 532 599 528 593 537 594 541 601 537 594 546 596 549 593 1663 600 524 597 530 601 530 601 533 598 540 591 550 592 553 599 536 595 528 593 536 595 536 595 540 591 547 595 548 593 552 600 535 596 529 592 536 595 535 596 538 593 545 597 546 596 550 592 542 600 524 597 531 600 531 600 534 597 542 600 542 600 545 597 538 593 530 601 526 595 537 594 540 591 547 595 546 595 550 592 543 599 526 595 532 599 531 601 535 596 542 600 542 600 546 596 538 593 531 600 1648 594 536 595 539 592 1669 594 1669 594 1671 602 1637 595 7947 592 532 599 529 592 539 592 543 599 540 591 551 601 544 598 537 594 531 600 1647 595 535 596 539 592 545 597 546 596 550 592 543 599 526 595 533 598 534 597 538 593 545 597 546 596 550 602 534 597 527 594 533 598 533 598 536 595 544 598 543 599 547 595 540 591 533 598 529 592 539 592 1663 600 538 593 547 595 551 591 543 599 524 597 530 591 539 592 542 600 537 594 547 595 550 592 542 600 525 596 1651 592 538 593 1662 591 546 596 545 597 548 594 523 629 +# name: Dh type: raw frequency: 38000 duty_cycle: 0.33 data: 507 3430 506 479 505 480 504 481 503 481 503 483 501 485 509 1453 504 1465 503 482 502 483 511 473 500 485 509 476 508 477 507 478 506 487 507 477 507 478 506 479 505 480 504 482 502 483 501 484 500 523 503 482 502 484 500 485 509 476 508 476 508 478 506 1456 501 501 504 482 502 483 501 484 500 485 509 476 508 477 507 1455 502 509 506 479 505 1457 500 485 509 476 508 1454 503 482 502 483 501 568 499 1459 509 1450 507 471 502 474 510 3421 505 # +name: Dh +type: raw +frequency: 38000 +duty_cycle: 0.330000 +data: 8990 4494 599 1648 595 1654 599 533 598 537 594 544 598 544 598 548 594 1662 601 523 598 1651 592 1660 593 542 600 539 593 550 592 553 599 536 596 527 594 531 601 1648 595 538 593 542 600 540 592 551 601 532 600 1643 600 1650 593 538 593 542 600 1660 593 1671 592 1673 601 534 598 527 594 534 597 533 599 536 595 543 599 542 600 545 597 537 595 530 591 536 596 535 596 538 593 544 598 543 599 546 596 522 599 7935 595 530 591 536 596 536 596 539 592 545 597 544 598 547 595 1660 593 530 591 536 596 535 596 536 595 542 600 541 591 552 600 534 597 525 596 531 601 529 592 541 601 537 595 546 596 548 594 540 591 532 600 527 594 536 595 538 594 544 598 543 599 546 596 538 594 531 600 527 594 536 595 539 593 545 597 543 599 546 596 538 593 530 591 535 596 532 599 532 600 536 595 543 599 544 598 535 596 525 596 530 591 538 593 538 593 542 600 540 591 551 601 532 600 1640 593 1651 592 1655 598 535 596 1657 596 1663 601 1661 592 1641 592 7941 599 526 595 533 599 532 600 535 597 541 601 541 601 544 598 537 595 1651 592 535 597 535 597 538 594 545 597 545 597 548 594 540 592 532 600 528 593 539 593 542 600 539 592 549 593 551 601 533 598 524 597 528 593 536 595 538 593 544 598 543 599 546 596 539 593 531 601 528 593 538 593 1661 592 546 596 545 597 547 595 539 592 532 600 527 594 536 596 538 593 543 599 542 600 544 598 535 596 1646 597 531 601 529 592 1663 601 537 595 547 595 550 592 524 597 +# name: Cool_hi type: raw frequency: 38000 duty_cycle: 0.33 data: 504 3433 503 482 502 484 510 474 510 475 509 476 508 478 506 1456 564 1405 510 475 509 476 508 502 482 477 507 478 506 479 505 480 504 489 505 480 504 481 503 482 502 483 511 473 511 474 510 475 509 509 506 479 505 480 504 481 503 482 512 473 511 474 510 476 508 1469 509 475 509 476 508 477 507 478 506 479 505 480 504 481 503 505 510 475 509 502 482 503 481 504 480 505 478 507 477 1459 509 560 507 1451 506 473 511 493 480 1450 507 3422 503 # +name: Cool_hi +type: raw +frequency: 38000 +duty_cycle: 0.330000 +data: 8982 4489 604 1643 600 1649 594 537 594 540 602 537 594 547 595 550 592 1664 599 525 596 1652 601 1651 592 542 600 538 593 549 593 552 600 534 597 1646 597 530 601 1651 602 534 597 541 601 541 601 544 598 537 594 529 592 1655 598 533 598 536 595 542 600 542 600 546 596 539 592 532 599 527 594 537 594 540 591 546 596 545 597 548 594 540 602 523 598 529 592 539 592 542 600 539 592 549 593 550 592 524 597 7929 600 525 596 532 599 533 598 537 594 543 599 542 600 544 598 1654 599 524 597 530 591 538 593 540 591 544 598 543 599 544 598 535 596 526 595 531 600 529 592 544 598 541 601 542 600 546 596 540 602 522 599 529 602 530 601 534 597 541 601 541 601 545 597 539 592 532 599 528 593 539 592 541 601 537 594 547 595 551 601 535 596 529 592 536 595 537 594 541 601 538 593 549 593 553 599 536 595 529 592 536 595 534 597 537 594 544 598 543 599 546 596 539 592 1653 600 1650 593 1660 593 543 599 541 601 541 601 546 596 1643 600 7943 596 529 602 527 594 538 593 541 601 538 593 549 593 553 599 536 595 1649 594 535 596 535 596 539 592 546 596 546 596 549 593 542 600 525 596 531 600 530 601 533 598 540 602 539 592 552 600 535 596 527 594 533 598 533 598 536 595 543 599 543 599 545 597 537 594 530 601 526 595 536 595 1660 593 546 596 547 595 550 602 533 598 526 595 533 598 534 597 538 593 546 596 547 595 551 601 534 597 1647 596 532 599 532 599 1656 597 541 601 542 600 545 597 522 599 +# name: Cool_lo type: raw frequency: 38000 duty_cycle: 0.33 data: 525 3615 530 506 561 474 562 474 562 473 563 473 531 505 562 1502 528 1542 562 474 562 474 530 505 531 504 532 504 532 504 616 419 533 510 589 447 526 509 527 509 527 509 527 508 528 508 528 507 529 542 525 510 526 509 527 509 527 509 527 508 528 508 528 1535 527 524 533 503 533 503 533 502 534 502 534 502 534 501 535 501 525 534 533 502 534 502 534 501 535 502 534 1529 533 503 533 503 533 587 533 497 528 501 524 1536 526 501 524 3609 526 # +name: Cool_lo +type: raw +frequency: 38000 +duty_cycle: 0.330000 +data: 8967 4495 597 1645 597 1648 594 535 596 537 594 542 600 541 601 543 599 1655 598 525 596 1651 592 1658 595 539 592 545 597 544 598 546 596 538 593 1648 595 532 599 1648 594 539 592 545 597 543 599 545 597 536 595 528 593 1651 592 538 593 541 601 1654 599 1661 592 1671 592 541 601 523 598 529 592 538 593 541 601 536 595 544 598 547 595 539 592 531 600 526 595 535 596 537 594 543 599 541 601 543 598 518 593 7937 602 522 599 528 593 537 594 539 592 545 597 544 598 546 596 1656 597 525 596 530 601 528 593 539 592 544 598 543 599 544 598 535 596 526 595 531 600 530 601 532 599 538 593 547 595 549 593 540 602 521 600 526 595 535 596 537 594 543 599 541 601 543 599 536 595 527 594 532 600 530 601 532 599 538 593 546 596 548 594 539 592 531 600 525 596 534 597 535 596 540 591 549 593 551 601 532 599 524 597 529 592 537 594 538 593 543 599 540 591 551 601 532 599 1641 591 1654 599 1650 593 540 591 1664 599 1660 593 1671 592 1643 600 7922 596 528 593 533 598 532 599 535 596 540 591 549 593 552 600 533 598 1644 599 529 592 538 593 539 592 544 598 541 590 550 592 539 592 528 593 531 590 537 594 536 595 539 592 546 596 546 596 536 595 526 595 529 592 535 596 535 596 538 593 546 596 546 596 535 596 524 597 527 594 533 598 1649 593 541 601 538 593 549 593 538 593 528 593 532 599 528 593 539 592 542 600 538 593 548 594 538 593 1643 599 525 596 532 599 1649 593 541 601 538 593 548 594 520 591 +# name: Heat_hi type: raw frequency: 38000 duty_cycle: 0.33 data: 531 3406 530 455 529 456 528 457 537 447 537 448 535 450 534 1429 528 1442 536 448 536 449 534 451 532 452 532 453 530 454 530 455 529 464 530 454 529 456 528 457 537 448 536 449 535 450 533 451 533 490 535 449 534 450 534 451 533 452 532 453 531 455 529 1433 534 1443 535 449 535 450 534 452 531 453 530 454 530 455 529 456 538 472 532 452 532 454 530 1433 535 1427 530 1432 536 1427 530 1431 537 1511 530 448 536 1422 535 1423 534 1422 535 3395 530 # +name: Heat_hi +type: raw +frequency: 38000 +duty_cycle: 0.330000 +data: 8970 4496 597 1648 595 1652 601 530 602 533 598 541 601 541 601 543 599 1652 601 523 598 1649 594 1656 597 538 593 545 597 545 597 549 593 541 601 523 598 529 592 1658 595 540 592 546 596 545 597 548 594 541 601 523 598 529 592 539 593 542 600 538 593 1668 595 1670 593 1662 591 533 599 529 592 539 593 542 600 538 593 547 595 549 593 542 600 524 597 530 602 529 592 543 599 539 593 549 593 551 601 516 595 7937 593 532 599 527 594 536 596 539 592 546 596 545 597 548 594 1661 592 532 600 528 593 538 593 541 601 537 594 547 595 550 602 533 599 526 595 533 599 533 599 536 595 543 599 541 601 544 598 536 595 529 592 535 596 535 596 538 594 544 598 544 598 547 595 541 601 523 598 528 593 537 594 540 602 536 595 546 596 550 602 533 598 526 595 532 600 531 600 534 597 541 601 541 601 545 597 539 593 532 600 528 593 538 593 541 601 537 594 547 595 550 602 532 599 523 598 527 594 1653 600 533 598 538 593 1664 599 1662 591 523 598 7926 593 529 592 534 597 532 599 534 597 538 593 546 596 547 595 537 594 1648 595 532 600 532 599 536 595 543 599 543 599 546 596 540 602 522 599 529 592 538 594 541 601 536 595 546 596 549 593 542 600 523 598 529 592 538 593 541 601 538 593 548 594 552 600 534 597 527 594 534 597 534 597 1657 596 543 599 543 599 548 594 542 600 524 597 530 601 530 602 533 598 538 593 547 595 551 601 533 599 1644 599 528 593 538 593 1661 592 545 597 545 597 548 594 524 597 +# name: Heat_lo type: raw frequency: 38000 duty_cycle: 0.33 data: 506 3430 506 478 506 479 505 480 504 481 503 482 502 484 500 1463 505 1465 503 482 502 483 501 484 500 485 509 476 508 477 507 478 506 486 508 477 507 478 506 479 505 480 504 481 503 482 502 483 500 523 502 482 502 483 501 484 500 485 509 476 508 478 506 1455 502 498 507 478 506 479 505 481 503 482 501 483 500 484 500 485 509 500 505 481 502 482 502 1461 507 1455 502 1459 509 476 508 477 507 563 504 1453 504 1454 503 1454 503 1453 504 3426 499 +# +name: Heat_lo +type: raw +frequency: 38000 +duty_cycle: 0.330000 +data: 8972 4491 592 1651 592 1655 598 532 599 535 597 542 600 541 601 544 598 1656 597 526 595 1652 591 1658 595 539 593 545 597 545 597 546 596 537 594 529 592 535 596 1653 600 534 597 541 601 539 592 552 600 533 598 525 596 530 591 538 593 539 592 1665 598 1662 591 1673 601 533 598 526 595 533 598 532 600 534 597 540 591 548 594 550 592 542 600 523 598 528 593 536 595 537 594 543 599 542 600 543 599 517 594 7937 593 531 601 526 595 535 597 537 594 542 600 541 601 543 599 1654 599 523 598 528 593 536 596 538 594 542 600 541 590 552 600 532 599 524 597 528 593 536 595 537 595 541 601 539 593 551 591 542 600 522 599 527 594 536 595 537 594 543 599 540 591 552 600 532 600 523 598 527 594 535 596 537 595 542 600 540 591 552 600 532 600 523 598 528 593 536 595 538 593 543 599 541 601 543 599 535 596 527 594 532 600 531 601 534 597 540 592 549 593 552 600 534 597 525 596 529 592 1655 598 534 597 1656 597 1661 592 1671 592 1644 599 7934 596 529 592 535 597 535 597 538 593 544 598 543 599 545 597 538 593 1650 593 535 596 534 597 536 595 540 591 547 595 547 595 536 595 526 595 529 592 536 595 535 596 539 593 546 596 547 595 538 593 528 593 531 601 529 592 541 601 536 596 545 597 548 594 540 592 532 600 526 595 535 596 1656 597 541 601 540 592 553 599 534 597 526 595 532 599 531 600 533 598 539 593 548 594 552 600 535 596 1647 596 531 590 538 593 1656 597 538 594 545 597 545 597 518 593 From 5bb7cabea6cb02ce2ad281484da70db4e83d2df1 Mon Sep 17 00:00:00 2001 From: Sergey Gavrilov Date: Tue, 27 Sep 2022 01:59:28 +1000 Subject: [PATCH 06/47] Applications loader: do not use view dispatcher queue #1788 --- applications/main/fap_loader/fap_loader_app.c | 21 +++++++++++-------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/applications/main/fap_loader/fap_loader_app.c b/applications/main/fap_loader/fap_loader_app.c index 9050ddf78..c0f60ceca 100644 --- a/applications/main/fap_loader/fap_loader_app.c +++ b/applications/main/fap_loader/fap_loader_app.c @@ -15,6 +15,9 @@ typedef struct { DialogsApp* dialogs; Gui* gui; string_t fap_path; + + ViewDispatcher* view_dispatcher; + Loading* loading; } FapLoader; static bool @@ -144,12 +147,12 @@ int32_t fap_loader_app(void* p) { loader->dialogs = furi_record_open(RECORD_DIALOGS); loader->gui = furi_record_open(RECORD_GUI); - ViewDispatcher* view_dispatcher = view_dispatcher_alloc(); - Loading* loading = loading_alloc(); + loader->view_dispatcher = view_dispatcher_alloc(); + loader->loading = loading_alloc(); - view_dispatcher_enable_queue(view_dispatcher); - view_dispatcher_attach_to_gui(view_dispatcher, loader->gui, ViewDispatcherTypeFullscreen); - view_dispatcher_add_view(view_dispatcher, 0, loading_get_view(loading)); + view_dispatcher_attach_to_gui( + loader->view_dispatcher, loader->gui, ViewDispatcherTypeFullscreen); + view_dispatcher_add_view(loader->view_dispatcher, 0, loading_get_view(loader->loading)); if(p) { string_init_set(loader->fap_path, (const char*)p); @@ -158,14 +161,14 @@ int32_t fap_loader_app(void* p) { string_init_set(loader->fap_path, EXT_PATH("apps")); while(fap_loader_select_app(loader)) { - view_dispatcher_switch_to_view(view_dispatcher, 0); + view_dispatcher_switch_to_view(loader->view_dispatcher, 0); fap_loader_run_selected_app(loader); }; } - view_dispatcher_remove_view(view_dispatcher, 0); - loading_free(loading); - view_dispatcher_free(view_dispatcher); + view_dispatcher_remove_view(loader->view_dispatcher, 0); + loading_free(loader->loading); + view_dispatcher_free(loader->view_dispatcher); string_clear(loader->fap_path); furi_record_close(RECORD_GUI); From a58807c57a16d4b34882b2b14a2763d6074f7355 Mon Sep 17 00:00:00 2001 From: derskythe Date: Mon, 26 Sep 2022 20:14:33 +0400 Subject: [PATCH 07/47] Add SubGhzTxRxWorker for later use --- .../subbrute/helpers/subbrute_worker.c | 125 +++++++----------- .../subbrute/helpers/subbrute_worker.h | 11 +- .../scenes/subbrute_scene_run_attack.c | 104 ++++++++++----- .../scenes/subbrute_scene_setup_attack.c | 16 ++- .../plugins/subbrute/subbrute_custom_event.h | 1 + .../subbrute/views/subbrute_attack_view.c | 58 +++++--- .../subbrute/views/subbrute_attack_view.h | 2 +- 7 files changed, 180 insertions(+), 137 deletions(-) diff --git a/applications/plugins/subbrute/helpers/subbrute_worker.c b/applications/plugins/subbrute/helpers/subbrute_worker.c index 0b8441df5..e12d7c9f6 100644 --- a/applications/plugins/subbrute/helpers/subbrute_worker.c +++ b/applications/plugins/subbrute/helpers/subbrute_worker.c @@ -3,14 +3,16 @@ #include #include #include +#include #define TAG "SubBruteWorker" struct SubBruteWorker { -// FuriThread* thread; + SubGhzTxRxWorker* subghz_txrx; volatile bool worker_running; volatile bool worker_manual_mode; bool is_manual_init; + bool is_continuous_worker; SubGhzEnvironment* environment; SubGhzTransmitter* transmitter; @@ -31,80 +33,25 @@ struct SubBruteWorker { #define SUBBRUTE_TXRX_WORKER_BUF_SIZE 2048 #define SUBBRUTE_TXRX_WORKER_MAX_TXRX_SIZE 60 #define SUBBRUTE_TXRX_WORKER_TIMEOUT_READ_WRITE_BUF 40 -#define SUBBRUTE_TX_TIMEOUT 10 -#define SUBBRUTE_SEND_DELAY 260 - -/** - * Entrypoint for worker - * - * @param context SubBruteWorker* - * @return 0 if ok - */ -int32_t subbrute_worker_thread(void* context) { - furi_assert(context); - SubBruteWorker* instance = (SubBruteWorker*)context; - - if(!instance->worker_running) { - FURI_LOG_W(TAG, "Worker is not set to running state!"); - return -1; - } -#ifdef FURI_DEBUG - FURI_LOG_I(TAG, "Worker start"); -#endif - - instance->environment = subghz_environment_alloc(); - instance->transmitter = subghz_transmitter_alloc_init( - instance->environment, string_get_cstr(instance->protocol_name)); - - furi_hal_subghz_reset(); - furi_hal_subghz_load_preset(instance->preset); - instance->frequency = furi_hal_subghz_set_frequency_and_path(instance->frequency); - - furi_hal_gpio_init(&gpio_cc1101_g0, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow); - furi_hal_gpio_write(&gpio_cc1101_g0, true); - - // Set ready to transmit value - instance->last_time_tx_data = furi_get_tick() - SUBBRUTE_SEND_DELAY; - - while(instance->worker_running) { - // Transmit - if(!furi_hal_subghz_tx()) { - FURI_LOG_E(TAG, "Cannot transmit!"); - break; - } - furi_delay_ms(SUBBRUTE_TX_TIMEOUT); - } - - furi_hal_subghz_set_path(FuriHalSubGhzPathIsolate); - furi_hal_subghz_sleep(); - - subghz_transmitter_free(instance->transmitter); - instance->transmitter = NULL; - subghz_environment_free(instance->environment); - instance->environment = NULL; - -#ifdef FURI_DEBUG - FURI_LOG_I(TAG, "Worker stop"); -#endif - return 0; -} +#define SUBBRUTE_TX_TIMEOUT 5 +#define SUBBRUTE_SEND_DELAY 20 SubBruteWorker* subbrute_worker_alloc() { SubBruteWorker* instance = malloc(sizeof(SubBruteWorker)); -// instance->thread = furi_thread_alloc(); -// furi_thread_set_name(instance->thread, "SubBruteAttackWorker"); -// furi_thread_set_stack_size(instance->thread, 2048); -// furi_thread_set_context(instance->thread, instance); -// furi_thread_set_callback(instance->thread, subbrute_worker_thread); - //instance->status = SubBruteWorkerStatusIDLE; instance->worker_running = false; instance->worker_manual_mode = false; + instance->environment = NULL; + instance->transmitter = NULL; + instance->flipper_format = flipper_format_string_alloc(); string_init(instance->protocol_name); + // SubGhzTxRxWorker + instance->subghz_txrx = subghz_tx_rx_worker_alloc(); + return instance; } @@ -122,11 +69,13 @@ void subbrute_worker_free(SubBruteWorker* instance) { instance->environment = NULL; } -// furi_thread_free(instance->thread); flipper_format_free(instance->flipper_format); string_clear(instance->protocol_name); + // SubGhzTxRxWorker + subghz_tx_rx_worker_free(instance->subghz_txrx); + free(instance); } @@ -138,6 +87,7 @@ bool subbrute_worker_start( furi_assert(instance); if(instance->worker_manual_mode) { + FURI_LOG_W(TAG, "Invalid mode for starting worker!"); return false; } @@ -166,9 +116,10 @@ bool subbrute_worker_start( FURI_LOG_I(TAG, "Frequency: %d", frequency); #endif instance->preset = preset; - -// furi_thread_start(instance->thread); - + if(res) { + instance->worker_running = res = + subghz_tx_rx_worker_start(instance->subghz_txrx, frequency); + } return res; } @@ -177,10 +128,21 @@ void subbrute_worker_stop(SubBruteWorker* instance) { instance->worker_running = false; -// furi_thread_join(instance->thread); + if(subghz_tx_rx_worker_is_running(instance->subghz_txrx)) { + subghz_tx_rx_worker_stop(instance->subghz_txrx); + } +} - furi_hal_subghz_set_path(FuriHalSubGhzPathIsolate); - furi_hal_subghz_sleep(); +void subbrute_worker_set_continuous_worker(SubBruteWorker* instance, bool is_continuous_worker) { + furi_assert(instance); + + instance->is_continuous_worker = is_continuous_worker; +} + +bool subbrute_worker_get_continuous_worker(SubBruteWorker* instance) { + furi_assert(instance); + + return instance->is_continuous_worker; } bool subbrute_worker_is_running(SubBruteWorker* instance) { @@ -216,14 +178,20 @@ bool subbrute_worker_transmit(SubBruteWorker* instance, const char* payload) { //FURI_LOG_D(TAG, "payload: %s", payload); #endif - Stream* stream = flipper_format_get_raw_stream(instance->flipper_format); - stream_clean(stream); - stream_write_cstring(stream, payload); - subghz_transmitter_deserialize(instance->transmitter, instance->flipper_format); + while(!subghz_tx_rx_worker_write(instance->subghz_txrx, (uint8_t*)payload, strlen(payload))) { + furi_delay_ms(10); + } + + furi_hal_subghz_flush_tx(); + // Stream* stream = flipper_format_get_raw_stream(instance->flipper_format); + // stream_clean(stream); + // stream_write_cstring(stream, payload); + // subghz_transmitter_deserialize(instance->transmitter, instance->flipper_format); return true; } +// Init MANUAL bool subbrute_worker_init_manual_transmit( SubBruteWorker* instance, uint32_t frequency, @@ -236,7 +204,8 @@ bool subbrute_worker_init_manual_transmit( frequency, protocol_name); #endif - if(instance->worker_manual_mode || !subbrute_worker_can_transmit(instance)) { + if(instance->worker_manual_mode || !subbrute_worker_can_manual_transmit(instance) || + instance->worker_running) { #ifdef FURI_DEBUG FURI_LOG_D(TAG, "cannot transmit"); #endif @@ -332,9 +301,7 @@ bool subbrute_worker_manual_transmit(SubBruteWorker* instance, const char* paylo return false; } if(instance->worker_running) { -#ifdef FURI_DEBUG - FURI_LOG_D(TAG, "subbrute_worker_stop"); -#endif + FURI_LOG_W(TAG, "Worker was working for manual mode. Shutdown thread"); subbrute_worker_stop(instance); } if(!instance->is_manual_init) { diff --git a/applications/plugins/subbrute/helpers/subbrute_worker.h b/applications/plugins/subbrute/helpers/subbrute_worker.h index be22b69ee..3338657d1 100644 --- a/applications/plugins/subbrute/helpers/subbrute_worker.h +++ b/applications/plugins/subbrute/helpers/subbrute_worker.h @@ -23,14 +23,17 @@ bool subbrute_worker_start( FuriHalSubGhzPreset preset, const char* protocol_name); void subbrute_worker_stop(SubBruteWorker* instance); +bool subbrute_worker_get_continuous_worker(SubBruteWorker* instance); +void subbrute_worker_set_continuous_worker(SubBruteWorker* instance, bool is_continuous_worker); //bool subbrute_worker_write(SubBruteWorker* instance, uint8_t* data, size_t size); bool subbrute_worker_is_running(SubBruteWorker* instance); bool subbrute_worker_can_transmit(SubBruteWorker* instance); bool subbrute_worker_can_manual_transmit(SubBruteWorker* instance); bool subbrute_worker_transmit(SubBruteWorker* instance, const char* payload); -bool subbrute_worker_init_manual_transmit(SubBruteWorker* instance, - uint32_t frequency, - FuriHalSubGhzPreset preset, - const char* protocol_name); +bool subbrute_worker_init_manual_transmit( + SubBruteWorker* instance, + uint32_t frequency, + FuriHalSubGhzPreset preset, + const char* protocol_name); bool subbrute_worker_manual_transmit(SubBruteWorker* instance, const char* payload); void subbrute_worker_manual_transmit_stop(SubBruteWorker* instance); \ No newline at end of file diff --git a/applications/plugins/subbrute/scenes/subbrute_scene_run_attack.c b/applications/plugins/subbrute/scenes/subbrute_scene_run_attack.c index af174dd27..5f5ba3e27 100644 --- a/applications/plugins/subbrute/scenes/subbrute_scene_run_attack.c +++ b/applications/plugins/subbrute/scenes/subbrute_scene_run_attack.c @@ -59,6 +59,10 @@ void subbrute_scene_run_attack_on_exit(void* context) { // furi_timer_free(state->timer); // free(state); + if(subbrute_worker_get_continuous_worker(instance->worker)) { + subbrute_worker_stop(instance->worker); + } + notification_message(instance->notifications, &sequence_blink_stop); } @@ -82,18 +86,29 @@ void subbrute_scene_run_attack_on_enter(void* context) { instance->device->key_index, true); - // Init worker with values - if(!subbrute_worker_init_manual_transmit( - instance->worker, - instance->device->frequency, - instance->device->preset, - string_get_cstr(instance->device->protocol_name))) { - FURI_LOG_W(TAG, "Worker init failed!"); - } + if(subbrute_worker_get_continuous_worker(instance->worker)) { + // Init Continuous worker with values! + if(!subbrute_worker_start( + instance->worker, + instance->device->frequency, + instance->device->preset, + string_get_cstr(instance->device->protocol_name))) { + FURI_LOG_W(TAG, "Worker Continuous init failed!"); + } + } else { + // Init worker with values + if(!subbrute_worker_init_manual_transmit( + instance->worker, + instance->device->frequency, + instance->device->preset, + string_get_cstr(instance->device->protocol_name))) { + FURI_LOG_W(TAG, "Worker init failed!"); + } - // state->timer = furi_timer_alloc( - // subbrute_scene_run_attack_worker_callback, FuriTimerTypePeriodic, instance); - // furi_timer_start(state->timer, pdMS_TO_TICKS(100)); // 20 ms + // state->timer = furi_timer_alloc( + // subbrute_scene_run_attack_worker_callback, FuriTimerTypePeriodic, instance); + // furi_timer_start(state->timer, pdMS_TO_TICKS(100)); // 20 ms + } } bool subbrute_scene_run_attack_on_event(void* context, SceneManagerEvent event) { @@ -116,33 +131,60 @@ bool subbrute_scene_run_attack_on_event(void* context, SceneManagerEvent event) scene_manager_search_and_switch_to_previous_scene( instance->scene_manager, SubBruteSceneSetupAttack); consumed = true; - } else if (event.event == SubBruteCustomEventTypeUpdateView) { + } else if(event.event == SubBruteCustomEventTypeUpdateView) { subbrute_attack_view_set_current_step(view, instance->device->key_index); } } else if(event.type == SceneManagerEventTypeTick) { - if(subbrute_worker_can_manual_transmit(instance->worker)) { - // Blink - notification_message(instance->notifications, &sequence_blink_yellow_100); + if(subbrute_worker_get_continuous_worker(instance->worker)) { + if(subbrute_worker_can_transmit(instance->worker)) { + // Blink + notification_message(instance->notifications, &sequence_blink_yellow_100); - subbrute_device_create_packet_parsed( - instance->device, instance->device->key_index, true); + subbrute_device_create_packet_parsed( + instance->device, instance->device->key_index, true); - if(subbrute_worker_manual_transmit(instance->worker, instance->device->payload)) { - // Make payload for new iteration or exit - if(instance->device->key_index + 1 > instance->device->max_value) { - // End of list - view_dispatcher_send_custom_event( - instance->view_dispatcher, SubBruteCustomEventTypeTransmitFinished); - } else { - instance->device->key_index++; - view_dispatcher_send_custom_event( - instance->view_dispatcher, SubBruteCustomEventTypeUpdateView); - //subbrute_attack_view_set_current_step(view, instance->device->key_index); + if(subbrute_worker_transmit(instance->worker, instance->device->payload)) { + // Make payload for new iteration or exit + if(instance->device->key_index + 1 > instance->device->max_value) { + // End of list + view_dispatcher_send_custom_event( + instance->view_dispatcher, SubBruteCustomEventTypeTransmitFinished); + } else { + instance->device->key_index++; + view_dispatcher_send_custom_event( + instance->view_dispatcher, SubBruteCustomEventTypeUpdateView); + //subbrute_attack_view_set_current_step(view, instance->device->key_index); + } } - } - // Stop - notification_message(instance->notifications, &sequence_blink_stop); + // Stop + notification_message(instance->notifications, &sequence_blink_stop); + } + } else { + if(subbrute_worker_can_manual_transmit(instance->worker)) { + // Blink + notification_message(instance->notifications, &sequence_blink_yellow_100); + + subbrute_device_create_packet_parsed( + instance->device, instance->device->key_index, true); + + if(subbrute_worker_manual_transmit(instance->worker, instance->device->payload)) { + // Make payload for new iteration or exit + if(instance->device->key_index + 1 > instance->device->max_value) { + // End of list + view_dispatcher_send_custom_event( + instance->view_dispatcher, SubBruteCustomEventTypeTransmitFinished); + } else { + instance->device->key_index++; + view_dispatcher_send_custom_event( + instance->view_dispatcher, SubBruteCustomEventTypeUpdateView); + //subbrute_attack_view_set_current_step(view, instance->device->key_index); + } + } + + // Stop + notification_message(instance->notifications, &sequence_blink_stop); + } } consumed = true; diff --git a/applications/plugins/subbrute/scenes/subbrute_scene_setup_attack.c b/applications/plugins/subbrute/scenes/subbrute_scene_setup_attack.c index e2186ce49..c645a899a 100644 --- a/applications/plugins/subbrute/scenes/subbrute_scene_setup_attack.c +++ b/applications/plugins/subbrute/scenes/subbrute_scene_setup_attack.c @@ -28,10 +28,10 @@ void subbrute_scene_setup_attack_on_enter(void* context) { false); if(!subbrute_worker_init_manual_transmit( - instance->worker, - instance->device->frequency, - instance->device->preset, - string_get_cstr(instance->device->protocol_name))) { + instance->worker, + instance->device->frequency, + instance->device->preset, + string_get_cstr(instance->device->protocol_name))) { FURI_LOG_W(TAG, "Worker init failed!"); } @@ -57,7 +57,13 @@ bool subbrute_scene_setup_attack_on_event(void* context, SceneManagerEvent event if(event.type == SceneManagerEventTypeCustom) { if(event.event == SubBruteCustomEventTypeTransmitStarted) { - subbrute_device_create_packet_parsed(instance->device, instance->device->key_index, false); + subbrute_worker_set_continuous_worker(instance->worker, false); + subbrute_attack_view_set_worker_type(view, false); + scene_manager_next_scene(instance->scene_manager, SubBruteSceneRunAttack); + } else if(event.event == SubBruteCustomEventTypeTransmitContinuousStarted) { + // Setting different type of worker + subbrute_worker_set_continuous_worker(instance->worker, true); + subbrute_attack_view_set_worker_type(view, true); scene_manager_next_scene(instance->scene_manager, SubBruteSceneRunAttack); } else if(event.event == SubBruteCustomEventTypeSaveFile) { subbrute_worker_manual_transmit_stop(instance->worker); diff --git a/applications/plugins/subbrute/subbrute_custom_event.h b/applications/plugins/subbrute/subbrute_custom_event.h index 8be1a4469..800d8f5e0 100644 --- a/applications/plugins/subbrute/subbrute_custom_event.h +++ b/applications/plugins/subbrute/subbrute_custom_event.h @@ -10,6 +10,7 @@ typedef enum { SubBruteCustomEventTypeBackPressed, SubBruteCustomEventTypeIndexSelected, SubBruteCustomEventTypeTransmitStarted, + SubBruteCustomEventTypeTransmitContinuousStarted, SubBruteCustomEventTypeTransmitFinished, SubBruteCustomEventTypeTransmitNotStarted, SubBruteCustomEventTypeTransmitCustom, diff --git a/applications/plugins/subbrute/views/subbrute_attack_view.c b/applications/plugins/subbrute/views/subbrute_attack_view.c index 97eca6a66..12c849b43 100644 --- a/applications/plugins/subbrute/views/subbrute_attack_view.c +++ b/applications/plugins/subbrute/views/subbrute_attack_view.c @@ -20,6 +20,7 @@ typedef struct { uint64_t max_value; uint64_t current_step; bool is_attacking; + bool is_continuous_worker; IconAnimation* icon; } SubBruteAttackViewModel; @@ -47,6 +48,7 @@ bool subbrute_attack_view_input(InputEvent* event, void* context) { with_view_model( instance->view, (SubBruteAttackViewModel * model) { model->is_attacking = false; + model->is_continuous_worker = false; return true; }); return true; @@ -67,25 +69,45 @@ bool subbrute_attack_view_input(InputEvent* event, void* context) { // } if(!is_attacking) { - if((event->type == InputTypeShort || event->type == InputTypeRepeat) && - event->key == InputKeyOk) { + if(event->type == InputTypeShort && event->key == InputKeyOk) { #ifdef FURI_DEBUG FURI_LOG_D(TAG, "InputKey: %d OK", event->key); #endif with_view_model( instance->view, (SubBruteAttackViewModel * model) { model->is_attacking = true; + model->is_continuous_worker = false; icon_animation_stop(model->icon); icon_animation_start(model->icon); return true; }); instance->callback(SubBruteCustomEventTypeTransmitStarted, instance->context); - // } else if(event->key == InputKeyBack) { - // if(previous_scene == SubBruteSceneLoadFile) { - // instance->callback(SubBruteCustomEventTypeLoadFile, instance->context); - // } else { - // instance->callback(SubBruteCustomEventTypeBackPressed, instance->context); - // } + /*if(event->type == InputTypeRepeat && event->key == InputKeyOk) { +#ifdef FURI_DEBUG + FURI_LOG_D(TAG, "InputKey: %d OK. SubBruteCustomEventTypeTransmitContinuousStarted", event->key); +#endif + with_view_model( + instance->view, (SubBruteAttackViewModel * model) { + model->is_attacking = true; + model->is_continuous_worker = true; + icon_animation_stop(model->icon); + icon_animation_start(model->icon); + return true; + }); + instance->callback(SubBruteCustomEventTypeTransmitContinuousStarted, instance->context); + } else if(event->type == InputTypeShort && event->key == InputKeyOk) { +#ifdef FURI_DEBUG + FURI_LOG_D(TAG, "InputKey: %d OK", event->key); +#endif + with_view_model( + instance->view, (SubBruteAttackViewModel * model) { + model->is_attacking = true; + model->is_continuous_worker = false; + icon_animation_stop(model->icon); + icon_animation_start(model->icon); + return true; + }); + instance->callback(SubBruteCustomEventTypeTransmitStarted, instance->context);*/ } else if(event->key == InputKeyUp) { instance->callback(SubBruteCustomEventTypeSaveFile, instance->context); } else if(event->key == InputKeyDown) { @@ -131,6 +153,7 @@ bool subbrute_attack_view_input(InputEvent* event, void* context) { with_view_model( instance->view, (SubBruteAttackViewModel * model) { model->is_attacking = false; + model->is_continuous_worker = false; icon_animation_stop(model->icon); icon_animation_start(model->icon); return true; @@ -161,7 +184,6 @@ SubBruteAttackView* subbrute_attack_view_alloc() { view_set_enter_callback(instance->view, subbrute_attack_view_enter); view_set_exit_callback(instance->view, subbrute_attack_view_exit); - return instance; } @@ -207,17 +229,13 @@ void subbrute_attack_view_set_current_step(SubBruteAttackView* instance, uint64_ }); } -uint64_t subbrute_attack_view_get_current_step(SubBruteAttackView* instance) { - uint64_t current_step; +void subbrute_attack_view_set_worker_type(SubBruteAttackView* instance, bool is_continuous_worker) { + furi_assert(instance); with_view_model( instance->view, (SubBruteAttackViewModel * model) { - current_step = model->current_step; - return false; + model->is_continuous_worker = is_continuous_worker; + return true; }); -#ifdef FURI_DEBUG - FURI_LOG_D(TAG, "Get step: %d", current_step); -#endif - return current_step; } // We need to call init every time, because not every time we calls enter @@ -356,6 +374,9 @@ void subbrute_attack_view_draw(Canvas* canvas, void* context) { elements_button_top_left(canvas, "Save"); elements_button_top_right(canvas, "Resend"); } else { + if (model->is_continuous_worker) { + canvas_invert_color(canvas); + } // canvas_draw_icon_animation const uint8_t icon_h_offset = 0; const uint8_t icon_width_with_offset = model->icon->icon->width + icon_h_offset; @@ -370,5 +391,8 @@ void subbrute_attack_view_draw(Canvas* canvas, void* context) { elements_progress_bar(canvas, 8, 37, 110, progress_value > 1 ? 1 : progress_value); elements_button_center(canvas, "Stop"); + if (model->is_continuous_worker) { + canvas_invert_color(canvas); + } } } diff --git a/applications/plugins/subbrute/views/subbrute_attack_view.h b/applications/plugins/subbrute/views/subbrute_attack_view.h index e72d69d4c..2aa9c4012 100644 --- a/applications/plugins/subbrute/views/subbrute_attack_view.h +++ b/applications/plugins/subbrute/views/subbrute_attack_view.h @@ -19,7 +19,7 @@ SubBruteAttackView* subbrute_attack_view_alloc(); void subbrute_attack_view_free(SubBruteAttackView* instance); View* subbrute_attack_view_get_view(SubBruteAttackView* instance); void subbrute_attack_view_set_current_step(SubBruteAttackView* instance, uint64_t current_step); -uint64_t subbrute_attack_view_get_current_step(SubBruteAttackView* instance); +void subbrute_attack_view_set_worker_type(SubBruteAttackView* instance, bool is_continuous_worker); void subbrute_attack_view_init_values( SubBruteAttackView* instance, uint8_t index, From 60242cd7c4c87b87f58f1405dc82a3fb2d8b25aa Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Mon, 26 Sep 2022 19:46:12 +0300 Subject: [PATCH 08/47] =?UTF-8?q?fix=20nfc=20device=20typo,=20doesn?= =?UTF-8?q?=E2=80=99t=20affect=20resulting=20keys?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/nfc/nfc_device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/nfc/nfc_device.c b/lib/nfc/nfc_device.c index dd78e2daf..45d05a55b 100644 --- a/lib/nfc/nfc_device.c +++ b/lib/nfc/nfc_device.c @@ -925,7 +925,7 @@ static bool nfc_device_save_mifare_classic_keys(NfcDevice* dev) { flipper_format_write_hex(file, string_get_cstr(temp_str), sec_tr->key_a, 6); } if(!key_save_success) break; - if(FURI_BIT(data->key_a_mask, i)) { + if(FURI_BIT(data->key_b_mask, i)) { string_printf(temp_str, "Key B sector %d", i); key_save_success = flipper_format_write_hex(file, string_get_cstr(temp_str), sec_tr->key_b, 6); From a0bcbf731d6f6292c24cfba2a492512185f14ee2 Mon Sep 17 00:00:00 2001 From: derskythe Date: Mon, 26 Sep 2022 21:01:14 +0400 Subject: [PATCH 09/47] fix error on back when selecting existing dump --- .../scenes/subbrute_scene_load_file.c | 25 +++++++++++-------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/applications/plugins/subbrute/scenes/subbrute_scene_load_file.c b/applications/plugins/subbrute/scenes/subbrute_scene_load_file.c index 6557b4ba1..05a7125e1 100644 --- a/applications/plugins/subbrute/scenes/subbrute_scene_load_file.c +++ b/applications/plugins/subbrute/scenes/subbrute_scene_load_file.c @@ -45,19 +45,22 @@ void subbrute_scene_load_file_on_enter(void* context) { res = true; } } - } - if(load_result == SubBruteFileResultOk) { - scene_manager_next_scene(instance->scene_manager, SubBruteSceneLoadSelect); + if(load_result == SubBruteFileResultOk) { + scene_manager_next_scene(instance->scene_manager, SubBruteSceneLoadSelect); + } else { + FURI_LOG_E(TAG, "Returned error: %d", load_result); + + string_t dialog_msg; + string_init(dialog_msg); + string_cat_printf( + dialog_msg, "Cannot parse\nfile: %s", subbrute_device_error_get_desc(load_result)); + dialog_message_show_storage_error(instance->dialogs, string_get_cstr(dialog_msg)); + string_clear(dialog_msg); + scene_manager_search_and_switch_to_previous_scene( + instance->scene_manager, SubBruteSceneStart); + } } else { - FURI_LOG_E(TAG, "Returned error: %d", load_result); - - string_t dialog_msg; - string_init(dialog_msg); - string_cat_printf( - dialog_msg, "Cannot parse\nfile: %s", subbrute_device_error_get_desc(load_result)); - dialog_message_show_storage_error(instance->dialogs, string_get_cstr(dialog_msg)); - string_clear(dialog_msg); scene_manager_search_and_switch_to_previous_scene( instance->scene_manager, SubBruteSceneStart); } From 633145495c42cfc1126672b31bd160c415e26170 Mon Sep 17 00:00:00 2001 From: derskythe Date: Mon, 26 Sep 2022 21:10:41 +0400 Subject: [PATCH 10/47] fix twice button press in manual mode --- .../plugins/subbrute/helpers/subbrute_worker.c | 12 +++++++++--- .../plugins/subbrute/helpers/subbrute_worker.h | 2 +- .../subbrute/scenes/subbrute_scene_run_attack.c | 2 +- .../subbrute/scenes/subbrute_scene_setup_attack.c | 2 +- 4 files changed, 12 insertions(+), 6 deletions(-) diff --git a/applications/plugins/subbrute/helpers/subbrute_worker.c b/applications/plugins/subbrute/helpers/subbrute_worker.c index e12d7c9f6..2fab20e95 100644 --- a/applications/plugins/subbrute/helpers/subbrute_worker.c +++ b/applications/plugins/subbrute/helpers/subbrute_worker.c @@ -157,10 +157,16 @@ bool subbrute_worker_can_transmit(SubBruteWorker* instance) { return (furi_get_tick() - instance->last_time_tx_data) > SUBBRUTE_SEND_DELAY; } -bool subbrute_worker_can_manual_transmit(SubBruteWorker* instance) { +bool subbrute_worker_can_manual_transmit(SubBruteWorker* instance, bool is_button_pressed) { furi_assert(instance); - return !instance->worker_manual_mode; + if(is_button_pressed) { + // It's human pressed, trying to reset twice pressing + return !instance->worker_manual_mode && + (furi_get_tick() - instance->last_time_tx_data) > 500; + } else { + return !instance->worker_manual_mode; + } } bool subbrute_worker_transmit(SubBruteWorker* instance, const char* payload) { @@ -204,7 +210,7 @@ bool subbrute_worker_init_manual_transmit( frequency, protocol_name); #endif - if(instance->worker_manual_mode || !subbrute_worker_can_manual_transmit(instance) || + if(instance->worker_manual_mode || !subbrute_worker_can_manual_transmit(instance, false) || instance->worker_running) { #ifdef FURI_DEBUG FURI_LOG_D(TAG, "cannot transmit"); diff --git a/applications/plugins/subbrute/helpers/subbrute_worker.h b/applications/plugins/subbrute/helpers/subbrute_worker.h index 3338657d1..d96fbdde2 100644 --- a/applications/plugins/subbrute/helpers/subbrute_worker.h +++ b/applications/plugins/subbrute/helpers/subbrute_worker.h @@ -28,7 +28,7 @@ void subbrute_worker_set_continuous_worker(SubBruteWorker* instance, bool is_con //bool subbrute_worker_write(SubBruteWorker* instance, uint8_t* data, size_t size); bool subbrute_worker_is_running(SubBruteWorker* instance); bool subbrute_worker_can_transmit(SubBruteWorker* instance); -bool subbrute_worker_can_manual_transmit(SubBruteWorker* instance); +bool subbrute_worker_can_manual_transmit(SubBruteWorker* instance, bool is_button_pressed); bool subbrute_worker_transmit(SubBruteWorker* instance, const char* payload); bool subbrute_worker_init_manual_transmit( SubBruteWorker* instance, diff --git a/applications/plugins/subbrute/scenes/subbrute_scene_run_attack.c b/applications/plugins/subbrute/scenes/subbrute_scene_run_attack.c index 5f5ba3e27..978c7de40 100644 --- a/applications/plugins/subbrute/scenes/subbrute_scene_run_attack.c +++ b/applications/plugins/subbrute/scenes/subbrute_scene_run_attack.c @@ -161,7 +161,7 @@ bool subbrute_scene_run_attack_on_event(void* context, SceneManagerEvent event) notification_message(instance->notifications, &sequence_blink_stop); } } else { - if(subbrute_worker_can_manual_transmit(instance->worker)) { + if(subbrute_worker_can_manual_transmit(instance->worker, false)) { // Blink notification_message(instance->notifications, &sequence_blink_yellow_100); diff --git a/applications/plugins/subbrute/scenes/subbrute_scene_setup_attack.c b/applications/plugins/subbrute/scenes/subbrute_scene_setup_attack.c index c645a899a..f707ff3cb 100644 --- a/applications/plugins/subbrute/scenes/subbrute_scene_setup_attack.c +++ b/applications/plugins/subbrute/scenes/subbrute_scene_setup_attack.c @@ -135,7 +135,7 @@ bool subbrute_scene_setup_attack_on_event(void* context, SceneManagerEvent event } subbrute_attack_view_set_current_step(view, instance->device->key_index); } else if(event.event == SubBruteCustomEventTypeTransmitCustom) { - if(subbrute_worker_can_manual_transmit(instance->worker)) { + if(subbrute_worker_can_manual_transmit(instance->worker, true)) { // Blink notification_message(instance->notifications, &sequence_blink_green_100); From 286300b35bd73017642b7e46f2295202e3b31332 Mon Sep 17 00:00:00 2001 From: derskythe Date: Mon, 26 Sep 2022 21:15:02 +0400 Subject: [PATCH 11/47] fix disable env allocation many times --- applications/plugins/subbrute/helpers/subbrute_worker.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/applications/plugins/subbrute/helpers/subbrute_worker.c b/applications/plugins/subbrute/helpers/subbrute_worker.c index 2fab20e95..d96461aa1 100644 --- a/applications/plugins/subbrute/helpers/subbrute_worker.c +++ b/applications/plugins/subbrute/helpers/subbrute_worker.c @@ -43,7 +43,7 @@ SubBruteWorker* subbrute_worker_alloc() { instance->worker_running = false; instance->worker_manual_mode = false; - instance->environment = NULL; + instance->environment = subghz_environment_alloc(); instance->transmitter = NULL; instance->flipper_format = flipper_format_string_alloc(); @@ -257,7 +257,6 @@ bool subbrute_worker_init_manual_transmit( FURI_LOG_I(TAG, "Frequency: %d", frequency); #endif - instance->environment = subghz_environment_alloc(); instance->transmitter = subghz_transmitter_alloc_init( instance->environment, string_get_cstr(instance->protocol_name)); @@ -291,8 +290,6 @@ void subbrute_worker_manual_transmit_stop(SubBruteWorker* instance) { subghz_transmitter_free(instance->transmitter); instance->transmitter = NULL; } - subghz_environment_free(instance->environment); - instance->environment = NULL; instance->is_manual_init = false; } From a40e1a2be26a1597a1c9eec6eb0ebabafacd58ed Mon Sep 17 00:00:00 2001 From: derskythe Date: Mon, 26 Sep 2022 21:15:46 +0400 Subject: [PATCH 12/47] set big step to 50 --- .../plugins/subbrute/scenes/subbrute_scene_setup_attack.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/applications/plugins/subbrute/scenes/subbrute_scene_setup_attack.c b/applications/plugins/subbrute/scenes/subbrute_scene_setup_attack.c index f707ff3cb..2da28f672 100644 --- a/applications/plugins/subbrute/scenes/subbrute_scene_setup_attack.c +++ b/applications/plugins/subbrute/scenes/subbrute_scene_setup_attack.c @@ -102,8 +102,8 @@ bool subbrute_scene_setup_attack_on_event(void* context, SceneManagerEvent event } subbrute_attack_view_set_current_step(view, instance->device->key_index); } else if(event.event == SubBruteCustomEventTypeChangeStepUpMore) { - // +100 - uint64_t value = instance->device->key_index + 100; + // +50 + uint64_t value = instance->device->key_index + 50; if(value == instance->device->max_value) { instance->device->key_index += value; } else { @@ -126,8 +126,8 @@ bool subbrute_scene_setup_attack_on_event(void* context, SceneManagerEvent event } subbrute_attack_view_set_current_step(view, instance->device->key_index); } else if(event.event == SubBruteCustomEventTypeChangeStepDownMore) { - // -100 - uint64_t value = ((instance->device->key_index - 100) + instance->device->max_value); + // -50 + uint64_t value = ((instance->device->key_index - 50) + instance->device->max_value); if(value == instance->device->max_value) { instance->device->key_index = value; } else { From 545c4349d6eedfc2b7fbc274b8fda58eb4204c98 Mon Sep 17 00:00:00 2001 From: derskythe Date: Mon, 26 Sep 2022 21:26:51 +0400 Subject: [PATCH 13/47] add vibro on finish and main menu set left --- .../plugins/subbrute/scenes/subbrute_scene_run_attack.c | 2 ++ applications/plugins/subbrute/views/subbrute_main_view.c | 8 ++++---- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/applications/plugins/subbrute/scenes/subbrute_scene_run_attack.c b/applications/plugins/subbrute/scenes/subbrute_scene_run_attack.c index 978c7de40..385f43b9b 100644 --- a/applications/plugins/subbrute/scenes/subbrute_scene_run_attack.c +++ b/applications/plugins/subbrute/scenes/subbrute_scene_run_attack.c @@ -127,6 +127,8 @@ bool subbrute_scene_run_attack_on_event(void* context, SceneManagerEvent event) event.event == SubBruteCustomEventTypeBackPressed) { // furi_timer_stop(state->timer); // Stop transmit + notification_message(instance->notifications, &sequence_display_backlight_on); + notification_message(instance->notifications, &sequence_single_vibro); subbrute_attack_view_set_current_step(view, instance->device->key_index); scene_manager_search_and_switch_to_previous_scene( instance->scene_manager, SubBruteSceneSetupAttack); diff --git a/applications/plugins/subbrute/views/subbrute_main_view.c b/applications/plugins/subbrute/views/subbrute_main_view.c index 141e3ce27..8d8bf477e 100644 --- a/applications/plugins/subbrute/views/subbrute_main_view.c +++ b/applications/plugins/subbrute/views/subbrute_main_view.c @@ -127,9 +127,9 @@ void subbrute_main_view_draw(Canvas* canvas, SubBruteMainViewModel* model) { if(m->index == position) { canvas_draw_str_aligned( canvas, - 64, + 4, 9 + (item_position * item_height) + STATUS_BAR_Y_SHIFT, - AlignCenter, + AlignLeft, AlignCenter, str); elements_frame( @@ -137,9 +137,9 @@ void subbrute_main_view_draw(Canvas* canvas, SubBruteMainViewModel* model) { } else { canvas_draw_str_aligned( canvas, - 64, + 4, 9 + (item_position * item_height) + STATUS_BAR_Y_SHIFT, - AlignCenter, + AlignLeft, AlignCenter, str); } From 91c06a216826530f43fa7aa8924fc8c6293f86d2 Mon Sep 17 00:00:00 2001 From: derskythe Date: Mon, 26 Sep 2022 21:41:49 +0400 Subject: [PATCH 14/47] fix disable env allocation many times --- .../plugins/subbrute/subbrute_device.c | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) diff --git a/applications/plugins/subbrute/subbrute_device.c b/applications/plugins/subbrute/subbrute_device.c index 6262eeff4..037a0f11b 100644 --- a/applications/plugins/subbrute/subbrute_device.c +++ b/applications/plugins/subbrute/subbrute_device.c @@ -60,7 +60,7 @@ SubBruteDevice* subbrute_device_alloc() { instance->decoder_result = NULL; instance->receiver = NULL; - instance->environment = NULL; + instance->environment = subghz_environment_alloc(); subbrute_device_attack_set_default_values(instance, SubBruteAttackCAME12bit307); @@ -84,13 +84,8 @@ void subbrute_device_free(SubBruteDevice* instance) { instance->receiver = NULL; } - if(instance->environment != NULL) { -#ifdef FURI_DEBUG - FURI_LOG_D(TAG, "subghz_environment_free"); -#endif - subghz_environment_free(instance->environment); - instance->environment = NULL; - } + subghz_environment_free(instance->environment); + instance->environment = NULL; #ifdef FURI_DEBUG FURI_LOG_D(TAG, "before free"); @@ -236,7 +231,7 @@ bool subbrute_device_create_packet_parsed(SubBruteDevice* instance, uint64_t ste FURI_LOG_D(TAG, "candidate: %s, step: %d", string_get_cstr(candidate), step); #endif - if (small) { + if(small) { if(instance->has_tail) { snprintf( instance->payload, @@ -358,7 +353,6 @@ SubBruteFileResult subbrute_device_attack_set(SubBruteDevice* instance, SubBrute } // For non-file types we didn't set SubGhzProtocolDecoderBase - instance->environment = subghz_environment_alloc(); instance->receiver = subghz_receiver_alloc_init(instance->environment); subghz_receiver_set_filter(instance->receiver, SubGhzProtocolFlag_Decodable); furi_hal_subghz_reset(); @@ -380,10 +374,8 @@ SubBruteFileResult subbrute_device_attack_set(SubBruteDevice* instance, SubBrute protocol_check_result = SubBruteFileResultOk; } - subghz_environment_free(instance->environment); subghz_receiver_free(instance->receiver); instance->receiver = NULL; - instance->environment = NULL; if(protocol_check_result != SubBruteFileResultOk) { return SubBruteFileResultProtocolNotFound; @@ -447,7 +439,6 @@ uint8_t subbrute_device_load_from_file(SubBruteDevice* instance, string_t file_p string_init(temp_str); uint32_t temp_data32; - instance->environment = subghz_environment_alloc(); instance->receiver = subghz_receiver_alloc_init(instance->environment); subghz_receiver_set_filter(instance->receiver, SubGhzProtocolFlag_Decodable); furi_hal_subghz_reset(); @@ -582,12 +573,10 @@ uint8_t subbrute_device_load_from_file(SubBruteDevice* instance, string_t file_p flipper_format_free(fff_data_file); furi_record_close(RECORD_STORAGE); - subghz_environment_free(instance->environment); subghz_receiver_free(instance->receiver); instance->decoder_result = NULL; instance->receiver = NULL; - instance->environment = NULL; if(result == SubBruteFileResultOk) { #ifdef FURI_DEBUG From 069dd29f0823bdea3d26caacc923942c9d7b2221 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Mon, 26 Sep 2022 06:24:47 +0300 Subject: [PATCH 15/47] Revert "some fixes, trying to speed up bruteforce(unsuccessful)" This reverts commit 61fee8e2693ad45f8ddb9a26fe75e5001360e154. --- .../subbrute/helpers/subbrute_worker.c | 27 +++++++++---------- .../scenes/subbrute_scene_run_attack.c | 6 ++--- .../scenes/subbrute_scene_setup_attack.c | 10 +++---- applications/plugins/subbrute/subbrute.c | 12 ++++----- .../plugins/subbrute/subbrute_device.c | 14 +++++----- .../subbrute/views/subbrute_main_view.c | 8 +++--- 6 files changed, 36 insertions(+), 41 deletions(-) diff --git a/applications/plugins/subbrute/helpers/subbrute_worker.c b/applications/plugins/subbrute/helpers/subbrute_worker.c index c821506a2..22e0e7ec4 100644 --- a/applications/plugins/subbrute/helpers/subbrute_worker.c +++ b/applications/plugins/subbrute/helpers/subbrute_worker.c @@ -31,7 +31,7 @@ struct SubBruteWorker { #define SUBBRUTE_TXRX_WORKER_BUF_SIZE 2048 #define SUBBRUTE_TXRX_WORKER_MAX_TXRX_SIZE 60 #define SUBBRUTE_TXRX_WORKER_TIMEOUT_READ_WRITE_BUF 40 -#define SUBBRUTE_TX_TIMEOUT 1 +#define SUBBRUTE_TX_TIMEOUT 50 #define SUBBRUTE_SEND_DELAY 260 /** @@ -52,7 +52,7 @@ int32_t subbrute_worker_thread(void* context) { FURI_LOG_I(TAG, "Worker start"); #endif - //instance->environment = subghz_environment_alloc(); + instance->environment = subghz_environment_alloc(); instance->transmitter = subghz_transmitter_alloc_init( instance->environment, string_get_cstr(instance->protocol_name)); @@ -64,7 +64,7 @@ int32_t subbrute_worker_thread(void* context) { furi_hal_gpio_write(&gpio_cc1101_g0, true); // Set ready to transmit value - //instance->last_time_tx_data = furi_get_tick() - SUBBRUTE_SEND_DELAY; + instance->last_time_tx_data = furi_get_tick() - SUBBRUTE_SEND_DELAY; while(instance->worker_running) { // Transmit @@ -80,8 +80,8 @@ int32_t subbrute_worker_thread(void* context) { subghz_transmitter_free(instance->transmitter); instance->transmitter = NULL; - /*subghz_environment_free(instance->environment); - instance->environment = NULL;*/ + subghz_environment_free(instance->environment); + instance->environment = NULL; #ifdef FURI_DEBUG FURI_LOG_I(TAG, "Worker stop"); @@ -117,10 +117,10 @@ void subbrute_worker_free(SubBruteWorker* instance) { instance->transmitter = NULL; } - /*if(instance->environment != NULL) { + if(instance->environment != NULL) { subghz_environment_free(instance->environment); instance->environment = NULL; - }*/ + } furi_thread_free(instance->thread); flipper_format_free(instance->flipper_format); @@ -190,10 +190,9 @@ bool subbrute_worker_is_running(SubBruteWorker* instance) { } bool subbrute_worker_can_transmit(SubBruteWorker* instance) { - UNUSED(instance); - return true; - //furi_assert(instance); - //return (furi_get_tick() - instance->last_time_tx_data) > SUBBRUTE_SEND_DELAY; + furi_assert(instance); + + return (furi_get_tick() - instance->last_time_tx_data) > SUBBRUTE_SEND_DELAY; } bool subbrute_worker_transmit(SubBruteWorker* instance, const char* payload) { @@ -277,7 +276,7 @@ bool subbrute_worker_init_manual_transmit( FURI_LOG_I(TAG, "Frequency: %d", frequency); #endif - //instance->environment = subghz_environment_alloc(); + instance->environment = subghz_environment_alloc(); instance->transmitter = subghz_transmitter_alloc_init( instance->environment, string_get_cstr(instance->protocol_name)); @@ -311,8 +310,8 @@ void subbrute_worker_manual_transmit_stop(SubBruteWorker* instance) { subghz_transmitter_free(instance->transmitter); instance->transmitter = NULL; } - /*subghz_environment_free(instance->environment); - instance->environment = NULL;*/ + subghz_environment_free(instance->environment); + instance->environment = NULL; instance->is_manual_init = false; } diff --git a/applications/plugins/subbrute/scenes/subbrute_scene_run_attack.c b/applications/plugins/subbrute/scenes/subbrute_scene_run_attack.c index 209eb9df8..36a9e86f9 100644 --- a/applications/plugins/subbrute/scenes/subbrute_scene_run_attack.c +++ b/applications/plugins/subbrute/scenes/subbrute_scene_run_attack.c @@ -39,8 +39,6 @@ void subbrute_scene_run_attack_on_enter(void* context) { instance->device->frequency, instance->device->preset, string_get_cstr(instance->device->protocol_name)); - - notification_message(instance->notifications, &sequence_blink_start_magenta); } bool subbrute_scene_run_attack_on_event(void* context, SceneManagerEvent event) { @@ -59,13 +57,12 @@ bool subbrute_scene_run_attack_on_event(void* context, SceneManagerEvent event) } else if(event.type == SceneManagerEventTypeTick) { if(subbrute_worker_can_transmit(instance->worker)) { // Blink + notification_message(instance->notifications, &sequence_blink_yellow_100); if(subbrute_worker_manual_transmit(instance->worker, instance->device->payload)) { // Make payload for new iteration or exit if(instance->device->key_index + 1 > instance->device->max_value) { // End of list - notification_message(instance->notifications, &sequence_single_vibro); - notification_message(instance->notifications, &sequence_blink_stop); scene_manager_next_scene(instance->scene_manager, SubBruteSceneSetupAttack); } else { instance->device->key_index++; @@ -76,6 +73,7 @@ bool subbrute_scene_run_attack_on_event(void* context, SceneManagerEvent event) } // Stop + notification_message(instance->notifications, &sequence_blink_stop); } consumed = true; diff --git a/applications/plugins/subbrute/scenes/subbrute_scene_setup_attack.c b/applications/plugins/subbrute/scenes/subbrute_scene_setup_attack.c index 7929b5d73..22d0a3a5f 100644 --- a/applications/plugins/subbrute/scenes/subbrute_scene_setup_attack.c +++ b/applications/plugins/subbrute/scenes/subbrute_scene_setup_attack.c @@ -94,8 +94,8 @@ bool subbrute_scene_setup_attack_on_event(void* context, SceneManagerEvent event } subbrute_attack_view_set_current_step(view, instance->device->key_index); } else if(event.event == SubBruteCustomEventTypeChangeStepUpMore) { - // +50 - uint64_t value = instance->device->key_index + 50; + // +100 + uint64_t value = instance->device->key_index + 100; if(value == instance->device->max_value) { instance->device->key_index += value; } else { @@ -118,8 +118,8 @@ bool subbrute_scene_setup_attack_on_event(void* context, SceneManagerEvent event } subbrute_attack_view_set_current_step(view, instance->device->key_index); } else if(event.event == SubBruteCustomEventTypeChangeStepDownMore) { - // -50 - uint64_t value = ((instance->device->key_index - 50) + instance->device->max_value); + // -100 + uint64_t value = ((instance->device->key_index - 100) + instance->device->max_value); if(value == instance->device->max_value) { instance->device->key_index = value; } else { @@ -129,7 +129,7 @@ bool subbrute_scene_setup_attack_on_event(void* context, SceneManagerEvent event } else if(event.event == SubBruteCustomEventTypeTransmitCustom) { if(subbrute_worker_can_transmit(instance->worker)) { // Blink - notification_message(instance->notifications, &sequence_blink_magenta_10); + notification_message(instance->notifications, &sequence_blink_green_100); // if(!subbrute_attack_view_is_worker_running(view)) { // subbrute_attack_view_start_worker( diff --git a/applications/plugins/subbrute/subbrute.c b/applications/plugins/subbrute/subbrute.c index b3cc25caf..fb6e15882 100644 --- a/applications/plugins/subbrute/subbrute.c +++ b/applications/plugins/subbrute/subbrute.c @@ -142,6 +142,12 @@ SubBruteState* subbrute_alloc() { void subbrute_free(SubBruteState* instance) { furi_assert(instance); + // SubBruteDevice +#ifdef FURI_DEBUG + FURI_LOG_D(TAG, "free SubBruteDevice"); +#endif + subbrute_device_free(instance->device); + // SubBruteWorker #ifdef FURI_DEBUG FURI_LOG_D(TAG, "free SubBruteDevice"); @@ -149,12 +155,6 @@ void subbrute_free(SubBruteState* instance) { subbrute_worker_stop(instance->worker); subbrute_worker_free(instance->worker); - // SubBruteDevice -#ifdef FURI_DEBUG - FURI_LOG_D(TAG, "free SubBruteDevice"); -#endif - subbrute_device_free(instance->device); - // Notifications #ifdef FURI_DEBUG FURI_LOG_D(TAG, "free Notifications"); diff --git a/applications/plugins/subbrute/subbrute_device.c b/applications/plugins/subbrute/subbrute_device.c index e8b33a9ec..28b47562b 100644 --- a/applications/plugins/subbrute/subbrute_device.c +++ b/applications/plugins/subbrute/subbrute_device.c @@ -60,8 +60,6 @@ SubBruteDevice* subbrute_device_alloc() { instance->receiver = NULL; instance->environment = NULL; - instance->environment = subghz_environment_alloc(); - subbrute_device_attack_set_default_values(instance, SubBruteAttackCAME12bit307); return instance; @@ -339,7 +337,7 @@ SubBruteFileResult subbrute_device_attack_set(SubBruteDevice* instance, SubBrute } // For non-file types we didn't set SubGhzProtocolDecoderBase - //instance->environment = subghz_environment_alloc(); + instance->environment = subghz_environment_alloc(); instance->receiver = subghz_receiver_alloc_init(instance->environment); subghz_receiver_set_filter(instance->receiver, SubGhzProtocolFlag_Decodable); furi_hal_subghz_reset(); @@ -361,10 +359,10 @@ SubBruteFileResult subbrute_device_attack_set(SubBruteDevice* instance, SubBrute protocol_check_result = SubBruteFileResultOk; } - //subghz_environment_free(instance->environment); + subghz_environment_free(instance->environment); subghz_receiver_free(instance->receiver); instance->receiver = NULL; - //instance->environment = NULL; + instance->environment = NULL; if(protocol_check_result != SubBruteFileResultOk) { return SubBruteFileResultProtocolNotFound; @@ -428,7 +426,7 @@ uint8_t subbrute_device_load_from_file(SubBruteDevice* instance, string_t file_p string_init(temp_str); uint32_t temp_data32; - //instance->environment = subghz_environment_alloc(); + instance->environment = subghz_environment_alloc(); instance->receiver = subghz_receiver_alloc_init(instance->environment); subghz_receiver_set_filter(instance->receiver, SubGhzProtocolFlag_Decodable); furi_hal_subghz_reset(); @@ -563,12 +561,12 @@ uint8_t subbrute_device_load_from_file(SubBruteDevice* instance, string_t file_p flipper_format_free(fff_data_file); furi_record_close(RECORD_STORAGE); - //subghz_environment_free(instance->environment); + subghz_environment_free(instance->environment); subghz_receiver_free(instance->receiver); instance->decoder_result = NULL; instance->receiver = NULL; - //instance->environment = NULL; + instance->environment = NULL; if(result == SubBruteFileResultOk) { #ifdef FURI_DEBUG diff --git a/applications/plugins/subbrute/views/subbrute_main_view.c b/applications/plugins/subbrute/views/subbrute_main_view.c index 8d8bf477e..141e3ce27 100644 --- a/applications/plugins/subbrute/views/subbrute_main_view.c +++ b/applications/plugins/subbrute/views/subbrute_main_view.c @@ -127,9 +127,9 @@ void subbrute_main_view_draw(Canvas* canvas, SubBruteMainViewModel* model) { if(m->index == position) { canvas_draw_str_aligned( canvas, - 4, + 64, 9 + (item_position * item_height) + STATUS_BAR_Y_SHIFT, - AlignLeft, + AlignCenter, AlignCenter, str); elements_frame( @@ -137,9 +137,9 @@ void subbrute_main_view_draw(Canvas* canvas, SubBruteMainViewModel* model) { } else { canvas_draw_str_aligned( canvas, - 4, + 64, 9 + (item_position * item_height) + STATUS_BAR_Y_SHIFT, - AlignLeft, + AlignCenter, AlignCenter, str); } From 8cc3e2f35ab2549a27c86538497d0886dae0827f Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Mon, 26 Sep 2022 23:07:53 +0300 Subject: [PATCH 16/47] remove extra environment alloc --- .../plugins/subbrute/helpers/subbrute_worker.c | 6 +++--- applications/plugins/subbrute/subbrute.c | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/applications/plugins/subbrute/helpers/subbrute_worker.c b/applications/plugins/subbrute/helpers/subbrute_worker.c index d96461aa1..369ffd81c 100644 --- a/applications/plugins/subbrute/helpers/subbrute_worker.c +++ b/applications/plugins/subbrute/helpers/subbrute_worker.c @@ -43,7 +43,7 @@ SubBruteWorker* subbrute_worker_alloc() { instance->worker_running = false; instance->worker_manual_mode = false; - instance->environment = subghz_environment_alloc(); + //instance->environment = subghz_environment_alloc(); instance->transmitter = NULL; instance->flipper_format = flipper_format_string_alloc(); @@ -64,10 +64,10 @@ void subbrute_worker_free(SubBruteWorker* instance) { instance->transmitter = NULL; } - if(instance->environment != NULL) { + /*if(instance->environment != NULL) { subghz_environment_free(instance->environment); instance->environment = NULL; - } + }*/ flipper_format_free(instance->flipper_format); diff --git a/applications/plugins/subbrute/subbrute.c b/applications/plugins/subbrute/subbrute.c index cacb2e68c..0393335ab 100644 --- a/applications/plugins/subbrute/subbrute.c +++ b/applications/plugins/subbrute/subbrute.c @@ -142,12 +142,6 @@ SubBruteState* subbrute_alloc() { void subbrute_free(SubBruteState* instance) { furi_assert(instance); - // SubBruteDevice -#ifdef FURI_DEBUG - FURI_LOG_D(TAG, "free SubBruteDevice"); -#endif - subbrute_device_free(instance->device); - // SubBruteWorker #ifdef FURI_DEBUG FURI_LOG_D(TAG, "free SubBruteDevice"); @@ -155,6 +149,12 @@ void subbrute_free(SubBruteState* instance) { subbrute_worker_stop(instance->worker); subbrute_worker_free(instance->worker); + // SubBruteDevice +#ifdef FURI_DEBUG + FURI_LOG_D(TAG, "free SubBruteDevice"); +#endif + subbrute_device_free(instance->device); + // Notifications #ifdef FURI_DEBUG FURI_LOG_D(TAG, "free Notifications"); From 91f3774246a7ae69468187312dd7ef0003a7a550 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Mon, 26 Sep 2022 23:55:39 +0300 Subject: [PATCH 17/47] update changelog --- CHANGELOG.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c9ef2b85d..c93e1f85e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,9 @@ ### New changes -* PR: SubGHz bruteforcer plugin - deep refactoring (huge thanks to @derskythe ! | PR #75) -* OFW: Preliminary Rust support +* PR: SubGHz bruteforcer plugin - fixes and speed-up (-2 min) (by @derskythe | PR #76) +* Fix nfc device typo - key_a_mask was used for key B +* OFW: Applications loader: do not use view dispatcher queue +* OFW: Power: Also ask charger if charge done +* OFW: Fast flash programming mode (faster firmware flash) #### **DFU files no longer included in releases to avoid issues with wrong manual installation of assets - use .tgz file with qFlipper, or install automatically via web updater or use microSD update package** From c4783664c005c95438e69d1fbad57883c8b25af4 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Tue, 27 Sep 2022 00:51:36 +0300 Subject: [PATCH 18/47] subghz bruteforcer plugin: move title a bit --- applications/plugins/subbrute/views/subbrute_main_view.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/applications/plugins/subbrute/views/subbrute_main_view.c b/applications/plugins/subbrute/views/subbrute_main_view.c index 8d8bf477e..1159a33b3 100644 --- a/applications/plugins/subbrute/views/subbrute_main_view.c +++ b/applications/plugins/subbrute/views/subbrute_main_view.c @@ -85,7 +85,7 @@ void subbrute_main_view_draw(Canvas* canvas, SubBruteMainViewModel* model) { canvas_set_font(canvas, FontPrimary); canvas_draw_box(canvas, 0, 0, canvas_width(canvas), STATUS_BAR_Y_SHIFT); canvas_invert_color(canvas); - canvas_draw_str_aligned(canvas, 64, 2, AlignCenter, AlignTop, "Sub-GHz Bruteforcer"); + canvas_draw_str_aligned(canvas, 64, 3, AlignCenter, AlignTop, "Sub-GHz Bruteforcer"); canvas_invert_color(canvas); if(m->is_select_byte) { From cb14d23108ba5043dd01407fcab73312488c6212 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Tue, 27 Sep 2022 04:31:52 +0300 Subject: [PATCH 19/47] format, add chamberlain 9bit 300mhz --- .../plugins/subbrute/scenes/subbrute_scene_save_success.c | 2 +- applications/plugins/subbrute/subbrute.c | 2 ++ applications/plugins/subbrute/subbrute_device.c | 6 ++++++ applications/plugins/subbrute/subbrute_device.h | 5 ++++- applications/plugins/subbrute/views/subbrute_attack_view.c | 6 +++--- 5 files changed, 16 insertions(+), 5 deletions(-) diff --git a/applications/plugins/subbrute/scenes/subbrute_scene_save_success.c b/applications/plugins/subbrute/scenes/subbrute_scene_save_success.c index 7f0e28809..f83c0c0fe 100644 --- a/applications/plugins/subbrute/scenes/subbrute_scene_save_success.c +++ b/applications/plugins/subbrute/scenes/subbrute_scene_save_success.c @@ -21,7 +21,7 @@ bool subbrute_scene_save_success_on_event(void* context, SceneManagerEvent event SubBruteState* instance = (SubBruteState*)context; //SubBruteMainView* view = instance->view_main; - + if(event.type == SceneManagerEventTypeCustom) { if(event.event == SubBruteCustomEventTypePopupClosed) { if(!scene_manager_search_and_switch_to_previous_scene( diff --git a/applications/plugins/subbrute/subbrute.c b/applications/plugins/subbrute/subbrute.c index 0393335ab..5bdacde63 100644 --- a/applications/plugins/subbrute/subbrute.c +++ b/applications/plugins/subbrute/subbrute.c @@ -24,6 +24,7 @@ static const char* subbrute_menu_names[] = { [SubBruteAttackCAME12bit307] = "CAME 12bit 307mhz", [SubBruteAttackCAME12bit433] = "CAME 12bit 433mhz", [SubBruteAttackCAME12bit868] = "CAME 12bit 868mhz", + [SubBruteAttackChamberlain9bit300] = "Chamberlain 9bit 300mhz", [SubBruteAttackChamberlain9bit315] = "Chamberlain 9bit 315mhz", [SubBruteAttackChamberlain9bit390] = "Chamberlain 9bit 390mhz", [SubBruteAttackLinear10bit300] = "Linear 10bit 300mhz", @@ -38,6 +39,7 @@ static const char* subbrute_menu_names_small[] = { [SubBruteAttackCAME12bit307] = "CAME 307mhz", [SubBruteAttackCAME12bit433] = "CAME 433mhz", [SubBruteAttackCAME12bit868] = "CAME 868mhz", + [SubBruteAttackChamberlain9bit300] = "Cham 300mhz", [SubBruteAttackChamberlain9bit315] = "Cham 315mhz", [SubBruteAttackChamberlain9bit390] = "Cham 390mhz", [SubBruteAttackLinear10bit300] = "Linear 300mhz", diff --git a/applications/plugins/subbrute/subbrute_device.c b/applications/plugins/subbrute/subbrute_device.c index 037a0f11b..f1ca6962a 100644 --- a/applications/plugins/subbrute/subbrute_device.c +++ b/applications/plugins/subbrute/subbrute_device.c @@ -306,6 +306,12 @@ SubBruteFileResult subbrute_device_attack_set(SubBruteDevice* instance, SubBrute string_set_str(instance->protocol_name, protocol_came); string_set_str(instance->preset_name, preset_ook650_async); break; + case SubBruteAttackChamberlain9bit300: + instance->frequency = 300000000; + instance->bit = 9; + string_set_str(instance->protocol_name, protocol_cham_code); + string_set_str(instance->preset_name, preset_ook650_async); + break; case SubBruteAttackChamberlain9bit315: instance->frequency = 315000000; instance->bit = 9; diff --git a/applications/plugins/subbrute/subbrute_device.h b/applications/plugins/subbrute/subbrute_device.h index 008e022a8..5419c10de 100644 --- a/applications/plugins/subbrute/subbrute_device.h +++ b/applications/plugins/subbrute/subbrute_device.h @@ -20,6 +20,7 @@ typedef enum { SubBruteAttackCAME12bit307, SubBruteAttackCAME12bit433, SubBruteAttackCAME12bit868, + SubBruteAttackChamberlain9bit300, SubBruteAttackChamberlain9bit315, SubBruteAttackChamberlain9bit390, SubBruteAttackLinear10bit300, @@ -96,4 +97,6 @@ bool subbrute_device_create_packet_parsed(SubBruteDevice* context, uint64_t step SubBruteFileResult subbrute_device_attack_set(SubBruteDevice* context, SubBruteAttacks type); uint8_t subbrute_device_load_from_file(SubBruteDevice* context, string_t file_path); FuriHalSubGhzPreset subbrute_device_convert_preset(const char* preset); -void subbrute_device_attack_set_default_values(SubBruteDevice* context, SubBruteAttacks default_attack); \ No newline at end of file +void subbrute_device_attack_set_default_values( + SubBruteDevice* context, + SubBruteAttacks default_attack); \ No newline at end of file diff --git a/applications/plugins/subbrute/views/subbrute_attack_view.c b/applications/plugins/subbrute/views/subbrute_attack_view.c index 12c849b43..562c30131 100644 --- a/applications/plugins/subbrute/views/subbrute_attack_view.c +++ b/applications/plugins/subbrute/views/subbrute_attack_view.c @@ -82,7 +82,7 @@ bool subbrute_attack_view_input(InputEvent* event, void* context) { return true; }); instance->callback(SubBruteCustomEventTypeTransmitStarted, instance->context); - /*if(event->type == InputTypeRepeat && event->key == InputKeyOk) { + /*if(event->type == InputTypeRepeat && event->key == InputKeyOk) { #ifdef FURI_DEBUG FURI_LOG_D(TAG, "InputKey: %d OK. SubBruteCustomEventTypeTransmitContinuousStarted", event->key); #endif @@ -374,7 +374,7 @@ void subbrute_attack_view_draw(Canvas* canvas, void* context) { elements_button_top_left(canvas, "Save"); elements_button_top_right(canvas, "Resend"); } else { - if (model->is_continuous_worker) { + if(model->is_continuous_worker) { canvas_invert_color(canvas); } // canvas_draw_icon_animation @@ -391,7 +391,7 @@ void subbrute_attack_view_draw(Canvas* canvas, void* context) { elements_progress_bar(canvas, 8, 37, 110, progress_value > 1 ? 1 : progress_value); elements_button_center(canvas, "Stop"); - if (model->is_continuous_worker) { + if(model->is_continuous_worker) { canvas_invert_color(canvas); } } From e6e1e7fe15f14610ce83bbd25d94c06a41148102 Mon Sep 17 00:00:00 2001 From: Tom Samstag Date: Tue, 27 Sep 2022 10:00:50 -0700 Subject: [PATCH 20/47] Add formatting to DESfire data dump (#1784) Co-authored-by: gornekich --- lib/nfc/protocols/mifare_desfire.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/lib/nfc/protocols/mifare_desfire.c b/lib/nfc/protocols/mifare_desfire.c index 1822d5c1a..f969cdde6 100644 --- a/lib/nfc/protocols/mifare_desfire.c +++ b/lib/nfc/protocols/mifare_desfire.c @@ -209,8 +209,24 @@ void mf_df_cat_file(MifareDesfireFile* file, string_t out) { uint8_t* data = file->contents; if(data) { for(int rec = 0; rec < num; rec++) { - for(int ch = 0; ch < size; ch++) { - string_cat_printf(out, "%02x", data[rec * size + ch]); + string_cat_printf(out, "record %d\n", rec); + for(int ch = 0; ch < size; ch += 4) { + string_cat_printf(out, "%03x|", ch); + for(int i = 0; i < 4; i++) { + if(ch + i < size) { + string_cat_printf(out, "%02x ", data[rec * size + ch + i]); + } else { + string_cat_printf(out, " "); + } + } + for(int i = 0; i < 4 && ch + i < size; i++) { + if(isprint(data[rec * size + ch + i])) { + string_cat_printf(out, "%c", data[rec * size + ch + i]); + } else { + string_cat_printf(out, "."); + } + } + string_cat_printf(out, "\n"); } string_cat_printf(out, " \n"); } From 12a6290e911f837d67383eb7d2e8dd1f568af396 Mon Sep 17 00:00:00 2001 From: Georgii Surkov <37121527+gsurkov@users.noreply.github.com> Date: Tue, 27 Sep 2022 20:11:28 +0300 Subject: [PATCH 21/47] [FL-2853] Reorganise Universal A/C library (#1792) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Reorganise A/C universal remote library file * Refactor infrared brute force code * Update UniversalRemotes.md Co-authored-by: あく --- .../main/infrared/infrared_brute_force.c | 49 +++++++-------- applications/main/infrared/infrared_signal.c | 63 +++++++++++++++---- applications/main/infrared/infrared_signal.h | 4 ++ assets/resources/infrared/assets/ac.ir | 62 +++++++++--------- documentation/UniversalRemotes.md | 6 +- 5 files changed, 112 insertions(+), 72 deletions(-) diff --git a/applications/main/infrared/infrared_brute_force.c b/applications/main/infrared/infrared_brute_force.c index 575fa05ec..0edc5f742 100644 --- a/applications/main/infrared/infrared_brute_force.c +++ b/applications/main/infrared/infrared_brute_force.c @@ -23,30 +23,36 @@ struct InfraredBruteForce { FlipperFormat* ff; const char* db_filename; string_t current_record_name; + InfraredSignal* current_signal; InfraredBruteForceRecordDict_t records; + bool is_started; }; InfraredBruteForce* infrared_brute_force_alloc() { InfraredBruteForce* brute_force = malloc(sizeof(InfraredBruteForce)); brute_force->ff = NULL; brute_force->db_filename = NULL; + brute_force->current_signal = NULL; + brute_force->is_started = false; string_init(brute_force->current_record_name); InfraredBruteForceRecordDict_init(brute_force->records); return brute_force; } void infrared_brute_force_free(InfraredBruteForce* brute_force) { - furi_assert(!brute_force->ff); + furi_assert(!brute_force->is_started); InfraredBruteForceRecordDict_clear(brute_force->records); string_clear(brute_force->current_record_name); free(brute_force); } void infrared_brute_force_set_db_filename(InfraredBruteForce* brute_force, const char* db_filename) { + furi_assert(!brute_force->is_started); brute_force->db_filename = db_filename; } bool infrared_brute_force_calculate_messages(InfraredBruteForce* brute_force) { + furi_assert(!brute_force->is_started); furi_assert(brute_force->db_filename); bool success = false; @@ -76,6 +82,7 @@ bool infrared_brute_force_start( InfraredBruteForce* brute_force, uint32_t index, uint32_t* record_count) { + furi_assert(!brute_force->is_started); bool success = false; *record_count = 0; @@ -96,50 +103,37 @@ bool infrared_brute_force_start( if(*record_count) { Storage* storage = furi_record_open(RECORD_STORAGE); brute_force->ff = flipper_format_buffered_file_alloc(storage); + brute_force->current_signal = infrared_signal_alloc(); + brute_force->is_started = true; success = flipper_format_buffered_file_open_existing(brute_force->ff, brute_force->db_filename); - if(!success) { - flipper_format_free(brute_force->ff); - brute_force->ff = NULL; - furi_record_close(RECORD_STORAGE); - } + if(!success) infrared_brute_force_stop(brute_force); } return success; } bool infrared_brute_force_is_started(InfraredBruteForce* brute_force) { - return brute_force->ff; + return brute_force->is_started; } void infrared_brute_force_stop(InfraredBruteForce* brute_force) { - furi_assert(string_size(brute_force->current_record_name)); - furi_assert(brute_force->ff); - + furi_assert(brute_force->is_started); string_reset(brute_force->current_record_name); + infrared_signal_free(brute_force->current_signal); flipper_format_free(brute_force->ff); - furi_record_close(RECORD_STORAGE); + brute_force->current_signal = NULL; brute_force->ff = NULL; + brute_force->is_started = false; + furi_record_close(RECORD_STORAGE); } bool infrared_brute_force_send_next(InfraredBruteForce* brute_force) { - furi_assert(string_size(brute_force->current_record_name)); - furi_assert(brute_force->ff); - bool success = false; - - string_t signal_name; - string_init(signal_name); - InfraredSignal* signal = infrared_signal_alloc(); - - do { - success = infrared_signal_read(signal, brute_force->ff, signal_name); - } while(success && !string_equal_p(brute_force->current_record_name, signal_name)); - + furi_assert(brute_force->is_started); + const bool success = infrared_signal_search_and_read( + brute_force->current_signal, brute_force->ff, brute_force->current_record_name); if(success) { - infrared_signal_transmit(signal); + infrared_signal_transmit(brute_force->current_signal); } - - infrared_signal_free(signal); - string_clear(signal_name); return success; } @@ -155,5 +149,6 @@ void infrared_brute_force_add_record( } void infrared_brute_force_reset(InfraredBruteForce* brute_force) { + furi_assert(!brute_force->is_started); InfraredBruteForceRecordDict_reset(brute_force->records); } diff --git a/applications/main/infrared/infrared_signal.c b/applications/main/infrared/infrared_signal.c index b76717dd3..f2e359c8a 100644 --- a/applications/main/infrared/infrared_signal.c +++ b/applications/main/infrared/infrared_signal.c @@ -146,6 +146,26 @@ static inline bool infrared_signal_read_raw(InfraredSignal* signal, FlipperForma return success; } +static bool infrared_signal_read_body(InfraredSignal* signal, FlipperFormat* ff) { + string_t tmp; + string_init(tmp); + bool success = false; + + do { + if(!flipper_format_read_string(ff, "type", tmp)) break; + if(string_equal_p(tmp, "raw")) { + success = infrared_signal_read_raw(signal, ff); + } else if(string_equal_p(tmp, "parsed")) { + success = infrared_signal_read_message(signal, ff); + } else { + FURI_LOG_E(TAG, "Unknown signal type"); + } + } while(false); + + string_clear(tmp); + return success; +} + InfraredSignal* infrared_signal_alloc() { InfraredSignal* signal = malloc(sizeof(InfraredSignal)); @@ -227,24 +247,41 @@ bool infrared_signal_save(InfraredSignal* signal, FlipperFormat* ff, const char* } bool infrared_signal_read(InfraredSignal* signal, FlipperFormat* ff, string_t name) { - string_t buf; - string_init(buf); + string_t tmp; + string_init(tmp); bool success = false; do { - if(!flipper_format_read_string(ff, "name", buf)) break; - string_set(name, buf); - if(!flipper_format_read_string(ff, "type", buf)) break; - if(!string_cmp_str(buf, "raw")) { - success = infrared_signal_read_raw(signal, ff); - } else if(!string_cmp_str(buf, "parsed")) { - success = infrared_signal_read_message(signal, ff); - } else { - FURI_LOG_E(TAG, "Unknown type of signal (allowed - raw/parsed) "); - } + if(!flipper_format_read_string(ff, "name", tmp)) break; + string_set(name, tmp); + if(!infrared_signal_read_body(signal, ff)) break; + success = true; } while(0); - string_clear(buf); + string_clear(tmp); + return success; +} + +bool infrared_signal_search_and_read( + InfraredSignal* signal, + FlipperFormat* ff, + const string_t name) { + bool success = false; + string_t tmp; + string_init(tmp); + + do { + bool is_name_found = false; + while(flipper_format_read_string(ff, "name", tmp)) { + is_name_found = string_equal_p(name, tmp); + if(is_name_found) break; + } + if(!is_name_found) break; + if(!infrared_signal_read_body(signal, ff)) break; + success = true; + } while(false); + + string_clear(tmp); return success; } diff --git a/applications/main/infrared/infrared_signal.h b/applications/main/infrared/infrared_signal.h index 2dbaa75fa..ad2f5d57a 100644 --- a/applications/main/infrared/infrared_signal.h +++ b/applications/main/infrared/infrared_signal.h @@ -37,5 +37,9 @@ InfraredMessage* infrared_signal_get_message(InfraredSignal* signal); bool infrared_signal_save(InfraredSignal* signal, FlipperFormat* ff, const char* name); bool infrared_signal_read(InfraredSignal* signal, FlipperFormat* ff, string_t name); +bool infrared_signal_search_and_read( + InfraredSignal* signal, + FlipperFormat* ff, + const string_t name); void infrared_signal_transmit(InfraredSignal* signal); diff --git a/assets/resources/infrared/assets/ac.ir b/assets/resources/infrared/assets/ac.ir index 49586b555..7866febc6 100644 --- a/assets/resources/infrared/assets/ac.ir +++ b/assets/resources/infrared/assets/ac.ir @@ -1,24 +1,50 @@ Filetype: IR library file Version: 1 # +# Model: Electrolux EACM-16 HP/N3 name: Off type: raw frequency: 38000 duty_cycle: 0.33 data: 502 3436 510 475 509 476 508 477 507 477 507 479 505 480 504 480 504 490 504 481 502 482 501 483 563 420 511 474 510 475 509 476 508 485 561 423 508 476 508 477 507 478 506 479 505 480 504 481 503 517 508 476 508 478 506 479 505 479 505 481 503 483 521 1456 501 498 507 479 505 480 504 481 503 482 501 483 563 421 562 422 509 499 506 479 505 480 504 481 503 482 502 484 510 1451 506 479 505 1542 562 1396 509 471 502 476 508 469 504 3425 511 # -name: Off -type: raw -frequency: 38000 -duty_cycle: 0.330000 -data: 8974 4505 598 1647 595 1651 591 539 592 542 600 537 594 547 595 549 593 1662 591 532 599 1649 593 1659 594 540 602 538 593 548 594 552 600 535 596 528 593 535 596 536 595 540 602 538 593 548 593 551 601 532 599 525 596 1651 591 539 592 543 599 1660 593 1669 594 1672 601 533 598 526 595 533 598 533 598 536 595 543 599 543 599 547 595 540 602 524 597 530 601 530 601 534 597 541 601 541 601 545 597 522 599 7938 591 532 599 528 593 537 594 541 601 537 594 546 596 549 593 1663 600 524 597 530 601 530 601 533 598 540 591 550 592 553 599 536 595 528 593 536 595 536 595 540 591 547 595 548 593 552 600 535 596 529 592 536 595 535 596 538 593 545 597 546 596 550 592 542 600 524 597 531 600 531 600 534 597 542 600 542 600 545 597 538 593 530 601 526 595 537 594 540 591 547 595 546 595 550 592 543 599 526 595 532 599 531 601 535 596 542 600 542 600 546 596 538 593 531 600 1648 594 536 595 539 592 1669 594 1669 594 1671 602 1637 595 7947 592 532 599 529 592 539 592 543 599 540 591 551 601 544 598 537 594 531 600 1647 595 535 596 539 592 545 597 546 596 550 592 543 599 526 595 533 598 534 597 538 593 545 597 546 596 550 602 534 597 527 594 533 598 533 598 536 595 544 598 543 599 547 595 540 591 533 598 529 592 539 592 1663 600 538 593 547 595 551 591 543 599 524 597 530 591 539 592 542 600 537 594 547 595 550 592 542 600 525 596 1651 592 538 593 1662 591 546 596 545 597 548 594 523 629 -# name: Dh type: raw frequency: 38000 duty_cycle: 0.33 data: 507 3430 506 479 505 480 504 481 503 481 503 483 501 485 509 1453 504 1465 503 482 502 483 511 473 500 485 509 476 508 477 507 478 506 487 507 477 507 478 506 479 505 480 504 482 502 483 501 484 500 523 503 482 502 484 500 485 509 476 508 476 508 478 506 1456 501 501 504 482 502 483 501 484 500 485 509 476 508 477 507 1455 502 509 506 479 505 1457 500 485 509 476 508 1454 503 482 502 483 501 568 499 1459 509 1450 507 471 502 474 510 3421 505 # +name: Cool_hi +type: raw +frequency: 38000 +duty_cycle: 0.33 +data: 504 3433 503 482 502 484 510 474 510 475 509 476 508 478 506 1456 564 1405 510 475 509 476 508 502 482 477 507 478 506 479 505 480 504 489 505 480 504 481 503 482 502 483 511 473 511 474 510 475 509 509 506 479 505 480 504 481 503 482 512 473 511 474 510 476 508 1469 509 475 509 476 508 477 507 478 506 479 505 480 504 481 503 505 510 475 509 502 482 503 481 504 480 505 478 507 477 1459 509 560 507 1451 506 473 511 493 480 1450 507 3422 503 +# +name: Cool_lo +type: raw +frequency: 38000 +duty_cycle: 0.33 +data: 525 3615 530 506 561 474 562 474 562 473 563 473 531 505 562 1502 528 1542 562 474 562 474 530 505 531 504 532 504 532 504 616 419 533 510 589 447 526 509 527 509 527 509 527 508 528 508 528 507 529 542 525 510 526 509 527 509 527 509 527 508 528 508 528 1535 527 524 533 503 533 503 533 502 534 502 534 502 534 501 535 501 525 534 533 502 534 502 534 501 535 502 534 1529 533 503 533 503 533 587 533 497 528 501 524 1536 526 501 524 3609 526 +# +name: Heat_hi +type: raw +frequency: 38000 +duty_cycle: 0.33 +data: 531 3406 530 455 529 456 528 457 537 447 537 448 535 450 534 1429 528 1442 536 448 536 449 534 451 532 452 532 453 530 454 530 455 529 464 530 454 529 456 528 457 537 448 536 449 535 450 533 451 533 490 535 449 534 450 534 451 533 452 532 453 531 455 529 1433 534 1443 535 449 535 450 534 452 531 453 530 454 530 455 529 456 538 472 532 452 532 454 530 1433 535 1427 530 1432 536 1427 530 1431 537 1511 530 448 536 1422 535 1423 534 1422 535 3395 530 +# +name: Heat_lo +type: raw +frequency: 38000 +duty_cycle: 0.33 +data: 506 3430 506 478 506 479 505 480 504 481 503 482 502 484 500 1463 505 1465 503 482 502 483 501 484 500 485 509 476 508 477 507 478 506 486 508 477 507 478 506 479 505 480 504 481 503 482 502 483 500 523 502 482 502 483 501 484 500 485 509 476 508 478 506 1455 502 498 507 478 506 479 505 481 503 482 501 483 500 484 500 485 509 500 505 481 502 482 502 1461 507 1455 502 1459 509 476 508 477 507 563 504 1453 504 1454 503 1454 503 1453 504 3426 499 +# +# Model: Hisense Generic +name: Off +type: raw +frequency: 38000 +duty_cycle: 0.330000 +data: 8974 4505 598 1647 595 1651 591 539 592 542 600 537 594 547 595 549 593 1662 591 532 599 1649 593 1659 594 540 602 538 593 548 594 552 600 535 596 528 593 535 596 536 595 540 602 538 593 548 593 551 601 532 599 525 596 1651 591 539 592 543 599 1660 593 1669 594 1672 601 533 598 526 595 533 598 533 598 536 595 543 599 543 599 547 595 540 602 524 597 530 601 530 601 534 597 541 601 541 601 545 597 522 599 7938 591 532 599 528 593 537 594 541 601 537 594 546 596 549 593 1663 600 524 597 530 601 530 601 533 598 540 591 550 592 553 599 536 595 528 593 536 595 536 595 540 591 547 595 548 593 552 600 535 596 529 592 536 595 535 596 538 593 545 597 546 596 550 592 542 600 524 597 531 600 531 600 534 597 542 600 542 600 545 597 538 593 530 601 526 595 537 594 540 591 547 595 546 595 550 592 543 599 526 595 532 599 531 601 535 596 542 600 542 600 546 596 538 593 531 600 1648 594 536 595 539 592 1669 594 1669 594 1671 602 1637 595 7947 592 532 599 529 592 539 592 543 599 540 591 551 601 544 598 537 594 531 600 1647 595 535 596 539 592 545 597 546 596 550 592 543 599 526 595 533 598 534 597 538 593 545 597 546 596 550 602 534 597 527 594 533 598 533 598 536 595 544 598 543 599 547 595 540 591 533 598 529 592 539 592 1663 600 538 593 547 595 551 591 543 599 524 597 530 591 539 592 542 600 537 594 547 595 550 592 542 600 525 596 1651 592 538 593 1662 591 546 596 545 597 548 594 523 629 +# name: Dh type: raw frequency: 38000 @@ -28,47 +54,23 @@ data: 8990 4494 599 1648 595 1654 599 533 598 537 594 544 598 544 598 548 594 16 name: Cool_hi type: raw frequency: 38000 -duty_cycle: 0.33 -data: 504 3433 503 482 502 484 510 474 510 475 509 476 508 478 506 1456 564 1405 510 475 509 476 508 502 482 477 507 478 506 479 505 480 504 489 505 480 504 481 503 482 502 483 511 473 511 474 510 475 509 509 506 479 505 480 504 481 503 482 512 473 511 474 510 476 508 1469 509 475 509 476 508 477 507 478 506 479 505 480 504 481 503 505 510 475 509 502 482 503 481 504 480 505 478 507 477 1459 509 560 507 1451 506 473 511 493 480 1450 507 3422 503 -# -name: Cool_hi -type: raw -frequency: 38000 duty_cycle: 0.330000 data: 8982 4489 604 1643 600 1649 594 537 594 540 602 537 594 547 595 550 592 1664 599 525 596 1652 601 1651 592 542 600 538 593 549 593 552 600 534 597 1646 597 530 601 1651 602 534 597 541 601 541 601 544 598 537 594 529 592 1655 598 533 598 536 595 542 600 542 600 546 596 539 592 532 599 527 594 537 594 540 591 546 596 545 597 548 594 540 602 523 598 529 592 539 592 542 600 539 592 549 593 550 592 524 597 7929 600 525 596 532 599 533 598 537 594 543 599 542 600 544 598 1654 599 524 597 530 591 538 593 540 591 544 598 543 599 544 598 535 596 526 595 531 600 529 592 544 598 541 601 542 600 546 596 540 602 522 599 529 602 530 601 534 597 541 601 541 601 545 597 539 592 532 599 528 593 539 592 541 601 537 594 547 595 551 601 535 596 529 592 536 595 537 594 541 601 538 593 549 593 553 599 536 595 529 592 536 595 534 597 537 594 544 598 543 599 546 596 539 592 1653 600 1650 593 1660 593 543 599 541 601 541 601 546 596 1643 600 7943 596 529 602 527 594 538 593 541 601 538 593 549 593 553 599 536 595 1649 594 535 596 535 596 539 592 546 596 546 596 549 593 542 600 525 596 531 600 530 601 533 598 540 602 539 592 552 600 535 596 527 594 533 598 533 598 536 595 543 599 543 599 545 597 537 594 530 601 526 595 536 595 1660 593 546 596 547 595 550 602 533 598 526 595 533 598 534 597 538 593 546 596 547 595 551 601 534 597 1647 596 532 599 532 599 1656 597 541 601 542 600 545 597 522 599 # name: Cool_lo type: raw frequency: 38000 -duty_cycle: 0.33 -data: 525 3615 530 506 561 474 562 474 562 473 563 473 531 505 562 1502 528 1542 562 474 562 474 530 505 531 504 532 504 532 504 616 419 533 510 589 447 526 509 527 509 527 509 527 508 528 508 528 507 529 542 525 510 526 509 527 509 527 509 527 508 528 508 528 1535 527 524 533 503 533 503 533 502 534 502 534 502 534 501 535 501 525 534 533 502 534 502 534 501 535 502 534 1529 533 503 533 503 533 587 533 497 528 501 524 1536 526 501 524 3609 526 -# -name: Cool_lo -type: raw -frequency: 38000 duty_cycle: 0.330000 data: 8967 4495 597 1645 597 1648 594 535 596 537 594 542 600 541 601 543 599 1655 598 525 596 1651 592 1658 595 539 592 545 597 544 598 546 596 538 593 1648 595 532 599 1648 594 539 592 545 597 543 599 545 597 536 595 528 593 1651 592 538 593 541 601 1654 599 1661 592 1671 592 541 601 523 598 529 592 538 593 541 601 536 595 544 598 547 595 539 592 531 600 526 595 535 596 537 594 543 599 541 601 543 598 518 593 7937 602 522 599 528 593 537 594 539 592 545 597 544 598 546 596 1656 597 525 596 530 601 528 593 539 592 544 598 543 599 544 598 535 596 526 595 531 600 530 601 532 599 538 593 547 595 549 593 540 602 521 600 526 595 535 596 537 594 543 599 541 601 543 599 536 595 527 594 532 600 530 601 532 599 538 593 546 596 548 594 539 592 531 600 525 596 534 597 535 596 540 591 549 593 551 601 532 599 524 597 529 592 537 594 538 593 543 599 540 591 551 601 532 599 1641 591 1654 599 1650 593 540 591 1664 599 1660 593 1671 592 1643 600 7922 596 528 593 533 598 532 599 535 596 540 591 549 593 552 600 533 598 1644 599 529 592 538 593 539 592 544 598 541 590 550 592 539 592 528 593 531 590 537 594 536 595 539 592 546 596 546 596 536 595 526 595 529 592 535 596 535 596 538 593 546 596 546 596 535 596 524 597 527 594 533 598 1649 593 541 601 538 593 549 593 538 593 528 593 532 599 528 593 539 592 542 600 538 593 548 594 538 593 1643 599 525 596 532 599 1649 593 541 601 538 593 548 594 520 591 # name: Heat_hi type: raw frequency: 38000 -duty_cycle: 0.33 -data: 531 3406 530 455 529 456 528 457 537 447 537 448 535 450 534 1429 528 1442 536 448 536 449 534 451 532 452 532 453 530 454 530 455 529 464 530 454 529 456 528 457 537 448 536 449 535 450 533 451 533 490 535 449 534 450 534 451 533 452 532 453 531 455 529 1433 534 1443 535 449 535 450 534 452 531 453 530 454 530 455 529 456 538 472 532 452 532 454 530 1433 535 1427 530 1432 536 1427 530 1431 537 1511 530 448 536 1422 535 1423 534 1422 535 3395 530 -# -name: Heat_hi -type: raw -frequency: 38000 duty_cycle: 0.330000 data: 8970 4496 597 1648 595 1652 601 530 602 533 598 541 601 541 601 543 599 1652 601 523 598 1649 594 1656 597 538 593 545 597 545 597 549 593 541 601 523 598 529 592 1658 595 540 592 546 596 545 597 548 594 541 601 523 598 529 592 539 593 542 600 538 593 1668 595 1670 593 1662 591 533 599 529 592 539 593 542 600 538 593 547 595 549 593 542 600 524 597 530 602 529 592 543 599 539 593 549 593 551 601 516 595 7937 593 532 599 527 594 536 596 539 592 546 596 545 597 548 594 1661 592 532 600 528 593 538 593 541 601 537 594 547 595 550 602 533 599 526 595 533 599 533 599 536 595 543 599 541 601 544 598 536 595 529 592 535 596 535 596 538 594 544 598 544 598 547 595 541 601 523 598 528 593 537 594 540 602 536 595 546 596 550 602 533 598 526 595 532 600 531 600 534 597 541 601 541 601 545 597 539 593 532 600 528 593 538 593 541 601 537 594 547 595 550 602 532 599 523 598 527 594 1653 600 533 598 538 593 1664 599 1662 591 523 598 7926 593 529 592 534 597 532 599 534 597 538 593 546 596 547 595 537 594 1648 595 532 600 532 599 536 595 543 599 543 599 546 596 540 602 522 599 529 592 538 594 541 601 536 595 546 596 549 593 542 600 523 598 529 592 538 593 541 601 538 593 548 594 552 600 534 597 527 594 534 597 534 597 1657 596 543 599 543 599 548 594 542 600 524 597 530 601 530 602 533 598 538 593 547 595 551 601 533 599 1644 599 528 593 538 593 1661 592 545 597 545 597 548 594 524 597 # name: Heat_lo type: raw frequency: 38000 -duty_cycle: 0.33 -data: 506 3430 506 478 506 479 505 480 504 481 503 482 502 484 500 1463 505 1465 503 482 502 483 501 484 500 485 509 476 508 477 507 478 506 486 508 477 507 478 506 479 505 480 504 481 503 482 502 483 500 523 502 482 502 483 501 484 500 485 509 476 508 478 506 1455 502 498 507 478 506 479 505 481 503 482 501 483 500 484 500 485 509 500 505 481 502 482 502 1461 507 1455 502 1459 509 476 508 477 507 563 504 1453 504 1454 503 1454 503 1453 504 3426 499 -# -name: Heat_lo -type: raw -frequency: 38000 duty_cycle: 0.330000 data: 8972 4491 592 1651 592 1655 598 532 599 535 597 542 600 541 601 544 598 1656 597 526 595 1652 591 1658 595 539 593 545 597 545 597 546 596 537 594 529 592 535 596 1653 600 534 597 541 601 539 592 552 600 533 598 525 596 530 591 538 593 539 592 1665 598 1662 591 1673 601 533 598 526 595 533 598 532 600 534 597 540 591 548 594 550 592 542 600 523 598 528 593 536 595 537 594 543 599 542 600 543 599 517 594 7937 593 531 601 526 595 535 597 537 594 542 600 541 601 543 599 1654 599 523 598 528 593 536 596 538 594 542 600 541 590 552 600 532 599 524 597 528 593 536 595 537 595 541 601 539 593 551 591 542 600 522 599 527 594 536 595 537 594 543 599 540 591 552 600 532 600 523 598 527 594 535 596 537 595 542 600 540 591 552 600 532 600 523 598 528 593 536 595 538 593 543 599 541 601 543 599 535 596 527 594 532 600 531 601 534 597 540 592 549 593 552 600 534 597 525 596 529 592 1655 598 534 597 1656 597 1661 592 1671 592 1644 599 7934 596 529 592 535 597 535 597 538 593 544 598 543 599 545 597 538 593 1650 593 535 596 534 597 536 595 540 591 547 595 547 595 536 595 526 595 529 592 536 595 535 596 539 593 546 596 547 595 538 593 528 593 531 601 529 592 541 601 536 596 545 597 548 594 540 592 532 600 526 595 535 596 1656 597 541 601 540 592 553 599 534 597 526 595 532 599 531 600 533 598 539 593 548 594 552 600 535 596 1647 596 531 590 538 593 1656 597 538 594 545 597 545 597 518 593 diff --git a/documentation/UniversalRemotes.md b/documentation/UniversalRemotes.md index 6ecf3b11b..3dd82c615 100644 --- a/documentation/UniversalRemotes.md +++ b/documentation/UniversalRemotes.md @@ -33,6 +33,8 @@ Finally, record the `Off` signal: The resulting remote file should now contain 6 signals. Any of them can be omitted, but that will mean that this functionality will not be used. Test the file against the actual device. Every signal must do what it's supposed to. -If everything checks out, add these signals to the [A/C universal remote file](/assets/resources/infrared/assets/ac.ir). -Keep the signals of the same type grouped together (e.g. an `Off` signal must follow a previous `Off` one). +If everything checks out, append these signals **to the end** of the [A/C universal remote file](/assets/resources/infrared/assets/ac.ir). + +The order of signals is not important, but they must be preceded by a following comment: `# Model: ` in order to keep the library organised. + When done, open a pull request containing the changed file. From 497be7ccb055533063cb44f8209fc5a0f456df55 Mon Sep 17 00:00:00 2001 From: derskythe Date: Wed, 28 Sep 2022 02:01:09 +0400 Subject: [PATCH 22/47] Last SubGHz settings is ready --- .../subghz/scenes/subghz_scene_need_saving.c | 4 +- .../subghz/scenes/subghz_scene_read_raw.c | 15 +++++- .../subghz/scenes/subghz_scene_receiver.c | 18 +++++-- .../scenes/subghz_scene_receiver_config.c | 49 +++++++++---------- applications/main/subghz/subghz.c | 21 +++++++- applications/main/subghz/subghz_i.h | 4 +- .../main/subghz/subghz_last_settings.c | 19 +++++++ .../main/subghz/subghz_last_settings.h | 36 ++++++++++++++ .../subghz/subghz_last_settings_filename.h | 3 ++ applications/main/subghz/subghz_setting.c | 21 +++++--- applications/main/subghz/subghz_setting.h | 2 + 11 files changed, 150 insertions(+), 42 deletions(-) create mode 100644 applications/main/subghz/subghz_last_settings.c create mode 100644 applications/main/subghz/subghz_last_settings.h create mode 100644 applications/main/subghz/subghz_last_settings_filename.h diff --git a/applications/main/subghz/scenes/subghz_scene_need_saving.c b/applications/main/subghz/scenes/subghz_scene_need_saving.c index 53bffedc8..6f04be669 100644 --- a/applications/main/subghz/scenes/subghz_scene_need_saving.c +++ b/applications/main/subghz/scenes/subghz_scene_need_saving.c @@ -50,8 +50,8 @@ bool subghz_scene_need_saving_on_event(void* context, SceneManagerEvent event) { subghz->txrx->rx_key_state = SubGhzRxKeyStateIDLE; subghz_preset_init( subghz, - "AM650", - subghz_setting_get_default_frequency(subghz->setting), + subghz_setting_get_preset_name(subghz->setting, subghz->last_settings->preset), + subghz->last_settings->frequency, NULL, 0); scene_manager_search_and_switch_to_previous_scene( diff --git a/applications/main/subghz/scenes/subghz_scene_read_raw.c b/applications/main/subghz/scenes/subghz_scene_read_raw.c index 60783b060..8a087e134 100644 --- a/applications/main/subghz/scenes/subghz_scene_read_raw.c +++ b/applications/main/subghz/scenes/subghz_scene_read_raw.c @@ -131,13 +131,14 @@ bool subghz_scene_read_raw_on_event(void* context, SceneManagerEvent event) { if((subghz->txrx->rx_key_state == SubGhzRxKeyStateAddKey) || (subghz->txrx->rx_key_state == SubGhzRxKeyStateBack)) { subghz->txrx->rx_key_state = SubGhzRxKeyStateExit; + subghz->current_scene = SubGhzSceneNeedSaving; scene_manager_next_scene(subghz->scene_manager, SubGhzSceneNeedSaving); } else { //Restore default setting subghz_preset_init( subghz, - "AM650", - subghz_setting_get_default_frequency(subghz->setting), + subghz_setting_get_preset_name(subghz->setting, subghz->last_settings->preset), + subghz->last_settings->frequency, NULL, 0); if(!scene_manager_search_and_switch_to_previous_scene( @@ -146,7 +147,11 @@ bool subghz_scene_read_raw_on_event(void* context, SceneManagerEvent event) { subghz->scene_manager, SubGhzSceneStart)) { scene_manager_stop(subghz->scene_manager); view_dispatcher_stop(subghz->view_dispatcher); + } else { + subghz->current_scene = SubGhzSceneStart; } + } else { + subghz->current_scene = SubGhzSceneSaved; } } consumed = true; @@ -170,6 +175,7 @@ bool subghz_scene_read_raw_on_event(void* context, SceneManagerEvent event) { case SubGhzCustomEventViewReadRAWConfig: scene_manager_set_scene_state( subghz->scene_manager, SubGhzSceneReadRAW, SubGhzCustomEventManagerSet); + subghz->current_scene = SubGhzSceneReceiverConfig; scene_manager_next_scene(subghz->scene_manager, SubGhzSceneReceiverConfig); consumed = true; break; @@ -191,6 +197,7 @@ bool subghz_scene_read_raw_on_event(void* context, SceneManagerEvent event) { scene_manager_set_scene_state( subghz->scene_manager, SubGhzSceneReadRAW, SubGhzCustomEventManagerSet); subghz->txrx->rx_key_state = SubGhzRxKeyStateRAWLoad; + subghz->current_scene = SubGhzSceneMoreRAW; scene_manager_next_scene(subghz->scene_manager, SubGhzSceneMoreRAW); consumed = true; } else { @@ -210,6 +217,7 @@ bool subghz_scene_read_raw_on_event(void* context, SceneManagerEvent event) { (subghz->txrx->txrx_state == SubGhzTxRxStateSleep)) { if(!subghz_tx_start(subghz, subghz->txrx->fff_data)) { subghz->txrx->rx_key_state = SubGhzRxKeyStateBack; + subghz->current_scene = SubGhzSceneShowOnlyRx; scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowOnlyRx); } else { DOLPHIN_DEED(DolphinDeedSubGhzSend); @@ -269,6 +277,7 @@ bool subghz_scene_read_raw_on_event(void* context, SceneManagerEvent event) { case SubGhzCustomEventViewReadRAWREC: if(subghz->txrx->rx_key_state != SubGhzRxKeyStateIDLE) { + subghz->current_scene = SubGhzSceneNeedSaving; scene_manager_next_scene(subghz->scene_manager, SubGhzSceneNeedSaving); } else { //subghz_get_preset_name(subghz, subghz->error_str); @@ -289,6 +298,7 @@ bool subghz_scene_read_raw_on_event(void* context, SceneManagerEvent event) { subghz->txrx->rx_key_state = SubGhzRxKeyStateAddKey; } else { string_set_str(subghz->error_str, "Function requires\nan SD card."); + subghz->current_scene = SubGhzSceneShowError; scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowError); } } @@ -300,6 +310,7 @@ bool subghz_scene_read_raw_on_event(void* context, SceneManagerEvent event) { scene_manager_set_scene_state( subghz->scene_manager, SubGhzSceneReadRAW, SubGhzCustomEventManagerSetRAW); subghz->txrx->rx_key_state = SubGhzRxKeyStateBack; + subghz->current_scene = SubGhzSceneSaveName; scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSaveName); } consumed = true; diff --git a/applications/main/subghz/scenes/subghz_scene_receiver.c b/applications/main/subghz/scenes/subghz_scene_receiver.c index a58777d15..1e2bbbbcd 100644 --- a/applications/main/subghz/scenes/subghz_scene_receiver.c +++ b/applications/main/subghz/scenes/subghz_scene_receiver.c @@ -1,6 +1,8 @@ #include "../subghz_i.h" #include "../views/receiver.h" +#define TAG "SubGhzSceneReceiver" + const NotificationSequence subghz_sequence_rx = { &message_green_255, @@ -103,7 +105,11 @@ void subghz_scene_receiver_on_enter(void* context) { if(subghz->txrx->rx_key_state == SubGhzRxKeyStateIDLE) { subghz_preset_init( - subghz, "AM650", subghz_setting_get_default_frequency(subghz->setting), NULL, 0); + subghz, + subghz_setting_get_preset_name(subghz->setting, subghz->last_settings->preset), + subghz->last_settings->frequency, + NULL, + 0); subghz_history_reset(subghz->txrx->history); subghz->txrx->rx_key_state = SubGhzRxKeyStateStart; } @@ -164,15 +170,17 @@ bool subghz_scene_receiver_on_event(void* context, SceneManagerEvent event) { if(subghz->txrx->rx_key_state == SubGhzRxKeyStateAddKey) { subghz->txrx->rx_key_state = SubGhzRxKeyStateExit; + subghz->current_scene = SubGhzSceneNeedSaving; scene_manager_next_scene(subghz->scene_manager, SubGhzSceneNeedSaving); } else { subghz->txrx->rx_key_state = SubGhzRxKeyStateIDLE; subghz_preset_init( subghz, - "AM650", - subghz_setting_get_default_frequency(subghz->setting), + subghz_setting_get_preset_name(subghz->setting, subghz->last_settings->preset), + subghz->last_settings->frequency, NULL, 0); + subghz->current_scene = SubGhzSceneStart; scene_manager_search_and_switch_to_previous_scene( subghz->scene_manager, SubGhzSceneStart); } @@ -181,6 +189,7 @@ bool subghz_scene_receiver_on_event(void* context, SceneManagerEvent event) { case SubGhzCustomEventViewReceiverOK: subghz->txrx->idx_menu_chosen = subghz_view_receiver_get_idx_menu(subghz->subghz_receiver); + subghz->current_scene = SubGhzSceneReceiverInfo; scene_manager_next_scene(subghz->scene_manager, SubGhzSceneReceiverInfo); consumed = true; break; @@ -188,6 +197,9 @@ bool subghz_scene_receiver_on_event(void* context, SceneManagerEvent event) { subghz->state_notifications = SubGhzNotificationStateIDLE; subghz->txrx->idx_menu_chosen = subghz_view_receiver_get_idx_menu(subghz->subghz_receiver); + scene_manager_set_scene_state( + subghz->scene_manager, SubGhzViewIdReceiver, SubGhzCustomEventManagerSet); + subghz->current_scene = SubGhzSceneReceiverConfig; scene_manager_next_scene(subghz->scene_manager, SubGhzSceneReceiverConfig); consumed = true; break; diff --git a/applications/main/subghz/scenes/subghz_scene_receiver_config.c b/applications/main/subghz/scenes/subghz_scene_receiver_config.c index d565666a1..55c177f6d 100644 --- a/applications/main/subghz/scenes/subghz_scene_receiver_config.c +++ b/applications/main/subghz/scenes/subghz_scene_receiver_config.c @@ -145,6 +145,8 @@ static void subghz_scene_receiver_config_set_frequency(VariableItem* item) { (subghz_setting_get_frequency(subghz->setting, index) % 1000000) / 10000); variable_item_set_current_value_text(item, text_buf); subghz->txrx->preset->frequency = subghz_setting_get_frequency(subghz->setting, index); + subghz->last_settings->frequency = subghz->txrx->preset->frequency; + subghz_setting_set_default_frequency(subghz->setting, subghz->txrx->preset->frequency); } else { variable_item_set_current_value_index( item, subghz_setting_get_frequency_default_index(subghz->setting)); @@ -154,11 +156,13 @@ static void subghz_scene_receiver_config_set_frequency(VariableItem* item) { static void subghz_scene_receiver_config_set_preset(VariableItem* item) { SubGhz* subghz = variable_item_get_context(item); uint8_t index = variable_item_get_current_value_index(item); - variable_item_set_current_value_text( - item, subghz_setting_get_preset_name(subghz->setting, index)); + const char* preset_name = subghz_setting_get_preset_name(subghz->setting, index); + variable_item_set_current_value_text(item, preset_name); + subghz->last_settings->preset = index; + subghz_preset_init( subghz, - subghz_setting_get_preset_name(subghz->setting, index), + preset_name, subghz->txrx->preset->frequency, subghz_setting_get_preset_data(subghz->setting, index), subghz_setting_get_preset_data_size(subghz->setting, index)); @@ -246,8 +250,6 @@ void subghz_scene_receiver_config_on_enter(void* context) { subghz); value_index = subghz_scene_receiver_config_next_frequency(subghz->txrx->preset->frequency, subghz); - scene_manager_set_scene_state( - subghz->scene_manager, SubGhzSceneReceiverConfig, (uint32_t)item); variable_item_set_current_value_index(item, value_index); char text_buf[10] = {0}; snprintf( @@ -258,20 +260,6 @@ void subghz_scene_receiver_config_on_enter(void* context) { (subghz_setting_get_frequency(subghz->setting, value_index) % 1000000) / 10000); variable_item_set_current_value_text(item, text_buf); - if(scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneReadRAW) != - SubGhzCustomEventManagerSet) { - item = variable_item_list_add( - subghz->variable_item_list, - "Hopping:", - HOPPING_COUNT, - subghz_scene_receiver_config_set_hopping_running, - subghz); - value_index = subghz_scene_receiver_config_hopper_value_index( - subghz->txrx->hopper_state, hopping_value, HOPPING_COUNT, subghz); - variable_item_set_current_value_index(item, value_index); - variable_item_set_current_value_text(item, hopping_text[value_index]); - } - item = variable_item_list_add( subghz->variable_item_list, "Modulation:", @@ -286,6 +274,19 @@ void subghz_scene_receiver_config_on_enter(void* context) { if(scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneReadRAW) != SubGhzCustomEventManagerSet) { + // Hopping + item = variable_item_list_add( + subghz->variable_item_list, + "Hopping:", + HOPPING_COUNT, + subghz_scene_receiver_config_set_hopping_running, + subghz); + value_index = subghz_scene_receiver_config_hopper_value_index( + subghz->txrx->hopper_state, hopping_value, HOPPING_COUNT, subghz); + variable_item_set_current_value_index(item, value_index); + variable_item_set_current_value_text(item, hopping_text[value_index]); + + // Detect Raw item = variable_item_list_add( subghz->variable_item_list, "Detect Raw:", @@ -298,10 +299,8 @@ void subghz_scene_receiver_config_on_enter(void* context) { DETECT_RAW_COUNT); variable_item_set_current_value_index(item, value_index); variable_item_set_current_value_text(item, detect_raw_text[value_index]); - } - if(scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneReadRAW) != - SubGhzCustomEventManagerSet) { + // RSSI item = variable_item_list_add( subghz->variable_item_list, "RSSI for Raw:", @@ -315,10 +314,8 @@ void subghz_scene_receiver_config_on_enter(void* context) { RSSI_THRESHOLD_COUNT); variable_item_set_current_value_index(item, value_index); variable_item_set_current_value_text(item, rssi_threshold_text[value_index]); - } - if(scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneReadRAW) != - SubGhzCustomEventManagerSet) { + // Lock keyboard variable_item_list_add(subghz->variable_item_list, "Lock Keyboard", 1, NULL, NULL); variable_item_list_set_enter_callback( subghz->variable_item_list, @@ -345,8 +342,8 @@ bool subghz_scene_receiver_config_on_event(void* context, SceneManagerEvent even void subghz_scene_receiver_config_on_exit(void* context) { SubGhz* subghz = context; - variable_item_list_set_selected_item(subghz->variable_item_list, 0); variable_item_list_reset(subghz->variable_item_list); + SAVE_SUBGHZ_LAST_SETTINGS(&subghz->last_settings); scene_manager_set_scene_state( subghz->scene_manager, SubGhzSceneReadRAW, SubGhzCustomEventManagerNoSet); } diff --git a/applications/main/subghz/subghz.c b/applications/main/subghz/subghz.c index 08de91f91..666246af6 100644 --- a/applications/main/subghz/subghz.c +++ b/applications/main/subghz/subghz.c @@ -5,6 +5,8 @@ #include #include "subghz_i.h" +#define TAG "SubGhzApp" + bool subghz_custom_event_callback(void* context, uint32_t event) { furi_assert(context); SubGhz* subghz = context; @@ -174,13 +176,30 @@ SubGhz* subghz_alloc() { subghz->setting = subghz_setting_alloc(); subghz_setting_load(subghz->setting, EXT_PATH("subghz/assets/setting_user")); + // Load last used values for Read, Read RAW, etc. or default + subghz_last_settings_check_struct(); + LOAD_SUBGHZ_LAST_SETTINGS(&subghz->last_settings); +#if DEBUG + FURI_LOG_I( + TAG, + "last frequency: %d, preset: %d", + subghz->last_settings->frequency, + subghz->last_settings->preset); +#endif + subghz_setting_set_default_frequency(subghz->setting, subghz->last_settings->frequency); + SAVE_SUBGHZ_LAST_SETTINGS(&subghz->last_settings); + //init Worker & Protocol & History & KeyBoard subghz->lock = SubGhzLockOff; subghz->txrx = malloc(sizeof(SubGhzTxRx)); subghz->txrx->preset = malloc(sizeof(SubGhzPresetDefinition)); string_init(subghz->txrx->preset->name); subghz_preset_init( - subghz, "AM650", subghz_setting_get_default_frequency(subghz->setting), NULL, 0); + subghz, + subghz_setting_get_preset_name(subghz->setting, subghz->last_settings->preset), + subghz->last_settings->frequency, + NULL, + 0); subghz->txrx->txrx_state = SubGhzTxRxStateSleep; subghz->txrx->hopper_state = SubGhzHopperStateOFF; diff --git a/applications/main/subghz/subghz_i.h b/applications/main/subghz/subghz_i.h index 945228a45..f141b5399 100644 --- a/applications/main/subghz/subghz_i.h +++ b/applications/main/subghz/subghz_i.h @@ -33,6 +33,7 @@ #include "subghz_history.h" #include "subghz_setting.h" +#include "subghz_last_settings.h" #include #include @@ -100,10 +101,11 @@ struct SubGhz { SubGhzTestPacket* subghz_test_packet; string_t error_str; SubGhzSetting* setting; + SubGhzLastSettings* last_settings; SubGhzLock lock; bool in_decoder_scene; - + SubGhzScene current_scene; void* rpc_ctx; }; diff --git a/applications/main/subghz/subghz_last_settings.c b/applications/main/subghz/subghz_last_settings.c new file mode 100644 index 000000000..cfc7b4e2e --- /dev/null +++ b/applications/main/subghz/subghz_last_settings.c @@ -0,0 +1,19 @@ +#include "subghz_last_settings.h" + +#define TAG "SubGhzLastSettings" + +// 1 = "AM650" +// "AM270", "AM650", "FM238", "FM476", +#define SUBGHZ_LAST_SETTING_DEFAULT_PRESET 1 +#define SUBGHZ_LAST_SETTING_DEFAULT_FREQUENCY 433920000 + +void subghz_last_settings_check_struct(void) { + Storage* storage = furi_record_open(RECORD_STORAGE); + if(!storage_file_exists(storage, SUBGHZ_LAST_SETTINGS_PATH)) { + SubGhzLastSettings* instance = malloc(sizeof(SubGhzLastSettings)); + instance->frequency = SUBGHZ_LAST_SETTING_DEFAULT_FREQUENCY; + instance->preset = SUBGHZ_LAST_SETTING_DEFAULT_PRESET; + SAVE_SUBGHZ_LAST_SETTINGS(&instance); + } + furi_record_close(RECORD_STORAGE); +} \ No newline at end of file diff --git a/applications/main/subghz/subghz_last_settings.h b/applications/main/subghz/subghz_last_settings.h new file mode 100644 index 000000000..27e67e252 --- /dev/null +++ b/applications/main/subghz/subghz_last_settings.h @@ -0,0 +1,36 @@ +#pragma once + +#include "subghz_last_settings_filename.h" + +#include +#include +#include +#include +#include + +#define SUBGHZ_LAST_SETTINGS_VER (1) +#define SUBGHZ_LAST_SETTINGS_PATH EXT_PATH(SUBGHZ_LAST_SETTINGS_FILE_NAME) +#define SUBGHZ_LAST_SETTINGS_MAGIC (0xCC) + +#define SAVE_SUBGHZ_LAST_SETTINGS(x) \ + saved_struct_save( \ + SUBGHZ_LAST_SETTINGS_PATH, \ + (x), \ + sizeof(SubGhzLastSettings), \ + SUBGHZ_LAST_SETTINGS_MAGIC, \ + SUBGHZ_LAST_SETTINGS_VER) + +#define LOAD_SUBGHZ_LAST_SETTINGS(x) \ + saved_struct_load( \ + SUBGHZ_LAST_SETTINGS_PATH, \ + (x), \ + sizeof(SubGhzLastSettings), \ + SUBGHZ_LAST_SETTINGS_MAGIC, \ + SUBGHZ_LAST_SETTINGS_VER) + +typedef struct { + uint32_t frequency; + uint8_t preset; +} SubGhzLastSettings; + +void subghz_last_settings_check_struct(void); \ No newline at end of file diff --git a/applications/main/subghz/subghz_last_settings_filename.h b/applications/main/subghz/subghz_last_settings_filename.h new file mode 100644 index 000000000..3f34262c3 --- /dev/null +++ b/applications/main/subghz/subghz_last_settings_filename.h @@ -0,0 +1,3 @@ +#pragma once + +#define SUBGHZ_LAST_SETTINGS_FILE_NAME ".subghz.settings" \ No newline at end of file diff --git a/applications/main/subghz/subghz_setting.c b/applications/main/subghz/subghz_setting.c index b8f3794eb..2e94011cf 100644 --- a/applications/main/subghz/subghz_setting.c +++ b/applications/main/subghz/subghz_setting.c @@ -260,13 +260,7 @@ void subghz_setting_load(SubGhzSetting* instance, const char* file_path) { break; } if(flipper_format_read_uint32(fff_data_file, "Default_frequency", &temp_data32, 1)) { - for - M_EACH(frequency, instance->frequencies, FrequencyList_t) { - *frequency &= FREQUENCY_MASK; - if(*frequency == temp_data32) { - *frequency |= FREQUENCY_FLAG_DEFAULT; - } - } + subghz_setting_set_default_frequency(instance, temp_data32); } // custom preset (optional) @@ -294,6 +288,16 @@ void subghz_setting_load(SubGhzSetting* instance, const char* file_path) { } } +void subghz_setting_set_default_frequency(SubGhzSetting* instance, uint32_t frequency_to_setup) { + for + M_EACH(frequency, instance->frequencies, FrequencyList_t) { + *frequency &= FREQUENCY_MASK; + if(*frequency == frequency_to_setup) { + *frequency |= FREQUENCY_FLAG_DEFAULT; + } + } +} + size_t subghz_setting_get_frequency_count(SubGhzSetting* instance) { furi_assert(instance); return FrequencyList_size(instance->frequencies); @@ -311,6 +315,9 @@ size_t subghz_setting_get_preset_count(SubGhzSetting* instance) { const char* subghz_setting_get_preset_name(SubGhzSetting* instance, size_t idx) { furi_assert(instance); + if(idx >= SubGhzSettingCustomPresetItemArray_size(instance->preset->data)) { + idx = 0; + } SubGhzSettingCustomPresetItem* item = SubGhzSettingCustomPresetItemArray_get(instance->preset->data, idx); return string_get_cstr(item->custom_preset_name); diff --git a/applications/main/subghz/subghz_setting.h b/applications/main/subghz/subghz_setting.h index 0590cf499..d6fde1bd6 100644 --- a/applications/main/subghz/subghz_setting.h +++ b/applications/main/subghz/subghz_setting.h @@ -46,3 +46,5 @@ uint32_t subghz_setting_get_hopper_frequency(SubGhzSetting* instance, size_t idx uint32_t subghz_setting_get_frequency_default_index(SubGhzSetting* instance); uint32_t subghz_setting_get_default_frequency(SubGhzSetting* instance); + +void subghz_setting_set_default_frequency(SubGhzSetting* instance, uint32_t frequency_to_setup); From 0f0473bee6ba87d239682a7f7cafa54d4dee8770 Mon Sep 17 00:00:00 2001 From: derskythe Date: Wed, 28 Sep 2022 03:27:47 +0400 Subject: [PATCH 23/47] fix bug with invalid settings values in config --- applications/main/subghz/subghz.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/applications/main/subghz/subghz.c b/applications/main/subghz/subghz.c index 666246af6..39196fbfc 100644 --- a/applications/main/subghz/subghz.c +++ b/applications/main/subghz/subghz.c @@ -179,8 +179,8 @@ SubGhz* subghz_alloc() { // Load last used values for Read, Read RAW, etc. or default subghz_last_settings_check_struct(); LOAD_SUBGHZ_LAST_SETTINGS(&subghz->last_settings); -#if DEBUG - FURI_LOG_I( +#if FURI_DEBUG + FURI_LOG_D( TAG, "last frequency: %d, preset: %d", subghz->last_settings->frequency, From a3db6718c2d10d32f4c1e04c5a7007747e5f9397 Mon Sep 17 00:00:00 2001 From: derskythe Date: Wed, 28 Sep 2022 04:31:29 +0400 Subject: [PATCH 24/47] fix bug with invalid settings values in config --- .../main/subghz/scenes/subghz_scene_receiver_config.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/applications/main/subghz/scenes/subghz_scene_receiver_config.c b/applications/main/subghz/scenes/subghz_scene_receiver_config.c index 55c177f6d..5fc019f71 100644 --- a/applications/main/subghz/scenes/subghz_scene_receiver_config.c +++ b/applications/main/subghz/scenes/subghz_scene_receiver_config.c @@ -2,6 +2,8 @@ #include +#define TAG "SubGhzSceneReceiverConfig" + enum SubGhzSettingIndex { SubGhzSettingIndexFrequency, SubGhzSettingIndexHopping, @@ -242,6 +244,13 @@ void subghz_scene_receiver_config_on_enter(void* context) { VariableItem* item; uint8_t value_index; +#if FURI_DEBUG + FURI_LOG_D( + TAG, + "last frequency: %d, preset: %d", + subghz->last_settings->frequency, + subghz->last_settings->preset); +#endif item = variable_item_list_add( subghz->variable_item_list, "Frequency:", From 22a87d570707309adc738b1595af7cf2f54d4904 Mon Sep 17 00:00:00 2001 From: derskythe Date: Wed, 28 Sep 2022 05:49:06 +0400 Subject: [PATCH 25/47] struct doesn't correct written --- .../scenes/subghz_scene_receiver_config.c | 2 +- applications/main/subghz/subghz.c | 7 +- .../main/subghz/subghz_last_settings.c | 94 ++++++++++++++++++- .../main/subghz/subghz_last_settings.h | 33 ++----- .../subghz/subghz_last_settings_filename.h | 3 - 5 files changed, 103 insertions(+), 36 deletions(-) delete mode 100644 applications/main/subghz/subghz_last_settings_filename.h diff --git a/applications/main/subghz/scenes/subghz_scene_receiver_config.c b/applications/main/subghz/scenes/subghz_scene_receiver_config.c index 5fc019f71..affb01a0b 100644 --- a/applications/main/subghz/scenes/subghz_scene_receiver_config.c +++ b/applications/main/subghz/scenes/subghz_scene_receiver_config.c @@ -352,7 +352,7 @@ bool subghz_scene_receiver_config_on_event(void* context, SceneManagerEvent even void subghz_scene_receiver_config_on_exit(void* context) { SubGhz* subghz = context; variable_item_list_reset(subghz->variable_item_list); - SAVE_SUBGHZ_LAST_SETTINGS(&subghz->last_settings); + subghz_last_settings_save(subghz->last_settings); scene_manager_set_scene_state( subghz->scene_manager, SubGhzSceneReadRAW, SubGhzCustomEventManagerNoSet); } diff --git a/applications/main/subghz/subghz.c b/applications/main/subghz/subghz.c index 39196fbfc..8b9dd399f 100644 --- a/applications/main/subghz/subghz.c +++ b/applications/main/subghz/subghz.c @@ -177,8 +177,9 @@ SubGhz* subghz_alloc() { subghz_setting_load(subghz->setting, EXT_PATH("subghz/assets/setting_user")); // Load last used values for Read, Read RAW, etc. or default - subghz_last_settings_check_struct(); - LOAD_SUBGHZ_LAST_SETTINGS(&subghz->last_settings); + subghz->last_settings = subghz_last_settings_alloc(); + subghz_last_settings_load( + subghz->last_settings, subghz_setting_get_preset_count(subghz->setting)); #if FURI_DEBUG FURI_LOG_D( TAG, @@ -187,7 +188,6 @@ SubGhz* subghz_alloc() { subghz->last_settings->preset); #endif subghz_setting_set_default_frequency(subghz->setting, subghz->last_settings->frequency); - SAVE_SUBGHZ_LAST_SETTINGS(&subghz->last_settings); //init Worker & Protocol & History & KeyBoard subghz->lock = SubGhzLockOff; @@ -306,6 +306,7 @@ void subghz_free(SubGhz* subghz) { //setting subghz_setting_free(subghz->setting); + subghz_last_settings_free(subghz->last_settings); //Worker & Protocol & History subghz_receiver_free(subghz->txrx->receiver); diff --git a/applications/main/subghz/subghz_last_settings.c b/applications/main/subghz/subghz_last_settings.c index cfc7b4e2e..764c78fea 100644 --- a/applications/main/subghz/subghz_last_settings.c +++ b/applications/main/subghz/subghz_last_settings.c @@ -1,19 +1,105 @@ #include "subghz_last_settings.h" +#include +#include +#include #define TAG "SubGhzLastSettings" +#define SUBGHZ_LAST_SETTING_FILE_TYPE "Flipper SubGhz Last Setting File" +#define SUBGHZ_LAST_SETTING_FILE_VERSION 1 +#define SUBGHZ_LAST_SETTINGS_PATH EXT_PATH(".subghz.settings") // 1 = "AM650" // "AM270", "AM650", "FM238", "FM476", #define SUBGHZ_LAST_SETTING_DEFAULT_PRESET 1 #define SUBGHZ_LAST_SETTING_DEFAULT_FREQUENCY 433920000 -void subghz_last_settings_check_struct(void) { +SubGhzLastSettings* subghz_last_settings_alloc(void) { + SubGhzLastSettings* instance = malloc(sizeof(SubGhzLastSettings)); + return instance; +} + +void subghz_last_settings_free(SubGhzLastSettings* instance) { + furi_assert(instance); + free(instance); +} + +void subghz_last_settings_load(SubGhzLastSettings* instance, size_t preset_count) { + furi_assert(instance); +#if FURI_DEBUG + FURI_LOG_I(TAG, "subghz_last_settings_load"); +#endif + Storage* storage = furi_record_open(RECORD_STORAGE); - if(!storage_file_exists(storage, SUBGHZ_LAST_SETTINGS_PATH)) { - SubGhzLastSettings* instance = malloc(sizeof(SubGhzLastSettings)); + FlipperFormat* fff_data_file = flipper_format_file_alloc(storage); + + uint32_t temp_frequency = 0; + int32_t temp_preset = 0; + + if(FSE_OK == storage_sd_status(storage) && SUBGHZ_LAST_SETTINGS_PATH && + flipper_format_file_open_existing(fff_data_file, SUBGHZ_LAST_SETTINGS_PATH)) { + flipper_format_read_int32(fff_data_file, "Preset", (int32_t*)&temp_preset, 1); + flipper_format_read_uint32(fff_data_file, "Frequency", (uint32_t*)&temp_frequency, 1); + } else { + FURI_LOG_E(TAG, "Error open file %s", SUBGHZ_LAST_SETTINGS_PATH); + } + + if(temp_frequency == 0 || !furi_hal_subghz_is_tx_allowed(temp_frequency)) { + FURI_LOG_W(TAG, "Last used frequency not found or can't be used!"); instance->frequency = SUBGHZ_LAST_SETTING_DEFAULT_FREQUENCY; instance->preset = SUBGHZ_LAST_SETTING_DEFAULT_PRESET; - SAVE_SUBGHZ_LAST_SETTINGS(&instance); + } else { + instance->frequency = temp_frequency; + + if(temp_preset > (int32_t)preset_count - 1 || temp_preset < 0) { + FURI_LOG_W(TAG, "Last used preset no found"); + instance->preset = SUBGHZ_LAST_SETTING_DEFAULT_PRESET; + } else { + instance->preset = temp_preset; + } } + + flipper_format_free(fff_data_file); furi_record_close(RECORD_STORAGE); +} + +bool subghz_last_settings_save(SubGhzLastSettings* instance) { + furi_assert(instance); +#if FURI_DEBUG + FURI_LOG_I(TAG, "subghz_last_settings_save"); +#endif + + bool saved = false; + Storage* storage = furi_record_open(RECORD_STORAGE); + FlipperFormat* file = flipper_format_file_alloc(storage); + + do { + if(FSE_OK != storage_sd_status(storage)) { + break; + } + + // Open file + if(!flipper_format_file_open_always(file, SUBGHZ_LAST_SETTINGS_PATH)) break; + + // Write header + if(!flipper_format_write_header_cstr( + file, SUBGHZ_LAST_SETTING_FILE_TYPE, SUBGHZ_LAST_SETTING_FILE_VERSION)) + break; + + if(!flipper_format_insert_or_update_int32(file, "Preset", &instance->preset, 1)) { + break; + } + if(!flipper_format_insert_or_update_uint32(file, "Frequency", &instance->frequency, 1)) { + break; + } + saved = true; + } while(0); + + if(!saved) { + FURI_LOG_E(TAG, "Error save file %s", SUBGHZ_LAST_SETTINGS_PATH); + } + + flipper_format_free(file); + furi_record_close(RECORD_STORAGE); + + return saved; } \ No newline at end of file diff --git a/applications/main/subghz/subghz_last_settings.h b/applications/main/subghz/subghz_last_settings.h index 27e67e252..8067bb66a 100644 --- a/applications/main/subghz/subghz_last_settings.h +++ b/applications/main/subghz/subghz_last_settings.h @@ -1,36 +1,19 @@ #pragma once -#include "subghz_last_settings_filename.h" - #include #include #include -#include #include -#define SUBGHZ_LAST_SETTINGS_VER (1) -#define SUBGHZ_LAST_SETTINGS_PATH EXT_PATH(SUBGHZ_LAST_SETTINGS_FILE_NAME) -#define SUBGHZ_LAST_SETTINGS_MAGIC (0xCC) - -#define SAVE_SUBGHZ_LAST_SETTINGS(x) \ - saved_struct_save( \ - SUBGHZ_LAST_SETTINGS_PATH, \ - (x), \ - sizeof(SubGhzLastSettings), \ - SUBGHZ_LAST_SETTINGS_MAGIC, \ - SUBGHZ_LAST_SETTINGS_VER) - -#define LOAD_SUBGHZ_LAST_SETTINGS(x) \ - saved_struct_load( \ - SUBGHZ_LAST_SETTINGS_PATH, \ - (x), \ - sizeof(SubGhzLastSettings), \ - SUBGHZ_LAST_SETTINGS_MAGIC, \ - SUBGHZ_LAST_SETTINGS_VER) - typedef struct { uint32_t frequency; - uint8_t preset; + int32_t preset; } SubGhzLastSettings; -void subghz_last_settings_check_struct(void); \ No newline at end of file +SubGhzLastSettings* subghz_last_settings_alloc(void); + +void subghz_last_settings_free(SubGhzLastSettings* instance); + +void subghz_last_settings_load(SubGhzLastSettings* instance, size_t preset_count); + +bool subghz_last_settings_save(SubGhzLastSettings* instance); \ No newline at end of file diff --git a/applications/main/subghz/subghz_last_settings_filename.h b/applications/main/subghz/subghz_last_settings_filename.h deleted file mode 100644 index 3f34262c3..000000000 --- a/applications/main/subghz/subghz_last_settings_filename.h +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once - -#define SUBGHZ_LAST_SETTINGS_FILE_NAME ".subghz.settings" \ No newline at end of file From 406247c5d875db68f3144e464fa70645bc3d8ccf Mon Sep 17 00:00:00 2001 From: derskythe Date: Wed, 28 Sep 2022 06:22:02 +0400 Subject: [PATCH 26/47] Ok button in frequency analyzer will set this frequency to receiver --- .../scenes/subghz_scene_frequency_analyzer.c | 15 ++- .../subghz/views/subghz_frequency_analyzer.c | 114 ++++++++++++++++++ .../subghz/views/subghz_frequency_analyzer.h | 2 + 3 files changed, 128 insertions(+), 3 deletions(-) diff --git a/applications/main/subghz/scenes/subghz_scene_frequency_analyzer.c b/applications/main/subghz/scenes/subghz_scene_frequency_analyzer.c index f067f9859..a78fccd3f 100644 --- a/applications/main/subghz/scenes/subghz_scene_frequency_analyzer.c +++ b/applications/main/subghz/scenes/subghz_scene_frequency_analyzer.c @@ -1,5 +1,4 @@ #include "../subghz_i.h" -#include "../views/subghz_frequency_analyzer.h" #include void subghz_scene_frequency_analyzer_callback(SubGhzCustomEvent event, void* context) { @@ -17,8 +16,18 @@ void subghz_scene_frequency_analyzer_on_enter(void* context) { } bool subghz_scene_frequency_analyzer_on_event(void* context, SceneManagerEvent event) { - UNUSED(context); - UNUSED(event); + SubGhz* subghz = context; + if(event.type == SceneManagerEventTypeCustom && + event.event == SubGhzCustomEventViewReceiverOK) { + uint32_t frequency = + subghz_frequency_analyzer_get_frequency_to_save(subghz->subghz_frequency_analyzer); + if(frequency > 0) { + subghz->last_settings->frequency = frequency; + subghz_last_settings_save(subghz->last_settings); + } + + return true; + } return false; } diff --git a/applications/main/subghz/views/subghz_frequency_analyzer.c b/applications/main/subghz/views/subghz_frequency_analyzer.c index 5be00888f..7d1239cd8 100644 --- a/applications/main/subghz/views/subghz_frequency_analyzer.c +++ b/applications/main/subghz/views/subghz_frequency_analyzer.c @@ -30,6 +30,43 @@ static const NotificationSequence sequence_hw_blink_stop = { NULL, }; +static const NotificationSequence sequence_saved = { + &message_blink_stop, + &message_blue_0, + &message_green_0, + &message_red_255, + &message_vibro_on, + &message_delay_100, + &message_vibro_off, + NULL, +}; +static const NotificationSequence sequence_not_saved = { + &message_blink_stop, + &message_green_255, + &message_blue_255, + &message_red_255, + NULL, +}; + +static const uint32_t subghz_frequency_list[17] = { + 300000000, + 303875000, + 304250000, + 310000000, + 315000000, + 318000000, + 390000000, + 418000000, + 433075000, + 433420000, + 433920000, + 434420000, + 434775000, + 438900000, + 868350000, + 915000000, + 925000000}; + typedef enum { SubGhzFrequencyAnalyzerStatusIDLE, } SubGhzFrequencyAnalyzerStatus; @@ -50,6 +87,7 @@ struct SubGhzFrequencyAnalyzer { typedef struct { uint32_t frequency; uint32_t frequency_last; + uint32_t frequency_to_save; float rssi; float rssi_last; float trigger; @@ -163,6 +201,33 @@ void subghz_frequency_analyzer_draw(Canvas* canvas, SubGhzFrequencyAnalyzerModel elements_button_right(canvas, "T+"); } +uint32_t subghz_frequency_find_correct(uint32_t input) { + uint32_t prev_freq = 0; + uint32_t current = 0; + uint32_t result = 0; +#if FURI_DEBUG + FURI_LOG_D(TAG, "input: %d", input); +#endif + for(size_t i = 0; i < sizeof(subghz_frequency_list); i++) { + current = subghz_frequency_list[i]; + if(current == input) { + result = current; + break; + } + if(current > input && prev_freq < input) { + if(current - input < input - prev_freq) { + result = current; + } else { + result = prev_freq; + } + break; + } + prev_freq = current; + } + + return result; +} + bool subghz_frequency_analyzer_input(InputEvent* event, void* context) { furi_assert(context); SubGhzFrequencyAnalyzer* instance = context; @@ -201,6 +266,43 @@ bool subghz_frequency_analyzer_input(InputEvent* event, void* context) { need_redraw = true; } + if(event->type == InputTypeShort && event->key == InputKeyOk) { + with_view_model( + instance->view, (SubGhzFrequencyAnalyzerModel * model) { + uint32_t prev_freq_to_save = model->frequency_to_save; + uint32_t frequency_candidate = 0; + if(model->frequency != 0) { + frequency_candidate = model->frequency; + } else if(model->frequency_last != 0) { + frequency_candidate = model->frequency_last; + } + if(frequency_candidate == 0 || + !furi_hal_subghz_is_frequency_valid(frequency_candidate) || + prev_freq_to_save == frequency_candidate) { + frequency_candidate = 0; + } else { + frequency_candidate = subghz_frequency_find_correct(frequency_candidate); + } + if(frequency_candidate > 0 && frequency_candidate != model->frequency_to_save) { +#if FURI_DEBUG + FURI_LOG_D( + TAG, + "frequency_to_save: %d, candidate: %d", + model->frequency_to_save, + frequency_candidate); +#endif + model->frequency_to_save = frequency_candidate; + notification_message(instance->notifications, &sequence_saved); + instance->callback(SubGhzCustomEventViewReceiverOK, instance->context); + notification_message(instance->notifications, &sequence_hw_blink); + } else { + notification_message(instance->notifications, &sequence_not_saved); + notification_message(instance->notifications, &sequence_hw_blink); + } + return true; + }); + } + if(need_redraw) { SubGhzFrequencyAnalyzer* instance = context; with_view_model( @@ -309,6 +411,7 @@ void subghz_frequency_analyzer_enter(void* context) { model->rssi_last = 0; model->frequency = 0; model->frequency_last = 0; + model->frequency_to_save = 0; model->trigger = RSSI_MIN; return true; }); @@ -359,4 +462,15 @@ void subghz_frequency_analyzer_free(SubGhzFrequencyAnalyzer* instance) { View* subghz_frequency_analyzer_get_view(SubGhzFrequencyAnalyzer* instance) { furi_assert(instance); return instance->view; +} + +uint32_t subghz_frequency_analyzer_get_frequency_to_save(SubGhzFrequencyAnalyzer* instance) { + uint32_t frequency; + with_view_model( + instance->view, (SubGhzFrequencyAnalyzerModel * model) { + frequency = model->frequency_to_save; + return false; + }); + + return frequency; } \ No newline at end of file diff --git a/applications/main/subghz/views/subghz_frequency_analyzer.h b/applications/main/subghz/views/subghz_frequency_analyzer.h index 3de003bf8..5e00c6444 100644 --- a/applications/main/subghz/views/subghz_frequency_analyzer.h +++ b/applications/main/subghz/views/subghz_frequency_analyzer.h @@ -17,3 +17,5 @@ SubGhzFrequencyAnalyzer* subghz_frequency_analyzer_alloc(); void subghz_frequency_analyzer_free(SubGhzFrequencyAnalyzer* subghz_static); View* subghz_frequency_analyzer_get_view(SubGhzFrequencyAnalyzer* subghz_static); + +uint32_t subghz_frequency_analyzer_get_frequency_to_save(SubGhzFrequencyAnalyzer* instance); From 8be08093e2825ad874a13f6268eaa1a90ca76a72 Mon Sep 17 00:00:00 2001 From: derskythe Date: Wed, 28 Sep 2022 06:28:23 +0400 Subject: [PATCH 27/47] Change name of file to not able to "Run in App" in Browser --- applications/main/subghz/subghz_last_settings.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/applications/main/subghz/subghz_last_settings.c b/applications/main/subghz/subghz_last_settings.c index 764c78fea..a4e89c0ee 100644 --- a/applications/main/subghz/subghz_last_settings.c +++ b/applications/main/subghz/subghz_last_settings.c @@ -7,7 +7,7 @@ #define SUBGHZ_LAST_SETTING_FILE_TYPE "Flipper SubGhz Last Setting File" #define SUBGHZ_LAST_SETTING_FILE_VERSION 1 -#define SUBGHZ_LAST_SETTINGS_PATH EXT_PATH(".subghz.settings") +#define SUBGHZ_LAST_SETTINGS_PATH EXT_PATH("subghz.settings") // 1 = "AM650" // "AM270", "AM650", "FM238", "FM476", #define SUBGHZ_LAST_SETTING_DEFAULT_PRESET 1 From 746b732034ae833c65aed1dfde9f9aadbb99ce2e Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Wed, 28 Sep 2022 05:49:21 +0300 Subject: [PATCH 28/47] remove unused code --- .../main/subghz/scenes/subghz_scene_read_raw.c | 11 ----------- .../main/subghz/scenes/subghz_scene_receiver.c | 4 ---- applications/main/subghz/subghz_i.h | 1 - 3 files changed, 16 deletions(-) diff --git a/applications/main/subghz/scenes/subghz_scene_read_raw.c b/applications/main/subghz/scenes/subghz_scene_read_raw.c index 8a087e134..7392221dc 100644 --- a/applications/main/subghz/scenes/subghz_scene_read_raw.c +++ b/applications/main/subghz/scenes/subghz_scene_read_raw.c @@ -131,7 +131,6 @@ bool subghz_scene_read_raw_on_event(void* context, SceneManagerEvent event) { if((subghz->txrx->rx_key_state == SubGhzRxKeyStateAddKey) || (subghz->txrx->rx_key_state == SubGhzRxKeyStateBack)) { subghz->txrx->rx_key_state = SubGhzRxKeyStateExit; - subghz->current_scene = SubGhzSceneNeedSaving; scene_manager_next_scene(subghz->scene_manager, SubGhzSceneNeedSaving); } else { //Restore default setting @@ -147,11 +146,7 @@ bool subghz_scene_read_raw_on_event(void* context, SceneManagerEvent event) { subghz->scene_manager, SubGhzSceneStart)) { scene_manager_stop(subghz->scene_manager); view_dispatcher_stop(subghz->view_dispatcher); - } else { - subghz->current_scene = SubGhzSceneStart; } - } else { - subghz->current_scene = SubGhzSceneSaved; } } consumed = true; @@ -175,7 +170,6 @@ bool subghz_scene_read_raw_on_event(void* context, SceneManagerEvent event) { case SubGhzCustomEventViewReadRAWConfig: scene_manager_set_scene_state( subghz->scene_manager, SubGhzSceneReadRAW, SubGhzCustomEventManagerSet); - subghz->current_scene = SubGhzSceneReceiverConfig; scene_manager_next_scene(subghz->scene_manager, SubGhzSceneReceiverConfig); consumed = true; break; @@ -197,7 +191,6 @@ bool subghz_scene_read_raw_on_event(void* context, SceneManagerEvent event) { scene_manager_set_scene_state( subghz->scene_manager, SubGhzSceneReadRAW, SubGhzCustomEventManagerSet); subghz->txrx->rx_key_state = SubGhzRxKeyStateRAWLoad; - subghz->current_scene = SubGhzSceneMoreRAW; scene_manager_next_scene(subghz->scene_manager, SubGhzSceneMoreRAW); consumed = true; } else { @@ -217,7 +210,6 @@ bool subghz_scene_read_raw_on_event(void* context, SceneManagerEvent event) { (subghz->txrx->txrx_state == SubGhzTxRxStateSleep)) { if(!subghz_tx_start(subghz, subghz->txrx->fff_data)) { subghz->txrx->rx_key_state = SubGhzRxKeyStateBack; - subghz->current_scene = SubGhzSceneShowOnlyRx; scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowOnlyRx); } else { DOLPHIN_DEED(DolphinDeedSubGhzSend); @@ -277,7 +269,6 @@ bool subghz_scene_read_raw_on_event(void* context, SceneManagerEvent event) { case SubGhzCustomEventViewReadRAWREC: if(subghz->txrx->rx_key_state != SubGhzRxKeyStateIDLE) { - subghz->current_scene = SubGhzSceneNeedSaving; scene_manager_next_scene(subghz->scene_manager, SubGhzSceneNeedSaving); } else { //subghz_get_preset_name(subghz, subghz->error_str); @@ -298,7 +289,6 @@ bool subghz_scene_read_raw_on_event(void* context, SceneManagerEvent event) { subghz->txrx->rx_key_state = SubGhzRxKeyStateAddKey; } else { string_set_str(subghz->error_str, "Function requires\nan SD card."); - subghz->current_scene = SubGhzSceneShowError; scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowError); } } @@ -310,7 +300,6 @@ bool subghz_scene_read_raw_on_event(void* context, SceneManagerEvent event) { scene_manager_set_scene_state( subghz->scene_manager, SubGhzSceneReadRAW, SubGhzCustomEventManagerSetRAW); subghz->txrx->rx_key_state = SubGhzRxKeyStateBack; - subghz->current_scene = SubGhzSceneSaveName; scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSaveName); } consumed = true; diff --git a/applications/main/subghz/scenes/subghz_scene_receiver.c b/applications/main/subghz/scenes/subghz_scene_receiver.c index 1e2bbbbcd..4a35c5f2c 100644 --- a/applications/main/subghz/scenes/subghz_scene_receiver.c +++ b/applications/main/subghz/scenes/subghz_scene_receiver.c @@ -170,7 +170,6 @@ bool subghz_scene_receiver_on_event(void* context, SceneManagerEvent event) { if(subghz->txrx->rx_key_state == SubGhzRxKeyStateAddKey) { subghz->txrx->rx_key_state = SubGhzRxKeyStateExit; - subghz->current_scene = SubGhzSceneNeedSaving; scene_manager_next_scene(subghz->scene_manager, SubGhzSceneNeedSaving); } else { subghz->txrx->rx_key_state = SubGhzRxKeyStateIDLE; @@ -180,7 +179,6 @@ bool subghz_scene_receiver_on_event(void* context, SceneManagerEvent event) { subghz->last_settings->frequency, NULL, 0); - subghz->current_scene = SubGhzSceneStart; scene_manager_search_and_switch_to_previous_scene( subghz->scene_manager, SubGhzSceneStart); } @@ -189,7 +187,6 @@ bool subghz_scene_receiver_on_event(void* context, SceneManagerEvent event) { case SubGhzCustomEventViewReceiverOK: subghz->txrx->idx_menu_chosen = subghz_view_receiver_get_idx_menu(subghz->subghz_receiver); - subghz->current_scene = SubGhzSceneReceiverInfo; scene_manager_next_scene(subghz->scene_manager, SubGhzSceneReceiverInfo); consumed = true; break; @@ -199,7 +196,6 @@ bool subghz_scene_receiver_on_event(void* context, SceneManagerEvent event) { subghz_view_receiver_get_idx_menu(subghz->subghz_receiver); scene_manager_set_scene_state( subghz->scene_manager, SubGhzViewIdReceiver, SubGhzCustomEventManagerSet); - subghz->current_scene = SubGhzSceneReceiverConfig; scene_manager_next_scene(subghz->scene_manager, SubGhzSceneReceiverConfig); consumed = true; break; diff --git a/applications/main/subghz/subghz_i.h b/applications/main/subghz/subghz_i.h index f141b5399..8872d31f6 100644 --- a/applications/main/subghz/subghz_i.h +++ b/applications/main/subghz/subghz_i.h @@ -105,7 +105,6 @@ struct SubGhz { SubGhzLock lock; bool in_decoder_scene; - SubGhzScene current_scene; void* rpc_ctx; }; From 006d27ed935d58dac6676984679de30e762ba477 Mon Sep 17 00:00:00 2001 From: derskythe Date: Wed, 28 Sep 2022 06:53:52 +0400 Subject: [PATCH 29/47] Add removed fixed --- applications/main/subghz/scenes/subghz_scene_receiver_config.c | 1 + 1 file changed, 1 insertion(+) diff --git a/applications/main/subghz/scenes/subghz_scene_receiver_config.c b/applications/main/subghz/scenes/subghz_scene_receiver_config.c index affb01a0b..3469de573 100644 --- a/applications/main/subghz/scenes/subghz_scene_receiver_config.c +++ b/applications/main/subghz/scenes/subghz_scene_receiver_config.c @@ -351,6 +351,7 @@ bool subghz_scene_receiver_config_on_event(void* context, SceneManagerEvent even void subghz_scene_receiver_config_on_exit(void* context) { SubGhz* subghz = context; + variable_item_list_set_selected_item(subghz->variable_item_list, 0); variable_item_list_reset(subghz->variable_item_list); subghz_last_settings_save(subghz->last_settings); scene_manager_set_scene_state( From 0c5f11f713974322d29f7b8af6f238377c825960 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Wed, 28 Sep 2022 06:02:23 +0300 Subject: [PATCH 30/47] return fix --- applications/main/subghz/scenes/subghz_scene_receiver_config.c | 3 +++ applications/main/subghz/subghz_last_settings.c | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/applications/main/subghz/scenes/subghz_scene_receiver_config.c b/applications/main/subghz/scenes/subghz_scene_receiver_config.c index affb01a0b..0175cd0fd 100644 --- a/applications/main/subghz/scenes/subghz_scene_receiver_config.c +++ b/applications/main/subghz/scenes/subghz_scene_receiver_config.c @@ -259,6 +259,8 @@ void subghz_scene_receiver_config_on_enter(void* context) { subghz); value_index = subghz_scene_receiver_config_next_frequency(subghz->txrx->preset->frequency, subghz); + scene_manager_set_scene_state( + subghz->scene_manager, SubGhzSceneReceiverConfig, (uint32_t)item); variable_item_set_current_value_index(item, value_index); char text_buf[10] = {0}; snprintf( @@ -351,6 +353,7 @@ bool subghz_scene_receiver_config_on_event(void* context, SceneManagerEvent even void subghz_scene_receiver_config_on_exit(void* context) { SubGhz* subghz = context; + variable_item_list_set_selected_item(subghz->variable_item_list, 0); variable_item_list_reset(subghz->variable_item_list); subghz_last_settings_save(subghz->last_settings); scene_manager_set_scene_state( diff --git a/applications/main/subghz/subghz_last_settings.c b/applications/main/subghz/subghz_last_settings.c index 764c78fea..241d8e950 100644 --- a/applications/main/subghz/subghz_last_settings.c +++ b/applications/main/subghz/subghz_last_settings.c @@ -7,7 +7,7 @@ #define SUBGHZ_LAST_SETTING_FILE_TYPE "Flipper SubGhz Last Setting File" #define SUBGHZ_LAST_SETTING_FILE_VERSION 1 -#define SUBGHZ_LAST_SETTINGS_PATH EXT_PATH(".subghz.settings") +#define SUBGHZ_LAST_SETTINGS_PATH EXT_PATH("subghz/assets/.subghz.settings") // 1 = "AM650" // "AM270", "AM650", "FM238", "FM476", #define SUBGHZ_LAST_SETTING_DEFAULT_PRESET 1 From 8f2bd3be571a3f949d0817dda8474d7624594751 Mon Sep 17 00:00:00 2001 From: derskythe Date: Wed, 28 Sep 2022 07:14:38 +0400 Subject: [PATCH 31/47] Update list of frequencies and change name of file of settings to not able to run in browser --- .../main/subghz/subghz_last_settings.c | 4 +-- .../subghz/views/subghz_frequency_analyzer.c | 25 ++++++------------- 2 files changed, 8 insertions(+), 21 deletions(-) diff --git a/applications/main/subghz/subghz_last_settings.c b/applications/main/subghz/subghz_last_settings.c index 241d8e950..0a45e36ba 100644 --- a/applications/main/subghz/subghz_last_settings.c +++ b/applications/main/subghz/subghz_last_settings.c @@ -1,13 +1,11 @@ #include "subghz_last_settings.h" -#include -#include #include #define TAG "SubGhzLastSettings" #define SUBGHZ_LAST_SETTING_FILE_TYPE "Flipper SubGhz Last Setting File" #define SUBGHZ_LAST_SETTING_FILE_VERSION 1 -#define SUBGHZ_LAST_SETTINGS_PATH EXT_PATH("subghz/assets/.subghz.settings") +#define SUBGHZ_LAST_SETTINGS_PATH EXT_PATH("subghz/assets/subghz.settings") // 1 = "AM650" // "AM270", "AM650", "FM238", "FM476", #define SUBGHZ_LAST_SETTING_DEFAULT_PRESET 1 diff --git a/applications/main/subghz/views/subghz_frequency_analyzer.c b/applications/main/subghz/views/subghz_frequency_analyzer.c index 7d1239cd8..f7c41f627 100644 --- a/applications/main/subghz/views/subghz_frequency_analyzer.c +++ b/applications/main/subghz/views/subghz_frequency_analyzer.c @@ -48,24 +48,13 @@ static const NotificationSequence sequence_not_saved = { NULL, }; -static const uint32_t subghz_frequency_list[17] = { - 300000000, - 303875000, - 304250000, - 310000000, - 315000000, - 318000000, - 390000000, - 418000000, - 433075000, - 433420000, - 433920000, - 434420000, - 434775000, - 438900000, - 868350000, - 915000000, - 925000000}; +static const uint32_t subghz_frequency_list[] = { + 300000000, 302757000, 303875000, 304250000, 307000000, 307500000, 307800000, + 309000000, 310000000, 312000000, 312100000, 313000000, 313850000, 314000000, + 314350000, 315000000, 318000000, 345000000, 348000000, 387000000, 390000000, + 418000000, 433075000, 433220000, 433420000, 433657070, 433889000, 433920000, + 434176948, 434420000, 434775000, 438900000, 464000000, 779000000, 868350000, + 868400000, 868950000, 906400000, 915000000, 925000000, 928000000}; typedef enum { SubGhzFrequencyAnalyzerStatusIDLE, From 0ebb3f060ebc2e2b312a39dbc2534cf5efa17565 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Wed, 28 Sep 2022 06:46:45 +0300 Subject: [PATCH 32/47] add a bit of changes --- applications/main/subghz/subghz_last_settings.c | 2 +- applications/main/subghz/views/subghz_frequency_analyzer.c | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/applications/main/subghz/subghz_last_settings.c b/applications/main/subghz/subghz_last_settings.c index 0a45e36ba..aa234c602 100644 --- a/applications/main/subghz/subghz_last_settings.c +++ b/applications/main/subghz/subghz_last_settings.c @@ -5,7 +5,7 @@ #define SUBGHZ_LAST_SETTING_FILE_TYPE "Flipper SubGhz Last Setting File" #define SUBGHZ_LAST_SETTING_FILE_VERSION 1 -#define SUBGHZ_LAST_SETTINGS_PATH EXT_PATH("subghz/assets/subghz.settings") +#define SUBGHZ_LAST_SETTINGS_PATH EXT_PATH("subghz/assets/last_subghz.settings") // 1 = "AM650" // "AM270", "AM650", "FM238", "FM476", #define SUBGHZ_LAST_SETTING_DEFAULT_PRESET 1 diff --git a/applications/main/subghz/views/subghz_frequency_analyzer.c b/applications/main/subghz/views/subghz_frequency_analyzer.c index f7c41f627..9900c32c9 100644 --- a/applications/main/subghz/views/subghz_frequency_analyzer.c +++ b/applications/main/subghz/views/subghz_frequency_analyzer.c @@ -33,8 +33,8 @@ static const NotificationSequence sequence_hw_blink_stop = { static const NotificationSequence sequence_saved = { &message_blink_stop, &message_blue_0, - &message_green_0, - &message_red_255, + &message_green_255, + &message_red_0, &message_vibro_on, &message_delay_100, &message_vibro_off, @@ -454,6 +454,7 @@ View* subghz_frequency_analyzer_get_view(SubGhzFrequencyAnalyzer* instance) { } uint32_t subghz_frequency_analyzer_get_frequency_to_save(SubGhzFrequencyAnalyzer* instance) { + furi_assert(instance); uint32_t frequency; with_view_model( instance->view, (SubGhzFrequencyAnalyzerModel * model) { From b934c41ed04a305b6895709d8a1f8a278ab1f03a Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Wed, 28 Sep 2022 06:51:13 +0300 Subject: [PATCH 33/47] close file --- applications/main/subghz/subghz_last_settings.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/applications/main/subghz/subghz_last_settings.c b/applications/main/subghz/subghz_last_settings.c index aa234c602..b24273cf3 100644 --- a/applications/main/subghz/subghz_last_settings.c +++ b/applications/main/subghz/subghz_last_settings.c @@ -56,6 +56,7 @@ void subghz_last_settings_load(SubGhzLastSettings* instance, size_t preset_count } } + flipper_format_file_close(fff_data_file); flipper_format_free(fff_data_file); furi_record_close(RECORD_STORAGE); } @@ -96,6 +97,7 @@ bool subghz_last_settings_save(SubGhzLastSettings* instance) { FURI_LOG_E(TAG, "Error save file %s", SUBGHZ_LAST_SETTINGS_PATH); } + flipper_format_file_close(file); flipper_format_free(file); furi_record_close(RECORD_STORAGE); From aa00606d22a2cf4ee5c924dc24c201f010b1e740 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Wed, 28 Sep 2022 07:50:09 +0300 Subject: [PATCH 34/47] remove unnecessary checks from brute plugin, subghz improvements fix subghz gui in add manually, add BETT protocol in add manually --- .../main/subghz/helpers/subghz_custom_event.h | 1 + .../subghz/scenes/subghz_scene_set_type.c | 49 ++++++++++++------- .../subbrute/helpers/subbrute_worker.c | 12 ++--- applications/plugins/subbrute/subbrute.c | 40 +++++++-------- .../plugins/subbrute/subbrute_device.c | 22 ++++----- .../plugins/subbrute/subbrute_device.h | 4 +- 6 files changed, 69 insertions(+), 59 deletions(-) diff --git a/applications/main/subghz/helpers/subghz_custom_event.h b/applications/main/subghz/helpers/subghz_custom_event.h index 3d45c0bc6..39acf5fd6 100644 --- a/applications/main/subghz/helpers/subghz_custom_event.h +++ b/applications/main/subghz/helpers/subghz_custom_event.h @@ -14,6 +14,7 @@ typedef enum { SubmenuIndexNiceFlo24bit, SubmenuIndexCAME12bit, SubmenuIndexCAME24bit, + SubmenuIndexBETT_433, SubmenuIndexCAMETwee, SubmenuIndexNeroSketch, SubmenuIndexNeroRadio, diff --git a/applications/main/subghz/scenes/subghz_scene_set_type.c b/applications/main/subghz/scenes/subghz_scene_set_type.c index 6cb54f157..93734023d 100644 --- a/applications/main/subghz/scenes/subghz_scene_set_type.c +++ b/applications/main/subghz/scenes/subghz_scene_set_type.c @@ -69,61 +69,67 @@ void subghz_scene_set_type_on_enter(void* context) { submenu_add_item( subghz->submenu, - "Faac SLH_868", + "Faac SLH 868MHz", SubmenuIndexFaacSLH_868, subghz_scene_set_type_submenu_callback, subghz); submenu_add_item( subghz->submenu, - "Faac SLH_433", + "Faac SLH 433MHz", SubmenuIndexFaacSLH_433, subghz_scene_set_type_submenu_callback, subghz); submenu_add_item( subghz->submenu, - "BFT Mitto", + "BFT Mitto 433MHz", SubmenuIndexBFT, subghz_scene_set_type_submenu_callback, subghz); submenu_add_item( subghz->submenu, - "Princeton_433", + "Princeton 433MHz", SubmenuIndexPricenton, subghz_scene_set_type_submenu_callback, subghz); submenu_add_item( subghz->submenu, - "Nice Flo 12bit_433", + "Nice Flo 12bit 433MHz", SubmenuIndexNiceFlo12bit, subghz_scene_set_type_submenu_callback, subghz); submenu_add_item( subghz->submenu, - "Nice Flo 24bit_433", + "Nice Flo 24bit 433MHz", SubmenuIndexNiceFlo24bit, subghz_scene_set_type_submenu_callback, subghz); submenu_add_item( subghz->submenu, - "CAME 12bit_433", + "CAME 12bit 433MHz", SubmenuIndexCAME12bit, subghz_scene_set_type_submenu_callback, subghz); submenu_add_item( subghz->submenu, - "CAME 24bit_433", + "CAME 24bit 433MHz", SubmenuIndexCAME24bit, subghz_scene_set_type_submenu_callback, subghz); submenu_add_item( subghz->submenu, - "Linear_300", + "BETT 433MHz", + SubmenuIndexBETT_433, + subghz_scene_set_type_submenu_callback, + subghz); + submenu_add_item( + subghz->submenu, + "Linear 300MHz", SubmenuIndexLinear_300_00, subghz_scene_set_type_submenu_callback, subghz); submenu_add_item( subghz->submenu, - "CAME TWEE", + "CAME TWEE 433MHz", SubmenuIndexCAMETwee, subghz_scene_set_type_submenu_callback, subghz); @@ -133,49 +139,49 @@ void subghz_scene_set_type_on_enter(void* context) { // subghz->submenu, "Nero Radio", SubmenuIndexNeroRadio, subghz_scene_set_type_submenu_callback, subghz); submenu_add_item( subghz->submenu, - "Gate TX_433", + "Gate TX 433MHz", SubmenuIndexGateTX, subghz_scene_set_type_submenu_callback, subghz); submenu_add_item( subghz->submenu, - "DoorHan_315", + "DoorHan 315MHz", SubmenuIndexDoorHan_315_00, subghz_scene_set_type_submenu_callback, subghz); submenu_add_item( subghz->submenu, - "DoorHan_433", + "DoorHan 433MHz", SubmenuIndexDoorHan_433_92, subghz_scene_set_type_submenu_callback, subghz); submenu_add_item( subghz->submenu, - "LiftMaster_315", + "Security+1.0 315MHz", SubmenuIndexLiftMaster_315_00, subghz_scene_set_type_submenu_callback, subghz); submenu_add_item( subghz->submenu, - "LiftMaster_390", + "Security+1.0 390MHz", SubmenuIndexLiftMaster_390_00, subghz_scene_set_type_submenu_callback, subghz); submenu_add_item( subghz->submenu, - "Security+2.0_310", + "Security+2.0 310MHz", SubmenuIndexSecPlus_v2_310_00, subghz_scene_set_type_submenu_callback, subghz); submenu_add_item( subghz->submenu, - "Security+2.0_315", + "Security+2.0 315MHz", SubmenuIndexSecPlus_v2_315_00, subghz_scene_set_type_submenu_callback, subghz); submenu_add_item( subghz->submenu, - "Security+2.0_390", + "Security+2.0 390MHz", SubmenuIndexSecPlus_v2_390_00, subghz_scene_set_type_submenu_callback, subghz); @@ -247,6 +253,13 @@ bool subghz_scene_set_type_on_event(void* context, SceneManagerEvent event) { generated_protocol = true; } break; + case SubmenuIndexBETT_433: + key = (key & 0x0000FFF0); + if(subghz_scene_set_type_submenu_gen_data_protocol( + subghz, SUBGHZ_PROTOCOL_BETT_NAME, key, 18, 433920000, "AM650")) { + generated_protocol = true; + } + break; case SubmenuIndexCAMETwee: key = (key & 0x0FFFFFF0); key = 0x003FFF7200000000 | (key ^ 0xE0E0E0EE); diff --git a/applications/plugins/subbrute/helpers/subbrute_worker.c b/applications/plugins/subbrute/helpers/subbrute_worker.c index 369ffd81c..80275698e 100644 --- a/applications/plugins/subbrute/helpers/subbrute_worker.c +++ b/applications/plugins/subbrute/helpers/subbrute_worker.c @@ -106,10 +106,10 @@ bool subbrute_worker_start( furi_hal_subghz_set_frequency_and_path(instance->frequency); furi_hal_subghz_flush_rx(); - if(furi_hal_subghz_is_tx_allowed(frequency)) { - instance->frequency = frequency; - res = true; - } + //if(furi_hal_subghz_is_tx_allowed(frequency)) { + instance->frequency = frequency; + res = true; + //} instance->worker_running = res; #ifdef FURI_DEBUG @@ -245,13 +245,13 @@ bool subbrute_worker_init_manual_transmit( furi_hal_subghz_set_frequency_and_path(instance->frequency); furi_hal_subghz_flush_rx(); - if(!furi_hal_subghz_is_tx_allowed(frequency)) { + /*if(!furi_hal_subghz_is_tx_allowed(frequency)) { FURI_LOG_E(TAG, "Frequency: %d invalid!", frequency); instance->frequency = frequency; instance->worker_manual_mode = false; return false; - } + }*/ #ifdef FURI_DEBUG FURI_LOG_I(TAG, "Frequency: %d", frequency); diff --git a/applications/plugins/subbrute/subbrute.c b/applications/plugins/subbrute/subbrute.c index 5bdacde63..f9c6e67dc 100644 --- a/applications/plugins/subbrute/subbrute.c +++ b/applications/plugins/subbrute/subbrute.c @@ -21,31 +21,31 @@ #define TAG "SubBruteApp" static const char* subbrute_menu_names[] = { - [SubBruteAttackCAME12bit307] = "CAME 12bit 307mhz", - [SubBruteAttackCAME12bit433] = "CAME 12bit 433mhz", - [SubBruteAttackCAME12bit868] = "CAME 12bit 868mhz", - [SubBruteAttackChamberlain9bit300] = "Chamberlain 9bit 300mhz", - [SubBruteAttackChamberlain9bit315] = "Chamberlain 9bit 315mhz", - [SubBruteAttackChamberlain9bit390] = "Chamberlain 9bit 390mhz", - [SubBruteAttackLinear10bit300] = "Linear 10bit 300mhz", - [SubBruteAttackLinear10bit310] = "Linear 10bit 310mhz", - [SubBruteAttackNICE12bit433] = "NICE 12bit 433mhz", - [SubBruteAttackNICE12bit868] = "NICE 12bit 868mhz", + [SubBruteAttackCAME12bit307] = "CAME 12bit 307MHz", + [SubBruteAttackCAME12bit433] = "CAME 12bit 433MHz", + [SubBruteAttackCAME12bit868] = "CAME 12bit 868MHz", + [SubBruteAttackNICE12bit433] = "NICE 12bit 433MHz", + [SubBruteAttackNICE12bit868] = "NICE 12bit 868MHz", + [SubBruteAttackChamberlain9bit300] = "Chamberlain 9bit 300MHz", + [SubBruteAttackChamberlain9bit315] = "Chamberlain 9bit 315MHz", + [SubBruteAttackChamberlain9bit390] = "Chamberlain 9bit 390MHz", + [SubBruteAttackLinear10bit300] = "Linear 10bit 300MHz", + [SubBruteAttackLinear10bit310] = "Linear 10bit 310MHz", [SubBruteAttackLoadFile] = "BF existing dump", [SubBruteAttackTotalCount] = "Total Count", }; static const char* subbrute_menu_names_small[] = { - [SubBruteAttackCAME12bit307] = "CAME 307mhz", - [SubBruteAttackCAME12bit433] = "CAME 433mhz", - [SubBruteAttackCAME12bit868] = "CAME 868mhz", - [SubBruteAttackChamberlain9bit300] = "Cham 300mhz", - [SubBruteAttackChamberlain9bit315] = "Cham 315mhz", - [SubBruteAttackChamberlain9bit390] = "Cham 390mhz", - [SubBruteAttackLinear10bit300] = "Linear 300mhz", - [SubBruteAttackLinear10bit310] = "Linear 310mhz", - [SubBruteAttackNICE12bit433] = "NICE 433mhz", - [SubBruteAttackNICE12bit868] = "NICE 868mhz", + [SubBruteAttackCAME12bit307] = "CAME 307MHz", + [SubBruteAttackCAME12bit433] = "CAME 433MHz", + [SubBruteAttackCAME12bit868] = "CAME 868MHz", + [SubBruteAttackNICE12bit433] = "NICE 433MHz", + [SubBruteAttackNICE12bit868] = "NICE 868MHz", + [SubBruteAttackChamberlain9bit300] = "Cham 300MHz", + [SubBruteAttackChamberlain9bit315] = "Cham 315MHz", + [SubBruteAttackChamberlain9bit390] = "Cham 390MHz", + [SubBruteAttackLinear10bit300] = "Linear 300MHz", + [SubBruteAttackLinear10bit310] = "Linear 310MHz", [SubBruteAttackLoadFile] = "Existing", [SubBruteAttackTotalCount] = "Total Count", }; diff --git a/applications/plugins/subbrute/subbrute_device.c b/applications/plugins/subbrute/subbrute_device.c index f1ca6962a..d5712d96b 100644 --- a/applications/plugins/subbrute/subbrute_device.c +++ b/applications/plugins/subbrute/subbrute_device.c @@ -307,19 +307,15 @@ SubBruteFileResult subbrute_device_attack_set(SubBruteDevice* instance, SubBrute string_set_str(instance->preset_name, preset_ook650_async); break; case SubBruteAttackChamberlain9bit300: - instance->frequency = 300000000; - instance->bit = 9; - string_set_str(instance->protocol_name, protocol_cham_code); - string_set_str(instance->preset_name, preset_ook650_async); - break; case SubBruteAttackChamberlain9bit315: - instance->frequency = 315000000; - instance->bit = 9; - string_set_str(instance->protocol_name, protocol_cham_code); - string_set_str(instance->preset_name, preset_ook650_async); - break; case SubBruteAttackChamberlain9bit390: - instance->frequency = 390000000; + if(type == SubBruteAttackChamberlain9bit300) { + instance->frequency = 300000000; + } else if(type == SubBruteAttackChamberlain9bit315) { + instance->frequency = 315000000; + } else /* ALWAYS TRUE if(type == SubBruteAttackChamberlain9bit390) */ { + instance->frequency = 390000000; + } instance->bit = 9; string_set_str(instance->protocol_name, protocol_cham_code); string_set_str(instance->preset_name, preset_ook650_async); @@ -353,10 +349,10 @@ SubBruteFileResult subbrute_device_attack_set(SubBruteDevice* instance, SubBrute return SubBruteFileResultProtocolNotFound; // RETURN } - if(!furi_hal_subghz_is_tx_allowed(instance->frequency)) { + /*if(!furi_hal_subghz_is_tx_allowed(instance->frequency)) { FURI_LOG_E(TAG, "Frequency invalid: %d", instance->frequency); return SubBruteFileResultMissingOrIncorrectFrequency; // RETURN - } + }*/ // For non-file types we didn't set SubGhzProtocolDecoderBase instance->receiver = subghz_receiver_alloc_init(instance->environment); diff --git a/applications/plugins/subbrute/subbrute_device.h b/applications/plugins/subbrute/subbrute_device.h index 5419c10de..46a1d2598 100644 --- a/applications/plugins/subbrute/subbrute_device.h +++ b/applications/plugins/subbrute/subbrute_device.h @@ -20,13 +20,13 @@ typedef enum { SubBruteAttackCAME12bit307, SubBruteAttackCAME12bit433, SubBruteAttackCAME12bit868, + SubBruteAttackNICE12bit433, + SubBruteAttackNICE12bit868, SubBruteAttackChamberlain9bit300, SubBruteAttackChamberlain9bit315, SubBruteAttackChamberlain9bit390, SubBruteAttackLinear10bit300, SubBruteAttackLinear10bit310, - SubBruteAttackNICE12bit433, - SubBruteAttackNICE12bit868, SubBruteAttackLoadFile, SubBruteAttackTotalCount, } SubBruteAttacks; From 9ad7f7825d88fdf9c493a591832bf88670c45a4d Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Wed, 28 Sep 2022 07:50:43 +0300 Subject: [PATCH 35/47] update projector asset by @Amec0e --- assets/resources/infrared/assets/projectors.ir | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/assets/resources/infrared/assets/projectors.ir b/assets/resources/infrared/assets/projectors.ir index 3f9a5f8a4..1ba36ab17 100644 --- a/assets/resources/infrared/assets/projectors.ir +++ b/assets/resources/infrared/assets/projectors.ir @@ -1,12 +1,18 @@ Filetype: IR library file Version: 1 -# Last Updated 17th Sept, 2022 +# Last Updated 27th Sept, 2022 # # ON 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 +type: raw +frequency: 38000 +duty_cycle: 0.330000 data: 529 7218 126 6585 219 703 180 5362 427 18618 177 # name: VOL+ @@ -410,4 +416,9 @@ type: parsed protocol: Samsung32 address: 07 00 00 00 command: 0F 00 00 00 -# +# OFF +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 From 3dcd8a73f11db563a2948bb576bc15a72451bb61 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Wed, 28 Sep 2022 08:06:47 +0300 Subject: [PATCH 36/47] update changelog --- CHANGELOG.md | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c93e1f85e..00640615d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,9 +1,11 @@ ### New changes -* PR: SubGHz bruteforcer plugin - fixes and speed-up (-2 min) (by @derskythe | PR #76) -* Fix nfc device typo - key_a_mask was used for key B -* OFW: Applications loader: do not use view dispatcher queue -* OFW: Power: Also ask charger if charge done -* OFW: Fast flash programming mode (faster firmware flash) +* PR: SubGHz new feature -> press Ok in Frequency analyzer to use frequency in Read modes (by @derskythe | PR #77) +* PR: SubGHz save last settings (frequency and modulation) (by @derskythe | PR #77) +* Plugins: SubGHz Bruteforcer - add chamberlain 9bit 300mhz, removed unnecessary checks (made it a bit faster), fixed title position & menu text +* SubGHz: Fix Add Manually item names, Add BETT protocol in add manually +* Infrared: Update assets (by @Amec0e) +* OFW: Refactor infrared brute force code +* OFW: Add formatting to DESfire data dump #### **DFU files no longer included in releases to avoid issues with wrong manual installation of assets - use .tgz file with qFlipper, or install automatically via web updater or use microSD update package** From 6bcc6f363b01041c08f2ada2411f35fccacc2748 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Wed, 28 Sep 2022 16:35:40 +0300 Subject: [PATCH 37/47] add 868.8 mhz for sommer systems --- assets/resources/subghz/assets/setting_user | 1 + 1 file changed, 1 insertion(+) diff --git a/assets/resources/subghz/assets/setting_user b/assets/resources/subghz/assets/setting_user index 9742ba2db..67174e5f2 100644 --- a/assets/resources/subghz/assets/setting_user +++ b/assets/resources/subghz/assets/setting_user @@ -44,6 +44,7 @@ Frequency: 464000000 Frequency: 779000000 Frequency: 868350000 Frequency: 868400000 +Frequency: 868800000 Frequency: 868950000 Frequency: 906400000 Frequency: 915000000 From 4241ad24a3e038cf2f60f83e4c6b9d1ae4bb7453 Mon Sep 17 00:00:00 2001 From: Nikolay Minaylov Date: Wed, 28 Sep 2022 19:37:24 +0300 Subject: [PATCH 38/47] [FL-2797] Signal Generator app (#1793) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Signal Generator app * MCO pin initialization in app * furi_hal_pwm documentation Co-authored-by: あく --- .../plugins/signal_generator/application.fam | 12 + .../scenes/signal_gen_scene.c | 30 ++ .../scenes/signal_gen_scene.h | 29 ++ .../scenes/signal_gen_scene_config.h | 3 + .../scenes/signal_gen_scene_mco.c | 132 ++++++++ .../scenes/signal_gen_scene_pwm.c | 60 ++++ .../scenes/signal_gen_scene_start.c | 55 ++++ .../signal_generator/signal_gen_10px.png | Bin 0 -> 6082 bytes .../plugins/signal_generator/signal_gen_app.c | 93 ++++++ .../signal_generator/signal_gen_app_i.h | 46 +++ .../signal_generator/views/signal_gen_pwm.c | 301 ++++++++++++++++++ .../signal_generator/views/signal_gen_pwm.h | 21 ++ assets/icons/Interface/SmallArrowDown_4x7.png | Bin 0 -> 8340 bytes assets/icons/Interface/SmallArrowUp_4x7.png | Bin 0 -> 8552 bytes firmware/targets/f7/api_symbols.csv | 10 +- firmware/targets/f7/furi_hal/furi_hal_clock.c | 61 ++++ firmware/targets/f7/furi_hal/furi_hal_clock.h | 37 +++ firmware/targets/f7/furi_hal/furi_hal_pwm.c | 138 ++++++++ firmware/targets/f7/furi_hal/furi_hal_pwm.h | 42 +++ 19 files changed, 1069 insertions(+), 1 deletion(-) create mode 100644 applications/plugins/signal_generator/application.fam create mode 100644 applications/plugins/signal_generator/scenes/signal_gen_scene.c create mode 100644 applications/plugins/signal_generator/scenes/signal_gen_scene.h create mode 100644 applications/plugins/signal_generator/scenes/signal_gen_scene_config.h create mode 100644 applications/plugins/signal_generator/scenes/signal_gen_scene_mco.c create mode 100644 applications/plugins/signal_generator/scenes/signal_gen_scene_pwm.c create mode 100644 applications/plugins/signal_generator/scenes/signal_gen_scene_start.c create mode 100644 applications/plugins/signal_generator/signal_gen_10px.png create mode 100644 applications/plugins/signal_generator/signal_gen_app.c create mode 100644 applications/plugins/signal_generator/signal_gen_app_i.h create mode 100644 applications/plugins/signal_generator/views/signal_gen_pwm.c create mode 100644 applications/plugins/signal_generator/views/signal_gen_pwm.h create mode 100644 assets/icons/Interface/SmallArrowDown_4x7.png create mode 100644 assets/icons/Interface/SmallArrowUp_4x7.png create mode 100644 firmware/targets/f7/furi_hal/furi_hal_pwm.c create mode 100644 firmware/targets/f7/furi_hal/furi_hal_pwm.h diff --git a/applications/plugins/signal_generator/application.fam b/applications/plugins/signal_generator/application.fam new file mode 100644 index 000000000..7794ee492 --- /dev/null +++ b/applications/plugins/signal_generator/application.fam @@ -0,0 +1,12 @@ +App( + appid="signal_generator", + name="Signal Generator", + apptype=FlipperAppType.PLUGIN, + entry_point="signal_gen_app", + cdefines=["APP_SIGNAL_GEN"], + requires=["gui"], + stack_size=1 * 1024, + order=50, + fap_icon="signal_gen_10px.png", + fap_category="Tools", +) diff --git a/applications/plugins/signal_generator/scenes/signal_gen_scene.c b/applications/plugins/signal_generator/scenes/signal_gen_scene.c new file mode 100644 index 000000000..29b11ee3f --- /dev/null +++ b/applications/plugins/signal_generator/scenes/signal_gen_scene.c @@ -0,0 +1,30 @@ +#include "../signal_gen_app_i.h" + +// Generate scene on_enter handlers array +#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_enter, +void (*const signal_gen_scene_on_enter_handlers[])(void*) = { +#include "signal_gen_scene_config.h" +}; +#undef ADD_SCENE + +// Generate scene on_event handlers array +#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_event, +bool (*const signal_gen_scene_on_event_handlers[])(void* context, SceneManagerEvent event) = { +#include "signal_gen_scene_config.h" +}; +#undef ADD_SCENE + +// Generate scene on_exit handlers array +#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_exit, +void (*const signal_gen_scene_on_exit_handlers[])(void* context) = { +#include "signal_gen_scene_config.h" +}; +#undef ADD_SCENE + +// Initialize scene handlers configuration structure +const SceneManagerHandlers signal_gen_scene_handlers = { + .on_enter_handlers = signal_gen_scene_on_enter_handlers, + .on_event_handlers = signal_gen_scene_on_event_handlers, + .on_exit_handlers = signal_gen_scene_on_exit_handlers, + .scene_num = SignalGenSceneNum, +}; diff --git a/applications/plugins/signal_generator/scenes/signal_gen_scene.h b/applications/plugins/signal_generator/scenes/signal_gen_scene.h new file mode 100644 index 000000000..c139afa3b --- /dev/null +++ b/applications/plugins/signal_generator/scenes/signal_gen_scene.h @@ -0,0 +1,29 @@ +#pragma once + +#include + +// Generate scene id and total number +#define ADD_SCENE(prefix, name, id) SignalGenScene##id, +typedef enum { +#include "signal_gen_scene_config.h" + SignalGenSceneNum, +} SignalGenScene; +#undef ADD_SCENE + +extern const SceneManagerHandlers signal_gen_scene_handlers; + +// Generate scene on_enter handlers declaration +#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_enter(void*); +#include "signal_gen_scene_config.h" +#undef ADD_SCENE + +// Generate scene on_event handlers declaration +#define ADD_SCENE(prefix, name, id) \ + bool prefix##_scene_##name##_on_event(void* context, SceneManagerEvent event); +#include "signal_gen_scene_config.h" +#undef ADD_SCENE + +// Generate scene on_exit handlers declaration +#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_exit(void* context); +#include "signal_gen_scene_config.h" +#undef ADD_SCENE diff --git a/applications/plugins/signal_generator/scenes/signal_gen_scene_config.h b/applications/plugins/signal_generator/scenes/signal_gen_scene_config.h new file mode 100644 index 000000000..b6c750256 --- /dev/null +++ b/applications/plugins/signal_generator/scenes/signal_gen_scene_config.h @@ -0,0 +1,3 @@ +ADD_SCENE(signal_gen, start, Start) +ADD_SCENE(signal_gen, pwm, Pwm) +ADD_SCENE(signal_gen, mco, Mco) diff --git a/applications/plugins/signal_generator/scenes/signal_gen_scene_mco.c b/applications/plugins/signal_generator/scenes/signal_gen_scene_mco.c new file mode 100644 index 000000000..632b08c75 --- /dev/null +++ b/applications/plugins/signal_generator/scenes/signal_gen_scene_mco.c @@ -0,0 +1,132 @@ +#include "../signal_gen_app_i.h" + +typedef enum { + LineIndexSource, + LineIndexDivision, +} LineIndex; + +static const char* const mco_source_names[] = { + "32768", + "64MHz", + "~100K", + "~200K", + "~400K", + "~800K", + "~1MHz", + "~2MHz", + "~4MHz", + "~8MHz", + "~16MHz", + "~24MHz", + "~32MHz", + "~48MHz", +}; + +static const FuriHalClockMcoSourceId mco_sources[] = { + FuriHalClockMcoLse, + FuriHalClockMcoSysclk, + FuriHalClockMcoMsi100k, + FuriHalClockMcoMsi200k, + FuriHalClockMcoMsi400k, + FuriHalClockMcoMsi800k, + FuriHalClockMcoMsi1m, + FuriHalClockMcoMsi2m, + FuriHalClockMcoMsi4m, + FuriHalClockMcoMsi8m, + FuriHalClockMcoMsi16m, + FuriHalClockMcoMsi24m, + FuriHalClockMcoMsi32m, + FuriHalClockMcoMsi48m, +}; + +static const char* const mco_divisor_names[] = { + "1", + "2", + "4", + "8", + "16", +}; + +static const FuriHalClockMcoDivisorId mco_divisors[] = { + FuriHalClockMcoDiv1, + FuriHalClockMcoDiv2, + FuriHalClockMcoDiv4, + FuriHalClockMcoDiv8, + FuriHalClockMcoDiv16, +}; + +static void mco_source_list_change_callback(VariableItem* item) { + SignalGenApp* app = variable_item_get_context(item); + uint8_t index = variable_item_get_current_value_index(item); + variable_item_set_current_value_text(item, mco_source_names[index]); + + app->mco_src = mco_sources[index]; + + view_dispatcher_send_custom_event(app->view_dispatcher, SignalGenMcoEventUpdate); +} + +static void mco_divisor_list_change_callback(VariableItem* item) { + SignalGenApp* app = variable_item_get_context(item); + uint8_t index = variable_item_get_current_value_index(item); + variable_item_set_current_value_text(item, mco_divisor_names[index]); + + app->mco_div = mco_divisors[index]; + + view_dispatcher_send_custom_event(app->view_dispatcher, SignalGenMcoEventUpdate); +} + +void signal_gen_scene_mco_on_enter(void* context) { + SignalGenApp* app = context; + VariableItemList* var_item_list = app->var_item_list; + + VariableItem* item; + + item = variable_item_list_add( + var_item_list, "Source", COUNT_OF(mco_source_names), mco_source_list_change_callback, app); + variable_item_set_current_value_index(item, 0); + variable_item_set_current_value_text(item, mco_source_names[0]); + + item = variable_item_list_add( + var_item_list, + "Division", + COUNT_OF(mco_divisor_names), + mco_divisor_list_change_callback, + app); + variable_item_set_current_value_index(item, 0); + variable_item_set_current_value_text(item, mco_divisor_names[0]); + + variable_item_list_set_selected_item(var_item_list, LineIndexSource); + + view_dispatcher_switch_to_view(app->view_dispatcher, SignalGenViewVarItemList); + + app->mco_src = FuriHalClockMcoLse; + app->mco_div = FuriHalClockMcoDiv1; + furi_hal_clock_mco_enable(app->mco_src, app->mco_div); + furi_hal_gpio_init_ex( + &gpio_usart_tx, GpioModeAltFunctionPushPull, GpioPullUp, GpioSpeedVeryHigh, GpioAltFn0MCO); +} + +bool signal_gen_scene_mco_on_event(void* context, SceneManagerEvent event) { + SignalGenApp* app = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + if(event.event == SignalGenMcoEventUpdate) { + consumed = true; + furi_hal_clock_mco_enable(app->mco_src, app->mco_div); + } + } + return consumed; +} + +void signal_gen_scene_mco_on_exit(void* context) { + SignalGenApp* app = context; + variable_item_list_reset(app->var_item_list); + furi_hal_gpio_init_ex( + &gpio_usart_tx, + GpioModeAltFunctionPushPull, + GpioPullUp, + GpioSpeedVeryHigh, + GpioAltFn7USART1); + furi_hal_clock_mco_disable(); +} diff --git a/applications/plugins/signal_generator/scenes/signal_gen_scene_pwm.c b/applications/plugins/signal_generator/scenes/signal_gen_scene_pwm.c new file mode 100644 index 000000000..f302c0232 --- /dev/null +++ b/applications/plugins/signal_generator/scenes/signal_gen_scene_pwm.c @@ -0,0 +1,60 @@ +#include "../signal_gen_app_i.h" + +static const FuriHalPwmOutputId pwm_ch_id[] = { + FuriHalPwmOutputIdTim1PA7, + FuriHalPwmOutputIdLptim2PA4, +}; + +#define DEFAULT_FREQ 1000 +#define DEFAULT_DUTY 50 + +static void + signal_gen_pwm_callback(uint8_t channel_id, uint32_t freq, uint8_t duty, void* context) { + SignalGenApp* app = context; + + app->pwm_freq = freq; + app->pwm_duty = duty; + + if(app->pwm_ch != pwm_ch_id[channel_id]) { + app->pwm_ch_prev = app->pwm_ch; + app->pwm_ch = pwm_ch_id[channel_id]; + view_dispatcher_send_custom_event(app->view_dispatcher, SignalGenPwmEventChannelChange); + } else { + app->pwm_ch = pwm_ch_id[channel_id]; + view_dispatcher_send_custom_event(app->view_dispatcher, SignalGenPwmEventUpdate); + } +} + +void signal_gen_scene_pwm_on_enter(void* context) { + SignalGenApp* app = context; + + view_dispatcher_switch_to_view(app->view_dispatcher, SignalGenViewPwm); + + signal_gen_pwm_set_callback(app->pwm_view, signal_gen_pwm_callback, app); + + signal_gen_pwm_set_params(app->pwm_view, 0, DEFAULT_FREQ, DEFAULT_DUTY); + furi_hal_pwm_start(pwm_ch_id[0], DEFAULT_FREQ, DEFAULT_DUTY); +} + +bool signal_gen_scene_pwm_on_event(void* context, SceneManagerEvent event) { + SignalGenApp* app = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + if(event.event == SignalGenPwmEventUpdate) { + consumed = true; + furi_hal_pwm_set_params(app->pwm_ch, app->pwm_freq, app->pwm_duty); + } else if(event.event == SignalGenPwmEventChannelChange) { + consumed = true; + furi_hal_pwm_stop(app->pwm_ch_prev); + furi_hal_pwm_start(app->pwm_ch, app->pwm_freq, app->pwm_duty); + } + } + return consumed; +} + +void signal_gen_scene_pwm_on_exit(void* context) { + SignalGenApp* app = context; + variable_item_list_reset(app->var_item_list); + furi_hal_pwm_stop(app->pwm_ch); +} diff --git a/applications/plugins/signal_generator/scenes/signal_gen_scene_start.c b/applications/plugins/signal_generator/scenes/signal_gen_scene_start.c new file mode 100644 index 000000000..91f6081d8 --- /dev/null +++ b/applications/plugins/signal_generator/scenes/signal_gen_scene_start.c @@ -0,0 +1,55 @@ +#include "../signal_gen_app_i.h" + +typedef enum { + SubmenuIndexPwm, + SubmenuIndexClockOutput, +} SubmenuIndex; + +void signal_gen_scene_start_submenu_callback(void* context, uint32_t index) { + SignalGenApp* app = context; + + view_dispatcher_send_custom_event(app->view_dispatcher, index); +} + +void signal_gen_scene_start_on_enter(void* context) { + SignalGenApp* app = context; + Submenu* submenu = app->submenu; + + submenu_add_item( + submenu, "PWM", SubmenuIndexPwm, signal_gen_scene_start_submenu_callback, app); + submenu_add_item( + submenu, + "Clock Output", + SubmenuIndexClockOutput, + signal_gen_scene_start_submenu_callback, + app); + + submenu_set_selected_item( + submenu, scene_manager_get_scene_state(app->scene_manager, SignalGenSceneStart)); + + view_dispatcher_switch_to_view(app->view_dispatcher, SignalGenViewSubmenu); +} + +bool signal_gen_scene_start_on_event(void* context, SceneManagerEvent event) { + SignalGenApp* app = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + if(event.event == SubmenuIndexPwm) { + scene_manager_next_scene(app->scene_manager, SignalGenScenePwm); + consumed = true; + } else if(event.event == SubmenuIndexClockOutput) { + scene_manager_next_scene(app->scene_manager, SignalGenSceneMco); + consumed = true; + } + scene_manager_set_scene_state(app->scene_manager, SignalGenSceneStart, event.event); + } + + return consumed; +} + +void signal_gen_scene_start_on_exit(void* context) { + SignalGenApp* app = context; + + submenu_reset(app->submenu); +} diff --git a/applications/plugins/signal_generator/signal_gen_10px.png b/applications/plugins/signal_generator/signal_gen_10px.png new file mode 100644 index 0000000000000000000000000000000000000000..9f6dcc5d0d9a9c1fbc54b7459b46c50c16c7e863 GIT binary patch literal 6082 zcmeHKcTiK?)(=H`Q&6fHBZ{aY4MGygMWibMM0!yU$q58VF$pA85d={Xy<8FL0s>M6 z5%JoPD<~ogTpJ=FRzRgH*x@_Da`k&}=8ZG&{by!!&fcs1_FBKa_L_b6I6K-Z%4x~L zU@%2{J1ZCHEgH*-NkGrWkAAZ-n2chit0&(D5WqQHHk}a)!ubDp3%bQnz7JL>Hd z{+Oin@yZ&yZ1hfe=A|K`K)U{;!GUzuwPUXv@|yN6PB~$<;ZyW_a@s2C&xh3}JyGL$*zs+)7Y5Zs;95jL_9?e)5}zAdt=0pGrM)qodxPbdP23TyBFDvE%D1sL|4X6zO?BaK$j(n zE9A0Hi5m{x>WM4t7}4#I$8Oii$lTdE`hN3PvIec;M3P++@M6j4d$Ba}rsSF7wjhCm z_sDM8VHr!@MNeg^i&{m0*@UzZ>y{)rz>mSsylQqs`)Bz{+o`J%2Uii7YBj?17#>%Y z%4COr@3<(r;(}x!d~ChDjKbXS2L>$@$KT;eZVbP-g27Gm;V1A)g$JKk952M)_ADvQ4q=Eo z+du1)>Jeo!l_R?{a4OGMd!h|Dis|$k1g^TLl8Y_N&3dV__$4eoqn?$4L2D$1rFNO0 zUeT!O_H5wMKE1xlXIsIvgJ<-!KD6Ioap#PqB@=V1*m+;DS&?$g-c4^W`A#>KnEMG& z#ke^$!<9NGvd~D~Whw~8JJO$8(_8{~wVqJMU95;T(z}z}YD$~!3$`daX(9DWMNcO$ zyi#Ger5RNo&Z!TGyHoEQzwTZ}T&-2ncyZ&y-D;H$cTx_e}9>)ypAMAQ6Pv{`%pHm!* zlTwk_i8@txU68}^2f;Hb4T^5 zo%@q*o3=(LE>{VO@Iqv#A3`iY)qcrISEfr#a^{-Y{*~AA6*axD_wlL}8TQM19#EER zM9w&L1vVR8bBX%{qjzyaTBG2ZltjGRUe(0(z0VJJ(ri0>9-891aN%gs!MrN-N${}n zy#x}3zYv7$H3WQ0-*}DcY1lT^QLZK17s@V)*tK)K;cWItAg%KbAymxVg(pcB#4>be z?6jS@zDW+g&L&QN-C0SpE$hI&VmC_QEsqv4f@*`8)EcE%Pf`Z-852?W20HJ5P|nga zTJr~-pK`7(YRR&GiRh)DA2ER!11Gu#QqjrB?ep<+xm7J$acas24QNG&xbuyy4Xux? z9bPQ5VR$Ou@=n^rS({Tkpb_I5hTOS---Z6xy5`~pT{p|rDniQss?K;jL`^tsKPiKr zIngIRaW$iM5nA^=n%s$0ocLXBx%`g$^oO-o;$AG!r6oQov*!4mpJ{!X1LLLM{$}+; zl9|n4gEbGNb{uJUQ;l@Xs9g2BVvPr7*v+jbyQ{Lo*SOHb?a$y1$1AwEcWrfh+WYtS zvZ?hAcU>XvxXq_>+4I`dWvgDZZWUyAo!z|S{|V<(hIia(8ty-4Zd@oRp4}Ndp4dJv z`Oeg0*6~1->Jwi$dhb%nuwA++Atz@~1y&&PqfcGSR!Gnc}O3&Np?sN#e zUKM6W6RsBcCa^Blh4oHdmrp9NkR2V-_?P zGW|&{gpEP^Cly1Ri$;CbJs)_#bl)j$?!8m6b?wBhHNsbg9nVjntXe5-!L&K9Jeghp z>V{Rw7O8-&(|Y?;I$k$EfA#LYe3p%0!=34wO{J@r=GVD9atc=P~A zzEmuS);2nQS0cxkvf;7qxnuC#v&rgviVG$YpPUXYn=E>Ipul0~@>#`==996DC(2*! zc>Ylto;nd#HF#DB1{2%Gu(Wixx3v6vF@UZExiPHny}ngj*{#6{$+7pd~HnhcIjH?cb&ykCJ>Fss7k& zc4$_oKlnz#`t^GGKoUdsxT+JgS86Eck<8lmHIu~2WA^HLu}{uCn$#YOzh;rIiMd%$ zd?Zun83dFhdUfAQ*56ZHQMx4-{kX0@BBkEFqV_WRoqS^Mg>x-o*$H<3VkrmU8!Q%R zuWq(Ub%CM&~4Uv2*_^sv$Ej zK3(xRdYP%?CrKHygh%AfZ8c&y3yyl^c)ykzz9(f^laqZy+II{V9 z4eovEx~?dBes$z|%*=%xfEohw;Q?SEgGEM+pKU_G88kA&!NN{tMm5@`tY-{j1MBnW^B@&UMz8Oq|3gk;1#E(sco#3%%O-h>}Q zMtD-3;g)PJ2sbh`GDIV-g^X}4;x{?C8J9*UxmekJfq-UYL=d0PA)!zLfxu9JGh}lE zQ5YhTh(cpgSS%8^eCu!ss;EXc9oA(P;rDNE!wJ zkVXK2LjpuJ7Kx^tfOG(3VuB}7zk{-8@%R9X3W}g0a6<-!6M)45bQ%^7K|qd1cnAyt z@pz;$9b^^V?=IRF5|j)?EFh{= z2w+|g0k?mieV&Fg=8qB_K7S}k z0QGYUJRlsT&BqC0eO6I}09GIfb&oIQ`c=;OH>E%&V2!Cp7%UQp!y6-wa8wL3fKCWN zLYx9P0)|ecVevnr^VoF00N{cafe?=nS5SG*a|K^LzflH1S_^_e(JnxQA<;zSzY>P} zk}yitGrneQhWZyy%;pWgYci1EXBpJIpk9dj)(pRJCTctX!{3*^_#dtSLH}Chr}+Iv z*Dtz$ih-Xp{#9MS==v!Je#-b)b^X`qlKba#3S>dIAOZBTG?n(K5BkuOa&~aFo|~J4 zhHih|jD=oe0h?^CV95)X+CdXpj-3||29sA6{l#F}xf+mAnr~0BmVPFyt)Qnu-8CEz vi5A;iS-8sFrTY8(*9Q7Kx2#uIhJi56XX0g^pLAD41~7YTN2{6*{_+0@Ugv#> literal 0 HcmV?d00001 diff --git a/applications/plugins/signal_generator/signal_gen_app.c b/applications/plugins/signal_generator/signal_gen_app.c new file mode 100644 index 000000000..ca065d330 --- /dev/null +++ b/applications/plugins/signal_generator/signal_gen_app.c @@ -0,0 +1,93 @@ +#include "signal_gen_app_i.h" + +#include +#include + +static bool signal_gen_app_custom_event_callback(void* context, uint32_t event) { + furi_assert(context); + SignalGenApp* app = context; + return scene_manager_handle_custom_event(app->scene_manager, event); +} + +static bool signal_gen_app_back_event_callback(void* context) { + furi_assert(context); + SignalGenApp* app = context; + return scene_manager_handle_back_event(app->scene_manager); +} + +static void signal_gen_app_tick_event_callback(void* context) { + furi_assert(context); + SignalGenApp* app = context; + scene_manager_handle_tick_event(app->scene_manager); +} + +SignalGenApp* signal_gen_app_alloc() { + SignalGenApp* app = malloc(sizeof(SignalGenApp)); + + app->gui = furi_record_open(RECORD_GUI); + + app->view_dispatcher = view_dispatcher_alloc(); + app->scene_manager = scene_manager_alloc(&signal_gen_scene_handlers, app); + view_dispatcher_enable_queue(app->view_dispatcher); + view_dispatcher_set_event_callback_context(app->view_dispatcher, app); + + view_dispatcher_set_custom_event_callback( + app->view_dispatcher, signal_gen_app_custom_event_callback); + view_dispatcher_set_navigation_event_callback( + app->view_dispatcher, signal_gen_app_back_event_callback); + view_dispatcher_set_tick_event_callback( + app->view_dispatcher, signal_gen_app_tick_event_callback, 100); + + view_dispatcher_attach_to_gui(app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen); + + app->var_item_list = variable_item_list_alloc(); + view_dispatcher_add_view( + app->view_dispatcher, + SignalGenViewVarItemList, + variable_item_list_get_view(app->var_item_list)); + + app->submenu = submenu_alloc(); + view_dispatcher_add_view( + app->view_dispatcher, SignalGenViewSubmenu, submenu_get_view(app->submenu)); + + app->pwm_view = signal_gen_pwm_alloc(); + view_dispatcher_add_view( + app->view_dispatcher, SignalGenViewPwm, signal_gen_pwm_get_view(app->pwm_view)); + + scene_manager_next_scene(app->scene_manager, SignalGenSceneStart); + + return app; +} + +void signal_gen_app_free(SignalGenApp* app) { + furi_assert(app); + + // Views + view_dispatcher_remove_view(app->view_dispatcher, SignalGenViewVarItemList); + view_dispatcher_remove_view(app->view_dispatcher, SignalGenViewSubmenu); + view_dispatcher_remove_view(app->view_dispatcher, SignalGenViewPwm); + + submenu_free(app->submenu); + variable_item_list_free(app->var_item_list); + signal_gen_pwm_free(app->pwm_view); + + // View dispatcher + view_dispatcher_free(app->view_dispatcher); + scene_manager_free(app->scene_manager); + + // Close records + furi_record_close(RECORD_GUI); + + free(app); +} + +int32_t signal_gen_app(void* p) { + UNUSED(p); + SignalGenApp* signal_gen_app = signal_gen_app_alloc(); + + view_dispatcher_run(signal_gen_app->view_dispatcher); + + signal_gen_app_free(signal_gen_app); + + return 0; +} diff --git a/applications/plugins/signal_generator/signal_gen_app_i.h b/applications/plugins/signal_generator/signal_gen_app_i.h new file mode 100644 index 000000000..47c266475 --- /dev/null +++ b/applications/plugins/signal_generator/signal_gen_app_i.h @@ -0,0 +1,46 @@ +#pragma once + +#include "scenes/signal_gen_scene.h" + +#include "furi_hal_clock.h" +#include "furi_hal_pwm.h" + +#include +#include +#include +#include +#include +#include +#include "views/signal_gen_pwm.h" + +typedef struct SignalGenApp SignalGenApp; + +struct SignalGenApp { + Gui* gui; + ViewDispatcher* view_dispatcher; + SceneManager* scene_manager; + + VariableItemList* var_item_list; + Submenu* submenu; + SignalGenPwm* pwm_view; + + FuriHalClockMcoSourceId mco_src; + FuriHalClockMcoDivisorId mco_div; + + FuriHalPwmOutputId pwm_ch_prev; + FuriHalPwmOutputId pwm_ch; + uint32_t pwm_freq; + uint8_t pwm_duty; +}; + +typedef enum { + SignalGenViewVarItemList, + SignalGenViewSubmenu, + SignalGenViewPwm, +} SignalGenAppView; + +typedef enum { + SignalGenMcoEventUpdate, + SignalGenPwmEventUpdate, + SignalGenPwmEventChannelChange, +} SignalGenCustomEvent; diff --git a/applications/plugins/signal_generator/views/signal_gen_pwm.c b/applications/plugins/signal_generator/views/signal_gen_pwm.c new file mode 100644 index 000000000..00b4ef267 --- /dev/null +++ b/applications/plugins/signal_generator/views/signal_gen_pwm.c @@ -0,0 +1,301 @@ +#include "../signal_gen_app_i.h" +#include "furi_hal.h" +#include + +typedef enum { + LineIndexChannel, + LineIndexFrequency, + LineIndexDuty, + LineIndexTotalCount +} LineIndex; + +static const char* const pwm_ch_names[] = {"TIM1(2)", "LPTIM2(4)"}; + +struct SignalGenPwm { + View* view; + SignalGenPwmViewCallback callback; + void* context; +}; + +typedef struct { + LineIndex line_sel; + bool edit_mode; + uint8_t edit_digit; + + uint8_t channel_id; + uint32_t freq; + uint8_t duty; + +} SignalGenPwmViewModel; + +#define ITEM_H 64 / 3 +#define ITEM_W 128 + +#define VALUE_X 95 +#define VALUE_W 55 + +#define FREQ_VALUE_X 62 +#define FREQ_MAX 1000000UL +#define FREQ_DIGITS_NB 7 + +static void pwm_set_config(SignalGenPwm* pwm) { + FuriHalPwmOutputId channel; + uint32_t freq; + uint8_t duty; + + with_view_model( + pwm->view, (SignalGenPwmViewModel * model) { + channel = model->channel_id; + freq = model->freq; + duty = model->duty; + return false; + }); + + furi_assert(pwm->callback); + pwm->callback(channel, freq, duty, pwm->context); +} + +static void pwm_channel_change(SignalGenPwmViewModel* model, InputEvent* event) { + if(event->key == InputKeyLeft) { + if(model->channel_id > 0) { + model->channel_id--; + } + } else if(event->key == InputKeyRight) { + if(model->channel_id < (COUNT_OF(pwm_ch_names) - 1)) { + model->channel_id++; + } + } +} + +static void pwm_duty_change(SignalGenPwmViewModel* model, InputEvent* event) { + if(event->key == InputKeyLeft) { + if(model->duty > 0) { + model->duty--; + } + } else if(event->key == InputKeyRight) { + if(model->duty < 100) { + model->duty++; + } + } +} + +static bool pwm_freq_edit(SignalGenPwmViewModel* model, InputEvent* event) { + bool consumed = false; + if((event->type == InputTypeShort) || (event->type == InputTypeRepeat)) { + if(event->key == InputKeyRight) { + if(model->edit_digit > 0) { + model->edit_digit--; + } + consumed = true; + } else if(event->key == InputKeyLeft) { + if(model->edit_digit < (FREQ_DIGITS_NB - 1)) { + model->edit_digit++; + } + consumed = true; + } else if(event->key == InputKeyUp) { + uint32_t step = 1; + for(uint8_t i = 0; i < model->edit_digit; i++) { + step *= 10; + } + if((model->freq + step) < FREQ_MAX) { + model->freq += step; + } else { + model->freq = FREQ_MAX; + } + consumed = true; + } else if(event->key == InputKeyDown) { + uint32_t step = 1; + for(uint8_t i = 0; i < model->edit_digit; i++) { + step *= 10; + } + if(model->freq > (step + 1)) { + model->freq -= step; + } else { + model->freq = 1; + } + consumed = true; + } + } + return consumed; +} + +static void signal_gen_pwm_draw_callback(Canvas* canvas, void* _model) { + SignalGenPwmViewModel* model = _model; + char* line_label = NULL; + char val_text[16]; + + for(uint8_t line = 0; line < LineIndexTotalCount; line++) { + if(line == LineIndexChannel) { + line_label = "PWM Channel"; + } else if(line == LineIndexFrequency) { + line_label = "Frequency"; + } else if(line == LineIndexDuty) { + line_label = "Duty Cycle"; + } + + canvas_set_color(canvas, ColorBlack); + if(line == model->line_sel) { + elements_slightly_rounded_box(canvas, 0, ITEM_H * line + 1, ITEM_W, ITEM_H - 1); + canvas_set_color(canvas, ColorWhite); + } + + uint8_t text_y = ITEM_H * line + ITEM_H / 2 + 2; + + canvas_draw_str_aligned(canvas, 6, text_y, AlignLeft, AlignCenter, line_label); + + if(line == LineIndexChannel) { + snprintf(val_text, sizeof(val_text), "%s", pwm_ch_names[model->channel_id]); + canvas_draw_str_aligned(canvas, VALUE_X, text_y, AlignCenter, AlignCenter, val_text); + if(model->channel_id != 0) { + canvas_draw_str_aligned( + canvas, VALUE_X - VALUE_W / 2, text_y, AlignCenter, AlignCenter, "<"); + } + if(model->channel_id != (COUNT_OF(pwm_ch_names) - 1)) { + canvas_draw_str_aligned( + canvas, VALUE_X + VALUE_W / 2, text_y, AlignCenter, AlignCenter, ">"); + } + } else if(line == LineIndexFrequency) { + snprintf(val_text, sizeof(val_text), "%7lu Hz", model->freq); + canvas_set_font(canvas, FontKeyboard); + canvas_draw_str_aligned( + canvas, FREQ_VALUE_X, text_y, AlignLeft, AlignCenter, val_text); + canvas_set_font(canvas, FontSecondary); + + if(model->edit_mode) { + uint8_t icon_x = (FREQ_VALUE_X - 1) + (FREQ_DIGITS_NB - model->edit_digit - 1) * 6; + canvas_draw_icon(canvas, icon_x, text_y - 9, &I_SmallArrowUp_4x7); + canvas_draw_icon(canvas, icon_x, text_y + 4, &I_SmallArrowDown_4x7); + } + } else if(line == LineIndexDuty) { + snprintf(val_text, sizeof(val_text), "%d%%", model->duty); + canvas_draw_str_aligned(canvas, VALUE_X, text_y, AlignCenter, AlignCenter, val_text); + if(model->duty != 0) { + canvas_draw_str_aligned( + canvas, VALUE_X - VALUE_W / 2, text_y, AlignCenter, AlignCenter, "<"); + } + if(model->duty != 100) { + canvas_draw_str_aligned( + canvas, VALUE_X + VALUE_W / 2, text_y, AlignCenter, AlignCenter, ">"); + } + } + } +} + +static bool signal_gen_pwm_input_callback(InputEvent* event, void* context) { + furi_assert(context); + SignalGenPwm* pwm = context; + bool consumed = false; + bool need_update = false; + + with_view_model( + pwm->view, (SignalGenPwmViewModel * model) { + if(model->edit_mode == false) { + if((event->type == InputTypeShort) || (event->type == InputTypeRepeat)) { + if(event->key == InputKeyUp) { + if(model->line_sel == 0) { + model->line_sel = LineIndexTotalCount - 1; + } else { + model->line_sel = + CLAMP(model->line_sel - 1, LineIndexTotalCount - 1, 0); + } + consumed = true; + } else if(event->key == InputKeyDown) { + if(model->line_sel == LineIndexTotalCount - 1) { + model->line_sel = 0; + } else { + model->line_sel = + CLAMP(model->line_sel + 1, LineIndexTotalCount - 1, 0); + } + consumed = true; + } else if((event->key == InputKeyLeft) || (event->key == InputKeyRight)) { + if(model->line_sel == LineIndexChannel) { + pwm_channel_change(model, event); + need_update = true; + } else if(model->line_sel == LineIndexDuty) { + pwm_duty_change(model, event); + need_update = true; + } else if(model->line_sel == LineIndexFrequency) { + model->edit_mode = true; + } + consumed = true; + } else if(event->key == InputKeyOk) { + if(model->line_sel == LineIndexFrequency) { + model->edit_mode = true; + } + consumed = true; + } + } + } else { + if((event->key == InputKeyOk) || (event->key == InputKeyBack)) { + if(event->type == InputTypeShort) { + model->edit_mode = false; + consumed = true; + } + } else { + if(model->line_sel == LineIndexFrequency) { + consumed = pwm_freq_edit(model, event); + need_update = consumed; + } + } + } + return true; + }); + + if(need_update) { + pwm_set_config(pwm); + } + + return consumed; +} + +SignalGenPwm* signal_gen_pwm_alloc() { + SignalGenPwm* pwm = malloc(sizeof(SignalGenPwm)); + + pwm->view = view_alloc(); + view_allocate_model(pwm->view, ViewModelTypeLocking, sizeof(SignalGenPwmViewModel)); + view_set_context(pwm->view, pwm); + view_set_draw_callback(pwm->view, signal_gen_pwm_draw_callback); + view_set_input_callback(pwm->view, signal_gen_pwm_input_callback); + + return pwm; +} + +void signal_gen_pwm_free(SignalGenPwm* pwm) { + furi_assert(pwm); + view_free(pwm->view); + free(pwm); +} + +View* signal_gen_pwm_get_view(SignalGenPwm* pwm) { + furi_assert(pwm); + return pwm->view; +} + +void signal_gen_pwm_set_callback( + SignalGenPwm* pwm, + SignalGenPwmViewCallback callback, + void* context) { + furi_assert(pwm); + furi_assert(callback); + + with_view_model( + pwm->view, (SignalGenPwmViewModel * model) { + UNUSED(model); + pwm->callback = callback; + pwm->context = context; + return false; + }); +} + +void signal_gen_pwm_set_params(SignalGenPwm* pwm, uint8_t channel_id, uint32_t freq, uint8_t duty) { + with_view_model( + pwm->view, (SignalGenPwmViewModel * model) { + model->channel_id = channel_id; + model->freq = freq; + model->duty = duty; + return true; + }); + + furi_assert(pwm->callback); + pwm->callback(channel_id, freq, duty, pwm->context); +} diff --git a/applications/plugins/signal_generator/views/signal_gen_pwm.h b/applications/plugins/signal_generator/views/signal_gen_pwm.h new file mode 100644 index 000000000..986794e7a --- /dev/null +++ b/applications/plugins/signal_generator/views/signal_gen_pwm.h @@ -0,0 +1,21 @@ +#pragma once + +#include +#include "../signal_gen_app_i.h" + +typedef struct SignalGenPwm SignalGenPwm; +typedef void ( + *SignalGenPwmViewCallback)(uint8_t channel_id, uint32_t freq, uint8_t duty, void* context); + +SignalGenPwm* signal_gen_pwm_alloc(); + +void signal_gen_pwm_free(SignalGenPwm* pwm); + +View* signal_gen_pwm_get_view(SignalGenPwm* pwm); + +void signal_gen_pwm_set_callback( + SignalGenPwm* pwm, + SignalGenPwmViewCallback callback, + void* context); + +void signal_gen_pwm_set_params(SignalGenPwm* pwm, uint8_t channel_id, uint32_t freq, uint8_t duty); diff --git a/assets/icons/Interface/SmallArrowDown_4x7.png b/assets/icons/Interface/SmallArrowDown_4x7.png new file mode 100644 index 0000000000000000000000000000000000000000..5c5252b167d2f9f9a1ce5e7b9f9c99123879c1b4 GIT binary patch literal 8340 zcmeHLc{tSV*B@j}*+Z$ulu*Vj3}!5av6FpYGG+!7W5&$LlAY{(sZ@5MMY3g!NS4UH zL=+)JkrYCChkBmh^IX5@_rC9QUGMwfGuQQ<@Ap3UIiLHS&pGG*F40D3wf1owvM_TlNP3M`sZmv}VuF%3 zx_1QJEUX^*RNcKdM;LI@i?{XYD^ImhobETB&8Ve)y!}%3*#7W{*J0GnF%3yq|43O>u2&c9J{f;uvQF zm}2B$++)y^_A-fAnA##dx$ki(`%T=G^BycGXTGq=GKbG+@>L>n6HFg|)CWYcC9ZP=7w$vYM=1b>F0x>cUS2a^P&u@o^Df$dCR_7K z@`ve~bAhULUK2?~{1b_8W32@*L`t7-wK+ zMN}Nf4Gmm2w$F6vQyV_Lnw+jta?VO;Dynm3__I}EN>aL1v+a7>kpc5}DS7uol5^!# zRX?y~Fe?SR_q>)0#2M9G5x#8V+J;c5m|@`8b}`CHp25YSMCWYc5pOhz<@0<;f(Om| z6774U_b9TOv`kj=$z7J_4T_-m|nlCz7`iJb3e4m;<`|~ zuNH%R(vmR5g)+;#@H*)UnU#SseIpss|IBhaLLZeJk2f1y+{CdadbGV2MvOMJOH?is z8(fZ?PPEl|NM79TF1k2pb+@GBjfyDx>%gO+ijR!s1x#tk36txdtl!m6@|m}(Nl>xZ zgD_JEI%c>60t>&R}2jD|&U=K`&H{UWs==oe4)Kd>nSUZs}cQ8mIB3&+EiwhH_IE9 zGGMdH*TXg$%u8Xyd5n4Gp@Wwt)`cF*=3Ou)sY??XKFox>CfnxrAQa5X!unHCU-qJ< z@EoTMvFvGvBoaIwf|UT5Wq(B7Wp8$c)X5aQ2dv^8GLBuu`VW zzMp)Bn%S1N)>1&0$_%7j^|zf2eE$39j#qU#5ES8J&jNjxS26d`azKv!IK@TVZpWXq zQ?P<@B&VyrZGRWyWq+G-&v>>m-x*#cUQNmC;G0x%z|%x}TU{bM6RzS?FF7MKg| zOBn7k4F(w>4JeE(Vu>Bp;u?NuyywfrCl!K@<;19=uT?~+!J#vWPEHFP4Ibt4^h_22Hg^n2~C^sC-xrXvR;yX)lZj8eE` zuJpLMnlNhbtJ6-FJ_%#z)@?`vfaK6-WVCT|J{w$OA~;t)xdaq*iNUyJVUI9+z>~~> z=&BB`NO=6Q?^5T@@uO>jZkcu6uU(b`hH3ywTVc#k^{v>0IkT4T1rTuE))OULUa& z7JROtY*JCgg#~BX)~n(5C$M2Oorp6nr0Ei2|Fd!ciIg$v8LBDH9gIzpfQN#od;t^M&(D48 zgIK-j=Ih{U?s{P(&3n8cO8A7GX+->GzSy_j-3GI<%`c$)<>QY{!iLj?twr8a0M6Z8 z*8ILi;Zl&|umVy6N(2+@B?f}*w{E7aUAXEH9<(ToKDyqtY8jZe5AZM_Uoo-~NhAmW z>=zh}YQINzIzj+3rS)F>13Zt^_&b<9o0M`nb#H9UPLCneO%gJ^{-ag zw(&(Vr>RApS0Ka^s9BAo~u@jw?z-02|NOjILQNKzlb~4vlOtmMT_ZM zXKZiU_4Li|&>sPoRr){L4jd0kz-po4RlLSsA8u^fFvoSjGXUJ`E}BjL=eq$7Dpt7Ej2 z3)*b?Su`|YM*3IwwjUL^G?{ZX+ag;o_pULkQF@`ufcb#Ld5*6<2AXa;oxNRi0Gbp^ zI6YQc(=zL3&*8bUIi4>H8v-n0+1NN(f>4mY$O(Zm#xmiuL;VTJOTsO2nEVo}`=}w2 zg_wQKl!s34utyvhxi9iwWL8WF2s<`OBR^6&XQy;F>eMsy2^+FF*^f|1Y zPy80A1|(=F?Tmf$qbz03zL?qFzg}#W?SuBzUcSTY@LW5(=$Wz2ZL?gO+53pTa=7`3 zCejS4?psEQ{mlGMi(jfaYEu2Jag4;Kgo^~$Ec~t^-n4qaYd~|}dR}3lx=cQEj|t&+ zImtDwTv8w=CSA8&H$ykR-BUpFaQ2~Irn&cD;2W3?uMI_Wu(_dm{rrhRxxrI+iw9>4 zeG8Wdbq8JzY7V@)BQp>%&_7Ul$NSEB{~5w{Lb%)X`47Dc_m*kpck+Wk% z;fPMzW3ra6i~S-!w}$$LKKHlx-R(o=el@%K;A3|B-8%Kn@YTHi=B)-=S!L?8d0p5D zj;71WU4^(WuzVWA>${g&&DWZ+8X3P9KV!d3ejokTzOZjdeLw#F@J8K+DGQ24l!ck4 zh^2Dha)eY9f0KR0_lV;7xOk^HIUz4$Ww?dRerT7x2cq6hP0mx^+PTk>(#el)ha1Se zCi;zV%9Y9M!S2Bh!6Q2lzhIuJ?TiHX95{PGEtVzrkUnq!<+LVue1c6MI1IcOTq~7n zEo{|nODvnO+;An5(mh_g2DC;v@wuA1_G4G>6{Ue+K5AKgW%t=`y!zhkh3)_k7mwD; zQLJ}=#`&X8Pa5lA{s;@p4QtEp#Pszxzub!`_*e%%K_Ta2USJru$c-wm?TnyV};tJr((7N0j zUU0|d?yPFJi^GrusCa+zOLv!5-Bn4_v(fI_XBT@SC;8r)ex#0DcFT`c4tlqDzad>3 zmkcToO4^p&KEzYyrDXlJNKqp~Pj+p%pmsdi=G?A}@L zOQAi%Js-2zp2js@y%caXft_n_F?)~@hR>M0_epS#gHsD;D*##HCd@qC0pU`253sdH&$9| z$m&-8`Z{m3*ex+F-ri_fG&p(*nSG0;>q}qo?FzkuD)&X{MZOGH5-TZXsU0$Fc)a>V zs<^W51%o#kN@8weZ#!x?(KVimJ7wwHp=xaq|T6v@Ct%k zkVLt(6vV$;+S%SP*`oJGPRZB61>0DG7>#CmxhnU<(WqAv!wOY|#r(SlNA-Nf1oeva zPU()5W<2WGQ#&nF&jq|nDaSv2k?r1X@xtQm(8B0g2Ao;(IcgGR939k^Mq@P z*FHQp!dMzt#y-?5)w2<{8?nb5RaDFec8pQ2*-|_j{y*%4-I#}irhTD zdAm2r!PGvnj|mG$R1W%-SGL|Rn7Y`pw05*#*@9~K&S!-EX><->=GmFdTPmqu^Y7nJ z_haky{FZJ-D^rUgk4c~0dq!4f{kzlOuYEY}`{wIb$=)u(1P7e`hni{f9cn{h))edJ zQ54Hz7R5-B$Qp>E{i1M&y#Hj(W@^7>U2#V30rJPbwyos13&t-=Z?vmK>z>zso3q#` znysXIbdOn61p_LlGy3XcHgBvQ3Y7g`Vm}X5R+(2ueR6CJQ^byyh@Zx9e+hg%C;AQ3 z9NvXqIX0@*dLlp^a@t|tXG>@3a#}(2=~LTwn=htEyr1}N!Jz_*h#z)ew)%^2o-2GZ zyxq5mU!o0v`EDs(?Cfyuv2hS}0=z)nuD$NfCsVytvUKY7^}xArLSL2_3*rnj1DV#s zS2mGZqtyVwehmWslZ};uJ_<`BN@H*&C%m)|kxc)j0{|$U_90`iZg?8d3GYJiPzEj4 zJ^=v!*%wEZY}Q@^ujSU)!`5(hf1!lC4Yq5}}|Gz`#(=S zaZ&W^9Wew1+*P5uDTAyGjDYGS3LYpcEh`NLYxoc@z(Fb;KqU&!8D)aj`~^WDDT7>T zG%^YT@%HwX_Lh+*QCuJ}BoYaM!Xa=tn63e)`g+hXK41^(u^ot?7-&2dOCgYH1d<1E z2NUB&@}en&K=gUwZ~hU<1_r;wdr*I|K<5MEgCRp;(ohJI2>GK0m8Nll4)V*PzqFv5 z(Z75_Oz>2a7X^#gxPbSd9s4tc3I1O({VyQs>VE>jVSjgk>_u_k;N9^=`dU=F z+ps_RtfgaM^t;6lhb{yndDn`btv_kf2+se(vz?h;KK>X9-TZglzl>v7nXYAEfI^e7 zUOVpTpp`*%i8PLYLm_0*YBErmf|@)`6$aB#Q&oehA~ob?Rn_5g2&k<5AIx<;s5FcR z7XO<$Vb@#%CWnwif)VoaNU$s%h5%!*P#D-526e(f5zbI&1=t@T3@HS9DP!FK$`e^A z5-y98$AX1RMcI%Hw6h7>o?kNgfN6!^k-8LgBC|O%jEOq1OO`h;hL~$Q~}c z6FVfMRE>0$L2zm4za&QP7@9NPKpCV@@bL2a*Mu2?h&QESb{K@o$;rZ@2$&pH9wCqT z74|Nk1)f5sm+uZH3@R-H-!J&VNMxvOJNbbs@9SGo# zj2UPl* zW^DqMzP|6S=w}<6;yr(keh%FUyZr|Q?sgIigZ&u-6>|ZP+x3%<^>YgAit%v4)3=;o zCHkA3@E4_kgu`WU3eGq%9P0!H%R+IoU?*9;JQ#yR(sL<`#LD7+lJq+|mE=tG#!&F8 zE_5F0T+v%%mn)#eZlWar?2ET6ekTib!oW}@_}>YG{0bPdv(fw(u@dCpIr&8s8c!k6 z1Ja(yrrw*fHtx{FKpmV*17o z`F&^ql}kF0|DV5KHS+(t1Q7VoB7ckDf9U#$uD`{=-%|dky8fZ-Z!z$e!&|1-Kc z{`GE%_n<$WdDGwgw!a$r+Y^Giobch9crB6t?+DnrSiS^G==$;`2~TTgKE-+ zYxCiOV$@(bO@`NwXVS@D>;31fZpKbRj|(}GEm}9&ett=~?v8k4+^ol3X-m+1SV<$i?3^J= zV29^bZFiW$)|?7JxM3@@+*~{oFT`}%g4BC!oZ5RApKwV=*7ieJ*;W}?XwhkCzY3{z zUn#>a>rEZxft=gbj)`(x9|Io7r?cR|eDS@J+aiTqi%+_{Dr;+^JFY+YbWw1yMQ5K} z)0Ogb2N^*X56mYoewqwaYZp#nz>Rry4LPnZq`4-&sgV+KZLE%7!|t0MYKG;8HI4Da zi8Jg!k%Tpvx@HseuKi%>@zgHfY6gbbBo@JE8r8gVac$t)< zkA(_o?hipaQ}5`+h_|NQY!x;9Ro_exE_EH5UUEi&qfo)G)} zwL*r+Z9R|Ow(PLM)l9t4aL_(IDGjL@GV4#ZBUOf;35p1L+WHraeC% zLkcrc=s@*bC@;&E%TvkE*km76(B7Z14ANS-xjDYg;6^i@Oh`%SS03oO@6ULc2JcLa z6y}~(SGQ+ixYXmG_SHzdMBF7!gTgJ4RNC%3bP&-T>XK@SK#QGDE~R=HR?`I!8cqw+z(lHY?f)`n*cf$)U{uCPGY z|Ev3ENf1zLNISFkzMX4*c<%*}g2tWnKq}UIz6={5^gD^is?8FeJpufOLtSd1Mqmk%{)~xn zx5Y!%PMO*VJFaa{AXzF(xehrzs0ibCm{xahReXgt%a-UmuxQ5`c`U~krmirb;`Wea z^o7Ivd4`^DQ01+B*QN9B1Ge+z_{cuS#PbTNoMZztt9$r1VGEc3o2ex=ENgO6+{Hy( zO&PE2yQ&qQw|=}*^wmc?k;%t+$V^{Q+*u~VM?CIB`Y-v*&7Ec6q;HJ=g6~Kvado2( zS&t=SNCv>2@sPIrC(`U4#r%q;(qlv6qTb*;?kHgkI_m52Uy9b$`EEw&bzpu81$Hoh z>{hkEcOYR{Iv)@&8^AjBE>$pYsHyZyhB!0RH-V<yYh}0A+|F+wh-EEYIwrn$NYYC-q-`LlkxI;q zzotU$U=19Joh}VF5n{5noHd+?zQU>P;o^MQw?h1tCpbk!$-wLr6UjR5d#ao0_q-{_ z8_CJQ%8}qC8>4{|M_;CE0b!zgGer^-xrsS^;Uc1-1aln$&7xB&*>iQ(nk`WWp_MC@ zDoMO7Usl#q{XUP6%v+Q z7g|!U;g$wPJC4{@d4z*kJxDS~UMXWGuNsMPi#R_&%70GRk+)gLh{}9bVk|i;j}*oy zt1#sv(5c2jrB2x8zt5E2`53&u?t7$qjQy;-bW|yrRMMSZsVGx%DU9PSCwS7pmM1R3 zTT-KOsqx%XAGI&Gkf57p`rxM>_0LwWc(iKwY-yQ65BtQ7JS_81t~ru%Cqw0io8$)0 zGxET}fL@0p;89EFjFuaBid&-U@f@e$6x9S1cV3Q^u9jAR7fT7=QC{g6y3_`CTn+)$ zt)kaiX2Qb&05&*DOUp!GOY667mcF@W-AMJZFdr6->aJI=H@V6ko6>XM)oh<0N4;K> z{Bbxdx51Mu0FV;af{HawDmZ`uzYERRN-71#US=>Yo!>8v9k@W{7fIE3E)stG$Zx4L z^R3u=@cEqj?$<6$L4&n`E8F2rPmQcuLl5Rz^N&xrL?^_#II=Jt`~+Zh2fU+}mum`c z=1CI2R3RD z4bu2M zR-RX~Fj`pJ-aIlPnJ;dm~zTIT}0%^F@Wy~p`3C!?;?;96&u zJ&67V*yi@G3F_B_A9A8L#8|$29~I=;mTZWIrf6ed6c_=GQY-D+`J$Q9H6ztGaxyl! zn!eu}u1Sp<+2H9(wcdAI{IGiPQ2_Wj50Ev$S+-{>h`m*p@oQ&XZ+hB|t?sbzK~~j9 z-`fQxLlW`2SVT3iY1hY$ZQFfFAV6E4aZX)ihLP{d{)bO^ssUW@824#_qxWBMgue^p zzruh83h{?l<{nB3D{_>%!|a{QgA7-q9->{szeA!}D>X27(=wEzyS zs$5f7-c13276}+@L8EO6k2_Pj<7w1^#0a6rXP*!#G5N5nC)cQqf!vD`r<<<7ml$!^0GY-Zh_*6$T$ybtLXW<-V&>c)k`XDx8rBl)`puHrLaF2 z6SzEaGd0gLPbvSNDT~RCJ0}Lt41nF(R(Xtd&fo0p?V175&%Cpx%22JSeAU8_c;9d@#dEbRe|qtmu%Q#k6@1`i zVvacdo{sfFgr4Sc93<~*j}FSP+R#@+l6N)wR5SHvXmzBuzA9Grw5U{rl&Kz3Qt8+w zNpZ6Hg3JxjYfwEf`I(M0m#3TeAFGLr!uA-x+#|9%5JCPDdE7!$-(Vncq zzQHg3&-?E6Ve(fkG9N7D-MCk;wH2{;i}OsIv2Jd;*7U6|d?Z^_a#GhF=M{JXP0{nCY86a}jeD$LC17CjKUe$ZwIw z3GoR|@k)ohh1C$23Y@SmWe>%M^O{N*lx>K8j-H+T_~!^?h1X>N;e$%$%7*a!a1lgQ z=aCMk4|SbUkRHKPf|_y6aUw>%{mJP~?u10!K1eu(9a1NkV5JV#9xfhjRik*H{%kifr^k&AufB(e z=ZClFb>jMZpTK)d2R}2%wX)&K#2Y@EDt_pqizV_4q9*v>n=g31wdz(Lu6pV7y!#F1^4nt}6(Lu4ly*cIY#GKv zKZM>@Z+mj>Qjo^2Tqcc|8eCzWVcLyq;#57y_O&Z@%N*0}(>|BOdO~{^^46cmH>F+< z5=&&|VlQS5IfUag6y;3*__N%*;R6=G&IiriU+b zvT8jW+aJx>?A?Z+%%9AhC=}Y18>^wJHlD~sjce6%Q^l8Z&>1#4-1{aOrWUHo6WSb>@ zv3MeA!Jb{XSvYvR;S{^^XwKR(HR*aa#_LIG7cBI63Rt%gl?uyrq0QK`vxtnzRP*FzX=Tj1Ubbg8jN(``{Kfc%%$K0$$7e6u zHahg$<=T}zbfn#$e!h98=icr6{#NtF^0sOXt(4A7l@XPs^C930c{ylcjXcrebdqIn z#?8{z;CZ_^fmrPpWuit{ZUmTw{zIf{!(*L^E z{XV6z>iW@rQIb(dLozoOR+}`U0)8n;tO#=1a3Hf(=HKF*vwwqrd96=sA#wib3Ht4C zRom^t$$%G2>tg+CmR|PneTP|}#@yt~IrSkY>%=whx!KvNetf;5|58?rnpY9@5#^J6 z&+zheVE2vL^^Yh0-mGqyvUdq3o^^KkSUW|%>-8i!camjG48wecStUv|surr^uqd3Z z95@lXb*02Z$(S}yOSqT>t&t89I z8sha1GEd&AOY`AVs97pql0BIgJoEL?%IC$x_|rMTjO!80Tj<=;8UTO`OrpP|u{Jis z;3;HzoHNCVAn!}2(%<0#0IDZ_sW|+30uAUya3Oi9ftKnXgMcJwHIS8}G0d2%MQ|nQ z`Fj$~{ZCoo{m+POpsJ@c5o3nc`3XU9sexQ+G%5xP_3`nM_fe3ic)CF0 zXfzrMLqHJ-2wel><>x`e`9eIrBz7TwU|~iQr zB2)LQ=-K*g*@em>or2s)H zA`~HLWdag{!zrMhl<{ySoPyIHlrtWqL-8cz=ruqh<6H<(s)x&7$1cej4HJDe5JDdI zhs4AkM%(I_SKA4--4PcM4;?qb4W z@(PH(p50Vn=)us*#O)S09bivRXBDI6Nx;!4o)#2}yBcWMCE%{*@7>1qIp~a|;jlOw zfes2oATTgA2BBmDM`7Sd3>+p4Q^3Ifq)%}s5&iyO+PgCjsQM$#dL%FU__-t&`=^`i^#it}(G(3hN_CHkA3^f#q|Mj#ZN zQAB450`CNaAYsl(h!c{a48b|0>AWJ*c%<_Wl72_`q7Z35I8TCx3!O(gSM({d#}yE~ zm#AZZ^~J}Pu$u)sVGtM^@{=$G2KgId(EomjP6!1UkzU#mWqOPdBwPszLBkb^5EK!K zz$v3pC?^!^uTK9jg!reL_!*)qbayTNEvc%||1<4BD*;RJB++xK<4Ga!W!#HKU&k=c z|9Kfu`oAs%^rG0c|GVV>Tt*cCqy3)iKOFzlra({G4;g*4q3>PL-#4$HxuloMfAjZq z8vHkh00RFVhfPHbFatXX(7Z9MYeG2&BLDyZ literal 0 HcmV?d00001 diff --git a/firmware/targets/f7/api_symbols.csv b/firmware/targets/f7/api_symbols.csv index c18780acb..18550984d 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,+,1.12,, +Version,+,1.13,, Header,+,applications/services/bt/bt_service/bt.h,, Header,+,applications/services/cli/cli.h,, Header,+,applications/services/cli/cli_vcp.h,, @@ -42,6 +42,7 @@ Header,+,firmware/targets/f7/furi_hal/furi_hal_i2c_types.h,, Header,+,firmware/targets/f7/furi_hal/furi_hal_idle_timer.h,, Header,+,firmware/targets/f7/furi_hal/furi_hal_interrupt.h,, Header,+,firmware/targets/f7/furi_hal/furi_hal_os.h,, +Header,+,firmware/targets/f7/furi_hal/furi_hal_pwm.h,, Header,+,firmware/targets/f7/furi_hal/furi_hal_resources.h,, Header,+,firmware/targets/f7/furi_hal/furi_hal_spi_config.h,, Header,+,firmware/targets/f7/furi_hal/furi_hal_spi_types.h,, @@ -954,6 +955,8 @@ Function,+,furi_hal_cdc_set_callbacks,void,"uint8_t, CdcCallbacks*, void*" Function,+,furi_hal_clock_deinit_early,void, Function,-,furi_hal_clock_init,void, Function,-,furi_hal_clock_init_early,void, +Function,+,furi_hal_clock_mco_disable,void, +Function,+,furi_hal_clock_mco_enable,void,"FuriHalClockMcoSourceId, FuriHalClockMcoDivisorId" Function,-,furi_hal_clock_resume_tick,void, Function,-,furi_hal_clock_suspend_tick,void, Function,-,furi_hal_clock_switch_to_hsi,void, @@ -1150,6 +1153,9 @@ Function,+,furi_hal_power_sleep,void, Function,+,furi_hal_power_sleep_available,_Bool, Function,+,furi_hal_power_suppress_charge_enter,void, Function,+,furi_hal_power_suppress_charge_exit,void, +Function,+,furi_hal_pwm_set_params,void,"FuriHalPwmOutputId, uint32_t, uint8_t" +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_region_get,const FuriHalRegion*, @@ -2665,6 +2671,8 @@ Variable,+,I_SDQuestion_35x43,const Icon, Variable,+,I_SDcardFail_11x8,const Icon, Variable,+,I_SDcardMounted_11x8,const Icon, Variable,+,I_Scanning_123x52,const Icon, +Variable,+,I_SmallArrowDown_4x7,const Icon, +Variable,+,I_SmallArrowUp_4x7,const Icon, Variable,+,I_Smile_18x18,const Icon, Variable,+,I_Space_65x18,const Icon, Variable,+,I_Tap_reader_36x38,const Icon, diff --git a/firmware/targets/f7/furi_hal/furi_hal_clock.c b/firmware/targets/f7/furi_hal/furi_hal_clock.c index a7c9b4d03..cf19451ec 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_clock.c +++ b/firmware/targets/f7/furi_hal/furi_hal_clock.c @@ -1,4 +1,5 @@ #include +#include #include #include @@ -236,3 +237,63 @@ void furi_hal_clock_suspend_tick() { void furi_hal_clock_resume_tick() { SET_BIT(SysTick->CTRL, SysTick_CTRL_ENABLE_Msk); } + +void furi_hal_clock_mco_enable(FuriHalClockMcoSourceId source, FuriHalClockMcoDivisorId div) { + if(source == FuriHalClockMcoLse) { + LL_RCC_ConfigMCO(LL_RCC_MCO1SOURCE_LSE, div); + } else if(source == FuriHalClockMcoSysclk) { + LL_RCC_ConfigMCO(LL_RCC_MCO1SOURCE_SYSCLK, div); + } else { + LL_RCC_MSI_Enable(); + while(LL_RCC_MSI_IsReady() != 1) + ; + switch(source) { + case FuriHalClockMcoMsi100k: + LL_RCC_MSI_SetRange(LL_RCC_MSIRANGE_0); + break; + case FuriHalClockMcoMsi200k: + LL_RCC_MSI_SetRange(LL_RCC_MSIRANGE_1); + break; + case FuriHalClockMcoMsi400k: + LL_RCC_MSI_SetRange(LL_RCC_MSIRANGE_2); + break; + case FuriHalClockMcoMsi800k: + LL_RCC_MSI_SetRange(LL_RCC_MSIRANGE_3); + break; + case FuriHalClockMcoMsi1m: + LL_RCC_MSI_SetRange(LL_RCC_MSIRANGE_4); + break; + case FuriHalClockMcoMsi2m: + LL_RCC_MSI_SetRange(LL_RCC_MSIRANGE_5); + break; + case FuriHalClockMcoMsi4m: + LL_RCC_MSI_SetRange(LL_RCC_MSIRANGE_6); + break; + case FuriHalClockMcoMsi8m: + LL_RCC_MSI_SetRange(LL_RCC_MSIRANGE_7); + break; + case FuriHalClockMcoMsi16m: + LL_RCC_MSI_SetRange(LL_RCC_MSIRANGE_8); + break; + case FuriHalClockMcoMsi24m: + LL_RCC_MSI_SetRange(LL_RCC_MSIRANGE_9); + break; + case FuriHalClockMcoMsi32m: + LL_RCC_MSI_SetRange(LL_RCC_MSIRANGE_10); + break; + case FuriHalClockMcoMsi48m: + LL_RCC_MSI_SetRange(LL_RCC_MSIRANGE_11); + break; + default: + break; + } + LL_RCC_ConfigMCO(LL_RCC_MCO1SOURCE_MSI, div); + } +} + +void furi_hal_clock_mco_disable() { + LL_RCC_ConfigMCO(LL_RCC_MCO1SOURCE_NOCLOCK, FuriHalClockMcoDiv1); + LL_RCC_MSI_Disable(); + while(LL_RCC_MSI_IsReady() != 0) + ; +} \ No newline at end of file diff --git a/firmware/targets/f7/furi_hal/furi_hal_clock.h b/firmware/targets/f7/furi_hal/furi_hal_clock.h index 6cebb20c6..5e651bbd3 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_clock.h +++ b/firmware/targets/f7/furi_hal/furi_hal_clock.h @@ -4,6 +4,33 @@ extern "C" { #endif +#include + +typedef enum { + FuriHalClockMcoLse, + FuriHalClockMcoSysclk, + FuriHalClockMcoMsi100k, + FuriHalClockMcoMsi200k, + FuriHalClockMcoMsi400k, + FuriHalClockMcoMsi800k, + FuriHalClockMcoMsi1m, + FuriHalClockMcoMsi2m, + FuriHalClockMcoMsi4m, + FuriHalClockMcoMsi8m, + FuriHalClockMcoMsi16m, + FuriHalClockMcoMsi24m, + FuriHalClockMcoMsi32m, + FuriHalClockMcoMsi48m, +} FuriHalClockMcoSourceId; + +typedef enum { + FuriHalClockMcoDiv1 = LL_RCC_MCO1_DIV_1, + FuriHalClockMcoDiv2 = LL_RCC_MCO1_DIV_2, + FuriHalClockMcoDiv4 = LL_RCC_MCO1_DIV_4, + FuriHalClockMcoDiv8 = LL_RCC_MCO1_DIV_8, + FuriHalClockMcoDiv16 = LL_RCC_MCO1_DIV_16, +} FuriHalClockMcoDivisorId; + /** Early initialization */ void furi_hal_clock_init_early(); @@ -25,6 +52,16 @@ void furi_hal_clock_suspend_tick(); /** Continue SysTick counter operation */ void furi_hal_clock_resume_tick(); +/** Enable clock output on MCO pin + * + * @param source MCO clock source + * @param div MCO clock division +*/ +void furi_hal_clock_mco_enable(FuriHalClockMcoSourceId source, FuriHalClockMcoDivisorId div); + +/** Disable clock output on MCO pin */ +void furi_hal_clock_mco_disable(); + #ifdef __cplusplus } #endif diff --git a/firmware/targets/f7/furi_hal/furi_hal_pwm.c b/firmware/targets/f7/furi_hal/furi_hal_pwm.c new file mode 100644 index 000000000..e484808d5 --- /dev/null +++ b/firmware/targets/f7/furi_hal/furi_hal_pwm.c @@ -0,0 +1,138 @@ +#include "furi_hal_pwm.h" +#include +#include + +#include +#include +#include +#include + +#include + +const uint32_t lptim_psc_table[] = { + LL_LPTIM_PRESCALER_DIV1, + LL_LPTIM_PRESCALER_DIV2, + LL_LPTIM_PRESCALER_DIV4, + LL_LPTIM_PRESCALER_DIV8, + LL_LPTIM_PRESCALER_DIV16, + LL_LPTIM_PRESCALER_DIV32, + LL_LPTIM_PRESCALER_DIV64, + LL_LPTIM_PRESCALER_DIV128, +}; + +void furi_hal_pwm_start(FuriHalPwmOutputId channel, uint32_t freq, uint8_t duty) { + if(channel == FuriHalPwmOutputIdTim1PA7) { + furi_hal_gpio_init_ex( + &gpio_ext_pa7, + GpioModeAltFunctionPushPull, + GpioPullNo, + GpioSpeedVeryHigh, + GpioAltFn1TIM1); + + FURI_CRITICAL_ENTER(); + LL_TIM_DeInit(TIM1); + FURI_CRITICAL_EXIT(); + + LL_TIM_SetCounterMode(TIM1, LL_TIM_COUNTERMODE_UP); + LL_TIM_SetRepetitionCounter(TIM1, 0); + LL_TIM_SetClockDivision(TIM1, LL_TIM_CLOCKDIVISION_DIV1); + LL_TIM_SetClockSource(TIM1, LL_TIM_CLOCKSOURCE_INTERNAL); + LL_TIM_EnableARRPreload(TIM1); + + LL_TIM_OC_EnablePreload(TIM1, LL_TIM_CHANNEL_CH1); + LL_TIM_OC_SetMode(TIM1, LL_TIM_CHANNEL_CH1, LL_TIM_OCMODE_PWM1); + 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_EnableAllOutputs(TIM1); + + furi_hal_pwm_set_params(channel, freq, duty); + + LL_TIM_EnableCounter(TIM1); + } else if(channel == FuriHalPwmOutputIdLptim2PA4) { + furi_hal_gpio_init_ex( + &gpio_ext_pa4, + GpioModeAltFunctionPushPull, + GpioPullNo, + GpioSpeedVeryHigh, + GpioAltFn14LPTIM2); + + FURI_CRITICAL_ENTER(); + LL_LPTIM_DeInit(LPTIM2); + FURI_CRITICAL_EXIT(); + + LL_LPTIM_SetUpdateMode(LPTIM2, LL_LPTIM_UPDATE_MODE_ENDOFPERIOD); + LL_RCC_SetLPTIMClockSource(LL_RCC_LPTIM2_CLKSOURCE_PCLK1); + LL_LPTIM_SetClockSource(LPTIM2, LL_LPTIM_CLK_SOURCE_INTERNAL); + LL_LPTIM_ConfigOutput( + LPTIM2, LL_LPTIM_OUTPUT_WAVEFORM_PWM, LL_LPTIM_OUTPUT_POLARITY_INVERSE); + LL_LPTIM_SetCounterMode(LPTIM2, LL_LPTIM_COUNTER_MODE_INTERNAL); + + LL_LPTIM_Enable(LPTIM2); + + furi_hal_pwm_set_params(channel, freq, duty); + + LL_LPTIM_StartCounter(LPTIM2, LL_LPTIM_OPERATING_MODE_CONTINUOUS); + } +} + +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(); + } else if(channel == FuriHalPwmOutputIdLptim2PA4) { + furi_hal_gpio_init_simple(&gpio_ext_pa4, GpioModeAnalog); + FURI_CRITICAL_ENTER(); + LL_LPTIM_DeInit(LPTIM2); + FURI_CRITICAL_EXIT(); + } +} + +void furi_hal_pwm_set_params(FuriHalPwmOutputId channel, uint32_t freq, uint8_t duty) { + furi_assert(freq > 0); + uint32_t freq_div = 64000000LU / freq; + + if(channel == FuriHalPwmOutputIdTim1PA7) { + uint32_t prescaler = freq_div / 0x10000LU; + uint32_t period = freq_div / (prescaler + 1); + uint32_t compare = period * duty / 100; + + LL_TIM_SetPrescaler(TIM1, prescaler); + LL_TIM_SetAutoReload(TIM1, period - 1); + LL_TIM_OC_SetCompareCH1(TIM1, compare); + } else if(channel == FuriHalPwmOutputIdLptim2PA4) { + uint32_t prescaler = 0; + uint32_t period = 0; + + bool clock_lse = false; + + do { + period = freq_div / (1 << prescaler); + if(period <= 0xFFFF) { + break; + } + prescaler++; + if(prescaler > 7) { + prescaler = 0; + clock_lse = true; + period = 32768LU / freq; + break; + } + } while(1); + + uint32_t compare = period * duty / 100; + + LL_LPTIM_SetPrescaler(LPTIM2, lptim_psc_table[prescaler]); + LL_LPTIM_SetAutoReload(LPTIM2, period); + LL_LPTIM_SetCompare(LPTIM2, compare); + + if(clock_lse) { + LL_RCC_SetLPTIMClockSource(LL_RCC_LPTIM2_CLKSOURCE_LSE); + } else { + LL_RCC_SetLPTIMClockSource(LL_RCC_LPTIM2_CLKSOURCE_PCLK1); + } + } +} diff --git a/firmware/targets/f7/furi_hal/furi_hal_pwm.h b/firmware/targets/f7/furi_hal/furi_hal_pwm.h new file mode 100644 index 000000000..a8682c5fb --- /dev/null +++ b/firmware/targets/f7/furi_hal/furi_hal_pwm.h @@ -0,0 +1,42 @@ +/** + * @file furi_hal_pwm.h + * PWM contol HAL + */ +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +typedef enum { + FuriHalPwmOutputIdTim1PA7, + FuriHalPwmOutputIdLptim2PA4, +} FuriHalPwmOutputId; + +/** Enable PWM channel and set parameters + * + * @param[in] channel PWM channel (FuriHalPwmOutputId) + * @param[in] freq Frequency in Hz + * @param[in] duty Duty cycle value in % +*/ +void furi_hal_pwm_start(FuriHalPwmOutputId channel, uint32_t freq, uint8_t duty); + +/** Disable PWM channel + * + * @param[in] channel PWM channel (FuriHalPwmOutputId) +*/ +void furi_hal_pwm_stop(FuriHalPwmOutputId channel); + +/** Set PWM channel parameters + * + * @param[in] channel PWM channel (FuriHalPwmOutputId) + * @param[in] freq Frequency in Hz + * @param[in] duty Duty cycle value in % +*/ +void furi_hal_pwm_set_params(FuriHalPwmOutputId channel, uint32_t freq, uint8_t duty); + +#ifdef __cplusplus +} +#endif From e25b4241881cabeb6dff957303179cc0ba254cf6 Mon Sep 17 00:00:00 2001 From: Vyacheslav Tumanov Date: Wed, 28 Sep 2022 21:52:46 +0500 Subject: [PATCH 39/47] Typos fix in some strings/comments #1794 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: あく --- applications/services/gui/canvas.h | 6 +++--- applications/services/gui/modules/button_panel.h | 2 +- documentation/AppManifests.md | 2 +- scripts/assets.py | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/applications/services/gui/canvas.h b/applications/services/gui/canvas.h index 4923e2e66..49bbd7d68 100644 --- a/applications/services/gui/canvas.h +++ b/applications/services/gui/canvas.h @@ -61,7 +61,7 @@ typedef struct { uint8_t descender; } CanvasFontParameters; -/** Canvas anonymouse structure */ +/** Canvas anonymous structure */ typedef struct Canvas Canvas; /** Get Canvas width @@ -297,7 +297,7 @@ void canvas_draw_disc(Canvas* canvas, uint8_t x, uint8_t y, uint8_t r); * @param y y coordinate of base and height intersection * @param base length of triangle side * @param height length of triangle height - * @param dir CanvasDirection triangle orientaion + * @param dir CanvasDirection triangle orientation */ void canvas_draw_triangle( Canvas* canvas, @@ -323,7 +323,7 @@ void canvas_draw_glyph(Canvas* canvas, uint8_t x, uint8_t y, uint16_t ch); */ void canvas_set_bitmap_mode(Canvas* canvas, bool alpha); -/** Draw rounded-corner frame of width, height at x,y, with round value raduis +/** Draw rounded-corner frame of width, height at x,y, with round value radius * * @param canvas Canvas instance * @param x x coordinate diff --git a/applications/services/gui/modules/button_panel.h b/applications/services/gui/modules/button_panel.h index 0c17e3a7c..f3b0bae70 100644 --- a/applications/services/gui/modules/button_panel.h +++ b/applications/services/gui/modules/button_panel.h @@ -53,7 +53,7 @@ void button_panel_reserve(ButtonPanel* button_panel, size_t reserve_x, size_t re * @param button_panel ButtonPanel instance * @param index value to pass to callback * @param matrix_place_x coordinates by x-axis on virtual grid, it - * is only used for naviagation + * is only used for navigation * @param matrix_place_y coordinates by y-axis on virtual grid, it * is only used for naviagation * @param x x-coordinate to draw icon on diff --git a/documentation/AppManifests.md b/documentation/AppManifests.md index 7bc8d0a47..5b14b7ddb 100644 --- a/documentation/AppManifests.md +++ b/documentation/AppManifests.md @@ -48,7 +48,7 @@ The following parameters are used only for [FAPs](./AppsOnSDCard.md): * **fap_icon**: name of a .png file, 1-bit color depth, 10x10px, to be embedded within .fap file. * **fap_libs**: list of extra libraries to link application against. Provides access to extra functions that are not exported as a part of main firmware at expense of increased .fap file size and RAM consumption. * **fap_category**: string, may be empty. App subcategory, also works as path of FAP within apps folder in the file system. -* **fap_description**: string, may be empty. Short application descriotion. +* **fap_description**: string, may be empty. Short application description. * **fap_author**: string, may be empty. Application's author. * **fap_weburl**: string, may be empty. Application's homepage. diff --git a/scripts/assets.py b/scripts/assets.py index 1f36a135b..6f9410137 100755 --- a/scripts/assets.py +++ b/scripts/assets.py @@ -111,7 +111,7 @@ class Main(App): if not filenames: continue if "frame_rate" in filenames: - self.logger.debug(f"Folder contatins animation") + self.logger.debug(f"Folder contains animation") icon_name = "A_" + os.path.split(dirpath)[1].replace("-", "_") width = height = None frame_count = 0 From f8b532f06317298566b730a4c6bc17dd6ee35f4e Mon Sep 17 00:00:00 2001 From: hedger Date: Wed, 28 Sep 2022 21:13:12 +0400 Subject: [PATCH 40/47] [FL-2831] Resources cleanup in updater (#1796) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * updater: remove files from existing resources Manifest file before deploying new resources * toolbox: tar: single file extraction API Co-authored-by: あく --- .../system/updater/util/update_task.h | 2 +- .../updater/util/update_task_worker_backup.c | 41 ++++++- .../updater/util/update_task_worker_flasher.c | 2 +- firmware/targets/f7/api_symbols.csv | 1 + .../targets/f7/furi_hal/furi_hal_cortex.c | 3 + lib/toolbox/tar/tar_archive.c | 100 ++++++++------- lib/toolbox/tar/tar_archive.h | 5 + lib/update_util/resources/manifest.c | 115 ++++++++++++++++++ lib/update_util/resources/manifest.h | 58 +++++++++ 9 files changed, 281 insertions(+), 46 deletions(-) create mode 100644 lib/update_util/resources/manifest.c create mode 100644 lib/update_util/resources/manifest.h diff --git a/applications/system/updater/util/update_task.h b/applications/system/updater/util/update_task.h index 1f2915568..ad8c50857 100644 --- a/applications/system/updater/util/update_task.h +++ b/applications/system/updater/util/update_task.h @@ -10,7 +10,7 @@ extern "C" { #include #include -#define UPDATE_DELAY_OPERATION_OK 300 +#define UPDATE_DELAY_OPERATION_OK 10 #define UPDATE_DELAY_OPERATION_ERROR INT_MAX typedef enum { diff --git a/applications/system/updater/util/update_task_worker_backup.c b/applications/system/updater/util/update_task_worker_backup.c index 09e459533..046be372d 100644 --- a/applications/system/updater/util/update_task_worker_backup.c +++ b/applications/system/updater/util/update_task_worker_backup.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -50,10 +51,46 @@ static bool update_task_resource_unpack_cb(const char* name, bool is_directory, update_task_set_progress( unpack_progress->update_task, UpdateTaskStageProgress, - unpack_progress->processed_files * 100 / (unpack_progress->total_files + 1)); + /* For this stage, last 70% of progress = extraction */ + 30 + (unpack_progress->processed_files * 70) / (unpack_progress->total_files + 1)); return true; } +static void + update_task_cleanup_resources(UpdateTask* update_task, uint32_t n_approx_file_entries) { + ResourceManifestReader* manifest_reader = resource_manifest_reader_alloc(update_task->storage); + do { + FURI_LOG_I(TAG, "Cleaning up old manifest"); + if(!resource_manifest_reader_open(manifest_reader, EXT_PATH("Manifest"))) { + FURI_LOG_W(TAG, "No existing manifest"); + break; + } + + /* We got # of entries in TAR file. Approx 1/4th is dir entries, we skip them */ + n_approx_file_entries = n_approx_file_entries * 3 / 4 + 1; + uint32_t n_processed_files = 0; + + ResourceManifestEntry* entry_ptr = NULL; + while((entry_ptr = resource_manifest_reader_next(manifest_reader))) { + if(entry_ptr->type == ResourceManifestEntryTypeFile) { + update_task_set_progress( + update_task, + UpdateTaskStageProgress, + /* For this stage, first 30% of progress = cleanup */ + (n_processed_files++ * 30) / (n_approx_file_entries + 1)); + + string_t file_path; + string_init(file_path); + path_concat(STORAGE_EXT_PATH_PREFIX, string_get_cstr(entry_ptr->name), file_path); + FURI_LOG_D(TAG, "Removing %s", string_get_cstr(file_path)); + storage_simply_remove(update_task->storage, string_get_cstr(file_path)); + string_clear(file_path); + } + } + } while(false); + resource_manifest_reader_free(manifest_reader); +} + static bool update_task_post_update(UpdateTask* update_task) { bool success = false; @@ -88,6 +125,8 @@ static bool update_task_post_update(UpdateTask* update_task) { progress.total_files = tar_archive_get_entries_count(archive); if(progress.total_files > 0) { + update_task_cleanup_resources(update_task, progress.total_files); + CHECK_RESULT(tar_archive_unpack_to(archive, STORAGE_EXT_PATH_PREFIX, NULL)); } } diff --git a/applications/system/updater/util/update_task_worker_flasher.c b/applications/system/updater/util/update_task_worker_flasher.c index 7b598c50b..b235d0018 100644 --- a/applications/system/updater/util/update_task_worker_flasher.c +++ b/applications/system/updater/util/update_task_worker_flasher.c @@ -308,7 +308,7 @@ bool update_task_validate_optionbytes(UpdateTask* update_task) { } } } else { - FURI_LOG_I( + FURI_LOG_D( TAG, "OB MATCH: #%d: real %08X == %08X (exp.)", idx, diff --git a/firmware/targets/f7/api_symbols.csv b/firmware/targets/f7/api_symbols.csv index 18550984d..2cbdae77c 100644 --- a/firmware/targets/f7/api_symbols.csv +++ b/firmware/targets/f7/api_symbols.csv @@ -2269,6 +2269,7 @@ Function,+,tar_archive_get_entries_count,int32_t,TarArchive* Function,+,tar_archive_open,_Bool,"TarArchive*, const char*, TarOpenMode" Function,+,tar_archive_set_file_callback,void,"TarArchive*, tar_unpack_file_cb, void*" Function,+,tar_archive_store_data,_Bool,"TarArchive*, const char*, const uint8_t*, const int32_t" +Function,+,tar_archive_unpack_file,_Bool,"TarArchive*, const char*, const char*" Function,+,tar_archive_unpack_to,_Bool,"TarArchive*, const char*, Storage_name_converter" Function,-,tempnam,char*,"const char*, const char*" Function,+,text_box_alloc,TextBox*, diff --git a/firmware/targets/f7/furi_hal/furi_hal_cortex.c b/firmware/targets/f7/furi_hal/furi_hal_cortex.c index 2b4ea6e99..c9c8400a7 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_cortex.c +++ b/firmware/targets/f7/furi_hal/furi_hal_cortex.c @@ -6,6 +6,9 @@ void furi_hal_cortex_init_early() { CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk; DWT->CYCCNT = 0U; + + /* Enable instruction prefetch */ + SET_BIT(FLASH->ACR, FLASH_ACR_PRFTEN); } void furi_hal_cortex_delay_us(uint32_t microseconds) { diff --git a/lib/toolbox/tar/tar_archive.c b/lib/toolbox/tar/tar_archive.c index f51d62317..1a542b2e0 100644 --- a/lib/toolbox/tar/tar_archive.c +++ b/lib/toolbox/tar/tar_archive.c @@ -168,7 +168,44 @@ typedef struct { Storage_name_converter converter; } TarArchiveDirectoryOpParams; +static bool archive_extract_current_file(TarArchive* archive, const char* dst_path) { + mtar_t* tar = &archive->tar; + File* out_file = storage_file_alloc(archive->storage); + uint8_t* readbuf = malloc(FILE_BLOCK_SIZE); + + bool success = true; + uint8_t n_tries = FILE_OPEN_NTRIES; + do { + while(n_tries-- > 0) { + if(storage_file_open(out_file, dst_path, FSAM_WRITE, FSOM_CREATE_ALWAYS)) { + break; + } + FURI_LOG_W(TAG, "Failed to open '%s', reties: %d", dst_path, n_tries); + storage_file_close(out_file); + furi_delay_ms(FILE_OPEN_RETRY_DELAY); + } + + if(!storage_file_is_open(out_file)) { + success = false; + break; + } + + while(!mtar_eof_data(tar)) { + int32_t readcnt = mtar_read_data(tar, readbuf, FILE_BLOCK_SIZE); + if(!readcnt || !storage_file_write(out_file, readbuf, readcnt)) { + success = false; + break; + } + } + } while(false); + storage_file_free(out_file); + free(readbuf); + + return success; +} + static int archive_extract_foreach_cb(mtar_t* tar, const mtar_header_t* header, void* param) { + UNUSED(tar); TarArchiveDirectoryOpParams* op_params = param; TarArchive* archive = op_params->archive; @@ -199,58 +236,22 @@ static int archive_extract_foreach_cb(mtar_t* tar, const mtar_header_t* header, return 0; } - string_init(full_extracted_fname); + FURI_LOG_D(TAG, "Extracting %d bytes to '%s'", header->size, header->name); string_t converted_fname; string_init_set(converted_fname, header->name); if(op_params->converter) { op_params->converter(converted_fname); } + + string_init(full_extracted_fname); path_concat(op_params->work_dir, string_get_cstr(converted_fname), full_extracted_fname); + + bool success = archive_extract_current_file(archive, string_get_cstr(full_extracted_fname)); + string_clear(converted_fname); - - FURI_LOG_D(TAG, "Extracting %d bytes to '%s'", header->size, header->name); - File* out_file = storage_file_alloc(archive->storage); - uint8_t* readbuf = malloc(FILE_BLOCK_SIZE); - - bool failed = false; - uint8_t n_tries = FILE_OPEN_NTRIES; - do { - while(n_tries-- > 0) { - if(storage_file_open( - out_file, - string_get_cstr(full_extracted_fname), - FSAM_WRITE, - FSOM_CREATE_ALWAYS)) { - break; - } - FURI_LOG_W( - TAG, - "Failed to open '%s', reties: %d", - string_get_cstr(full_extracted_fname), - n_tries); - storage_file_close(out_file); - furi_delay_ms(FILE_OPEN_RETRY_DELAY); - } - - if(!storage_file_is_open(out_file)) { - failed = true; - break; - } - - while(!mtar_eof_data(tar)) { - int32_t readcnt = mtar_read_data(tar, readbuf, FILE_BLOCK_SIZE); - if(!readcnt || !storage_file_write(out_file, readbuf, readcnt)) { - failed = true; - break; - } - } - } while(false); - - storage_file_free(out_file); - free(readbuf); string_clear(full_extracted_fname); - return failed ? -1 : 0; + return success ? 0 : -1; } bool tar_archive_unpack_to( @@ -369,3 +370,16 @@ bool tar_archive_add_dir(TarArchive* archive, const char* fs_full_path, const ch storage_file_free(directory); return success; } + +bool tar_archive_unpack_file( + TarArchive* archive, + const char* archive_fname, + const char* destination) { + furi_assert(archive); + furi_assert(archive_fname); + furi_assert(destination); + if(mtar_find(&archive->tar, archive_fname) != MTAR_ESUCCESS) { + return false; + } + return archive_extract_current_file(archive, destination); +} \ No newline at end of file diff --git a/lib/toolbox/tar/tar_archive.h b/lib/toolbox/tar/tar_archive.h index 88cb3dd4d..ceaf82ee9 100644 --- a/lib/toolbox/tar/tar_archive.h +++ b/lib/toolbox/tar/tar_archive.h @@ -41,6 +41,11 @@ bool tar_archive_add_dir(TarArchive* archive, const char* fs_full_path, const ch int32_t tar_archive_get_entries_count(TarArchive* archive); +bool tar_archive_unpack_file( + TarArchive* archive, + const char* archive_fname, + const char* destination); + /* Optional per-entry callback on unpacking - return false to skip entry */ typedef bool (*tar_unpack_file_cb)(const char* name, bool is_directory, void* context); diff --git a/lib/update_util/resources/manifest.c b/lib/update_util/resources/manifest.c new file mode 100644 index 000000000..4f8a7d1ab --- /dev/null +++ b/lib/update_util/resources/manifest.c @@ -0,0 +1,115 @@ +#include "manifest.h" + +#include +#include + +struct ResourceManifestReader { + Storage* storage; + Stream* stream; + string_t linebuf; + ResourceManifestEntry entry; +}; + +ResourceManifestReader* resource_manifest_reader_alloc(Storage* storage) { + ResourceManifestReader* resource_manifest = + (ResourceManifestReader*)malloc(sizeof(ResourceManifestReader)); + resource_manifest->storage = storage; + resource_manifest->stream = buffered_file_stream_alloc(resource_manifest->storage); + memset(&resource_manifest->entry, 0, sizeof(ResourceManifestEntry)); + string_init(resource_manifest->entry.name); + string_init(resource_manifest->linebuf); + return resource_manifest; +} + +void resource_manifest_reader_free(ResourceManifestReader* resource_manifest) { + furi_assert(resource_manifest); + + string_clear(resource_manifest->linebuf); + string_clear(resource_manifest->entry.name); + buffered_file_stream_close(resource_manifest->stream); + stream_free(resource_manifest->stream); + free(resource_manifest); +} + +bool resource_manifest_reader_open(ResourceManifestReader* resource_manifest, const char* filename) { + furi_assert(resource_manifest); + + return buffered_file_stream_open( + resource_manifest->stream, filename, FSAM_READ, FSOM_OPEN_EXISTING); +} + +/* Read entries in format of + * F::: + * D: + */ +ResourceManifestEntry* resource_manifest_reader_next(ResourceManifestReader* resource_manifest) { + furi_assert(resource_manifest); + + string_reset(resource_manifest->entry.name); + resource_manifest->entry.type = ResourceManifestEntryTypeUnknown; + resource_manifest->entry.size = 0; + memset(resource_manifest->entry.hash, 0, sizeof(resource_manifest->entry.hash)); + + do { + if(!stream_read_line(resource_manifest->stream, resource_manifest->linebuf)) { + return NULL; + } + + /* Trim end of line */ + string_strim(resource_manifest->linebuf); + + char type_code = string_get_char(resource_manifest->linebuf, 0); + switch(type_code) { + case 'F': + resource_manifest->entry.type = ResourceManifestEntryTypeFile; + break; + case 'D': + resource_manifest->entry.type = ResourceManifestEntryTypeDirectory; + break; + default: /* Skip other entries - version, timestamp, etc */ + continue; + }; + + if(resource_manifest->entry.type == ResourceManifestEntryTypeFile) { + /* Parse file entry + F::: */ + + /* Remove entry type code */ + string_right(resource_manifest->linebuf, 2); + + if(string_search_char(resource_manifest->linebuf, ':') != + sizeof(resource_manifest->entry.hash) * 2) { + /* Invalid hash */ + continue; + } + + /* Read hash */ + hex_chars_to_uint8( + string_get_cstr(resource_manifest->linebuf), resource_manifest->entry.hash); + + /* Remove hash */ + string_right( + resource_manifest->linebuf, sizeof(resource_manifest->entry.hash) * 2 + 1); + + resource_manifest->entry.size = atoi(string_get_cstr(resource_manifest->linebuf)); + + /* Remove size */ + size_t offs = string_search_char(resource_manifest->linebuf, ':'); + string_right(resource_manifest->linebuf, offs + 1); + + string_set(resource_manifest->entry.name, resource_manifest->linebuf); + } else if(resource_manifest->entry.type == ResourceManifestEntryTypeDirectory) { + /* Parse directory entry + D: */ + + /* Remove entry type code */ + string_right(resource_manifest->linebuf, 2); + + string_set(resource_manifest->entry.name, resource_manifest->linebuf); + } + + return &resource_manifest->entry; + } while(true); + + return NULL; +} diff --git a/lib/update_util/resources/manifest.h b/lib/update_util/resources/manifest.h new file mode 100644 index 000000000..092b7badb --- /dev/null +++ b/lib/update_util/resources/manifest.h @@ -0,0 +1,58 @@ +#pragma once + +#include + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + ResourceManifestEntryTypeUnknown = 0, + ResourceManifestEntryTypeDirectory, + ResourceManifestEntryTypeFile, +} ResourceManifestEntryType; + +typedef struct { + ResourceManifestEntryType type; + string_t name; + uint32_t size; + uint8_t hash[16]; +} ResourceManifestEntry; + +typedef struct ResourceManifestReader ResourceManifestReader; + +/** + * @brief Initialize resource manifest reader + * @param storage Storage API pointer + * @return allocated object + */ +ResourceManifestReader* resource_manifest_reader_alloc(Storage* storage); + +/** + * @brief Release resource manifest reader + * @param resource_manifest allocated object + */ +void resource_manifest_reader_free(ResourceManifestReader* resource_manifest); + +/** + * @brief Initialize resource manifest reader iteration + * @param resource_manifest allocated object + * @param filename manifest file name + * @return true if file opened + */ +bool resource_manifest_reader_open(ResourceManifestReader* resource_manifest, const char* filename); + +/** + * @brief Read next file/dir entry from manifest + * @param resource_manifest allocated object + * @return entry or NULL if end of file + */ +ResourceManifestEntry* resource_manifest_reader_next(ResourceManifestReader* resource_manifest); + +#ifdef __cplusplus +} // extern "C" +#endif \ No newline at end of file From 5883e134d4c870a2b08f705eb48a2e56f8a24a23 Mon Sep 17 00:00:00 2001 From: Sergey Gavrilov Date: Thu, 29 Sep 2022 03:37:07 +1000 Subject: [PATCH 41/47] Furi Thread: don't use thread pointer after FuriThreadStateStopped callback (#1799) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Furi Thread: correct furi_thread_join, do not use thread pointer after FuriThreadStateStopped callback * Furi: a little bit easier way to do harakiri * Furi: crash on thread self join attempt Co-authored-by: あく --- furi/core/thread.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/furi/core/thread.c b/furi/core/thread.c index 58cb9bc09..538ae4d87 100644 --- a/furi/core/thread.c +++ b/furi/core/thread.c @@ -85,7 +85,6 @@ static void furi_thread_body(void* context) { } furi_assert(thread->state == FuriThreadStateRunning); - furi_thread_set_state(thread, FuriThreadStateStopped); if(thread->is_service) { FURI_LOG_E( @@ -99,7 +98,10 @@ static void furi_thread_body(void* context) { furi_assert(pvTaskGetThreadLocalStoragePointer(NULL, 0) != NULL); vTaskSetThreadLocalStoragePointer(NULL, 0, NULL); - vTaskDelete(thread->task_handle); + // from here we can't use thread pointer + furi_thread_set_state(thread, FuriThreadStateStopped); + + vTaskDelete(NULL); furi_thread_catch(); } @@ -205,7 +207,9 @@ void furi_thread_start(FuriThread* thread) { bool furi_thread_join(FuriThread* thread) { furi_assert(thread); - while(thread->state != FuriThreadStateStopped) { + furi_check(furi_thread_get_current() != thread); + + while(eTaskGetState(thread->task_handle) != eDeleted) { furi_delay_ms(10); } From bcfb12bf28ab8784732a76cb0400318de7a12585 Mon Sep 17 00:00:00 2001 From: Mewa Date: Wed, 28 Sep 2022 19:44:24 +0200 Subject: [PATCH 42/47] Keyboard: show Uppercase keys when replacing content (#1548) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: あく --- applications/services/gui/modules/text_input.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/applications/services/gui/modules/text_input.c b/applications/services/gui/modules/text_input.c index 58d7ecab0..b2aba03fc 100644 --- a/applications/services/gui/modules/text_input.c +++ b/applications/services/gui/modules/text_input.c @@ -232,7 +232,8 @@ static void text_input_view_draw_callback(Canvas* canvas, void* _model) { canvas_set_color(canvas, ColorBlack); } - if(text_length == 0 && char_is_lowercase(keys[column].text)) { + if(model->clear_default_text || + (text_length == 0 && char_is_lowercase(keys[column].text))) { canvas_draw_glyph( canvas, keyboard_origin_x + keys[column].x, From 62e56e2618baaf46333954d1e47cab2dd71d02b8 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Thu, 29 Sep 2022 08:20:00 +0300 Subject: [PATCH 43/47] rename apps to make it look a bit better in Apps tab in archive app now old assets are removed so we can avoid duplicates --- applications/debug/application.fam | 4 ++-- applications/debug/uart_echo/application.fam | 2 +- applications/debug/usb_mouse/application.fam | 2 +- applications/plugins/arkanoid/application.fam | 2 +- applications/plugins/barcode_generator/application.fam | 2 +- applications/plugins/bt_hid_app/application.fam | 2 +- applications/plugins/doom/application.fam | 2 +- applications/plugins/esp8266_deauth/application.fam | 2 +- applications/plugins/flappy_bird/application.fam | 2 +- applications/plugins/flipfrid/application.fam | 2 +- applications/plugins/mousejacker/application.fam | 2 +- applications/plugins/multi_converter/application.fam | 2 +- applications/plugins/music_player/application.fam | 2 +- applications/plugins/nrfsniff/application.fam | 2 +- applications/plugins/picopass/application.fam | 2 +- applications/plugins/playlist/application.fam | 2 +- applications/plugins/sentry_safe/application.fam | 2 +- applications/plugins/signal_generator/application.fam | 2 +- applications/plugins/snake_game/application.fam | 2 +- applications/plugins/spectrum_analyzer/application.fam | 2 +- applications/plugins/subbrute/application.fam | 2 +- applications/plugins/tetris_game/application.fam | 2 +- applications/plugins/tictactoe_game/application.fam | 2 +- applications/plugins/wav_player/application.fam | 2 +- applications/plugins/wifi_marauder_companion/application.fam | 2 +- applications/plugins/wifi_scanner/application.fam | 2 +- applications/plugins/zombiez/application.fam | 2 +- applications/services/desktop/scenes/desktop_scene_main.c | 4 ++-- 28 files changed, 30 insertions(+), 30 deletions(-) diff --git a/applications/debug/application.fam b/applications/debug/application.fam index a33b3693d..c52907002 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/debug/uart_echo/application.fam b/applications/debug/uart_echo/application.fam index 956aa17af..a979c2e4f 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.PLUGIN, entry_point="uart_echo_app", diff --git a/applications/debug/usb_mouse/application.fam b/applications/debug/usb_mouse/application.fam index 9c2f19da6..fb7595e10 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.PLUGIN, entry_point="usb_mouse_app", diff --git a/applications/plugins/arkanoid/application.fam b/applications/plugins/arkanoid/application.fam index 99a2f10bc..05520b4bf 100644 --- a/applications/plugins/arkanoid/application.fam +++ b/applications/plugins/arkanoid/application.fam @@ -1,5 +1,5 @@ App( - appid="arkanoid_game", + appid="Arkanoid", name="Arkanoid", apptype=FlipperAppType.EXTERNAL, entry_point="arkanoid_game_app", diff --git a/applications/plugins/barcode_generator/application.fam b/applications/plugins/barcode_generator/application.fam index 05ddbae0f..0724fdfba 100644 --- a/applications/plugins/barcode_generator/application.fam +++ b/applications/plugins/barcode_generator/application.fam @@ -1,5 +1,5 @@ App( - appid="barcode_generator", + appid="Barcode_Generator", name="UPC-A Generator", apptype=FlipperAppType.EXTERNAL, entry_point="barcode_UPCA_generator_app", diff --git a/applications/plugins/bt_hid_app/application.fam b/applications/plugins/bt_hid_app/application.fam index e6a3b1752..e18783e9a 100644 --- a/applications/plugins/bt_hid_app/application.fam +++ b/applications/plugins/bt_hid_app/application.fam @@ -1,5 +1,5 @@ App( - appid="bt_hid", + appid="Bluetooth_Remote", name="Bluetooth Remote", apptype=FlipperAppType.PLUGIN, entry_point="bt_hid_app", diff --git a/applications/plugins/doom/application.fam b/applications/plugins/doom/application.fam index a032e14eb..d9ae4d67d 100644 --- a/applications/plugins/doom/application.fam +++ b/applications/plugins/doom/application.fam @@ -1,5 +1,5 @@ App( - appid="game_doom", + appid="DOOM", name="DOOM", apptype=FlipperAppType.EXTERNAL, entry_point="doom_app", diff --git a/applications/plugins/esp8266_deauth/application.fam b/applications/plugins/esp8266_deauth/application.fam index 8342edfba..0b305e1fb 100644 --- a/applications/plugins/esp8266_deauth/application.fam +++ b/applications/plugins/esp8266_deauth/application.fam @@ -1,5 +1,5 @@ App( - appid="esp8266_deauth", + appid="ESP8266_Deauther", name="[ESP8266] Deauther", apptype=FlipperAppType.EXTERNAL, entry_point="esp8266_deauth_app", diff --git a/applications/plugins/flappy_bird/application.fam b/applications/plugins/flappy_bird/application.fam index daee5791d..dd8c67e85 100644 --- a/applications/plugins/flappy_bird/application.fam +++ b/applications/plugins/flappy_bird/application.fam @@ -1,5 +1,5 @@ App( - appid="game_flappybird", + appid="FlappyBird", name="Flappy Bird", apptype=FlipperAppType.EXTERNAL, entry_point="flappy_game_app", diff --git a/applications/plugins/flipfrid/application.fam b/applications/plugins/flipfrid/application.fam index 77cfefbed..4a09f1064 100644 --- a/applications/plugins/flipfrid/application.fam +++ b/applications/plugins/flipfrid/application.fam @@ -1,5 +1,5 @@ App( - appid="flipfrid", + appid="RFID_Fuzzer", name="RFID Fuzzer", apptype=FlipperAppType.EXTERNAL, entry_point="flipfrid_start", diff --git a/applications/plugins/mousejacker/application.fam b/applications/plugins/mousejacker/application.fam index 9c71bf7a3..07ee51ae3 100644 --- a/applications/plugins/mousejacker/application.fam +++ b/applications/plugins/mousejacker/application.fam @@ -1,5 +1,5 @@ App( - appid="mouse_jacker", + appid="NRF24_Mouse_Jacker", name="[NRF24] Mouse Jacker", apptype=FlipperAppType.EXTERNAL, entry_point="mousejacker_app", diff --git a/applications/plugins/multi_converter/application.fam b/applications/plugins/multi_converter/application.fam index 5da46e06b..b19bce895 100644 --- a/applications/plugins/multi_converter/application.fam +++ b/applications/plugins/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/plugins/music_player/application.fam b/applications/plugins/music_player/application.fam index 30f2b9268..cfb50c451 100644 --- a/applications/plugins/music_player/application.fam +++ b/applications/plugins/music_player/application.fam @@ -1,5 +1,5 @@ App( - appid="music_player", + appid="Music_Player", name="Music Player", apptype=FlipperAppType.PLUGIN, entry_point="music_player_app", diff --git a/applications/plugins/nrfsniff/application.fam b/applications/plugins/nrfsniff/application.fam index 269f139a9..5caa945ee 100644 --- a/applications/plugins/nrfsniff/application.fam +++ b/applications/plugins/nrfsniff/application.fam @@ -1,5 +1,5 @@ App( - appid="nrf_sniff", + appid="NRF24_Sniffer", name="[NRF24] Sniffer", apptype=FlipperAppType.EXTERNAL, entry_point="nrfsniff_app", diff --git a/applications/plugins/picopass/application.fam b/applications/plugins/picopass/application.fam index 7a81e0804..888ecc128 100644 --- a/applications/plugins/picopass/application.fam +++ b/applications/plugins/picopass/application.fam @@ -1,5 +1,5 @@ App( - appid="picopass", + appid="Picopass", name="PicoPass Reader", apptype=FlipperAppType.EXTERNAL, entry_point="picopass_app", diff --git a/applications/plugins/playlist/application.fam b/applications/plugins/playlist/application.fam index 991809ae3..8be27aa6c 100644 --- a/applications/plugins/playlist/application.fam +++ b/applications/plugins/playlist/application.fam @@ -1,5 +1,5 @@ App( - appid="sub_playlist", + appid="SubGHz_Playlist", name="Sub-GHz Playlist", apptype=FlipperAppType.EXTERNAL, entry_point="playlist_app", diff --git a/applications/plugins/sentry_safe/application.fam b/applications/plugins/sentry_safe/application.fam index f409e0b06..070a677ba 100644 --- a/applications/plugins/sentry_safe/application.fam +++ b/applications/plugins/sentry_safe/application.fam @@ -1,5 +1,5 @@ App( - appid="sentry_safe", + appid="GPIO_Sentry_Safe", name="[GPIO] Sentry Safe", apptype=FlipperAppType.EXTERNAL, entry_point="sentry_safe_app", diff --git a/applications/plugins/signal_generator/application.fam b/applications/plugins/signal_generator/application.fam index 7794ee492..c2bb097a4 100644 --- a/applications/plugins/signal_generator/application.fam +++ b/applications/plugins/signal_generator/application.fam @@ -1,5 +1,5 @@ App( - appid="signal_generator", + appid="Signal_Generator", name="Signal Generator", apptype=FlipperAppType.PLUGIN, entry_point="signal_gen_app", diff --git a/applications/plugins/snake_game/application.fam b/applications/plugins/snake_game/application.fam index d55f53bb1..abf4f72c5 100644 --- a/applications/plugins/snake_game/application.fam +++ b/applications/plugins/snake_game/application.fam @@ -1,5 +1,5 @@ App( - appid="snake_game", + appid="Snake", name="Snake Game", apptype=FlipperAppType.PLUGIN, entry_point="snake_game_app", diff --git a/applications/plugins/spectrum_analyzer/application.fam b/applications/plugins/spectrum_analyzer/application.fam index 5028c999b..04bb946ee 100644 --- a/applications/plugins/spectrum_analyzer/application.fam +++ b/applications/plugins/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/plugins/subbrute/application.fam b/applications/plugins/subbrute/application.fam index 1afdc539f..5e9dd9c8d 100644 --- a/applications/plugins/subbrute/application.fam +++ b/applications/plugins/subbrute/application.fam @@ -1,5 +1,5 @@ App( - appid="subbrute", + appid="SubGHz_Bruteforcer", name="Sub-GHz Bruteforcer", apptype=FlipperAppType.EXTERNAL, entry_point="subbrute_app", diff --git a/applications/plugins/tetris_game/application.fam b/applications/plugins/tetris_game/application.fam index 9a298a3d5..69dda3297 100644 --- a/applications/plugins/tetris_game/application.fam +++ b/applications/plugins/tetris_game/application.fam @@ -1,5 +1,5 @@ App( - appid="tetris_game", + appid="Tetris", name="Tetris", apptype=FlipperAppType.EXTERNAL, entry_point="tetris_game_app", diff --git a/applications/plugins/tictactoe_game/application.fam b/applications/plugins/tictactoe_game/application.fam index 289f4f88d..2e769417e 100644 --- a/applications/plugins/tictactoe_game/application.fam +++ b/applications/plugins/tictactoe_game/application.fam @@ -1,5 +1,5 @@ App( - appid="tictactoe_game", + appid="TicTacToe", name="Tic Tac Toe", apptype=FlipperAppType.EXTERNAL, entry_point="tictactoe_game_app", diff --git a/applications/plugins/wav_player/application.fam b/applications/plugins/wav_player/application.fam index 4e8d81ab2..394e45d29 100644 --- a/applications/plugins/wav_player/application.fam +++ b/applications/plugins/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/plugins/wifi_marauder_companion/application.fam b/applications/plugins/wifi_marauder_companion/application.fam index 0548905d9..e3185d50a 100644 --- a/applications/plugins/wifi_marauder_companion/application.fam +++ b/applications/plugins/wifi_marauder_companion/application.fam @@ -1,5 +1,5 @@ App( - appid="wifi_marauder", + appid="ESP32_WiFi_Marauder", name="[ESP32] WiFi Marauder", apptype=FlipperAppType.EXTERNAL, entry_point="wifi_marauder_app", diff --git a/applications/plugins/wifi_scanner/application.fam b/applications/plugins/wifi_scanner/application.fam index 22ca79673..dc229efc0 100644 --- a/applications/plugins/wifi_scanner/application.fam +++ b/applications/plugins/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/plugins/zombiez/application.fam b/applications/plugins/zombiez/application.fam index 14cad08ce..3245187d2 100644 --- a/applications/plugins/zombiez/application.fam +++ b/applications/plugins/zombiez/application.fam @@ -1,5 +1,5 @@ App( - appid="game_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 dc9ac04d0..c66ada158 100644 --- a/applications/services/desktop/scenes/desktop_scene_main.c +++ b/applications/services/desktop/scenes/desktop_scene_main.c @@ -165,8 +165,8 @@ bool desktop_scene_main_on_event(void* context, SceneManagerEvent event) { break; } case DesktopMainEventOpenGameMenu: { - LoaderStatus status = loader_start( - desktop->loader, "Applications", EXT_PATH("/apps/Games/snake_game.fap")); + LoaderStatus status = + loader_start(desktop->loader, "Applications", EXT_PATH("/apps/Games/Snake.fap")); if(status != LoaderStatusOk) { FURI_LOG_E(TAG, "loader_start failed: %d", status); } From 972c0dcb4a0c18a81e44c72e4f53c41f0159712b Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Thu, 29 Sep 2022 08:20:30 +0300 Subject: [PATCH 44/47] hide layouts folder in badusb app --- applications/main/bad_usb/scenes/bad_usb_scene_file_select.c | 1 + applications/services/gui/modules/file_browser_worker.c | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/applications/main/bad_usb/scenes/bad_usb_scene_file_select.c b/applications/main/bad_usb/scenes/bad_usb_scene_file_select.c index 9eb225fd1..53e5ecc7b 100644 --- a/applications/main/bad_usb/scenes/bad_usb_scene_file_select.c +++ b/applications/main/bad_usb/scenes/bad_usb_scene_file_select.c @@ -8,6 +8,7 @@ static bool bad_usb_file_select(BadUsbApp* bad_usb) { DialogsFileBrowserOptions browser_options; dialog_file_browser_set_basic_options( &browser_options, BAD_USB_APP_SCRIPT_EXTENSION, &I_badusb_10px); + browser_options.skip_assets = true; // Input events and views are managed by file_browser bool res = dialog_file_browser_show( diff --git a/applications/services/gui/modules/file_browser_worker.c b/applications/services/gui/modules/file_browser_worker.c index 36df6cc83..a316a0779 100644 --- a/applications/services/gui/modules/file_browser_worker.c +++ b/applications/services/gui/modules/file_browser_worker.c @@ -13,6 +13,7 @@ #define TAG "BrowserWorker" #define ASSETS_DIR "assets" +#define BADUSB_LAYOUTS_DIR "layouts" #define BROWSER_ROOT STORAGE_ANY_PATH_PREFIX #define FILE_NAME_LEN_MAX 256 #define LONG_LOAD_THRESHOLD 100 @@ -78,7 +79,8 @@ static bool browser_filter_by_name(BrowserWorker* browser, string_t name, bool i if(is_folder) { // Skip assets folders (if enabled) if(browser->skip_assets) { - return ((string_cmp_str(name, ASSETS_DIR) == 0) ? (false) : (true)); + return ((string_cmp_str(name, ASSETS_DIR) == 0) ? (false) : (true)) && + ((string_cmp_str(name, BADUSB_LAYOUTS_DIR) == 0) ? (false) : (true)); } else { return true; } From 9176387b9f7e2a8b0e7e6987ab58dd7b768fb76a Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Thu, 29 Sep 2022 09:14:47 +0300 Subject: [PATCH 45/47] update assets and changelog --- CHANGELOG.md | 19 +++++------ assets/resources/infrared/assets/ac.ir | 44 +++++++++++++++++++++++++- assets/resources/infrared/assets/tv.ir | 26 ++++++++++++++- 3 files changed, 78 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 00640615d..a0dd50a35 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,17 +1,18 @@ ### New changes -* PR: SubGHz new feature -> press Ok in Frequency analyzer to use frequency in Read modes (by @derskythe | PR #77) -* PR: SubGHz save last settings (frequency and modulation) (by @derskythe | PR #77) -* Plugins: SubGHz Bruteforcer - add chamberlain 9bit 300mhz, removed unnecessary checks (made it a bit faster), fixed title position & menu text -* SubGHz: Fix Add Manually item names, Add BETT protocol in add manually +* Hide layouts folder in badusb app +* SubGHz: Added 868.8 mhz into user config for sommer systems +* Renamed apps to make it look a bit better in Apps tab in archive app * Infrared: Update assets (by @Amec0e) -* OFW: Refactor infrared brute force code -* OFW: Add formatting to DESfire data dump +* OFW: Keyboard: show Uppercase keys when replacing content +* OFW: Furi Thread: don't use thread pointer after FuriThreadStateStopped callback +* OFW: Resources cleanup in updater +* OFW: Signal Generator app -#### **DFU files no longer included in releases to avoid issues with wrong manual installation of assets - use .tgz file with qFlipper, or install automatically via web updater or use microSD update package** +#### [🎲 Download extra apps pack](https://download-directory.github.io/?url=https://github.com/UberGuidoZ/Flipper/tree/main/Applications/Unleashed) -[- How to install](https://github.com/Eng1n33r/flipperzero-firmware/blob/dev/documentation/HowToInstall.md) +[-> How to install firmware](https://github.com/Eng1n33r/flipperzero-firmware/blob/dev/documentation/HowToInstall.md) -[- Download qFlipper 1.2.0 (allows .tgz installation) (official link)](https://update.flipperzero.one/builds/qFlipper/1.2.0/) +[-> Download qFlipper 1.2.0 (allows .tgz installation) (official link)](https://update.flipperzero.one/builds/qFlipper/1.2.0/) **Note: To avoid issues with .dfu, prefer installing using .tgz with qFlipper, web updater or by self update package, all needed assets will be installed** diff --git a/assets/resources/infrared/assets/ac.ir b/assets/resources/infrared/assets/ac.ir index 8f219bb14..54384cf40 100644 --- a/assets/resources/infrared/assets/ac.ir +++ b/assets/resources/infrared/assets/ac.ir @@ -1,7 +1,25 @@ Filetype: IR library file Version: 1 -# Last Updated 20th Sept, 2022 +# Last Updated 28th Sept, 2022 # +# SWING ON +name: SWING +type: raw +frequency: 38000 +duty_cycle: 0.330000 +data: 3158 1552 601 1065 575 1093 596 328 560 330 555 329 556 1068 573 338 545 341 544 1095 571 1096 571 341 543 1101 566 342 543 342 542 1125 543 1125 542 343 542 1124 542 1125 542 344 542 343 542 1126 542 344 541 345 541 1124 542 344 542 345 541 344 541 345 540 345 541 343 541 345 540 345 541 345 541 345 541 345 541 345 541 343 541 345 541 345 541 344 542 344 541 1127 541 345 541 344 542 1126 541 345 541 345 541 1126 541 1127 541 345 541 343 541 345 541 345 541 345 541 344 541 1127 541 346 541 1127 540 1127 541 345 541 344 541 345 541 346 540 1127 541 1127 540 344 541 1128 541 1126 541 1127 541 345 541 345 541 344 540 345 541 345 541 345 541 345 541 345 541 344 541 345 541 345 541 345 541 345 541 345 541 345 541 344 541 345 541 345 541 345 541 345 541 345 541 345 541 344 541 345 541 345 541 345 541 345 541 345 541 345 541 344 541 345 541 345 541 345 541 345 541 345 541 345 540 1127 541 345 541 345 541 344 541 346 541 1127 542 +# ON +name: POWER +type: raw +frequency: 38000 +duty_cycle: 0.330000 +data: 3126 1586 542 1123 544 1124 543 346 540 344 542 344 541 1124 543 345 541 343 541 1124 543 1125 542 346 540 1124 542 346 540 346 516 1149 518 1150 517 369 516 1151 517 1148 518 369 517 370 516 1148 518 369 516 369 541 1125 543 342 542 344 542 345 541 346 540 371 515 371 515 371 514 370 514 371 515 371 515 371 515 371 515 371 515 370 515 371 514 371 515 372 515 1151 515 371 515 372 515 1151 515 372 514 372 515 1153 514 1153 515 371 515 372 514 370 514 372 514 372 514 372 514 1153 514 1153 514 1131 538 1127 539 347 539 346 540 346 540 345 540 1128 540 347 540 1126 540 346 540 345 541 345 541 345 541 345 541 345 541 343 541 345 541 345 541 345 541 345 541 345 541 344 541 343 541 344 542 344 542 345 541 345 541 344 542 343 541 344 542 345 541 344 542 345 541 345 541 345 541 344 540 345 541 345 541 345 541 345 541 345 541 345 541 343 541 345 541 345 541 345 541 345 541 345 541 345 541 344 541 1127 541 344 541 1127 541 345 541 +# ON +name: POWER +type: raw +frequency: 38000 +duty_cycle: 0.330000 +data: 3034 3976 1907 1980 1914 2004 1880 1006 941 1032 915 999 937 1008 939 1982 933 1008 1907 2008 939 978 1916 998 970 980 936 976 971 1034 913 1000 936 1984 942 997 1939 975 941 1003 944 1004 943 999 937 1037 941 971 965 984 942 999 969 1919 975 1025 3890 3957 1936 1982 1912 1940 1944 1038 909 1033 914 996 940 1009 938 1948 967 1009 1917 1970 945 994 1942 979 937 1034 913 1003 944 1000 936 1012 935 1981 934 1008 1907 1036 932 982 944 1036 911 1027 910 1004 964 984 942 1033 914 999 937 1976 939 1008 3917 3982 1932 1922 1941 1945 1970 981 945 997 940 1008 939 1004 943 1979 936 998 1917 1943 972 1002 1913 1032 904 1013 944 1000 936 1041 906 1001 967 1923 972 1003 1912 1030 906 1009 969 975 941 1004 943 1002 945 996 940 975 972 1005 942 1944 971 968 4915 # ON name: POWER type: raw @@ -1232,4 +1250,28 @@ type: parsed protocol: NEC address: 80 00 00 00 command: 92 00 00 00 +# OFF +name: POWER +type: raw +frequency: 38000 +duty_cycle: 0.330000 +data: 3031 3980 1912 1945 1969 1950 1912 973 994 981 965 951 975 1027 909 1950 975 965 971 974 1941 1006 940 977 969 1003 964 951 975 1000 936 1006 940 973 973 1974 941 973 1942 1006 941 974 993 950 975 999 937 1036 910 975 992 952 974 998 938 1950 975 967 3947 3987 1916 2002 1881 1975 1939 947 999 943 972 971 996 948 967 1949 997 949 976 997 1907 980 966 1006 941 975 971 1001 945 999 968 945 970 976 970 1974 972 942 1942 975 992 952 994 949 977 970 997 948 967 979 967 1005 942 999 968 1923 971 1000 3914 3958 1965 1919 1995 1893 1969 984 962 954 972 996 971 973 942 1949 976 992 965 947 1947 1002 965 950 976 1001 945 997 939 1007 939 1006 940 998 969 1915 1000 944 2002 946 969 944 992 956 1001 943 972 1000 967 949 966 977 969 1001 966 1926 968 1003 4889 +# OFF +name: POWER +type: raw +frequency: 38000 +duty_cycle: 0.330000 +data: 3160 1550 576 1092 576 1091 577 329 555 338 573 329 558 1065 601 329 557 329 556 1065 601 1066 575 338 547 1093 574 339 546 339 546 1095 573 1095 572 339 546 1096 572 1097 571 341 544 341 544 1124 544 342 543 342 543 1125 542 344 542 344 541 344 542 344 542 343 541 344 542 344 542 344 542 344 542 344 542 344 542 343 541 344 542 344 542 344 542 344 542 344 542 344 542 343 541 345 542 1126 542 343 541 345 541 1126 542 1126 542 344 542 344 542 344 542 343 541 344 542 345 541 1126 541 1126 541 1127 542 1127 541 343 542 345 541 344 542 345 542 1125 541 345 542 1127 541 343 542 345 541 345 541 345 541 345 541 345 541 345 541 343 541 345 541 345 541 345 541 345 541 345 541 345 541 344 541 345 541 345 541 345 541 345 541 345 541 345 541 344 540 345 541 345 541 345 541 345 541 345 541 344 541 345 541 345 541 345 541 346 540 345 541 344 540 345 541 346 540 345 541 345 541 345 540 1128 541 1126 541 345 541 346 541 1126 541 345 541 +# SWING OFF +name: SWING +type: raw +frequency: 38000 +duty_cycle: 0.330000 +data: 3186 1522 603 1065 602 1063 603 330 554 330 556 330 551 1068 600 330 529 340 546 1093 573 1094 573 340 545 1095 573 340 545 340 545 1097 570 1098 569 343 543 1123 544 1125 542 343 542 343 542 1126 542 344 542 343 542 1126 541 344 542 345 541 345 541 343 541 344 541 345 541 344 541 345 541 345 541 345 541 343 541 345 541 345 541 345 541 344 541 345 541 344 541 1126 541 345 541 344 541 1126 541 345 541 344 541 1127 541 1125 541 345 541 345 541 345 541 345 541 345 541 344 541 1128 540 345 540 1128 541 1126 541 345 541 346 540 346 540 345 540 1129 540 1128 540 344 541 346 540 346 540 346 540 346 540 345 541 346 540 344 540 346 540 346 539 346 540 346 540 346 540 346 539 344 540 346 540 346 540 346 540 346 540 346 540 345 539 346 540 346 540 346 540 346 540 346 539 346 540 345 540 346 540 346 540 347 539 346 540 346 540 346 540 345 539 346 540 346 540 346 540 346 540 346 539 1129 540 1127 539 347 539 347 540 1127 539 346 540 +# +name: MODE +type: raw +frequency: 38000 +duty_cycle: 0.330000 +data: 3157 1552 601 1065 575 1093 598 330 554 330 530 340 545 1094 573 338 545 341 545 1094 572 1095 572 340 544 1097 570 342 543 341 543 1101 567 1123 543 342 542 1124 543 1124 543 344 542 342 542 1125 542 344 542 345 541 1125 541 344 542 344 542 344 542 344 542 344 542 343 541 344 541 345 541 344 542 344 542 344 541 345 541 343 541 344 542 344 541 344 542 344 541 1126 542 344 542 344 541 1126 542 344 542 345 541 1126 541 1126 541 345 541 343 541 345 541 345 541 344 542 344 541 1127 541 1126 541 1125 541 1127 541 345 541 344 541 344 541 344 541 1126 541 344 541 1126 542 344 541 344 541 344 541 344 542 344 542 343 541 345 541 345 541 344 542 344 542 345 540 343 541 344 541 344 541 344 542 344 541 344 541 344 542 343 541 344 542 344 541 345 541 345 541 344 542 344 541 343 541 344 542 344 542 344 542 344 542 344 542 344 542 343 541 344 542 344 542 345 541 344 542 345 541 345 541 343 542 345 542 1127 541 344 541 1126 542 344 542 # diff --git a/assets/resources/infrared/assets/tv.ir b/assets/resources/infrared/assets/tv.ir index 4a60dfdb4..4ea018d39 100755 --- a/assets/resources/infrared/assets/tv.ir +++ b/assets/resources/infrared/assets/tv.ir @@ -1,6 +1,30 @@ Filetype: IR library file Version: 1 -# Last Updated 25th Sept, 2022 +# Last Updated 28th Sept, 2022 +# +name: POWER +type: raw +frequency: 38000 +duty_cycle: 0.330000 +data: 3557 1672 516 388 488 1237 515 389 487 389 487 389 487 389 486 389 487 388 487 365 512 386 490 386 489 386 489 387 488 1263 488 389 485 391 483 392 483 394 481 397 479 398 478 421 455 398 478 421 455 1297 455 421 455 421 455 421 455 421 455 421 455 421 455 421 455 421 455 1298 454 421 455 1298 454 1298 454 1298 454 1298 454 421 455 422 454 1298 454 422 454 1298 454 1299 453 1299 453 1298 454 422 454 1298 454 74664 3522 1735 454 422 454 1299 453 422 454 422 454 422 454 422 454 422 454 422 454 422 454 422 454 422 454 422 454 422 454 1299 453 422 454 422 454 422 454 422 454 422 454 422 454 422 454 422 454 422 454 1299 453 422 454 422 454 423 453 423 453 423 453 422 454 423 453 423 453 1299 453 423 453 1299 453 1299 453 1300 452 1299 453 423 453 423 453 1300 452 423 453 1300 452 1300 452 1300 452 1300 452 423 453 1300 452 74665 3522 1735 453 422 454 1299 453 422 454 422 454 422 454 422 454 422 454 422 453 422 454 422 454 422 454 422 454 422 454 1299 453 422 454 422 454 422 454 422 454 422 454 422 454 422 454 422 454 423 453 1299 453 423 453 422 454 422 454 422 454 422 454 423 453 423 453 423 453 1299 453 423 453 1299 453 1299 453 1299 453 1299 453 423 453 423 453 1299 453 423 453 1299 453 1299 453 1299 453 1300 452 423 453 1299 453 74662 3527 1705 482 394 482 1270 482 394 482 393 483 394 482 393 483 393 483 393 483 393 483 393 483 394 482 393 483 394 482 1294 458 418 458 417 459 417 459 418 458 418 458 418 458 418 458 418 458 418 458 1295 457 419 456 419 457 419 457 419 457 419 457 419 457 419 457 419 457 1296 456 419 457 1296 456 1297 455 1297 455 1299 453 446 430 446 430 1323 429 446 430 1323 429 1323 429 1323 429 1323 429 446 430 1323 429 +# +name: VOL+ +type: raw +frequency: 38000 +duty_cycle: 0.330000 +data: 3542 1717 467 411 465 1285 467 411 493 383 493 382 494 381 466 409 467 408 493 383 493 383 492 384 491 387 488 413 462 1290 461 416 459 416 460 416 460 417 459 417 459 416 460 417 459 417 459 417 459 1293 459 417 459 417 459 417 459 417 458 417 459 417 459 417 459 417 458 417 459 417 459 417 459 417 459 417 459 1293 459 417 459 417 459 417 459 417 459 417 459 417 459 417 459 1294 458 417 459 1294 458 74496 3534 1725 460 416 460 1293 459 416 460 417 459 417 459 416 460 416 460 416 460 416 460 416 460 416 460 416 459 417 459 1293 459 416 460 417 459 417 459 417 459 416 460 417 459 417 459 416 460 417 459 1293 459 416 460 417 459 416 460 417 459 417 459 416 460 416 460 417 459 417 459 417 459 417 459 417 459 416 460 1293 459 417 459 417 459 417 459 417 459 417 459 417 459 417 459 1293 459 417 459 1293 459 74497 3534 1725 459 416 460 1293 459 416 460 417 459 417 459 416 460 417 459 417 459 416 460 417 459 417 459 417 459 417 459 1293 459 417 459 417 459 417 459 417 459 417 459 417 458 417 459 417 459 417 459 1294 458 417 459 417 459 417 459 417 459 417 459 417 459 417 459 417 459 417 459 418 458 418 458 417 459 418 458 1294 458 417 459 418 458 418 458 418 458 418 458 418 458 418 458 1294 458 418 458 1294 458 +# +name: VOL- +type: raw +frequency: 38000 +duty_cycle: 0.330000 +data: 3540 1691 494 383 465 1284 468 409 492 383 493 383 492 384 491 386 488 388 486 414 461 415 460 416 460 416 460 416 460 1293 459 416 460 416 460 416 460 416 460 416 460 416 460 417 459 417 459 417 459 1293 459 417 459 417 459 417 459 417 459 417 459 417 459 417 459 417 459 1293 459 416 460 417 459 417 459 416 459 1294 458 417 459 417 458 1294 458 417 459 417 459 417 459 417 459 1294 458 417 459 1294 458 74801 3534 1725 459 416 460 1293 459 416 460 416 460 416 460 417 459 417 459 417 459 417 459 417 459 417 459 417 459 417 459 1293 459 417 459 417 459 417 459 417 459 417 459 417 459 417 459 417 459 417 459 1294 458 417 459 417 459 417 459 417 459 417 459 417 459 417 459 417 459 1294 458 417 459 417 459 418 458 418 458 1294 458 418 458 418 458 1294 458 418 458 418 458 418 458 418 458 1294 458 418 458 1294 458 +# +name: MUTE +type: raw +frequency: 38000 +duty_cycle: 0.330000 +data: 3512 1685 500 409 467 1256 496 409 467 409 466 410 466 410 466 409 467 410 466 410 466 410 495 381 495 380 522 353 493 1256 469 407 494 381 495 382 493 383 492 384 491 386 489 413 462 414 461 415 460 1291 461 415 461 415 461 415 461 415 461 415 461 415 461 415 461 415 461 415 461 1292 460 415 461 415 461 1292 460 1292 460 415 461 415 461 415 461 1292 460 416 460 415 461 1292 460 1292 460 415 461 1292 460 74573 3531 1726 460 416 460 1292 460 416 460 416 460 416 460 392 484 415 460 416 460 416 460 393 483 393 483 392 484 393 483 1268 484 392 484 392 484 392 484 392 484 392 484 392 484 392 484 392 484 392 484 1268 484 392 484 392 484 392 484 392 484 392 484 392 484 392 484 392 484 392 484 1268 484 392 484 391 485 1268 484 1268 484 392 484 392 484 392 484 1292 460 392 484 392 484 1269 483 1269 483 392 484 1292 460 # name: POWER type: raw From 7df70d7c62f6cbb91a0c695171fe5efc0c7bda6a Mon Sep 17 00:00:00 2001 From: Sergey Gavrilov Date: Thu, 29 Sep 2022 03:37:07 +1000 Subject: [PATCH 46/47] Revert "Furi Thread: don't use thread pointer after FuriThreadStateStopped callback (#1799)" This reverts commit 5883e134d4c870a2b08f705eb48a2e56f8a24a23. --- furi/core/thread.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/furi/core/thread.c b/furi/core/thread.c index 538ae4d87..58cb9bc09 100644 --- a/furi/core/thread.c +++ b/furi/core/thread.c @@ -85,6 +85,7 @@ static void furi_thread_body(void* context) { } furi_assert(thread->state == FuriThreadStateRunning); + furi_thread_set_state(thread, FuriThreadStateStopped); if(thread->is_service) { FURI_LOG_E( @@ -98,10 +99,7 @@ static void furi_thread_body(void* context) { furi_assert(pvTaskGetThreadLocalStoragePointer(NULL, 0) != NULL); vTaskSetThreadLocalStoragePointer(NULL, 0, NULL); - // from here we can't use thread pointer - furi_thread_set_state(thread, FuriThreadStateStopped); - - vTaskDelete(NULL); + vTaskDelete(thread->task_handle); furi_thread_catch(); } @@ -207,9 +205,7 @@ void furi_thread_start(FuriThread* thread) { bool furi_thread_join(FuriThread* thread) { furi_assert(thread); - furi_check(furi_thread_get_current() != thread); - - while(eTaskGetState(thread->task_handle) != eDeleted) { + while(thread->state != FuriThreadStateStopped) { furi_delay_ms(10); } From 226f8517f38764eff2e5d28798dda85958b7246e Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Thu, 29 Sep 2022 11:01:15 +0300 Subject: [PATCH 47/47] update readme and changelog --- CHANGELOG.md | 2 +- ReadMe.md | 17 +++++++++++------ 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a0dd50a35..0d6ac87aa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ * Renamed apps to make it look a bit better in Apps tab in archive app * Infrared: Update assets (by @Amec0e) * OFW: Keyboard: show Uppercase keys when replacing content -* OFW: Furi Thread: don't use thread pointer after FuriThreadStateStopped callback +* OFW: (Temporarily excluded due to crashes) Furi Thread: don't use thread pointer after FuriThreadStateStopped callback * OFW: Resources cleanup in updater * OFW: Signal Generator app diff --git a/ReadMe.md b/ReadMe.md index fbc97304f..df6dcf257 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -36,9 +36,11 @@ Our Discord Community: * Universal remote for Projectors, Fans, A/Cs and Audio(soundbars, etc.) * BadUSB keyboard layouts * Customizable Flipper name +* SubGHz -> Press OK in frequency analyzer to use detected frequency in Read modes * Other small fixes and changes throughout +* See other changes in changelog and in readme below -See changelog in releases for latest updates! +Also check changelog in releases for latest updates! ### Current modified and new SubGHz protocols list: - HCS101 @@ -59,8 +61,8 @@ See changelog in releases for latest updates! ### Community apps included: -- RFID Fuzzer plugin [(by Ganapati)](https://github.com/Eng1n33r/flipperzero-firmware/pull/54) with some changes by xMasterX -- Sub-GHz bruteforce plugin [(by Ganapati & xMasterX)](https://github.com/Eng1n33r/flipperzero-firmware/pull/57) +- RFID Fuzzer plugin [(by Ganapati)](https://github.com/Eng1n33r/flipperzero-firmware/pull/54) with changes by @xMasterX & New protocols by @mvanzanten +- Sub-GHz bruteforce plugin [(by Ganapati & xMasterX)](https://github.com/Eng1n33r/flipperzero-firmware/pull/57) & Refactored by @derskythe - Sub-GHz playlist plugin [(by darmiel)](https://github.com/Eng1n33r/flipperzero-firmware/pull/62) - ESP8266 Deauther plugin [(by SequoiaSan)](https://github.com/SequoiaSan/FlipperZero-Wifi-ESP8266-Deauther-Module) - WiFi Scanner plugin [(by SequoiaSan)](https://github.com/SequoiaSan/FlipperZero-WiFi-Scanner_Module) @@ -85,8 +87,10 @@ Games: ### Other changes - BadUSB -> Keyboard layouts [(by rien > dummy-decoy)](https://github.com/dummy-decoy/flipperzero-firmware/tree/dummy_decoy/bad_usb_keyboard_layout) -- SubGHz -> New frequency analyzer - [(by ClusterM)](https://github.com/ClusterM) +- SubGHz -> New frequency analyzer - [(by ClusterM)](https://github.com/Eng1n33r/flipperzero-firmware/pull/43) - SubGHz -> Detect RAW feature - [(by perspecdev)](https://github.com/RogueMaster/flipperzero-firmware-wPlugins/pull/152) +- SubGHz -> Save last used frequency and moduluation [(by derskythe)](https://github.com/Eng1n33r/flipperzero-firmware/pull/77) +- SubGHz -> Press OK in frequency analyzer to use detected frequency in Read modes [(by derskythe)](https://github.com/Eng1n33r/flipperzero-firmware/pull/77) # Instructions ## [- How to install firmware](https://github.com/Eng1n33r/flipperzero-firmware/blob/dev/documentation/HowToInstall.md) @@ -99,7 +103,7 @@ Games: ### **Plugins** -## [- 💎 Extra plugins precompiled for Unleashed](https://github.com/UberGuidoZ/Flipper/tree/main/Applications/Unleashed) +## [- 🎲 Download Extra plugins for Unleashed](https://github.com/UberGuidoZ/Flipper/tree/main/Applications/Unleashed) ## [- Configure Sub-GHz Remote App](https://github.com/Eng1n33r/flipperzero-firmware/blob/dev/documentation/SubGHzRemotePlugin.md) @@ -139,9 +143,10 @@ Games:
# Where I can find IR, SubGhz, ... files, DBs, and other stuff? -## [Awesome Flipper Zero - Github](https://github.com/djsime1/awesome-flipperzero) ## [UberGuidoZ Playground - Large collection of files - Github](https://github.com/UberGuidoZ/Flipper) +## [Awesome Flipper Zero - Github](https://github.com/djsime1/awesome-flipperzero) ## [CAME-12bit, NICE-12bit, Linear-10bit, PT-2240 - SubGHz fixed code bruteforce](https://github.com/tobiabocchi/flipperzero-bruteforce) +## [SMC5326, UNILARM - SubGHz fixed code bruteforce](https://github.com/Hong5489/flipperzero-gate-bruteforce)