From 7d022c6fda24ef10a5606c00c73b82297b2af8b5 Mon Sep 17 00:00:00 2001 From: Skorpionm <85568270+Skorpionm@users.noreply.github.com> Date: Sat, 9 Apr 2022 22:47:14 +0400 Subject: [PATCH 01/20] [FL-2439] SubGhz: fix magic numbers and description in crash (#1103) * [FL-2439] SubGhz: fix magic numbers and description on crash --- .../subghz/scenes/subghz_scene_read_raw.c | 2 +- applications/subghz/subghz_i.c | 46 +++++++++---------- applications/subghz/subghz_i.h | 8 ++++ .../targets/f7/furi_hal/furi_hal_subghz.c | 6 +-- 4 files changed, 34 insertions(+), 28 deletions(-) diff --git a/applications/subghz/scenes/subghz_scene_read_raw.c b/applications/subghz/scenes/subghz_scene_read_raw.c index d50d5626fca..e63014f7136 100644 --- a/applications/subghz/scenes/subghz_scene_read_raw.c +++ b/applications/subghz/scenes/subghz_scene_read_raw.c @@ -181,7 +181,7 @@ bool subghz_scene_read_raw_on_event(void* context, SceneManagerEvent event) { scene_manager_next_scene(subghz->scene_manager, SubGhzSceneMoreRAW); return true; } else { - furi_crash(NULL); + furi_crash("SugGhz: RAW file name update error."); } break; diff --git a/applications/subghz/subghz_i.c b/applications/subghz/subghz_i.c index 80d7a52c146..ea6fa80e4bc 100644 --- a/applications/subghz/subghz_i.c +++ b/applications/subghz/subghz_i.c @@ -52,7 +52,7 @@ void subghz_get_frequency_modulation(SubGhz* subghz, string_t frequency, string_ subghz->txrx->preset == FuriHalSubGhzPreset2FSKDev476Async) { string_set(modulation, "FM"); } else { - furi_crash(NULL); + furi_crash("SugGhz: Modulation is incorrect."); } } } @@ -69,7 +69,7 @@ void subghz_begin(SubGhz* subghz, FuriHalSubGhzPreset preset) { uint32_t subghz_rx(SubGhz* subghz, uint32_t frequency) { furi_assert(subghz); if(!furi_hal_subghz_is_frequency_valid(frequency)) { - furi_crash(NULL); + furi_crash("SugGhz: Incorrect RX frequency."); } furi_assert( subghz->txrx->txrx_state != SubGhzTxRxStateRx && @@ -90,7 +90,7 @@ uint32_t subghz_rx(SubGhz* subghz, uint32_t frequency) { static bool subghz_tx(SubGhz* subghz, uint32_t frequency) { furi_assert(subghz); if(!furi_hal_subghz_is_frequency_valid(frequency)) { - furi_crash(NULL); + furi_crash("SugGhz: Incorrect TX frequency."); } furi_assert(subghz->txrx->txrx_state != SubGhzTxRxStateSleep); furi_hal_subghz_idle(); @@ -221,8 +221,7 @@ bool subghz_key_load(SubGhz* subghz, const char* file_path) { FlipperFormat* fff_data_file = flipper_format_file_alloc(storage); Stream* fff_data_stream = flipper_format_get_raw_stream(subghz->txrx->fff_data); - uint8_t err = 1; - bool loaded = false; + SubGhzLoadKeyState load_key_state = SubGhzLoadKeyStateParseErr; string_t temp_str; string_init(temp_str); uint32_t temp_data32; @@ -259,7 +258,7 @@ bool subghz_key_load(SubGhz* subghz, const char* file_path) { if(!furi_hal_subghz_is_tx_allowed(temp_data32)) { FURI_LOG_E(TAG, "This frequency can only be used for RX in your region"); - err = 2; + load_key_state = SubGhzLoadKeyStateOnlyRx; break; } subghz->txrx->frequency = temp_data32; @@ -300,30 +299,29 @@ bool subghz_key_load(SubGhz* subghz, const char* file_path) { break; } - loaded = true; + load_key_state = SubGhzLoadKeyStateOK; } while(0); - if(!loaded) { - switch(err) { - case 1: - dialog_message_show_storage_error(subghz->dialogs, "Cannot parse\nfile"); - break; - - case 2: - subghz_dialog_message_show_only_rx(subghz); - break; - - default: - furi_crash(NULL); - break; - } - } - string_clear(temp_str); flipper_format_free(fff_data_file); furi_record_close("storage"); - return loaded; + switch(load_key_state) { + case SubGhzLoadKeyStateParseErr: + dialog_message_show_storage_error(subghz->dialogs, "Cannot parse\nfile"); + return false; + + case SubGhzLoadKeyStateOnlyRx: + subghz_dialog_message_show_only_rx(subghz); + return false; + + case SubGhzLoadKeyStateOK: + return true; + + default: + furi_crash("SubGhz: Unknown load_key_state."); + return false; + } } bool subghz_get_next_name_file(SubGhz* subghz, uint8_t max_len) { diff --git a/applications/subghz/subghz_i.h b/applications/subghz/subghz_i.h index bfa80df30af..b2d7df71a36 100644 --- a/applications/subghz/subghz_i.h +++ b/applications/subghz/subghz_i.h @@ -79,6 +79,14 @@ typedef enum { SubGhzRxKeyStateRAWSave, } SubGhzRxKeyState; +/** SubGhzLoadKeyState state */ +typedef enum { + SubGhzLoadKeyStateUnknown, + SubGhzLoadKeyStateOK, + SubGhzLoadKeyStateParseErr, + SubGhzLoadKeyStateOnlyRx, +} SubGhzLoadKeyState; + struct SubGhzTxRx { SubGhzWorker* worker; diff --git a/firmware/targets/f7/furi_hal/furi_hal_subghz.c b/firmware/targets/f7/furi_hal/furi_hal_subghz.c index b64b2d7f5be..fc7c01ff187 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_subghz.c +++ b/firmware/targets/f7/furi_hal/furi_hal_subghz.c @@ -412,7 +412,7 @@ void furi_hal_subghz_load_preset(FuriHalSubGhzPreset preset) { furi_hal_subghz_load_registers(furi_hal_subghz_preset_gfsk_9_99kb_async_regs); furi_hal_subghz_load_patable(furi_hal_subghz_preset_gfsk_async_patable); } else { - furi_crash(NULL); + furi_crash("SugGhz: Missing config."); } furi_hal_subghz_preset = preset; } @@ -564,7 +564,7 @@ uint32_t furi_hal_subghz_set_frequency_and_path(uint32_t value) { } else if(value >= 778999847 && value <= 928000000) { furi_hal_subghz_set_path(FuriHalSubGhzPath868); } else { - furi_crash(NULL); + furi_crash("SugGhz: Incorrect frequency during set."); } return value; } @@ -650,7 +650,7 @@ void furi_hal_subghz_set_path(FuriHalSubGhzPath path) { furi_hal_gpio_write(&gpio_rf_sw_0, 0); cc1101_write_reg(&furi_hal_spi_bus_handle_subghz, CC1101_IOCFG2, CC1101IocfgHW); } else { - furi_crash(NULL); + furi_crash("SubGhz: Incorrect path during set."); } furi_hal_spi_release(&furi_hal_spi_bus_handle_subghz); } From b22ad77bbe5c922adcc0459db29a1ac68acc92e4 Mon Sep 17 00:00:00 2001 From: Dmitry Pavlov Date: Mon, 11 Apr 2022 14:54:38 +0300 Subject: [PATCH 02/20] [FL-2438] Correct grammar in menus and application names (#1102) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [FL-2403] Changed (Name and save) buttons name * [FL-2403] NFC Reading revert LED color to blue * [FL-2438] Capital_letter_menu_names * [FL-2438] Capital_letter_menu_names * [FL-2438] Rename and unify menu items with capitals * [FL-2438] Capital_letter_menu_and_returned_Empty_folder * [FL-2438] Capital_letter_menu_and_returned_Empty_folder_label * [FL-2438] Capital_letter_menu_and_returned_Empty_folder_label_reformating Co-authored-by: あく --- applications/applications.c | 6 +++--- .../bt_settings_app/scenes/bt_settings_scene_start.c | 2 +- applications/debug_tools/usb_mouse.c | 2 +- applications/gpio/scenes/gpio_scene_start.c | 4 ++-- applications/ibutton/scene/ibutton_scene_start.cpp | 2 +- .../infrared/scene/infrared_app_scene_edit.cpp | 10 +++++----- .../infrared/scene/infrared_app_scene_start.cpp | 6 +++--- applications/lfrfid/scene/lfrfid_app_scene_start.cpp | 2 +- applications/loader/loader.c | 2 +- applications/nfc/scenes/nfc_scene_card_menu.c | 4 ++-- .../nfc/scenes/nfc_scene_mifare_desfire_menu.c | 6 +----- applications/nfc/scenes/nfc_scene_mifare_ul_menu.c | 2 +- applications/nfc/scenes/nfc_scene_saved_menu.c | 2 +- applications/nfc/scenes/nfc_scene_scripts_menu.c | 2 +- applications/nfc/scenes/nfc_scene_start.c | 9 ++++----- applications/notification/notification_settings_app.c | 6 +++--- .../scenes/power_settings_scene_start.c | 2 +- .../scenes/storage_settings_scene_start.c | 2 +- applications/subghz/scenes/subghz_scene_start.c | 2 +- 19 files changed, 34 insertions(+), 39 deletions(-) diff --git a/applications/applications.c b/applications/applications.c index b4df86a909b..24279d82a32 100644 --- a/applications/applications.c +++ b/applications/applications.c @@ -207,7 +207,7 @@ const size_t FLIPPER_ON_SYSTEM_START_COUNT = // Plugin menu const FlipperApplication FLIPPER_PLUGINS[] = { #ifdef APP_BLE_HID - {.app = bt_hid_app, .name = "Bluetooth remote", .stack_size = 1024, .icon = NULL}, + {.app = bt_hid_app, .name = "Bluetooth Remote", .stack_size = 1024, .icon = NULL}, #endif #ifdef APP_MUSIC_PLAYER @@ -244,7 +244,7 @@ const FlipperApplication FLIPPER_DEBUG_APPS[] = { #endif #ifdef APP_USB_MOUSE - {.app = usb_mouse_app, .name = "USB Mouse demo", .stack_size = 1024, .icon = NULL}, + {.app = usb_mouse_app, .name = "USB Mouse Demo", .stack_size = 1024, .icon = NULL}, #endif #ifdef APP_UART_ECHO @@ -295,7 +295,7 @@ const FlipperApplication FLIPPER_SETTINGS_APPS[] = { #ifdef SRV_NOTIFICATION {.app = notification_settings_app, - .name = "LCD and notifications", + .name = "LCD and Notifications", .stack_size = 1024, .icon = NULL}, #endif diff --git a/applications/bt/bt_settings_app/scenes/bt_settings_scene_start.c b/applications/bt/bt_settings_app/scenes/bt_settings_scene_start.c index 9dd0b1e7af4..089038dda63 100755 --- a/applications/bt/bt_settings_app/scenes/bt_settings_scene_start.c +++ b/applications/bt/bt_settings_app/scenes/bt_settings_scene_start.c @@ -54,7 +54,7 @@ void bt_settings_scene_start_on_enter(void* context) { variable_item_set_current_value_index(item, BtSettingOff); variable_item_set_current_value_text(item, bt_settings_text[BtSettingOff]); } - variable_item_list_add(var_item_list, "Forget all paired devices", 1, NULL, NULL); + variable_item_list_add(var_item_list, "Forget All Paired Devices", 1, NULL, NULL); variable_item_list_set_enter_callback( var_item_list, bt_settings_scene_start_var_list_enter_callback, app); } else { diff --git a/applications/debug_tools/usb_mouse.c b/applications/debug_tools/usb_mouse.c index 1468f6c6511..6943e189d5e 100644 --- a/applications/debug_tools/usb_mouse.c +++ b/applications/debug_tools/usb_mouse.c @@ -21,7 +21,7 @@ static void usb_mouse_render_callback(Canvas* canvas, void* ctx) { canvas_clear(canvas); canvas_set_font(canvas, FontPrimary); - canvas_draw_str(canvas, 0, 10, "USB Mouse demo"); + canvas_draw_str(canvas, 0, 10, "USB Mouse Demo"); canvas_set_font(canvas, FontSecondary); canvas_draw_str(canvas, 0, 63, "Hold [back] to exit"); diff --git a/applications/gpio/scenes/gpio_scene_start.c b/applications/gpio/scenes/gpio_scene_start.c index 39aabbd89fc..4257ec39b3f 100644 --- a/applications/gpio/scenes/gpio_scene_start.c +++ b/applications/gpio/scenes/gpio_scene_start.c @@ -49,9 +49,9 @@ void gpio_scene_start_on_enter(void* context) { variable_item_list_set_enter_callback( var_item_list, gpio_scene_start_var_list_enter_callback, app); - variable_item_list_add(var_item_list, "USB-UART bridge", 0, NULL, NULL); + variable_item_list_add(var_item_list, "USB-UART Bridge", 0, NULL, NULL); - variable_item_list_add(var_item_list, "GPIO manual control", 0, NULL, NULL); + variable_item_list_add(var_item_list, "GPIO Manual Control", 0, NULL, NULL); item = variable_item_list_add( var_item_list, diff --git a/applications/ibutton/scene/ibutton_scene_start.cpp b/applications/ibutton/scene/ibutton_scene_start.cpp index 4b877dd200d..f746545958f 100644 --- a/applications/ibutton/scene/ibutton_scene_start.cpp +++ b/applications/ibutton/scene/ibutton_scene_start.cpp @@ -24,7 +24,7 @@ void iButtonSceneStart::on_enter(iButtonApp* app) { submenu_add_item(submenu, "Read", SubmenuIndexRead, submenu_callback, app); submenu_add_item(submenu, "Saved", SubmenuIndexSaved, submenu_callback, app); - submenu_add_item(submenu, "Add manually", SubmenuIndexAdd, submenu_callback, app); + submenu_add_item(submenu, "Add Manually", SubmenuIndexAdd, submenu_callback, app); submenu_set_selected_item(submenu, submenu_item_selected); view_manager->switch_to(iButtonAppViewManager::Type::iButtonAppViewSubmenu); diff --git a/applications/infrared/scene/infrared_app_scene_edit.cpp b/applications/infrared/scene/infrared_app_scene_edit.cpp index 3d9aafe78da..73e9153e94e 100644 --- a/applications/infrared/scene/infrared_app_scene_edit.cpp +++ b/applications/infrared/scene/infrared_app_scene_edit.cpp @@ -23,11 +23,11 @@ void InfraredAppSceneEdit::on_enter(InfraredApp* app) { InfraredAppViewManager* view_manager = app->get_view_manager(); Submenu* submenu = view_manager->get_submenu(); - submenu_add_item(submenu, "Add key", SubmenuIndexAddKey, submenu_callback, app); - submenu_add_item(submenu, "Rename key", SubmenuIndexRenameKey, submenu_callback, app); - submenu_add_item(submenu, "Delete key", SubmenuIndexDeleteKey, submenu_callback, app); - submenu_add_item(submenu, "Rename remote", SubmenuIndexRenameRemote, submenu_callback, app); - submenu_add_item(submenu, "Delete remote", SubmenuIndexDeleteRemote, submenu_callback, app); + submenu_add_item(submenu, "Add Key", SubmenuIndexAddKey, submenu_callback, app); + submenu_add_item(submenu, "Rename Key", SubmenuIndexRenameKey, submenu_callback, app); + submenu_add_item(submenu, "Delete Key", SubmenuIndexDeleteKey, submenu_callback, app); + submenu_add_item(submenu, "Rename Remote", SubmenuIndexRenameRemote, submenu_callback, app); + submenu_add_item(submenu, "Delete Remote", SubmenuIndexDeleteRemote, submenu_callback, app); submenu_set_selected_item(submenu, submenu_item_selected); submenu_item_selected = 0; diff --git a/applications/infrared/scene/infrared_app_scene_start.cpp b/applications/infrared/scene/infrared_app_scene_start.cpp index dd9a2c15620..c42ab9feded 100644 --- a/applications/infrared/scene/infrared_app_scene_start.cpp +++ b/applications/infrared/scene/infrared_app_scene_start.cpp @@ -21,10 +21,10 @@ void InfraredAppSceneStart::on_enter(InfraredApp* app) { Submenu* submenu = view_manager->get_submenu(); submenu_add_item( - submenu, "Universal library", SubmenuIndexUniversalLibrary, submenu_callback, app); + submenu, "Universal Library", SubmenuIndexUniversalLibrary, submenu_callback, app); submenu_add_item( - submenu, "Learn new remote", SubmenuIndexLearnNewRemote, submenu_callback, app); - submenu_add_item(submenu, "Saved remotes", SubmenuIndexSavedRemotes, submenu_callback, app); + submenu, "Learn New Remote", SubmenuIndexLearnNewRemote, submenu_callback, app); + submenu_add_item(submenu, "Saved Remotes", SubmenuIndexSavedRemotes, submenu_callback, app); submenu_set_selected_item(submenu, submenu_item_selected); submenu_item_selected = 0; diff --git a/applications/lfrfid/scene/lfrfid_app_scene_start.cpp b/applications/lfrfid/scene/lfrfid_app_scene_start.cpp index 2d881288377..f5afad5c988 100644 --- a/applications/lfrfid/scene/lfrfid_app_scene_start.cpp +++ b/applications/lfrfid/scene/lfrfid_app_scene_start.cpp @@ -11,7 +11,7 @@ void LfRfidAppSceneStart::on_enter(LfRfidApp* app, bool need_restore) { submenu->add_item("Read", SubmenuRead, submenu_callback, app); submenu->add_item("Saved", SubmenuSaved, submenu_callback, app); - submenu->add_item("Add manually", SubmenuAddManually, submenu_callback, app); + submenu->add_item("Add Manually", SubmenuAddManually, submenu_callback, app); if(need_restore) { submenu->set_selected_item(submenu_item_selected); diff --git a/applications/loader/loader.c b/applications/loader/loader.c index 63eb3634c9d..d35fcf646e7 100644 --- a/applications/loader/loader.c +++ b/applications/loader/loader.c @@ -386,7 +386,7 @@ static void loader_build_menu() { if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)) { menu_add_item( loader_instance->primary_menu, - "Debug tools", + "Debug Tools", &A_Debug_14, i++, loader_submenu_callback, diff --git a/applications/nfc/scenes/nfc_scene_card_menu.c b/applications/nfc/scenes/nfc_scene_card_menu.c index 0eb3e0cf8c6..03497958d8b 100755 --- a/applications/nfc/scenes/nfc_scene_card_menu.c +++ b/applications/nfc/scenes/nfc_scene_card_menu.c @@ -20,7 +20,7 @@ void nfc_scene_card_menu_on_enter(void* context) { if(nfc->dev->dev_data.nfc_data.protocol > NfcDeviceProtocolUnknown) { submenu_add_item( submenu, - "Run compatible app", + "Run Compatible App", SubmenuIndexRunApp, nfc_scene_card_menu_submenu_callback, nfc); @@ -34,7 +34,7 @@ void nfc_scene_card_menu_on_enter(void* context) { submenu_add_item( submenu, "Emulate UID", SubmenuIndexEmulate, nfc_scene_card_menu_submenu_callback, nfc); submenu_add_item( - submenu, "Name and save UID", SubmenuIndexSave, nfc_scene_card_menu_submenu_callback, nfc); + submenu, "Save UID", SubmenuIndexSave, nfc_scene_card_menu_submenu_callback, nfc); submenu_set_selected_item( nfc->submenu, scene_manager_get_scene_state(nfc->scene_manager, NfcSceneCardMenu)); diff --git a/applications/nfc/scenes/nfc_scene_mifare_desfire_menu.c b/applications/nfc/scenes/nfc_scene_mifare_desfire_menu.c index 1741e123d60..9aa68a43053 100644 --- a/applications/nfc/scenes/nfc_scene_mifare_desfire_menu.c +++ b/applications/nfc/scenes/nfc_scene_mifare_desfire_menu.c @@ -15,11 +15,7 @@ void nfc_scene_mifare_desfire_menu_on_enter(void* context) { Submenu* submenu = nfc->submenu; submenu_add_item( - submenu, - "Name and save", - SubmenuIndexSave, - nfc_scene_mifare_desfire_menu_submenu_callback, - nfc); + submenu, "Save", SubmenuIndexSave, nfc_scene_mifare_desfire_menu_submenu_callback, nfc); submenu_set_selected_item( nfc->submenu, scene_manager_get_scene_state(nfc->scene_manager, NfcSceneMifareDesfireMenu)); diff --git a/applications/nfc/scenes/nfc_scene_mifare_ul_menu.c b/applications/nfc/scenes/nfc_scene_mifare_ul_menu.c index f8b4f2f198b..0e2aaf99709 100755 --- a/applications/nfc/scenes/nfc_scene_mifare_ul_menu.c +++ b/applications/nfc/scenes/nfc_scene_mifare_ul_menu.c @@ -16,7 +16,7 @@ void nfc_scene_mifare_ul_menu_on_enter(void* context) { Submenu* submenu = nfc->submenu; submenu_add_item( - submenu, "Name and save", SubmenuIndexSave, nfc_scene_mifare_ul_menu_submenu_callback, nfc); + submenu, "Save", SubmenuIndexSave, nfc_scene_mifare_ul_menu_submenu_callback, nfc); submenu_add_item( submenu, "Emulate", SubmenuIndexEmulate, nfc_scene_mifare_ul_menu_submenu_callback, nfc); submenu_set_selected_item( diff --git a/applications/nfc/scenes/nfc_scene_saved_menu.c b/applications/nfc/scenes/nfc_scene_saved_menu.c index 201132c1b86..14eb4ca262a 100644 --- a/applications/nfc/scenes/nfc_scene_saved_menu.c +++ b/applications/nfc/scenes/nfc_scene_saved_menu.c @@ -36,7 +36,7 @@ void nfc_scene_saved_menu_on_enter(void* context) { nfc); } submenu_add_item( - submenu, "Edit UID and name", SubmenuIndexEdit, nfc_scene_saved_menu_submenu_callback, nfc); + submenu, "Edit UID and Name", SubmenuIndexEdit, nfc_scene_saved_menu_submenu_callback, nfc); submenu_add_item( submenu, "Delete", SubmenuIndexDelete, nfc_scene_saved_menu_submenu_callback, nfc); submenu_add_item( diff --git a/applications/nfc/scenes/nfc_scene_scripts_menu.c b/applications/nfc/scenes/nfc_scene_scripts_menu.c index 24d439befa0..446b9d8200f 100755 --- a/applications/nfc/scenes/nfc_scene_scripts_menu.c +++ b/applications/nfc/scenes/nfc_scene_scripts_menu.c @@ -18,7 +18,7 @@ void nfc_scene_scripts_menu_on_enter(void* context) { submenu_add_item( submenu, - "Read bank card", + "Read Bank Card", SubmenuIndexBankCard, nfc_scene_scripts_menu_submenu_callback, nfc); diff --git a/applications/nfc/scenes/nfc_scene_start.c b/applications/nfc/scenes/nfc_scene_start.c index eaf32468651..2be7775b345 100644 --- a/applications/nfc/scenes/nfc_scene_start.c +++ b/applications/nfc/scenes/nfc_scene_start.c @@ -19,17 +19,16 @@ void nfc_scene_start_on_enter(void* context) { Submenu* submenu = nfc->submenu; submenu_add_item( - submenu, "Read card", SubmenuIndexRead, nfc_scene_start_submenu_callback, nfc); + submenu, "Read Card", SubmenuIndexRead, nfc_scene_start_submenu_callback, nfc); submenu_add_item( submenu, - "Run special action", + "Run Special Action", SubmenuIndexRunScript, nfc_scene_start_submenu_callback, nfc); + submenu_add_item(submenu, "Saved", SubmenuIndexSaved, nfc_scene_start_submenu_callback, nfc); submenu_add_item( - submenu, "Saved cards", SubmenuIndexSaved, nfc_scene_start_submenu_callback, nfc); - submenu_add_item( - submenu, "Add manually", SubmenuIndexAddManualy, nfc_scene_start_submenu_callback, nfc); + submenu, "Add Manually", SubmenuIndexAddManualy, nfc_scene_start_submenu_callback, nfc); if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)) { submenu_add_item( diff --git a/applications/notification/notification_settings_app.c b/applications/notification/notification_settings_app.c index 43ae9071fd8..fc2c16276df 100644 --- a/applications/notification/notification_settings_app.c +++ b/applications/notification/notification_settings_app.c @@ -163,21 +163,21 @@ static NotificationAppSettings* alloc_settings() { uint8_t value_index; item = variable_item_list_add( - app->variable_item_list, "LCD backlight", BACKLIGHT_COUNT, backlight_changed, app); + app->variable_item_list, "LCD Backlight", BACKLIGHT_COUNT, backlight_changed, app); value_index = float_value_index( app->notification->settings.display_brightness, backlight_value, BACKLIGHT_COUNT); variable_item_set_current_value_index(item, value_index); variable_item_set_current_value_text(item, backlight_text[value_index]); item = variable_item_list_add( - app->variable_item_list, "Backlight time", DELAY_COUNT, screen_changed, app); + app->variable_item_list, "Backlight Time", DELAY_COUNT, screen_changed, app); value_index = uint32_value_index( app->notification->settings.display_off_delay_ms, delay_value, DELAY_COUNT); variable_item_set_current_value_index(item, value_index); variable_item_set_current_value_text(item, delay_text[value_index]); item = variable_item_list_add( - app->variable_item_list, "LED brightness", BACKLIGHT_COUNT, led_changed, app); + app->variable_item_list, "LED Brightness", BACKLIGHT_COUNT, led_changed, app); value_index = float_value_index( app->notification->settings.led_brightness, backlight_value, BACKLIGHT_COUNT); variable_item_set_current_value_index(item, value_index); diff --git a/applications/power/power_settings_app/scenes/power_settings_scene_start.c b/applications/power/power_settings_app/scenes/power_settings_scene_start.c index 1b368dbc460..63f123d8900 100755 --- a/applications/power/power_settings_app/scenes/power_settings_scene_start.c +++ b/applications/power/power_settings_app/scenes/power_settings_scene_start.c @@ -18,7 +18,7 @@ void power_settings_scene_start_on_enter(void* context) { submenu_add_item( submenu, - "Battery info", + "Battery Info", PowerSettingsSubmenuIndexBatteryInfo, power_settings_scene_start_submenu_callback, app); diff --git a/applications/storage_settings/scenes/storage_settings_scene_start.c b/applications/storage_settings/scenes/storage_settings_scene_start.c index 027a59985ef..9f41061b893 100644 --- a/applications/storage_settings/scenes/storage_settings_scene_start.c +++ b/applications/storage_settings/scenes/storage_settings_scene_start.c @@ -21,7 +21,7 @@ void storage_settings_scene_start_on_enter(void* context) { submenu_add_item( submenu, - "About internal storage", + "About Internal Storage", StorageSettingsStartSubmenuIndexInternalInfo, storage_settings_scene_start_submenu_callback, app); diff --git a/applications/subghz/scenes/subghz_scene_start.c b/applications/subghz/scenes/subghz_scene_start.c index 53a1e0fafaa..f37ccae9e42 100644 --- a/applications/subghz/scenes/subghz_scene_start.c +++ b/applications/subghz/scenes/subghz_scene_start.c @@ -31,7 +31,7 @@ void subghz_scene_start_on_enter(void* context) { subghz->submenu, "Saved", SubmenuIndexSaved, subghz_scene_start_submenu_callback, subghz); submenu_add_item( subghz->submenu, - "Add manually", + "Add Manually", SubmenuIndexAddManualy, subghz_scene_start_submenu_callback, subghz); From a25552eb996cf7d651fd1303fab80d468d1a0377 Mon Sep 17 00:00:00 2001 From: Dmitry Pavlov Date: Mon, 11 Apr 2022 14:59:50 +0300 Subject: [PATCH 03/20] [FL-2344] iButton deleted back button (#1096) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: あく --- .../scene/ibutton_scene_delete_confirm.cpp | 2 +- .../ibutton/scene/ibutton_scene_info.cpp | 31 +++---------------- 2 files changed, 6 insertions(+), 27 deletions(-) diff --git a/applications/ibutton/scene/ibutton_scene_delete_confirm.cpp b/applications/ibutton/scene/ibutton_scene_delete_confirm.cpp index 8b1aa9f554e..1c96b4dfe49 100755 --- a/applications/ibutton/scene/ibutton_scene_delete_confirm.cpp +++ b/applications/ibutton/scene/ibutton_scene_delete_confirm.cpp @@ -22,7 +22,7 @@ void iButtonSceneDeleteConfirm::on_enter(iButtonApp* app) { app->set_text_store("\e#Delete %s?\e#", ibutton_key_get_name_p(key)); widget_add_text_box_element( widget, 0, 0, 128, 27, AlignCenter, AlignCenter, app->get_text_store()); - widget_add_button_element(widget, GuiButtonTypeLeft, "Back", widget_callback, app); + widget_add_button_element(widget, GuiButtonTypeLeft, "Cancel", widget_callback, app); widget_add_button_element(widget, GuiButtonTypeRight, "Delete", widget_callback, app); switch(ibutton_key_get_type(key)) { diff --git a/applications/ibutton/scene/ibutton_scene_info.cpp b/applications/ibutton/scene/ibutton_scene_info.cpp index afc8c050c47..ae39774f835 100755 --- a/applications/ibutton/scene/ibutton_scene_info.cpp +++ b/applications/ibutton/scene/ibutton_scene_info.cpp @@ -1,18 +1,6 @@ #include "ibutton_scene_info.h" #include "../ibutton_app.h" -static void widget_callback(GuiButtonType result, InputType type, void* context) { - furi_assert(context); - iButtonApp* app = static_cast(context); - iButtonEvent event; - - if(type == InputTypeShort) { - event.type = iButtonEvent::Type::EventTypeWidgetButtonResult; - event.payload.widget_button_result = result; - app->get_view_manager()->send_event(&event); - } -} - void iButtonSceneInfo::on_enter(iButtonApp* app) { iButtonAppViewManager* view_manager = app->get_view_manager(); Widget* widget = view_manager->get_widget(); @@ -21,8 +9,7 @@ void iButtonSceneInfo::on_enter(iButtonApp* app) { app->set_text_store("%s", ibutton_key_get_name_p(key)); widget_add_text_box_element( - widget, 0, 0, 128, 27, AlignCenter, AlignCenter, app->get_text_store()); - widget_add_button_element(widget, GuiButtonTypeLeft, "Back", widget_callback, app); + widget, 0, 0, 128, 28, AlignCenter, AlignCenter, app->get_text_store()); switch(ibutton_key_get_type(key)) { case iButtonKeyDS1990: @@ -37,36 +24,28 @@ void iButtonSceneInfo::on_enter(iButtonApp* app) { key_data[6], key_data[7]); widget_add_string_element( - widget, 64, 45, AlignCenter, AlignBottom, FontSecondary, "Dallas"); + widget, 64, 51, AlignCenter, AlignBottom, FontSecondary, "Dallas"); break; case iButtonKeyMetakom: app->set_text_store( "%02X %02X %02X %02X", key_data[0], key_data[1], key_data[2], key_data[3]); widget_add_string_element( - widget, 64, 45, AlignCenter, AlignBottom, FontSecondary, "Metakom"); + widget, 64, 51, AlignCenter, AlignBottom, FontSecondary, "Metakom"); break; case iButtonKeyCyfral: app->set_text_store("%02X %02X", key_data[0], key_data[1]); widget_add_string_element( - widget, 64, 45, AlignCenter, AlignBottom, FontSecondary, "Cyfral"); + widget, 64, 51, AlignCenter, AlignBottom, FontSecondary, "Cyfral"); break; } widget_add_string_element( - widget, 64, 33, AlignCenter, AlignBottom, FontPrimary, app->get_text_store()); + widget, 64, 35, AlignCenter, AlignBottom, FontPrimary, app->get_text_store()); view_manager->switch_to(iButtonAppViewManager::Type::iButtonAppViewWidget); } bool iButtonSceneInfo::on_event(iButtonApp* app, iButtonEvent* event) { bool consumed = false; - - if(event->type == iButtonEvent::Type::EventTypeWidgetButtonResult) { - if(event->payload.widget_button_result == GuiButtonTypeLeft) { - app->switch_to_previous_scene(); - consumed = true; - } - } - return consumed; } From e02040107b2c8c0a4d72ffb1b112d2dff7384b7c Mon Sep 17 00:00:00 2001 From: hedger Date: Wed, 13 Apr 2022 23:50:25 +0300 Subject: [PATCH 04/20] [FL-2263] Flasher service & RAM exec (#1006) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * WIP on stripping fw * Compact FW build - use RAM_EXEC=1 COMPACT=1 DEBUG=0 * Fixed uninitialized storage struct; small fixes to compact fw * Flasher srv w/mocked flash ops * Fixed typos & accomodated FFF changes * Alternative fw startup branch * Working load & jmp to RAM fw * +manifest processing for stage loader; + crc verification for stage payload * Fixed questionable code & potential leaks * Lowered screen update rate; added radio stack update stubs; working dfu write * Console EP with manifest & stage validation * Added microtar lib; minor ui fixes for updater * Removed microtar * Removed mtar #2 * Added a better version of microtar * TAR archive api; LFS backup & restore core * Recursive backup/restore * LFS worker thread * Added system apps to loader - not visible in UI; full update process with restarts * Typo fix * Dropped BL & f6; tooling for updater WIP * Minor py fixes * Minor fixes to make it build after merge * Ported flash workaround from BL + fixed visuals * Minor cleanup * Chmod + loader app search fix * Python linter fix * Removed usb stuff & float read support for staged loader == -10% of binary size * Added backup/restore & update pb requests * Added stub impl to RPC for backup/restore/update commands * Reworked TAR to use borrowed Storage api; slightly reduced build size by removing `static string`; hidden update-related RPC behind defines * Moved backup&restore to storage * Fixed new message types * Backup/restore/update RPC impl * Moved furi_hal_crc to LL; minor fixes * CRC HAL rework to LL * Purging STM HAL * Brought back minimal DFU boot mode (no gui); additional crc state checks * Added splash screen, BROKEN usb function * Clock init rework WIP * Stripped graphics from DFU mode * Temp fix for unused static fun * WIP update picker - broken! * Fixed UI * Bumping version * Fixed RTC setup * Backup to update folder instead of ext root * Removed unused scenes & more usb remnants from staged loader * CI updates * Fixed update bundle name * Temporary restored USB handler * Attempt to prevent .text corruption * Comments on how I spent this Saturday * Added update file icon * Documentation updates * Moved common code to lib folder * Storage: more unit tests * Storage: blocking dir open, differentiate file and dir when freed. * Major refactoring; added input processing to updater to allow retrying on failures (not very useful prob). Added API for extraction of thread return value * Removed re-init check for manifest * Changed low-level path manipulation to toolbox/path.h; makefile cleanup; tiny fix in lint.py * Increased update worker stack size * Text fixes in backup CLI * Displaying number of update stages to run; removed timeout in handling errors * Bumping version * Added thread cleanup for spawner thread * Updated build targets to exclude firmware bundle from 'ALL' * Fixed makefile for update_package; skipping VCP init for update mode (ugly) * Switched github build from ALL to update_package * Added +x for dist_update.sh * Cli: add total heap size to "free" command * Moved (RAM) suffix to build version instead of git commit no. * DFU comment * Some fixes suggested by clang-tidy * Fixed recursive PREFIX macro * Makefile: gather all new rules in updater namespace. FuriHal: rename bootloader to boot, isr safe delays * Github: correct build target name in firmware build * FuriHal: move target switch to boot * Makefile: fix firmware flash * Furi, FuriHal: move kernel start to furi, early init * Drop bootloader related stuff * Drop cube. Drop bootloader linker script. * Renamed update_hl, moved constants to #defines * Moved update-related boot mode to separate bitfield * Reworked updater cli to single entry point; fixed crash on tar cleanup * Added Python replacement for dist shell scripts * Linter fixes for dist.py +x * Fixes for environment suffix * Dropped bash scripts * Added dirty build flag to version structure & interfaces * Version string escapes * Fixed flag logic in dist.py; added support for App instances being imported and not terminating the whole program * Fixed fw address in ReadMe.md * Rpc: fix crash on double screen start * Return back original boot behavior and fix jump to system bootloader * Cleanup code, add error sequence for RTC * Update firmware readme * FuriHal: drop boot, restructure RTC registers usage and add header register check * Furi goes first * Toolchain: add ccache support * Renamed update bundle dir Co-authored-by: DrZlo13 Co-authored-by: あく --- .github/CODEOWNERS | 1 + .github/workflows/build.yml | 25 +- .gitmodules | 3 + Makefile | 52 +- ReadMe.md | 6 +- applications/ReadMe.md | 1 + applications/about/about.c | 36 +- applications/applications.c | 29 +- applications/applications.h | 8 +- applications/applications.mk | 31 +- .../archive/helpers/archive_browser.h | 1 + applications/archive/helpers/archive_files.h | 1 + .../archive/scenes/archive_scene_browser.c | 1 + .../archive/views/archive_browser_view.c | 6 +- applications/bt/bt_cli.c | 4 +- applications/cli/cli.c | 3 +- applications/cli/cli_commands.c | 1 + applications/crypto/crypto_cli.c | 4 +- .../desktop/views/desktop_view_debug.c | 8 +- .../desktop/views/desktop_view_debug.h | 1 - applications/gui/elements.c | 2 +- applications/ibutton/ibutton_cli.c | 13 +- applications/infrared/cli/infrared_cli.cpp | 2 + .../infrared/infrared_app_remote_manager.cpp | 2 +- applications/input/input_cli.c | 2 +- applications/lfrfid/lfrfid_cli.cpp | 14 +- applications/loader/loader.c | 53 +- applications/nfc/nfc_cli.c | 2 + applications/power/power_cli.c | 2 + applications/power/power_service/power_api.c | 7 +- applications/rpc/rpc_gui.c | 50 +- applications/rpc/rpc_storage.c | 59 +- applications/rpc/rpc_system.c | 30 +- applications/storage/storage.c | 2 + applications/storage/storage.h | 18 +- applications/storage/storage_cli.c | 4 +- applications/storage/storage_internal_api.c | 22 + applications/storage/storage_processing.c | 4 + applications/storage/storages/storage_ext.c | 48 +- applications/subghz/subghz_cli.c | 4 +- applications/updater/cli/updater_cli.c | 134 +++ applications/updater/scenes/updater_scene.c | 30 + applications/updater/scenes/updater_scene.h | 29 + .../updater/scenes/updater_scene_config.h | 5 + .../updater/scenes/updater_scene_error.c | 65 ++ .../updater/scenes/updater_scene_loadcfg.c | 105 +++ .../updater/scenes/updater_scene_main.c | 106 +++ applications/updater/updater.c | 132 +++ applications/updater/updater_i.h | 65 ++ applications/updater/util/update_task.c | 226 +++++ applications/updater/util/update_task.h | 66 ++ applications/updater/util/update_task_i.h | 24 + .../updater/util/update_task_workers.c | 148 ++++ applications/updater/views/updater_main.c | 151 ++++ applications/updater/views/updater_main.h | 28 + assets/assets.mk | 2 +- assets/compiled/assets_icons.c | 4 + assets/compiled/assets_icons.h | 1 + assets/icons/Archive/update_10px.png | Bin 0 -> 156 bytes bootloader/Makefile | 44 - bootloader/ReadMe.md | 50 -- bootloader/src/main.c | 14 - bootloader/targets/f7/furi_hal/furi_hal.c | 21 - .../targets/f7/furi_hal/furi_hal_gpio.c | 214 ----- .../targets/f7/furi_hal/furi_hal_gpio.h | 264 ------ bootloader/targets/f7/furi_hal/furi_hal_i2c.c | 205 ----- bootloader/targets/f7/furi_hal/furi_hal_i2c.h | 195 ----- .../targets/f7/furi_hal/furi_hal_i2c_config.c | 151 ---- .../targets/f7/furi_hal/furi_hal_i2c_config.h | 31 - .../targets/f7/furi_hal/furi_hal_i2c_types.h | 51 -- .../targets/f7/furi_hal/furi_hal_light.c | 49 -- .../targets/f7/furi_hal/furi_hal_light.h | 17 - .../targets/f7/furi_hal/furi_hal_resources.c | 43 - .../targets/f7/furi_hal/furi_hal_resources.h | 73 -- bootloader/targets/f7/furi_hal/furi_hal_spi.c | 151 ---- .../targets/f7/furi_hal/furi_hal_spi_config.c | 290 ------- .../targets/f7/furi_hal/furi_hal_spi_config.h | 61 -- .../targets/f7/furi_hal/furi_hal_spi_types.h | 64 -- .../targets/f7/furi_hal/furi_hal_version.c | 268 ------ bootloader/targets/f7/furi_hal/main.h | 108 --- .../targets/f7/stm32wb55xx_flash_cm4.ld | 187 ----- bootloader/targets/f7/target.c | 264 ------ bootloader/targets/f7/target.mk | 50 -- .../targets/furi_hal_include/furi_hal.h | 15 - .../targets/furi_hal_include/furi_hal_spi.h | 102 --- .../furi_hal_include/furi_hal_version.h | 173 ---- bootloader/targets/furi_hal_include/target.h | 25 - core/flipper.c | 11 +- core/furi.c | 6 + core/furi.h | 2 + core/furi/check.c | 14 +- core/furi/check.h | 9 +- core/furi/common_defines.h | 24 +- core/furi/memmgr.c | 5 + core/furi/memmgr.h | 6 + core/furi/memmgr_heap.c | 5 + core/furi/record.h | 2 +- core/furi/thread.c | 8 +- core/furi/thread.h | 10 +- firmware/Makefile | 7 +- firmware/ReadMe.md | 16 +- firmware/targets/f7/Inc/FreeRTOSConfig.h | 4 +- firmware/targets/f7/Inc/alt_boot.h | 13 + firmware/targets/f7/Src/dfu.c | 41 + firmware/targets/f7/Src/main.c | 76 +- firmware/targets/f7/Src/system_stm32wbxx.c | 12 +- firmware/targets/f7/Src/update.c | 196 +++++ firmware/targets/f7/cube/Inc/FreeRTOSConfig.h | 193 ----- firmware/targets/f7/cube/Inc/adc.h | 52 -- firmware/targets/f7/cube/Inc/aes.h | 54 -- firmware/targets/f7/cube/Inc/comp.h | 52 -- firmware/targets/f7/cube/Inc/crc.h | 52 -- firmware/targets/f7/cube/Inc/gpio.h | 49 -- firmware/targets/f7/cube/Inc/i2c.h | 50 -- firmware/targets/f7/cube/Inc/main.h | 175 ---- firmware/targets/f7/cube/Inc/pka.h | 52 -- firmware/targets/f7/cube/Inc/rf.h | 50 -- firmware/targets/f7/cube/Inc/rng.h | 52 -- firmware/targets/f7/cube/Inc/rtc.h | 52 -- firmware/targets/f7/cube/Inc/spi.h | 54 -- firmware/targets/f7/cube/Inc/stm32_assert.h | 53 -- .../targets/f7/cube/Inc/stm32wbxx_hal_conf.h | 354 -------- firmware/targets/f7/cube/Inc/stm32wbxx_it.h | 77 -- firmware/targets/f7/cube/Inc/tim.h | 58 -- firmware/targets/f7/cube/Inc/usart.h | 50 -- firmware/targets/f7/cube/Inc/usb_device.h | 105 --- firmware/targets/f7/cube/Inc/usbd_cdc_if.h | 133 --- firmware/targets/f7/cube/Inc/usbd_conf.h | 179 ---- firmware/targets/f7/cube/Inc/usbd_desc.h | 145 ---- firmware/targets/f7/cube/Makefile | 253 ------ firmware/targets/f7/cube/Src/adc.c | 128 --- firmware/targets/f7/cube/Src/aes.c | 129 --- firmware/targets/f7/cube/Src/app_freertos.c | 173 ---- firmware/targets/f7/cube/Src/comp.c | 103 --- firmware/targets/f7/cube/Src/crc.c | 82 -- firmware/targets/f7/cube/Src/gpio.c | 177 ---- firmware/targets/f7/cube/Src/i2c.c | 80 -- firmware/targets/f7/cube/Src/main.c | 275 ------ firmware/targets/f7/cube/Src/pka.c | 77 -- firmware/targets/f7/cube/Src/rf.c | 45 - firmware/targets/f7/cube/Src/rng.c | 78 -- firmware/targets/f7/cube/Src/rtc.c | 122 --- firmware/targets/f7/cube/Src/spi.c | 214 ----- .../targets/f7/cube/Src/stm32wbxx_hal_msp.c | 92 -- firmware/targets/f7/cube/Src/stm32wbxx_it.c | 304 ------- .../targets/f7/cube/Src/system_stm32wbxx.c | 384 --------- firmware/targets/f7/cube/Src/tim.c | 347 -------- firmware/targets/f7/cube/Src/usart.c | 91 -- firmware/targets/f7/cube/Src/usb_device.c | 98 --- firmware/targets/f7/cube/Src/usbd_cdc_if.c | 318 ------- firmware/targets/f7/cube/Src/usbd_conf.c | 783 ------------------ firmware/targets/f7/cube/Src/usbd_desc.c | 368 -------- firmware/targets/f7/cube/f7.ioc | 598 ------------- .../targets/f7/cube/startup_stm32wb55xx_cm4.s | 446 ---------- .../targets/f7/cube/stm32wb55xx_flash_cm4.ld | 187 ----- firmware/targets/f7/fatfs/ffconf.h | 9 +- firmware/targets/f7/furi_hal/furi_hal.c | 49 +- .../targets/f7/furi_hal/furi_hal_bootloader.c | 25 - firmware/targets/f7/furi_hal/furi_hal_clock.c | 33 + firmware/targets/f7/furi_hal/furi_hal_clock.h | 6 + firmware/targets/f7/furi_hal/furi_hal_crc.c | 88 ++ firmware/targets/f7/furi_hal/furi_hal_crc.h | 35 + firmware/targets/f7/furi_hal/furi_hal_delay.c | 25 +- firmware/targets/f7/furi_hal/furi_hal_flash.c | 87 +- firmware/targets/f7/furi_hal/furi_hal_flash.h | 23 + firmware/targets/f7/furi_hal/furi_hal_i2c.c | 9 +- .../targets/f7/furi_hal/furi_hal_i2c_config.c | 25 +- firmware/targets/f7/furi_hal/furi_hal_info.c | 18 +- .../targets/f7/furi_hal/furi_hal_interrupt.c | 4 +- firmware/targets/f7/furi_hal/furi_hal_light.c | 28 + .../targets/f7/furi_hal/furi_hal_resources.c | 20 +- .../targets/f7/furi_hal/furi_hal_resources.h | 16 +- firmware/targets/f7/furi_hal/furi_hal_rtc.c | 79 +- firmware/targets/f7/furi_hal/furi_hal_spi.c | 12 +- .../targets/f7/furi_hal/furi_hal_spi_config.c | 12 +- firmware/targets/f7/furi_hal/furi_hal_vcp.c | 5 + .../targets/f7/furi_hal/furi_hal_version.c | 11 +- ..._no_bootloader.ld => stm32wb55xx_flash.ld} | 0 ...th_bootloader.ld => stm32wb55xx_ram_fw.ld} | 24 +- firmware/targets/f7/target.mk | 32 +- firmware/targets/furi_hal_include/furi_hal.h | 26 +- .../furi_hal_include/furi_hal_bootloader.h | 29 - .../targets/furi_hal_include/furi_hal_delay.h | 9 +- .../targets/furi_hal_include/furi_hal_i2c.h | 9 +- .../targets/furi_hal_include/furi_hal_light.h | 6 + .../targets/furi_hal_include/furi_hal_rtc.h | 35 +- .../targets/furi_hal_include/furi_hal_spi.h | 8 +- .../furi_hal_include/furi_hal_version.h | 24 +- lib/ReadMe.md | 10 +- lib/flipper_format/flipper_format_stream.c | 6 +- lib/lib.mk | 7 + lib/microtar | 1 + lib/one_wire/ibutton/encoder/encoder_cyfral.c | 2 +- .../ibutton/encoder/encoder_metakom.c | 2 +- .../ibutton/pulse_protocols/protocol_cyfral.c | 2 +- lib/one_wire/one_wire_slave.c | 6 +- lib/subghz/subghz_keystore.c | 4 +- lib/toolbox/path.c | 40 + lib/toolbox/path.h | 35 +- lib/toolbox/tar/tar_archive.c | 306 +++++++ lib/toolbox/tar/tar_archive.h | 59 ++ lib/toolbox/version.c | 14 +- lib/toolbox/version.h | 14 +- lib/update_util/dfu_file.c | 183 ++++ lib/update_util/dfu_file.h | 40 + lib/update_util/dfu_headers.h | 41 + lib/update_util/lfs_backup.c | 22 + lib/update_util/lfs_backup.h | 18 + lib/update_util/update_manifest.c | 86 ++ lib/update_util/update_manifest.h | 40 + lib/update_util/update_operation.c | 207 +++++ lib/update_util/update_operation.h | 72 ++ make/git.mk | 21 +- make/rules.mk | 5 +- make/toolchain.mk | 9 +- scripts/dist.py | 92 ++ scripts/dist.sh | 52 -- scripts/flipper/app.py | 16 +- scripts/flipper/utils/fff.py | 8 +- scripts/lint.py | 2 +- scripts/update.py | 77 ++ 221 files changed, 4194 insertions(+), 11699 deletions(-) create mode 100644 applications/storage/storage_internal_api.c create mode 100644 applications/updater/cli/updater_cli.c create mode 100644 applications/updater/scenes/updater_scene.c create mode 100644 applications/updater/scenes/updater_scene.h create mode 100644 applications/updater/scenes/updater_scene_config.h create mode 100644 applications/updater/scenes/updater_scene_error.c create mode 100644 applications/updater/scenes/updater_scene_loadcfg.c create mode 100644 applications/updater/scenes/updater_scene_main.c create mode 100644 applications/updater/updater.c create mode 100644 applications/updater/updater_i.h create mode 100644 applications/updater/util/update_task.c create mode 100644 applications/updater/util/update_task.h create mode 100644 applications/updater/util/update_task_i.h create mode 100644 applications/updater/util/update_task_workers.c create mode 100644 applications/updater/views/updater_main.c create mode 100644 applications/updater/views/updater_main.h create mode 100644 assets/icons/Archive/update_10px.png delete mode 100644 bootloader/Makefile delete mode 100644 bootloader/ReadMe.md delete mode 100644 bootloader/src/main.c delete mode 100644 bootloader/targets/f7/furi_hal/furi_hal.c delete mode 100644 bootloader/targets/f7/furi_hal/furi_hal_gpio.c delete mode 100644 bootloader/targets/f7/furi_hal/furi_hal_gpio.h delete mode 100644 bootloader/targets/f7/furi_hal/furi_hal_i2c.c delete mode 100644 bootloader/targets/f7/furi_hal/furi_hal_i2c.h delete mode 100644 bootloader/targets/f7/furi_hal/furi_hal_i2c_config.c delete mode 100644 bootloader/targets/f7/furi_hal/furi_hal_i2c_config.h delete mode 100644 bootloader/targets/f7/furi_hal/furi_hal_i2c_types.h delete mode 100644 bootloader/targets/f7/furi_hal/furi_hal_light.c delete mode 100644 bootloader/targets/f7/furi_hal/furi_hal_light.h delete mode 100644 bootloader/targets/f7/furi_hal/furi_hal_resources.c delete mode 100644 bootloader/targets/f7/furi_hal/furi_hal_resources.h delete mode 100644 bootloader/targets/f7/furi_hal/furi_hal_spi.c delete mode 100644 bootloader/targets/f7/furi_hal/furi_hal_spi_config.c delete mode 100644 bootloader/targets/f7/furi_hal/furi_hal_spi_config.h delete mode 100644 bootloader/targets/f7/furi_hal/furi_hal_spi_types.h delete mode 100644 bootloader/targets/f7/furi_hal/furi_hal_version.c delete mode 100644 bootloader/targets/f7/furi_hal/main.h delete mode 100644 bootloader/targets/f7/stm32wb55xx_flash_cm4.ld delete mode 100644 bootloader/targets/f7/target.c delete mode 100644 bootloader/targets/f7/target.mk delete mode 100644 bootloader/targets/furi_hal_include/furi_hal.h delete mode 100644 bootloader/targets/furi_hal_include/furi_hal_spi.h delete mode 100644 bootloader/targets/furi_hal_include/furi_hal_version.h delete mode 100644 bootloader/targets/furi_hal_include/target.h create mode 100644 firmware/targets/f7/Inc/alt_boot.h create mode 100644 firmware/targets/f7/Src/dfu.c create mode 100644 firmware/targets/f7/Src/update.c delete mode 100644 firmware/targets/f7/cube/Inc/FreeRTOSConfig.h delete mode 100644 firmware/targets/f7/cube/Inc/adc.h delete mode 100644 firmware/targets/f7/cube/Inc/aes.h delete mode 100644 firmware/targets/f7/cube/Inc/comp.h delete mode 100644 firmware/targets/f7/cube/Inc/crc.h delete mode 100644 firmware/targets/f7/cube/Inc/gpio.h delete mode 100644 firmware/targets/f7/cube/Inc/i2c.h delete mode 100644 firmware/targets/f7/cube/Inc/main.h delete mode 100644 firmware/targets/f7/cube/Inc/pka.h delete mode 100644 firmware/targets/f7/cube/Inc/rf.h delete mode 100644 firmware/targets/f7/cube/Inc/rng.h delete mode 100644 firmware/targets/f7/cube/Inc/rtc.h delete mode 100644 firmware/targets/f7/cube/Inc/spi.h delete mode 100644 firmware/targets/f7/cube/Inc/stm32_assert.h delete mode 100644 firmware/targets/f7/cube/Inc/stm32wbxx_hal_conf.h delete mode 100644 firmware/targets/f7/cube/Inc/stm32wbxx_it.h delete mode 100644 firmware/targets/f7/cube/Inc/tim.h delete mode 100644 firmware/targets/f7/cube/Inc/usart.h delete mode 100644 firmware/targets/f7/cube/Inc/usb_device.h delete mode 100644 firmware/targets/f7/cube/Inc/usbd_cdc_if.h delete mode 100644 firmware/targets/f7/cube/Inc/usbd_conf.h delete mode 100644 firmware/targets/f7/cube/Inc/usbd_desc.h delete mode 100644 firmware/targets/f7/cube/Makefile delete mode 100644 firmware/targets/f7/cube/Src/adc.c delete mode 100644 firmware/targets/f7/cube/Src/aes.c delete mode 100644 firmware/targets/f7/cube/Src/app_freertos.c delete mode 100644 firmware/targets/f7/cube/Src/comp.c delete mode 100644 firmware/targets/f7/cube/Src/crc.c delete mode 100644 firmware/targets/f7/cube/Src/gpio.c delete mode 100644 firmware/targets/f7/cube/Src/i2c.c delete mode 100644 firmware/targets/f7/cube/Src/main.c delete mode 100644 firmware/targets/f7/cube/Src/pka.c delete mode 100644 firmware/targets/f7/cube/Src/rf.c delete mode 100644 firmware/targets/f7/cube/Src/rng.c delete mode 100644 firmware/targets/f7/cube/Src/rtc.c delete mode 100644 firmware/targets/f7/cube/Src/spi.c delete mode 100644 firmware/targets/f7/cube/Src/stm32wbxx_hal_msp.c delete mode 100644 firmware/targets/f7/cube/Src/stm32wbxx_it.c delete mode 100644 firmware/targets/f7/cube/Src/system_stm32wbxx.c delete mode 100644 firmware/targets/f7/cube/Src/tim.c delete mode 100644 firmware/targets/f7/cube/Src/usart.c delete mode 100644 firmware/targets/f7/cube/Src/usb_device.c delete mode 100644 firmware/targets/f7/cube/Src/usbd_cdc_if.c delete mode 100644 firmware/targets/f7/cube/Src/usbd_conf.c delete mode 100644 firmware/targets/f7/cube/Src/usbd_desc.c delete mode 100644 firmware/targets/f7/cube/f7.ioc delete mode 100644 firmware/targets/f7/cube/startup_stm32wb55xx_cm4.s delete mode 100644 firmware/targets/f7/cube/stm32wb55xx_flash_cm4.ld delete mode 100644 firmware/targets/f7/furi_hal/furi_hal_bootloader.c create mode 100644 firmware/targets/f7/furi_hal/furi_hal_crc.c create mode 100644 firmware/targets/f7/furi_hal/furi_hal_crc.h rename firmware/targets/f7/{stm32wb55xx_flash_cm4_no_bootloader.ld => stm32wb55xx_flash.ld} (100%) rename firmware/targets/f7/{stm32wb55xx_flash_cm4_with_bootloader.ld => stm32wb55xx_ram_fw.ld} (95%) delete mode 100644 firmware/targets/furi_hal_include/furi_hal_bootloader.h create mode 160000 lib/microtar create mode 100644 lib/toolbox/tar/tar_archive.c create mode 100644 lib/toolbox/tar/tar_archive.h create mode 100644 lib/update_util/dfu_file.c create mode 100644 lib/update_util/dfu_file.h create mode 100644 lib/update_util/dfu_headers.h create mode 100644 lib/update_util/lfs_backup.c create mode 100644 lib/update_util/lfs_backup.h create mode 100644 lib/update_util/update_manifest.c create mode 100644 lib/update_util/update_manifest.h create mode 100644 lib/update_util/update_operation.c create mode 100644 lib/update_util/update_operation.h create mode 100755 scripts/dist.py delete mode 100755 scripts/dist.sh create mode 100755 scripts/update.py diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 2c82c7d47c2..9a88ae2b4f1 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -25,6 +25,7 @@ applications/sd-filesystem/** @skotopes @DrZlo13 applications/subghz/** @skotopes @DrZlo13 applications/template/** @skotopes @DrZlo13 applications/tests/** @skotopes @DrZlo13 +applications/updater/** @skotopes @DrZlo13 @hedger # Assets and asset generator assets/** @skotopes @DrZlo13 diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d4a2e97e126..9e5f3c7296c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -42,7 +42,7 @@ jobs: run: | test -d artifacts && rm -rf artifacts || true mkdir artifacts - + - name: 'Generate suffix and folder name' id: names run: | @@ -52,13 +52,13 @@ jobs: fi BRANCH_OR_TAG=${REF#refs/*/} SHA=$(git rev-parse --short HEAD) - + if [[ "${{ github.ref }}" == "refs/tags/"* ]]; then SUFFIX=${BRANCH_OR_TAG//\//_} else SUFFIX=${BRANCH_OR_TAG//\//_}-$(date +'%d%m%Y')-${SHA} fi - + echo "WORKFLOW_BRANCH_OR_TAG=${BRANCH_OR_TAG}" >> $GITHUB_ENV echo "DIST_SUFFIX=${SUFFIX}" >> $GITHUB_ENV echo "::set-output name=artifacts-path::${BRANCH_OR_TAG}" @@ -86,7 +86,7 @@ jobs: set -e for TARGET in ${TARGETS} do - make TARGET=${TARGET} ${{ startsWith(github.ref, 'refs/tags') && 'DEBUG=0 COMPACT=1' || '' }} + make updater_package TARGET=${TARGET} ${{ startsWith(github.ref, 'refs/tags') && 'DEBUG=0 COMPACT=1' || '' }} done - name: 'Move upload files' @@ -100,6 +100,17 @@ jobs: mv dist/${TARGET}/* artifacts/ done + - name: 'Bundle self-update package' + if: ${{ !github.event.pull_request.head.repo.fork }} + run: | + set -e + for UPDATEBUNDLE in artifacts/*/ + do + BUNDLE_NAME=`echo $UPDATEBUNDLE | cut -d'/' -f2` + echo Packaging ${BUNDLE_NAME} + tar czpf artifacts/flipper-z-${BUNDLE_NAME}.tgz -C artifacts ${BUNDLE_NAME} + done + - name: 'Bundle resources' if: ${{ !github.event.pull_request.head.repo.fork }} run: | @@ -175,7 +186,7 @@ jobs: - name: 'Build docker image' uses: ./.github/actions/docker - + - name: 'Generate suffix and folder name' id: names run: | @@ -185,13 +196,13 @@ jobs: fi BRANCH_OR_TAG=${REF#refs/*/} SHA=$(git rev-parse --short HEAD) - + if [[ "${{ github.ref }}" == "refs/tags/"* ]]; then SUFFIX=${BRANCH_OR_TAG//\//_} else SUFFIX=${BRANCH_OR_TAG//\//_}-$(date +'%d%m%Y')-${SHA} fi - + echo "WORKFLOW_BRANCH_OR_TAG=${BRANCH_OR_TAG}" >> $GITHUB_ENV echo "DIST_SUFFIX=${SUFFIX}" >> $GITHUB_ENV diff --git a/.gitmodules b/.gitmodules index a16101ad786..c4649fdca92 100644 --- a/.gitmodules +++ b/.gitmodules @@ -19,3 +19,6 @@ [submodule "lib/FreeRTOS-Kernel"] path = lib/FreeRTOS-Kernel url = https://github.com/FreeRTOS/FreeRTOS-Kernel.git +[submodule "lib/microtar"] + path = lib/microtar + url = https://github.com/amachronic/microtar.git diff --git a/Makefile b/Makefile index cd448e2e2d0..02008033dc3 100644 --- a/Makefile +++ b/Makefile @@ -1,16 +1,16 @@ PROJECT_ROOT := $(abspath $(dir $(abspath $(firstword $(MAKEFILE_LIST))))) + +include $(PROJECT_ROOT)/make/git.mk + COPRO_DIR := $(PROJECT_ROOT)/lib/STM32CubeWB/Projects/STM32WB_Copro_Wireless_Binaries/STM32WB5x PROJECT_SOURCE_DIRECTORIES := \ $(PROJECT_ROOT)/applications \ - $(PROJECT_ROOT)/bootloader/src \ - $(PROJECT_ROOT)/bootloader/targets \ $(PROJECT_ROOT)/core \ $(PROJECT_ROOT)/firmware/targets \ $(PROJECT_ROOT)/lib/app-template \ $(PROJECT_ROOT)/lib/app-scened-template \ $(PROJECT_ROOT)/lib/common-api \ - $(PROJECT_ROOT)/lib/cyfral \ $(PROJECT_ROOT)/lib/drivers \ $(PROJECT_ROOT)/lib/flipper_file \ $(PROJECT_ROOT)/lib/infrared \ @@ -34,18 +34,18 @@ endif include $(PROJECT_ROOT)/make/defaults.mk .PHONY: all -all: bootloader_all firmware_all - @$(PROJECT_ROOT)/scripts/dist.sh +all: firmware_all + @$(PROJECT_ROOT)/scripts/dist.py copy -t $(TARGET) -p firmware -s $(DIST_SUFFIX) .PHONY: whole -whole: flash_radio bootloader_flash firmware_flash +whole: flash_radio firmware_flash .PHONY: clean -clean: bootloader_clean firmware_clean +clean: firmware_clean updater_clean @rm -rf $(PROJECT_ROOT)/dist/$(TARGET) .PHONY: flash -flash: bootloader_flash firmware_flash +flash: firmware_flash .PHONY: debug debug: @@ -60,36 +60,38 @@ wipe: @$(PROJECT_ROOT)/scripts/flash.py wipe @$(PROJECT_ROOT)/scripts/ob.py set -.PHONY: bootloader_all -bootloader_all: - @$(MAKE) -C $(PROJECT_ROOT)/bootloader -j$(NPROCS) all - .PHONY: firmware_all firmware_all: @$(MAKE) -C $(PROJECT_ROOT)/firmware -j$(NPROCS) all -.PHONY: bootloader_clean -bootloader_clean: - @$(MAKE) -C $(PROJECT_ROOT)/bootloader -j$(NPROCS) clean - .PHONY: firmware_clean firmware_clean: @$(MAKE) -C $(PROJECT_ROOT)/firmware -j$(NPROCS) clean -.PHONY: bootloader_flash -bootloader_flash: -ifeq ($(FORCE), 1) - @rm $(PROJECT_ROOT)/bootloader/.obj/f*/flash || true -endif - @$(MAKE) -C $(PROJECT_ROOT)/bootloader -j$(NPROCS) flash - .PHONY: firmware_flash firmware_flash: ifeq ($(FORCE), 1) - @rm $(PROJECT_ROOT)/firmware/.obj/f*/flash || true + @rm $(PROJECT_ROOT)/firmware/.obj/f*-firmware/flash || true endif @$(MAKE) -C $(PROJECT_ROOT)/firmware -j$(NPROCS) flash + +.PHONY: updater +updater: + @$(MAKE) -C $(PROJECT_ROOT)/firmware -j$(NPROCS) RAM_EXEC=1 all + +.PHONY: updater_clean +updater_clean: + @$(MAKE) -C $(PROJECT_ROOT)/firmware -j$(NPROCS) RAM_EXEC=1 clean + +.PHONY: updater_debug +updater_debug: + @$(MAKE) -C $(PROJECT_ROOT)/firmware -j$(NPROCS) RAM_EXEC=1 debug + +.PHONY: updater_package +updater_package: firmware_all updater + @$(PROJECT_ROOT)/scripts/dist.py copy -t $(TARGET) -p firmware updater -s $(DIST_SUFFIX) --bundlever "$(VERSION_STRING)" + .PHONY: flash_radio flash_radio: @$(PROJECT_ROOT)/scripts/flash.py core2radio 0x080D7000 $(COPRO_DIR)/stm32wb5x_BLE_Stack_light_fw.bin @@ -100,7 +102,7 @@ flash_radio_fus: @echo @echo "================ DON'T DO IT ================" @echo "= Flashing FUS is going to erase secure enclave =" - @echo "= You will loose ability to use encrypted assets =" + @echo "= You will lose ability to use encrypted assets =" @echo "= type 'find / -exec rm -rf {} \;' =" @echo "= In case if you still want to continue =" @echo "================ JUST DON'T ================" diff --git a/ReadMe.md b/ReadMe.md index 940e6051c37..9a355ebacee 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -11,17 +11,16 @@ Our goal is to create nice and clean code with good documentation, to make it a [Get Latest Firmware from Update Server](https://update.flipperzero.one/) -Flipper Zero's firmware consists of three components: +Flipper Zero's firmware consists of two components: - Core2 firmware set - proprietary components by ST: FUS + radio stack. FUS is flashed at factory and you should never update it. -- Core1 Bootloader - controls basic hardware initialization and loads firmware. - Core1 Firmware - HAL + OS + Drivers + Applications. All 3 of them must be flashed in order described. ## With STLink -### Core1 Bootloader + Firmware +### Core1 Firmware Prerequisites: @@ -144,7 +143,6 @@ make whole - `applications` - Applications and services used in firmware - `assets` - Assets used by applications and services -- `bootloader` - Bootloader source code - `core` - Furi Core: os level primitives and helpers - `debug` - Debug tool: GDB-plugins, SVD-file and etc - `docker` - Docker image sources (used for firmware build automation) diff --git a/applications/ReadMe.md b/applications/ReadMe.md index 4c7066eef52..2c78dfa2631 100644 --- a/applications/ReadMe.md +++ b/applications/ReadMe.md @@ -34,6 +34,7 @@ - `system` - System settings, tools and API - `tests` - Unit tests and etc - `u2f` - U2F Application +- `updater` - Update service & application - `application.c` - Firmware application list source - `application.h` - Firmware application list header diff --git a/applications/about/about.c b/applications/about/about.c index 22b8a3a3756..bda50a4b0c1 100644 --- a/applications/about/about.c +++ b/applications/about/about.c @@ -116,9 +116,10 @@ static DialogMessageButton fw_version_screen(DialogsApp* dialogs, DialogMessage* } else { string_cat_printf( buffer, - "%s [%s]\n%s [%s]\n[%d] %s", + "%s [%s]\n%s%s [%s]\n[%d] %s", version_get_version(ver), version_get_builddate(ver), + version_get_dirty_flag(ver) ? "[!] " : "", version_get_githash(ver), version_get_gitbranchnum(ver), version_get_target(ver), @@ -135,36 +136,6 @@ static DialogMessageButton fw_version_screen(DialogsApp* dialogs, DialogMessage* return result; } -static DialogMessageButton bootloader_version_screen(DialogsApp* dialogs, DialogMessage* message) { - DialogMessageButton result; - string_t buffer; - string_init(buffer); - const Version* ver = furi_hal_version_get_bootloader_version(); - - if(!ver) { - string_cat_printf(buffer, "No info\n"); - } else { - string_cat_printf( - buffer, - "%s [%s]\n%s [%s]\n[%d] %s", - version_get_version(ver), - version_get_builddate(ver), - version_get_githash(ver), - version_get_gitbranchnum(ver), - version_get_target(ver), - version_get_gitbranch(ver)); - } - - dialog_message_set_header(message, "Boot Version info:", 0, 0, AlignLeft, AlignTop); - dialog_message_set_text(message, string_get_cstr(buffer), 0, 13, AlignLeft, AlignTop); - result = dialog_message_show(dialogs, message); - dialog_message_set_text(message, NULL, 0, 0, AlignLeft, AlignTop); - dialog_message_set_header(message, NULL, 0, 0, AlignLeft, AlignTop); - string_clear(buffer); - - return result; -} - const AboutDialogScreen about_screens[] = { product_screen, compliance_screen, @@ -172,8 +143,7 @@ const AboutDialogScreen about_screens[] = { icon1_screen, icon2_screen, hw_version_screen, - fw_version_screen, - bootloader_version_screen}; + fw_version_screen}; const size_t about_screens_count = sizeof(about_screens) / sizeof(AboutDialogScreen); diff --git a/applications/applications.c b/applications/applications.c index 24279d82a32..d5e7efd79f0 100644 --- a/applications/applications.c +++ b/applications/applications.c @@ -14,6 +14,7 @@ extern int32_t notification_srv(void* p); extern int32_t power_srv(void* p); extern int32_t storage_srv(void* p); extern int32_t desktop_srv(void* p); +extern int32_t updater_srv(void* p); // Apps extern int32_t accessor_app(void* p); @@ -58,6 +59,7 @@ extern void storage_on_system_start(); extern void subghz_on_system_start(); extern void power_on_system_start(); extern void unit_tests_on_system_start(); +extern void updater_on_system_start(); // Settings extern int32_t notification_settings_app(void* p); @@ -91,6 +93,9 @@ const FlipperApplication FLIPPER_SERVICES[] = { #endif #ifdef SRV_DESKTOP +#ifdef SRV_UPDATER +#error SRV_UPDATER and SRV_DESKTOP are mutually exclusive! +#endif {.app = desktop_srv, .name = "DesktopSrv", .stack_size = 2048, .icon = NULL}, #endif @@ -117,10 +122,28 @@ const FlipperApplication FLIPPER_SERVICES[] = { #ifdef SRV_STORAGE {.app = storage_srv, .name = "StorageSrv", .stack_size = 3072, .icon = NULL}, #endif + +#ifdef SRV_UPDATER +#ifdef SRV_DESKTOP +#error SRV_UPDATER and SRV_DESKTOP are mutually exclusive! +#endif + {.app = updater_srv, .name = "UpdaterSrv", .stack_size = 2048, .icon = NULL}, +#endif }; const size_t FLIPPER_SERVICES_COUNT = sizeof(FLIPPER_SERVICES) / sizeof(FlipperApplication); +const FlipperApplication FLIPPER_SYSTEM_APPS[] = { +#ifdef APP_UPDATER +#ifdef SRV_UPDATER +#error APP_UPDATER and SRV_UPDATER are mutually exclusive! +#endif + {.app = updater_srv, .name = "UpdaterApp", .stack_size = 2048, .icon = NULL}, +#endif +}; + +const size_t FLIPPER_SYSTEM_APPS_COUNT = sizeof(FLIPPER_SERVICES) / sizeof(FlipperApplication); + // Main menu APP const FlipperApplication FLIPPER_APPS[] = { @@ -199,6 +222,10 @@ const FlipperOnStartHook FLIPPER_ON_SYSTEM_START[] = { #ifdef APP_UNIT_TESTS unit_tests_on_system_start, #endif + +#ifdef APP_UPDATER + updater_on_system_start, +#endif }; const size_t FLIPPER_ON_SYSTEM_START_COUNT = @@ -326,4 +353,4 @@ const FlipperApplication FLIPPER_SETTINGS_APPS[] = { }; const size_t FLIPPER_SETTINGS_APPS_COUNT = - sizeof(FLIPPER_SETTINGS_APPS) / sizeof(FlipperApplication); + sizeof(FLIPPER_SETTINGS_APPS) / sizeof(FlipperApplication); \ No newline at end of file diff --git a/applications/applications.h b/applications/applications.h index 962eaa7726a..705dba28d4b 100644 --- a/applications/applications.h +++ b/applications/applications.h @@ -42,6 +42,12 @@ extern const size_t FLIPPER_PLUGINS_COUNT; extern const FlipperApplication FLIPPER_DEBUG_APPS[]; extern const size_t FLIPPER_DEBUG_APPS_COUNT; +/* System apps + * Can only be spawned by loader by name + */ +extern const FlipperApplication FLIPPER_SYSTEM_APPS[]; +extern const size_t FLIPPER_SYSTEM_APPS_COUNT; + /* Seperate scene app holder * Spawned by loader */ @@ -55,4 +61,4 @@ extern const FlipperApplication FLIPPER_ARCHIVE; * Spawned by loader */ extern const FlipperApplication FLIPPER_SETTINGS_APPS[]; -extern const size_t FLIPPER_SETTINGS_APPS_COUNT; \ No newline at end of file +extern const size_t FLIPPER_SETTINGS_APPS_COUNT; diff --git a/applications/applications.mk b/applications/applications.mk index 954ec647797..c6295fd8035 100644 --- a/applications/applications.mk +++ b/applications/applications.mk @@ -5,6 +5,16 @@ CFLAGS += -I$(APP_DIR) C_SOURCES += $(shell find $(APP_DIR) -name "*.c") CPP_SOURCES += $(shell find $(APP_DIR) -name "*.cpp") +RAM_EXEC ?= 0 +ifeq ($(RAM_EXEC), 1) +APP_RELEASE = 0 +SRV_GUI = 1 +SRV_INPUT = 1 +SRV_NOTIFICATION = 1 +SRV_STORAGE = 1 +SRV_UPDATER = 1 +APP_UPDATER = 0 +endif APP_RELEASE ?= 1 ifeq ($(APP_RELEASE), 1) @@ -18,13 +28,13 @@ SRV_INPUT = 1 SRV_LOADER = 1 SRV_NOTIFICATION = 1 SRV_POWER = 1 -SRV_RPC = 1 +SRV_RPC = 1 SRV_STORAGE = 1 # Apps SRV_DESKTOP = 1 APP_ARCHIVE = 1 -APP_GPIO = 1 +APP_GPIO = 1 APP_IBUTTON = 1 APP_INFRARED = 1 APP_LF_RFID = 1 @@ -32,6 +42,7 @@ APP_NFC = 1 APP_SUBGHZ = 1 APP_ABOUT = 1 APP_PASSPORT = 1 +APP_UPDATER = 1 # Plugins APP_MUSIC_PLAYER = 1 @@ -223,6 +234,14 @@ CFLAGS += -DAPP_IBUTTON SRV_GUI = 1 endif +APP_UPDATER ?= 0 +ifeq ($(APP_UPDATER), 1) +CFLAGS += -DAPP_UPDATER +SRV_GUI = 1 +SRV_STORAGE = 1 +SRV_NOTIFICATION = 1 +SRV_INPUT = 1 +endif # Services # that will start with OS @@ -245,6 +264,14 @@ SRV_GUI = 1 endif +SRV_UPDATER ?= 0 +ifeq ($(SRV_UPDATER), 1) +CFLAGS += -DSRV_UPDATER +SRV_STORAGE = 1 +SRV_GUI = 1 +endif + + SRV_DOLPHIN ?= 0 ifeq ($(SRV_DOLPHIN), 1) CFLAGS += -DSRV_DOLPHIN diff --git a/applications/archive/helpers/archive_browser.h b/applications/archive/helpers/archive_browser.h index 968564cdf3f..593a9be0db7 100644 --- a/applications/archive/helpers/archive_browser.h +++ b/applications/archive/helpers/archive_browser.h @@ -25,6 +25,7 @@ static const char* known_ext[] = { [ArchiveFileTypeInfrared] = ".ir", [ArchiveFileTypeBadUsb] = ".txt", [ArchiveFileTypeU2f] = "?", + [ArchiveFileTypeUpdateManifest] = ".fuf", [ArchiveFileTypeFolder] = "?", [ArchiveFileTypeUnknown] = "*", }; diff --git a/applications/archive/helpers/archive_files.h b/applications/archive/helpers/archive_files.h index e6f6eaa1a91..b65f96aefd5 100644 --- a/applications/archive/helpers/archive_files.h +++ b/applications/archive/helpers/archive_files.h @@ -10,6 +10,7 @@ typedef enum { ArchiveFileTypeInfrared, ArchiveFileTypeBadUsb, ArchiveFileTypeU2f, + ArchiveFileTypeUpdateManifest, ArchiveFileTypeFolder, ArchiveFileTypeUnknown, ArchiveFileTypeLoading, diff --git a/applications/archive/scenes/archive_scene_browser.c b/applications/archive/scenes/archive_scene_browser.c index 9410062dd4c..92a493040a8 100644 --- a/applications/archive/scenes/archive_scene_browser.c +++ b/applications/archive/scenes/archive_scene_browser.c @@ -15,6 +15,7 @@ static const char* flipper_app_name[] = { [ArchiveFileTypeInfrared] = "Infrared", [ArchiveFileTypeBadUsb] = "Bad USB", [ArchiveFileTypeU2f] = "U2F", + [ArchiveFileTypeUpdateManifest] = "UpdaterApp", }; static void archive_run_in_app(ArchiveBrowserView* browser, ArchiveFile_t* selected) { diff --git a/applications/archive/views/archive_browser_view.c b/applications/archive/views/archive_browser_view.c index cd63c4d7402..34588f33a21 100644 --- a/applications/archive/views/archive_browser_view.c +++ b/applications/archive/views/archive_browser_view.c @@ -12,7 +12,8 @@ static const char* ArchiveTabNames[] = { [ArchiveTabInfrared] = "Infrared", [ArchiveTabBadUsb] = "Bad USB", [ArchiveTabU2f] = "U2F", - [ArchiveTabBrowser] = "Browser"}; + [ArchiveTabBrowser] = "Browser", +}; static const Icon* ArchiveItemIcons[] = { [ArchiveFileTypeIButton] = &I_ibutt_10px, @@ -22,6 +23,7 @@ static const Icon* ArchiveItemIcons[] = { [ArchiveFileTypeInfrared] = &I_ir_10px, [ArchiveFileTypeBadUsb] = &I_badusb_10px, [ArchiveFileTypeU2f] = &I_u2f_10px, + [ArchiveFileTypeUpdateManifest] = &I_update_10px, [ArchiveFileTypeFolder] = &I_dir_10px, [ArchiveFileTypeUnknown] = &I_unknown_10px, [ArchiveFileTypeLoading] = &I_unknown_10px, // TODO loading icon @@ -374,4 +376,4 @@ void browser_free(ArchiveBrowserView* browser) { view_free(browser->view); free(browser); -} +} \ No newline at end of file diff --git a/applications/bt/bt_cli.c b/applications/bt/bt_cli.c index 50b5c22534e..2469e74ebfe 100644 --- a/applications/bt/bt_cli.c +++ b/applications/bt/bt_cli.c @@ -244,5 +244,7 @@ void bt_on_system_start() { cli_add_command(cli, "bt", CliCommandFlagDefault, bt_cli, NULL); furi_record_close("bt"); furi_record_close("cli"); +#else + UNUSED(bt_cli); #endif -} +} \ No newline at end of file diff --git a/applications/cli/cli.c b/applications/cli/cli.c index 4b36521b157..0453fb66925 100644 --- a/applications/cli/cli.c +++ b/applications/cli/cli.c @@ -95,10 +95,11 @@ void cli_motd() { const Version* firmware_version = furi_hal_version_get_firmware_version(); if(firmware_version) { printf( - "Firmware version: %s %s (%s built on %s)\r\n", + "Firmware version: %s %s (%s%s built on %s)\r\n", version_get_gitbranch(firmware_version), version_get_version(firmware_version), version_get_githash(firmware_version), + version_get_dirty_flag(firmware_version) ? "-dirty" : "", version_get_builddate(firmware_version)); } } diff --git a/applications/cli/cli_commands.c b/applications/cli/cli_commands.c index 53595a08151..58c131600ba 100644 --- a/applications/cli/cli_commands.c +++ b/applications/cli/cli_commands.c @@ -327,6 +327,7 @@ void cli_command_ps(Cli* cli, string_t args, void* context) { void cli_command_free(Cli* cli, string_t args, void* context) { printf("Free heap size: %d\r\n", memmgr_get_free_heap()); + printf("Total heap size: %d\r\n", memmgr_get_total_heap()); printf("Minimum heap size: %d\r\n", memmgr_get_minimum_free_heap()); printf("Maximum heap block: %d\r\n", memmgr_heap_get_max_free_block()); } diff --git a/applications/crypto/crypto_cli.c b/applications/crypto/crypto_cli.c index 60e32b2bde2..7cd9d5ccb17 100644 --- a/applications/crypto/crypto_cli.c +++ b/applications/crypto/crypto_cli.c @@ -276,7 +276,7 @@ void crypto_cli_store_key(Cli* cli, string_t args) { string_clear(key_type); } -void crypto_cli(Cli* cli, string_t args, void* context) { +static void crypto_cli(Cli* cli, string_t args, void* context) { string_t cmd; string_init(cmd); @@ -317,5 +317,7 @@ void crypto_on_system_start() { Cli* cli = furi_record_open("cli"); cli_add_command(cli, "crypto", CliCommandFlagDefault, crypto_cli, NULL); furi_record_close("cli"); +#else + UNUSED(crypto_cli); #endif } diff --git a/applications/desktop/views/desktop_view_debug.c b/applications/desktop/views/desktop_view_debug.c index 4cb8e8ea56d..0aed2adfc27 100644 --- a/applications/desktop/views/desktop_view_debug.c +++ b/applications/desktop/views/desktop_view_debug.c @@ -23,7 +23,7 @@ void desktop_debug_render(Canvas* canvas, void* model) { const Version* ver; char buffer[64]; - static const char* headers[] = {"FW Version info:", "Boot Version info:", "Dolphin info:"}; + static const char* headers[] = {"FW Version info:", "Dolphin info:"}; canvas_set_color(canvas, ColorBlack); canvas_set_font(canvas, FontPrimary); @@ -44,8 +44,7 @@ void desktop_debug_render(Canvas* canvas, void* model) { my_name ? my_name : "Unknown"); canvas_draw_str(canvas, 5, 19 + STATUS_BAR_Y_SHIFT, buffer); - ver = m->screen == DesktopViewStatsBoot ? furi_hal_version_get_bootloader_version() : - furi_hal_version_get_firmware_version(); + ver = furi_hal_version_get_firmware_version(); if(!ver) { canvas_draw_str(canvas, 5, 29 + STATUS_BAR_Y_SHIFT, "No info"); @@ -63,7 +62,8 @@ void desktop_debug_render(Canvas* canvas, void* model) { snprintf( buffer, sizeof(buffer), - "%s [%s]", + "%s%s [%s]", + version_get_dirty_flag(ver) ? "[!] " : "", version_get_githash(ver), version_get_gitbranchnum(ver)); canvas_draw_str(canvas, 5, 39 + STATUS_BAR_Y_SHIFT, buffer); diff --git a/applications/desktop/views/desktop_view_debug.h b/applications/desktop/views/desktop_view_debug.h index fecbb2aae5c..f6af16b2e96 100644 --- a/applications/desktop/views/desktop_view_debug.h +++ b/applications/desktop/views/desktop_view_debug.h @@ -11,7 +11,6 @@ typedef void (*DesktopDebugViewCallback)(DesktopEvent event, void* context); // Debug info typedef enum { DesktopViewStatsFw, - DesktopViewStatsBoot, DesktopViewStatsMeta, DesktopViewStatsTotalCount, } DesktopViewStatsScreens; diff --git a/applications/gui/elements.c b/applications/gui/elements.c index 4fbafbd5fbe..289e4d8e05c 100644 --- a/applications/gui/elements.c +++ b/applications/gui/elements.c @@ -739,4 +739,4 @@ void elements_text_box( } } canvas_set_font(canvas, FontSecondary); -} +} \ No newline at end of file diff --git a/applications/ibutton/ibutton_cli.c b/applications/ibutton/ibutton_cli.c index 243ee36bd3e..c50ec210e8d 100644 --- a/applications/ibutton/ibutton_cli.c +++ b/applications/ibutton/ibutton_cli.c @@ -6,8 +6,8 @@ #include #include -void ibutton_cli(Cli* cli, string_t args, void* context); -void onewire_cli(Cli* cli, string_t args, void* context); +static void ibutton_cli(Cli* cli, string_t args, void* context); +static void onewire_cli(Cli* cli, string_t args, void* context); // app cli function void ibutton_on_system_start() { @@ -16,6 +16,9 @@ void ibutton_on_system_start() { cli_add_command(cli, "ikey", CliCommandFlagDefault, ibutton_cli, cli); cli_add_command(cli, "onewire", CliCommandFlagDefault, onewire_cli, cli); furi_record_close("cli"); +#else + UNUSED(ibutton_cli); + UNUSED(onewire_cli); #endif } @@ -236,7 +239,7 @@ void ibutton_cli_emulate(Cli* cli, string_t args) { ibutton_key_free(key); }; -void ibutton_cli(Cli* cli, string_t args, void* context) { +static void ibutton_cli(Cli* cli, string_t args, void* context) { string_t cmd; string_init(cmd); @@ -264,7 +267,7 @@ void onewire_cli_print_usage() { printf("onewire search\r\n"); }; -void onewire_cli_search(Cli* cli) { +static void onewire_cli_search(Cli* cli) { OneWireHost* onewire = onewire_host_alloc(); uint8_t address[8]; bool done = false; @@ -308,4 +311,4 @@ void onewire_cli(Cli* cli, string_t args, void* context) { } string_clear(cmd); -} +} \ No newline at end of file diff --git a/applications/infrared/cli/infrared_cli.cpp b/applications/infrared/cli/infrared_cli.cpp index 8cda0cd7c64..15de2d852bf 100644 --- a/applications/infrared/cli/infrared_cli.cpp +++ b/applications/infrared/cli/infrared_cli.cpp @@ -192,5 +192,7 @@ extern "C" void infrared_on_system_start() { Cli* cli = (Cli*)furi_record_open("cli"); cli_add_command(cli, "ir", CliCommandFlagDefault, infrared_cli_start_ir, NULL); furi_record_close("cli"); +#else + UNUSED(infrared_cli_start_ir); #endif } diff --git a/applications/infrared/infrared_app_remote_manager.cpp b/applications/infrared/infrared_app_remote_manager.cpp index b2637ccb40c..9fbef84febc 100644 --- a/applications/infrared/infrared_app_remote_manager.cpp +++ b/applications/infrared/infrared_app_remote_manager.cpp @@ -13,7 +13,7 @@ #include #include "infrared_app.h" -static const std::string default_remote_name = "remote"; +static const char* default_remote_name = "remote"; std::string InfraredAppRemoteManager::make_full_name( const std::string& path, diff --git a/applications/input/input_cli.c b/applications/input/input_cli.c index c244ece5ec5..eb510f6c7fe 100644 --- a/applications/input/input_cli.c +++ b/applications/input/input_cli.c @@ -50,7 +50,7 @@ static void input_cli_send_print_usage() { printf("\t\t \t - one of 'press', 'release', 'short', 'long'\r\n"); } -void input_cli_send(Cli* cli, string_t args, Input* input) { +static void input_cli_send(Cli* cli, string_t args, Input* input) { InputEvent event; string_t key_str; string_init(key_str); diff --git a/applications/lfrfid/lfrfid_cli.cpp b/applications/lfrfid/lfrfid_cli.cpp index 18784876fe3..235dd68fc60 100644 --- a/applications/lfrfid/lfrfid_cli.cpp +++ b/applications/lfrfid/lfrfid_cli.cpp @@ -7,7 +7,7 @@ #include "helpers/rfid_reader.h" #include "helpers/rfid_timer_emulator.h" -void lfrfid_cli(Cli* cli, string_t args, void* context); +static void lfrfid_cli(Cli* cli, string_t args, void* context); // app cli function extern "C" void lfrfid_on_system_start() { @@ -15,6 +15,8 @@ extern "C" void lfrfid_on_system_start() { Cli* cli = static_cast(furi_record_open("cli")); cli_add_command(cli, "rfid", CliCommandFlagDefault, lfrfid_cli, NULL); furi_record_close("cli"); +#else + UNUSED(lfrfid_cli); #endif } @@ -29,7 +31,7 @@ void lfrfid_cli_print_usage() { printf("\t are hex-formatted\r\n"); }; -bool lfrfid_cli_get_key_type(string_t data, LfrfidKeyType* type) { +static bool lfrfid_cli_get_key_type(string_t data, LfrfidKeyType* type) { bool result = false; if(string_cmp_str(data, "EM4100") == 0 || string_cmp_str(data, "EM-Marin") == 0) { @@ -46,7 +48,7 @@ bool lfrfid_cli_get_key_type(string_t data, LfrfidKeyType* type) { return result; } -void lfrfid_cli_read(Cli* cli, string_t args) { +static void lfrfid_cli_read(Cli* cli, string_t args) { RfidReader reader; string_t type_string; string_init(type_string); @@ -97,12 +99,12 @@ void lfrfid_cli_read(Cli* cli, string_t args) { string_clear(type_string); } -void lfrfid_cli_write(Cli* cli, string_t args) { +static void lfrfid_cli_write(Cli* cli, string_t args) { // TODO implement rfid write printf("Not implemented :(\r\n"); } -void lfrfid_cli_emulate(Cli* cli, string_t args) { +static void lfrfid_cli_emulate(Cli* cli, string_t args) { string_t data; string_init(data); RfidTimerEmulator emulator; @@ -144,7 +146,7 @@ void lfrfid_cli_emulate(Cli* cli, string_t args) { string_clear(data); } -void lfrfid_cli(Cli* cli, string_t args, void* context) { +static void lfrfid_cli(Cli* cli, string_t args, void* context) { string_t cmd; string_init(cmd); diff --git a/applications/loader/loader.c b/applications/loader/loader.c index d35fcf646e7..054562a2f6e 100644 --- a/applications/loader/loader.c +++ b/applications/loader/loader.c @@ -65,33 +65,36 @@ static void loader_cli_print_usage() { printf("\topen \t - Open application by name\r\n"); } -const FlipperApplication* loader_find_application_by_name(const char* name) { - const FlipperApplication* application = NULL; - - for(size_t i = 0; i < FLIPPER_APPS_COUNT; i++) { - if(strcmp(name, FLIPPER_APPS[i].name) == 0) { - application = &FLIPPER_APPS[i]; +static FlipperApplication const* loader_find_application_by_name_in_list( + const char* name, + const FlipperApplication* list, + const uint32_t n_apps) { + for(size_t i = 0; i < n_apps; i++) { + if(strcmp(name, list[i].name) == 0) { + return &list[i]; } } + return NULL; +} - for(size_t i = 0; i < FLIPPER_PLUGINS_COUNT; i++) { - if(strcmp(name, FLIPPER_PLUGINS[i].name) == 0) { - application = &FLIPPER_PLUGINS[i]; - } +const FlipperApplication* loader_find_application_by_name(const char* name) { + const FlipperApplication* application = NULL; + application = loader_find_application_by_name_in_list(name, FLIPPER_APPS, FLIPPER_APPS_COUNT); + if(!application) { + application = + loader_find_application_by_name_in_list(name, FLIPPER_PLUGINS, FLIPPER_PLUGINS_COUNT); } - - for(size_t i = 0; i < FLIPPER_SETTINGS_APPS_COUNT; i++) { - if(strcmp(name, FLIPPER_SETTINGS_APPS[i].name) == 0) { - application = &FLIPPER_SETTINGS_APPS[i]; - } + if(!application) { + application = loader_find_application_by_name_in_list( + name, FLIPPER_SETTINGS_APPS, FLIPPER_SETTINGS_APPS_COUNT); } - - if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)) { - for(size_t i = 0; i < FLIPPER_DEBUG_APPS_COUNT; i++) { - if(strcmp(name, FLIPPER_DEBUG_APPS[i].name) == 0) { - application = &FLIPPER_DEBUG_APPS[i]; - } - } + if(!application) { + application = loader_find_application_by_name_in_list( + name, FLIPPER_SYSTEM_APPS, FLIPPER_SYSTEM_APPS_COUNT); + } + if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug) && !application) { + application = loader_find_application_by_name_in_list( + name, FLIPPER_DEBUG_APPS, FLIPPER_DEBUG_APPS_COUNT); } return application; @@ -149,7 +152,7 @@ void loader_cli_list(Cli* cli, string_t args, Loader* instance) { } } -void loader_cli(Cli* cli, string_t args, void* _ctx) { +static void loader_cli(Cli* cli, string_t args, void* _ctx) { furi_assert(_ctx); Loader* instance = _ctx; @@ -290,6 +293,8 @@ static Loader* loader_alloc() { #ifdef SRV_CLI instance->cli = furi_record_open("cli"); cli_add_command(instance->cli, "loader", CliCommandFlagDefault, loader_cli, instance); +#else + UNUSED(loader_cli); #endif instance->loader_thread = osThreadGetId(); @@ -483,4 +488,4 @@ int32_t loader_srv(void* p) { FuriPubSub* loader_get_pubsub(Loader* instance) { return instance->pubsub; -} +} \ No newline at end of file diff --git a/applications/nfc/nfc_cli.c b/applications/nfc/nfc_cli.c index 0dd212a63e1..98024e7daf2 100755 --- a/applications/nfc/nfc_cli.c +++ b/applications/nfc/nfc_cli.c @@ -136,5 +136,7 @@ void nfc_on_system_start() { Cli* cli = furi_record_open("cli"); cli_add_command(cli, "nfc", CliCommandFlagDefault, nfc_cli, NULL); furi_record_close("cli"); +#else + UNUSED(nfc_cli); #endif } diff --git a/applications/power/power_cli.c b/applications/power/power_cli.c index 110318accfa..09e75fa90b6 100644 --- a/applications/power/power_cli.c +++ b/applications/power/power_cli.c @@ -128,5 +128,7 @@ void power_on_system_start() { cli_add_command(cli, "power", CliCommandFlagParallelSafe, power_cli, NULL); furi_record_close("cli"); +#else + UNUSED(power_cli); #endif } diff --git a/applications/power/power_service/power_api.c b/applications/power/power_service/power_api.c index a92bfd002ca..28c23fcff43 100644 --- a/applications/power/power_service/power_api.c +++ b/applications/power/power_service/power_api.c @@ -1,8 +1,7 @@ #include "power_i.h" #include -#include "furi_hal_power.h" -#include "furi_hal_bootloader.h" +#include void power_off(Power* power) { furi_hal_power_off(); @@ -15,9 +14,9 @@ void power_off(Power* power) { void power_reboot(PowerBootMode mode) { if(mode == PowerBootModeNormal) { - furi_hal_bootloader_set_mode(FuriHalBootloaderModeNormal); + furi_hal_rtc_set_boot_mode(FuriHalRtcBootModeNormal); } else if(mode == PowerBootModeDfu) { - furi_hal_bootloader_set_mode(FuriHalBootloaderModeDFU); + furi_hal_rtc_set_boot_mode(FuriHalRtcBootModeDfu); } furi_hal_power_reset(); } diff --git a/applications/rpc/rpc_gui.c b/applications/rpc/rpc_gui.c index 84051bffebc..b67035ac2c8 100644 --- a/applications/rpc/rpc_gui.c +++ b/applications/rpc/rpc_gui.c @@ -69,30 +69,34 @@ static void rpc_system_gui_start_screen_stream_process(const PB_Main* request, v RpcSession* session = rpc_gui->session; furi_assert(session); - furi_assert(!rpc_gui->is_streaming); - rpc_send_and_release_empty(session, request->command_id, PB_CommandStatus_OK); - - rpc_gui->is_streaming = true; - size_t framebuffer_size = gui_get_framebuffer_size(rpc_gui->gui); - // Reusable Frame - rpc_gui->transmit_frame = malloc(sizeof(PB_Main)); - rpc_gui->transmit_frame->which_content = PB_Main_gui_screen_frame_tag; - rpc_gui->transmit_frame->command_status = PB_CommandStatus_OK; - rpc_gui->transmit_frame->content.gui_screen_frame.data = - malloc(PB_BYTES_ARRAY_T_ALLOCSIZE(framebuffer_size)); - rpc_gui->transmit_frame->content.gui_screen_frame.data->size = framebuffer_size; - // Transmission thread for async TX - rpc_gui->transmit_thread = furi_thread_alloc(); - furi_thread_set_name(rpc_gui->transmit_thread, "GuiRpcWorker"); - furi_thread_set_callback( - rpc_gui->transmit_thread, rpc_system_gui_screen_stream_frame_transmit_thread); - furi_thread_set_context(rpc_gui->transmit_thread, rpc_gui); - furi_thread_set_stack_size(rpc_gui->transmit_thread, 1024); - furi_thread_start(rpc_gui->transmit_thread); - // GUI framebuffer callback - gui_add_framebuffer_callback( - rpc_gui->gui, rpc_system_gui_screen_stream_frame_callback, context); + if(rpc_gui->is_streaming) { + rpc_send_and_release_empty( + session, request->command_id, PB_CommandStatus_ERROR_VIRTUAL_DISPLAY_ALREADY_STARTED); + } else { + rpc_send_and_release_empty(session, request->command_id, PB_CommandStatus_OK); + + rpc_gui->is_streaming = true; + size_t framebuffer_size = gui_get_framebuffer_size(rpc_gui->gui); + // Reusable Frame + rpc_gui->transmit_frame = malloc(sizeof(PB_Main)); + rpc_gui->transmit_frame->which_content = PB_Main_gui_screen_frame_tag; + rpc_gui->transmit_frame->command_status = PB_CommandStatus_OK; + rpc_gui->transmit_frame->content.gui_screen_frame.data = + malloc(PB_BYTES_ARRAY_T_ALLOCSIZE(framebuffer_size)); + rpc_gui->transmit_frame->content.gui_screen_frame.data->size = framebuffer_size; + // Transmission thread for async TX + rpc_gui->transmit_thread = furi_thread_alloc(); + furi_thread_set_name(rpc_gui->transmit_thread, "GuiRpcWorker"); + furi_thread_set_callback( + rpc_gui->transmit_thread, rpc_system_gui_screen_stream_frame_transmit_thread); + furi_thread_set_context(rpc_gui->transmit_thread, rpc_gui); + furi_thread_set_stack_size(rpc_gui->transmit_thread, 1024); + furi_thread_start(rpc_gui->transmit_thread); + // GUI framebuffer callback + gui_add_framebuffer_callback( + rpc_gui->gui, rpc_system_gui_screen_stream_frame_callback, context); + } } static void rpc_system_gui_stop_screen_stream_process(const PB_Main* request, void* context) { diff --git a/applications/rpc/rpc_storage.c b/applications/rpc/rpc_storage.c index b70ec4cc45f..e9c13ca304b 100644 --- a/applications/rpc/rpc_storage.c +++ b/applications/rpc/rpc_storage.c @@ -10,10 +10,12 @@ #include "storage/storage.h" #include #include +#include #define RPC_TAG "RPC_STORAGE" #define MAX_NAME_LENGTH 255 -#define MAX_DATA_SIZE 512 + +static const size_t MAX_DATA_SIZE = 512; typedef enum { RpcStorageStateIdle = 0, @@ -185,7 +187,7 @@ static void rpc_system_storage_list_root(const PB_Main* request, void* context) }; furi_assert(COUNT_OF(hard_coded_dirs) < COUNT_OF(response.content.storage_list_response.file)); - for(int i = 0; i < COUNT_OF(hard_coded_dirs); ++i) { + for(uint32_t i = 0; i < COUNT_OF(hard_coded_dirs); ++i) { ++response.content.storage_list_response.file_count; response.content.storage_list_response.file[i].data = NULL; response.content.storage_list_response.file[i].size = 0; @@ -538,6 +540,53 @@ static void rpc_system_storage_rename_process(const PB_Main* request, void* cont rpc_send_and_release_empty(session, request->command_id, status); } +static void rpc_system_storage_backup_create_process(const PB_Main* request, void* context) { + furi_assert(request); + furi_assert(request->which_content == PB_Main_storage_backup_create_request_tag); + + RpcSession* session = (RpcSession*)context; + furi_assert(session); + + PB_Main* response = malloc(sizeof(PB_Main)); + response->command_id = request->command_id; + response->has_next = false; + + Storage* fs_api = furi_record_open("storage"); + + bool backup_ok = + lfs_backup_create(fs_api, request->content.storage_backup_create_request.archive_path); + response->command_status = backup_ok ? PB_CommandStatus_OK : PB_CommandStatus_ERROR; + + furi_record_close("storage"); + + rpc_send_and_release(session, response); + free(response); +} + +static void rpc_system_storage_backup_restore_process(const PB_Main* request, void* context) { + furi_assert(request); + furi_assert(request->which_content == PB_Main_storage_backup_restore_request_tag); + + RpcSession* session = (RpcSession*)context; + furi_assert(session); + + PB_Main* response = malloc(sizeof(PB_Main)); + response->command_id = request->command_id; + response->has_next = false; + response->command_status = PB_CommandStatus_OK; + + Storage* fs_api = furi_record_open("storage"); + + bool backup_ok = + lfs_backup_unpack(fs_api, request->content.storage_backup_restore_request.archive_path); + response->command_status = backup_ok ? PB_CommandStatus_OK : PB_CommandStatus_ERROR; + + furi_record_close("storage"); + + rpc_send_and_release(session, response); + free(response); +} + void* rpc_system_storage_alloc(RpcSession* session) { furi_assert(session); @@ -579,6 +628,12 @@ void* rpc_system_storage_alloc(RpcSession* session) { rpc_handler.message_handler = rpc_system_storage_rename_process; rpc_add_handler(session, PB_Main_storage_rename_request_tag, &rpc_handler); + rpc_handler.message_handler = rpc_system_storage_backup_create_process; + rpc_add_handler(session, PB_Main_storage_backup_create_request_tag, &rpc_handler); + + rpc_handler.message_handler = rpc_system_storage_backup_restore_process; + rpc_add_handler(session, PB_Main_storage_backup_restore_request_tag, &rpc_handler); + return rpc_storage; } diff --git a/applications/rpc/rpc_system.c b/applications/rpc/rpc_system.c index f3a8242ae6f..6ea3b02e4b3 100644 --- a/applications/rpc/rpc_system.c +++ b/applications/rpc/rpc_system.c @@ -3,6 +3,7 @@ #include #include #include +#include #include "rpc_i.h" @@ -242,6 +243,28 @@ static void rpc_system_system_get_power_info_process(const PB_Main* request, voi free(response); } +#ifdef APP_UPDATER +static void rpc_system_system_update_request_process(const PB_Main* request, void* context) { + furi_assert(request); + furi_assert(request->which_content == PB_Main_system_update_request_tag); + + RpcSession* session = (RpcSession*)context; + furi_assert(session); + + bool update_prepare_result = + update_operation_prepare(request->content.system_update_request.update_folder) == + UpdatePrepareResultOK; + + PB_Main* response = malloc(sizeof(PB_Main)); + response->command_id = request->command_id; + response->has_next = false; + response->command_status = update_prepare_result ? PB_CommandStatus_OK : + PB_CommandStatus_ERROR_INVALID_PARAMETERS; + rpc_send_and_release(session, response); + free(response); +} +#endif + void* rpc_system_system_alloc(RpcSession* session) { RpcHandler rpc_handler = { .message_handler = NULL, @@ -276,5 +299,10 @@ void* rpc_system_system_alloc(RpcSession* session) { rpc_handler.message_handler = rpc_system_system_get_power_info_process; rpc_add_handler(session, PB_Main_system_power_info_request_tag, &rpc_handler); +#ifdef APP_UPDATER + rpc_handler.message_handler = rpc_system_system_update_request_process; + rpc_add_handler(session, PB_Main_system_update_request_tag, &rpc_handler); +#endif + return NULL; -} +} \ No newline at end of file diff --git a/applications/storage/storage.c b/applications/storage/storage.c index 4aa5f10573d..078a136cddf 100644 --- a/applications/storage/storage.c +++ b/applications/storage/storage.c @@ -40,7 +40,9 @@ Storage* storage_app_alloc() { storage_data_init(&app->storage[i]); } +#ifndef FURI_RAM_EXEC storage_int_init(&app->storage[ST_INT]); +#endif storage_ext_init(&app->storage[ST_EXT]); // sd icon gui diff --git a/applications/storage/storage.h b/applications/storage/storage.h index d5eb87d3650..bb71447b2d5 100644 --- a/applications/storage/storage.h +++ b/applications/storage/storage.h @@ -263,6 +263,22 @@ FS_Error storage_sd_info(Storage* api, SDInfo* info); */ FS_Error storage_sd_status(Storage* api); +/******************* Internal LFS Functions *******************/ + +/** Backs up internal storage to a tar archive + * @param api pointer to the api + * @param dstmane destination archive path + * @return FS_Error operation result + */ +FS_Error storage_int_backup(Storage* api, const char* dstname); + +/** Restores internal storage from a tar archive + * @param api pointer to the api + * @param dstmane archive path + * @return FS_Error operation result + */ +FS_Error storage_int_restore(Storage* api, const char* dstname); + /***************** Simplified Functions ******************/ /** @@ -309,4 +325,4 @@ void storage_get_next_filename( #ifdef __cplusplus } -#endif +#endif \ No newline at end of file diff --git a/applications/storage/storage_cli.c b/applications/storage/storage_cli.c index 07fa638f0ae..17bffa97a9c 100644 --- a/applications/storage/storage_cli.c +++ b/applications/storage/storage_cli.c @@ -521,7 +521,7 @@ void storage_cli(Cli* cli, string_t args, void* context) { string_clear(cmd); } -void storage_cli_factory_reset(Cli* cli, string_t args, void* context) { +static void storage_cli_factory_reset(Cli* cli, string_t args, void* context) { printf("All data will be lost. Are you sure (y/n)?\r\n"); char c = cli_getc(cli); if(c == 'y' || c == 'Y') { @@ -540,5 +540,7 @@ void storage_on_system_start() { cli_add_command( cli, "factory_reset", CliCommandFlagParallelSafe, storage_cli_factory_reset, NULL); furi_record_close("cli"); +#else + UNUSED(storage_cli_factory_reset); #endif } diff --git a/applications/storage/storage_internal_api.c b/applications/storage/storage_internal_api.c new file mode 100644 index 00000000000..754ae0dd09b --- /dev/null +++ b/applications/storage/storage_internal_api.c @@ -0,0 +1,22 @@ +#include +#include +#include "storage.h" +#include + +#define INT_PATH "/int" + +FS_Error storage_int_backup(Storage* api, const char* dstname) { + TarArchive* archive = tar_archive_alloc(api); + bool success = tar_archive_open(archive, dstname, TAR_OPEN_MODE_WRITE) && + tar_archive_add_dir(archive, INT_PATH, "") && tar_archive_finalize(archive); + tar_archive_free(archive); + return success ? FSE_OK : FSE_INTERNAL; +} + +FS_Error storage_int_restore(Storage* api, const char* srcname) { + TarArchive* archive = tar_archive_alloc(api); + bool success = tar_archive_open(archive, srcname, TAR_OPEN_MODE_READ) && + tar_archive_unpack_to(archive, INT_PATH); + tar_archive_free(archive); + return success ? FSE_OK : FSE_INTERNAL; +} \ No newline at end of file diff --git a/applications/storage/storage_processing.c b/applications/storage/storage_processing.c index bb1ac9c303e..6120a345bbf 100644 --- a/applications/storage/storage_processing.c +++ b/applications/storage/storage_processing.c @@ -20,7 +20,11 @@ static StorageData* storage_get_storage_by_type(Storage* app, StorageType type) } static bool storage_type_is_not_valid(StorageType type) { +#ifdef FURI_RAM_EXEC + return type != ST_EXT; +#else return type >= ST_ERROR; +#endif } static StorageData* get_storage_by_file(File* file, StorageData* storages) { diff --git a/applications/storage/storages/storage_ext.c b/applications/storage/storages/storage_ext.c index 8a3d21ca428..4ef9a8eae97 100644 --- a/applications/storage/storages/storage_ext.c +++ b/applications/storage/storages/storage_ext.c @@ -54,10 +54,12 @@ static bool sd_mount_card(StorageData* storage, bool notify) { SDError status = f_mount(sd_data->fs, sd_data->path, 1); if(status == FR_OK || status == FR_NO_FILESYSTEM) { +#ifndef FURI_RAM_EXEC FATFS* fs; uint32_t free_clusters; status = f_getfree(sd_data->path, &free_clusters, &fs); +#endif if(status == FR_OK || status == FR_NO_FILESYSTEM) { result = true; @@ -110,6 +112,9 @@ FS_Error sd_unmount_card(StorageData* storage) { } FS_Error sd_format_card(StorageData* storage) { +#ifdef FURI_RAM_EXEC + return FSE_NOT_READY; +#else uint8_t* work_area; SDData* sd_data = storage->data; SDError error; @@ -135,11 +140,14 @@ FS_Error sd_format_card(StorageData* storage) { storage_data_unlock(storage); return storage_ext_parse_error(error); +#endif } FS_Error sd_card_info(StorageData* storage, SDInfo* sd_info) { +#ifndef FURI_RAM_EXEC uint32_t free_clusters, free_sectors, total_sectors; FATFS* fs; +#endif SDData* sd_data = storage->data; SDError error; @@ -150,20 +158,32 @@ FS_Error sd_card_info(StorageData* storage, SDInfo* sd_info) { storage_data_lock(storage); error = f_getlabel(sd_data->path, sd_info->label, NULL); if(error == FR_OK) { +#ifndef FURI_RAM_EXEC error = f_getfree(sd_data->path, &free_clusters, &fs); +#endif } storage_data_unlock(storage); if(error == FR_OK) { // calculate size +#ifndef FURI_RAM_EXEC total_sectors = (fs->n_fatent - 2) * fs->csize; free_sectors = free_clusters * fs->csize; +#endif uint16_t sector_size = _MAX_SS; #if _MAX_SS != _MIN_SS sector_size = fs->ssize; #endif +#ifdef FURI_RAM_EXEC + sd_info->fs_type = 0; + sd_info->kb_total = 0; + sd_info->kb_free = 0; + sd_info->cluster_size = 512; + sd_info->sector_size = sector_size; +#else + sd_info->fs_type = fs->fs_type; switch(fs->fs_type) { case FS_FAT12: sd_info->fs_type = FST_FAT12; @@ -177,7 +197,6 @@ FS_Error sd_card_info(StorageData* storage, SDInfo* sd_info) { case FS_EXFAT: sd_info->fs_type = FST_EXFAT; break; - default: sd_info->fs_type = FST_UNKNOWN; break; @@ -187,6 +206,7 @@ FS_Error sd_card_info(StorageData* storage, SDInfo* sd_info) { sd_info->kb_free = free_sectors / 1024 * sector_size; sd_info->cluster_size = fs->csize; sd_info->sector_size = sector_size; +#endif } return storage_ext_parse_error(error); @@ -328,12 +348,16 @@ static uint16_t static uint16_t storage_ext_file_write(void* ctx, File* file, const void* buff, uint16_t const bytes_to_write) { +#ifdef FURI_RAM_EXEC + return FSE_NOT_READY; +#else StorageData* storage = ctx; SDFile* file_data = storage_get_storage_file_data(file, storage); uint16_t bytes_written = 0; file->internal_error_id = f_write(file_data, buff, bytes_to_write, &bytes_written); file->error_id = storage_ext_parse_error(file->internal_error_id); return bytes_written; +#endif } static bool @@ -364,21 +388,29 @@ static uint64_t storage_ext_file_tell(void* ctx, File* file) { } static bool storage_ext_file_truncate(void* ctx, File* file) { +#ifdef FURI_RAM_EXEC + return FSE_NOT_READY; +#else StorageData* storage = ctx; SDFile* file_data = storage_get_storage_file_data(file, storage); file->internal_error_id = f_truncate(file_data); file->error_id = storage_ext_parse_error(file->internal_error_id); return (file->error_id == FSE_OK); +#endif } static bool storage_ext_file_sync(void* ctx, File* file) { +#ifdef FURI_RAM_EXEC + return FSE_NOT_READY; +#else StorageData* storage = ctx; SDFile* file_data = storage_get_storage_file_data(file, storage); file->internal_error_id = f_sync(file_data); file->error_id = storage_ext_parse_error(file->internal_error_id); return (file->error_id == FSE_OK); +#endif } static uint64_t storage_ext_file_size(void* ctx, File* file) { @@ -479,13 +511,21 @@ static FS_Error storage_ext_common_stat(void* ctx, const char* path, FileInfo* f } static FS_Error storage_ext_common_remove(void* ctx, const char* path) { +#ifdef FURI_RAM_EXEC + return FSE_NOT_READY; +#else SDError result = f_unlink(path); return storage_ext_parse_error(result); +#endif } static FS_Error storage_ext_common_mkdir(void* ctx, const char* path) { +#ifdef FURI_RAM_EXEC + return FSE_NOT_READY; +#else SDError result = f_mkdir(path); return storage_ext_parse_error(result); +#endif } static FS_Error storage_ext_common_fs_info( @@ -493,6 +533,9 @@ static FS_Error storage_ext_common_fs_info( const char* fs_path, uint64_t* total_space, uint64_t* free_space) { +#ifdef FURI_RAM_EXEC + return FSE_NOT_READY; +#else StorageData* storage = ctx; SDData* sd_data = storage->data; @@ -519,6 +562,7 @@ static FS_Error storage_ext_common_fs_info( } return storage_ext_parse_error(fresult); +#endif } /******************* Init Storage *******************/ @@ -566,4 +610,4 @@ void storage_ext_init(StorageData* storage) { // do not notify on first launch, notifications app is waiting for our thread to read settings storage_ext_tick_internal(storage, false); -} +} \ No newline at end of file diff --git a/applications/subghz/subghz_cli.c b/applications/subghz/subghz_cli.c index ad2f40315b1..143016a1955 100644 --- a/applications/subghz/subghz_cli.c +++ b/applications/subghz/subghz_cli.c @@ -571,7 +571,7 @@ static void subghz_cli_command_chat(Cli* cli, string_t args) { printf("\r\nExit chat\r\n"); } -void subghz_cli_command(Cli* cli, string_t args, void* context) { +static void subghz_cli_command(Cli* cli, string_t args, void* context) { string_t cmd; string_init(cmd); @@ -630,5 +630,7 @@ void subghz_on_system_start() { cli_add_command(cli, "subghz", CliCommandFlagDefault, subghz_cli_command, NULL); furi_record_close("cli"); +#else + UNUSED(subghz_cli_command); #endif } diff --git a/applications/updater/cli/updater_cli.c b/applications/updater/cli/updater_cli.c new file mode 100644 index 00000000000..aa08bc61391 --- /dev/null +++ b/applications/updater/cli/updater_cli.c @@ -0,0 +1,134 @@ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +typedef void (*cmd_handler)(string_t args); +typedef struct { + const char* command; + const cmd_handler handler; +} CliSubcommand; + +static void updater_cli_install(string_t manifest_path) { + printf("Verifying update package at '%s'\r\n", string_get_cstr(manifest_path)); + + UpdatePrepareResult result = update_operation_prepare(string_get_cstr(manifest_path)); + if(result != UpdatePrepareResultOK) { + printf( + "Error: %s. Stopping update.\r\n", + update_operation_describe_preparation_result(result)); + return; + } + printf("OK.\r\nRestarting to apply update. BRB\r\n"); + osDelay(100); + furi_hal_power_reset(); +} + +static void updater_cli_backup(string_t args) { + printf("Backup /int to '%s'\r\n", string_get_cstr(args)); + Storage* storage = furi_record_open("storage"); + bool success = lfs_backup_create(storage, string_get_cstr(args)); + furi_record_close("storage"); + printf("Result: %s\r\n", success ? "OK" : "FAIL"); +} + +static void updater_cli_restore(string_t args) { + printf("Restore /int from '%s'\r\n", string_get_cstr(args)); + Storage* storage = furi_record_open("storage"); + bool success = lfs_backup_unpack(storage, string_get_cstr(args)); + furi_record_close("storage"); + printf("Result: %s\r\n", success ? "OK" : "FAIL"); +} + +static void updater_cli_help(string_t args) { + UNUSED(args); + printf("Commands:\r\n" + "\tinstall /ext/update/PACKAGE/update.fuf - verify & apply update package\r\n" + "\tbackup /ext/path/to/backup.tar - create internal storage backup\r\n" + "\trestore /ext/path/to/backup.tar - restore internal storage backup\r\n"); +} + +static const CliSubcommand update_cli_subcommands[] = { + {.command = "install", .handler = updater_cli_install}, + {.command = "backup", .handler = updater_cli_backup}, + {.command = "restore", .handler = updater_cli_restore}, + {.command = "help", .handler = updater_cli_help}, +}; + +static void updater_cli_ep(Cli* cli, string_t args, void* context) { + string_t subcommand; + string_init(subcommand); + if(!args_read_string_and_trim(args, subcommand) || string_empty_p(args)) { + updater_cli_help(args); + string_clear(subcommand); + return; + } + for(size_t idx = 0; idx < COUNT_OF(update_cli_subcommands); ++idx) { + const CliSubcommand* subcmd_def = &update_cli_subcommands[idx]; + if(string_cmp_str(subcommand, subcmd_def->command) == 0) { + string_clear(subcommand); + subcmd_def->handler(args); + return; + } + } + string_clear(subcommand); + updater_cli_help(args); +} + +static int32_t updater_spawner_thread_worker(void* arg) { + Loader* loader = furi_record_open("loader"); + loader_start(loader, "UpdaterApp", NULL); + furi_record_close("loader"); + return 0; +} + +static void updater_spawner_thread_cleanup(FuriThreadState state, void* context) { + FuriThread* thread = context; + if(state == FuriThreadStateStopped) { + furi_thread_free(thread); + } +} + +static void updater_start_app() { + FuriHalRtcBootMode mode = furi_hal_rtc_get_boot_mode(); + if((mode != FuriHalRtcBootModePreUpdate) && (mode != FuriHalRtcBootModePostUpdate)) { + return; + } + + /* We need to spawn a separate thread, because these callbacks are executed + * inside loader process, at startup. + * So, accessing its record would cause a deadlock + */ + FuriThread* thread = furi_thread_alloc(); + + furi_thread_set_name(thread, "UpdateAppSpawner"); + furi_thread_set_stack_size(thread, 768); + furi_thread_set_callback(thread, updater_spawner_thread_worker); + furi_thread_set_state_callback(thread, updater_spawner_thread_cleanup); + furi_thread_set_state_context(thread, thread); + furi_thread_start(thread); +} + +void updater_on_system_start() { +#ifdef SRV_CLI + Cli* cli = (Cli*)furi_record_open("cli"); + cli_add_command(cli, "update", CliCommandFlagDefault, updater_cli_ep, NULL); + furi_record_close("cli"); +#else + UNUSED(updater_cli_ep); +#endif +#ifndef FURI_RAM_EXEC + updater_start_app(); +#else + UNUSED(updater_start_app); +#endif +} diff --git a/applications/updater/scenes/updater_scene.c b/applications/updater/scenes/updater_scene.c new file mode 100644 index 00000000000..afc5d08ac76 --- /dev/null +++ b/applications/updater/scenes/updater_scene.c @@ -0,0 +1,30 @@ +#include "updater_scene.h" + +// Generate scene on_enter handlers array +#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_enter, +void (*const updater_on_enter_handlers[])(void*) = { +#include "updater_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 updater_on_event_handlers[])(void* context, SceneManagerEvent event) = { +#include "updater_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 updater_on_exit_handlers[])(void* context) = { +#include "updater_scene_config.h" +}; +#undef ADD_SCENE + +// Initialize scene handlers configuration structure +const SceneManagerHandlers updater_scene_handlers = { + .on_enter_handlers = updater_on_enter_handlers, + .on_event_handlers = updater_on_event_handlers, + .on_exit_handlers = updater_on_exit_handlers, + .scene_num = UpdaterSceneNum, +}; diff --git a/applications/updater/scenes/updater_scene.h b/applications/updater/scenes/updater_scene.h new file mode 100644 index 00000000000..1c2dba27a04 --- /dev/null +++ b/applications/updater/scenes/updater_scene.h @@ -0,0 +1,29 @@ +#pragma once + +#include + +// Generate scene id and total number +#define ADD_SCENE(prefix, name, id) UpdaterScene##id, +typedef enum { +#include "updater_scene_config.h" + UpdaterSceneNum, +} UpdaterScene; +#undef ADD_SCENE + +extern const SceneManagerHandlers updater_scene_handlers; + +// Generate scene on_enter handlers declaration +#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_enter(void*); +#include "updater_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 "updater_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 "updater_scene_config.h" +#undef ADD_SCENE diff --git a/applications/updater/scenes/updater_scene_config.h b/applications/updater/scenes/updater_scene_config.h new file mode 100644 index 00000000000..d2441c597f9 --- /dev/null +++ b/applications/updater/scenes/updater_scene_config.h @@ -0,0 +1,5 @@ +ADD_SCENE(updater, main, Main) +#ifndef FURI_RAM_EXEC +ADD_SCENE(updater, loadcfg, LoadCfg) +ADD_SCENE(updater, error, Error) +#endif \ No newline at end of file diff --git a/applications/updater/scenes/updater_scene_error.c b/applications/updater/scenes/updater_scene_error.c new file mode 100644 index 00000000000..362c471a681 --- /dev/null +++ b/applications/updater/scenes/updater_scene_error.c @@ -0,0 +1,65 @@ +#include "updater/updater_i.h" +#include "updater_scene.h" +#include + +void updater_scene_error_callback(GuiButtonType result, InputType type, void* context) { + furi_assert(context); + Updater* updater = context; + if(type != InputTypeShort) { + return; + } + + if(result == GuiButtonTypeLeft) { + view_dispatcher_send_custom_event( + updater->view_dispatcher, UpdaterCustomEventCancelUpdate); + } +} + +void updater_scene_error_on_enter(void* context) { + Updater* updater = (Updater*)context; + + widget_add_button_element( + updater->widget, GuiButtonTypeLeft, "Exit", updater_scene_error_callback, updater); + + widget_add_string_multiline_element( + updater->widget, 64, 13, AlignCenter, AlignCenter, FontPrimary, "Error"); + + widget_add_string_multiline_element( + updater->widget, + 64, + 33, + AlignCenter, + AlignCenter, + FontPrimary, + update_operation_describe_preparation_result(updater->preparation_result)); + + view_dispatcher_switch_to_view(updater->view_dispatcher, UpdaterViewWidget); +} + +bool updater_scene_error_on_event(void* context, SceneManagerEvent event) { + Updater* updater = (Updater*)context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeBack) { + view_dispatcher_stop(updater->view_dispatcher); + consumed = true; + } else if(event.type == SceneManagerEventTypeCustom) { + switch(event.event) { + case UpdaterCustomEventCancelUpdate: + view_dispatcher_stop(updater->view_dispatcher); + consumed = true; + break; + default: + break; + } + } + + return consumed; +} + +void updater_scene_error_on_exit(void* context) { + Updater* updater = (Updater*)context; + + widget_reset(updater->widget); + free(updater->pending_update); +} diff --git a/applications/updater/scenes/updater_scene_loadcfg.c b/applications/updater/scenes/updater_scene_loadcfg.c new file mode 100644 index 00000000000..78423b071a5 --- /dev/null +++ b/applications/updater/scenes/updater_scene_loadcfg.c @@ -0,0 +1,105 @@ +#include "updater/updater_i.h" +#include "updater_scene.h" + +#include +#include + +void updater_scene_loadcfg_apply_callback(GuiButtonType result, InputType type, void* context) { + furi_assert(context); + Updater* updater = context; + if(type != InputTypeShort) { + return; + } + + if(result == GuiButtonTypeRight) { + view_dispatcher_send_custom_event(updater->view_dispatcher, UpdaterCustomEventStartUpdate); + } else if(result == GuiButtonTypeLeft) { + view_dispatcher_send_custom_event( + updater->view_dispatcher, UpdaterCustomEventCancelUpdate); + } +} + +void updater_scene_loadcfg_on_enter(void* context) { + Updater* updater = (Updater*)context; + UpdaterManifestProcessingState* pending_upd = updater->pending_update = + malloc(sizeof(UpdaterManifestProcessingState)); + pending_upd->manifest = update_manifest_alloc(); + + if(update_manifest_init(pending_upd->manifest, string_get_cstr(updater->startup_arg))) { + widget_add_string_element( + updater->widget, 64, 12, AlignCenter, AlignCenter, FontPrimary, "Update"); + + widget_add_string_multiline_element( + updater->widget, + 64, + 32, + AlignCenter, + AlignCenter, + FontSecondary, + string_get_cstr(pending_upd->manifest->version)); + + widget_add_button_element( + updater->widget, + GuiButtonTypeRight, + "Install", + updater_scene_loadcfg_apply_callback, + updater); + } else { + widget_add_string_element( + updater->widget, 64, 24, AlignCenter, AlignCenter, FontPrimary, "Invalid manifest"); + } + + widget_add_button_element( + updater->widget, + GuiButtonTypeLeft, + "Cancel", + updater_scene_loadcfg_apply_callback, + updater); + + view_dispatcher_switch_to_view(updater->view_dispatcher, UpdaterViewWidget); +} + +bool updater_scene_loadcfg_on_event(void* context, SceneManagerEvent event) { + Updater* updater = (Updater*)context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeBack) { + view_dispatcher_stop(updater->view_dispatcher); + consumed = true; + } else if(event.type == SceneManagerEventTypeCustom) { + switch(event.event) { + case UpdaterCustomEventStartUpdate: + updater->preparation_result = + update_operation_prepare(string_get_cstr(updater->startup_arg)); + if(updater->preparation_result == UpdatePrepareResultOK) { + furi_hal_power_reset(); + } else { +#ifndef FURI_RAM_EXEC + scene_manager_next_scene(updater->scene_manager, UpdaterSceneError); +#endif + } + consumed = true; + break; + case UpdaterCustomEventCancelUpdate: + view_dispatcher_stop(updater->view_dispatcher); + consumed = true; + break; + default: + break; + } + } + + return consumed; +} + +void updater_scene_loadcfg_on_exit(void* context) { + Updater* updater = (Updater*)context; + + if(updater->pending_update) { + update_manifest_free(updater->pending_update->manifest); + string_clear(updater->pending_update->message); + } + + widget_reset(updater->widget); + free(updater->pending_update); +} \ No newline at end of file diff --git a/applications/updater/scenes/updater_scene_main.c b/applications/updater/scenes/updater_scene_main.c new file mode 100644 index 00000000000..d7b28a9db5d --- /dev/null +++ b/applications/updater/scenes/updater_scene_main.c @@ -0,0 +1,106 @@ +#include +#include +#include +#include + +#include "updater/updater_i.h" +#include "updater/views/updater_main.h" +#include "updater_scene.h" + +static void sd_mount_callback(const void* message, void* context) { + Updater* updater = context; + const StorageEvent* new_event = message; + + switch(new_event->type) { + case StorageEventTypeCardMount: + view_dispatcher_send_custom_event(updater->view_dispatcher, UpdaterCustomEventStartUpdate); + break; + case StorageEventTypeCardUnmount: + view_dispatcher_send_custom_event(updater->view_dispatcher, UpdaterCustomEventSdUnmounted); + break; + default: + break; + } +} + +void updater_scene_main_on_enter(void* context) { + Updater* updater = (Updater*)context; + UpdaterMainView* main_view = updater->main_view; + + FuriPubSubSubscription* sub = + furi_pubsub_subscribe(storage_get_pubsub(updater->storage), &sd_mount_callback, updater); + updater_main_set_storage_pubsub(main_view, sub); + + /* FIXME: there's a misbehavior in storage subsystem. If we produce heavy load on it before it + * fires an SD card event, it'll never do that until the load is lifted. Meanwhile SD card icon + * will be missing from UI, however, /ext will be fully operational. So, until it's fixed, this + * should remain commented out. */ + // If (somehow) we started after SD card is mounted, initiate update immediately + //if(storage_sd_status(updater->storage) == FSE_OK) { + // view_dispatcher_send_custom_event(updater->view_dispatcher, UpdaterCustomEventStartUpdate); + //} + + updater_main_set_view_dispatcher(main_view, updater->view_dispatcher); + view_dispatcher_switch_to_view(updater->view_dispatcher, UpdaterViewMain); +} + +static void updater_scene_restart_to_postupdate() { + furi_hal_rtc_set_boot_mode(FuriHalRtcBootModePostUpdate); + furi_hal_power_reset(); +} + +bool updater_scene_main_on_event(void* context, SceneManagerEvent event) { + Updater* updater = (Updater*)context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeTick) { + if(!update_task_is_running(updater->update_task)) { + if(updater->idle_ticks++ >= (UPDATE_DELAY_OPERATION_ERROR / UPDATER_APP_TICK)) { + updater_scene_restart_to_postupdate(); + } + } else { + updater->idle_ticks = 0; + } + } else if(event.type == SceneManagerEventTypeCustom) { + switch(event.event) { + case UpdaterCustomEventStartUpdate: + if(!update_task_is_running(updater->update_task) && + update_task_init(updater->update_task)) { + update_task_start(updater->update_task); + } + consumed = true; + break; + + case UpdaterCustomEventRetryUpdate: + if(!update_task_is_running(updater->update_task) && + (update_task_get_state(updater->update_task)->stage != UpdateTaskStageComplete)) + update_task_start(updater->update_task); + consumed = true; + break; + + case UpdaterCustomEventCancelUpdate: + if(!update_task_is_running(updater->update_task)) { + updater_scene_restart_to_postupdate(); + } + consumed = true; + break; + + case UpdaterCustomEventSdUnmounted: + // TODO: error out, stop worker (it's probably dead actually) + break; + default: + break; + } + } + + return consumed; +} + +void updater_scene_main_on_exit(void* context) { + Updater* updater = (Updater*)context; + + furi_pubsub_unsubscribe( + storage_get_pubsub(updater->storage), updater_main_get_storage_pubsub(updater->main_view)); + + scene_manager_set_scene_state(updater->scene_manager, UpdaterSceneMain, 0); +} \ No newline at end of file diff --git a/applications/updater/updater.c b/applications/updater/updater.c new file mode 100644 index 00000000000..dbad239b0f1 --- /dev/null +++ b/applications/updater/updater.c @@ -0,0 +1,132 @@ +#include "scenes/updater_scene.h" +#include "updater_i.h" + +#include +#include +#include +#include +#include +#include + +static bool updater_custom_event_callback(void* context, uint32_t event) { + furi_assert(context); + Updater* updater = (Updater*)context; + return scene_manager_handle_custom_event(updater->scene_manager, event); +} + +static void updater_tick_event_callback(void* context) { + furi_assert(context); + Updater* app = context; + scene_manager_handle_tick_event(app->scene_manager); +} + +static bool updater_back_event_callback(void* context) { + furi_assert(context); + Updater* updater = (Updater*)context; + return scene_manager_handle_back_event(updater->scene_manager); +} + +static void status_update_cb( + const char* message, + const uint8_t progress, + const uint8_t idx_stage, + const uint8_t total_stages, + bool failed, + void* context) { + UpdaterMainView* main_view = context; + updater_main_model_set_state(main_view, message, progress, idx_stage, total_stages, failed); +} + +Updater* updater_alloc(const char* arg) { + Updater* updater = malloc(sizeof(Updater)); + if(arg) { + string_init_set_str(updater->startup_arg, arg); + string_replace_str(updater->startup_arg, "/any/", "/ext/"); + } else { + string_init(updater->startup_arg); + } + + updater->storage = furi_record_open("storage"); + + updater->gui = furi_record_open("gui"); + updater->view_dispatcher = view_dispatcher_alloc(); + updater->scene_manager = scene_manager_alloc(&updater_scene_handlers, updater); + + view_dispatcher_enable_queue(updater->view_dispatcher); + + view_dispatcher_set_event_callback_context(updater->view_dispatcher, updater); + view_dispatcher_set_custom_event_callback( + updater->view_dispatcher, updater_custom_event_callback); + view_dispatcher_set_navigation_event_callback( + updater->view_dispatcher, updater_back_event_callback); + view_dispatcher_set_tick_event_callback( + updater->view_dispatcher, updater_tick_event_callback, UPDATER_APP_TICK); + + view_dispatcher_attach_to_gui( + updater->view_dispatcher, + updater->gui, + arg ? ViewDispatcherTypeFullscreen : ViewDispatcherTypeWindow); + + updater->main_view = updater_main_alloc(); + view_dispatcher_add_view( + updater->view_dispatcher, UpdaterViewMain, updater_main_get_view(updater->main_view)); + +#ifndef FURI_RAM_EXEC + updater->widget = widget_alloc(); + view_dispatcher_add_view( + updater->view_dispatcher, UpdaterViewWidget, widget_get_view(updater->widget)); +#endif + +#ifdef FURI_RAM_EXEC + if(true) { +#else + if(!arg) { +#endif + updater->update_task = update_task_alloc(); + update_task_set_progress_cb(updater->update_task, status_update_cb, updater->main_view); + + scene_manager_next_scene(updater->scene_manager, UpdaterSceneMain); + } else { +#ifndef FURI_RAM_EXEC + scene_manager_next_scene(updater->scene_manager, UpdaterSceneLoadCfg); +#endif + } + + return updater; +} + +void updater_free(Updater* updater) { + furi_assert(updater); + + string_clear(updater->startup_arg); + if(updater->update_task) { + update_task_set_progress_cb(updater->update_task, NULL, NULL); + update_task_free(updater->update_task); + } + + view_dispatcher_remove_view(updater->view_dispatcher, UpdaterViewMain); + updater_main_free(updater->main_view); + +#ifndef FURI_RAM_EXEC + view_dispatcher_remove_view(updater->view_dispatcher, UpdaterViewWidget); + widget_free(updater->widget); +#endif + + view_dispatcher_free(updater->view_dispatcher); + scene_manager_free(updater->scene_manager); + + furi_record_close("gui"); + furi_record_close("storage"); + + free(updater); +} + +int32_t updater_srv(void* p) { + const char* cfgpath = p; + + Updater* updater = updater_alloc(cfgpath); + view_dispatcher_run(updater->view_dispatcher); + updater_free(updater); + + return 0; +} \ No newline at end of file diff --git a/applications/updater/updater_i.h b/applications/updater/updater_i.h new file mode 100644 index 00000000000..d0e7c77c97c --- /dev/null +++ b/applications/updater/updater_i.h @@ -0,0 +1,65 @@ +#pragma once + +#include "views/updater_main.h" +#include "util/update_task.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define UPDATER_APP_TICK 500 + +typedef enum { + UpdaterViewMain, + UpdaterViewWidget, +} UpdaterViewEnum; + +typedef enum { + UpdaterCustomEventUnknown, + UpdaterCustomEventStartUpdate, + UpdaterCustomEventRetryUpdate, + UpdaterCustomEventCancelUpdate, + UpdaterCustomEventSdUnmounted, +} UpdaterCustomEvent; + +typedef struct UpdaterManifestProcessingState { + UpdateManifest* manifest; + string_t message; + bool ready_to_be_applied; +} UpdaterManifestProcessingState; + +typedef struct { + // GUI + Gui* gui; + SceneManager* scene_manager; + ViewDispatcher* view_dispatcher; + Storage* storage; + + UpdaterMainView* main_view; + + UpdaterManifestProcessingState* pending_update; + UpdatePrepareResult preparation_result; + + UpdateTask* update_task; + Widget* widget; + string_t startup_arg; + int32_t idle_ticks; +} Updater; + +Updater* updater_alloc(const char* arg); + +void updater_free(Updater* updater); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/applications/updater/util/update_task.c b/applications/updater/util/update_task.c new file mode 100644 index 00000000000..8ca5aad2116 --- /dev/null +++ b/applications/updater/util/update_task.c @@ -0,0 +1,226 @@ +#include "update_task.h" +#include "update_task_i.h" + +#include +#include +#include +#include +#include +#include +#include + +static const char* update_task_stage_descr[] = { + [UpdateTaskStageProgress] = "...", + [UpdateTaskStageReadManifest] = "Loading update manifest", + [UpdateTaskStageValidateDFUImage] = "Checking DFU file", + [UpdateTaskStageFlashWrite] = "Writing flash", + [UpdateTaskStageFlashValidate] = "Validating", + [UpdateTaskStageRadioWrite] = "Writing radio stack", + [UpdateTaskStageRadioCommit] = "Applying radio stack", + [UpdateTaskStageLfsBackup] = "Backing up LFS", + [UpdateTaskStageLfsRestore] = "Restoring LFS", + [UpdateTaskStageComplete] = "Complete", + [UpdateTaskStageError] = "Error", +}; + +static void update_task_set_status(UpdateTask* update_task, const char* status) { + if(!status) { + if(update_task->state.stage >= COUNT_OF(update_task_stage_descr)) { + status = "..."; + } else { + status = update_task_stage_descr[update_task->state.stage]; + } + } + string_set_str(update_task->state.status, status); +} + +void update_task_set_progress(UpdateTask* update_task, UpdateTaskStage stage, uint8_t progress) { + if(stage != UpdateTaskStageProgress) { + update_task->state.stage = stage; + update_task->state.current_stage_idx++; + update_task_set_status(update_task, NULL); + } + + if(progress > 100) { + progress = 100; + } + + update_task->state.progress = progress; + if(update_task->status_change_cb) { + (update_task->status_change_cb)( + string_get_cstr(update_task->state.status), + progress, + update_task->state.current_stage_idx, + update_task->state.total_stages, + update_task->state.stage == UpdateTaskStageError, + update_task->status_change_cb_state); + } +} + +static void update_task_close_file(UpdateTask* update_task) { + furi_assert(update_task); + if(!storage_file_is_open(update_task->file)) { + return; + } + + storage_file_close(update_task->file); +} + +static bool update_task_check_file_exists(UpdateTask* update_task, string_t filename) { + furi_assert(update_task); + string_t tmp_path; + string_init_set(tmp_path, update_task->update_path); + path_append(tmp_path, string_get_cstr(filename)); + bool exists = + (storage_common_stat(update_task->storage, string_get_cstr(tmp_path), NULL) == FSE_OK); + string_clear(tmp_path); + return exists; +} + +bool update_task_open_file(UpdateTask* update_task, string_t filename) { + furi_assert(update_task); + update_task_close_file(update_task); + + string_t tmp_path; + string_init_set(tmp_path, update_task->update_path); + path_append(tmp_path, string_get_cstr(filename)); + bool open_success = storage_file_open( + update_task->file, string_get_cstr(tmp_path), FSAM_READ, FSOM_OPEN_EXISTING); + string_clear(tmp_path); + return open_success; +} + +static void update_task_worker_thread_cb(FuriThreadState state, void* context) { + UpdateTask* update_task = context; + + if(state != FuriThreadStateStopped) { + return; + } + + int32_t op_result = furi_thread_get_return_code(update_task->thread); + if(op_result == UPDATE_TASK_NOERR) { + osDelay(UPDATE_DELAY_OPERATION_OK); + furi_hal_power_reset(); + } +} + +UpdateTask* update_task_alloc() { + UpdateTask* update_task = malloc(sizeof(UpdateTask)); + + update_task->state.stage = UpdateTaskStageProgress; + update_task->state.progress = 0; + string_init(update_task->state.status); + + update_task->manifest = update_manifest_alloc(); + update_task->storage = furi_record_open("storage"); + update_task->file = storage_file_alloc(update_task->storage); + update_task->status_change_cb = NULL; + + FuriThread* thread = update_task->thread = furi_thread_alloc(); + + furi_thread_set_name(thread, "UpdateWorker"); + furi_thread_set_stack_size(thread, 5120); + furi_thread_set_context(thread, update_task); + + furi_thread_set_state_callback(thread, update_task_worker_thread_cb); + furi_thread_set_state_context(thread, update_task); +#ifdef FURI_RAM_EXEC + UNUSED(update_task_worker_backup_restore); + furi_thread_set_callback(thread, update_task_worker_flash_writer); +#else + UNUSED(update_task_worker_flash_writer); + furi_thread_set_callback(thread, update_task_worker_backup_restore); +#endif + + return update_task; +} + +void update_task_free(UpdateTask* update_task) { + furi_assert(update_task); + + furi_thread_join(update_task->thread); + + furi_thread_free(update_task->thread); + update_task_close_file(update_task); + storage_file_free(update_task->file); + update_manifest_free(update_task->manifest); + + furi_record_close("storage"); + string_clear(update_task->update_path); + + free(update_task); +} + +bool update_task_init(UpdateTask* update_task) { + furi_assert(update_task); + string_init(update_task->update_path); + return true; +} + +bool update_task_parse_manifest(UpdateTask* update_task) { + furi_assert(update_task); + update_task_set_progress(update_task, UpdateTaskStageReadManifest, 0); + bool result = false; + string_t manifest_path; + string_init(manifest_path); + + do { + update_task_set_progress(update_task, UpdateTaskStageProgress, 10); + if(!update_operation_get_current_package_path( + update_task->storage, update_task->update_path)) { + break; + } + + path_concat( + string_get_cstr(update_task->update_path), + UPDATE_MANIFEST_DEFAULT_NAME, + manifest_path); + update_task_set_progress(update_task, UpdateTaskStageProgress, 30); + if(!update_manifest_init(update_task->manifest, string_get_cstr(manifest_path))) { + break; + } + + update_task_set_progress(update_task, UpdateTaskStageProgress, 50); + if(!string_empty_p(update_task->manifest->firmware_dfu_image) && + !update_task_check_file_exists(update_task, update_task->manifest->firmware_dfu_image)) { + break; + } + + update_task_set_progress(update_task, UpdateTaskStageProgress, 70); + if(!string_empty_p(update_task->manifest->radio_image) && + !update_task_check_file_exists(update_task, update_task->manifest->radio_image)) { + break; + } + + update_task_set_progress(update_task, UpdateTaskStageProgress, 100); + result = true; + } while(false); + + string_clear(manifest_path); + return result; +} + +void update_task_set_progress_cb(UpdateTask* update_task, updateProgressCb cb, void* state) { + update_task->status_change_cb = cb; + update_task->status_change_cb_state = state; +} + +bool update_task_start(UpdateTask* update_task) { + furi_assert(update_task); + return furi_thread_start(update_task->thread); +} + +bool update_task_is_running(UpdateTask* update_task) { + furi_assert(update_task); + return furi_thread_get_state(update_task->thread) == FuriThreadStateRunning; +} + +UpdateTaskState const* update_task_get_state(UpdateTask* update_task) { + furi_assert(update_task); + return &update_task->state; +} + +UpdateManifest const* update_task_get_manifest(UpdateTask* update_task) { + furi_assert(update_task); + return update_task->manifest; +} diff --git a/applications/updater/util/update_task.h b/applications/updater/util/update_task.h new file mode 100644 index 00000000000..32dea989ca0 --- /dev/null +++ b/applications/updater/util/update_task.h @@ -0,0 +1,66 @@ +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#include +#include +#include + +#define UPDATE_DELAY_OPERATION_OK 600 +#define UPDATE_DELAY_OPERATION_ERROR INT_MAX + +typedef enum { + UpdateTaskStageProgress, + UpdateTaskStageReadManifest, + UpdateTaskStageValidateDFUImage, + UpdateTaskStageFlashWrite, + UpdateTaskStageFlashValidate, + UpdateTaskStageRadioWrite, + UpdateTaskStageRadioCommit, + UpdateTaskStageLfsBackup, + UpdateTaskStageLfsRestore, + UpdateTaskStageComplete, + UpdateTaskStageError, +} UpdateTaskStage; + +typedef struct { + UpdateTaskStage stage; + uint8_t progress; + uint8_t current_stage_idx; + uint8_t total_stages; + string_t status; +} UpdateTaskState; + +typedef struct UpdateTask UpdateTask; + +typedef void (*updateProgressCb)( + const char* status, + const uint8_t stage_pct, + const uint8_t idx_stage, + const uint8_t total_stages, + bool failed, + void* state); + +UpdateTask* update_task_alloc(); + +void update_task_free(UpdateTask* update_task); + +bool update_task_init(UpdateTask* update_task); + +void update_task_set_progress_cb(UpdateTask* update_task, updateProgressCb cb, void* state); + +bool update_task_start(UpdateTask* update_task); + +bool update_task_is_running(UpdateTask* update_task); + +UpdateTaskState const* update_task_get_state(UpdateTask* update_task); + +UpdateManifest const* update_task_get_manifest(UpdateTask* update_task); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/applications/updater/util/update_task_i.h b/applications/updater/util/update_task_i.h new file mode 100644 index 00000000000..fb6b4ac114a --- /dev/null +++ b/applications/updater/util/update_task_i.h @@ -0,0 +1,24 @@ +#pragma once + +#include + +#define UPDATE_TASK_NOERR 0 +#define UPDATE_TASK_FAILED -1 + +typedef struct UpdateTask { + UpdateTaskState state; + string_t update_path; + UpdateManifest* manifest; + FuriThread* thread; + Storage* storage; + File* file; + updateProgressCb status_change_cb; + void* status_change_cb_state; +} UpdateTask; + +void update_task_set_progress(UpdateTask* update_task, UpdateTaskStage stage, uint8_t progress); +bool update_task_parse_manifest(UpdateTask* update_task); +bool update_task_open_file(UpdateTask* update_task, string_t filename); + +int32_t update_task_worker_flash_writer(void* context); +int32_t update_task_worker_backup_restore(void* context); diff --git a/applications/updater/util/update_task_workers.c b/applications/updater/util/update_task_workers.c new file mode 100644 index 00000000000..fb1e86becbe --- /dev/null +++ b/applications/updater/util/update_task_workers.c @@ -0,0 +1,148 @@ +#include "update_task.h" +#include "update_task_i.h" + +#include +#include +#include +#include +#include +#include +#include + +#define CHECK_RESULT(x) \ + if(!(x)) { \ + break; \ + } + +#define STM_DFU_VENDOR_ID 0x0483 +#define STM_DFU_PRODUCT_ID 0xDF11 +/* Written into DFU file by build pipeline */ +#define FLIPPER_ZERO_DFU_DEVICE_CODE 0xFFFF + +static const DfuValidationParams flipper_dfu_params = { + .device = FLIPPER_ZERO_DFU_DEVICE_CODE, + .product = STM_DFU_PRODUCT_ID, + .vendor = STM_DFU_VENDOR_ID, +}; + +static void update_task_dfu_progress(const uint8_t progress, void* context) { + UpdateTask* update_task = context; + update_task_set_progress(update_task, UpdateTaskStageProgress, progress); +} + +static bool page_task_compare_flash( + const uint8_t i_page, + const uint8_t* update_block, + uint16_t update_block_len) { + const size_t page_addr = furi_hal_flash_get_base() + furi_hal_flash_get_page_size() * i_page; + return (memcmp(update_block, (void*)page_addr, update_block_len) == 0); +} + +/* Verifies a flash operation address for fitting into writable memory + */ +static bool check_address_boundaries(const size_t address) { + const size_t min_allowed_address = furi_hal_flash_get_base(); + const size_t max_allowed_address = (size_t)furi_hal_flash_get_free_end_address(); + return ((address >= min_allowed_address) && (address < max_allowed_address)); +} + +int32_t update_task_worker_flash_writer(void* context) { + furi_assert(context); + UpdateTask* update_task = context; + bool success = false; + DfuUpdateTask page_task = { + .address_cb = &check_address_boundaries, + .progress_cb = &update_task_dfu_progress, + .task_cb = &furi_hal_flash_program_page, + .context = update_task, + }; + + update_task->state.current_stage_idx = 0; + update_task->state.total_stages = 4; + + do { + CHECK_RESULT(update_task_parse_manifest(update_task)); + + if(!string_empty_p(update_task->manifest->firmware_dfu_image)) { + update_task_set_progress(update_task, UpdateTaskStageValidateDFUImage, 0); + CHECK_RESULT( + update_task_open_file(update_task, update_task->manifest->firmware_dfu_image)); + CHECK_RESULT( + dfu_file_validate_crc(update_task->file, &update_task_dfu_progress, update_task)); + + const uint8_t valid_targets = + dfu_file_validate_headers(update_task->file, &flipper_dfu_params); + if(valid_targets == 0) { + break; + } + + update_task_set_progress(update_task, UpdateTaskStageFlashWrite, 0); + CHECK_RESULT(dfu_file_process_targets(&page_task, update_task->file, valid_targets)); + + page_task.task_cb = &page_task_compare_flash; + + update_task_set_progress(update_task, UpdateTaskStageFlashValidate, 0); + CHECK_RESULT(dfu_file_process_targets(&page_task, update_task->file, valid_targets)); + } + + update_task_set_progress(update_task, UpdateTaskStageComplete, 100); + + furi_hal_rtc_set_boot_mode(FuriHalRtcBootModePostUpdate); + + success = true; + } while(false); + + if(!success) { + update_task_set_progress(update_task, UpdateTaskStageError, update_task->state.progress); + } + + return success ? UPDATE_TASK_NOERR : UPDATE_TASK_FAILED; +} + +int32_t update_task_worker_backup_restore(void* context) { + furi_assert(context); + UpdateTask* update_task = context; + bool success = false; + + FuriHalRtcBootMode boot_mode = furi_hal_rtc_get_boot_mode(); + if((boot_mode != FuriHalRtcBootModePreUpdate) && (boot_mode != FuriHalRtcBootModePostUpdate)) { + // no idea how we got here. Clear to normal boot + furi_hal_rtc_set_boot_mode(FuriHalRtcBootModeNormal); + return UPDATE_TASK_NOERR; + } + + update_task->state.current_stage_idx = 0; + update_task->state.total_stages = 1; + + if(!update_operation_get_current_package_path(update_task->storage, update_task->update_path)) { + return UPDATE_TASK_FAILED; + } + + string_t backup_file_path; + string_init(backup_file_path); + path_concat( + string_get_cstr(update_task->update_path), LFS_BACKUP_DEFAULT_FILENAME, backup_file_path); + + if(boot_mode == FuriHalRtcBootModePreUpdate) { + update_task_set_progress(update_task, UpdateTaskStageLfsBackup, 0); + furi_hal_rtc_set_boot_mode(FuriHalRtcBootModeNormal); // to avoid bootloops + if((success = + lfs_backup_create(update_task->storage, string_get_cstr(backup_file_path)))) { + furi_hal_rtc_set_boot_mode(FuriHalRtcBootModeUpdate); + } + } else if(boot_mode == FuriHalRtcBootModePostUpdate) { + update_task_set_progress(update_task, UpdateTaskStageLfsRestore, 0); + furi_hal_rtc_set_boot_mode(FuriHalRtcBootModeNormal); + success = lfs_backup_unpack(update_task->storage, string_get_cstr(backup_file_path)); + } + + if(success) { + update_task_set_progress(update_task, UpdateTaskStageComplete, 100); + } else { + update_task_set_progress(update_task, UpdateTaskStageError, update_task->state.progress); + } + + string_clear(backup_file_path); + + return success ? UPDATE_TASK_NOERR : UPDATE_TASK_FAILED; +} diff --git a/applications/updater/views/updater_main.c b/applications/updater/views/updater_main.c new file mode 100644 index 00000000000..8d9b3e95314 --- /dev/null +++ b/applications/updater/views/updater_main.c @@ -0,0 +1,151 @@ +#include +#include +#include +#include +#include +#include + +#include "../updater_i.h" +#include "updater_main.h" + +struct UpdaterMainView { + View* view; + ViewDispatcher* view_dispatcher; + FuriPubSubSubscription* subscription; + void* context; +}; + +static const uint8_t PROGRESS_RENDER_STEP = 3; /* percent, to limit rendering rate */ + +typedef struct { + string_t status; + uint8_t progress, rendered_progress; + uint8_t idx_stage, total_stages; + bool failed; +} UpdaterProgressModel; + +void updater_main_model_set_state( + UpdaterMainView* main_view, + const char* message, + uint8_t progress, + uint8_t idx_stage, + uint8_t total_stages, + bool failed) { + with_view_model( + main_view->view, (UpdaterProgressModel * model) { + model->failed = failed; + model->idx_stage = idx_stage; + model->total_stages = total_stages; + model->progress = progress; + if(string_cmp_str(model->status, message)) { + string_set(model->status, message); + model->rendered_progress = progress; + return true; + } + if((model->rendered_progress > progress) || + ((progress - model->rendered_progress) > PROGRESS_RENDER_STEP)) { + model->rendered_progress = progress; + return true; + } + return false; + }); +} + +View* updater_main_get_view(UpdaterMainView* main_view) { + furi_assert(main_view); + return main_view->view; +} + +bool updater_main_input(InputEvent* event, void* context) { + furi_assert(event); + furi_assert(context); + + UpdaterMainView* main_view = context; + if(!main_view->view_dispatcher) { + return true; + } + + if(event->type != InputTypeShort) { + return true; + } + + if(event->key == InputKeyOk) { + view_dispatcher_send_custom_event( + main_view->view_dispatcher, UpdaterCustomEventRetryUpdate); + } else if(event->key == InputKeyBack) { + view_dispatcher_send_custom_event( + main_view->view_dispatcher, UpdaterCustomEventCancelUpdate); + } + + return true; +} + +static void updater_main_draw_callback(Canvas* canvas, void* _model) { + UpdaterProgressModel* model = _model; + + canvas_set_font(canvas, FontPrimary); + + uint16_t y_offset = model->failed ? 5 : 13; + string_t status_text; + if(!model->failed && (model->idx_stage != 0) && (model->idx_stage <= model->total_stages)) { + string_init_printf( + status_text, + "[%d/%d] %s", + model->idx_stage, + model->total_stages, + string_get_cstr(model->status)); + } else { + string_init_set(status_text, model->status); + } + canvas_draw_str_aligned( + canvas, 128 / 2, y_offset, AlignCenter, AlignTop, string_get_cstr(status_text)); + string_clear(status_text); + if(model->failed) { + canvas_set_font(canvas, FontSecondary); + canvas_draw_str_aligned( + canvas, 128 / 2, 20, AlignCenter, AlignTop, "[OK] to retry, [Back] to abort"); + } + elements_progress_bar(canvas, 14, 35, 100, (float)model->progress / 100); +} + +UpdaterMainView* updater_main_alloc() { + UpdaterMainView* main_view = malloc(sizeof(UpdaterMainView)); + + main_view->view = view_alloc(); + view_allocate_model(main_view->view, ViewModelTypeLocking, sizeof(UpdaterProgressModel)); + + with_view_model( + main_view->view, (UpdaterProgressModel * model) { + string_init_set(model->status, "Waiting for storage"); + return true; + }); + + view_set_context(main_view->view, main_view); + view_set_input_callback(main_view->view, updater_main_input); + view_set_draw_callback(main_view->view, updater_main_draw_callback); + + return main_view; +} + +void updater_main_free(UpdaterMainView* main_view) { + furi_assert(main_view); + with_view_model( + main_view->view, (UpdaterProgressModel * model) { + string_clear(model->status); + return false; + }); + view_free(main_view->view); + free(main_view); +} + +void updater_main_set_storage_pubsub(UpdaterMainView* main_view, FuriPubSubSubscription* sub) { + main_view->subscription = sub; +} + +FuriPubSubSubscription* updater_main_get_storage_pubsub(UpdaterMainView* main_view) { + return main_view->subscription; +} + +void updater_main_set_view_dispatcher(UpdaterMainView* main_view, ViewDispatcher* view_dispatcher) { + main_view->view_dispatcher = view_dispatcher; +} diff --git a/applications/updater/views/updater_main.h b/applications/updater/views/updater_main.h new file mode 100644 index 00000000000..3c55a8c24bb --- /dev/null +++ b/applications/updater/views/updater_main.h @@ -0,0 +1,28 @@ +#pragma once + +#include + +typedef struct UpdaterMainView UpdaterMainView; +typedef struct FuriPubSubSubscription FuriPubSubSubscription; +typedef struct ViewDispatcher ViewDispatcher; +typedef void (*UpdaterMainInputCallback)(InputType type, void* context); + +View* updater_main_get_view(UpdaterMainView* main_view); + +UpdaterMainView* updater_main_alloc(); + +void updater_main_free(UpdaterMainView* main_view); + +void updater_main_model_set_state( + UpdaterMainView* main_view, + const char* message, + uint8_t progress, + uint8_t idx_stage, + uint8_t total_stages, + bool failed); + +void updater_main_set_storage_pubsub(UpdaterMainView* main_view, FuriPubSubSubscription* sub); + +FuriPubSubSubscription* updater_main_get_storage_pubsub(UpdaterMainView* main_view); + +void updater_main_set_view_dispatcher(UpdaterMainView* main_view, ViewDispatcher* view_dispatcher); \ No newline at end of file diff --git a/assets/assets.mk b/assets/assets.mk index cd5a9b2ecab..55783ec8bba 100644 --- a/assets/assets.mk +++ b/assets/assets.mk @@ -16,7 +16,7 @@ PROTOBUF_COMPILED_DIR := $(ASSETS_COMPILED_DIR) PROTOBUF_SOURCES := $(shell find $(PROTOBUF_SOURCE_DIR) -type f -iname '*.proto') PROTOBUF_FILENAMES := $(notdir $(addsuffix .pb.c,$(basename $(PROTOBUF_SOURCES)))) PROTOBUF := $(addprefix $(PROTOBUF_COMPILED_DIR)/,$(PROTOBUF_FILENAMES)) $(PROTOBUF_COMPILED_DIR)/protobuf_version.h -PROTOBUF_VERSION := $(shell git -C $(PROTOBUF_SOURCE_DIR) fetch --tags 2>/dev/null && git -C $(PROTOBUF_SOURCE_DIR) describe --tags --abbrev=0 2>/dev/null || echo 'unknown') +PROTOBUF_VERSION := $(shell git -C $(PROTOBUF_SOURCE_DIR) fetch --tags 2>/dev/null ; git -C $(PROTOBUF_SOURCE_DIR) describe --tags --abbrev=0 2>/dev/null || echo 'unknown') PROTOBUF_MAJOR_VERSION := $(word 1,$(subst ., ,$(PROTOBUF_VERSION))) PROTOBUF_MINOR_VERSION := $(word 2,$(subst ., ,$(PROTOBUF_VERSION))) $(if $(PROTOBUF_MAJOR_VERSION),,$(error "Protobuf major version is not specified, $$PROTOBUF_VERSION=$(PROTOBUF_VERSION), please perform git fetch in assets/protobuf directory")) diff --git a/assets/compiled/assets_icons.c b/assets/compiled/assets_icons.c index 03dda94a0a2..8b17d0780b2 100644 --- a/assets/compiled/assets_icons.c +++ b/assets/compiled/assets_icons.c @@ -64,6 +64,9 @@ const uint8_t* const _I_u2f_10px[] = {_I_u2f_10px_0}; const uint8_t _I_unknown_10px_0[] = {0x01,0x00,0x12,0x00,0xbc,0x40,0x39,0x90,0x0c,0x24,0x03,0x81,0x00,0xb0,0x40,0x26,0x00,0x12,0x00,0x08,0x14,0xc0,}; const uint8_t* const _I_unknown_10px[] = {_I_unknown_10px_0}; +const uint8_t _I_update_10px_0[] = {0x00,0xFE,0x01,0x01,0x02,0xFF,0x03,0x01,0x02,0x31,0x02,0x79,0x02,0xFD,0x02,0x31,0x02,0x31,0x02,0xFF,0x03,}; +const uint8_t* const _I_update_10px[] = {_I_update_10px_0}; + const uint8_t _I_BLE_Pairing_128x64_0[] = {0x01,0x00,0xb7,0x01,0x00,0x6c,0x38,0x1f,0xd0,0x10,0x76,0xe0,0x03,0xdd,0x40,0x07,0xf4,0x82,0x01,0x08,0x07,0xf4,0xc0,0x1f,0x91,0x08,0x07,0x00,0x1f,0xc0,0x0d,0x1e,0xe8,0x3f,0xc0,0x03,0x58,0x80,0xcf,0x11,0xd9,0xaf,0x85,0x77,0x01,0xf7,0x60,0xf8,0x45,0xff,0x05,0xed,0x9e,0x7c,0x09,0xdb,0xe0,0x2f,0x78,0x03,0x3c,0x8e,0xee,0x8a,0x43,0x81,0xfb,0x0c,0x66,0xe8,0xfc,0x59,0xba,0x6f,0x28,0x1b,0xfb,0xa3,0x80,0xfc,0xa0,0x1f,0xc6,0x86,0xbf,0xc3,0x78,0xce,0x04,0x19,0x26,0x77,0xfa,0x43,0xbe,0x12,0xa0,0x7e,0xf8,0x2a,0xa2,0x02,0xff,0x89,0x27,0x01,0xbf,0x99,0x38,0x8a,0xfc,0x0f,0x8e,0x07,0xfe,0x0e,0x94,0x2c,0x07,0xfc,0x7f,0x1f,0xf5,0x00,0xc3,0x00,0xe4,0x31,0x13,0xd1,0x00,0x0a,0xb8,0x19,0x25,0x91,0xc0,0x81,0xe2,0xb9,0x4d,0x5d,0x78,0x64,0x2e,0x84,0x80,0x61,0x07,0x02,0x3e,0x2a,0xa4,0xa2,0x00,0xf2,0x40,0x20,0xe3,0x21,0xa0,0x62,0x9f,0x60,0x05,0x02,0x3e,0x36,0x41,0x66,0x23,0x20,0x51,0xfc,0x40,0x68,0x0f,0x15,0x90,0x60,0x20,0x1b,0x09,0x89,0x70,0x46,0x42,0x07,0x14,0x99,0x41,0xe8,0x1f,0x18,0x0c,0x07,0xc1,0x19,0xff,0xc3,0xce,0x6b,0x54,0x8f,0xe0,0x3f,0x90,0x78,0x17,0x02,0x1a,0x70,0x39,0x01,0xa0,0xb1,0x53,0xb5,0x88,0xc7,0xe0,0x98,0x08,0x3a,0xd5,0xe8,0x97,0xd0,0x78,0xcf,0xe1,0x07,0xf1,0x0d,0x08,0x00,0x74,0x10,0x80,0x18,0xe8,0x97,0xc3,0xf2,0xff,0xc4,0x03,0xe3,0x04,0x8c,0x19,0xcc,0x00,0x35,0x0c,0x3c,0x03,0xf9,0x3f,0xb0,0x8f,0xc6,0x31,0x0e,0x0f,0x90,0x90,0xb5,0x45,0xc1,0xf8,0x4f,0xf0,0xde,0x18,0xcc,0x82,0x08,0x1f,0x22,0x20,0xd0,0x3a,0xab,0xd1,0xe0,0x5f,0xa1,0x1b,0x19,0x8d,0x02,0x04,0x9a,0x1d,0x04,0x28,0x26,0x36,0xa8,0x05,0xf0,0xe0,0x3f,0x04,0xf8,0xd0,0x30,0x55,0xfa,0xad,0x54,0x3e,0x35,0x09,0xab,0xac,0xbf,0x2b,0xf2,0x0a,0x0e,0xfb,0x55,0xaa,0x0f,0x94,0x68,0x04,0x30,0x6f,0xd3,0x7c,0xb0,0x15,0x0f,0xfd,0x7f,0xeb,0x05,0x4f,0x0b,0x60,0xa3,0x1f,0x28,0x0b,0xfc,0xbc,0x30,0x1f,0xf7,0xfe,0x54,0x2c,0x18,0x30,0x3c,0x6f,0x00,0xf2,0x1c,0x8c,0xf8,0x10,0x3c,0x00,0xf8,0xd5,0x5c,0x05,0xb8,0xb0,0xaa,0xdb,0x01,0x2b,0x31,0x0a,0xdc,0xa7,0x00,0xe6,0x00,0x0c,0x56,0x00,0x7e,0x10,0x00,0xcc,0x01,0xf0,0x1f,0x1b,0x40,0x2e,0x00,0x07,0x16,0x10,0x90,0x02,0xe5,0x90,0x06,0x29,0x00,0x2a,0xa9,0x00,0x2f,0x10,0x02,0xa5,0x10,0x02,0xf1,0x00,0x2a,0xa0,0x0d,0xc0,0x00,0xec,0x01,0xfd,0x60,0x17,0x6a,0xc0,0x60,0x40,0xfd,0xc0,0x30,0x04,0x01,0xb0,0xb0,0x7f,0x45,0x80,}; const uint8_t* const _I_BLE_Pairing_128x64[] = {_I_BLE_Pairing_128x64_0}; @@ -674,6 +677,7 @@ const Icon I_ir_10px = {.width=10,.height=10,.frame_count=1,.frame_rate=0,.frame const Icon I_sub1_10px = {.width=10,.height=10,.frame_count=1,.frame_rate=0,.frames=_I_sub1_10px}; const Icon I_u2f_10px = {.width=10,.height=10,.frame_count=1,.frame_rate=0,.frames=_I_u2f_10px}; const Icon I_unknown_10px = {.width=10,.height=10,.frame_count=1,.frame_rate=0,.frames=_I_unknown_10px}; +const Icon I_update_10px = {.width=10,.height=10,.frame_count=1,.frame_rate=0,.frames=_I_update_10px}; const Icon I_BLE_Pairing_128x64 = {.width=128,.height=64,.frame_count=1,.frame_rate=0,.frames=_I_BLE_Pairing_128x64}; const Icon I_Ble_connected_38x34 = {.width=38,.height=34,.frame_count=1,.frame_rate=0,.frames=_I_Ble_connected_38x34}; const Icon I_Ble_disconnected_24x34 = {.width=24,.height=34,.frame_count=1,.frame_rate=0,.frames=_I_Ble_disconnected_24x34}; diff --git a/assets/compiled/assets_icons.h b/assets/compiled/assets_icons.h index e80fdd2f112..be1023f6522 100644 --- a/assets/compiled/assets_icons.h +++ b/assets/compiled/assets_icons.h @@ -15,6 +15,7 @@ extern const Icon I_ir_10px; extern const Icon I_sub1_10px; extern const Icon I_u2f_10px; extern const Icon I_unknown_10px; +extern const Icon I_update_10px; extern const Icon I_BLE_Pairing_128x64; extern const Icon I_Ble_connected_38x34; extern const Icon I_Ble_disconnected_24x34; diff --git a/assets/icons/Archive/update_10px.png b/assets/icons/Archive/update_10px.png new file mode 100644 index 0000000000000000000000000000000000000000..5a97651c486c421d11cb6ba8a74c02bb4804b373 GIT binary patch literal 156 zcmeAS@N?(olHy`uVBq!ia0vp^AT}2xGmzZ=C-xtZVk{1FcVbv~PUa<$!;&U>c zv7h@-A}f&37T^=&`v3obAT#vPO>_%)r2R7=#&*=dVZs3d(!BIEF}EPF|6p ukWrBEqn^R#n}xxd;)EOgX$%+tGc!!f -#include - -void furi_hal_init() { - furi_hal_i2c_init(); - furi_hal_light_init(); - furi_hal_spi_init(); - furi_hal_version_init(); -} - -void furi_hal_delay_ms(float milliseconds) { - LL_mDelay((uint32_t)milliseconds); -} - -void furi_hal_delay_us(float microseconds) { - microseconds = microseconds / 1000; - if(microseconds < 1) { - microseconds = 1; - } - LL_mDelay((uint32_t)microseconds); -} diff --git a/bootloader/targets/f7/furi_hal/furi_hal_gpio.c b/bootloader/targets/f7/furi_hal/furi_hal_gpio.c deleted file mode 100644 index f80f4c1e1a3..00000000000 --- a/bootloader/targets/f7/furi_hal/furi_hal_gpio.c +++ /dev/null @@ -1,214 +0,0 @@ -#include -#include -#include - -#define GET_SYSCFG_EXTI_PORT(gpio) \ - (((gpio) == (GPIOA)) ? LL_SYSCFG_EXTI_PORTA : \ - ((gpio) == (GPIOB)) ? LL_SYSCFG_EXTI_PORTB : \ - ((gpio) == (GPIOC)) ? LL_SYSCFG_EXTI_PORTC : \ - ((gpio) == (GPIOD)) ? LL_SYSCFG_EXTI_PORTD : \ - ((gpio) == (GPIOE)) ? LL_SYSCFG_EXTI_PORTE : \ - LL_SYSCFG_EXTI_PORTH) - -#define GPIO_PIN_MAP(pin, prefix) \ - (((pin) == (LL_GPIO_PIN_0)) ? prefix##0 : \ - ((pin) == (LL_GPIO_PIN_1)) ? prefix##1 : \ - ((pin) == (LL_GPIO_PIN_2)) ? prefix##2 : \ - ((pin) == (LL_GPIO_PIN_3)) ? prefix##3 : \ - ((pin) == (LL_GPIO_PIN_4)) ? prefix##4 : \ - ((pin) == (LL_GPIO_PIN_5)) ? prefix##5 : \ - ((pin) == (LL_GPIO_PIN_6)) ? prefix##6 : \ - ((pin) == (LL_GPIO_PIN_7)) ? prefix##7 : \ - ((pin) == (LL_GPIO_PIN_8)) ? prefix##8 : \ - ((pin) == (LL_GPIO_PIN_9)) ? prefix##9 : \ - ((pin) == (LL_GPIO_PIN_10)) ? prefix##10 : \ - ((pin) == (LL_GPIO_PIN_11)) ? prefix##11 : \ - ((pin) == (LL_GPIO_PIN_12)) ? prefix##12 : \ - ((pin) == (LL_GPIO_PIN_13)) ? prefix##13 : \ - ((pin) == (LL_GPIO_PIN_14)) ? prefix##14 : \ - prefix##15) - -#define GET_SYSCFG_EXTI_LINE(pin) GPIO_PIN_MAP(pin, LL_SYSCFG_EXTI_LINE) -#define GET_EXTI_LINE(pin) GPIO_PIN_MAP(pin, LL_EXTI_LINE_) - -static volatile GpioInterrupt gpio_interrupt[GPIO_NUMBER]; - -static uint8_t furi_hal_gpio_get_pin_num(const GpioPin* gpio) { - uint8_t pin_num = 0; - for(pin_num = 0; pin_num < GPIO_NUMBER; pin_num++) { - if(gpio->pin & (1 << pin_num)) break; - } - return pin_num; -} - -void furi_hal_gpio_init_simple(const GpioPin* gpio, const GpioMode mode) { - furi_hal_gpio_init(gpio, mode, GpioPullNo, GpioSpeedLow); -} - -void furi_hal_gpio_init( - const GpioPin* gpio, - const GpioMode mode, - const GpioPull pull, - const GpioSpeed speed) { - // we cannot set alternate mode in this function - assert(mode != GpioModeAltFunctionPushPull); - assert(mode != GpioModeAltFunctionOpenDrain); - - furi_hal_gpio_init_ex(gpio, mode, pull, speed, GpioAltFnUnused); -} - -void furi_hal_gpio_init_ex( - const GpioPin* gpio, - const GpioMode mode, - const GpioPull pull, - const GpioSpeed speed, - const GpioAltFn alt_fn) { - uint32_t sys_exti_port = GET_SYSCFG_EXTI_PORT(gpio->port); - uint32_t sys_exti_line = GET_SYSCFG_EXTI_LINE(gpio->pin); - uint32_t exti_line = GET_EXTI_LINE(gpio->pin); - - // Configure gpio with interrupts disabled - __disable_irq(); - - // Set gpio speed - switch(speed) { - case GpioSpeedLow: - LL_GPIO_SetPinSpeed(gpio->port, gpio->pin, LL_GPIO_SPEED_FREQ_LOW); - break; - case GpioSpeedMedium: - LL_GPIO_SetPinSpeed(gpio->port, gpio->pin, LL_GPIO_SPEED_FREQ_MEDIUM); - break; - case GpioSpeedHigh: - LL_GPIO_SetPinSpeed(gpio->port, gpio->pin, LL_GPIO_SPEED_FREQ_HIGH); - break; - case GpioSpeedVeryHigh: - LL_GPIO_SetPinSpeed(gpio->port, gpio->pin, LL_GPIO_SPEED_FREQ_VERY_HIGH); - break; - } - - // Set gpio pull mode - switch(pull) { - case GpioPullNo: - LL_GPIO_SetPinPull(gpio->port, gpio->pin, LL_GPIO_PULL_NO); - break; - case GpioPullUp: - LL_GPIO_SetPinPull(gpio->port, gpio->pin, LL_GPIO_PULL_UP); - break; - case GpioPullDown: - LL_GPIO_SetPinPull(gpio->port, gpio->pin, LL_GPIO_PULL_DOWN); - break; - } - - // Set gpio mode - if(mode >= GpioModeInterruptRise) { - // Set pin in interrupt mode - LL_GPIO_SetPinMode(gpio->port, gpio->pin, LL_GPIO_MODE_INPUT); - LL_SYSCFG_SetEXTISource(sys_exti_port, sys_exti_line); - if(mode == GpioModeInterruptRise || mode == GpioModeInterruptRiseFall) { - LL_EXTI_EnableIT_0_31(exti_line); - LL_EXTI_EnableRisingTrig_0_31(exti_line); - } - if(mode == GpioModeInterruptFall || mode == GpioModeInterruptRiseFall) { - LL_EXTI_EnableIT_0_31(exti_line); - LL_EXTI_EnableFallingTrig_0_31(exti_line); - } - if(mode == GpioModeEventRise || mode == GpioModeEventRiseFall) { - LL_EXTI_EnableEvent_0_31(exti_line); - LL_EXTI_EnableRisingTrig_0_31(exti_line); - } - if(mode == GpioModeEventFall || mode == GpioModeEventRiseFall) { - LL_EXTI_EnableEvent_0_31(exti_line); - LL_EXTI_EnableFallingTrig_0_31(exti_line); - } - } else { - // Disable interrupts if set - if(LL_SYSCFG_GetEXTISource(sys_exti_line) == sys_exti_port && - LL_EXTI_IsEnabledIT_0_31(exti_line)) { - LL_EXTI_DisableIT_0_31(exti_line); - LL_EXTI_DisableRisingTrig_0_31(exti_line); - LL_EXTI_DisableFallingTrig_0_31(exti_line); - } - - // Prepare alternative part if any - if(mode == GpioModeAltFunctionPushPull || mode == GpioModeAltFunctionOpenDrain) { - // set alternate function - if(furi_hal_gpio_get_pin_num(gpio) < 8) { - LL_GPIO_SetAFPin_0_7(gpio->port, gpio->pin, alt_fn); - } else { - LL_GPIO_SetAFPin_8_15(gpio->port, gpio->pin, alt_fn); - } - } - - // Set not interrupt pin modes - switch(mode) { - case GpioModeInput: - LL_GPIO_SetPinMode(gpio->port, gpio->pin, LL_GPIO_MODE_INPUT); - break; - case GpioModeOutputPushPull: - LL_GPIO_SetPinOutputType(gpio->port, gpio->pin, LL_GPIO_OUTPUT_PUSHPULL); - LL_GPIO_SetPinMode(gpio->port, gpio->pin, LL_GPIO_MODE_OUTPUT); - break; - case GpioModeAltFunctionPushPull: - LL_GPIO_SetPinOutputType(gpio->port, gpio->pin, LL_GPIO_OUTPUT_PUSHPULL); - LL_GPIO_SetPinMode(gpio->port, gpio->pin, LL_GPIO_MODE_ALTERNATE); - break; - case GpioModeOutputOpenDrain: - LL_GPIO_SetPinOutputType(gpio->port, gpio->pin, LL_GPIO_OUTPUT_OPENDRAIN); - LL_GPIO_SetPinMode(gpio->port, gpio->pin, LL_GPIO_MODE_OUTPUT); - break; - case GpioModeAltFunctionOpenDrain: - LL_GPIO_SetPinOutputType(gpio->port, gpio->pin, LL_GPIO_OUTPUT_OPENDRAIN); - LL_GPIO_SetPinMode(gpio->port, gpio->pin, LL_GPIO_MODE_ALTERNATE); - break; - case GpioModeAnalog: - LL_GPIO_SetPinMode(gpio->port, gpio->pin, LL_GPIO_MODE_ANALOG); - break; - default: - break; - } - } - __enable_irq(); -} - -void furi_hal_gpio_add_int_callback(const GpioPin* gpio, GpioExtiCallback cb, void* ctx) { - assert(gpio); - assert(cb); - - __disable_irq(); - uint8_t pin_num = furi_hal_gpio_get_pin_num(gpio); - gpio_interrupt[pin_num].callback = cb; - gpio_interrupt[pin_num].context = ctx; - gpio_interrupt[pin_num].ready = true; - __enable_irq(); -} - -void furi_hal_gpio_enable_int_callback(const GpioPin* gpio) { - assert(gpio); - - __disable_irq(); - uint8_t pin_num = furi_hal_gpio_get_pin_num(gpio); - if(gpio_interrupt[pin_num].callback) { - gpio_interrupt[pin_num].ready = true; - } - __enable_irq(); -} - -void furi_hal_gpio_disable_int_callback(const GpioPin* gpio) { - assert(gpio); - - __disable_irq(); - uint8_t pin_num = furi_hal_gpio_get_pin_num(gpio); - gpio_interrupt[pin_num].ready = false; - __enable_irq(); -} - -void furi_hal_gpio_remove_int_callback(const GpioPin* gpio) { - assert(gpio); - - __disable_irq(); - uint8_t pin_num = furi_hal_gpio_get_pin_num(gpio); - gpio_interrupt[pin_num].callback = NULL; - gpio_interrupt[pin_num].context = NULL; - gpio_interrupt[pin_num].ready = false; - __enable_irq(); -} diff --git a/bootloader/targets/f7/furi_hal/furi_hal_gpio.h b/bootloader/targets/f7/furi_hal/furi_hal_gpio.h deleted file mode 100644 index f633e834c76..00000000000 --- a/bootloader/targets/f7/furi_hal/furi_hal_gpio.h +++ /dev/null @@ -1,264 +0,0 @@ -#pragma once -#include "stdbool.h" -#include "main.h" -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * Number of gpio on one port - */ -#define GPIO_NUMBER (16U) - -/** - * Interrupt callback prototype - */ -typedef void (*GpioExtiCallback)(void* ctx); - -/** - * Gpio interrupt type - */ -typedef struct { - GpioExtiCallback callback; - void* context; - volatile bool ready; -} GpioInterrupt; - -/** - * Gpio modes - */ -typedef enum { - GpioModeInput, - GpioModeOutputPushPull, - GpioModeOutputOpenDrain, - GpioModeAltFunctionPushPull, - GpioModeAltFunctionOpenDrain, - GpioModeAnalog, - GpioModeInterruptRise, - GpioModeInterruptFall, - GpioModeInterruptRiseFall, - GpioModeEventRise, - GpioModeEventFall, - GpioModeEventRiseFall, -} GpioMode; - -/** - * Gpio pull modes - */ -typedef enum { - GpioPullNo, - GpioPullUp, - GpioPullDown, -} GpioPull; - -/** - * Gpio speed modes - */ -typedef enum { - GpioSpeedLow, - GpioSpeedMedium, - GpioSpeedHigh, - GpioSpeedVeryHigh, -} GpioSpeed; - -/** - * Gpio alternate functions - */ -typedef enum { - GpioAltFn0MCO = 0, /*!< MCO Alternate Function mapping */ - GpioAltFn0LSCO = 0, /*!< LSCO Alternate Function mapping */ - GpioAltFn0JTMS_SWDIO = 0, /*!< JTMS-SWDIO Alternate Function mapping */ - GpioAltFn0JTCK_SWCLK = 0, /*!< JTCK-SWCLK Alternate Function mapping */ - GpioAltFn0JTDI = 0, /*!< JTDI Alternate Function mapping */ - GpioAltFn0RTC_OUT = 0, /*!< RCT_OUT Alternate Function mapping */ - GpioAltFn0JTD_TRACE = 0, /*!< JTDO-TRACESWO Alternate Function mapping */ - GpioAltFn0NJTRST = 0, /*!< NJTRST Alternate Function mapping */ - GpioAltFn0RTC_REFIN = 0, /*!< RTC_REFIN Alternate Function mapping */ - GpioAltFn0TRACED0 = 0, /*!< TRACED0 Alternate Function mapping */ - GpioAltFn0TRACED1 = 0, /*!< TRACED1 Alternate Function mapping */ - GpioAltFn0TRACED2 = 0, /*!< TRACED2 Alternate Function mapping */ - GpioAltFn0TRACED3 = 0, /*!< TRACED3 Alternate Function mapping */ - GpioAltFn0TRIG_INOUT = 0, /*!< TRIG_INOUT Alternate Function mapping */ - GpioAltFn0TRACECK = 0, /*!< TRACECK Alternate Function mapping */ - GpioAltFn0SYS = 0, /*!< System Function mapping */ - - GpioAltFn1TIM1 = 1, /*!< TIM1 Alternate Function mapping */ - GpioAltFn1TIM2 = 1, /*!< TIM2 Alternate Function mapping */ - GpioAltFn1LPTIM1 = 1, /*!< LPTIM1 Alternate Function mapping */ - - GpioAltFn2TIM2 = 2, /*!< TIM2 Alternate Function mapping */ - GpioAltFn2TIM1 = 2, /*!< TIM1 Alternate Function mapping */ - - GpioAltFn3SAI1 = 3, /*!< SAI1_CK1 Alternate Function mapping */ - GpioAltFn3SPI2 = 3, /*!< SPI2 Alternate Function mapping */ - GpioAltFn3TIM1 = 3, /*!< TIM1 Alternate Function mapping */ - - GpioAltFn4I2C1 = 4, /*!< I2C1 Alternate Function mapping */ - GpioAltFn4I2C3 = 4, /*!< I2C3 Alternate Function mapping */ - - GpioAltFn5SPI1 = 5, /*!< SPI1 Alternate Function mapping */ - GpioAltFn5SPI2 = 5, /*!< SPI2 Alternate Function mapping */ - - GpioAltFn6MCO = 6, /*!< MCO Alternate Function mapping */ - GpioAltFn6LSCO = 6, /*!< LSCO Alternate Function mapping */ - GpioAltFn6RF_DTB0 = 6, /*!< RF_DTB0 Alternate Function mapping */ - GpioAltFn6RF_DTB1 = 6, /*!< RF_DTB1 Alternate Function mapping */ - GpioAltFn6RF_DTB2 = 6, /*!< RF_DTB2 Alternate Function mapping */ - GpioAltFn6RF_DTB3 = 6, /*!< RF_DTB3 Alternate Function mapping */ - GpioAltFn6RF_DTB4 = 6, /*!< RF_DTB4 Alternate Function mapping */ - GpioAltFn6RF_DTB5 = 6, /*!< RF_DTB5 Alternate Function mapping */ - GpioAltFn6RF_DTB6 = 6, /*!< RF_DTB6 Alternate Function mapping */ - GpioAltFn6RF_DTB7 = 6, /*!< RF_DTB7 Alternate Function mapping */ - GpioAltFn6RF_DTB8 = 6, /*!< RF_DTB8 Alternate Function mapping */ - GpioAltFn6RF_DTB9 = 6, /*!< RF_DTB9 Alternate Function mapping */ - GpioAltFn6RF_DTB10 = 6, /*!< RF_DTB10 Alternate Function mapping */ - GpioAltFn6RF_DTB11 = 6, /*!< RF_DTB11 Alternate Function mapping */ - GpioAltFn6RF_DTB12 = 6, /*!< RF_DTB12 Alternate Function mapping */ - GpioAltFn6RF_DTB13 = 6, /*!< RF_DTB13 Alternate Function mapping */ - GpioAltFn6RF_DTB14 = 6, /*!< RF_DTB14 Alternate Function mapping */ - GpioAltFn6RF_DTB15 = 6, /*!< RF_DTB15 Alternate Function mapping */ - GpioAltFn6RF_DTB16 = 6, /*!< RF_DTB16 Alternate Function mapping */ - GpioAltFn6RF_DTB17 = 6, /*!< RF_DTB17 Alternate Function mapping */ - GpioAltFn6RF_DTB18 = 6, /*!< RF_DTB18 Alternate Function mapping */ - GpioAltFn6RF_MISO = 6, /*!< RF_MISO Alternate Function mapping */ - GpioAltFn6RF_MOSI = 6, /*!< RF_MOSI Alternate Function mapping */ - GpioAltFn6RF_SCK = 6, /*!< RF_SCK Alternate Function mapping */ - GpioAltFn6RF_NSS = 6, /*!< RF_NSS Alternate Function mapping */ - - GpioAltFn7USART1 = 7, /*!< USART1 Alternate Function mapping */ - - GpioAltFn8LPUART1 = 8, /*!< LPUART1 Alternate Function mapping */ - GpioAltFn8IR = 8, /*!< IR Alternate Function mapping */ - - GpioAltFn9TSC = 9, /*!< TSC Alternate Function mapping */ - - GpioAltFn10QUADSPI = 10, /*!< QUADSPI Alternate Function mapping */ - GpioAltFn10USB = 10, /*!< USB Alternate Function mapping */ - - GpioAltFn11LCD = 11, /*!< LCD Alternate Function mapping */ - - GpioAltFn12COMP1 = 12, /*!< COMP1 Alternate Function mapping */ - GpioAltFn12COMP2 = 12, /*!< COMP2 Alternate Function mapping */ - GpioAltFn12TIM1 = 12, /*!< TIM1 Alternate Function mapping */ - - GpioAltFn13SAI1 = 13, /*!< SAI1 Alternate Function mapping */ - - GpioAltFn14TIM2 = 14, /*!< TIM2 Alternate Function mapping */ - GpioAltFn14TIM16 = 14, /*!< TIM16 Alternate Function mapping */ - GpioAltFn14TIM17 = 14, /*!< TIM17 Alternate Function mapping */ - GpioAltFn14LPTIM2 = 14, /*!< LPTIM2 Alternate Function mapping */ - - GpioAltFn15EVENTOUT = 15, /*!< EVENTOUT Alternate Function mapping */ - - GpioAltFnUnused = 16, /*!< just dummy value */ -} GpioAltFn; - -/** - * Gpio structure - */ -typedef struct { - GPIO_TypeDef* port; - uint16_t pin; -} GpioPin; - -/** - * GPIO initialization function, simple version - * @param gpio GpioPin - * @param mode GpioMode - */ -void furi_hal_gpio_init_simple(const GpioPin* gpio, const GpioMode mode); - -/** - * GPIO initialization function, normal version - * @param gpio GpioPin - * @param mode GpioMode - * @param pull GpioPull - * @param speed GpioSpeed - */ -void furi_hal_gpio_init( - const GpioPin* gpio, - const GpioMode mode, - const GpioPull pull, - const GpioSpeed speed); - -/** - * GPIO initialization function, extended version - * @param gpio GpioPin - * @param mode GpioMode - * @param pull GpioPull - * @param speed GpioSpeed - * @param alt_fn GpioAltFn - */ -void furi_hal_gpio_init_ex( - const GpioPin* gpio, - const GpioMode mode, - const GpioPull pull, - const GpioSpeed speed, - const GpioAltFn alt_fn); - -/** - * Add and enable interrupt - * @param gpio GpioPin - * @param cb GpioExtiCallback - * @param ctx context for callback - */ -void furi_hal_gpio_add_int_callback(const GpioPin* gpio, GpioExtiCallback cb, void* ctx); - -/** - * Enable interrupt - * @param gpio GpioPin - */ -void furi_hal_gpio_enable_int_callback(const GpioPin* gpio); - -/** - * Disable interrupt - * @param gpio GpioPin - */ -void furi_hal_gpio_disable_int_callback(const GpioPin* gpio); - -/** - * Remove interrupt - * @param gpio GpioPin - */ -void furi_hal_gpio_remove_int_callback(const GpioPin* gpio); - -/** - * GPIO write pin - * @param gpio GpioPin - * @param state true / false - */ -static inline void furi_hal_gpio_write(const GpioPin* gpio, const bool state) { - // writing to BSSR is an atomic operation - if(state == true) { - gpio->port->BSRR = gpio->pin; - } else { - gpio->port->BSRR = (uint32_t)gpio->pin << GPIO_NUMBER; - } -} - -/** - * GPIO read pin - * @param gpio GpioPin - * @return true / false - */ -static inline bool furi_hal_gpio_read(const GpioPin* gpio) { - if((gpio->port->IDR & gpio->pin) != 0x00U) { - return true; - } else { - return false; - } -} - -/** - * Get RFID IN level - * @return false = LOW, true = HIGH - */ -bool furi_hal_gpio_get_rfid_in_level(); - -#ifdef __cplusplus -} -#endif diff --git a/bootloader/targets/f7/furi_hal/furi_hal_i2c.c b/bootloader/targets/f7/furi_hal/furi_hal_i2c.c deleted file mode 100644 index 210f96d63b0..00000000000 --- a/bootloader/targets/f7/furi_hal/furi_hal_i2c.c +++ /dev/null @@ -1,205 +0,0 @@ -#include -#include - -#include -#include -#include - -#include - -void furi_hal_i2c_init() { - furi_hal_i2c_bus_power.callback(&furi_hal_i2c_bus_power, FuriHalI2cBusEventInit); -} - -void furi_hal_i2c_acquire(FuriHalI2cBusHandle* handle) { - handle->bus->callback(handle->bus, FuriHalI2cBusEventLock); - - assert(handle->bus->current_handle == NULL); - - handle->bus->current_handle = handle; - - handle->bus->callback(handle->bus, FuriHalI2cBusEventActivate); - - handle->callback(handle, FuriHalI2cBusHandleEventActivate); -} - -void furi_hal_i2c_release(FuriHalI2cBusHandle* handle) { - assert(handle->bus->current_handle == handle); - - handle->callback(handle, FuriHalI2cBusHandleEventDeactivate); - - handle->bus->callback(handle->bus, FuriHalI2cBusEventDeactivate); - - handle->bus->current_handle = NULL; - - handle->bus->callback(handle->bus, FuriHalI2cBusEventUnlock); -} - -bool furi_hal_i2c_tx( - FuriHalI2cBusHandle* handle, - uint8_t address, - const uint8_t* data, - uint8_t size, - uint32_t timeout) { - assert(handle->bus->current_handle == handle); - uint32_t time_left = timeout; - bool ret = true; - - while(LL_I2C_IsActiveFlag_BUSY(handle->bus->i2c)) - ; - - LL_I2C_HandleTransfer( - handle->bus->i2c, - address, - LL_I2C_ADDRSLAVE_7BIT, - size, - LL_I2C_MODE_AUTOEND, - LL_I2C_GENERATE_START_WRITE); - - while(!LL_I2C_IsActiveFlag_STOP(handle->bus->i2c) || size > 0) { - if(LL_I2C_IsActiveFlag_TXIS(handle->bus->i2c)) { - LL_I2C_TransmitData8(handle->bus->i2c, (*data)); - data++; - size--; - time_left = timeout; - } - - if(LL_SYSTICK_IsActiveCounterFlag()) { - if(--time_left == 0) { - ret = false; - break; - } - } - } - - LL_I2C_ClearFlag_STOP(handle->bus->i2c); - - return ret; -} - -bool furi_hal_i2c_rx( - FuriHalI2cBusHandle* handle, - uint8_t address, - uint8_t* data, - uint8_t size, - uint32_t timeout) { - assert(handle->bus->current_handle == handle); - uint32_t time_left = timeout; - bool ret = true; - - while(LL_I2C_IsActiveFlag_BUSY(handle->bus->i2c)) - ; - - LL_I2C_HandleTransfer( - handle->bus->i2c, - address, - LL_I2C_ADDRSLAVE_7BIT, - size, - LL_I2C_MODE_AUTOEND, - LL_I2C_GENERATE_START_READ); - - while(!LL_I2C_IsActiveFlag_STOP(handle->bus->i2c) || size > 0) { - if(LL_I2C_IsActiveFlag_RXNE(handle->bus->i2c)) { - *data = LL_I2C_ReceiveData8(handle->bus->i2c); - data++; - size--; - time_left = timeout; - } - - if(LL_SYSTICK_IsActiveCounterFlag()) { - if(--time_left == 0) { - ret = false; - break; - } - } - } - - LL_I2C_ClearFlag_STOP(handle->bus->i2c); - - return ret; -} - -bool furi_hal_i2c_trx( - FuriHalI2cBusHandle* handle, - uint8_t address, - const uint8_t* tx_data, - uint8_t tx_size, - uint8_t* rx_data, - uint8_t rx_size, - uint32_t timeout) { - if(furi_hal_i2c_tx(handle, address, tx_data, tx_size, timeout) && - furi_hal_i2c_rx(handle, address, rx_data, rx_size, timeout)) { - return true; - } else { - return false; - } -} - -bool furi_hal_i2c_read_reg_8( - FuriHalI2cBusHandle* handle, - uint8_t i2c_addr, - uint8_t reg_addr, - uint8_t* data, - uint32_t timeout) { - assert(handle); - - return furi_hal_i2c_trx(handle, i2c_addr, ®_addr, 1, data, 1, timeout); -} - -bool furi_hal_i2c_read_reg_16( - FuriHalI2cBusHandle* handle, - uint8_t i2c_addr, - uint8_t reg_addr, - uint16_t* data, - uint32_t timeout) { - assert(handle); - - uint8_t reg_data[2]; - bool ret = furi_hal_i2c_trx(handle, i2c_addr, ®_addr, 1, reg_data, 2, timeout); - *data = (reg_data[0] << 8) | (reg_data[1]); - - return ret; -} - -bool furi_hal_i2c_read_mem( - FuriHalI2cBusHandle* handle, - uint8_t i2c_addr, - uint8_t mem_addr, - uint8_t* data, - uint8_t len, - uint32_t timeout) { - assert(handle); - - return furi_hal_i2c_trx(handle, i2c_addr, &mem_addr, 1, data, len, timeout); -} - -bool furi_hal_i2c_write_reg_8( - FuriHalI2cBusHandle* handle, - uint8_t i2c_addr, - uint8_t reg_addr, - uint8_t data, - uint32_t timeout) { - assert(handle); - - uint8_t tx_data[2]; - tx_data[0] = reg_addr; - tx_data[1] = data; - - return furi_hal_i2c_tx(handle, i2c_addr, (const uint8_t*)&tx_data, 2, timeout); -} - -bool furi_hal_i2c_write_reg_16( - FuriHalI2cBusHandle* handle, - uint8_t i2c_addr, - uint8_t reg_addr, - uint16_t data, - uint32_t timeout) { - assert(handle); - - uint8_t tx_data[3]; - tx_data[0] = reg_addr; - tx_data[1] = (data >> 8) & 0xFF; - tx_data[2] = data & 0xFF; - - return furi_hal_i2c_tx(handle, i2c_addr, (const uint8_t*)&tx_data, 3, timeout); -} diff --git a/bootloader/targets/f7/furi_hal/furi_hal_i2c.h b/bootloader/targets/f7/furi_hal/furi_hal_i2c.h deleted file mode 100644 index c2ad172803f..00000000000 --- a/bootloader/targets/f7/furi_hal/furi_hal_i2c.h +++ /dev/null @@ -1,195 +0,0 @@ -/** - * @file furi_hal_i2c.h - * I2C HAL API - */ - -#pragma once - -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** Init I2C - */ -void furi_hal_i2c_init(); - -/** Acquire i2c bus handle - * - * @return Instance of FuriHalI2cBus - */ -void furi_hal_i2c_acquire(FuriHalI2cBusHandle* handle); - -/** Release i2c bus handle - * - * @param bus instance of FuriHalI2cBus aquired in `furi_hal_i2c_acquire` - */ -void furi_hal_i2c_release(FuriHalI2cBusHandle* handle); - -/** Perform I2C tx transfer - * - * @param handle pointer to FuriHalI2cBusHandle instance - * @param address I2C slave address - * @param data pointer to data buffer - * @param size size of data buffer - * @param timeout timeout in ticks - * - * @return true on successful transfer, false otherwise - */ -bool furi_hal_i2c_tx( - FuriHalI2cBusHandle* handle, - const uint8_t address, - const uint8_t* data, - const uint8_t size, - uint32_t timeout); - -/** Perform I2C rx transfer - * - * @param handle pointer to FuriHalI2cBusHandle instance - * @param address I2C slave address - * @param data pointer to data buffer - * @param size size of data buffer - * @param timeout timeout in ticks - * - * @return true on successful transfer, false otherwise - */ -bool furi_hal_i2c_rx( - FuriHalI2cBusHandle* handle, - const uint8_t address, - uint8_t* data, - const uint8_t size, - uint32_t timeout); - -/** Perform I2C tx and rx transfers - * - * @param handle pointer to FuriHalI2cBusHandle instance - * @param address I2C slave address - * @param tx_data pointer to tx data buffer - * @param tx_size size of tx data buffer - * @param rx_data pointer to rx data buffer - * @param rx_size size of rx data buffer - * @param timeout timeout in ticks - * - * @return true on successful transfer, false otherwise - */ -bool furi_hal_i2c_trx( - FuriHalI2cBusHandle* handle, - const uint8_t address, - const uint8_t* tx_data, - const uint8_t tx_size, - uint8_t* rx_data, - const uint8_t rx_size, - uint32_t timeout); - -/** Perform I2C device register read (8-bit) - * - * @param handle pointer to FuriHalI2cBusHandle instance - * @param i2c_addr I2C slave address - * @param reg_addr register address - * @param data pointer to register value - * @param timeout timeout in ticks - * - * @return true on successful transfer, false otherwise - */ -bool furi_hal_i2c_read_reg_8( - FuriHalI2cBusHandle* handle, - uint8_t i2c_addr, - uint8_t reg_addr, - uint8_t* data, - uint32_t timeout); - -/** Perform I2C device register read (16-bit) - * - * @param handle pointer to FuriHalI2cBusHandle instance - * @param i2c_addr I2C slave address - * @param reg_addr register address - * @param data pointer to register value - * @param timeout timeout in ticks - * - * @return true on successful transfer, false otherwise - */ -bool furi_hal_i2c_read_reg_16( - FuriHalI2cBusHandle* handle, - uint8_t i2c_addr, - uint8_t reg_addr, - uint16_t* data, - uint32_t timeout); - -/** Perform I2C device memory read - * - * @param handle pointer to FuriHalI2cBusHandle instance - * @param i2c_addr I2C slave address - * @param mem_addr memory start address - * @param data pointer to data buffer - * @param len size of data buffer - * @param timeout timeout in ticks - * - * @return true on successful transfer, false otherwise - */ -bool furi_hal_i2c_read_mem( - FuriHalI2cBusHandle* handle, - uint8_t i2c_addr, - uint8_t mem_addr, - uint8_t* data, - uint8_t len, - uint32_t timeout); - -/** Perform I2C device register write (8-bit) - * - * @param handle pointer to FuriHalI2cBusHandle instance - * @param i2c_addr I2C slave address - * @param reg_addr register address - * @param data register value - * @param timeout timeout in ticks - * - * @return true on successful transfer, false otherwise - */ -bool furi_hal_i2c_write_reg_8( - FuriHalI2cBusHandle* handle, - uint8_t i2c_addr, - uint8_t reg_addr, - uint8_t data, - uint32_t timeout); - -/** Perform I2C device register write (16-bit) - * - * @param handle pointer to FuriHalI2cBusHandle instance - * @param i2c_addr I2C slave address - * @param reg_addr register address - * @param data register value - * @param timeout timeout in ticks - * - * @return true on successful transfer, false otherwise - */ -bool furi_hal_i2c_write_reg_16( - FuriHalI2cBusHandle* handle, - uint8_t i2c_addr, - uint8_t reg_addr, - uint16_t data, - uint32_t timeout); - -/** Perform I2C device memory - * - * @param handle pointer to FuriHalI2cBusHandle instance - * @param i2c_addr I2C slave address - * @param mem_addr memory start address - * @param data pointer to data buffer - * @param len size of data buffer - * @param timeout timeout in ticks - * - * @return true on successful transfer, false otherwise - */ -bool furi_hal_i2c_write_mem( - FuriHalI2cBusHandle* handle, - uint8_t i2c_addr, - uint8_t mem_addr, - uint8_t* data, - uint8_t len, - uint32_t timeout); - -#ifdef __cplusplus -} -#endif diff --git a/bootloader/targets/f7/furi_hal/furi_hal_i2c_config.c b/bootloader/targets/f7/furi_hal/furi_hal_i2c_config.c deleted file mode 100644 index e693911a13a..00000000000 --- a/bootloader/targets/f7/furi_hal/furi_hal_i2c_config.c +++ /dev/null @@ -1,151 +0,0 @@ -#include "furi_hal_i2c_config.h" -#include -#include - -#include -#include - -/** Timing register value is computed with the STM32CubeMX Tool, - * Standard Mode @100kHz with I2CCLK = 64 MHz, - * rise time = 0ns, fall time = 0ns - */ -#define FURI_HAL_I2C_CONFIG_POWER_I2C_TIMINGS_100 0x10707DBC - -/** Timing register value is computed with the STM32CubeMX Tool, - * Fast Mode @400kHz with I2CCLK = 64 MHz, - * rise time = 0ns, fall time = 0ns - */ -#define FURI_HAL_I2C_CONFIG_POWER_I2C_TIMINGS_400 0x00602173 - -static void furi_hal_i2c_bus_power_event(FuriHalI2cBus* bus, FuriHalI2cBusEvent event) { - if(event == FuriHalI2cBusEventInit) { - LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_I2C1); - LL_RCC_SetI2CClockSource(LL_RCC_I2C1_CLKSOURCE_PCLK1); - LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_I2C1); - bus->current_handle = NULL; - } else if(event == FuriHalI2cBusEventDeinit) { - } else if(event == FuriHalI2cBusEventLock) { - } else if(event == FuriHalI2cBusEventUnlock) { - } else if(event == FuriHalI2cBusEventActivate) { - LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_I2C1); - } else if(event == FuriHalI2cBusEventDeactivate) { - LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_I2C1); - } -} - -FuriHalI2cBus furi_hal_i2c_bus_power = { - .i2c = I2C1, - .current_handle = NULL, - .callback = furi_hal_i2c_bus_power_event, -}; - -static void furi_hal_i2c_bus_external_event(FuriHalI2cBus* bus, FuriHalI2cBusEvent event) { - if(event == FuriHalI2cBusEventActivate) { - LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_I2C3); - LL_RCC_SetI2CClockSource(LL_RCC_I2C3_CLKSOURCE_PCLK1); - LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_I2C3); - } else if(event == FuriHalI2cBusEventDeactivate) { - LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_I2C3); - } -} - -FuriHalI2cBus furi_hal_i2c_bus_external = { - .i2c = I2C3, - .current_handle = NULL, - .callback = furi_hal_i2c_bus_external_event, -}; - -void furi_hal_i2c_bus_handle_power_event( - FuriHalI2cBusHandle* handle, - FuriHalI2cBusHandleEvent event) { - if(event == FuriHalI2cBusHandleEventActivate) { - LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOA); - furi_hal_gpio_init_ex( - &gpio_i2c_power_sda, - GpioModeAltFunctionOpenDrain, - GpioPullNo, - GpioSpeedLow, - GpioAltFn4I2C1); - furi_hal_gpio_init_ex( - &gpio_i2c_power_scl, - GpioModeAltFunctionOpenDrain, - GpioPullNo, - GpioSpeedLow, - GpioAltFn4I2C1); - - LL_I2C_InitTypeDef I2C_InitStruct = {0}; - I2C_InitStruct.PeripheralMode = LL_I2C_MODE_I2C; - I2C_InitStruct.AnalogFilter = LL_I2C_ANALOGFILTER_ENABLE; - I2C_InitStruct.DigitalFilter = 0; - I2C_InitStruct.OwnAddress1 = 0; - I2C_InitStruct.TypeAcknowledge = LL_I2C_ACK; - I2C_InitStruct.OwnAddrSize = LL_I2C_OWNADDRESS1_7BIT; - if(furi_hal_version_get_hw_version() > 10) { - I2C_InitStruct.Timing = FURI_HAL_I2C_CONFIG_POWER_I2C_TIMINGS_400; - } else { - I2C_InitStruct.Timing = FURI_HAL_I2C_CONFIG_POWER_I2C_TIMINGS_100; - } - LL_I2C_Init(handle->bus->i2c, &I2C_InitStruct); - - LL_I2C_EnableAutoEndMode(handle->bus->i2c); - LL_I2C_SetOwnAddress2(handle->bus->i2c, 0, LL_I2C_OWNADDRESS2_NOMASK); - LL_I2C_DisableOwnAddress2(handle->bus->i2c); - LL_I2C_DisableGeneralCall(handle->bus->i2c); - LL_I2C_EnableClockStretching(handle->bus->i2c); - LL_I2C_Enable(handle->bus->i2c); - } else if(event == FuriHalI2cBusHandleEventDeactivate) { - LL_I2C_Disable(handle->bus->i2c); - furi_hal_gpio_write(&gpio_i2c_power_sda, 1); - furi_hal_gpio_write(&gpio_i2c_power_scl, 1); - furi_hal_gpio_init_ex( - &gpio_i2c_power_sda, GpioModeAnalog, GpioPullNo, GpioSpeedLow, GpioAltFnUnused); - furi_hal_gpio_init_ex( - &gpio_i2c_power_scl, GpioModeAnalog, GpioPullNo, GpioSpeedLow, GpioAltFnUnused); - } -} - -FuriHalI2cBusHandle furi_hal_i2c_handle_power = { - .bus = &furi_hal_i2c_bus_power, - .callback = furi_hal_i2c_bus_handle_power_event, -}; - -void furi_hal_i2c_bus_handle_external_event( - FuriHalI2cBusHandle* handle, - FuriHalI2cBusHandleEvent event) { - if(event == FuriHalI2cBusHandleEventActivate) { - furi_hal_gpio_init_ex( - &gpio_ext_pc0, GpioModeAltFunctionOpenDrain, GpioPullNo, GpioSpeedLow, GpioAltFn4I2C3); - furi_hal_gpio_init_ex( - &gpio_ext_pc1, GpioModeAltFunctionOpenDrain, GpioPullNo, GpioSpeedLow, GpioAltFn4I2C3); - - LL_I2C_InitTypeDef I2C_InitStruct = {0}; - I2C_InitStruct.PeripheralMode = LL_I2C_MODE_I2C; - I2C_InitStruct.AnalogFilter = LL_I2C_ANALOGFILTER_ENABLE; - I2C_InitStruct.DigitalFilter = 0; - I2C_InitStruct.OwnAddress1 = 0; - I2C_InitStruct.TypeAcknowledge = LL_I2C_ACK; - I2C_InitStruct.OwnAddrSize = LL_I2C_OWNADDRESS1_7BIT; - I2C_InitStruct.Timing = FURI_HAL_I2C_CONFIG_POWER_I2C_TIMINGS_100; - LL_I2C_Init(handle->bus->i2c, &I2C_InitStruct); - - LL_I2C_EnableAutoEndMode(handle->bus->i2c); - LL_I2C_SetOwnAddress2(handle->bus->i2c, 0, LL_I2C_OWNADDRESS2_NOMASK); - LL_I2C_DisableOwnAddress2(handle->bus->i2c); - LL_I2C_DisableGeneralCall(handle->bus->i2c); - LL_I2C_EnableClockStretching(handle->bus->i2c); - LL_I2C_Enable(handle->bus->i2c); - } else if(event == FuriHalI2cBusHandleEventDeactivate) { - LL_I2C_Disable(handle->bus->i2c); - furi_hal_gpio_write(&gpio_ext_pc0, 1); - furi_hal_gpio_write(&gpio_ext_pc1, 1); - furi_hal_gpio_init_ex( - &gpio_ext_pc0, GpioModeAnalog, GpioPullNo, GpioSpeedLow, GpioAltFnUnused); - furi_hal_gpio_init_ex( - &gpio_ext_pc1, GpioModeAnalog, GpioPullNo, GpioSpeedLow, GpioAltFnUnused); - } -} - -FuriHalI2cBusHandle furi_hal_i2c_handle_external = { - .bus = &furi_hal_i2c_bus_external, - .callback = furi_hal_i2c_bus_handle_external_event, -}; diff --git a/bootloader/targets/f7/furi_hal/furi_hal_i2c_config.h b/bootloader/targets/f7/furi_hal/furi_hal_i2c_config.h deleted file mode 100644 index 03c0f1ca1c2..00000000000 --- a/bootloader/targets/f7/furi_hal/furi_hal_i2c_config.h +++ /dev/null @@ -1,31 +0,0 @@ -#pragma once - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** Internal(power) i2c bus, I2C1, under reset when not used */ -extern FuriHalI2cBus furi_hal_i2c_bus_power; - -/** External i2c bus, I2C3, under reset when not used */ -extern FuriHalI2cBus furi_hal_i2c_bus_external; - -/** Handle for internal(power) i2c bus - * Bus: furi_hal_i2c_bus_external - * Pins: PA9(SCL) / PA10(SDA), float on release - * Params: 400khz - */ -extern FuriHalI2cBusHandle furi_hal_i2c_handle_power; - -/** Handle for external i2c bus - * Bus: furi_hal_i2c_bus_external - * Pins: PC0(SCL) / PC1(SDA), float on release - * Params: 100khz - */ -extern FuriHalI2cBusHandle furi_hal_i2c_handle_external; - -#ifdef __cplusplus -} -#endif \ No newline at end of file diff --git a/bootloader/targets/f7/furi_hal/furi_hal_i2c_types.h b/bootloader/targets/f7/furi_hal/furi_hal_i2c_types.h deleted file mode 100644 index 0f2b735e4db..00000000000 --- a/bootloader/targets/f7/furi_hal/furi_hal_i2c_types.h +++ /dev/null @@ -1,51 +0,0 @@ -#pragma once - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct FuriHalI2cBus FuriHalI2cBus; -typedef struct FuriHalI2cBusHandle FuriHalI2cBusHandle; - -/** FuriHal i2c bus states */ -typedef enum { - FuriHalI2cBusEventInit, /**< Bus initialization event, called on system start */ - FuriHalI2cBusEventDeinit, /**< Bus deinitialization event, called on system stop */ - FuriHalI2cBusEventLock, /**< Bus lock event, called before activation */ - FuriHalI2cBusEventUnlock, /**< Bus unlock event, called after deactivation */ - FuriHalI2cBusEventActivate, /**< Bus activation event, called before handle activation */ - FuriHalI2cBusEventDeactivate, /**< Bus deactivation event, called after handle deactivation */ -} FuriHalI2cBusEvent; - -/** FuriHal i2c bus event callback */ -typedef void (*FuriHalI2cBusEventCallback)(FuriHalI2cBus* bus, FuriHalI2cBusEvent event); - -/** FuriHal i2c bus */ -struct FuriHalI2cBus { - I2C_TypeDef* i2c; - FuriHalI2cBusHandle* current_handle; - FuriHalI2cBusEventCallback callback; -}; - -/** FuriHal i2c handle states */ -typedef enum { - FuriHalI2cBusHandleEventActivate, /**< Handle activate: connect gpio and apply bus config */ - FuriHalI2cBusHandleEventDeactivate, /**< Handle deactivate: disconnect gpio and reset bus config */ -} FuriHalI2cBusHandleEvent; - -/** FuriHal i2c handle event callback */ -typedef void (*FuriHalI2cBusHandleEventCallback)( - FuriHalI2cBusHandle* handle, - FuriHalI2cBusHandleEvent event); - -/** FuriHal i2c handle */ -struct FuriHalI2cBusHandle { - FuriHalI2cBus* bus; - FuriHalI2cBusHandleEventCallback callback; -}; - -#ifdef __cplusplus -} -#endif \ No newline at end of file diff --git a/bootloader/targets/f7/furi_hal/furi_hal_light.c b/bootloader/targets/f7/furi_hal/furi_hal_light.c deleted file mode 100644 index 6aba7efb7f2..00000000000 --- a/bootloader/targets/f7/furi_hal/furi_hal_light.c +++ /dev/null @@ -1,49 +0,0 @@ -#include -#include - -#define LED_CURRENT_RED 50 -#define LED_CURRENT_GREEN 50 -#define LED_CURRENT_BLUE 50 -#define LED_CURRENT_WHITE 150 - -void furi_hal_light_init() { - furi_hal_i2c_acquire(&furi_hal_i2c_handle_power); - - lp5562_reset(&furi_hal_i2c_handle_power); - - lp5562_set_channel_current(&furi_hal_i2c_handle_power, LP5562ChannelRed, LED_CURRENT_RED); - lp5562_set_channel_current(&furi_hal_i2c_handle_power, LP5562ChannelGreen, LED_CURRENT_GREEN); - lp5562_set_channel_current(&furi_hal_i2c_handle_power, LP5562ChannelBlue, LED_CURRENT_BLUE); - lp5562_set_channel_current(&furi_hal_i2c_handle_power, LP5562ChannelWhite, LED_CURRENT_WHITE); - - lp5562_set_channel_value(&furi_hal_i2c_handle_power, LP5562ChannelRed, 0x00); - lp5562_set_channel_value(&furi_hal_i2c_handle_power, LP5562ChannelGreen, 0x00); - lp5562_set_channel_value(&furi_hal_i2c_handle_power, LP5562ChannelBlue, 0x00); - lp5562_set_channel_value(&furi_hal_i2c_handle_power, LP5562ChannelWhite, 0x00); - - lp5562_enable(&furi_hal_i2c_handle_power); - lp5562_configure(&furi_hal_i2c_handle_power); - - furi_hal_i2c_release(&furi_hal_i2c_handle_power); -} - -void furi_hal_light_set(Light light, uint8_t value) { - furi_hal_i2c_acquire(&furi_hal_i2c_handle_power); - switch(light) { - case LightRed: - lp5562_set_channel_value(&furi_hal_i2c_handle_power, LP5562ChannelRed, value); - break; - case LightGreen: - lp5562_set_channel_value(&furi_hal_i2c_handle_power, LP5562ChannelGreen, value); - break; - case LightBlue: - lp5562_set_channel_value(&furi_hal_i2c_handle_power, LP5562ChannelBlue, value); - break; - case LightBacklight: - lp5562_set_channel_value(&furi_hal_i2c_handle_power, LP5562ChannelWhite, value); - break; - default: - break; - } - furi_hal_i2c_release(&furi_hal_i2c_handle_power); -} \ No newline at end of file diff --git a/bootloader/targets/f7/furi_hal/furi_hal_light.h b/bootloader/targets/f7/furi_hal/furi_hal_light.h deleted file mode 100644 index c585ddf52ac..00000000000 --- a/bootloader/targets/f7/furi_hal/furi_hal_light.h +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once - -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -void furi_hal_light_init(); - -void furi_hal_light_set(Light light, uint8_t value); - -#ifdef __cplusplus -} -#endif diff --git a/bootloader/targets/f7/furi_hal/furi_hal_resources.c b/bootloader/targets/f7/furi_hal/furi_hal_resources.c deleted file mode 100644 index fd792aa6e68..00000000000 --- a/bootloader/targets/f7/furi_hal/furi_hal_resources.c +++ /dev/null @@ -1,43 +0,0 @@ -#include "furi_hal_resources.h" - -const GpioPin vibro_gpio = {.port = VIBRO_GPIO_Port, .pin = VIBRO_Pin}; -const GpioPin ibutton_gpio = {.port = iBTN_GPIO_Port, .pin = iBTN_Pin}; - -const GpioPin gpio_cc1101_g0 = {.port = CC1101_G0_GPIO_Port, .pin = CC1101_G0_Pin}; -const GpioPin gpio_rf_sw_0 = {.port = RF_SW_0_GPIO_Port, .pin = RF_SW_0_Pin}; - -const GpioPin gpio_subghz_cs = {.port = CC1101_CS_GPIO_Port, .pin = CC1101_CS_Pin}; -const GpioPin gpio_display_cs = {.port = DISPLAY_CS_GPIO_Port, .pin = DISPLAY_CS_Pin}; -const GpioPin gpio_display_rst = {.port = DISPLAY_RST_GPIO_Port, .pin = DISPLAY_RST_Pin}; -const GpioPin gpio_display_di = {.port = DISPLAY_DI_GPIO_Port, .pin = DISPLAY_DI_Pin}; -const GpioPin gpio_sdcard_cs = {.port = SD_CS_GPIO_Port, .pin = SD_CS_Pin}; -const GpioPin gpio_nfc_cs = {.port = NFC_CS_GPIO_Port, .pin = NFC_CS_Pin}; - -const GpioPin gpio_spi_d_miso = {.port = SPI_D_MISO_GPIO_Port, .pin = SPI_D_MISO_Pin}; -const GpioPin gpio_spi_d_mosi = {.port = SPI_D_MOSI_GPIO_Port, .pin = SPI_D_MOSI_Pin}; -const GpioPin gpio_spi_d_sck = {.port = SPI_D_SCK_GPIO_Port, .pin = SPI_D_SCK_Pin}; -const GpioPin gpio_spi_r_miso = {.port = SPI_R_MISO_GPIO_Port, .pin = SPI_R_MISO_Pin}; -const GpioPin gpio_spi_r_mosi = {.port = SPI_R_MOSI_GPIO_Port, .pin = SPI_R_MOSI_Pin}; -const GpioPin gpio_spi_r_sck = {.port = SPI_R_SCK_GPIO_Port, .pin = SPI_R_SCK_Pin}; - -const GpioPin gpio_ext_pc0 = {.port = GPIOC, .pin = LL_GPIO_PIN_0}; -const GpioPin gpio_ext_pc1 = {.port = GPIOC, .pin = LL_GPIO_PIN_1}; -const GpioPin gpio_ext_pc3 = {.port = GPIOC, .pin = LL_GPIO_PIN_3}; -const GpioPin gpio_ext_pb2 = {.port = GPIOB, .pin = LL_GPIO_PIN_2}; -const GpioPin gpio_ext_pb3 = {.port = GPIOB, .pin = LL_GPIO_PIN_3}; -const GpioPin gpio_ext_pa4 = {.port = GPIOA, .pin = LL_GPIO_PIN_4}; -const GpioPin gpio_ext_pa6 = {.port = GPIOA, .pin = LL_GPIO_PIN_6}; -const GpioPin gpio_ext_pa7 = {.port = GPIOA, .pin = LL_GPIO_PIN_7}; - -const GpioPin gpio_rfid_pull = {.port = RFID_PULL_GPIO_Port, .pin = RFID_PULL_Pin}; -const GpioPin gpio_rfid_carrier_out = {.port = RFID_OUT_GPIO_Port, .pin = RFID_OUT_Pin}; -const GpioPin gpio_rfid_data_in = {.port = RFID_RF_IN_GPIO_Port, .pin = RFID_RF_IN_Pin}; - -const GpioPin gpio_infrared_rx = {.port = IR_RX_GPIO_Port, .pin = IR_RX_Pin}; -const GpioPin gpio_infrared_tx = {.port = IR_TX_GPIO_Port, .pin = IR_TX_Pin}; - -const GpioPin gpio_usart_tx = {.port = USART1_TX_Port, .pin = USART1_TX_Pin}; -const GpioPin gpio_usart_rx = {.port = USART1_RX_Port, .pin = USART1_RX_Pin}; - -const GpioPin gpio_i2c_power_sda = {.port = GPIOA, .pin = LL_GPIO_PIN_10}; -const GpioPin gpio_i2c_power_scl = {.port = GPIOA, .pin = LL_GPIO_PIN_9}; diff --git a/bootloader/targets/f7/furi_hal/furi_hal_resources.h b/bootloader/targets/f7/furi_hal/furi_hal_resources.h deleted file mode 100644 index 925bd5acd0f..00000000000 --- a/bootloader/targets/f7/furi_hal/furi_hal_resources.h +++ /dev/null @@ -1,73 +0,0 @@ -#pragma once - -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* Input Keys */ -typedef enum { - InputKeyUp, - InputKeyDown, - InputKeyRight, - InputKeyLeft, - InputKeyOk, - InputKeyBack, -} InputKey; - -/* Light */ -typedef enum { - LightRed, - LightGreen, - LightBlue, - LightBacklight, -} Light; - -extern const GpioPin vibro_gpio; -extern const GpioPin ibutton_gpio; - -extern const GpioPin gpio_cc1101_g0; -extern const GpioPin gpio_rf_sw_0; - -extern const GpioPin gpio_subghz_cs; -extern const GpioPin gpio_display_cs; -extern const GpioPin gpio_display_rst; -extern const GpioPin gpio_display_di; -extern const GpioPin gpio_sdcard_cs; -extern const GpioPin gpio_nfc_cs; - -extern const GpioPin gpio_spi_d_miso; -extern const GpioPin gpio_spi_d_mosi; -extern const GpioPin gpio_spi_d_sck; -extern const GpioPin gpio_spi_r_miso; -extern const GpioPin gpio_spi_r_mosi; -extern const GpioPin gpio_spi_r_sck; - -extern const GpioPin gpio_ext_pc0; -extern const GpioPin gpio_ext_pc1; -extern const GpioPin gpio_ext_pc3; -extern const GpioPin gpio_ext_pb2; -extern const GpioPin gpio_ext_pb3; -extern const GpioPin gpio_ext_pa4; -extern const GpioPin gpio_ext_pa6; -extern const GpioPin gpio_ext_pa7; - -extern const GpioPin gpio_rfid_pull; -extern const GpioPin gpio_rfid_carrier_out; -extern const GpioPin gpio_rfid_data_in; - -extern const GpioPin gpio_infrared_rx; -extern const GpioPin gpio_infrared_tx; - -extern const GpioPin gpio_usart_tx; -extern const GpioPin gpio_usart_rx; - -extern const GpioPin gpio_i2c_power_sda; -extern const GpioPin gpio_i2c_power_scl; - -#ifdef __cplusplus -} -#endif diff --git a/bootloader/targets/f7/furi_hal/furi_hal_spi.c b/bootloader/targets/f7/furi_hal/furi_hal_spi.c deleted file mode 100644 index 85f2f71b384..00000000000 --- a/bootloader/targets/f7/furi_hal/furi_hal_spi.c +++ /dev/null @@ -1,151 +0,0 @@ -#include "furi_hal_spi.h" -#include "furi_hal_resources.h" - -#include -#include -#include - -#include -#include -#include - -void furi_hal_spi_init() { - furi_hal_spi_bus_init(&furi_hal_spi_bus_r); - furi_hal_spi_bus_init(&furi_hal_spi_bus_d); - - furi_hal_spi_bus_handle_init(&furi_hal_spi_bus_handle_subghz); - furi_hal_spi_bus_handle_init(&furi_hal_spi_bus_handle_nfc); - furi_hal_spi_bus_handle_init(&furi_hal_spi_bus_handle_display); - furi_hal_spi_bus_handle_init(&furi_hal_spi_bus_handle_sd_fast); - furi_hal_spi_bus_handle_init(&furi_hal_spi_bus_handle_sd_slow); -} - -void furi_hal_spi_bus_init(FuriHalSpiBus* bus) { - assert(bus); - bus->callback(bus, FuriHalSpiBusEventInit); -} - -void furi_hal_spi_bus_deinit(FuriHalSpiBus* bus) { - assert(bus); - bus->callback(bus, FuriHalSpiBusEventDeinit); -} - -void furi_hal_spi_bus_handle_init(FuriHalSpiBusHandle* handle) { - assert(handle); - handle->callback(handle, FuriHalSpiBusHandleEventInit); -} - -void furi_hal_spi_bus_handle_deinit(FuriHalSpiBusHandle* handle) { - assert(handle); - handle->callback(handle, FuriHalSpiBusHandleEventDeinit); -} - -void furi_hal_spi_acquire(FuriHalSpiBusHandle* handle) { - assert(handle); - - handle->bus->callback(handle->bus, FuriHalSpiBusEventLock); - handle->bus->callback(handle->bus, FuriHalSpiBusEventActivate); - - assert(handle->bus->current_handle == NULL); - - handle->bus->current_handle = handle; - handle->callback(handle, FuriHalSpiBusHandleEventActivate); -} - -void furi_hal_spi_release(FuriHalSpiBusHandle* handle) { - assert(handle); - assert(handle->bus->current_handle == handle); - - // Handle event and unset handle - handle->callback(handle, FuriHalSpiBusHandleEventDeactivate); - handle->bus->current_handle = NULL; - - // Bus events - handle->bus->callback(handle->bus, FuriHalSpiBusEventDeactivate); - handle->bus->callback(handle->bus, FuriHalSpiBusEventUnlock); -} - -static void furi_hal_spi_bus_end_txrx(FuriHalSpiBusHandle* handle, uint32_t timeout) { - while(LL_SPI_GetTxFIFOLevel(handle->bus->spi) != LL_SPI_TX_FIFO_EMPTY) - ; - while(LL_SPI_IsActiveFlag_BSY(handle->bus->spi)) - ; - while(LL_SPI_GetRxFIFOLevel(handle->bus->spi) != LL_SPI_RX_FIFO_EMPTY) { - LL_SPI_ReceiveData8(handle->bus->spi); - } -} - -bool furi_hal_spi_bus_rx( - FuriHalSpiBusHandle* handle, - uint8_t* buffer, - size_t size, - uint32_t timeout) { - assert(handle); - assert(handle->bus->current_handle == handle); - assert(buffer); - assert(size > 0); - - return furi_hal_spi_bus_trx(handle, buffer, buffer, size, timeout); -} - -bool furi_hal_spi_bus_tx( - FuriHalSpiBusHandle* handle, - uint8_t* buffer, - size_t size, - uint32_t timeout) { - assert(handle); - assert(handle->bus->current_handle == handle); - assert(buffer); - assert(size > 0); - bool ret = true; - - while(size > 0) { - if(LL_SPI_IsActiveFlag_TXE(handle->bus->spi)) { - LL_SPI_TransmitData8(handle->bus->spi, *buffer); - buffer++; - size--; - } - } - - furi_hal_spi_bus_end_txrx(handle, timeout); - LL_SPI_ClearFlag_OVR(handle->bus->spi); - - return ret; -} - -bool furi_hal_spi_bus_trx( - FuriHalSpiBusHandle* handle, - uint8_t* tx_buffer, - uint8_t* rx_buffer, - size_t size, - uint32_t timeout) { - assert(handle); - assert(handle->bus->current_handle == handle); - assert(tx_buffer); - assert(rx_buffer); - assert(size > 0); - - bool ret = true; - size_t tx_size = size; - bool tx_allowed = true; - - while(size > 0) { - if(tx_size > 0 && LL_SPI_IsActiveFlag_TXE(handle->bus->spi) && tx_allowed) { - LL_SPI_TransmitData8(handle->bus->spi, *tx_buffer); - tx_buffer++; - tx_size--; - tx_allowed = false; - } - - if(LL_SPI_IsActiveFlag_RXNE(handle->bus->spi)) { - *rx_buffer = LL_SPI_ReceiveData8(handle->bus->spi); - rx_buffer++; - size--; - tx_allowed = true; - } - } - - furi_hal_spi_bus_end_txrx(handle, timeout); - - return ret; -} diff --git a/bootloader/targets/f7/furi_hal/furi_hal_spi_config.c b/bootloader/targets/f7/furi_hal/furi_hal_spi_config.c deleted file mode 100644 index a7c745cdd39..00000000000 --- a/bootloader/targets/f7/furi_hal/furi_hal_spi_config.c +++ /dev/null @@ -1,290 +0,0 @@ -#include -#include - -/* SPI Presets */ - -const LL_SPI_InitTypeDef furi_hal_spi_preset_2edge_low_8m = { - .Mode = LL_SPI_MODE_MASTER, - .TransferDirection = LL_SPI_FULL_DUPLEX, - .DataWidth = LL_SPI_DATAWIDTH_8BIT, - .ClockPolarity = LL_SPI_POLARITY_LOW, - .ClockPhase = LL_SPI_PHASE_2EDGE, - .NSS = LL_SPI_NSS_SOFT, - .BaudRate = LL_SPI_BAUDRATEPRESCALER_DIV8, - .BitOrder = LL_SPI_MSB_FIRST, - .CRCCalculation = LL_SPI_CRCCALCULATION_DISABLE, - .CRCPoly = 7, -}; - -const LL_SPI_InitTypeDef furi_hal_spi_preset_1edge_low_8m = { - .Mode = LL_SPI_MODE_MASTER, - .TransferDirection = LL_SPI_FULL_DUPLEX, - .DataWidth = LL_SPI_DATAWIDTH_8BIT, - .ClockPolarity = LL_SPI_POLARITY_LOW, - .ClockPhase = LL_SPI_PHASE_1EDGE, - .NSS = LL_SPI_NSS_SOFT, - .BaudRate = LL_SPI_BAUDRATEPRESCALER_DIV8, - .BitOrder = LL_SPI_MSB_FIRST, - .CRCCalculation = LL_SPI_CRCCALCULATION_DISABLE, - .CRCPoly = 7, -}; - -const LL_SPI_InitTypeDef furi_hal_spi_preset_1edge_low_4m = { - .Mode = LL_SPI_MODE_MASTER, - .TransferDirection = LL_SPI_FULL_DUPLEX, - .DataWidth = LL_SPI_DATAWIDTH_8BIT, - .ClockPolarity = LL_SPI_POLARITY_LOW, - .ClockPhase = LL_SPI_PHASE_1EDGE, - .NSS = LL_SPI_NSS_SOFT, - .BaudRate = LL_SPI_BAUDRATEPRESCALER_DIV16, - .BitOrder = LL_SPI_MSB_FIRST, - .CRCCalculation = LL_SPI_CRCCALCULATION_DISABLE, - .CRCPoly = 7, -}; - -const LL_SPI_InitTypeDef furi_hal_spi_preset_1edge_low_16m = { - .Mode = LL_SPI_MODE_MASTER, - .TransferDirection = LL_SPI_FULL_DUPLEX, - .DataWidth = LL_SPI_DATAWIDTH_8BIT, - .ClockPolarity = LL_SPI_POLARITY_LOW, - .ClockPhase = LL_SPI_PHASE_1EDGE, - .NSS = LL_SPI_NSS_SOFT, - .BaudRate = LL_SPI_BAUDRATEPRESCALER_DIV2, - .BitOrder = LL_SPI_MSB_FIRST, - .CRCCalculation = LL_SPI_CRCCALCULATION_DISABLE, - .CRCPoly = 7, -}; - -const LL_SPI_InitTypeDef furi_hal_spi_preset_1edge_low_2m = { - .Mode = LL_SPI_MODE_MASTER, - .TransferDirection = LL_SPI_FULL_DUPLEX, - .DataWidth = LL_SPI_DATAWIDTH_8BIT, - .ClockPolarity = LL_SPI_POLARITY_LOW, - .ClockPhase = LL_SPI_PHASE_1EDGE, - .NSS = LL_SPI_NSS_SOFT, - .BaudRate = LL_SPI_BAUDRATEPRESCALER_DIV32, - .BitOrder = LL_SPI_MSB_FIRST, - .CRCCalculation = LL_SPI_CRCCALCULATION_DISABLE, - .CRCPoly = 7, -}; - -/* SPI Buses */ - -static void furi_hal_spi_bus_r_event_callback(FuriHalSpiBus* bus, FuriHalSpiBusEvent event) { - if(event == FuriHalSpiBusEventInit) { - LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_SPI1); - LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_SPI1); - bus->current_handle = NULL; - } else if(event == FuriHalSpiBusEventDeinit) { - } else if(event == FuriHalSpiBusEventLock) { - } else if(event == FuriHalSpiBusEventUnlock) { - } else if(event == FuriHalSpiBusEventActivate) { - LL_APB2_GRP1_ReleaseReset(LL_APB2_GRP1_PERIPH_SPI1); - } else if(event == FuriHalSpiBusEventDeactivate) { - LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_SPI1); - } -} - -FuriHalSpiBus furi_hal_spi_bus_r = { - .spi = SPI1, - .callback = furi_hal_spi_bus_r_event_callback, -}; - -static void furi_hal_spi_bus_d_event_callback(FuriHalSpiBus* bus, FuriHalSpiBusEvent event) { - if(event == FuriHalSpiBusEventInit) { - LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_SPI2); - LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_SPI2); - bus->current_handle = NULL; - } else if(event == FuriHalSpiBusEventDeinit) { - } else if(event == FuriHalSpiBusEventLock) { - } else if(event == FuriHalSpiBusEventUnlock) { - } else if(event == FuriHalSpiBusEventActivate) { - LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_SPI2); - } else if(event == FuriHalSpiBusEventDeactivate) { - LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_SPI2); - } -} - -FuriHalSpiBus furi_hal_spi_bus_d = { - .spi = SPI2, - .callback = furi_hal_spi_bus_d_event_callback, -}; - -/* SPI Bus Handles */ - -inline static void furi_hal_spi_bus_r_handle_event_callback( - FuriHalSpiBusHandle* handle, - FuriHalSpiBusHandleEvent event, - const LL_SPI_InitTypeDef* preset) { - if(event == FuriHalSpiBusHandleEventInit) { - furi_hal_gpio_write(handle->cs, true); - furi_hal_gpio_init(handle->cs, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh); - } else if(event == FuriHalSpiBusHandleEventDeinit) { - furi_hal_gpio_write(handle->cs, true); - furi_hal_gpio_init(handle->cs, GpioModeAnalog, GpioPullNo, GpioSpeedLow); - } else if(event == FuriHalSpiBusHandleEventActivate) { - LL_SPI_Init(handle->bus->spi, (LL_SPI_InitTypeDef*)preset); - LL_SPI_SetRxFIFOThreshold(handle->bus->spi, LL_SPI_RX_FIFO_TH_QUARTER); - LL_SPI_Enable(handle->bus->spi); - - furi_hal_gpio_init_ex( - handle->miso, - GpioModeAltFunctionPushPull, - GpioPullNo, - GpioSpeedVeryHigh, - GpioAltFn5SPI1); - furi_hal_gpio_init_ex( - handle->mosi, - GpioModeAltFunctionPushPull, - GpioPullNo, - GpioSpeedVeryHigh, - GpioAltFn5SPI1); - furi_hal_gpio_init_ex( - handle->sck, - GpioModeAltFunctionPushPull, - GpioPullNo, - GpioSpeedVeryHigh, - GpioAltFn5SPI1); - - furi_hal_gpio_write(handle->cs, false); - } else if(event == FuriHalSpiBusHandleEventDeactivate) { - furi_hal_gpio_write(handle->cs, true); - - furi_hal_gpio_init(handle->miso, GpioModeAnalog, GpioPullNo, GpioSpeedLow); - furi_hal_gpio_init(handle->mosi, GpioModeAnalog, GpioPullNo, GpioSpeedLow); - furi_hal_gpio_init(handle->sck, GpioModeAnalog, GpioPullNo, GpioSpeedLow); - - LL_SPI_Disable(handle->bus->spi); - } -} - -static void furi_hal_spi_bus_handle_subghz_event_callback( - FuriHalSpiBusHandle* handle, - FuriHalSpiBusHandleEvent event) { - furi_hal_spi_bus_r_handle_event_callback(handle, event, &furi_hal_spi_preset_1edge_low_8m); -} - -FuriHalSpiBusHandle furi_hal_spi_bus_handle_subghz = { - .bus = &furi_hal_spi_bus_r, - .callback = furi_hal_spi_bus_handle_subghz_event_callback, - .miso = &gpio_spi_r_miso, - .mosi = &gpio_spi_r_mosi, - .sck = &gpio_spi_r_sck, - .cs = &gpio_subghz_cs, -}; - -static void furi_hal_spi_bus_handle_nfc_event_callback( - FuriHalSpiBusHandle* handle, - FuriHalSpiBusHandleEvent event) { - furi_hal_spi_bus_r_handle_event_callback(handle, event, &furi_hal_spi_preset_2edge_low_8m); -} - -FuriHalSpiBusHandle furi_hal_spi_bus_handle_nfc = { - .bus = &furi_hal_spi_bus_r, - .callback = furi_hal_spi_bus_handle_nfc_event_callback, - .miso = &gpio_spi_r_miso, - .mosi = &gpio_spi_r_mosi, - .sck = &gpio_spi_r_sck, - .cs = &gpio_nfc_cs, -}; - -static void furi_hal_spi_bus_handle_external_event_callback( - FuriHalSpiBusHandle* handle, - FuriHalSpiBusHandleEvent event) { - furi_hal_spi_bus_r_handle_event_callback(handle, event, &furi_hal_spi_preset_1edge_low_2m); -} - -FuriHalSpiBusHandle furi_hal_spi_bus_handle_external = { - .bus = &furi_hal_spi_bus_r, - .callback = furi_hal_spi_bus_handle_external_event_callback, - .miso = &gpio_ext_pa6, - .mosi = &gpio_ext_pa7, - .sck = &gpio_ext_pb3, - .cs = &gpio_ext_pa4, -}; - -inline static void furi_hal_spi_bus_d_handle_event_callback( - FuriHalSpiBusHandle* handle, - FuriHalSpiBusHandleEvent event, - const LL_SPI_InitTypeDef* preset) { - if(event == FuriHalSpiBusHandleEventInit) { - furi_hal_gpio_write(handle->cs, true); - furi_hal_gpio_init(handle->cs, GpioModeOutputPushPull, GpioPullUp, GpioSpeedVeryHigh); - - furi_hal_gpio_init_ex( - handle->miso, - GpioModeAltFunctionPushPull, - GpioPullNo, - GpioSpeedVeryHigh, - GpioAltFn5SPI2); - furi_hal_gpio_init_ex( - handle->mosi, - GpioModeAltFunctionPushPull, - GpioPullNo, - GpioSpeedVeryHigh, - GpioAltFn5SPI2); - furi_hal_gpio_init_ex( - handle->sck, - GpioModeAltFunctionPushPull, - GpioPullNo, - GpioSpeedVeryHigh, - GpioAltFn5SPI2); - - } else if(event == FuriHalSpiBusHandleEventDeinit) { - furi_hal_gpio_write(handle->cs, true); - furi_hal_gpio_init(handle->cs, GpioModeAnalog, GpioPullUp, GpioSpeedLow); - } else if(event == FuriHalSpiBusHandleEventActivate) { - LL_SPI_Init(handle->bus->spi, (LL_SPI_InitTypeDef*)preset); - LL_SPI_SetRxFIFOThreshold(handle->bus->spi, LL_SPI_RX_FIFO_TH_QUARTER); - LL_SPI_Enable(handle->bus->spi); - furi_hal_gpio_write(handle->cs, false); - } else if(event == FuriHalSpiBusHandleEventDeactivate) { - furi_hal_gpio_write(handle->cs, true); - LL_SPI_Disable(handle->bus->spi); - } -} - -static void furi_hal_spi_bus_handle_display_event_callback( - FuriHalSpiBusHandle* handle, - FuriHalSpiBusHandleEvent event) { - furi_hal_spi_bus_d_handle_event_callback(handle, event, &furi_hal_spi_preset_1edge_low_4m); -} - -FuriHalSpiBusHandle furi_hal_spi_bus_handle_display = { - .bus = &furi_hal_spi_bus_d, - .callback = furi_hal_spi_bus_handle_display_event_callback, - .miso = &gpio_spi_d_miso, - .mosi = &gpio_spi_d_mosi, - .sck = &gpio_spi_d_sck, - .cs = &gpio_display_cs, -}; - -static void furi_hal_spi_bus_handle_sd_fast_event_callback( - FuriHalSpiBusHandle* handle, - FuriHalSpiBusHandleEvent event) { - furi_hal_spi_bus_d_handle_event_callback(handle, event, &furi_hal_spi_preset_1edge_low_16m); -} - -FuriHalSpiBusHandle furi_hal_spi_bus_handle_sd_fast = { - .bus = &furi_hal_spi_bus_d, - .callback = furi_hal_spi_bus_handle_sd_fast_event_callback, - .miso = &gpio_spi_d_miso, - .mosi = &gpio_spi_d_mosi, - .sck = &gpio_spi_d_sck, - .cs = &gpio_sdcard_cs, -}; - -static void furi_hal_spi_bus_handle_sd_slow_event_callback( - FuriHalSpiBusHandle* handle, - FuriHalSpiBusHandleEvent event) { - furi_hal_spi_bus_d_handle_event_callback(handle, event, &furi_hal_spi_preset_1edge_low_2m); -} - -FuriHalSpiBusHandle furi_hal_spi_bus_handle_sd_slow = { - .bus = &furi_hal_spi_bus_d, - .callback = furi_hal_spi_bus_handle_sd_slow_event_callback, - .miso = &gpio_spi_d_miso, - .mosi = &gpio_spi_d_mosi, - .sck = &gpio_spi_d_sck, - .cs = &gpio_sdcard_cs, -}; diff --git a/bootloader/targets/f7/furi_hal/furi_hal_spi_config.h b/bootloader/targets/f7/furi_hal/furi_hal_spi_config.h deleted file mode 100644 index 3e4296a0584..00000000000 --- a/bootloader/targets/f7/furi_hal/furi_hal_spi_config.h +++ /dev/null @@ -1,61 +0,0 @@ -#pragma once - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** Preset for ST25R916 */ -extern const LL_SPI_InitTypeDef furi_hal_spi_preset_2edge_low_8m; - -/** Preset for CC1101 */ -extern const LL_SPI_InitTypeDef furi_hal_spi_preset_1edge_low_8m; - -/** Preset for ST7567 (Display) */ -extern const LL_SPI_InitTypeDef furi_hal_spi_preset_1edge_low_4m; - -/** Preset for SdCard in fast mode */ -extern const LL_SPI_InitTypeDef furi_hal_spi_preset_1edge_low_16m; - -/** Preset for SdCard in slow mode */ -extern const LL_SPI_InitTypeDef furi_hal_spi_preset_1edge_low_2m; - -/** Furi Hal Spi Bus R (Radio: CC1101, Nfc, External)*/ -extern FuriHalSpiBus furi_hal_spi_bus_r; - -/** Furi Hal Spi Bus D (Display, SdCard) */ -extern FuriHalSpiBus furi_hal_spi_bus_d; - -/** CC1101 on `furi_hal_spi_bus_r` */ -extern FuriHalSpiBusHandle furi_hal_spi_bus_handle_subghz; - -/** ST25R3916 on `furi_hal_spi_bus_r` */ -extern FuriHalSpiBusHandle furi_hal_spi_bus_handle_nfc; - -/** External on `furi_hal_spi_bus_r` - * Preset: `furi_hal_spi_preset_1edge_low_2m` - * - * miso: pa6 - * mosi: pa7 - * sck: pb3 - * cs: pa4 (software controlled) - * - * @warning not initialized by default, call `furi_hal_spi_bus_handle_init` to initialize - * Bus pins are floating on inactive state, CS high after initialization - * - */ -extern FuriHalSpiBusHandle furi_hal_spi_bus_handle_external; - -/** ST7567(Display) on `furi_hal_spi_bus_d` */ -extern FuriHalSpiBusHandle furi_hal_spi_bus_handle_display; - -/** SdCard in fast mode on `furi_hal_spi_bus_d` */ -extern FuriHalSpiBusHandle furi_hal_spi_bus_handle_sd_fast; - -/** SdCard in slow mode on `furi_hal_spi_bus_d` */ -extern FuriHalSpiBusHandle furi_hal_spi_bus_handle_sd_slow; - -#ifdef __cplusplus -} -#endif \ No newline at end of file diff --git a/bootloader/targets/f7/furi_hal/furi_hal_spi_types.h b/bootloader/targets/f7/furi_hal/furi_hal_spi_types.h deleted file mode 100644 index 1fb1c02b6bd..00000000000 --- a/bootloader/targets/f7/furi_hal/furi_hal_spi_types.h +++ /dev/null @@ -1,64 +0,0 @@ -#pragma once - -#include -#include - -#include - -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct FuriHalSpiBus FuriHalSpiBus; -typedef struct FuriHalSpiBusHandle FuriHalSpiBusHandle; - -/** FuriHal spi bus states */ -typedef enum { - FuriHalSpiBusEventInit, /**< Bus initialization event, called on system start */ - FuriHalSpiBusEventDeinit, /**< Bus deinitialization event, called on system stop */ - FuriHalSpiBusEventLock, /**< Bus lock event, called before activation */ - FuriHalSpiBusEventUnlock, /**< Bus unlock event, called after deactivation */ - FuriHalSpiBusEventActivate, /**< Bus activation event, called before handle activation */ - FuriHalSpiBusEventDeactivate, /**< Bus deactivation event, called after handle deactivation */ -} FuriHalSpiBusEvent; - -/** FuriHal spi bus event callback */ -typedef void (*FuriHalSpiBusEventCallback)(FuriHalSpiBus* bus, FuriHalSpiBusEvent event); - -/** FuriHal spi bus */ -struct FuriHalSpiBus { - SPI_TypeDef* spi; - FuriHalSpiBusEventCallback callback; - FuriHalSpiBusHandle* current_handle; -}; - -/** FuriHal spi handle states */ -typedef enum { - FuriHalSpiBusHandleEventInit, /**< Handle init, called on system start, initialize gpio for idle state */ - FuriHalSpiBusHandleEventDeinit, /**< Handle deinit, called on system stop, deinitialize gpio for default state */ - FuriHalSpiBusHandleEventActivate, /**< Handle activate: connect gpio and apply bus config */ - FuriHalSpiBusHandleEventDeactivate, /**< Handle deactivate: disconnect gpio and reset bus config */ -} FuriHalSpiBusHandleEvent; - -/** FuriHal spi handle event callback */ -typedef void (*FuriHalSpiBusHandleEventCallback)( - FuriHalSpiBusHandle* handle, - FuriHalSpiBusHandleEvent event); - -/** FuriHal spi handle */ -struct FuriHalSpiBusHandle { - FuriHalSpiBus* bus; - FuriHalSpiBusHandleEventCallback callback; - const GpioPin* miso; - const GpioPin* mosi; - const GpioPin* sck; - const GpioPin* cs; -}; - -#ifdef __cplusplus -} -#endif \ No newline at end of file diff --git a/bootloader/targets/f7/furi_hal/furi_hal_version.c b/bootloader/targets/f7/furi_hal/furi_hal_version.c deleted file mode 100644 index 5e2bead9585..00000000000 --- a/bootloader/targets/f7/furi_hal/furi_hal_version.c +++ /dev/null @@ -1,268 +0,0 @@ -#include - -#include -#include -#include - -#include - -#define FURI_HAL_VERSION_OTP_HEADER_MAGIC 0xBABE -#define FURI_HAL_VERSION_OTP_ADDRESS OTP_AREA_BASE - -/** OTP V0 Structure: prototypes and early EVT */ -typedef struct { - uint8_t board_version; - uint8_t board_target; - uint8_t board_body; - uint8_t board_connect; - uint32_t header_timestamp; - char name[FURI_HAL_VERSION_NAME_LENGTH]; -} FuriHalVersionOTPv0; - -/** OTP V1 Structure: late EVT, DVT */ -typedef struct { - /* First 64 bits: header */ - uint16_t header_magic; - uint8_t header_version; - uint8_t header_reserved; - uint32_t header_timestamp; - - /* Second 64 bits: board info */ - uint8_t board_version; /** Board version */ - uint8_t board_target; /** Board target firmware */ - uint8_t board_body; /** Board body */ - uint8_t board_connect; /** Board interconnect */ - uint8_t board_color; /** Board color */ - uint8_t board_region; /** Board region */ - uint16_t board_reserved; /** Reserved for future use, 0x0000 */ - - /* Third 64 bits: Unique Device Name */ - char name[FURI_HAL_VERSION_NAME_LENGTH]; /** Unique Device Name */ -} FuriHalVersionOTPv1; - -/** OTP V2 Structure: DVT2, PVT, Production */ -typedef struct { - /* Early First 64 bits: header */ - uint16_t header_magic; - uint8_t header_version; - uint8_t header_reserved; - uint32_t header_timestamp; - - /* Early Second 64 bits: board info */ - uint8_t board_version; /** Board version */ - uint8_t board_target; /** Board target firmware */ - uint8_t board_body; /** Board body */ - uint8_t board_connect; /** Board interconnect */ - uint8_t board_display; /** Board display */ - uint8_t board_reserved2_0; /** Reserved for future use, 0x00 */ - uint16_t board_reserved2_1; /** Reserved for future use, 0x0000 */ - - /* Late Third 64 bits: device info */ - uint8_t board_color; /** Board color */ - uint8_t board_region; /** Board region */ - uint16_t board_reserved3_0; /** Reserved for future use, 0x0000 */ - uint32_t board_reserved3_1; /** Reserved for future use, 0x00000000 */ - - /* Late Fourth 64 bits: Unique Device Name */ - char name[FURI_HAL_VERSION_NAME_LENGTH]; /** Unique Device Name */ -} FuriHalVersionOTPv2; - -/** Represenation Model: */ -typedef struct { - uint32_t timestamp; - - uint8_t board_version; /** Board version */ - uint8_t board_target; /** Board target firmware */ - uint8_t board_body; /** Board body */ - uint8_t board_connect; /** Board interconnect */ - uint8_t board_color; /** Board color */ - uint8_t board_region; /** Board region */ - uint8_t board_display; /** Board display */ - - char name[FURI_HAL_VERSION_ARRAY_NAME_LENGTH]; /** \0 terminated name */ - char device_name[FURI_HAL_VERSION_DEVICE_NAME_LENGTH]; /** device name for special needs */ - uint8_t ble_mac[6]; -} FuriHalVersion; - -static FuriHalVersion furi_hal_version = {0}; - -static void furi_hal_version_set_name(const char* name) { - furi_hal_version.device_name[0] = 0; -} - -static void furi_hal_version_load_otp_default() { - furi_hal_version_set_name(NULL); -} - -static void furi_hal_version_load_otp_v0() { - const FuriHalVersionOTPv0* otp = (FuriHalVersionOTPv0*)FURI_HAL_VERSION_OTP_ADDRESS; - - furi_hal_version.timestamp = otp->header_timestamp; - furi_hal_version.board_version = otp->board_version; - furi_hal_version.board_target = otp->board_target; - furi_hal_version.board_body = otp->board_body; - furi_hal_version.board_connect = otp->board_connect; - - furi_hal_version_set_name(otp->name); -} - -static void furi_hal_version_load_otp_v1() { - const FuriHalVersionOTPv1* otp = (FuriHalVersionOTPv1*)FURI_HAL_VERSION_OTP_ADDRESS; - - furi_hal_version.timestamp = otp->header_timestamp; - furi_hal_version.board_version = otp->board_version; - furi_hal_version.board_target = otp->board_target; - furi_hal_version.board_body = otp->board_body; - furi_hal_version.board_connect = otp->board_connect; - furi_hal_version.board_color = otp->board_color; - furi_hal_version.board_region = otp->board_region; - - furi_hal_version_set_name(otp->name); -} - -static void furi_hal_version_load_otp_v2() { - const FuriHalVersionOTPv2* otp = (FuriHalVersionOTPv2*)FURI_HAL_VERSION_OTP_ADDRESS; - - // 1st block, programmed afer baking - furi_hal_version.timestamp = otp->header_timestamp; - - // 2nd block, programmed afer baking - furi_hal_version.board_version = otp->board_version; - furi_hal_version.board_target = otp->board_target; - furi_hal_version.board_body = otp->board_body; - furi_hal_version.board_connect = otp->board_connect; - furi_hal_version.board_display = otp->board_display; - - // 3rd and 4th blocks, programmed on FATP stage - if(otp->board_color != 0xFF) { - furi_hal_version.board_color = otp->board_color; - furi_hal_version.board_region = otp->board_region; - furi_hal_version_set_name(otp->name); - } else { - furi_hal_version.board_color = 0; - furi_hal_version.board_region = 0; - furi_hal_version_set_name(NULL); - } -} - -void furi_hal_version_init() { - switch(furi_hal_version_get_otp_version()) { - case FuriHalVersionOtpVersionUnknown: - furi_hal_version_load_otp_default(); - break; - case FuriHalVersionOtpVersionEmpty: - furi_hal_version_load_otp_default(); - break; - case FuriHalVersionOtpVersion0: - furi_hal_version_load_otp_v0(); - break; - case FuriHalVersionOtpVersion1: - furi_hal_version_load_otp_v1(); - break; - case FuriHalVersionOtpVersion2: - furi_hal_version_load_otp_v2(); - break; - default: - furi_hal_version_load_otp_default(); - } -} - -bool furi_hal_version_do_i_belong_here() { - return furi_hal_version_get_hw_target() == 7; -} - -const char* furi_hal_version_get_model_name() { - return "Flipper Zero"; -} - -const FuriHalVersionOtpVersion furi_hal_version_get_otp_version() { - if(*(uint64_t*)FURI_HAL_VERSION_OTP_ADDRESS == 0xFFFFFFFF) { - return FuriHalVersionOtpVersionEmpty; - } else { - if(((FuriHalVersionOTPv1*)FURI_HAL_VERSION_OTP_ADDRESS)->header_magic == - FURI_HAL_VERSION_OTP_HEADER_MAGIC) { - // Version 1+ - uint8_t version = ((FuriHalVersionOTPv1*)FURI_HAL_VERSION_OTP_ADDRESS)->header_version; - if(version >= FuriHalVersionOtpVersion1 && version <= FuriHalVersionOtpVersion2) { - return version; - } else { - return FuriHalVersionOtpVersionUnknown; - } - } else if(((FuriHalVersionOTPv0*)FURI_HAL_VERSION_OTP_ADDRESS)->board_version <= 10) { - // Version 0 - return FuriHalVersionOtpVersion0; - } else { - // Version Unknown - return FuriHalVersionOtpVersionUnknown; - } - } -} - -const uint8_t furi_hal_version_get_hw_version() { - return furi_hal_version.board_version; -} - -const uint8_t furi_hal_version_get_hw_target() { - return furi_hal_version.board_target; -} - -const uint8_t furi_hal_version_get_hw_body() { - return furi_hal_version.board_body; -} - -const FuriHalVersionColor furi_hal_version_get_hw_color() { - return furi_hal_version.board_color; -} - -const uint8_t furi_hal_version_get_hw_connect() { - return furi_hal_version.board_connect; -} - -const FuriHalVersionRegion furi_hal_version_get_hw_region() { - return furi_hal_version.board_region; -} - -const FuriHalVersionDisplay furi_hal_version_get_hw_display() { - return furi_hal_version.board_display; -} - -const uint32_t furi_hal_version_get_hw_timestamp() { - return furi_hal_version.timestamp; -} - -const char* furi_hal_version_get_name_ptr() { - return *furi_hal_version.name == 0x00 ? NULL : furi_hal_version.name; -} - -const char* furi_hal_version_get_device_name_ptr() { - return furi_hal_version.device_name + 1; -} - -const char* furi_hal_version_get_ble_local_device_name_ptr() { - return furi_hal_version.device_name; -} - -const uint8_t* furi_hal_version_get_ble_mac() { - return furi_hal_version.ble_mac; -} - -const struct Version* furi_hal_version_get_firmware_version(void) { - return version_get(); -} - -const struct Version* furi_hal_version_get_bootloader_version(void) { -#ifdef NO_BOOTLOADER - return 0; -#else - /* Backup register which points to structure in flash memory */ - return (const struct Version*)LL_RTC_BAK_GetRegister(RTC, LL_RTC_BKP_DR1); -#endif -} - -size_t furi_hal_version_uid_size() { - return 64 / 8; -} - -const uint8_t* furi_hal_version_uid() { - return (const uint8_t*)UID64_BASE; -} diff --git a/bootloader/targets/f7/furi_hal/main.h b/bootloader/targets/f7/furi_hal/main.h deleted file mode 100644 index 6b1d644d861..00000000000 --- a/bootloader/targets/f7/furi_hal/main.h +++ /dev/null @@ -1,108 +0,0 @@ -#pragma once - -#include -#include -#include - -#define BUTTON_BACK_GPIO_Port GPIOC -#define BUTTON_BACK_Pin LL_GPIO_PIN_13 -#define BUTTON_DOWN_GPIO_Port GPIOC -#define BUTTON_DOWN_Pin LL_GPIO_PIN_6 -#define BUTTON_LEFT_GPIO_Port GPIOB -#define BUTTON_LEFT_Pin LL_GPIO_PIN_11 -#define BUTTON_OK_GPIO_Port GPIOH -#define BUTTON_OK_Pin LL_GPIO_PIN_3 -#define BUTTON_RIGHT_GPIO_Port GPIOB -#define BUTTON_RIGHT_Pin LL_GPIO_PIN_12 -#define BUTTON_UP_GPIO_Port GPIOB -#define BUTTON_UP_Pin LL_GPIO_PIN_10 - -#define CC1101_CS_GPIO_Port GPIOD -#define CC1101_CS_Pin LL_GPIO_PIN_0 -#define CC1101_G0_GPIO_Port GPIOA -#define CC1101_G0_Pin LL_GPIO_PIN_1 - -#define DISPLAY_CS_GPIO_Port GPIOC -#define DISPLAY_CS_Pin LL_GPIO_PIN_11 -#define DISPLAY_DI_GPIO_Port GPIOB -#define DISPLAY_DI_Pin LL_GPIO_PIN_1 -#define DISPLAY_RST_GPIO_Port GPIOB -#define DISPLAY_RST_Pin LL_GPIO_PIN_0 - -#define IR_RX_GPIO_Port GPIOA -#define IR_RX_Pin LL_GPIO_PIN_0 -#define IR_TX_GPIO_Port GPIOB -#define IR_TX_Pin LL_GPIO_PIN_9 - -#define NFC_CS_GPIO_Port GPIOE -#define NFC_CS_Pin LL_GPIO_PIN_4 - -#define PA4_GPIO_Port GPIOA -#define PA4_Pin LL_GPIO_PIN_4 -#define PA6_GPIO_Port GPIOA -#define PA6_Pin LL_GPIO_PIN_6 -#define PA7_GPIO_Port GPIOA -#define PA7_Pin LL_GPIO_PIN_7 -#define PB2_GPIO_Port GPIOB -#define PB2_Pin LL_GPIO_PIN_2 -#define PB3_GPIO_Port GPIOB -#define PB3_Pin LL_GPIO_PIN_3 -#define PC0_GPIO_Port GPIOC -#define PC0_Pin LL_GPIO_PIN_0 -#define PC1_GPIO_Port GPIOC -#define PC1_Pin LL_GPIO_PIN_1 -#define PC3_GPIO_Port GPIOC -#define PC3_Pin LL_GPIO_PIN_3 - -#define PERIPH_POWER_GPIO_Port GPIOA -#define PERIPH_POWER_Pin LL_GPIO_PIN_3 - -#define QUARTZ_32MHZ_IN_GPIO_Port GPIOC -#define QUARTZ_32MHZ_IN_Pin LL_GPIO_PIN_14 -#define QUARTZ_32MHZ_OUT_GPIO_Port GPIOC -#define QUARTZ_32MHZ_OUT_Pin LL_GPIO_PIN_15 - -#define RFID_OUT_GPIO_Port GPIOB -#define RFID_OUT_Pin LL_GPIO_PIN_13 -#define RFID_PULL_GPIO_Port GPIOA -#define RFID_PULL_Pin LL_GPIO_PIN_2 -#define RFID_RF_IN_GPIO_Port GPIOC -#define RFID_RF_IN_Pin LL_GPIO_PIN_5 -#define RFID_TUNE_GPIO_Port GPIOA -#define RFID_TUNE_Pin LL_GPIO_PIN_8 - -#define RF_SW_0_GPIO_Port GPIOC -#define RF_SW_0_Pin LL_GPIO_PIN_4 - -#define SD_CD_GPIO_Port GPIOC -#define SD_CD_Pin LL_GPIO_PIN_10 -#define SD_CS_GPIO_Port GPIOC -#define SD_CS_Pin LL_GPIO_PIN_12 - -#define SPEAKER_GPIO_Port GPIOB -#define SPEAKER_Pin LL_GPIO_PIN_8 - -#define VIBRO_GPIO_Port GPIOA -#define VIBRO_Pin LL_GPIO_PIN_15 - -#define iBTN_GPIO_Port GPIOB -#define iBTN_Pin LL_GPIO_PIN_14 - -#define USART1_TX_Pin LL_GPIO_PIN_6 -#define USART1_TX_Port GPIOB -#define USART1_RX_Pin LL_GPIO_PIN_7 -#define USART1_RX_Port GPIOB - -#define SPI_D_MISO_GPIO_Port GPIOC -#define SPI_D_MISO_Pin LL_GPIO_PIN_2 -#define SPI_D_MOSI_GPIO_Port GPIOB -#define SPI_D_MOSI_Pin LL_GPIO_PIN_15 -#define SPI_D_SCK_GPIO_Port GPIOD -#define SPI_D_SCK_Pin LL_GPIO_PIN_1 - -#define SPI_R_MISO_GPIO_Port GPIOB -#define SPI_R_MISO_Pin LL_GPIO_PIN_4 -#define SPI_R_MOSI_GPIO_Port GPIOB -#define SPI_R_MOSI_Pin LL_GPIO_PIN_5 -#define SPI_R_SCK_GPIO_Port GPIOA -#define SPI_R_SCK_Pin LL_GPIO_PIN_5 diff --git a/bootloader/targets/f7/stm32wb55xx_flash_cm4.ld b/bootloader/targets/f7/stm32wb55xx_flash_cm4.ld deleted file mode 100644 index 6d3a78a2258..00000000000 --- a/bootloader/targets/f7/stm32wb55xx_flash_cm4.ld +++ /dev/null @@ -1,187 +0,0 @@ -/** -***************************************************************************** -** -** File : stm32wb55xx_flash_cm4.ld -** -** Abstract : System Workbench Minimal System calls file -** -** For more information about which c-functions -** need which of these lowlevel functions -** please consult the Newlib libc-manual -** -** Environment : System Workbench for MCU -** -** Distribution: The file is distributed “as is,” without any warranty -** of any kind. -** -***************************************************************************** -** -**

© COPYRIGHT(c) 2019 Ac6

-** -** Redistribution and use in source and binary forms, with or without modification, -** are permitted provided that the following conditions are met: -** 1. Redistributions of source code must retain the above copyright notice, -** this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright notice, -** this list of conditions and the following disclaimer in the documentation -** and/or other materials provided with the distribution. -** 3. Neither the name of Ac6 nor the names of its contributors -** may be used to endorse or promote products derived from this software -** without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -** SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -** OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -** -***************************************************************************** -*/ - -/* Entry Point */ -ENTRY(Reset_Handler) - -/* Highest address of the user mode stack */ -_estack = 0x20030000; /* end of RAM */ -/* Generate a link error if heap and stack don't fit into RAM */ -_Min_Heap_Size = 0x200; /* required amount of heap */ -_Min_Stack_Size = 0x400; /* required amount of stack */ - -/* Specify the memory areas */ -MEMORY -{ -FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 32K -RAM1 (xrw) : ORIGIN = 0x20000008, LENGTH = 0x2FFF8 -RAM_SHARED (xrw) : ORIGIN = 0x20030000, LENGTH = 10K -} - -/* Define output sections */ -SECTIONS -{ - /* The startup code goes first into FLASH */ - .isr_vector : - { - . = ALIGN(4); - KEEP(*(.isr_vector)) /* Startup code */ - . = ALIGN(4); - } >FLASH - - /* The program code and other data goes into FLASH */ - .text : - { - . = ALIGN(4); - *(.text) /* .text sections (code) */ - *(.text*) /* .text* sections (code) */ - *(.glue_7) /* glue arm to thumb code */ - *(.glue_7t) /* glue thumb to arm code */ - *(.eh_frame) - - KEEP (*(.init)) - KEEP (*(.fini)) - - . = ALIGN(4); - _etext = .; /* define a global symbols at end of code */ - } >FLASH - - /* Constant data goes into FLASH */ - .rodata : - { - . = ALIGN(4); - *(.rodata) /* .rodata sections (constants, strings, etc.) */ - *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ - . = ALIGN(4); - } >FLASH - - .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH - .ARM : { - __exidx_start = .; - *(.ARM.exidx*) - __exidx_end = .; - } >FLASH - - .preinit_array : - { - PROVIDE_HIDDEN (__preinit_array_start = .); - KEEP (*(.preinit_array*)) - PROVIDE_HIDDEN (__preinit_array_end = .); - } >FLASH - .init_array : - { - PROVIDE_HIDDEN (__init_array_start = .); - KEEP (*(SORT(.init_array.*))) - KEEP (*(.init_array*)) - PROVIDE_HIDDEN (__init_array_end = .); - } >FLASH - .fini_array : - { - PROVIDE_HIDDEN (__fini_array_start = .); - KEEP (*(SORT(.fini_array.*))) - KEEP (*(.fini_array*)) - PROVIDE_HIDDEN (__fini_array_end = .); - } >FLASH - - /* used by the startup to initialize data */ - _sidata = LOADADDR(.data); - - /* Initialized data sections goes into RAM, load LMA copy after code */ - .data : - { - . = ALIGN(4); - _sdata = .; /* create a global symbol at data start */ - *(.data) /* .data sections */ - *(.data*) /* .data* sections */ - - . = ALIGN(4); - _edata = .; /* define a global symbol at data end */ - } >RAM1 AT> FLASH - - - /* Uninitialized data section */ - . = ALIGN(4); - .bss : - { - /* This is used by the startup in order to initialize the .bss secion */ - _sbss = .; /* define a global symbol at bss start */ - __bss_start__ = _sbss; - *(.bss) - *(.bss*) - *(COMMON) - - . = ALIGN(4); - _ebss = .; /* define a global symbol at bss end */ - __bss_end__ = _ebss; - } >RAM1 - - /* User_heap_stack section, used to check that there is enough RAM left */ - ._user_heap_stack : - { - . = ALIGN(8); - PROVIDE ( end = . ); - PROVIDE ( _end = . ); - . = . + _Min_Heap_Size; - . = . + _Min_Stack_Size; - . = ALIGN(8); - } >RAM1 - - - - /* Remove information from the standard libraries */ - /DISCARD/ : - { - libc.a ( * ) - libm.a ( * ) - libgcc.a ( * ) - } - - .ARM.attributes 0 : { *(.ARM.attributes) } - MAPPING_TABLE (NOLOAD) : { *(MAPPING_TABLE) } >RAM_SHARED - MB_MEM1 (NOLOAD) : { *(MB_MEM1) } >RAM_SHARED - MB_MEM2 (NOLOAD) : { _sMB_MEM2 = . ; *(MB_MEM2) ; _eMB_MEM2 = . ; } >RAM_SHARED -} - - diff --git a/bootloader/targets/f7/target.c b/bootloader/targets/f7/target.c deleted file mode 100644 index 58eace9c682..00000000000 --- a/bootloader/targets/f7/target.c +++ /dev/null @@ -1,264 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include - -const uint8_t I_DFU_128x50[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x07, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x38, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0xC0, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8F, 0x01, 0x00, 0x00, 0x03, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x7F, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xFF, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x75, 0x00, 0x00, 0xF0, 0x3F, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xFF, 0x0A, 0x00, 0x00, 0x0F, 0x60, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0xE0, 0x0F, 0x00, 0xC0, 0xE0, 0x4F, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x18, 0x00, 0x30, 0x1E, 0x90, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x18, 0x00, 0x8C, 0x01, 0xA0, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x81, 0xFF, 0x19, 0x00, 0x63, 0x00, 0xC0, 0xF0, 0x07, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x60, 0x5E, 0x1F, 0x80, 0x18, 0x00, 0xE0, 0x0E, 0x18, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x18, 0xAF, 0x0F, 0x40, 0x06, 0x00, 0xF8, 0x01, 0x20, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x06, 0x57, 0x01, 0x20, 0x01, 0x00, 0x78, 0x00, 0x3E, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x84, 0x81, 0xAF, 0x02, 0x90, 0x00, 0x00, 0x38, 0x80, 0x41, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x80, 0x57, 0x01, 0x48, 0x00, 0x00, 0x10, 0x60, 0x40, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x10, 0x80, 0xAB, 0x00, 0x24, 0x00, 0x00, 0x08, 0x10, 0x40, - 0x3F, 0x00, 0x00, 0x00, 0x00, 0x38, 0x0C, 0xC0, 0x57, 0x01, 0x12, 0x00, 0x00, 0x04, 0x08, 0x40, - 0xC0, 0x0F, 0x00, 0x00, 0xC0, 0x07, 0x03, 0xF0, 0xAB, 0x00, 0x0A, 0x00, 0x00, 0x02, 0x04, 0x40, - 0x00, 0xF0, 0x1F, 0x80, 0x3F, 0xC0, 0x00, 0xFC, 0x55, 0x01, 0x05, 0xE0, 0x00, 0x01, 0x04, 0x40, - 0x00, 0x00, 0xE0, 0x7F, 0x00, 0x30, 0x00, 0xFF, 0xAB, 0x00, 0x05, 0xE0, 0x80, 0x00, 0x02, 0x40, - 0x0F, 0x00, 0x00, 0x00, 0x80, 0x0F, 0xE0, 0xCF, 0x55, 0x81, 0x02, 0xF0, 0x40, 0x00, 0x02, 0x40, - 0xF0, 0x0F, 0x00, 0x00, 0x7F, 0x00, 0xFE, 0xC3, 0xAB, 0x80, 0x02, 0x78, 0x20, 0x00, 0x01, 0x40, - 0x00, 0xF0, 0xFF, 0xFF, 0x00, 0xF0, 0xFF, 0xC0, 0xD5, 0x81, 0x01, 0x7E, 0x10, 0x80, 0x00, 0x20, - 0x00, 0x00, 0x00, 0x00, 0xC0, 0xFF, 0x0F, 0xE0, 0xFA, 0x83, 0xC1, 0x3F, 0x08, 0x80, 0x00, 0x20, - 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x01, 0xD8, 0x07, 0x83, 0xF1, 0x1F, 0x04, 0x40, 0x00, 0x20, - 0x00, 0xE0, 0xFF, 0xFF, 0xFF, 0x0F, 0x80, 0xC7, 0x01, 0x83, 0xF1, 0x0F, 0x00, 0x20, 0x00, 0x10, - 0xE0, 0xFF, 0xFF, 0xFF, 0x3F, 0xC0, 0x7F, 0x40, 0x80, 0x83, 0xE1, 0x01, 0x00, 0x20, 0x00, 0x18, - 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x3F, 0x00, 0x20, 0xFC, 0x83, 0x01, 0x00, 0x00, 0x10, 0x00, 0x18, - 0xFF, 0xFF, 0xFF, 0x3F, 0xF0, 0x00, 0x00, 0x10, 0xD7, 0x01, 0x03, 0x00, 0x00, 0x08, 0x00, 0x1C, - 0xFF, 0xFF, 0x01, 0x00, 0x0F, 0x00, 0x00, 0x88, 0xAB, 0x02, 0xE3, 0x01, 0x00, 0x08, 0x00, 0x0C, - 0xFF, 0x07, 0x00, 0xE0, 0x00, 0x00, 0x00, 0xC4, 0x55, 0x05, 0x1E, 0x00, 0x00, 0x04, 0x00, 0x0E, - 0x7F, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0xA3, 0xAB, 0x02, 0x06, 0x00, 0x00, 0x02, 0x00, 0x0F, - 0x0F, 0x00, 0x80, 0x03, 0x00, 0x00, 0xC0, 0x10, 0x57, 0x05, 0x02, 0x00, 0x00, 0x01, 0x80, 0x07, - 0x03, 0x00, 0x70, 0x00, 0x00, 0x00, 0x30, 0x08, 0xAB, 0x0A, 0x02, 0x00, 0xC0, 0x00, 0xC0, 0x07, - 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0C, 0x84, 0x57, 0x15, 0x01, 0x00, 0x30, 0x00, 0xE0, 0x07, - 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0xC3, 0xFF, 0x2A, 0x01, 0x00, 0x0C, 0x00, 0xF0, 0x0F, - 0x00, 0xC0, 0x00, 0x00, 0x00, 0xE0, 0xC0, 0xE0, 0xFE, 0x55, 0x01, 0x82, 0x03, 0x00, 0xF8, 0x15, - 0x00, 0x30, 0x00, 0x00, 0x00, 0x1C, 0x30, 0x78, 0xFE, 0xAA, 0x01, 0x7C, 0x00, 0x00, 0xFC, 0x23, - 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x03, 0x0C, 0x3C, 0x7F, 0x5D, 0x01, 0x00, 0x00, 0x00, 0xFF, 0x45, - 0xC0, 0x01, 0x00, 0x00, 0x3E, 0x00, 0x02, 0x8F, 0xBF, 0xAE, 0x03, 0x00, 0x00, 0xC0, 0xFF, 0x82, - 0x30, 0x00, 0x00, 0xC0, 0x01, 0x80, 0xC1, 0x43, 0xFE, 0x5D, 0x01, 0x00, 0x00, 0xF0, 0xFF, 0x05, - 0x0F, 0x00, 0x80, 0x3F, 0x00, 0x60, 0xF0, 0x31, 0xF6, 0xAE, 0x03, 0x00, 0x00, 0xFA, 0xAF, 0x02, - 0xFC, 0xFF, 0x7F, 0x00, 0x00, 0x18, 0x7C, 0x08, 0x23, 0xFF, 0x05, 0x00, 0x00, 0xFD, 0x55, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0x1F, 0x84, 0x30, 0xFE, 0x0A, 0x00, 0x00, 0xAA, 0xAA, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x80, 0xF1, 0x07, 0x43, 0x18, 0xFF, 0x15, 0x00, 0x00, 0x54, 0x15, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0x80, 0x20, 0x8C, 0xFF, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, -}; - -// Boot request enum -#define BOOT_REQUEST_TAINTED 0x00000000 -#define BOOT_REQUEST_CLEAN 0xDADEDADE -#define BOOT_REQUEST_DFU 0xDF00B000 -// Boot to DFU pin -#define BOOT_DFU_PORT GPIOB -#define BOOT_DFU_PIN LL_GPIO_PIN_11 -// USB pins -#define BOOT_USB_PORT GPIOA -#define BOOT_USB_DM_PIN LL_GPIO_PIN_11 -#define BOOT_USB_DP_PIN LL_GPIO_PIN_12 -#define BOOT_USB_PIN (BOOT_USB_DM_PIN | BOOT_USB_DP_PIN) - -#define RTC_CLOCK_IS_READY() (LL_RCC_LSE_IsReady() && LL_RCC_LSI1_IsReady()) - -void target_led_control(char* c) { - furi_hal_light_set(LightRed, 0x00); - furi_hal_light_set(LightGreen, 0x00); - furi_hal_light_set(LightBlue, 0x00); - do { - if(*c == 'R') { - furi_hal_light_set(LightRed, 0xFF); - } else if(*c == 'G') { - furi_hal_light_set(LightGreen, 0xFF); - } else if(*c == 'B') { - furi_hal_light_set(LightBlue, 0xFF); - } else if(*c == '.') { - LL_mDelay(125); - furi_hal_light_set(LightRed, 0x00); - furi_hal_light_set(LightGreen, 0x00); - furi_hal_light_set(LightBlue, 0x00); - LL_mDelay(125); - } else if(*c == '-') { - LL_mDelay(250); - furi_hal_light_set(LightRed, 0x00); - furi_hal_light_set(LightGreen, 0x00); - furi_hal_light_set(LightBlue, 0x00); - LL_mDelay(250); - } else if(*c == '|') { - furi_hal_light_set(LightRed, 0x00); - furi_hal_light_set(LightGreen, 0x00); - furi_hal_light_set(LightBlue, 0x00); - } - c++; - } while(*c != 0); -} - -void target_clock_init() { - LL_Init1msTick(4000000); - LL_SetSystemCoreClock(4000000); - - LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOA); - LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOB); - LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOC); - LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOD); - LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOE); - LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOH); - - LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_SPI1); - LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_SPI2); -} - -void target_gpio_init() { - // USB D+ - LL_GPIO_SetPinMode(BOOT_USB_PORT, BOOT_USB_DP_PIN, LL_GPIO_MODE_OUTPUT); - LL_GPIO_SetPinSpeed(BOOT_USB_PORT, BOOT_USB_DP_PIN, LL_GPIO_SPEED_FREQ_VERY_HIGH); - LL_GPIO_SetPinOutputType(BOOT_USB_PORT, BOOT_USB_DP_PIN, LL_GPIO_OUTPUT_OPENDRAIN); - // USB D- - LL_GPIO_SetPinMode(BOOT_USB_PORT, BOOT_USB_DM_PIN, LL_GPIO_MODE_OUTPUT); - LL_GPIO_SetPinSpeed(BOOT_USB_PORT, BOOT_USB_DM_PIN, LL_GPIO_SPEED_FREQ_VERY_HIGH); - LL_GPIO_SetPinOutputType(BOOT_USB_PORT, BOOT_USB_DM_PIN, LL_GPIO_OUTPUT_OPENDRAIN); - // Button: back - LL_GPIO_SetPinMode(BOOT_DFU_PORT, BOOT_DFU_PIN, LL_GPIO_MODE_INPUT); - LL_GPIO_SetPinPull(BOOT_DFU_PORT, BOOT_DFU_PIN, LL_GPIO_PULL_UP); -} - -void target_rtc_init() { - // LSE and RTC - LL_PWR_EnableBkUpAccess(); - if(!RTC_CLOCK_IS_READY()) { - // Start LSI1 needed for CSS - LL_RCC_LSI1_Enable(); - // Try to start LSE normal way - LL_RCC_LSE_SetDriveCapability(LL_RCC_LSEDRIVE_HIGH); - LL_RCC_LSE_Enable(); - uint32_t c = 0; - while(!RTC_CLOCK_IS_READY() && c < 200) { - LL_mDelay(10); - c++; - } - // Plan B: reset backup domain - if(!RTC_CLOCK_IS_READY()) { - target_led_control("-R.R.R."); - LL_RCC_ForceBackupDomainReset(); - LL_RCC_ReleaseBackupDomainReset(); - NVIC_SystemReset(); - } - // Set RTC domain clock to LSE - LL_RCC_SetRTCClockSource(LL_RCC_RTC_CLKSOURCE_LSE); - // Enable LSE CSS - LL_RCC_LSE_EnableCSS(); - } - // Enable clocking - LL_RCC_EnableRTC(); - LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_RTCAPB); -} - -void target_version_save(void) { - LL_RTC_BAK_SetRegister(RTC, LL_RTC_BKP_DR1, (uint32_t)version_get()); -} - -void target_usb_wire_reset() { - LL_GPIO_ResetOutputPin(BOOT_USB_PORT, BOOT_USB_PIN); -} - -void target_display_init() { - // Prepare gpio - furi_hal_gpio_init_simple(&gpio_display_rst, GpioModeOutputPushPull); - furi_hal_gpio_init_simple(&gpio_display_di, GpioModeOutputPushPull); - // Initialize - u8g2_t fb; - u8g2_Setup_st756x_flipper(&fb, U8G2_R0, u8x8_hw_spi_stm32, u8g2_gpio_and_delay_stm32); - u8g2_InitDisplay(&fb); - // Create payload - u8g2_ClearBuffer(&fb); - u8g2_SetDrawColor(&fb, 0x01); - u8g2_DrawXBM(&fb, 0, 64 - 50, 128, 50, I_DFU_128x50); -#ifndef SLIM_BOOTLOADER - u8g2_SetFont(&fb, u8g2_font_helvB08_tf); - u8g2_DrawStr(&fb, 2, 8, "Update & Recovery Mode"); - u8g2_DrawStr(&fb, 2, 21, "DFU started"); -#endif - // Send buffer - u8g2_SetPowerSave(&fb, 0); - u8g2_SendBuffer(&fb); -} - -void target_init() { - target_clock_init(); - target_gpio_init(); - furi_hal_init(); - target_led_control("RGB"); - target_rtc_init(); - target_version_save(); - target_usb_wire_reset(); - - // Errata 2.2.9, Flash OPTVERR flag is always set after system reset - __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_ALL_ERRORS); -} - -int target_is_dfu_requested() { - if(LL_RTC_BAK_GetRegister(RTC, LL_RTC_BKP_DR0) == BOOT_REQUEST_TAINTED) { - // Default system state is tainted - // We must ensure that MCU is cleanly booted - LL_RTC_BAK_SetRegister(RTC, LL_RTC_BKP_DR0, BOOT_REQUEST_CLEAN); - NVIC_SystemReset(); - } else if(LL_RTC_BAK_GetRegister(RTC, LL_RTC_BKP_DR0) == BOOT_REQUEST_DFU) { - return 1; - } - LL_mDelay(100); - if(!LL_GPIO_IsInputPinSet(BOOT_DFU_PORT, BOOT_DFU_PIN)) { - return 1; - } - - return 0; -} - -void target_switch(void* offset) { - asm volatile("ldr r3, [%0] \n" - "msr msp, r3 \n" - "ldr r3, [%1] \n" - "mov pc, r3 \n" - : - : "r"(offset), "r"(offset + 0x4) - : "r3"); -} - -void target_switch2dfu() { - target_led_control("B"); - furi_hal_light_set(LightBacklight, 0xFF); - target_display_init(); - // Mark system as tainted, it will be soon - LL_RTC_BAK_SetRegister(RTC, LL_RTC_BKP_DR0, BOOT_REQUEST_TAINTED); - // Remap memory to system bootloader - LL_SYSCFG_SetRemapMemory(LL_SYSCFG_REMAP_SYSTEMFLASH); - // Jump - target_switch(0x0); -} - -void target_switch2os() { - target_led_control("G"); - SCB->VTOR = OS_OFFSET; - target_switch((void*)(BOOT_ADDRESS + OS_OFFSET)); -} diff --git a/bootloader/targets/f7/target.mk b/bootloader/targets/f7/target.mk deleted file mode 100644 index 72677daf11d..00000000000 --- a/bootloader/targets/f7/target.mk +++ /dev/null @@ -1,50 +0,0 @@ -TOOLCHAIN = arm - -BOOT_ADDRESS = 0x08000000 -FW_ADDRESS = 0x08008000 -OS_OFFSET = 0x00008000 -FLASH_ADDRESS = 0x08000000 - -OPENOCD_OPTS = -f interface/stlink.cfg -c "transport select hla_swd" -f ../debug/stm32wbx.cfg -c "init" -BOOT_CFLAGS = -DBOOT_ADDRESS=$(BOOT_ADDRESS) -DFW_ADDRESS=$(FW_ADDRESS) -DOS_OFFSET=$(OS_OFFSET) -MCU_FLAGS = -mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=hard - -CFLAGS += $(MCU_FLAGS) $(BOOT_CFLAGS) -DSTM32WB55xx -Wall -fdata-sections -ffunction-sections -LDFLAGS += $(MCU_FLAGS) -specs=nosys.specs -specs=nano.specs - -HARDWARE_TARGET = 7 - -CUBE_DIR = $(PROJECT_ROOT)/lib/STM32CubeWB - -# ST HAL -CFLAGS += -DUSE_FULL_LL_DRIVER -ASM_SOURCES += $(CUBE_DIR)/Drivers/CMSIS/Device/ST/STM32WBxx/Source/Templates/gcc/startup_stm32wb55xx_cm4.s -C_SOURCES += $(CUBE_DIR)/Drivers/CMSIS/Device/ST/STM32WBxx/Source/Templates/system_stm32wbxx.c -C_SOURCES += $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_ll_utils.c -C_SOURCES += $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_ll_gpio.c -C_SOURCES += $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_ll_i2c.c -C_SOURCES += $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_ll_spi.c - -CFLAGS += -I$(CUBE_DIR)/Drivers/CMSIS/Include -CFLAGS += -I$(CUBE_DIR)/Drivers/CMSIS/Device/ST/STM32WBxx/Include -CFLAGS += -I$(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Inc - -LDFLAGS += -T$(TARGET_DIR)/stm32wb55xx_flash_cm4.ld - -# Drivers -DRIVERS_DIR = $(PROJECT_ROOT)//lib/drivers -CFLAGS += -I$(DRIVERS_DIR) -C_SOURCES += $(DRIVERS_DIR)/lp5562.c - -# API-HAL -CFLAGS += -I$(TARGET_DIR)/furi_hal -C_SOURCES += $(wildcard $(TARGET_DIR)/furi_hal/*.c) - -# Version generation -C_SOURCES += $(PROJECT_ROOT)/lib/toolbox/version.c - -ASM_SOURCES += $(wildcard $(TARGET_DIR)/*.s) -C_SOURCES += $(wildcard $(TARGET_DIR)/*.c) -CPP_SOURCES += $(wildcard $(TARGET_DIR)/*.cpp) - -SVD_FILE = $(PROJECT_ROOT)/debug/STM32WB55_CM4.svd diff --git a/bootloader/targets/furi_hal_include/furi_hal.h b/bootloader/targets/furi_hal_include/furi_hal.h deleted file mode 100644 index 5d612566d34..00000000000 --- a/bootloader/targets/furi_hal_include/furi_hal.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include - -#define furi_assert(value) (void)(value) - -void furi_hal_init(); - -void furi_hal_delay_ms(float milliseconds); - -void furi_hal_delay_us(float microseconds); diff --git a/bootloader/targets/furi_hal_include/furi_hal_spi.h b/bootloader/targets/furi_hal_include/furi_hal_spi.h deleted file mode 100644 index be31727f063..00000000000 --- a/bootloader/targets/furi_hal_include/furi_hal_spi.h +++ /dev/null @@ -1,102 +0,0 @@ -#pragma once - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** Initialize SPI HAL */ -void furi_hal_spi_init(); - -/** Initialize SPI Bus - * - * @param handle pointer to FuriHalSpiBus instance - */ -void furi_hal_spi_bus_init(FuriHalSpiBus* bus); - -/** Deinitialize SPI Bus - * - * @param handle pointer to FuriHalSpiBus instance - */ -void furi_hal_spi_bus_deinit(FuriHalSpiBus* bus); - -/** Initialize SPI Bus Handle - * - * @param handle pointer to FuriHalSpiBusHandle instance - */ -void furi_hal_spi_bus_handle_init(FuriHalSpiBusHandle* handle); - -/** Deinitialize SPI Bus Handle - * - * @param handle pointer to FuriHalSpiBusHandle instance - */ -void furi_hal_spi_bus_handle_deinit(FuriHalSpiBusHandle* handle); - -/** Acquire SPI bus - * - * @warning blocking, calls `furi_crash` on programming error, CS transition is up to handler event routine - * - * @param handle pointer to FuriHalSpiBusHandle instance - */ -void furi_hal_spi_acquire(FuriHalSpiBusHandle* handle); - -/** Release SPI bus - * - * @warning calls `furi_crash` on programming error, CS transition is up to handler event routine - * - * @param handle pointer to FuriHalSpiBusHandle instance - */ -void furi_hal_spi_release(FuriHalSpiBusHandle* handle); - -/** SPI Receive - * - * @param handle pointer to FuriHalSpiBusHandle instance - * @param buffer receive buffer - * @param size transaction size (buffer size) - * @param timeout operation timeout in ms - * - * @return true on sucess - */ -bool furi_hal_spi_bus_rx( - FuriHalSpiBusHandle* handle, - uint8_t* buffer, - size_t size, - uint32_t timeout); - -/** SPI Transmit - * - * @param handle pointer to FuriHalSpiBusHandle instance - * @param buffer transmit buffer - * @param size transaction size (buffer size) - * @param timeout operation timeout in ms - * - * @return true on success - */ -bool furi_hal_spi_bus_tx( - FuriHalSpiBusHandle* handle, - uint8_t* buffer, - size_t size, - uint32_t timeout); - -/** SPI Transmit and Receive - * - * @param handle pointer to FuriHalSpiBusHandle instance - * @param tx_buffer pointer to tx buffer - * @param rx_buffer pointer to rx buffer - * @param size transaction size (buffer size) - * @param timeout operation timeout in ms - * - * @return true on success - */ -bool furi_hal_spi_bus_trx( - FuriHalSpiBusHandle* handle, - uint8_t* tx_buffer, - uint8_t* rx_buffer, - size_t size, - uint32_t timeout); - -#ifdef __cplusplus -} -#endif \ No newline at end of file diff --git a/bootloader/targets/furi_hal_include/furi_hal_version.h b/bootloader/targets/furi_hal_include/furi_hal_version.h deleted file mode 100644 index 62f0147f26a..00000000000 --- a/bootloader/targets/furi_hal_include/furi_hal_version.h +++ /dev/null @@ -1,173 +0,0 @@ -/** - * @file furi_hal_version.h - * Version HAL API - */ - -#pragma once - -#include -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#define FURI_HAL_VERSION_NAME_LENGTH 8 -#define FURI_HAL_VERSION_ARRAY_NAME_LENGTH (FURI_HAL_VERSION_NAME_LENGTH + 1) -/** BLE symbol + "Flipper " + name */ -#define FURI_HAL_VERSION_DEVICE_NAME_LENGTH (1 + 8 + FURI_HAL_VERSION_ARRAY_NAME_LENGTH) - -/** OTP Versions enum */ -typedef enum { - FuriHalVersionOtpVersion0 = 0x00, - FuriHalVersionOtpVersion1 = 0x01, - FuriHalVersionOtpVersion2 = 0x02, - FuriHalVersionOtpVersionEmpty = 0xFFFFFFFE, - FuriHalVersionOtpVersionUnknown = 0xFFFFFFFF, -} FuriHalVersionOtpVersion; - -/** Device Colors */ -typedef enum { - FuriHalVersionColorUnknown = 0x00, - FuriHalVersionColorBlack = 0x01, - FuriHalVersionColorWhite = 0x02, -} FuriHalVersionColor; - -/** Device Regions */ -typedef enum { - FuriHalVersionRegionUnknown = 0x00, - FuriHalVersionRegionEuRu = 0x01, - FuriHalVersionRegionUsCaAu = 0x02, - FuriHalVersionRegionJp = 0x03, -} FuriHalVersionRegion; - -/** Device Display */ -typedef enum { - FuriHalVersionDisplayUnknown = 0x00, - FuriHalVersionDisplayErc = 0x01, - FuriHalVersionDisplayMgg = 0x02, -} FuriHalVersionDisplay; - -/** Init flipper version - */ -void furi_hal_version_init(); - -/** Check target firmware version - * - * @return true if target and real matches - */ -bool furi_hal_version_do_i_belong_here(); - -/** Get model name - * - * @return model name C-string - */ -const char* furi_hal_version_get_model_name(); - -/** Get OTP version - * - * @return OTP Version - */ -const FuriHalVersionOtpVersion furi_hal_version_get_otp_version(); - -/** Get hardware version - * - * @return Hardware Version - */ -const uint8_t furi_hal_version_get_hw_version(); - -/** Get hardware target - * - * @return Hardware Target - */ -const uint8_t furi_hal_version_get_hw_target(); - -/** Get hardware body - * - * @return Hardware Body - */ -const uint8_t furi_hal_version_get_hw_body(); - -/** Get hardware body color - * - * @return Hardware Color - */ -const FuriHalVersionColor furi_hal_version_get_hw_color(); - -/** Get hardware connect - * - * @return Hardware Interconnect - */ -const uint8_t furi_hal_version_get_hw_connect(); - -/** Get hardware region - * - * @return Hardware Region - */ -const FuriHalVersionRegion furi_hal_version_get_hw_region(); - -/** Get hardware display id - * - * @return Display id - */ -const FuriHalVersionDisplay furi_hal_version_get_hw_display(); - -/** Get hardware timestamp - * - * @return Hardware Manufacture timestamp - */ -const uint32_t furi_hal_version_get_hw_timestamp(); - -/** Get pointer to target name - * - * @return Hardware Name C-string - */ -const char* furi_hal_version_get_name_ptr(); - -/** Get pointer to target device name - * - * @return Hardware Device Name C-string - */ -const char* furi_hal_version_get_device_name_ptr(); - -/** Get pointer to target ble local device name - * - * @return Ble Device Name C-string - */ -const char* furi_hal_version_get_ble_local_device_name_ptr(); - -/** Get BLE MAC address - * - * @return pointer to BLE MAC address - */ -const uint8_t* furi_hal_version_get_ble_mac(); - -/** Get address of version structure of bootloader, stored in chip flash. - * - * @return Address of boot version structure. - */ -const struct Version* furi_hal_version_get_bootloader_version(); - -/** Get address of version structure of firmware. - * - * @return Address of firmware version structure. - */ -const struct Version* furi_hal_version_get_firmware_version(); - -/** Get platform UID size in bytes - * - * @return UID size in bytes - */ -size_t furi_hal_version_uid_size(); - -/** Get const pointer to UID - * - * @return pointer to UID - */ -const uint8_t* furi_hal_version_uid(); - -#ifdef __cplusplus -} -#endif diff --git a/bootloader/targets/furi_hal_include/target.h b/bootloader/targets/furi_hal_include/target.h deleted file mode 100644 index e16d4f78fc8..00000000000 --- a/bootloader/targets/furi_hal_include/target.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef TARGET_H -#define TARGET_H - -/** - * Initialize hardware -*/ -void target_init(); - -/** - * Check if dfu mode requested - * @return 1 if dfu mode requested, 0 if not - */ -int target_is_dfu_requested(); - -/** - * Switch to dfu mode - */ -void target_switch2dfu(); - -/** - * Switch to OS - */ -void target_switch2os(); - -#endif \ No newline at end of file diff --git a/core/flipper.c b/core/flipper.c index c7190b3b0ff..c7d7c5a6c2e 100755 --- a/core/flipper.c +++ b/core/flipper.c @@ -11,13 +11,14 @@ static void flipper_print_version(const char* target, const Version* version) { TAG, "\r\n\t%s version:\t%s\r\n" "\tBuild date:\t\t%s\r\n" - "\tGit Commit:\t\t%s (%s)\r\n" + "\tGit Commit:\t\t%s (%s)%s\r\n" "\tGit Branch:\t\t%s", target, version_get_version(version), version_get_builddate(version), version_get_githash(version), version_get_gitbranchnum(version), + version_get_dirty_flag(version) ? " (dirty)" : "", version_get_gitbranch(version)); } else { FURI_LOG_I(TAG, "No build info for %s", target); @@ -25,13 +26,7 @@ static void flipper_print_version(const char* target, const Version* version) { } void flipper_init() { - const Version* version; - - version = (const Version*)furi_hal_version_get_bootloader_version(); - flipper_print_version("Bootloader", version); - - version = (const Version*)furi_hal_version_get_firmware_version(); - flipper_print_version("Firmware", version); + flipper_print_version("Firmware", furi_hal_version_get_firmware_version()); FURI_LOG_I(TAG, "starting services"); diff --git a/core/furi.c b/core/furi.c index 09c5851da68..edee15926f9 100644 --- a/core/furi.c +++ b/core/furi.c @@ -1,7 +1,13 @@ #include "furi.h" void furi_init() { + osKernelInitialize(); + furi_log_init(); furi_record_init(); furi_stdglue_init(); } + +void furi_run() { + osKernelStart(); +} diff --git a/core/furi.h b/core/furi.h index 1844ec9a09b..6a0d1b0a3a0 100644 --- a/core/furi.h +++ b/core/furi.h @@ -27,6 +27,8 @@ extern "C" { void furi_init(); +void furi_run(); + #ifdef __cplusplus } #endif diff --git a/core/furi/check.c b/core/furi/check.c index fafddd910af..5ea76614321 100644 --- a/core/furi/check.c +++ b/core/furi/check.c @@ -21,20 +21,21 @@ void __furi_print_name() { } } -void __furi_halt() { +static FURI_NORETURN void __furi_halt() { asm volatile( #ifdef FURI_DEBUG "bkpt 0x00 \n" #endif - "loop: \n" + "loop%=: \n" "wfi \n" - "b loop \n" + "b loop%= \n" : : : "memory"); + __builtin_unreachable(); } -void furi_crash(const char* message) { +FURI_NORETURN void furi_crash(const char* message) { __disable_irq(); if(message == NULL) { @@ -54,9 +55,10 @@ void furi_crash(const char* message) { furi_hal_console_puts("\033[0m\r\n"); furi_hal_power_reset(); #endif + __builtin_unreachable(); } -void furi_halt(const char* message) { +FURI_NORETURN void furi_halt(const char* message) { __disable_irq(); if(message == NULL) { @@ -69,4 +71,4 @@ void furi_halt(const char* message) { furi_hal_console_puts("\r\nSystem halted. Bye-bye!\r\n"); furi_hal_console_puts("\033[0m\r\n"); __furi_halt(); -} +} \ No newline at end of file diff --git a/core/furi/check.h b/core/furi/check.h index b4b668150f2..adea40399b7 100644 --- a/core/furi/check.h +++ b/core/furi/check.h @@ -1,7 +1,10 @@ #pragma once - #ifdef __cplusplus extern "C" { +#define FURI_NORETURN [[noreturn]] +#else +#include +#define FURI_NORETURN noreturn #endif /** Check condition and crash if check failed */ @@ -15,10 +18,10 @@ extern "C" { #endif /** Crash system */ -void furi_crash(const char* message); +FURI_NORETURN void furi_crash(const char* message); /** Halt system */ -void furi_halt(const char* message); +FURI_NORETURN void furi_halt(const char* message); #ifdef __cplusplus } diff --git a/core/furi/common_defines.h b/core/furi/common_defines.h index 38e6031584f..9c4f7b18ef0 100644 --- a/core/furi/common_defines.h +++ b/core/furi/common_defines.h @@ -101,18 +101,20 @@ extern "C" { #endif #ifndef FURI_IS_ISR -#define FURI_IS_ISR() \ - (FURI_IS_IRQ_MODE() || (FURI_IS_IRQ_MASKED() && (osKernelGetState() == osKernelRunning))) +#define FURI_IS_ISR() (FURI_IS_IRQ_MODE() || FURI_IS_IRQ_MASKED()) #endif #ifndef FURI_CRITICAL_ENTER -#define FURI_CRITICAL_ENTER() \ - uint32_t __isrm = 0; \ - bool __from_isr = FURI_IS_ISR(); \ - if(__from_isr) { \ - __isrm = taskENTER_CRITICAL_FROM_ISR(); \ - } else { \ - taskENTER_CRITICAL(); \ +#define FURI_CRITICAL_ENTER() \ + uint32_t __isrm = 0; \ + bool __from_isr = FURI_IS_ISR(); \ + bool __kernel_running = (osKernelGetState() == osKernelRunning); \ + if(__from_isr) { \ + __isrm = taskENTER_CRITICAL_FROM_ISR(); \ + } else if(__kernel_running) { \ + taskENTER_CRITICAL(); \ + } else { \ + __disable_irq(); \ } #endif @@ -120,8 +122,10 @@ extern "C" { #define FURI_CRITICAL_EXIT() \ if(__from_isr) { \ taskEXIT_CRITICAL_FROM_ISR(__isrm); \ - } else { \ + } else if(__kernel_running) { \ taskEXIT_CRITICAL(); \ + } else { \ + __enable_irq(); \ } #endif diff --git a/core/furi/memmgr.c b/core/furi/memmgr.c index f7a24a768c3..457520d92c8 100644 --- a/core/furi/memmgr.c +++ b/core/furi/memmgr.c @@ -4,6 +4,7 @@ extern void* pvPortMalloc(size_t xSize); extern void vPortFree(void* pv); extern size_t xPortGetFreeHeapSize(void); +extern size_t xPortGetTotalHeapSize(void); extern size_t xPortGetMinimumEverFreeHeapSize(void); void* malloc(size_t size) { @@ -50,6 +51,10 @@ size_t memmgr_get_free_heap(void) { return xPortGetFreeHeapSize(); } +size_t memmgr_get_total_heap(void) { + return xPortGetTotalHeapSize(); +} + size_t memmgr_get_minimum_free_heap(void) { return xPortGetMinimumEverFreeHeapSize(); } diff --git a/core/furi/memmgr.h b/core/furi/memmgr.h index b749c8e5c06..d7285fb238a 100644 --- a/core/furi/memmgr.h +++ b/core/furi/memmgr.h @@ -23,6 +23,12 @@ extern "C" { */ size_t memmgr_get_free_heap(void); +/** Get total heap size + * + * @return total heap size in bytes + */ +size_t memmgr_get_total_heap(void); + /** Get heap watermark * * @return minimum heap in bytes diff --git a/core/furi/memmgr_heap.c b/core/furi/memmgr_heap.c index d40da870b7a..9455371e7c0 100644 --- a/core/furi/memmgr_heap.c +++ b/core/furi/memmgr_heap.c @@ -526,6 +526,11 @@ void vPortFree(void* pv) { } /*-----------------------------------------------------------*/ +size_t xPortGetTotalHeapSize(void) { + return (size_t)&__heap_end__ - (size_t)&__heap_start__; +} +/*-----------------------------------------------------------*/ + size_t xPortGetFreeHeapSize(void) { return xFreeBytesRemaining; } diff --git a/core/furi/record.h b/core/furi/record.h index 2d5f2c49051..cb4bd199f88 100644 --- a/core/furi/record.h +++ b/core/furi/record.h @@ -49,7 +49,7 @@ bool furi_record_destroy(const char* name); * * @return pointer to the record * @note Thread safe. Open and close must be executed from the same - * thread. Suspends caller thread till record appear + * thread. Suspends caller thread till record is available */ void* furi_record_open(const char* name); diff --git a/core/furi/thread.c b/core/furi/thread.c index de86cbdc67f..ee86f62eb5b 100644 --- a/core/furi/thread.c +++ b/core/furi/thread.c @@ -30,7 +30,7 @@ void furi_thread_set_state(FuriThread* thread, FuriThreadState state) { } } -void furi_thread_body(void* context) { +static void furi_thread_body(void* context) { furi_assert(context); FuriThread* thread = context; @@ -167,3 +167,9 @@ size_t furi_thread_get_heap_size(FuriThread* thread) { furi_assert(thread->heap_trace_enabled == true); return thread->heap_size; } + +int32_t furi_thread_get_return_code(FuriThread* thread) { + furi_assert(thread); + furi_assert(thread->state == FuriThreadStateStopped); + return thread->ret; +} diff --git a/core/furi/thread.h b/core/furi/thread.h index 503425179c8..ea1da27afce 100644 --- a/core/furi/thread.h +++ b/core/furi/thread.h @@ -150,6 +150,14 @@ void furi_thread_disable_heap_trace(FuriThread* thread); */ size_t furi_thread_get_heap_size(FuriThread* thread); +/** Get thread return code + * + * @param thread FuriThread instance + * + * @return return code + */ +int32_t furi_thread_get_return_code(FuriThread* thread); + #ifdef __cplusplus } -#endif +#endif \ No newline at end of file diff --git a/firmware/Makefile b/firmware/Makefile index 3237ed590ba..efa185ca620 100644 --- a/firmware/Makefile +++ b/firmware/Makefile @@ -1,6 +1,5 @@ MAKEFILE_DIR := $(dir $(abspath $(firstword $(MAKEFILE_LIST)))) PROJECT_ROOT := $(abspath $(MAKEFILE_DIR)/..) -PROJECT := firmware include $(PROJECT_ROOT)/make/base.mk include $(PROJECT_ROOT)/make/freertos-heap.mk @@ -17,6 +16,12 @@ include $(PROJECT_ROOT)/make/defaults.mk TARGET_DIR = targets/$(TARGET) include $(TARGET_DIR)/target.mk +ifeq ($(RAM_EXEC), 0) +PROJECT := firmware +else +PROJECT := updater +endif + include $(PROJECT_ROOT)/make/git.mk include $(PROJECT_ROOT)/make/toolchain.mk include $(PROJECT_ROOT)/make/rules.mk diff --git a/firmware/ReadMe.md b/firmware/ReadMe.md index 237adae9a97..f12f2e7bd4c 100644 --- a/firmware/ReadMe.md +++ b/firmware/ReadMe.md @@ -1,6 +1,6 @@ # Flipper firmware -What it does? +What does it do? - [x] RTOS - [x] FuriHAL @@ -10,13 +10,13 @@ What it does? # Targets -| Name | Bootloader | Firmware | Reset | DFU | -| | Address | Address | Combo | Combo | ------------------------------------------------------------------------------ -| f7 | 0x08000000 | 0x00008000 | L+Back | L+Back, hold L | +| Name | Firmware | Reset | DFU | +| | Address | Combo | Combo | +--------------------------------------------------------------------------------- +| f7 | 0x08000000 | L+Back, release both | L+Back, release Back | -Also there is a ST bootloader combo available on empty device: L+Ok+Back, release Back,Left. -Target independent code and headers in `target/include` folders. +Also there is a "hardware" ST bootloader combo available even on a bricked or empty device: L+Ok+Back, release Back, Left. +Target independent code and headers in `target/include` folders. More details in `documentation/KeyCombo.md` # Building @@ -31,7 +31,9 @@ Target independent code and headers in `target/include` folders. ## Build Options - `DEBUG` - 0/1 - enable or disable debug build. Default is 1. +- `COMPACT` - 0/1 - enable or disable compiler optimizations. Significantly reduces binary size. Default is 0. - `TARGET` - string - target to build. Default is `f7`. +- `RAM_EXEC` - 0/1 - whether to build full firmware or RAM-based stage for firmware update. 0 is default, builds firmware. # Flashing diff --git a/firmware/targets/f7/Inc/FreeRTOSConfig.h b/firmware/targets/f7/Inc/FreeRTOSConfig.h index ee56922b15d..f0944cb7640 100644 --- a/firmware/targets/f7/Inc/FreeRTOSConfig.h +++ b/firmware/targets/f7/Inc/FreeRTOSConfig.h @@ -30,7 +30,7 @@ extern uint32_t SystemCoreClock; #define configUSE_16_BIT_TICKS 0 #define configUSE_MUTEXES 1 #define configQUEUE_REGISTRY_SIZE 8 -#define configCHECK_FOR_STACK_OVERFLOW 1 +#define configCHECK_FOR_STACK_OVERFLOW 2 #define configUSE_RECURSIVE_MUTEXES 1 #define configUSE_COUNTING_SEMAPHORES 1 #define configENABLE_BACKWARD_COMPATIBILITY 0 @@ -124,11 +124,13 @@ See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */ /* Normal assert() semantics without relying on the provision of an assert.h header file. */ +#ifdef DEBUG #include #define configASSERT(x) \ if((x) == 0) { \ furi_crash("FreeRTOS Assert"); \ } +#endif /* Definitions that map the FreeRTOS port interrupt handlers to their CMSIS standard names. */ diff --git a/firmware/targets/f7/Inc/alt_boot.h b/firmware/targets/f7/Inc/alt_boot.h new file mode 100644 index 00000000000..91bf9bdf71d --- /dev/null +++ b/firmware/targets/f7/Inc/alt_boot.h @@ -0,0 +1,13 @@ +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +void flipper_boot_update_exec(); + +void flipper_boot_dfu_exec(); + +#ifdef __cplusplus +} +#endif diff --git a/firmware/targets/f7/Src/dfu.c b/firmware/targets/f7/Src/dfu.c new file mode 100644 index 00000000000..889c3c1ecd5 --- /dev/null +++ b/firmware/targets/f7/Src/dfu.c @@ -0,0 +1,41 @@ +#include +#include +#include +#include +#include +#include + +void flipper_boot_dfu_show_splash() { + // Initialize + furi_hal_compress_icon_init(); + + u8g2_t* fb = malloc(sizeof(u8g2_t)); + memset(fb, 0, sizeof(u8g2_t)); + u8g2_Setup_st756x_flipper(fb, U8G2_R0, u8x8_hw_spi_stm32, u8g2_gpio_and_delay_stm32); + u8g2_InitDisplay(fb); + u8g2_SetDrawColor(fb, 0x01); + uint8_t* splash_data = NULL; + furi_hal_compress_icon_decode(icon_get_data(&I_DFU_128x50), &splash_data); + u8g2_DrawXBM(fb, 0, 64 - 50, 128, 50, splash_data); + u8g2_SetFont(fb, u8g2_font_helvB08_tr); + u8g2_DrawStr(fb, 2, 8, "Update & Recovery Mode"); + u8g2_DrawStr(fb, 2, 21, "DFU started"); + u8g2_SetPowerSave(fb, 0); + u8g2_SendBuffer(fb); +} + +void flipper_boot_dfu_exec() { + // Show DFU splashscreen + flipper_boot_dfu_show_splash(); + + // Errata 2.2.9, Flash OPTVERR flag is always set after system reset + WRITE_REG(FLASH->SR, FLASH_SR_OPTVERR); + + // Cleanup before jumping to DFU + furi_hal_deinit_early(); + + // Remap memory to system bootloader + LL_SYSCFG_SetRemapMemory(LL_SYSCFG_REMAP_SYSTEMFLASH); + // Jump + furi_hal_switch(0x0); +} diff --git a/firmware/targets/f7/Src/main.c b/firmware/targets/f7/Src/main.c index 2dcaab920cb..2e3bf04ff8b 100644 --- a/firmware/targets/f7/Src/main.c +++ b/firmware/targets/f7/Src/main.c @@ -1,29 +1,85 @@ #include #include #include +#include +#include #define TAG "Main" -int main(void) { - // Flipper critical FURI HAL - furi_hal_init_critical(); - +#ifdef FURI_RAM_EXEC +int main() { // Initialize FURI layer furi_init(); + // Flipper critical FURI HAL + furi_hal_init_early(); + // Flipper FURI HAL furi_hal_init(); - // CMSIS initialization - osKernelInitialize(); - FURI_LOG_I(TAG, "KERNEL OK"); - // Init flipper flipper_init(); - // Start kernel - osKernelStart(); + furi_run(); while(1) { } } +#else +int main() { + // Initialize FURI layer + furi_init(); + + // Flipper critical FURI HAL + furi_hal_init_early(); + furi_hal_light_sequence("RGB"); + + // Delay is for button sampling + furi_hal_delay_ms(100); + + FuriHalRtcBootMode boot_mode = furi_hal_rtc_get_boot_mode(); + if(boot_mode == FuriHalRtcBootModeDfu || !furi_hal_gpio_read(&gpio_button_left)) { + furi_hal_light_sequence("rgb WB"); + furi_hal_rtc_set_boot_mode(FuriHalRtcBootModeNormal); + flipper_boot_dfu_exec(); + furi_hal_power_reset(); + } else if(boot_mode == FuriHalRtcBootModeUpdate) { + furi_hal_light_sequence("rgb BR"); + flipper_boot_update_exec(); + // if things go nice, we shouldn't reach this point. + // But if we do, abandon to avoid bootloops + furi_hal_rtc_set_boot_mode(FuriHalRtcBootModeNormal); + furi_hal_power_reset(); + } else { + furi_hal_light_sequence("rgb G"); + + // Flipper FURI HAL + furi_hal_init(); + + // Init flipper + flipper_init(); + + furi_run(); + } + + while(1) { + } +} +#endif + +void Error_Handler(void) { + furi_crash("ErrorHandler"); +} + +#ifdef USE_FULL_ASSERT +/** + * @brief Reports the name of the source file and the source line number + * where the assert_param error has occurred. + * @param file: pointer to the source file name + * @param line: assert_param error line source number + * @retval None + */ +void assert_failed(uint8_t* file, uint32_t line) { + furi_crash("HAL assert failed"); +} +#endif /* USE_FULL_ASSERT */ diff --git a/firmware/targets/f7/Src/system_stm32wbxx.c b/firmware/targets/f7/Src/system_stm32wbxx.c index 9fc52ca7a17..77430fda8b8 100644 --- a/firmware/targets/f7/Src/system_stm32wbxx.c +++ b/firmware/targets/f7/Src/system_stm32wbxx.c @@ -1,15 +1,15 @@ #include "stm32wbxx.h" -/*!< Uncomment the following line if you need to relocate your vector Table in - Internal SRAM. */ +/*!< Uncomment the following line if you need to relocate your vector Table in Internal SRAM. */ /* #define VECT_TAB_SRAM */ + +#ifndef VECT_TAB_OFFSET #define VECT_TAB_OFFSET \ - OS_OFFSET /*!< Vector Table base offset field. - This value must be a multiple of 0x200. */ + 0x0 /*!< Vector Table base offset field. This value must be a multiple of 0x200. */ +#endif #define VECT_TAB_BASE_ADDRESS \ - SRAM1_BASE /*!< Vector Table base offset field. - This value must be a multiple of 0x200. */ + SRAM1_BASE /*!< Vector Table base offset field. This value must be a multiple of 0x200. */ /* The SystemCoreClock variable is updated in three ways: 1) by calling CMSIS function SystemCoreClockUpdate() diff --git a/firmware/targets/f7/Src/update.c b/firmware/targets/f7/Src/update.c new file mode 100644 index 00000000000..3e94fbecf1a --- /dev/null +++ b/firmware/targets/f7/Src/update.c @@ -0,0 +1,196 @@ +#include +#include +#include +#include + +#include +#include + +#include +#include + +static FATFS* pfs = NULL; + +static const char FS_ROOT_PATH[] = "/"; + +#define CHECK_FRESULT(result) \ + { \ + if((result) != FR_OK) { \ + return false; \ + } \ + } + +static bool flipper_update_init() { + furi_hal_clock_init(); + furi_hal_rtc_init(); + furi_hal_interrupt_init(); + furi_hal_delay_init(); + + furi_hal_spi_init(); + furi_hal_crc_init(false); + + MX_FATFS_Init(); + if(!hal_sd_detect()) { + return false; + } + + if(BSP_SD_Init(true)) { + return false; + } + + pfs = malloc(sizeof(FATFS)); + CHECK_FRESULT(f_mount(pfs, FS_ROOT_PATH, 1)); + return true; +} + +static bool flipper_update_load_stage(const string_t work_dir, UpdateManifest* manifest) { + FIL file; + FILINFO stat; + + string_t loader_img_path; + string_init_set(loader_img_path, work_dir); + path_append(loader_img_path, string_get_cstr(manifest->staged_loader_file)); + + if((f_stat(string_get_cstr(loader_img_path), &stat) != FR_OK) || + (f_open(&file, string_get_cstr(loader_img_path), FA_OPEN_EXISTING | FA_READ) != FR_OK)) { + string_clear(loader_img_path); + return false; + } + string_clear(loader_img_path); + + void* img = malloc(stat.fsize); + uint32_t bytes_read = 0; + const uint16_t MAX_READ = 0xFFFF; + + furi_hal_crc_reset(); + uint32_t crc = 0; + do { + uint16_t size_read = 0; + if(f_read(&file, img + bytes_read, MAX_READ, &size_read) != FR_OK) { + break; + } + crc = furi_hal_crc_feed(img + bytes_read, size_read); + bytes_read += size_read; + } while(bytes_read == MAX_READ); + furi_hal_crc_reset(); + + do { + if((bytes_read != stat.fsize) || (crc != manifest->staged_loader_crc)) { + break; + } + + /* Point of no return. Literally + * + * NB: we MUST disable IRQ, otherwise handlers from flash + * will change global variables (like tick count) + * that are located in .data. And we move staged loader + * to the same memory region. So, IRQ handlers will mess up + * memmove'd .text section and ruin your day. + * We don't want that to happen. + */ + __disable_irq(); + + memmove((void*)(SRAM1_BASE), img, stat.fsize); + LL_SYSCFG_SetRemapMemory(LL_SYSCFG_REMAP_SRAM); + furi_hal_switch((void*)SRAM1_BASE); + return true; + + } while(false); + + free(img); + return false; +} + +static bool flipper_update_get_work_directory(string_t out_dir) { + const uint32_t update_index = furi_hal_rtc_get_register(FuriHalRtcRegisterUpdateFolderFSIndex); + if(update_index == 0) { + string_set(out_dir, UPDATE_DIR_DEFAULT_REL_PATH); + return true; + } + + DIR dir; + UINT entry_idx = 0; + FILINFO fno; + CHECK_FRESULT(f_opendir(&dir, UPDATE_DIR_DEFAULT_REL_PATH)); + string_set(out_dir, UPDATE_DIR_DEFAULT_REL_PATH); + + while(f_readdir(&dir, &fno) == FR_OK) { + entry_idx++; + if(fno.fname[0] == '\0') { + return false; + } + if(entry_idx == update_index) { + path_append(out_dir, fno.fname); + return true; + } + } + + string_reset(out_dir); + return false; +} + +static UpdateManifest* flipper_update_process_manifest(const string_t work_dir) { + FIL file; + FILINFO stat; + + string_t manifest_path; + string_init_set(manifest_path, work_dir); + path_append(manifest_path, UPDATE_MANIFEST_DEFAULT_NAME); + + CHECK_FRESULT(f_stat(string_get_cstr(manifest_path), &stat)); + CHECK_FRESULT(f_open(&file, string_get_cstr(manifest_path), FA_OPEN_EXISTING | FA_READ)); + + uint8_t* manifest_data = malloc(stat.fsize); + uint32_t bytes_read = 0; + const uint16_t MAX_READ = 0xFFFF; + + do { + uint16_t size_read = 0; + if(f_read(&file, manifest_data + bytes_read, MAX_READ, &size_read) != FR_OK) { + break; + } + bytes_read += size_read; + } while(bytes_read == MAX_READ); + + UpdateManifest* manifest = NULL; + do { + if(bytes_read != stat.fsize) { + break; + } + + manifest = update_manifest_alloc(); + if(!update_manifest_init_mem(manifest, manifest_data, bytes_read)) { + update_manifest_free(manifest); + manifest = NULL; + } + } while(false); + + string_clear(manifest_path); + free(manifest_data); + return manifest; +} + +void flipper_boot_update_exec() { + if(!flipper_update_init()) { + return; + } + + string_t work_dir; + string_init(work_dir); + do { + if(!flipper_update_get_work_directory(work_dir)) { + break; + } + + UpdateManifest* manifest = flipper_update_process_manifest(work_dir); + if(!manifest) { + break; + } + + if(!flipper_update_load_stage(work_dir, manifest)) { + update_manifest_free(manifest); + } + } while(false); + string_clear(work_dir); + free(pfs); +} diff --git a/firmware/targets/f7/cube/Inc/FreeRTOSConfig.h b/firmware/targets/f7/cube/Inc/FreeRTOSConfig.h deleted file mode 100644 index 47883e666c0..00000000000 --- a/firmware/targets/f7/cube/Inc/FreeRTOSConfig.h +++ /dev/null @@ -1,193 +0,0 @@ -/* USER CODE BEGIN Header */ -/* - * FreeRTOS Kernel V10.3.1 - * Portion Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * Portion Copyright (C) 2019 StMicroelectronics, Inc. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * http://www.FreeRTOS.org - * http://aws.amazon.com/freertos - * - * 1 tab == 4 spaces! - */ -/* USER CODE END Header */ - -#ifndef FREERTOS_CONFIG_H -#define FREERTOS_CONFIG_H - -/*----------------------------------------------------------- - * Application specific definitions. - * - * These definitions should be adjusted for your particular hardware and - * application requirements. - * - * These parameters and more are described within the 'configuration' section of the - * FreeRTOS API documentation available on the FreeRTOS.org web site. - * - * See http://www.freertos.org/a00110.html - *----------------------------------------------------------*/ - -/* USER CODE BEGIN Includes */ -/* Section where include file can be added */ -/* USER CODE END Includes */ - -/* Ensure definitions are only used by the compiler, and not by the assembler. */ -#if defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__) -#include -extern uint32_t SystemCoreClock; -void xPortSysTickHandler(void); -/* USER CODE BEGIN 0 */ -extern void configureTimerForRunTimeStats(void); -extern unsigned long getRunTimeCounterValue(void); -/* USER CODE END 0 */ -#endif -#ifndef CMSIS_device_header -#define CMSIS_device_header "stm32wbxx.h" -#endif /* CMSIS_device_header */ - -#define configENABLE_FPU 1 -#define configENABLE_MPU 0 - -#define configUSE_PREEMPTION 1 -#define configSUPPORT_STATIC_ALLOCATION 1 -#define configSUPPORT_DYNAMIC_ALLOCATION 1 -#define configUSE_IDLE_HOOK 1 -#define configUSE_TICK_HOOK 0 -#define configCPU_CLOCK_HZ (SystemCoreClock) -#define configTICK_RATE_HZ ((TickType_t)1000) -#define configMAX_PRIORITIES (56) -#define configMINIMAL_STACK_SIZE ((uint16_t)128) -#define configTOTAL_HEAP_SIZE ((size_t)40960) -#define configMAX_TASK_NAME_LEN (16) -#define configGENERATE_RUN_TIME_STATS 1 -#define configUSE_TRACE_FACILITY 1 -#define configUSE_16_BIT_TICKS 0 -#define configUSE_MUTEXES 1 -#define configQUEUE_REGISTRY_SIZE 8 -#define configCHECK_FOR_STACK_OVERFLOW 1 -#define configUSE_RECURSIVE_MUTEXES 1 -#define configUSE_COUNTING_SEMAPHORES 1 -#define configENABLE_BACKWARD_COMPATIBILITY 0 -#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 -#define configUSE_TICKLESS_IDLE 2 -#define configRECORD_STACK_HIGH_ADDRESS 1 -/* USER CODE BEGIN MESSAGE_BUFFER_LENGTH_TYPE */ -/* Defaults to size_t for backward compatibility, but can be changed - if lengths will always be less than the number of bytes in a size_t. */ -#define configMESSAGE_BUFFER_LENGTH_TYPE size_t -/* USER CODE END MESSAGE_BUFFER_LENGTH_TYPE */ - -/* Co-routine definitions. */ -#define configUSE_CO_ROUTINES 0 -#define configMAX_CO_ROUTINE_PRIORITIES (2) - -/* Software timer definitions. */ -#define configUSE_TIMERS 1 -#define configTIMER_TASK_PRIORITY (2) -#define configTIMER_QUEUE_LENGTH 10 -#define configTIMER_TASK_STACK_DEPTH 256 - -/* CMSIS-RTOS V2 flags */ -#define configUSE_OS2_THREAD_SUSPEND_RESUME 1 -#define configUSE_OS2_THREAD_ENUMERATE 1 -#define configUSE_OS2_EVENTFLAGS_FROM_ISR 1 -#define configUSE_OS2_THREAD_FLAGS 1 -#define configUSE_OS2_TIMER 1 -#define configUSE_OS2_MUTEX 1 - -/* Set the following definitions to 1 to include the API function, or zero -to exclude the API function. */ -#define INCLUDE_vTaskPrioritySet 1 -#define INCLUDE_uxTaskPriorityGet 1 -#define INCLUDE_vTaskDelete 1 -#define INCLUDE_vTaskCleanUpResources 1 -#define INCLUDE_vTaskSuspend 1 -#define INCLUDE_vTaskDelayUntil 1 -#define INCLUDE_vTaskDelay 1 -#define INCLUDE_xTaskGetSchedulerState 1 -#define INCLUDE_xTimerPendFunctionCall 1 -#define INCLUDE_xQueueGetMutexHolder 1 -#define INCLUDE_uxTaskGetStackHighWaterMark 1 -#define INCLUDE_xTaskGetCurrentTaskHandle 1 -#define INCLUDE_eTaskGetState 1 - -/* - * The CMSIS-RTOS V2 FreeRTOS wrapper is dependent on the heap implementation used - * by the application thus the correct define need to be enabled below - */ -#define USE_FreeRTOS_HEAP_4 - -/* Cortex-M specific definitions. */ -#ifdef __NVIC_PRIO_BITS -/* __BVIC_PRIO_BITS will be specified when CMSIS is being used. */ -#define configPRIO_BITS __NVIC_PRIO_BITS -#else -#define configPRIO_BITS 4 -#endif - -/* The lowest interrupt priority that can be used in a call to a "set priority" -function. */ -#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 15 - -/* The highest interrupt priority that can be used by any interrupt service -routine that makes calls to interrupt safe FreeRTOS API functions. DO NOT CALL -INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER -PRIORITY THAN THIS! (higher priorities are lower numeric values. */ -#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5 - -/* Interrupt priorities used by the kernel port layer itself. These are generic -to all Cortex-M ports, and do not rely on any particular library functions. */ -#define configKERNEL_INTERRUPT_PRIORITY \ - (configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS)) -/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!! -See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */ -#define configMAX_SYSCALL_INTERRUPT_PRIORITY \ - (configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS)) - -/* Normal assert() semantics without relying on the provision of an assert.h -header file. */ -/* USER CODE BEGIN 1 */ -#define configASSERT(x) \ - if((x) == 0) { \ - taskDISABLE_INTERRUPTS(); \ - for(;;) \ - ; \ - } -/* USER CODE END 1 */ - -/* Definitions that map the FreeRTOS port interrupt handlers to their CMSIS -standard names. */ -#define vPortSVCHandler SVC_Handler -#define xPortPendSVHandler PendSV_Handler - -/* IMPORTANT: After 10.3.1 update, Systick_Handler comes from NVIC (if SYS timebase = systick), otherwise from cmsis_os2.c */ - -#define USE_CUSTOM_SYSTICK_HANDLER_IMPLEMENTATION 1 - -/* USER CODE BEGIN 2 */ -/* Definitions needed when configGENERATE_RUN_TIME_STATS is on */ -#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS configureTimerForRunTimeStats -#define portGET_RUN_TIME_COUNTER_VALUE getRunTimeCounterValue -/* USER CODE END 2 */ - -/* USER CODE BEGIN Defines */ -/* Section where parameter definitions can be added (for instance, to override default ones in FreeRTOS.h) */ -/* USER CODE END Defines */ - -#endif /* FREERTOS_CONFIG_H */ diff --git a/firmware/targets/f7/cube/Inc/adc.h b/firmware/targets/f7/cube/Inc/adc.h deleted file mode 100644 index 940f1d49723..00000000000 --- a/firmware/targets/f7/cube/Inc/adc.h +++ /dev/null @@ -1,52 +0,0 @@ -/** - ****************************************************************************** - * @file adc.h - * @brief This file contains all the function prototypes for - * the adc.c file - ****************************************************************************** - * @attention - * - *

© Copyright (c) 2021 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __ADC_H__ -#define __ADC_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "main.h" - -/* USER CODE BEGIN Includes */ - -/* USER CODE END Includes */ - -extern ADC_HandleTypeDef hadc1; - -/* USER CODE BEGIN Private defines */ - -/* USER CODE END Private defines */ - -void MX_ADC1_Init(void); - -/* USER CODE BEGIN Prototypes */ - -/* USER CODE END Prototypes */ - -#ifdef __cplusplus -} -#endif - -#endif /* __ADC_H__ */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/firmware/targets/f7/cube/Inc/aes.h b/firmware/targets/f7/cube/Inc/aes.h deleted file mode 100644 index 93c548f7508..00000000000 --- a/firmware/targets/f7/cube/Inc/aes.h +++ /dev/null @@ -1,54 +0,0 @@ -/** - ****************************************************************************** - * @file aes.h - * @brief This file contains all the function prototypes for - * the aes.c file - ****************************************************************************** - * @attention - * - *

© Copyright (c) 2021 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __AES_H__ -#define __AES_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "main.h" - -/* USER CODE BEGIN Includes */ - -/* USER CODE END Includes */ - -extern CRYP_HandleTypeDef hcryp1; -extern CRYP_HandleTypeDef hcryp2; - -/* USER CODE BEGIN Private defines */ - -/* USER CODE END Private defines */ - -void MX_AES1_Init(void); -void MX_AES2_Init(void); - -/* USER CODE BEGIN Prototypes */ - -/* USER CODE END Prototypes */ - -#ifdef __cplusplus -} -#endif - -#endif /* __AES_H__ */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/firmware/targets/f7/cube/Inc/comp.h b/firmware/targets/f7/cube/Inc/comp.h deleted file mode 100644 index a0ebfd5b642..00000000000 --- a/firmware/targets/f7/cube/Inc/comp.h +++ /dev/null @@ -1,52 +0,0 @@ -/** - ****************************************************************************** - * @file comp.h - * @brief This file contains all the function prototypes for - * the comp.c file - ****************************************************************************** - * @attention - * - *

© Copyright (c) 2021 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __COMP_H__ -#define __COMP_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "main.h" - -/* USER CODE BEGIN Includes */ - -/* USER CODE END Includes */ - -extern COMP_HandleTypeDef hcomp1; - -/* USER CODE BEGIN Private defines */ - -/* USER CODE END Private defines */ - -void MX_COMP1_Init(void); - -/* USER CODE BEGIN Prototypes */ - -/* USER CODE END Prototypes */ - -#ifdef __cplusplus -} -#endif - -#endif /* __COMP_H__ */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/firmware/targets/f7/cube/Inc/crc.h b/firmware/targets/f7/cube/Inc/crc.h deleted file mode 100644 index 8f05b75c253..00000000000 --- a/firmware/targets/f7/cube/Inc/crc.h +++ /dev/null @@ -1,52 +0,0 @@ -/** - ****************************************************************************** - * @file crc.h - * @brief This file contains all the function prototypes for - * the crc.c file - ****************************************************************************** - * @attention - * - *

© Copyright (c) 2021 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __CRC_H__ -#define __CRC_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "main.h" - -/* USER CODE BEGIN Includes */ - -/* USER CODE END Includes */ - -extern CRC_HandleTypeDef hcrc; - -/* USER CODE BEGIN Private defines */ - -/* USER CODE END Private defines */ - -void MX_CRC_Init(void); - -/* USER CODE BEGIN Prototypes */ - -/* USER CODE END Prototypes */ - -#ifdef __cplusplus -} -#endif - -#endif /* __CRC_H__ */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/firmware/targets/f7/cube/Inc/gpio.h b/firmware/targets/f7/cube/Inc/gpio.h deleted file mode 100644 index b8813862c7b..00000000000 --- a/firmware/targets/f7/cube/Inc/gpio.h +++ /dev/null @@ -1,49 +0,0 @@ -/** - ****************************************************************************** - * @file gpio.h - * @brief This file contains all the function prototypes for - * the gpio.c file - ****************************************************************************** - * @attention - * - *

© Copyright (c) 2021 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __GPIO_H__ -#define __GPIO_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "main.h" - -/* USER CODE BEGIN Includes */ - -/* USER CODE END Includes */ - -/* USER CODE BEGIN Private defines */ - -/* USER CODE END Private defines */ - -void MX_GPIO_Init(void); - -/* USER CODE BEGIN Prototypes */ - -/* USER CODE END Prototypes */ - -#ifdef __cplusplus -} -#endif -#endif /*__ GPIO_H__ */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/firmware/targets/f7/cube/Inc/i2c.h b/firmware/targets/f7/cube/Inc/i2c.h deleted file mode 100644 index b4f04780b91..00000000000 --- a/firmware/targets/f7/cube/Inc/i2c.h +++ /dev/null @@ -1,50 +0,0 @@ -/** - ****************************************************************************** - * @file i2c.h - * @brief This file contains all the function prototypes for - * the i2c.c file - ****************************************************************************** - * @attention - * - *

© Copyright (c) 2021 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __I2C_H__ -#define __I2C_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "main.h" - -/* USER CODE BEGIN Includes */ - -/* USER CODE END Includes */ - -/* USER CODE BEGIN Private defines */ - -/* USER CODE END Private defines */ - -void MX_I2C1_Init(void); - -/* USER CODE BEGIN Prototypes */ - -/* USER CODE END Prototypes */ - -#ifdef __cplusplus -} -#endif - -#endif /* __I2C_H__ */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/firmware/targets/f7/cube/Inc/main.h b/firmware/targets/f7/cube/Inc/main.h deleted file mode 100644 index 3d34eb81b47..00000000000 --- a/firmware/targets/f7/cube/Inc/main.h +++ /dev/null @@ -1,175 +0,0 @@ -/* USER CODE BEGIN Header */ -/** - ****************************************************************************** - * @file : main.h - * @brief : Header for main.c file. - * This file contains the common defines of the application. - ****************************************************************************** - * @attention - * - *

© Copyright (c) 2021 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ -/* USER CODE END Header */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __MAIN_H -#define __MAIN_H - -#ifdef __cplusplus -extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "stm32wbxx_hal.h" - -#include "stm32wbxx_ll_i2c.h" -#include "stm32wbxx_ll_crs.h" -#include "stm32wbxx_ll_rcc.h" -#include "stm32wbxx_ll_bus.h" -#include "stm32wbxx_ll_system.h" -#include "stm32wbxx_ll_exti.h" -#include "stm32wbxx_ll_cortex.h" -#include "stm32wbxx_ll_utils.h" -#include "stm32wbxx_ll_pwr.h" -#include "stm32wbxx_ll_dma.h" -#include "stm32wbxx_ll_usart.h" -#include "stm32wbxx_ll_gpio.h" - -/* Private includes ----------------------------------------------------------*/ -/* USER CODE BEGIN Includes */ - -/* USER CODE END Includes */ - -/* Exported types ------------------------------------------------------------*/ -/* USER CODE BEGIN ET */ - -/* USER CODE END ET */ - -/* Exported constants --------------------------------------------------------*/ -/* USER CODE BEGIN EC */ - -/* USER CODE END EC */ - -/* Exported macro ------------------------------------------------------------*/ -/* USER CODE BEGIN EM */ - -/* USER CODE END EM */ - -/* Exported functions prototypes ---------------------------------------------*/ -void Error_Handler(void); - -/* USER CODE BEGIN EFP */ - -/* USER CODE END EFP */ - -/* Private defines -----------------------------------------------------------*/ -#define BUTTON_BACK_Pin GPIO_PIN_13 -#define BUTTON_BACK_GPIO_Port GPIOC -#define BUTTON_BACK_EXTI_IRQn EXTI15_10_IRQn -#define QUARTZ_32MHZ_IN_Pin GPIO_PIN_14 -#define QUARTZ_32MHZ_IN_GPIO_Port GPIOC -#define QUARTZ_32MHZ_OUT_Pin GPIO_PIN_15 -#define QUARTZ_32MHZ_OUT_GPIO_Port GPIOC -#define BUTTON_OK_Pin GPIO_PIN_3 -#define BUTTON_OK_GPIO_Port GPIOH -#define BUTTON_OK_EXTI_IRQn EXTI3_IRQn -#define SPEAKER_Pin GPIO_PIN_8 -#define SPEAKER_GPIO_Port GPIOB -#define IR_TX_Pin GPIO_PIN_9 -#define IR_TX_GPIO_Port GPIOB -#define PC0_Pin GPIO_PIN_0 -#define PC0_GPIO_Port GPIOC -#define PC1_Pin GPIO_PIN_1 -#define PC1_GPIO_Port GPIOC -#define SPI_D_MISO_Pin GPIO_PIN_2 -#define SPI_D_MISO_GPIO_Port GPIOC -#define PC3_Pin GPIO_PIN_3 -#define PC3_GPIO_Port GPIOC -#define IR_RX_Pin GPIO_PIN_0 -#define IR_RX_GPIO_Port GPIOA -#define CC1101_G0_Pin GPIO_PIN_1 -#define CC1101_G0_GPIO_Port GPIOA -#define RFID_PULL_Pin GPIO_PIN_2 -#define RFID_PULL_GPIO_Port GPIOA -#define PERIPH_POWER_Pin GPIO_PIN_3 -#define PERIPH_POWER_GPIO_Port GPIOA -#define PA4_Pin GPIO_PIN_4 -#define PA4_GPIO_Port GPIOA -#define SPI_R_SCK_Pin GPIO_PIN_5 -#define SPI_R_SCK_GPIO_Port GPIOA -#define PA6_Pin GPIO_PIN_6 -#define PA6_GPIO_Port GPIOA -#define PA7_Pin GPIO_PIN_7 -#define PA7_GPIO_Port GPIOA -#define VIBRO_Pin GPIO_PIN_8 -#define VIBRO_GPIO_Port GPIOA -#define I2C_SCL_Pin GPIO_PIN_9 -#define I2C_SCL_GPIO_Port GPIOA -#define RF_SW_0_Pin GPIO_PIN_4 -#define RF_SW_0_GPIO_Port GPIOC -#define RFID_RF_IN_Pin GPIO_PIN_5 -#define RFID_RF_IN_GPIO_Port GPIOC -#define PB2_Pin GPIO_PIN_2 -#define PB2_GPIO_Port GPIOB -#define BUTTON_UP_Pin GPIO_PIN_10 -#define BUTTON_UP_GPIO_Port GPIOB -#define BUTTON_UP_EXTI_IRQn EXTI15_10_IRQn -#define BUTTON_LEFT_Pin GPIO_PIN_11 -#define BUTTON_LEFT_GPIO_Port GPIOB -#define BUTTON_LEFT_EXTI_IRQn EXTI15_10_IRQn -#define DISPLAY_RST_Pin GPIO_PIN_0 -#define DISPLAY_RST_GPIO_Port GPIOB -#define DISPLAY_DI_Pin GPIO_PIN_1 -#define DISPLAY_DI_GPIO_Port GPIOB -#define NFC_CS_Pin GPIO_PIN_4 -#define NFC_CS_GPIO_Port GPIOE -#define BUTTON_RIGHT_Pin GPIO_PIN_12 -#define BUTTON_RIGHT_GPIO_Port GPIOB -#define BUTTON_RIGHT_EXTI_IRQn EXTI15_10_IRQn -#define RFID_OUT_Pin GPIO_PIN_13 -#define RFID_OUT_GPIO_Port GPIOB -#define iBTN_Pin GPIO_PIN_14 -#define iBTN_GPIO_Port GPIOB -#define SPI_D_MOSI_Pin GPIO_PIN_15 -#define SPI_D_MOSI_GPIO_Port GPIOB -#define BUTTON_DOWN_Pin GPIO_PIN_6 -#define BUTTON_DOWN_GPIO_Port GPIOC -#define I2C_SDA_Pin GPIO_PIN_10 -#define I2C_SDA_GPIO_Port GPIOA -#define RFID_CARRIER_Pin GPIO_PIN_15 -#define RFID_CARRIER_GPIO_Port GPIOA -#define SD_CD_Pin GPIO_PIN_10 -#define SD_CD_GPIO_Port GPIOC -#define DISPLAY_CS_Pin GPIO_PIN_11 -#define DISPLAY_CS_GPIO_Port GPIOC -#define SD_CS_Pin GPIO_PIN_12 -#define SD_CS_GPIO_Port GPIOC -#define CC1101_CS_Pin GPIO_PIN_0 -#define CC1101_CS_GPIO_Port GPIOD -#define SPI_D_SCK_Pin GPIO_PIN_1 -#define SPI_D_SCK_GPIO_Port GPIOD -#define PB3_Pin GPIO_PIN_3 -#define PB3_GPIO_Port GPIOB -#define SPI_R_MISO_Pin GPIO_PIN_4 -#define SPI_R_MISO_GPIO_Port GPIOB -#define SPI_R_MOSI_Pin GPIO_PIN_5 -#define SPI_R_MOSI_GPIO_Port GPIOB -/* USER CODE BEGIN Private defines */ - -/* USER CODE END Private defines */ - -#ifdef __cplusplus -} -#endif - -#endif /* __MAIN_H */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/firmware/targets/f7/cube/Inc/pka.h b/firmware/targets/f7/cube/Inc/pka.h deleted file mode 100644 index 712a14877f4..00000000000 --- a/firmware/targets/f7/cube/Inc/pka.h +++ /dev/null @@ -1,52 +0,0 @@ -/** - ****************************************************************************** - * @file pka.h - * @brief This file contains all the function prototypes for - * the pka.c file - ****************************************************************************** - * @attention - * - *

© Copyright (c) 2021 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __PKA_H__ -#define __PKA_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "main.h" - -/* USER CODE BEGIN Includes */ - -/* USER CODE END Includes */ - -extern PKA_HandleTypeDef hpka; - -/* USER CODE BEGIN Private defines */ - -/* USER CODE END Private defines */ - -void MX_PKA_Init(void); - -/* USER CODE BEGIN Prototypes */ - -/* USER CODE END Prototypes */ - -#ifdef __cplusplus -} -#endif - -#endif /* __PKA_H__ */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/firmware/targets/f7/cube/Inc/rf.h b/firmware/targets/f7/cube/Inc/rf.h deleted file mode 100644 index 8ccea6b5601..00000000000 --- a/firmware/targets/f7/cube/Inc/rf.h +++ /dev/null @@ -1,50 +0,0 @@ -/** - ****************************************************************************** - * @file rf.h - * @brief This file contains all the function prototypes for - * the rf.c file - ****************************************************************************** - * @attention - * - *

© Copyright (c) 2021 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __RF_H__ -#define __RF_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "main.h" - -/* USER CODE BEGIN Includes */ - -/* USER CODE END Includes */ - -/* USER CODE BEGIN Private defines */ - -/* USER CODE END Private defines */ - -void MX_RF_Init(void); - -/* USER CODE BEGIN Prototypes */ - -/* USER CODE END Prototypes */ - -#ifdef __cplusplus -} -#endif - -#endif /* __RF_H__ */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/firmware/targets/f7/cube/Inc/rng.h b/firmware/targets/f7/cube/Inc/rng.h deleted file mode 100644 index 82b6139617c..00000000000 --- a/firmware/targets/f7/cube/Inc/rng.h +++ /dev/null @@ -1,52 +0,0 @@ -/** - ****************************************************************************** - * @file rng.h - * @brief This file contains all the function prototypes for - * the rng.c file - ****************************************************************************** - * @attention - * - *

© Copyright (c) 2021 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __RNG_H__ -#define __RNG_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "main.h" - -/* USER CODE BEGIN Includes */ - -/* USER CODE END Includes */ - -extern RNG_HandleTypeDef hrng; - -/* USER CODE BEGIN Private defines */ - -/* USER CODE END Private defines */ - -void MX_RNG_Init(void); - -/* USER CODE BEGIN Prototypes */ - -/* USER CODE END Prototypes */ - -#ifdef __cplusplus -} -#endif - -#endif /* __RNG_H__ */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/firmware/targets/f7/cube/Inc/rtc.h b/firmware/targets/f7/cube/Inc/rtc.h deleted file mode 100644 index 6dd24df40e1..00000000000 --- a/firmware/targets/f7/cube/Inc/rtc.h +++ /dev/null @@ -1,52 +0,0 @@ -/** - ****************************************************************************** - * @file rtc.h - * @brief This file contains all the function prototypes for - * the rtc.c file - ****************************************************************************** - * @attention - * - *

© Copyright (c) 2021 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __RTC_H__ -#define __RTC_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "main.h" - -/* USER CODE BEGIN Includes */ - -/* USER CODE END Includes */ - -extern RTC_HandleTypeDef hrtc; - -/* USER CODE BEGIN Private defines */ - -/* USER CODE END Private defines */ - -void MX_RTC_Init(void); - -/* USER CODE BEGIN Prototypes */ - -/* USER CODE END Prototypes */ - -#ifdef __cplusplus -} -#endif - -#endif /* __RTC_H__ */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/firmware/targets/f7/cube/Inc/spi.h b/firmware/targets/f7/cube/Inc/spi.h deleted file mode 100644 index 8647d5e77ca..00000000000 --- a/firmware/targets/f7/cube/Inc/spi.h +++ /dev/null @@ -1,54 +0,0 @@ -/** - ****************************************************************************** - * @file spi.h - * @brief This file contains all the function prototypes for - * the spi.c file - ****************************************************************************** - * @attention - * - *

© Copyright (c) 2021 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __SPI_H__ -#define __SPI_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "main.h" - -/* USER CODE BEGIN Includes */ - -/* USER CODE END Includes */ - -extern SPI_HandleTypeDef hspi1; -extern SPI_HandleTypeDef hspi2; - -/* USER CODE BEGIN Private defines */ - -/* USER CODE END Private defines */ - -void MX_SPI1_Init(void); -void MX_SPI2_Init(void); - -/* USER CODE BEGIN Prototypes */ - -/* USER CODE END Prototypes */ - -#ifdef __cplusplus -} -#endif - -#endif /* __SPI_H__ */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/firmware/targets/f7/cube/Inc/stm32_assert.h b/firmware/targets/f7/cube/Inc/stm32_assert.h deleted file mode 100644 index b9dad5deeba..00000000000 --- a/firmware/targets/f7/cube/Inc/stm32_assert.h +++ /dev/null @@ -1,53 +0,0 @@ -/** - ****************************************************************************** - * @file stm32_assert.h - * @brief STM32 assert file. - ****************************************************************************** - * @attention - * - *

© Copyright (c) 2019 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under BSD 3-Clause license, - * the "License"; You may not use this file except in compliance with the - * License. You may obtain a copy of the License at: - * opensource.org/licenses/BSD-3-Clause - * - ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __STM32_ASSERT_H -#define __STM32_ASSERT_H - -#ifdef __cplusplus -extern "C" { -#endif - -/* Exported types ------------------------------------------------------------*/ -/* Exported constants --------------------------------------------------------*/ -/* Includes ------------------------------------------------------------------*/ -/* Exported macro ------------------------------------------------------------*/ -#ifdef USE_FULL_ASSERT -/** - * @brief The assert_param macro is used for function's parameters check. - * @param expr: If expr is false, it calls assert_failed function - * which reports the name of the source file and the source - * line number of the call that failed. - * If expr is true, it returns no value. - * @retval None - */ -#define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t*)__FILE__, __LINE__)) -/* Exported functions ------------------------------------------------------- */ -void assert_failed(uint8_t* file, uint32_t line); -#else -#define assert_param(expr) ((void)0U) -#endif /* USE_FULL_ASSERT */ - -#ifdef __cplusplus -} -#endif - -#endif /* __STM32_ASSERT_H */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/firmware/targets/f7/cube/Inc/stm32wbxx_hal_conf.h b/firmware/targets/f7/cube/Inc/stm32wbxx_hal_conf.h deleted file mode 100644 index e151d81b54d..00000000000 --- a/firmware/targets/f7/cube/Inc/stm32wbxx_hal_conf.h +++ /dev/null @@ -1,354 +0,0 @@ -/** - ****************************************************************************** - * @file stm32wbxx_hal_conf.h - * @author MCD Application Team - * @brief HAL configuration file. - ****************************************************************************** - * @attention - * - *

© Copyright (c) 2019 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under BSD 3-Clause license, - * the "License"; You may not use this file except in compliance with the - * License. You may obtain a copy of the License at: - * opensource.org/licenses/BSD-3-Clause - * - ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __STM32WBxx_HAL_CONF_H -#define __STM32WBxx_HAL_CONF_H - -#ifdef __cplusplus -extern "C" { -#endif - -/* Exported types ------------------------------------------------------------*/ -/* Exported constants --------------------------------------------------------*/ - -/* ########################## Module Selection ############################## */ -/** - * @brief This is the list of modules to be used in the HAL driver - */ -#define HAL_MODULE_ENABLED -#define HAL_ADC_MODULE_ENABLED -#define HAL_CRYP_MODULE_ENABLED -#define HAL_COMP_MODULE_ENABLED -#define HAL_CRC_MODULE_ENABLED -#define HAL_HSEM_MODULE_ENABLED -/*#define HAL_I2C_MODULE_ENABLED */ -/*#define HAL_IPCC_MODULE_ENABLED */ -/*#define HAL_IRDA_MODULE_ENABLED */ -/*#define HAL_IWDG_MODULE_ENABLED */ -/*#define HAL_LCD_MODULE_ENABLED */ -/*#define HAL_LPTIM_MODULE_ENABLED */ -#define HAL_PCD_MODULE_ENABLED -#define HAL_PKA_MODULE_ENABLED -/*#define HAL_QSPI_MODULE_ENABLED */ -#define HAL_RNG_MODULE_ENABLED -#define HAL_RTC_MODULE_ENABLED -/*#define HAL_SAI_MODULE_ENABLED */ -/*#define HAL_SMBUS_MODULE_ENABLED */ -/*#define HAL_SMARTCARD_MODULE_ENABLED */ -#define HAL_SPI_MODULE_ENABLED -#define HAL_TIM_MODULE_ENABLED -/*#define HAL_TSC_MODULE_ENABLED */ -/*#define HAL_UART_MODULE_ENABLED */ -/*#define HAL_USART_MODULE_ENABLED */ -/*#define HAL_WWDG_MODULE_ENABLED */ -#define HAL_EXTI_MODULE_ENABLED -#define HAL_CORTEX_MODULE_ENABLED -#define HAL_DMA_MODULE_ENABLED -#define HAL_FLASH_MODULE_ENABLED -#define HAL_GPIO_MODULE_ENABLED -#define HAL_PWR_MODULE_ENABLED -#define HAL_RCC_MODULE_ENABLED - -#define USE_HAL_ADC_REGISTER_CALLBACKS 0u -#define USE_HAL_COMP_REGISTER_CALLBACKS 0u -#define USE_HAL_CRYP_REGISTER_CALLBACKS 0u -#define USE_HAL_I2C_REGISTER_CALLBACKS 0u -#define USE_HAL_IRDA_REGISTER_CALLBACKS 0u -#define USE_HAL_LPTIM_REGISTER_CALLBACKS 0u -#define USE_HAL_PCD_REGISTER_CALLBACKS 0u -#define USE_HAL_PKA_REGISTER_CALLBACKS 0u -#define USE_HAL_QSPI_REGISTER_CALLBACKS 0u -#define USE_HAL_RNG_REGISTER_CALLBACKS 0u -#define USE_HAL_RTC_REGISTER_CALLBACKS 0u -#define USE_HAL_SAI_REGISTER_CALLBACKS 0u -#define USE_HAL_SMARTCARD_REGISTER_CALLBACKS 0u -#define USE_HAL_SMBUS_REGISTER_CALLBACKS 0u -#define USE_HAL_SPI_REGISTER_CALLBACKS 0u -#define USE_HAL_TIM_REGISTER_CALLBACKS 0u -#define USE_HAL_TSC_REGISTER_CALLBACKS 0u -#define USE_HAL_UART_REGISTER_CALLBACKS 0u -#define USE_HAL_USART_REGISTER_CALLBACKS 0u -#define USE_HAL_WWDG_REGISTER_CALLBACKS 0u - -/* ########################## Oscillator Values adaptation ####################*/ -/** - * @brief Adjust the value of External High Speed oscillator (HSE) used in your application. - * This value is used by the RCC HAL module to compute the system frequency - * (when HSE is used as system clock source, directly or through the PLL). - */ -#if !defined(HSE_VALUE) -#define HSE_VALUE 32000000U /*!< Value of the External oscillator in Hz */ -#endif /* HSE_VALUE */ - -#if !defined(HSE_STARTUP_TIMEOUT) -#define HSE_STARTUP_TIMEOUT ((uint32_t)100) /*!< Time out for HSE start up, in ms */ -#endif /* HSE_STARTUP_TIMEOUT */ - -/** - * @brief Internal Multiple Speed oscillator (MSI) default value. - * This value is the default MSI range value after Reset. - */ -#if !defined(MSI_VALUE) -#define MSI_VALUE ((uint32_t)4000000) /*!< Value of the Internal oscillator in Hz*/ -#endif /* MSI_VALUE */ - -/** - * @brief Internal High Speed oscillator (HSI) value. - * This value is used by the RCC HAL module to compute the system frequency - * (when HSI is used as system clock source, directly or through the PLL). - */ -#if !defined(HSI_VALUE) -#define HSI_VALUE 16000000U /*!< Value of the Internal oscillator in Hz*/ -#endif /* HSI_VALUE */ - -/** - * @brief Internal Low Speed oscillator (LSI1) value. - */ -#if !defined(LSI1_VALUE) -#define LSI1_VALUE ((uint32_t)32000) /*!< LSI1 Typical Value in Hz*/ -#endif /* LSI1_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz - The real value may vary depending on the variations - in voltage and temperature.*/ -/** - * @brief Internal Low Speed oscillator (LSI2) value. - */ -#if !defined(LSI2_VALUE) -#define LSI2_VALUE ((uint32_t)32000) /*!< LSI2 Typical Value in Hz*/ -#endif /* LSI2_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz - The real value may vary depending on the variations - in voltage and temperature.*/ - -/** - * @brief External Low Speed oscillator (LSE) value. - * This value is used by the UART, RTC HAL module to compute the system frequency - */ -#if !defined(LSE_VALUE) -#define LSE_VALUE 32768U /*!< Value of the External oscillator in Hz*/ -#endif /* LSE_VALUE */ - -/** - * @brief Internal Multiple Speed oscillator (HSI48) default value. - * This value is the default HSI48 range value after Reset. - */ -#if !defined(HSI48_VALUE) -#define HSI48_VALUE ((uint32_t)48000000) /*!< Value of the Internal oscillator in Hz*/ -#endif /* HSI48_VALUE */ - -#if !defined(LSE_STARTUP_TIMEOUT) -#define LSE_STARTUP_TIMEOUT 1000U /*!< Time out for LSE start up, in ms */ -#endif /* HSE_STARTUP_TIMEOUT */ - -/** - * @brief External clock source for SAI1 peripheral - * This value is used by the RCC HAL module to compute the SAI1 & SAI2 clock source - * frequency. - */ -#if !defined(EXTERNAL_SAI1_CLOCK_VALUE) -#define EXTERNAL_SAI1_CLOCK_VALUE \ - ((uint32_t)2097000) /*!< Value of the SAI1 External clock source in Hz*/ -#endif /* EXTERNAL_SAI1_CLOCK_VALUE */ - -/* Tip: To avoid modifying this file each time you need to use different HSE, - === you can define the HSE value in your toolchain compiler preprocessor. */ - -/* ########################### System Configuration ######################### */ -/** - * @brief This is the HAL system configuration section - */ - -#define VDD_VALUE 3300U /*!< Value of VDD in mv */ -#define TICK_INT_PRIORITY 15U /*!< tick interrupt priority */ -#define USE_RTOS 0U -#define PREFETCH_ENABLE 1U -#define INSTRUCTION_CACHE_ENABLE 1U -#define DATA_CACHE_ENABLE 1U - -/* ########################## Assert Selection ############################## */ -/** - * @brief Uncomment the line below to expanse the "assert_param" macro in the - * HAL drivers code - */ -/* #define USE_FULL_ASSERT 1U */ - -/* ################## SPI peripheral configuration ########################## */ - -/* CRC FEATURE: Use to activate CRC feature inside HAL SPI Driver - * Activated: CRC code is present inside driver - * Deactivated: CRC code cleaned from driver - */ - -#define USE_SPI_CRC 0U - -/* Includes ------------------------------------------------------------------*/ -/** - * @brief Include module's header file - */ -#ifdef HAL_DMA_MODULE_ENABLED -#include "stm32wbxx_hal_dma.h" -#endif /* HAL_DMA_MODULE_ENABLED */ - -#ifdef HAL_ADC_MODULE_ENABLED -#include "stm32wbxx_hal_adc.h" -#endif /* HAL_ADC_MODULE_ENABLED */ - -#ifdef HAL_COMP_MODULE_ENABLED -#include "stm32wbxx_hal_comp.h" -#endif /* HAL_COMP_MODULE_ENABLED */ - -#ifdef HAL_CORTEX_MODULE_ENABLED -#include "stm32wbxx_hal_cortex.h" -#endif /* HAL_CORTEX_MODULE_ENABLED */ - -#ifdef HAL_CRC_MODULE_ENABLED -#include "stm32wbxx_hal_crc.h" -#endif /* HAL_CRC_MODULE_ENABLED */ - -#ifdef HAL_CRYP_MODULE_ENABLED -#include "stm32wbxx_hal_cryp.h" -#endif /* HAL_CRYP_MODULE_ENABLED */ - -#ifdef HAL_EXTI_MODULE_ENABLED -#include "stm32wbxx_hal_exti.h" -#endif /* HAL_EXTI_MODULE_ENABLED */ - -#ifdef HAL_FLASH_MODULE_ENABLED -#include "stm32wbxx_hal_flash.h" -#endif /* HAL_FLASH_MODULE_ENABLED */ - -#ifdef HAL_GPIO_MODULE_ENABLED -#include "stm32wbxx_hal_gpio.h" -#endif /* HAL_GPIO_MODULE_ENABLED */ - -#ifdef HAL_HSEM_MODULE_ENABLED -#include "stm32wbxx_hal_hsem.h" -#endif /* HAL_HSEM_MODULE_ENABLED */ - -#ifdef HAL_I2C_MODULE_ENABLED -#include "stm32wbxx_hal_i2c.h" -#endif /* HAL_I2C_MODULE_ENABLED */ - -#ifdef HAL_IPCC_MODULE_ENABLED -#include "stm32wbxx_hal_ipcc.h" -#endif /* HAL_IPCC_MODULE_ENABLED */ - -#ifdef HAL_IRDA_MODULE_ENABLED -#include "stm32wbxx_hal_irda.h" -#endif /* HAL_IRDA_MODULE_ENABLED */ - -#ifdef HAL_IWDG_MODULE_ENABLED -#include "stm32wbxx_hal_iwdg.h" -#endif /* HAL_IWDG_MODULE_ENABLED */ - -#ifdef HAL_LCD_MODULE_ENABLED -#include "stm32wbxx_hal_lcd.h" -#endif /* HAL_LCD_MODULE_ENABLED */ - -#ifdef HAL_LPTIM_MODULE_ENABLED -#include "stm32wbxx_hal_lptim.h" -#endif /* HAL_LPTIM_MODULE_ENABLED */ - -#ifdef HAL_PCD_MODULE_ENABLED -#include "stm32wbxx_hal_pcd.h" -#endif /* HAL_PCD_MODULE_ENABLED */ - -#ifdef HAL_PKA_MODULE_ENABLED -#include "stm32wbxx_hal_pka.h" -#endif /* HAL_PKA_MODULE_ENABLED */ - -#ifdef HAL_PWR_MODULE_ENABLED -#include "stm32wbxx_hal_pwr.h" -#endif /* HAL_PWR_MODULE_ENABLED */ - -#ifdef HAL_QSPI_MODULE_ENABLED -#include "stm32wbxx_hal_qspi.h" -#endif /* HAL_QSPI_MODULE_ENABLED */ - -#ifdef HAL_RCC_MODULE_ENABLED -#include "stm32wbxx_hal_rcc.h" -#endif /* HAL_RCC_MODULE_ENABLED */ - -#ifdef HAL_RNG_MODULE_ENABLED -#include "stm32wbxx_hal_rng.h" -#endif /* HAL_RNG_MODULE_ENABLED */ - -#ifdef HAL_RTC_MODULE_ENABLED -#include "stm32wbxx_hal_rtc.h" -#endif /* HAL_RTC_MODULE_ENABLED */ - -#ifdef HAL_SAI_MODULE_ENABLED -#include "stm32wbxx_hal_sai.h" -#endif /* HAL_SAI_MODULE_ENABLED */ - -#ifdef HAL_SMARTCARD_MODULE_ENABLED -#include "stm32wbxx_hal_smartcard.h" -#endif /* HAL_SMARTCARD_MODULE_ENABLED */ - -#ifdef HAL_SMBUS_MODULE_ENABLED -#include "stm32wbxx_hal_smbus.h" -#endif /* HAL_SMBUS_MODULE_ENABLED */ - -#ifdef HAL_SPI_MODULE_ENABLED -#include "stm32wbxx_hal_spi.h" -#endif /* HAL_SPI_MODULE_ENABLED */ - -#ifdef HAL_TIM_MODULE_ENABLED -#include "stm32wbxx_hal_tim.h" -#endif /* HAL_TIM_MODULE_ENABLED */ - -#ifdef HAL_TSC_MODULE_ENABLED -#include "stm32wbxx_hal_tsc.h" -#endif /* HAL_TSC_MODULE_ENABLED */ - -#ifdef HAL_UART_MODULE_ENABLED -#include "stm32wbxx_hal_uart.h" -#endif /* HAL_UART_MODULE_ENABLED */ - -#ifdef HAL_USART_MODULE_ENABLED -#include "stm32wbxx_hal_usart.h" -#endif /* HAL_USART_MODULE_ENABLED */ - -#ifdef HAL_WWDG_MODULE_ENABLED -#include "stm32wbxx_hal_wwdg.h" -#endif /* HAL_WWDG_MODULE_ENABLED */ - -/* Exported macro ------------------------------------------------------------*/ -#ifdef USE_FULL_ASSERT -/** - * @brief The assert_param macro is used for function's parameters check. - * @param expr If expr is false, it calls assert_failed function - * which reports the name of the source file and the source - * line number of the call that failed. - * If expr is true, it returns no value. - * @retval None - */ -#define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t*)__FILE__, __LINE__)) -/* Exported functions ------------------------------------------------------- */ -void assert_failed(uint8_t* file, uint32_t line); -#else -#define assert_param(expr) ((void)0U) -#endif /* USE_FULL_ASSERT */ - -#ifdef __cplusplus -} -#endif - -#endif /* __STM32WBxx_HAL_CONF_H */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/firmware/targets/f7/cube/Inc/stm32wbxx_it.h b/firmware/targets/f7/cube/Inc/stm32wbxx_it.h deleted file mode 100644 index 095a83ecdf4..00000000000 --- a/firmware/targets/f7/cube/Inc/stm32wbxx_it.h +++ /dev/null @@ -1,77 +0,0 @@ -/* USER CODE BEGIN Header */ -/** - ****************************************************************************** - * @file stm32wbxx_it.h - * @brief This file contains the headers of the interrupt handlers. - ****************************************************************************** - * @attention - * - *

© Copyright (c) 2021 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ -/* USER CODE END Header */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __STM32WBxx_IT_H -#define __STM32WBxx_IT_H - -#ifdef __cplusplus -extern "C" { -#endif - -/* Private includes ----------------------------------------------------------*/ -/* USER CODE BEGIN Includes */ - -/* USER CODE END Includes */ - -/* Exported types ------------------------------------------------------------*/ -/* USER CODE BEGIN ET */ - -/* USER CODE END ET */ - -/* Exported constants --------------------------------------------------------*/ -/* USER CODE BEGIN EC */ - -/* USER CODE END EC */ - -/* Exported macro ------------------------------------------------------------*/ -/* USER CODE BEGIN EM */ - -/* USER CODE END EM */ - -/* Exported functions prototypes ---------------------------------------------*/ -void NMI_Handler(void); -void HardFault_Handler(void); -void MemManage_Handler(void); -void BusFault_Handler(void); -void UsageFault_Handler(void); -void DebugMon_Handler(void); -void SysTick_Handler(void); -void TAMP_STAMP_LSECSS_IRQHandler(void); -void RCC_IRQHandler(void); -void EXTI3_IRQHandler(void); -void ADC1_IRQHandler(void); -void USB_LP_IRQHandler(void); -void COMP_IRQHandler(void); -void TIM1_TRG_COM_TIM17_IRQHandler(void); -void TIM2_IRQHandler(void); -void EXTI15_10_IRQHandler(void); -void HSEM_IRQHandler(void); -/* USER CODE BEGIN EFP */ - -/* USER CODE END EFP */ - -#ifdef __cplusplus -} -#endif - -#endif /* __STM32WBxx_IT_H */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/firmware/targets/f7/cube/Inc/tim.h b/firmware/targets/f7/cube/Inc/tim.h deleted file mode 100644 index e0f65f106ad..00000000000 --- a/firmware/targets/f7/cube/Inc/tim.h +++ /dev/null @@ -1,58 +0,0 @@ -/** - ****************************************************************************** - * @file tim.h - * @brief This file contains all the function prototypes for - * the tim.c file - ****************************************************************************** - * @attention - * - *

© Copyright (c) 2021 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __TIM_H__ -#define __TIM_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "main.h" - -/* USER CODE BEGIN Includes */ - -/* USER CODE END Includes */ - -extern TIM_HandleTypeDef htim1; -extern TIM_HandleTypeDef htim2; -extern TIM_HandleTypeDef htim16; - -/* USER CODE BEGIN Private defines */ - -/* USER CODE END Private defines */ - -void MX_TIM1_Init(void); -void MX_TIM2_Init(void); -void MX_TIM16_Init(void); - -void HAL_TIM_MspPostInit(TIM_HandleTypeDef* htim); - -/* USER CODE BEGIN Prototypes */ - -/* USER CODE END Prototypes */ - -#ifdef __cplusplus -} -#endif - -#endif /* __TIM_H__ */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/firmware/targets/f7/cube/Inc/usart.h b/firmware/targets/f7/cube/Inc/usart.h deleted file mode 100644 index 81412610ef2..00000000000 --- a/firmware/targets/f7/cube/Inc/usart.h +++ /dev/null @@ -1,50 +0,0 @@ -/** - ****************************************************************************** - * @file usart.h - * @brief This file contains all the function prototypes for - * the usart.c file - ****************************************************************************** - * @attention - * - *

© Copyright (c) 2021 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __USART_H__ -#define __USART_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "main.h" - -/* USER CODE BEGIN Includes */ - -/* USER CODE END Includes */ - -/* USER CODE BEGIN Private defines */ - -/* USER CODE END Private defines */ - -void MX_USART1_UART_Init(void); - -/* USER CODE BEGIN Prototypes */ - -/* USER CODE END Prototypes */ - -#ifdef __cplusplus -} -#endif - -#endif /* __USART_H__ */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/firmware/targets/f7/cube/Inc/usb_device.h b/firmware/targets/f7/cube/Inc/usb_device.h deleted file mode 100644 index b9a4bf4393f..00000000000 --- a/firmware/targets/f7/cube/Inc/usb_device.h +++ /dev/null @@ -1,105 +0,0 @@ -/* USER CODE BEGIN Header */ -/** - ****************************************************************************** - * @file : usb_device.h - * @version : v3.0_Cube - * @brief : Header for usb_device.c file. - ****************************************************************************** - * @attention - * - *

© Copyright (c) 2021 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ -/* USER CODE END Header */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __USB_DEVICE__H__ -#define __USB_DEVICE__H__ - -#ifdef __cplusplus -extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "stm32wbxx.h" -#include "stm32wbxx_hal.h" -#include "usbd_def.h" - -/* USER CODE BEGIN INCLUDE */ - -/* USER CODE END INCLUDE */ - -/** @addtogroup USBD_OTG_DRIVER - * @{ - */ - -/** @defgroup USBD_DEVICE USBD_DEVICE - * @brief Device file for Usb otg low level driver. - * @{ - */ - -/** @defgroup USBD_DEVICE_Exported_Variables USBD_DEVICE_Exported_Variables - * @brief Public variables. - * @{ - */ - -/* Private variables ---------------------------------------------------------*/ -/* USER CODE BEGIN PV */ - -/* USER CODE END PV */ - -/* Private function prototypes -----------------------------------------------*/ -/* USER CODE BEGIN PFP */ - -/* USER CODE END PFP */ - -/* - * -- Insert your variables declaration here -- - */ -/* USER CODE BEGIN VARIABLES */ - -/* USER CODE END VARIABLES */ -/** - * @} - */ - -/** @defgroup USBD_DEVICE_Exported_FunctionsPrototype USBD_DEVICE_Exported_FunctionsPrototype - * @brief Declaration of public functions for Usb device. - * @{ - */ - -/** USB Device initialization function. */ -void MX_USB_Device_Init(void); - -/* - * -- Insert functions declaration here -- - */ -/* USER CODE BEGIN FD */ - -/* USER CODE END FD */ -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -#ifdef __cplusplus -} -#endif - -#endif /* __USB_DEVICE__H__ */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/firmware/targets/f7/cube/Inc/usbd_cdc_if.h b/firmware/targets/f7/cube/Inc/usbd_cdc_if.h deleted file mode 100644 index 7ddbe67aa5d..00000000000 --- a/firmware/targets/f7/cube/Inc/usbd_cdc_if.h +++ /dev/null @@ -1,133 +0,0 @@ -/* USER CODE BEGIN Header */ -/** - ****************************************************************************** - * @file : usbd_cdc_if.h - * @version : v3.0_Cube - * @brief : Header for usbd_cdc_if.c file. - ****************************************************************************** - * @attention - * - *

© Copyright (c) 2021 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ -/* USER CODE END Header */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __USBD_CDC_IF_H__ -#define __USBD_CDC_IF_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "usbd_cdc.h" - -/* USER CODE BEGIN INCLUDE */ - -/* USER CODE END INCLUDE */ - -/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY - * @brief For Usb device. - * @{ - */ - -/** @defgroup USBD_CDC_IF USBD_CDC_IF - * @brief Usb VCP device module - * @{ - */ - -/** @defgroup USBD_CDC_IF_Exported_Defines USBD_CDC_IF_Exported_Defines - * @brief Defines. - * @{ - */ -/* Define size for the receive and transmit buffer over CDC */ -#define APP_RX_DATA_SIZE 512 -#define APP_TX_DATA_SIZE 512 -/* USER CODE BEGIN EXPORTED_DEFINES */ - -/* USER CODE END EXPORTED_DEFINES */ - -/** - * @} - */ - -/** @defgroup USBD_CDC_IF_Exported_Types USBD_CDC_IF_Exported_Types - * @brief Types. - * @{ - */ - -/* USER CODE BEGIN EXPORTED_TYPES */ - -/* USER CODE END EXPORTED_TYPES */ - -/** - * @} - */ - -/** @defgroup USBD_CDC_IF_Exported_Macros USBD_CDC_IF_Exported_Macros - * @brief Aliases. - * @{ - */ - -/* USER CODE BEGIN EXPORTED_MACRO */ - -/* USER CODE END EXPORTED_MACRO */ - -/** - * @} - */ - -/** @defgroup USBD_CDC_IF_Exported_Variables USBD_CDC_IF_Exported_Variables - * @brief Public variables. - * @{ - */ - -/** CDC Interface callback. */ -extern USBD_CDC_ItfTypeDef USBD_Interface_fops_FS; - -/* USER CODE BEGIN EXPORTED_VARIABLES */ - -/* USER CODE END EXPORTED_VARIABLES */ - -/** - * @} - */ - -/** @defgroup USBD_CDC_IF_Exported_FunctionsPrototype USBD_CDC_IF_Exported_FunctionsPrototype - * @brief Public functions declaration. - * @{ - */ - -uint8_t CDC_Transmit_FS(uint8_t* Buf, uint16_t Len); - -/* USER CODE BEGIN EXPORTED_FUNCTIONS */ - -/* USER CODE END EXPORTED_FUNCTIONS */ - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -#ifdef __cplusplus -} -#endif - -#endif /* __USBD_CDC_IF_H__ */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/firmware/targets/f7/cube/Inc/usbd_conf.h b/firmware/targets/f7/cube/Inc/usbd_conf.h deleted file mode 100644 index 98306d6a2dc..00000000000 --- a/firmware/targets/f7/cube/Inc/usbd_conf.h +++ /dev/null @@ -1,179 +0,0 @@ -/* USER CODE BEGIN Header */ -/** - ****************************************************************************** - * @file : usbd_conf.h - * @version : v3.0_Cube - * @brief : Header for usbd_conf.c file. - ****************************************************************************** - * @attention - * - *

© Copyright (c) 2021 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ -/* USER CODE END Header */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __USBD_CONF__H__ -#define __USBD_CONF__H__ - -#ifdef __cplusplus -extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include -#include -#include -#include "stm32wbxx.h" -#include "stm32wbxx_hal.h" - -/* USER CODE BEGIN INCLUDE */ - -/* USER CODE END INCLUDE */ - -/** @addtogroup USBD_OTG_DRIVER - * @brief Driver for Usb device. - * @{ - */ - -/** @defgroup USBD_CONF USBD_CONF - * @brief Configuration file for Usb otg low level driver. - * @{ - */ - -/** @defgroup USBD_CONF_Exported_Variables USBD_CONF_Exported_Variables - * @brief Public variables. - * @{ - */ - -/* Private variables ---------------------------------------------------------*/ -/* USER CODE BEGIN PV */ -/* USER CODE END PV */ -/** - * @} - */ - -/** @defgroup USBD_CONF_Exported_Defines USBD_CONF_Exported_Defines - * @brief Defines for configuration of the Usb device. - * @{ - */ - -/*---------- -----------*/ -#define USBD_MAX_NUM_INTERFACES 1U -/*---------- -----------*/ -#define USBD_MAX_NUM_CONFIGURATION 1U -/*---------- -----------*/ -#define USBD_MAX_STR_DESC_SIZ 512U -/*---------- -----------*/ -#define USBD_DEBUG_LEVEL 0U -/*---------- -----------*/ -#define USBD_LPM_ENABLED 1U -/*---------- -----------*/ -#define USBD_SELF_POWERED 1U - -/****************************************/ -/* #define for FS and HS identification */ -#define DEVICE_FS 0 - -/** - * @} - */ - -/** @defgroup USBD_CONF_Exported_Macros USBD_CONF_Exported_Macros - * @brief Aliases. - * @{ - */ - -/* Memory management macros */ - -/** Alias for memory allocation. */ -#define USBD_malloc (void*)USBD_static_malloc - -/** Alias for memory release. */ -#define USBD_free USBD_static_free - -/** Alias for memory set. */ -#define USBD_memset memset - -/** Alias for memory copy. */ -#define USBD_memcpy memcpy - -/** Alias for delay. */ -#define USBD_Delay HAL_Delay -/* DEBUG macros */ - -#if(USBD_DEBUG_LEVEL > 0) -#define USBD_UsrLog(...) \ - printf(__VA_ARGS__); \ - printf("\n"); -#else -#define USBD_UsrLog(...) -#endif - -#if(USBD_DEBUG_LEVEL > 1) - -#define USBD_ErrLog(...) \ - printf("ERROR: "); \ - printf(__VA_ARGS__); \ - printf("\n"); -#else -#define USBD_ErrLog(...) -#endif - -#if(USBD_DEBUG_LEVEL > 2) -#define USBD_DbgLog(...) \ - printf("DEBUG : "); \ - printf(__VA_ARGS__); \ - printf("\n"); -#else -#define USBD_DbgLog(...) -#endif - -/** - * @} - */ - -/** @defgroup USBD_CONF_Exported_Types USBD_CONF_Exported_Types - * @brief Types. - * @{ - */ - -/** - * @} - */ - -/** @defgroup USBD_CONF_Exported_FunctionsPrototype USBD_CONF_Exported_FunctionsPrototype - * @brief Declaration of public functions for Usb device. - * @{ - */ - -/* Exported functions -------------------------------------------------------*/ -void* USBD_static_malloc(uint32_t size); -void USBD_static_free(void* p); - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -#ifdef __cplusplus -} -#endif - -#endif /* __USBD_CONF__H__ */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/firmware/targets/f7/cube/Inc/usbd_desc.h b/firmware/targets/f7/cube/Inc/usbd_desc.h deleted file mode 100644 index 67a70dc6fbe..00000000000 --- a/firmware/targets/f7/cube/Inc/usbd_desc.h +++ /dev/null @@ -1,145 +0,0 @@ -/* USER CODE BEGIN Header */ -/** - ****************************************************************************** - * @file : usbd_desc.c - * @version : v3.0_Cube - * @brief : Header for usbd_conf.c file. - ****************************************************************************** - * @attention - * - *

© Copyright (c) 2021 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ -/* USER CODE END Header */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __USBD_DESC__C__ -#define __USBD_DESC__C__ - -#ifdef __cplusplus -extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "usbd_def.h" - -/* USER CODE BEGIN INCLUDE */ - -/* USER CODE END INCLUDE */ - -/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY - * @{ - */ - -/** @defgroup USBD_DESC USBD_DESC - * @brief Usb device descriptors module. - * @{ - */ - -/** @defgroup USBD_DESC_Exported_Constants USBD_DESC_Exported_Constants - * @brief Constants. - * @{ - */ -#define DEVICE_ID1 (UID_BASE) -#define DEVICE_ID2 (UID_BASE + 0x4) -#define DEVICE_ID3 (UID_BASE + 0x8) - -#define USB_SIZ_STRING_SERIAL 0x1A - -/* USER CODE BEGIN EXPORTED_CONSTANTS */ - -/* USER CODE END EXPORTED_CONSTANTS */ - -/** - * @} - */ - -/** @defgroup USBD_DESC_Exported_Defines USBD_DESC_Exported_Defines - * @brief Defines. - * @{ - */ - -/* USER CODE BEGIN EXPORTED_DEFINES */ - -/* USER CODE END EXPORTED_DEFINES */ - -/** - * @} - */ - -/** @defgroup USBD_DESC_Exported_TypesDefinitions USBD_DESC_Exported_TypesDefinitions - * @brief Types. - * @{ - */ - -/* USER CODE BEGIN EXPORTED_TYPES */ - -/* USER CODE END EXPORTED_TYPES */ - -/** - * @} - */ - -/** @defgroup USBD_DESC_Exported_Macros USBD_DESC_Exported_Macros - * @brief Aliases. - * @{ - */ - -/* USER CODE BEGIN EXPORTED_MACRO */ - -/* USER CODE END EXPORTED_MACRO */ - -/** - * @} - */ - -/** @defgroup USBD_DESC_Exported_Variables USBD_DESC_Exported_Variables - * @brief Public variables. - * @{ - */ - -extern USBD_DescriptorsTypeDef CDC_Desc; - -/* USER CODE BEGIN EXPORTED_VARIABLES */ - -/* USER CODE END EXPORTED_VARIABLES */ - -/** - * @} - */ - -/** @defgroup USBD_DESC_Exported_FunctionsPrototype USBD_DESC_Exported_FunctionsPrototype - * @brief Public functions declaration. - * @{ - */ - -/* USER CODE BEGIN EXPORTED_FUNCTIONS */ - -/* USER CODE END EXPORTED_FUNCTIONS */ - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -#ifdef __cplusplus -} -#endif - -#endif /* __USBD_DESC__C__ */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/firmware/targets/f7/cube/Makefile b/firmware/targets/f7/cube/Makefile deleted file mode 100644 index 4f5ffc8b337..00000000000 --- a/firmware/targets/f7/cube/Makefile +++ /dev/null @@ -1,253 +0,0 @@ -########################################################################################################################## -# File automatically-generated by tool: [projectgenerator] version: [3.14.1] date: [Fri Sep 10 04:36:47 MSK 2021] -########################################################################################################################## - -# ------------------------------------------------ -# Generic Makefile (based on gcc) -# -# ChangeLog : -# 2017-02-10 - Several enhancements + project update mode -# 2015-07-22 - first version -# ------------------------------------------------ - -###################################### -# target -###################################### -TARGET = f7 - - -###################################### -# building variables -###################################### -# debug build? -DEBUG = 1 -# optimization -OPT = -Og - - -####################################### -# paths -####################################### -# Build path -BUILD_DIR = build - -###################################### -# source -###################################### -# C sources -C_SOURCES = \ -Src/main.c \ -Src/gpio.c \ -Src/app_freertos.c \ -Src/adc.c \ -Src/aes.c \ -Src/comp.c \ -Src/crc.c \ -Src/i2c.c \ -Src/pka.c \ -Src/rf.c \ -Src/rng.c \ -Src/rtc.c \ -Src/spi.c \ -Src/tim.c \ -Src/usart.c \ -Src/usb_device.c \ -Src/usbd_conf.c \ -Src/usbd_desc.c \ -Src/usbd_cdc_if.c \ -Src/stm32wbxx_it.c \ -Src/stm32wbxx_hal_msp.c \ -/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_ll_utils.c \ -/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_ll_exti.c \ -/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_pcd.c \ -/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_pcd_ex.c \ -/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_ll_usb.c \ -/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_rcc.c \ -/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_rcc_ex.c \ -/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_flash.c \ -/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_flash_ex.c \ -/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_gpio.c \ -/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_hsem.c \ -/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_dma.c \ -/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_dma_ex.c \ -/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_pwr.c \ -/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_pwr_ex.c \ -/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_cortex.c \ -/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal.c \ -/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_exti.c \ -/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_adc.c \ -/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_adc_ex.c \ -/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_ll_adc.c \ -/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_cryp.c \ -/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_cryp_ex.c \ -/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_comp.c \ -/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_crc.c \ -/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_crc_ex.c \ -/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_ll_i2c.c \ -/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_ll_gpio.c \ -/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_ll_dma.c \ -/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_pka.c \ -/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_rng.c \ -/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_rtc.c \ -/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_rtc_ex.c \ -/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_spi.c \ -/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_spi_ex.c \ -/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_tim.c \ -/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_tim_ex.c \ -/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_ll_usart.c \ -/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_ll_rcc.c \ -Src/system_stm32wbxx.c \ -/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Middlewares/Third_Party/FreeRTOS/Source/croutine.c \ -/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Middlewares/Third_Party/FreeRTOS/Source/event_groups.c \ -/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Middlewares/Third_Party/FreeRTOS/Source/list.c \ -/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Middlewares/Third_Party/FreeRTOS/Source/queue.c \ -/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Middlewares/Third_Party/FreeRTOS/Source/stream_buffer.c \ -/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Middlewares/Third_Party/FreeRTOS/Source/tasks.c \ -/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Middlewares/Third_Party/FreeRTOS/Source/timers.c \ -/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os2.c \ -/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Middlewares/Third_Party/FreeRTOS/Source/portable/MemMang/heap_4.c \ -/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F/port.c \ -/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_core.c \ -/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ctlreq.c \ -/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ioreq.c \ -/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc.c - -# ASM sources -ASM_SOURCES = \ -startup_stm32wb55xx_cm4.s - - -####################################### -# binaries -####################################### -PREFIX = arm-none-eabi- -# The gcc compiler bin path can be either defined in make command via GCC_PATH variable (> make GCC_PATH=xxx) -# either it can be added to the PATH environment variable. -ifdef GCC_PATH -CC = $(GCC_PATH)/$(PREFIX)gcc -AS = $(GCC_PATH)/$(PREFIX)gcc -x assembler-with-cpp -CP = $(GCC_PATH)/$(PREFIX)objcopy -SZ = $(GCC_PATH)/$(PREFIX)size -else -CC = $(PREFIX)gcc -AS = $(PREFIX)gcc -x assembler-with-cpp -CP = $(PREFIX)objcopy -SZ = $(PREFIX)size -endif -HEX = $(CP) -O ihex -BIN = $(CP) -O binary -S - -####################################### -# CFLAGS -####################################### -# cpu -CPU = -mcpu=cortex-m4 - -# fpu -FPU = -mfpu=fpv4-sp-d16 - -# float-abi -FLOAT-ABI = -mfloat-abi=hard - -# mcu -MCU = $(CPU) -mthumb $(FPU) $(FLOAT-ABI) - -# macros for gcc -# AS defines -AS_DEFS = - -# C defines -C_DEFS = \ --DUSE_FULL_LL_DRIVER \ --DUSE_HAL_DRIVER \ --DSTM32WB55xx - - -# AS includes -AS_INCLUDES = \ --IInc - -# C includes -C_INCLUDES = \ --IInc \ --I/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Inc \ --I/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Inc/Legacy \ --I/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Middlewares/Third_Party/FreeRTOS/Source/include \ --I/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2 \ --I/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F \ --I/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Middlewares/ST/STM32_USB_Device_Library/Core/Inc \ --I/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc \ --I/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/CMSIS/Device/ST/STM32WBxx/Include \ --I/Users/aku/Work/flipper/flipperzero-firmware/lib/STM32CubeWB/Drivers/CMSIS/Include - - -# compile gcc flags -ASFLAGS = $(MCU) $(AS_DEFS) $(AS_INCLUDES) $(OPT) -Wall -fdata-sections -ffunction-sections - -CFLAGS = $(MCU) $(C_DEFS) $(C_INCLUDES) $(OPT) -Wall -fdata-sections -ffunction-sections - -ifeq ($(DEBUG), 1) -CFLAGS += -g -gdwarf-2 -endif - - -# Generate dependency information -CFLAGS += -MMD -MP -MF"$(@:%.o=%.d)" - - -####################################### -# LDFLAGS -####################################### -# link script -LDSCRIPT = stm32wb55xx_flash_cm4.ld - -# libraries -LIBS = -lc -lm -lnosys -LIBDIR = -LDFLAGS = $(MCU) -specs=nano.specs -T$(LDSCRIPT) $(LIBDIR) $(LIBS) -Wl,-Map=$(BUILD_DIR)/$(TARGET).map,--cref -Wl,--gc-sections - -# default action: build all -all: $(BUILD_DIR)/$(TARGET).elf $(BUILD_DIR)/$(TARGET).hex $(BUILD_DIR)/$(TARGET).bin - - -####################################### -# build the application -####################################### -# list of objects -OBJECTS = $(addprefix $(BUILD_DIR)/,$(notdir $(C_SOURCES:.c=.o))) -vpath %.c $(sort $(dir $(C_SOURCES))) -# list of ASM program objects -OBJECTS += $(addprefix $(BUILD_DIR)/,$(notdir $(ASM_SOURCES:.s=.o))) -vpath %.s $(sort $(dir $(ASM_SOURCES))) - -$(BUILD_DIR)/%.o: %.c Makefile | $(BUILD_DIR) - $(CC) -c $(CFLAGS) -Wa,-a,-ad,-alms=$(BUILD_DIR)/$(notdir $(<:.c=.lst)) $< -o $@ - -$(BUILD_DIR)/%.o: %.s Makefile | $(BUILD_DIR) - $(AS) -c $(CFLAGS) $< -o $@ - -$(BUILD_DIR)/$(TARGET).elf: $(OBJECTS) Makefile - $(CC) $(OBJECTS) $(LDFLAGS) -o $@ - $(SZ) $@ - -$(BUILD_DIR)/%.hex: $(BUILD_DIR)/%.elf | $(BUILD_DIR) - $(HEX) $< $@ - -$(BUILD_DIR)/%.bin: $(BUILD_DIR)/%.elf | $(BUILD_DIR) - $(BIN) $< $@ - -$(BUILD_DIR): - mkdir $@ - -####################################### -# clean up -####################################### -clean: - -rm -fR $(BUILD_DIR) - -####################################### -# dependencies -####################################### --include $(wildcard $(BUILD_DIR)/*.d) - -# *** EOF *** \ No newline at end of file diff --git a/firmware/targets/f7/cube/Src/adc.c b/firmware/targets/f7/cube/Src/adc.c deleted file mode 100644 index d0c3d98e100..00000000000 --- a/firmware/targets/f7/cube/Src/adc.c +++ /dev/null @@ -1,128 +0,0 @@ -/** - ****************************************************************************** - * @file adc.c - * @brief This file provides code for the configuration - * of the ADC instances. - ****************************************************************************** - * @attention - * - *

© Copyright (c) 2021 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "adc.h" - -/* USER CODE BEGIN 0 */ - -/* USER CODE END 0 */ - -ADC_HandleTypeDef hadc1; - -/* ADC1 init function */ -void MX_ADC1_Init(void) { - /* USER CODE BEGIN ADC1_Init 0 */ - - /* USER CODE END ADC1_Init 0 */ - - ADC_ChannelConfTypeDef sConfig = {0}; - - /* USER CODE BEGIN ADC1_Init 1 */ - - /* USER CODE END ADC1_Init 1 */ - /** Common config - */ - hadc1.Instance = ADC1; - hadc1.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1; - hadc1.Init.Resolution = ADC_RESOLUTION_12B; - hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT; - hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE; - hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV; - hadc1.Init.LowPowerAutoWait = DISABLE; - hadc1.Init.ContinuousConvMode = DISABLE; - hadc1.Init.NbrOfConversion = 1; - hadc1.Init.DiscontinuousConvMode = DISABLE; - hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START; - hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE; - hadc1.Init.DMAContinuousRequests = DISABLE; - hadc1.Init.Overrun = ADC_OVR_DATA_PRESERVED; - hadc1.Init.OversamplingMode = DISABLE; - if(HAL_ADC_Init(&hadc1) != HAL_OK) { - Error_Handler(); - } - /** Configure Regular Channel - */ - sConfig.Channel = ADC_CHANNEL_14; - sConfig.Rank = ADC_REGULAR_RANK_1; - sConfig.SamplingTime = ADC_SAMPLETIME_2CYCLES_5; - sConfig.SingleDiff = ADC_SINGLE_ENDED; - sConfig.OffsetNumber = ADC_OFFSET_NONE; - sConfig.Offset = 0; - if(HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK) { - Error_Handler(); - } - /* USER CODE BEGIN ADC1_Init 2 */ - - /* USER CODE END ADC1_Init 2 */ -} - -void HAL_ADC_MspInit(ADC_HandleTypeDef* adcHandle) { - GPIO_InitTypeDef GPIO_InitStruct = {0}; - if(adcHandle->Instance == ADC1) { - /* USER CODE BEGIN ADC1_MspInit 0 */ - - /* USER CODE END ADC1_MspInit 0 */ - /* ADC1 clock enable */ - __HAL_RCC_ADC_CLK_ENABLE(); - - __HAL_RCC_GPIOC_CLK_ENABLE(); - /**ADC1 GPIO Configuration - PC5 ------> ADC1_IN14 - */ - GPIO_InitStruct.Pin = RFID_RF_IN_Pin; - GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; - GPIO_InitStruct.Pull = GPIO_NOPULL; - HAL_GPIO_Init(RFID_RF_IN_GPIO_Port, &GPIO_InitStruct); - - /* ADC1 interrupt Init */ - HAL_NVIC_SetPriority(ADC1_IRQn, 5, 0); - HAL_NVIC_EnableIRQ(ADC1_IRQn); - /* USER CODE BEGIN ADC1_MspInit 1 */ - - /* USER CODE END ADC1_MspInit 1 */ - } -} - -void HAL_ADC_MspDeInit(ADC_HandleTypeDef* adcHandle) { - if(adcHandle->Instance == ADC1) { - /* USER CODE BEGIN ADC1_MspDeInit 0 */ - - /* USER CODE END ADC1_MspDeInit 0 */ - /* Peripheral clock disable */ - __HAL_RCC_ADC_CLK_DISABLE(); - - /**ADC1 GPIO Configuration - PC5 ------> ADC1_IN14 - */ - HAL_GPIO_DeInit(RFID_RF_IN_GPIO_Port, RFID_RF_IN_Pin); - - /* ADC1 interrupt Deinit */ - HAL_NVIC_DisableIRQ(ADC1_IRQn); - /* USER CODE BEGIN ADC1_MspDeInit 1 */ - - /* USER CODE END ADC1_MspDeInit 1 */ - } -} - -/* USER CODE BEGIN 1 */ - -/* USER CODE END 1 */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/firmware/targets/f7/cube/Src/aes.c b/firmware/targets/f7/cube/Src/aes.c deleted file mode 100644 index ace8334184c..00000000000 --- a/firmware/targets/f7/cube/Src/aes.c +++ /dev/null @@ -1,129 +0,0 @@ -/** - ****************************************************************************** - * @file aes.c - * @brief This file provides code for the configuration - * of the AES instances. - ****************************************************************************** - * @attention - * - *

© Copyright (c) 2021 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "aes.h" - -/* USER CODE BEGIN 0 */ - -/* USER CODE END 0 */ - -CRYP_HandleTypeDef hcryp1; -__ALIGN_BEGIN static const uint32_t pKeyAES1[4] __ALIGN_END = - {0x00000000, 0x00000000, 0x00000000, 0x00000000}; -CRYP_HandleTypeDef hcryp2; -__ALIGN_BEGIN static const uint32_t pKeyAES2[4] __ALIGN_END = - {0x00000000, 0x00000000, 0x00000000, 0x00000000}; - -/* AES1 init function */ -void MX_AES1_Init(void) { - /* USER CODE BEGIN AES1_Init 0 */ - - /* USER CODE END AES1_Init 0 */ - - /* USER CODE BEGIN AES1_Init 1 */ - - /* USER CODE END AES1_Init 1 */ - hcryp1.Instance = AES1; - hcryp1.Init.DataType = CRYP_DATATYPE_32B; - hcryp1.Init.KeySize = CRYP_KEYSIZE_128B; - hcryp1.Init.pKey = (uint32_t*)pKeyAES1; - hcryp1.Init.Algorithm = CRYP_AES_ECB; - hcryp1.Init.DataWidthUnit = CRYP_DATAWIDTHUNIT_WORD; - hcryp1.Init.KeyIVConfigSkip = CRYP_KEYIVCONFIG_ALWAYS; - if(HAL_CRYP_Init(&hcryp1) != HAL_OK) { - Error_Handler(); - } - /* USER CODE BEGIN AES1_Init 2 */ - - /* USER CODE END AES1_Init 2 */ -} -/* AES2 init function */ -void MX_AES2_Init(void) { - /* USER CODE BEGIN AES2_Init 0 */ - - /* USER CODE END AES2_Init 0 */ - - /* USER CODE BEGIN AES2_Init 1 */ - - /* USER CODE END AES2_Init 1 */ - hcryp2.Instance = AES2; - hcryp2.Init.DataType = CRYP_DATATYPE_32B; - hcryp2.Init.KeySize = CRYP_KEYSIZE_128B; - hcryp2.Init.pKey = (uint32_t*)pKeyAES2; - hcryp2.Init.Algorithm = CRYP_AES_ECB; - hcryp2.Init.DataWidthUnit = CRYP_DATAWIDTHUNIT_WORD; - hcryp2.Init.KeyIVConfigSkip = CRYP_KEYIVCONFIG_ALWAYS; - if(HAL_CRYP_Init(&hcryp2) != HAL_OK) { - Error_Handler(); - } - /* USER CODE BEGIN AES2_Init 2 */ - - /* USER CODE END AES2_Init 2 */ -} - -void HAL_CRYP_MspInit(CRYP_HandleTypeDef* crypHandle) { - if(crypHandle->Instance == AES1) { - /* USER CODE BEGIN AES1_MspInit 0 */ - - /* USER CODE END AES1_MspInit 0 */ - /* AES1 clock enable */ - __HAL_RCC_AES1_CLK_ENABLE(); - /* USER CODE BEGIN AES1_MspInit 1 */ - - /* USER CODE END AES1_MspInit 1 */ - } else if(crypHandle->Instance == AES2) { - /* USER CODE BEGIN AES2_MspInit 0 */ - - /* USER CODE END AES2_MspInit 0 */ - /* AES2 clock enable */ - __HAL_RCC_AES2_CLK_ENABLE(); - /* USER CODE BEGIN AES2_MspInit 1 */ - - /* USER CODE END AES2_MspInit 1 */ - } -} - -void HAL_CRYP_MspDeInit(CRYP_HandleTypeDef* crypHandle) { - if(crypHandle->Instance == AES1) { - /* USER CODE BEGIN AES1_MspDeInit 0 */ - - /* USER CODE END AES1_MspDeInit 0 */ - /* Peripheral clock disable */ - __HAL_RCC_AES1_CLK_DISABLE(); - /* USER CODE BEGIN AES1_MspDeInit 1 */ - - /* USER CODE END AES1_MspDeInit 1 */ - } else if(crypHandle->Instance == AES2) { - /* USER CODE BEGIN AES2_MspDeInit 0 */ - - /* USER CODE END AES2_MspDeInit 0 */ - /* Peripheral clock disable */ - __HAL_RCC_AES2_CLK_DISABLE(); - /* USER CODE BEGIN AES2_MspDeInit 1 */ - - /* USER CODE END AES2_MspDeInit 1 */ - } -} - -/* USER CODE BEGIN 1 */ - -/* USER CODE END 1 */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/firmware/targets/f7/cube/Src/app_freertos.c b/firmware/targets/f7/cube/Src/app_freertos.c deleted file mode 100644 index fcb18ce655f..00000000000 --- a/firmware/targets/f7/cube/Src/app_freertos.c +++ /dev/null @@ -1,173 +0,0 @@ -/* USER CODE BEGIN Header */ -/** - ****************************************************************************** - * File Name : app_freertos.c - * Description : Code for freertos applications - ****************************************************************************** - * @attention - * - *

© Copyright (c) 2021 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ -/* USER CODE END Header */ - -/* Includes ------------------------------------------------------------------*/ -#include "FreeRTOS.h" -#include "task.h" -#include "main.h" -#include "cmsis_os.h" - -/* Private includes ----------------------------------------------------------*/ -/* USER CODE BEGIN Includes */ - -/* USER CODE END Includes */ - -/* Private typedef -----------------------------------------------------------*/ -/* USER CODE BEGIN PTD */ - -/* USER CODE END PTD */ - -/* Private define ------------------------------------------------------------*/ -/* USER CODE BEGIN PD */ - -/* USER CODE END PD */ - -/* Private macro -------------------------------------------------------------*/ -/* USER CODE BEGIN PM */ - -/* USER CODE END PM */ - -/* Private variables ---------------------------------------------------------*/ -/* USER CODE BEGIN Variables */ - -/* USER CODE END Variables */ -/* Definitions for app_main */ -osThreadId_t app_mainHandle; -const osThreadAttr_t app_main_attributes = { - .name = "app_main", - .priority = (osPriority_t)osPriorityNormal, - .stack_size = 1024 * 4}; - -/* Private function prototypes -----------------------------------------------*/ -/* USER CODE BEGIN FunctionPrototypes */ - -/* USER CODE END FunctionPrototypes */ - -void app(void* argument); - -void MX_FREERTOS_Init(void); /* (MISRA C 2004 rule 8.1) */ - -/* Hook prototypes */ -void configureTimerForRunTimeStats(void); -unsigned long getRunTimeCounterValue(void); -void vApplicationIdleHook(void); -void vApplicationStackOverflowHook(TaskHandle_t xTask, signed char* pcTaskName); - -/* USER CODE BEGIN 1 */ -/* Functions needed when configGENERATE_RUN_TIME_STATS is on */ -__weak void configureTimerForRunTimeStats(void) { -} - -__weak unsigned long getRunTimeCounterValue(void) { - return 0; -} -/* USER CODE END 1 */ - -/* USER CODE BEGIN 2 */ -void vApplicationIdleHook(void) { - /* vApplicationIdleHook() will only be called if configUSE_IDLE_HOOK is set - to 1 in FreeRTOSConfig.h. It will be called on each iteration of the idle - task. It is essential that code added to this hook function never attempts - to block in any way (for example, call xQueueReceive() with a block time - specified, or call vTaskDelay()). If the application makes use of the - vTaskDelete() API function (as this demo application does) then it is also - important that vApplicationIdleHook() is permitted to return to its calling - function, because it is the responsibility of the idle task to clean up - memory allocated by the kernel to any task that has since been deleted. */ -} -/* USER CODE END 2 */ - -/* USER CODE BEGIN 4 */ -void vApplicationStackOverflowHook(TaskHandle_t xTask, signed char* pcTaskName) { - /* Run time stack overflow checking is performed if - configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook function is - called if a stack overflow is detected. */ -} -/* USER CODE END 4 */ - -/* USER CODE BEGIN VPORT_SUPPORT_TICKS_AND_SLEEP */ -__weak void vPortSuppressTicksAndSleep(TickType_t xExpectedIdleTime) { - // Generated when configUSE_TICKLESS_IDLE == 2. - // Function called in tasks.c (in portTASK_FUNCTION). - // TO BE COMPLETED or TO BE REPLACED by a user one, overriding that weak one. -} -/* USER CODE END VPORT_SUPPORT_TICKS_AND_SLEEP */ - -/** - * @brief FreeRTOS initialization - * @param None - * @retval None - */ -void MX_FREERTOS_Init(void) { - /* USER CODE BEGIN Init */ - - /* USER CODE END Init */ - - /* USER CODE BEGIN RTOS_MUTEX */ - /* add mutexes, ... */ - /* USER CODE END RTOS_MUTEX */ - - /* USER CODE BEGIN RTOS_SEMAPHORES */ - /* add semaphores, ... */ - /* USER CODE END RTOS_SEMAPHORES */ - - /* USER CODE BEGIN RTOS_TIMERS */ - /* start timers, add new ones, ... */ - /* USER CODE END RTOS_TIMERS */ - - /* USER CODE BEGIN RTOS_QUEUES */ - /* add queues, ... */ - /* USER CODE END RTOS_QUEUES */ - - /* Create the thread(s) */ - /* creation of app_main */ - app_mainHandle = osThreadNew(app, NULL, &app_main_attributes); - - /* USER CODE BEGIN RTOS_THREADS */ - /* add threads, ... */ - /* USER CODE END RTOS_THREADS */ - - /* USER CODE BEGIN RTOS_EVENTS */ - /* add events, ... */ - /* USER CODE END RTOS_EVENTS */ -} - -/* USER CODE BEGIN Header_app */ -/** - * @brief Function implementing the app_main thread. - * @param argument: Not used - * @retval None - */ -/* USER CODE END Header_app */ -__weak void app(void* argument) { - /* USER CODE BEGIN app */ - /* Infinite loop */ - for(;;) { - osDelay(1); - } - /* USER CODE END app */ -} - -/* Private application code --------------------------------------------------*/ -/* USER CODE BEGIN Application */ - -/* USER CODE END Application */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/firmware/targets/f7/cube/Src/comp.c b/firmware/targets/f7/cube/Src/comp.c deleted file mode 100644 index 95e697e3c4b..00000000000 --- a/firmware/targets/f7/cube/Src/comp.c +++ /dev/null @@ -1,103 +0,0 @@ -/** - ****************************************************************************** - * @file comp.c - * @brief This file provides code for the configuration - * of the COMP instances. - ****************************************************************************** - * @attention - * - *

© Copyright (c) 2021 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "comp.h" - -/* USER CODE BEGIN 0 */ - -/* USER CODE END 0 */ - -COMP_HandleTypeDef hcomp1; - -/* COMP1 init function */ -void MX_COMP1_Init(void) { - /* USER CODE BEGIN COMP1_Init 0 */ - - /* USER CODE END COMP1_Init 0 */ - - /* USER CODE BEGIN COMP1_Init 1 */ - - /* USER CODE END COMP1_Init 1 */ - hcomp1.Instance = COMP1; - hcomp1.Init.InputMinus = COMP_INPUT_MINUS_1_4VREFINT; - hcomp1.Init.InputPlus = COMP_INPUT_PLUS_IO1; - hcomp1.Init.OutputPol = COMP_OUTPUTPOL_NONINVERTED; - hcomp1.Init.Hysteresis = COMP_HYSTERESIS_HIGH; - hcomp1.Init.BlankingSrce = COMP_BLANKINGSRC_NONE; - hcomp1.Init.Mode = COMP_POWERMODE_MEDIUMSPEED; - hcomp1.Init.WindowMode = COMP_WINDOWMODE_DISABLE; - hcomp1.Init.TriggerMode = COMP_TRIGGERMODE_IT_RISING_FALLING; - if(HAL_COMP_Init(&hcomp1) != HAL_OK) { - Error_Handler(); - } - /* USER CODE BEGIN COMP1_Init 2 */ - - /* USER CODE END COMP1_Init 2 */ -} - -void HAL_COMP_MspInit(COMP_HandleTypeDef* compHandle) { - GPIO_InitTypeDef GPIO_InitStruct = {0}; - if(compHandle->Instance == COMP1) { - /* USER CODE BEGIN COMP1_MspInit 0 */ - - /* USER CODE END COMP1_MspInit 0 */ - - __HAL_RCC_GPIOC_CLK_ENABLE(); - /**COMP1 GPIO Configuration - PC5 ------> COMP1_INP - */ - GPIO_InitStruct.Pin = RFID_RF_IN_Pin; - GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; - GPIO_InitStruct.Pull = GPIO_NOPULL; - HAL_GPIO_Init(RFID_RF_IN_GPIO_Port, &GPIO_InitStruct); - - /* COMP1 interrupt Init */ - HAL_NVIC_SetPriority(COMP_IRQn, 5, 0); - HAL_NVIC_EnableIRQ(COMP_IRQn); - /* USER CODE BEGIN COMP1_MspInit 1 */ - - /* USER CODE END COMP1_MspInit 1 */ - } -} - -void HAL_COMP_MspDeInit(COMP_HandleTypeDef* compHandle) { - if(compHandle->Instance == COMP1) { - /* USER CODE BEGIN COMP1_MspDeInit 0 */ - - /* USER CODE END COMP1_MspDeInit 0 */ - - /**COMP1 GPIO Configuration - PC5 ------> COMP1_INP - */ - HAL_GPIO_DeInit(RFID_RF_IN_GPIO_Port, RFID_RF_IN_Pin); - - /* COMP1 interrupt Deinit */ - HAL_NVIC_DisableIRQ(COMP_IRQn); - /* USER CODE BEGIN COMP1_MspDeInit 1 */ - - /* USER CODE END COMP1_MspDeInit 1 */ - } -} - -/* USER CODE BEGIN 1 */ - -/* USER CODE END 1 */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/firmware/targets/f7/cube/Src/crc.c b/firmware/targets/f7/cube/Src/crc.c deleted file mode 100644 index 203032eaa41..00000000000 --- a/firmware/targets/f7/cube/Src/crc.c +++ /dev/null @@ -1,82 +0,0 @@ -/** - ****************************************************************************** - * @file crc.c - * @brief This file provides code for the configuration - * of the CRC instances. - ****************************************************************************** - * @attention - * - *

© Copyright (c) 2021 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "crc.h" - -/* USER CODE BEGIN 0 */ - -/* USER CODE END 0 */ - -CRC_HandleTypeDef hcrc; - -/* CRC init function */ -void MX_CRC_Init(void) { - /* USER CODE BEGIN CRC_Init 0 */ - - /* USER CODE END CRC_Init 0 */ - - /* USER CODE BEGIN CRC_Init 1 */ - - /* USER CODE END CRC_Init 1 */ - hcrc.Instance = CRC; - hcrc.Init.DefaultPolynomialUse = DEFAULT_POLYNOMIAL_ENABLE; - hcrc.Init.DefaultInitValueUse = DEFAULT_INIT_VALUE_ENABLE; - hcrc.Init.InputDataInversionMode = CRC_INPUTDATA_INVERSION_NONE; - hcrc.Init.OutputDataInversionMode = CRC_OUTPUTDATA_INVERSION_DISABLE; - hcrc.InputDataFormat = CRC_INPUTDATA_FORMAT_BYTES; - if(HAL_CRC_Init(&hcrc) != HAL_OK) { - Error_Handler(); - } - /* USER CODE BEGIN CRC_Init 2 */ - - /* USER CODE END CRC_Init 2 */ -} - -void HAL_CRC_MspInit(CRC_HandleTypeDef* crcHandle) { - if(crcHandle->Instance == CRC) { - /* USER CODE BEGIN CRC_MspInit 0 */ - - /* USER CODE END CRC_MspInit 0 */ - /* CRC clock enable */ - __HAL_RCC_CRC_CLK_ENABLE(); - /* USER CODE BEGIN CRC_MspInit 1 */ - - /* USER CODE END CRC_MspInit 1 */ - } -} - -void HAL_CRC_MspDeInit(CRC_HandleTypeDef* crcHandle) { - if(crcHandle->Instance == CRC) { - /* USER CODE BEGIN CRC_MspDeInit 0 */ - - /* USER CODE END CRC_MspDeInit 0 */ - /* Peripheral clock disable */ - __HAL_RCC_CRC_CLK_DISABLE(); - /* USER CODE BEGIN CRC_MspDeInit 1 */ - - /* USER CODE END CRC_MspDeInit 1 */ - } -} - -/* USER CODE BEGIN 1 */ - -/* USER CODE END 1 */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/firmware/targets/f7/cube/Src/gpio.c b/firmware/targets/f7/cube/Src/gpio.c deleted file mode 100644 index d8fd35dcadf..00000000000 --- a/firmware/targets/f7/cube/Src/gpio.c +++ /dev/null @@ -1,177 +0,0 @@ -/** - ****************************************************************************** - * @file gpio.c - * @brief This file provides code for the configuration - * of all used GPIO pins. - ****************************************************************************** - * @attention - * - *

© Copyright (c) 2021 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "gpio.h" - -/* USER CODE BEGIN 0 */ - -/* USER CODE END 0 */ - -/*----------------------------------------------------------------------------*/ -/* Configure GPIO */ -/*----------------------------------------------------------------------------*/ -/* USER CODE BEGIN 1 */ - -/* USER CODE END 1 */ - -/** Configure pins as - * Analog - * Input - * Output - * EVENT_OUT - * EXTI -*/ -void MX_GPIO_Init(void) { - GPIO_InitTypeDef GPIO_InitStruct = {0}; - - /* GPIO Ports Clock Enable */ - __HAL_RCC_GPIOC_CLK_ENABLE(); - __HAL_RCC_GPIOH_CLK_ENABLE(); - __HAL_RCC_GPIOB_CLK_ENABLE(); - __HAL_RCC_GPIOA_CLK_ENABLE(); - __HAL_RCC_GPIOE_CLK_ENABLE(); - __HAL_RCC_GPIOD_CLK_ENABLE(); - - /*Configure GPIO pin Output Level */ - HAL_GPIO_WritePin(GPIOA, RFID_PULL_Pin | VIBRO_Pin, GPIO_PIN_RESET); - - /*Configure GPIO pin Output Level */ - HAL_GPIO_WritePin(PERIPH_POWER_GPIO_Port, PERIPH_POWER_Pin, GPIO_PIN_SET); - - /*Configure GPIO pin Output Level */ - HAL_GPIO_WritePin(RF_SW_0_GPIO_Port, RF_SW_0_Pin, GPIO_PIN_RESET); - - /*Configure GPIO pin Output Level */ - HAL_GPIO_WritePin(GPIOB, DISPLAY_RST_Pin | DISPLAY_DI_Pin, GPIO_PIN_RESET); - - /*Configure GPIO pin Output Level */ - HAL_GPIO_WritePin(NFC_CS_GPIO_Port, NFC_CS_Pin, GPIO_PIN_SET); - - /*Configure GPIO pin Output Level */ - HAL_GPIO_WritePin(GPIOC, DISPLAY_CS_Pin | SD_CS_Pin, GPIO_PIN_SET); - - /*Configure GPIO pin Output Level */ - HAL_GPIO_WritePin(CC1101_CS_GPIO_Port, CC1101_CS_Pin, GPIO_PIN_SET); - - /*Configure GPIO pin : PtPin */ - GPIO_InitStruct.Pin = BUTTON_BACK_Pin; - GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING; - GPIO_InitStruct.Pull = GPIO_PULLUP; - HAL_GPIO_Init(BUTTON_BACK_GPIO_Port, &GPIO_InitStruct); - - /*Configure GPIO pin : PtPin */ - GPIO_InitStruct.Pin = BUTTON_OK_Pin; - GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING; - GPIO_InitStruct.Pull = GPIO_NOPULL; - HAL_GPIO_Init(BUTTON_OK_GPIO_Port, &GPIO_InitStruct); - - /*Configure GPIO pins : PCPin PCPin PCPin */ - GPIO_InitStruct.Pin = PC0_Pin | PC1_Pin | PC3_Pin; - GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; - GPIO_InitStruct.Pull = GPIO_NOPULL; - HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); - - /*Configure GPIO pins : PAPin PAPin PAPin PAPin - PAPin */ - GPIO_InitStruct.Pin = CC1101_G0_Pin | PA4_Pin | PA6_Pin | PA7_Pin | RFID_CARRIER_Pin; - GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; - GPIO_InitStruct.Pull = GPIO_NOPULL; - HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); - - /*Configure GPIO pins : PAPin PAPin */ - GPIO_InitStruct.Pin = RFID_PULL_Pin | VIBRO_Pin; - GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; - GPIO_InitStruct.Pull = GPIO_NOPULL; - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; - HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); - - /*Configure GPIO pin : PtPin */ - GPIO_InitStruct.Pin = PERIPH_POWER_Pin; - GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD; - GPIO_InitStruct.Pull = GPIO_NOPULL; - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; - HAL_GPIO_Init(PERIPH_POWER_GPIO_Port, &GPIO_InitStruct); - - /*Configure GPIO pins : PCPin PCPin */ - GPIO_InitStruct.Pin = RF_SW_0_Pin | DISPLAY_CS_Pin; - GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; - GPIO_InitStruct.Pull = GPIO_NOPULL; - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; - HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); - - /*Configure GPIO pins : PBPin PBPin PBPin */ - GPIO_InitStruct.Pin = PB2_Pin | iBTN_Pin | PB3_Pin; - GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; - GPIO_InitStruct.Pull = GPIO_NOPULL; - HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); - - /*Configure GPIO pins : PBPin PBPin PBPin */ - GPIO_InitStruct.Pin = BUTTON_UP_Pin | BUTTON_LEFT_Pin | BUTTON_RIGHT_Pin; - GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING; - GPIO_InitStruct.Pull = GPIO_PULLUP; - HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); - - /*Configure GPIO pins : PBPin PBPin */ - GPIO_InitStruct.Pin = DISPLAY_RST_Pin | DISPLAY_DI_Pin; - GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; - GPIO_InitStruct.Pull = GPIO_NOPULL; - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; - HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); - - /*Configure GPIO pin : PtPin */ - GPIO_InitStruct.Pin = NFC_CS_Pin; - GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; - GPIO_InitStruct.Pull = GPIO_NOPULL; - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; - HAL_GPIO_Init(NFC_CS_GPIO_Port, &GPIO_InitStruct); - - /*Configure GPIO pins : PCPin PCPin */ - GPIO_InitStruct.Pin = BUTTON_DOWN_Pin | SD_CD_Pin; - GPIO_InitStruct.Mode = GPIO_MODE_INPUT; - GPIO_InitStruct.Pull = GPIO_NOPULL; - HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); - - /*Configure GPIO pin : PtPin */ - GPIO_InitStruct.Pin = SD_CS_Pin; - GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; - GPIO_InitStruct.Pull = GPIO_NOPULL; - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; - HAL_GPIO_Init(SD_CS_GPIO_Port, &GPIO_InitStruct); - - /*Configure GPIO pin : PtPin */ - GPIO_InitStruct.Pin = CC1101_CS_Pin; - GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; - GPIO_InitStruct.Pull = GPIO_NOPULL; - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; - HAL_GPIO_Init(CC1101_CS_GPIO_Port, &GPIO_InitStruct); - - /* EXTI interrupt init*/ - HAL_NVIC_SetPriority(EXTI3_IRQn, 5, 0); - HAL_NVIC_EnableIRQ(EXTI3_IRQn); - - HAL_NVIC_SetPriority(EXTI15_10_IRQn, 5, 0); - HAL_NVIC_EnableIRQ(EXTI15_10_IRQn); -} - -/* USER CODE BEGIN 2 */ - -/* USER CODE END 2 */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/firmware/targets/f7/cube/Src/i2c.c b/firmware/targets/f7/cube/Src/i2c.c deleted file mode 100644 index 0ad9765ab74..00000000000 --- a/firmware/targets/f7/cube/Src/i2c.c +++ /dev/null @@ -1,80 +0,0 @@ -/** - ****************************************************************************** - * @file i2c.c - * @brief This file provides code for the configuration - * of the I2C instances. - ****************************************************************************** - * @attention - * - *

© Copyright (c) 2021 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "i2c.h" - -/* USER CODE BEGIN 0 */ - -/* USER CODE END 0 */ - -/* I2C1 init function */ -void MX_I2C1_Init(void) { - /* USER CODE BEGIN I2C1_Init 0 */ - - /* USER CODE END I2C1_Init 0 */ - - LL_I2C_InitTypeDef I2C_InitStruct = {0}; - - LL_GPIO_InitTypeDef GPIO_InitStruct = {0}; - - LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOA); - /**I2C1 GPIO Configuration - PA9 ------> I2C1_SCL - PA10 ------> I2C1_SDA - */ - GPIO_InitStruct.Pin = LL_GPIO_PIN_9 | LL_GPIO_PIN_10; - GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; - GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_VERY_HIGH; - GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_OPENDRAIN; - GPIO_InitStruct.Pull = LL_GPIO_PULL_UP; - GPIO_InitStruct.Alternate = LL_GPIO_AF_4; - LL_GPIO_Init(GPIOA, &GPIO_InitStruct); - - /* Peripheral clock enable */ - LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_I2C1); - - /* USER CODE BEGIN I2C1_Init 1 */ - - /* USER CODE END I2C1_Init 1 */ - /** I2C Initialization - */ - I2C_InitStruct.PeripheralMode = LL_I2C_MODE_I2C; - I2C_InitStruct.Timing = 0x10707DBC; - I2C_InitStruct.AnalogFilter = LL_I2C_ANALOGFILTER_ENABLE; - I2C_InitStruct.DigitalFilter = 0; - I2C_InitStruct.OwnAddress1 = 0; - I2C_InitStruct.TypeAcknowledge = LL_I2C_ACK; - I2C_InitStruct.OwnAddrSize = LL_I2C_OWNADDRESS1_7BIT; - LL_I2C_Init(I2C1, &I2C_InitStruct); - LL_I2C_EnableAutoEndMode(I2C1); - LL_I2C_SetOwnAddress2(I2C1, 0, LL_I2C_OWNADDRESS2_NOMASK); - LL_I2C_DisableOwnAddress2(I2C1); - LL_I2C_DisableGeneralCall(I2C1); - LL_I2C_EnableClockStretching(I2C1); - /* USER CODE BEGIN I2C1_Init 2 */ - - /* USER CODE END I2C1_Init 2 */ -} - -/* USER CODE BEGIN 1 */ - -/* USER CODE END 1 */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/firmware/targets/f7/cube/Src/main.c b/firmware/targets/f7/cube/Src/main.c deleted file mode 100644 index d4ec7ec2db8..00000000000 --- a/firmware/targets/f7/cube/Src/main.c +++ /dev/null @@ -1,275 +0,0 @@ -/* USER CODE BEGIN Header */ -/** - ****************************************************************************** - * @file : main.c - * @brief : Main program body - ****************************************************************************** - * @attention - * - *

© Copyright (c) 2021 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ -/* USER CODE END Header */ -/* Includes ------------------------------------------------------------------*/ -#include "main.h" -#include "cmsis_os.h" -#include "adc.h" -#include "aes.h" -#include "comp.h" -#include "crc.h" -#include "i2c.h" -#include "pka.h" -#include "rf.h" -#include "rng.h" -#include "rtc.h" -#include "spi.h" -#include "tim.h" -#include "usart.h" -#include "usb_device.h" -#include "gpio.h" - -/* Private includes ----------------------------------------------------------*/ -/* USER CODE BEGIN Includes */ - -/* USER CODE END Includes */ - -/* Private typedef -----------------------------------------------------------*/ -/* USER CODE BEGIN PTD */ - -/* USER CODE END PTD */ - -/* Private define ------------------------------------------------------------*/ -/* USER CODE BEGIN PD */ -/* USER CODE END PD */ - -/* Private macro -------------------------------------------------------------*/ -/* USER CODE BEGIN PM */ - -/* USER CODE END PM */ - -/* Private variables ---------------------------------------------------------*/ - -/* USER CODE BEGIN PV */ - -/* USER CODE END PV */ - -/* Private function prototypes -----------------------------------------------*/ -void SystemClock_Config(void); -void MX_FREERTOS_Init(void); -/* USER CODE BEGIN PFP */ - -/* USER CODE END PFP */ - -/* Private user code ---------------------------------------------------------*/ -/* USER CODE BEGIN 0 */ - -/* USER CODE END 0 */ - -/** - * @brief The application entry point. - * @retval int - */ -int main(void) { - /* USER CODE BEGIN 1 */ - - /* USER CODE END 1 */ - - /* MCU Configuration--------------------------------------------------------*/ - - /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ - HAL_Init(); - - /* USER CODE BEGIN Init */ - - /* USER CODE END Init */ - - /* Configure the system clock */ - SystemClock_Config(); - - /* USER CODE BEGIN SysInit */ - - /* USER CODE END SysInit */ - - /* Initialize all configured peripherals */ - MX_GPIO_Init(); - MX_ADC1_Init(); - MX_I2C1_Init(); - MX_RTC_Init(); - MX_SPI1_Init(); - MX_SPI2_Init(); - MX_USB_Device_Init(); - MX_TIM1_Init(); - MX_TIM2_Init(); - MX_TIM16_Init(); - MX_COMP1_Init(); - MX_RF_Init(); - MX_PKA_Init(); - MX_RNG_Init(); - MX_AES1_Init(); - MX_AES2_Init(); - MX_CRC_Init(); - MX_USART1_UART_Init(); - /* USER CODE BEGIN 2 */ - - /* USER CODE END 2 */ - - /* Init scheduler */ - osKernelInitialize(); /* Call init function for freertos objects (in freertos.c) */ - MX_FREERTOS_Init(); - /* Start scheduler */ - osKernelStart(); - - /* We should never get here as control is now taken by the scheduler */ - /* Infinite loop */ - /* USER CODE BEGIN WHILE */ - while(1) { - /* USER CODE END WHILE */ - - /* USER CODE BEGIN 3 */ - } - /* USER CODE END 3 */ -} - -/** - * @brief System Clock Configuration - * @retval None - */ -void SystemClock_Config(void) { - LL_FLASH_SetLatency(LL_FLASH_LATENCY_3); - while(LL_FLASH_GetLatency() != LL_FLASH_LATENCY_3) { - } - - /* HSE configuration and activation */ - LL_RCC_HSE_Enable(); - while(LL_RCC_HSE_IsReady() != 1) { - } - - /* HSI configuration and activation */ - LL_RCC_HSI_Enable(); - while(LL_RCC_HSI_IsReady() != 1) { - } - - LL_PWR_EnableBkUpAccess(); - if(LL_RCC_GetRTCClockSource() != LL_RCC_RTC_CLKSOURCE_LSE) { - LL_RCC_ForceBackupDomainReset(); - LL_RCC_ReleaseBackupDomainReset(); - } - LL_RCC_LSE_SetDriveCapability(LL_RCC_LSEDRIVE_MEDIUMLOW); - LL_RCC_LSE_Enable(); - - /* Wait till LSE is ready */ - while(LL_RCC_LSE_IsReady() != 1) { - } - - LL_RCC_HSE_EnableCSS(); - LL_RCC_LSE_EnableCSS(); - /* Main PLL configuration and activation */ - LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSE, LL_RCC_PLLM_DIV_2, 8, LL_RCC_PLLR_DIV_2); - LL_RCC_PLL_Enable(); - LL_RCC_PLL_EnableDomain_SYS(); - while(LL_RCC_PLL_IsReady() != 1) { - } - - LL_RCC_PLLSAI1_ConfigDomain_48M( - LL_RCC_PLLSOURCE_HSE, LL_RCC_PLLM_DIV_2, 6, LL_RCC_PLLSAI1Q_DIV_2); - LL_RCC_PLLSAI1_ConfigDomain_ADC( - LL_RCC_PLLSOURCE_HSE, LL_RCC_PLLM_DIV_2, 6, LL_RCC_PLLSAI1R_DIV_2); - LL_RCC_PLLSAI1_Enable(); - LL_RCC_PLLSAI1_EnableDomain_48M(); - LL_RCC_PLLSAI1_EnableDomain_ADC(); - - /* Wait till PLLSAI1 is ready */ - while(LL_RCC_PLLSAI1_IsReady() != 1) { - } - - /* Sysclk activation on the main PLL */ - /* Set CPU1 prescaler*/ - LL_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_1); - - /* Set CPU2 prescaler*/ - LL_C2_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_2); - - LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL); - while(LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL) { - } - - /* Set AHB SHARED prescaler*/ - LL_RCC_SetAHB4Prescaler(LL_RCC_SYSCLK_DIV_1); - - /* Set APB1 prescaler*/ - LL_RCC_SetAPB1Prescaler(LL_RCC_APB1_DIV_1); - - /* Set APB2 prescaler*/ - LL_RCC_SetAPB2Prescaler(LL_RCC_APB2_DIV_1); - - /* Disable MSI */ - LL_RCC_MSI_Disable(); - while(LL_RCC_MSI_IsReady() != 0) { - } - - /* Update CMSIS variable (which can be updated also through SystemCoreClockUpdate function) */ - LL_SetSystemCoreClock(64000000); - - /* Update the time base */ - if(HAL_InitTick(TICK_INT_PRIORITY) != HAL_OK) { - Error_Handler(); - } - if(LL_RCC_GetRTCClockSource() != LL_RCC_RTC_CLKSOURCE_LSE) { - LL_RCC_SetRTCClockSource(LL_RCC_RTC_CLKSOURCE_LSE); - } - LL_RCC_EnableRTC(); - LL_RCC_SetUSARTClockSource(LL_RCC_USART1_CLKSOURCE_PCLK2); - LL_RCC_SetADCClockSource(LL_RCC_ADC_CLKSOURCE_PLLSAI1); - LL_RCC_SetI2CClockSource(LL_RCC_I2C1_CLKSOURCE_PCLK1); - LL_RCC_SetRNGClockSource(LL_RCC_RNG_CLKSOURCE_CLK48); - LL_RCC_SetUSBClockSource(LL_RCC_USB_CLKSOURCE_PLLSAI1); - LL_RCC_SetCLK48ClockSource(LL_RCC_CLK48_CLKSOURCE_PLLSAI1); - LL_RCC_SetSMPSClockSource(LL_RCC_SMPS_CLKSOURCE_HSE); - LL_RCC_SetSMPSPrescaler(LL_RCC_SMPS_DIV_1); - LL_RCC_SetRFWKPClockSource(LL_RCC_RFWKP_CLKSOURCE_LSE); - /* USER CODE BEGIN Smps */ - - /* USER CODE END Smps */ -} - -/* USER CODE BEGIN 4 */ - -/* USER CODE END 4 */ - -/** - * @brief This function is executed in case of error occurrence. - * @retval None - */ -void Error_Handler(void) { - /* USER CODE BEGIN Error_Handler_Debug */ - /* User can add his own implementation to report the HAL error return state */ - __disable_irq(); - while(1) { - } - /* USER CODE END Error_Handler_Debug */ -} - -#ifdef USE_FULL_ASSERT -/** - * @brief Reports the name of the source file and the source line number - * where the assert_param error has occurred. - * @param file: pointer to the source file name - * @param line: assert_param error line source number - * @retval None - */ -void assert_failed(uint8_t* file, uint32_t line) { - /* USER CODE BEGIN 6 */ - /* User can add his own implementation to report the file name and line number, - ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ - /* USER CODE END 6 */ -} -#endif /* USE_FULL_ASSERT */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/firmware/targets/f7/cube/Src/pka.c b/firmware/targets/f7/cube/Src/pka.c deleted file mode 100644 index 6a5813171c4..00000000000 --- a/firmware/targets/f7/cube/Src/pka.c +++ /dev/null @@ -1,77 +0,0 @@ -/** - ****************************************************************************** - * @file pka.c - * @brief This file provides code for the configuration - * of the PKA instances. - ****************************************************************************** - * @attention - * - *

© Copyright (c) 2021 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "pka.h" - -/* USER CODE BEGIN 0 */ - -/* USER CODE END 0 */ - -PKA_HandleTypeDef hpka; - -/* PKA init function */ -void MX_PKA_Init(void) { - /* USER CODE BEGIN PKA_Init 0 */ - - /* USER CODE END PKA_Init 0 */ - - /* USER CODE BEGIN PKA_Init 1 */ - - /* USER CODE END PKA_Init 1 */ - hpka.Instance = PKA; - if(HAL_PKA_Init(&hpka) != HAL_OK) { - Error_Handler(); - } - /* USER CODE BEGIN PKA_Init 2 */ - - /* USER CODE END PKA_Init 2 */ -} - -void HAL_PKA_MspInit(PKA_HandleTypeDef* pkaHandle) { - if(pkaHandle->Instance == PKA) { - /* USER CODE BEGIN PKA_MspInit 0 */ - - /* USER CODE END PKA_MspInit 0 */ - /* PKA clock enable */ - __HAL_RCC_PKA_CLK_ENABLE(); - /* USER CODE BEGIN PKA_MspInit 1 */ - - /* USER CODE END PKA_MspInit 1 */ - } -} - -void HAL_PKA_MspDeInit(PKA_HandleTypeDef* pkaHandle) { - if(pkaHandle->Instance == PKA) { - /* USER CODE BEGIN PKA_MspDeInit 0 */ - - /* USER CODE END PKA_MspDeInit 0 */ - /* Peripheral clock disable */ - __HAL_RCC_PKA_CLK_DISABLE(); - /* USER CODE BEGIN PKA_MspDeInit 1 */ - - /* USER CODE END PKA_MspDeInit 1 */ - } -} - -/* USER CODE BEGIN 1 */ - -/* USER CODE END 1 */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/firmware/targets/f7/cube/Src/rf.c b/firmware/targets/f7/cube/Src/rf.c deleted file mode 100644 index eaa4ba67248..00000000000 --- a/firmware/targets/f7/cube/Src/rf.c +++ /dev/null @@ -1,45 +0,0 @@ -/** - ****************************************************************************** - * @file rf.c - * @brief This file provides code for the configuration - * of the RF instances. - ****************************************************************************** - * @attention - * - *

© Copyright (c) 2021 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "rf.h" - -/* USER CODE BEGIN 0 */ - -/* USER CODE END 0 */ - -/* RF init function */ -void MX_RF_Init(void) { - /* USER CODE BEGIN RF_Init 0 */ - - /* USER CODE END RF_Init 0 */ - - /* USER CODE BEGIN RF_Init 1 */ - - /* USER CODE END RF_Init 1 */ - /* USER CODE BEGIN RF_Init 2 */ - - /* USER CODE END RF_Init 2 */ -} - -/* USER CODE BEGIN 1 */ - -/* USER CODE END 1 */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/firmware/targets/f7/cube/Src/rng.c b/firmware/targets/f7/cube/Src/rng.c deleted file mode 100644 index bab1b278a5a..00000000000 --- a/firmware/targets/f7/cube/Src/rng.c +++ /dev/null @@ -1,78 +0,0 @@ -/** - ****************************************************************************** - * @file rng.c - * @brief This file provides code for the configuration - * of the RNG instances. - ****************************************************************************** - * @attention - * - *

© Copyright (c) 2021 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "rng.h" - -/* USER CODE BEGIN 0 */ - -/* USER CODE END 0 */ - -RNG_HandleTypeDef hrng; - -/* RNG init function */ -void MX_RNG_Init(void) { - /* USER CODE BEGIN RNG_Init 0 */ - - /* USER CODE END RNG_Init 0 */ - - /* USER CODE BEGIN RNG_Init 1 */ - - /* USER CODE END RNG_Init 1 */ - hrng.Instance = RNG; - hrng.Init.ClockErrorDetection = RNG_CED_ENABLE; - if(HAL_RNG_Init(&hrng) != HAL_OK) { - Error_Handler(); - } - /* USER CODE BEGIN RNG_Init 2 */ - - /* USER CODE END RNG_Init 2 */ -} - -void HAL_RNG_MspInit(RNG_HandleTypeDef* rngHandle) { - if(rngHandle->Instance == RNG) { - /* USER CODE BEGIN RNG_MspInit 0 */ - - /* USER CODE END RNG_MspInit 0 */ - /* RNG clock enable */ - __HAL_RCC_RNG_CLK_ENABLE(); - /* USER CODE BEGIN RNG_MspInit 1 */ - - /* USER CODE END RNG_MspInit 1 */ - } -} - -void HAL_RNG_MspDeInit(RNG_HandleTypeDef* rngHandle) { - if(rngHandle->Instance == RNG) { - /* USER CODE BEGIN RNG_MspDeInit 0 */ - - /* USER CODE END RNG_MspDeInit 0 */ - /* Peripheral clock disable */ - __HAL_RCC_RNG_CLK_DISABLE(); - /* USER CODE BEGIN RNG_MspDeInit 1 */ - - /* USER CODE END RNG_MspDeInit 1 */ - } -} - -/* USER CODE BEGIN 1 */ - -/* USER CODE END 1 */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/firmware/targets/f7/cube/Src/rtc.c b/firmware/targets/f7/cube/Src/rtc.c deleted file mode 100644 index 416159f8cfc..00000000000 --- a/firmware/targets/f7/cube/Src/rtc.c +++ /dev/null @@ -1,122 +0,0 @@ -/** - ****************************************************************************** - * @file rtc.c - * @brief This file provides code for the configuration - * of the RTC instances. - ****************************************************************************** - * @attention - * - *

© Copyright (c) 2021 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "rtc.h" - -/* USER CODE BEGIN 0 */ - -/* USER CODE END 0 */ - -RTC_HandleTypeDef hrtc; - -/* RTC init function */ -void MX_RTC_Init(void) { - /* USER CODE BEGIN RTC_Init 0 */ - - /* USER CODE END RTC_Init 0 */ - - RTC_TimeTypeDef sTime = {0}; - RTC_DateTypeDef sDate = {0}; - - /* USER CODE BEGIN RTC_Init 1 */ - - /* USER CODE END RTC_Init 1 */ - /** Initialize RTC Only - */ - hrtc.Instance = RTC; - hrtc.Init.HourFormat = RTC_HOURFORMAT_24; - hrtc.Init.AsynchPrediv = 127; - hrtc.Init.SynchPrediv = 255; - hrtc.Init.OutPut = RTC_OUTPUT_DISABLE; - hrtc.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH; - hrtc.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN; - hrtc.Init.OutPutRemap = RTC_OUTPUT_REMAP_NONE; - if(HAL_RTC_Init(&hrtc) != HAL_OK) { - Error_Handler(); - } - - /* USER CODE BEGIN Check_RTC_BKUP */ - - /* USER CODE END Check_RTC_BKUP */ - - /** Initialize RTC and set the Time and Date - */ - sTime.Hours = 0x0; - sTime.Minutes = 0x0; - sTime.Seconds = 0x0; - sTime.SubSeconds = 0x0; - sTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE; - sTime.StoreOperation = RTC_STOREOPERATION_RESET; - if(HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BCD) != HAL_OK) { - Error_Handler(); - } - sDate.WeekDay = RTC_WEEKDAY_MONDAY; - sDate.Month = RTC_MONTH_JANUARY; - sDate.Date = 0x1; - sDate.Year = 0x0; - - if(HAL_RTC_SetDate(&hrtc, &sDate, RTC_FORMAT_BCD) != HAL_OK) { - Error_Handler(); - } - /* USER CODE BEGIN RTC_Init 2 */ - - /* USER CODE END RTC_Init 2 */ -} - -void HAL_RTC_MspInit(RTC_HandleTypeDef* rtcHandle) { - if(rtcHandle->Instance == RTC) { - /* USER CODE BEGIN RTC_MspInit 0 */ - - /* USER CODE END RTC_MspInit 0 */ - /* RTC clock enable */ - __HAL_RCC_RTC_ENABLE(); - __HAL_RCC_RTCAPB_CLK_ENABLE(); - - /* RTC interrupt Init */ - HAL_NVIC_SetPriority(TAMP_STAMP_LSECSS_IRQn, 5, 0); - HAL_NVIC_EnableIRQ(TAMP_STAMP_LSECSS_IRQn); - /* USER CODE BEGIN RTC_MspInit 1 */ - - /* USER CODE END RTC_MspInit 1 */ - } -} - -void HAL_RTC_MspDeInit(RTC_HandleTypeDef* rtcHandle) { - if(rtcHandle->Instance == RTC) { - /* USER CODE BEGIN RTC_MspDeInit 0 */ - - /* USER CODE END RTC_MspDeInit 0 */ - /* Peripheral clock disable */ - __HAL_RCC_RTC_DISABLE(); - __HAL_RCC_RTCAPB_CLK_DISABLE(); - - /* RTC interrupt Deinit */ - HAL_NVIC_DisableIRQ(TAMP_STAMP_LSECSS_IRQn); - /* USER CODE BEGIN RTC_MspDeInit 1 */ - - /* USER CODE END RTC_MspDeInit 1 */ - } -} - -/* USER CODE BEGIN 1 */ - -/* USER CODE END 1 */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/firmware/targets/f7/cube/Src/spi.c b/firmware/targets/f7/cube/Src/spi.c deleted file mode 100644 index 329bc3bbaa6..00000000000 --- a/firmware/targets/f7/cube/Src/spi.c +++ /dev/null @@ -1,214 +0,0 @@ -/** - ****************************************************************************** - * @file spi.c - * @brief This file provides code for the configuration - * of the SPI instances. - ****************************************************************************** - * @attention - * - *

© Copyright (c) 2021 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "spi.h" - -/* USER CODE BEGIN 0 */ - -/* USER CODE END 0 */ - -SPI_HandleTypeDef hspi1; -SPI_HandleTypeDef hspi2; - -/* SPI1 init function */ -void MX_SPI1_Init(void) { - /* USER CODE BEGIN SPI1_Init 0 */ - - /* USER CODE END SPI1_Init 0 */ - - /* USER CODE BEGIN SPI1_Init 1 */ - - /* USER CODE END SPI1_Init 1 */ - hspi1.Instance = SPI1; - hspi1.Init.Mode = SPI_MODE_MASTER; - hspi1.Init.Direction = SPI_DIRECTION_2LINES; - hspi1.Init.DataSize = SPI_DATASIZE_8BIT; - hspi1.Init.CLKPolarity = SPI_POLARITY_LOW; - hspi1.Init.CLKPhase = SPI_PHASE_2EDGE; - hspi1.Init.NSS = SPI_NSS_SOFT; - hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16; - hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB; - hspi1.Init.TIMode = SPI_TIMODE_DISABLE; - hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; - hspi1.Init.CRCPolynomial = 7; - hspi1.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE; - hspi1.Init.NSSPMode = SPI_NSS_PULSE_DISABLE; - if(HAL_SPI_Init(&hspi1) != HAL_OK) { - Error_Handler(); - } - /* USER CODE BEGIN SPI1_Init 2 */ - - /* USER CODE END SPI1_Init 2 */ -} -/* SPI2 init function */ -void MX_SPI2_Init(void) { - /* USER CODE BEGIN SPI2_Init 0 */ - - /* USER CODE END SPI2_Init 0 */ - - /* USER CODE BEGIN SPI2_Init 1 */ - - /* USER CODE END SPI2_Init 1 */ - hspi2.Instance = SPI2; - hspi2.Init.Mode = SPI_MODE_MASTER; - hspi2.Init.Direction = SPI_DIRECTION_2LINES; - hspi2.Init.DataSize = SPI_DATASIZE_8BIT; - hspi2.Init.CLKPolarity = SPI_POLARITY_LOW; - hspi2.Init.CLKPhase = SPI_PHASE_1EDGE; - hspi2.Init.NSS = SPI_NSS_SOFT; - hspi2.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16; - hspi2.Init.FirstBit = SPI_FIRSTBIT_MSB; - hspi2.Init.TIMode = SPI_TIMODE_DISABLE; - hspi2.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; - hspi2.Init.CRCPolynomial = 7; - hspi2.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE; - hspi2.Init.NSSPMode = SPI_NSS_PULSE_ENABLE; - if(HAL_SPI_Init(&hspi2) != HAL_OK) { - Error_Handler(); - } - /* USER CODE BEGIN SPI2_Init 2 */ - - /* USER CODE END SPI2_Init 2 */ -} - -void HAL_SPI_MspInit(SPI_HandleTypeDef* spiHandle) { - GPIO_InitTypeDef GPIO_InitStruct = {0}; - if(spiHandle->Instance == SPI1) { - /* USER CODE BEGIN SPI1_MspInit 0 */ - - /* USER CODE END SPI1_MspInit 0 */ - /* SPI1 clock enable */ - __HAL_RCC_SPI1_CLK_ENABLE(); - - __HAL_RCC_GPIOA_CLK_ENABLE(); - __HAL_RCC_GPIOB_CLK_ENABLE(); - /**SPI1 GPIO Configuration - PA5 ------> SPI1_SCK - PB4 ------> SPI1_MISO - PB5 ------> SPI1_MOSI - */ - GPIO_InitStruct.Pin = SPI_R_SCK_Pin; - GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; - GPIO_InitStruct.Pull = GPIO_NOPULL; - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; - GPIO_InitStruct.Alternate = GPIO_AF5_SPI1; - HAL_GPIO_Init(SPI_R_SCK_GPIO_Port, &GPIO_InitStruct); - - GPIO_InitStruct.Pin = SPI_R_MISO_Pin | SPI_R_MOSI_Pin; - GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; - GPIO_InitStruct.Pull = GPIO_NOPULL; - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; - GPIO_InitStruct.Alternate = GPIO_AF5_SPI1; - HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); - - /* USER CODE BEGIN SPI1_MspInit 1 */ - - /* USER CODE END SPI1_MspInit 1 */ - } else if(spiHandle->Instance == SPI2) { - /* USER CODE BEGIN SPI2_MspInit 0 */ - - /* USER CODE END SPI2_MspInit 0 */ - /* SPI2 clock enable */ - __HAL_RCC_SPI2_CLK_ENABLE(); - - __HAL_RCC_GPIOC_CLK_ENABLE(); - __HAL_RCC_GPIOB_CLK_ENABLE(); - __HAL_RCC_GPIOD_CLK_ENABLE(); - /**SPI2 GPIO Configuration - PC2 ------> SPI2_MISO - PB15 ------> SPI2_MOSI - PD1 ------> SPI2_SCK - */ - GPIO_InitStruct.Pin = SPI_D_MISO_Pin; - GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; - GPIO_InitStruct.Pull = GPIO_NOPULL; - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; - GPIO_InitStruct.Alternate = GPIO_AF5_SPI2; - HAL_GPIO_Init(SPI_D_MISO_GPIO_Port, &GPIO_InitStruct); - - GPIO_InitStruct.Pin = SPI_D_MOSI_Pin; - GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; - GPIO_InitStruct.Pull = GPIO_NOPULL; - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; - GPIO_InitStruct.Alternate = GPIO_AF5_SPI2; - HAL_GPIO_Init(SPI_D_MOSI_GPIO_Port, &GPIO_InitStruct); - - GPIO_InitStruct.Pin = SPI_D_SCK_Pin; - GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; - GPIO_InitStruct.Pull = GPIO_NOPULL; - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; - GPIO_InitStruct.Alternate = GPIO_AF5_SPI2; - HAL_GPIO_Init(SPI_D_SCK_GPIO_Port, &GPIO_InitStruct); - - /* USER CODE BEGIN SPI2_MspInit 1 */ - - /* USER CODE END SPI2_MspInit 1 */ - } -} - -void HAL_SPI_MspDeInit(SPI_HandleTypeDef* spiHandle) { - if(spiHandle->Instance == SPI1) { - /* USER CODE BEGIN SPI1_MspDeInit 0 */ - - /* USER CODE END SPI1_MspDeInit 0 */ - /* Peripheral clock disable */ - __HAL_RCC_SPI1_CLK_DISABLE(); - - /**SPI1 GPIO Configuration - PA5 ------> SPI1_SCK - PB4 ------> SPI1_MISO - PB5 ------> SPI1_MOSI - */ - HAL_GPIO_DeInit(SPI_R_SCK_GPIO_Port, SPI_R_SCK_Pin); - - HAL_GPIO_DeInit(GPIOB, SPI_R_MISO_Pin | SPI_R_MOSI_Pin); - - /* USER CODE BEGIN SPI1_MspDeInit 1 */ - - /* USER CODE END SPI1_MspDeInit 1 */ - } else if(spiHandle->Instance == SPI2) { - /* USER CODE BEGIN SPI2_MspDeInit 0 */ - - /* USER CODE END SPI2_MspDeInit 0 */ - /* Peripheral clock disable */ - __HAL_RCC_SPI2_CLK_DISABLE(); - - /**SPI2 GPIO Configuration - PC2 ------> SPI2_MISO - PB15 ------> SPI2_MOSI - PD1 ------> SPI2_SCK - */ - HAL_GPIO_DeInit(SPI_D_MISO_GPIO_Port, SPI_D_MISO_Pin); - - HAL_GPIO_DeInit(SPI_D_MOSI_GPIO_Port, SPI_D_MOSI_Pin); - - HAL_GPIO_DeInit(SPI_D_SCK_GPIO_Port, SPI_D_SCK_Pin); - - /* USER CODE BEGIN SPI2_MspDeInit 1 */ - - /* USER CODE END SPI2_MspDeInit 1 */ - } -} - -/* USER CODE BEGIN 1 */ - -/* USER CODE END 1 */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/firmware/targets/f7/cube/Src/stm32wbxx_hal_msp.c b/firmware/targets/f7/cube/Src/stm32wbxx_hal_msp.c deleted file mode 100644 index 90ef3c3ffa0..00000000000 --- a/firmware/targets/f7/cube/Src/stm32wbxx_hal_msp.c +++ /dev/null @@ -1,92 +0,0 @@ -/* USER CODE BEGIN Header */ -/** - ****************************************************************************** - * @file stm32wbxx_hal_msp.c - * @brief This file provides code for the MSP Initialization - * and de-Initialization codes. - ****************************************************************************** - * @attention - * - *

© Copyright (c) 2021 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ -/* USER CODE END Header */ - -/* Includes ------------------------------------------------------------------*/ -#include "main.h" -/* USER CODE BEGIN Includes */ - -/* USER CODE END Includes */ - -/* Private typedef -----------------------------------------------------------*/ -/* USER CODE BEGIN TD */ - -/* USER CODE END TD */ - -/* Private define ------------------------------------------------------------*/ -/* USER CODE BEGIN Define */ - -/* USER CODE END Define */ - -/* Private macro -------------------------------------------------------------*/ -/* USER CODE BEGIN Macro */ - -/* USER CODE END Macro */ - -/* Private variables ---------------------------------------------------------*/ -/* USER CODE BEGIN PV */ - -/* USER CODE END PV */ - -/* Private function prototypes -----------------------------------------------*/ -/* USER CODE BEGIN PFP */ - -/* USER CODE END PFP */ - -/* External functions --------------------------------------------------------*/ -/* USER CODE BEGIN ExternalFunctions */ - -/* USER CODE END ExternalFunctions */ - -/* USER CODE BEGIN 0 */ - -/* USER CODE END 0 */ -/** - * Initializes the Global MSP. - */ -void HAL_MspInit(void) { - /* USER CODE BEGIN MspInit 0 */ - - /* USER CODE END MspInit 0 */ - - __HAL_RCC_HSEM_CLK_ENABLE(); - - /* System interrupt init*/ - /* PendSV_IRQn interrupt configuration */ - HAL_NVIC_SetPriority(PendSV_IRQn, 15, 0); - - /* Peripheral interrupt init */ - /* RCC_IRQn interrupt configuration */ - HAL_NVIC_SetPriority(RCC_IRQn, 5, 0); - HAL_NVIC_EnableIRQ(RCC_IRQn); - /* HSEM_IRQn interrupt configuration */ - HAL_NVIC_SetPriority(HSEM_IRQn, 5, 0); - HAL_NVIC_EnableIRQ(HSEM_IRQn); - - /* USER CODE BEGIN MspInit 1 */ - - /* USER CODE END MspInit 1 */ -} - -/* USER CODE BEGIN 1 */ - -/* USER CODE END 1 */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/firmware/targets/f7/cube/Src/stm32wbxx_it.c b/firmware/targets/f7/cube/Src/stm32wbxx_it.c deleted file mode 100644 index 57f420fbadc..00000000000 --- a/firmware/targets/f7/cube/Src/stm32wbxx_it.c +++ /dev/null @@ -1,304 +0,0 @@ -/* USER CODE BEGIN Header */ -/** - ****************************************************************************** - * @file stm32wbxx_it.c - * @brief Interrupt Service Routines. - ****************************************************************************** - * @attention - * - *

© Copyright (c) 2021 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ -/* USER CODE END Header */ - -/* Includes ------------------------------------------------------------------*/ -#include "main.h" -#include "stm32wbxx_it.h" -#include "FreeRTOS.h" -#include "task.h" -/* Private includes ----------------------------------------------------------*/ -/* USER CODE BEGIN Includes */ -/* USER CODE END Includes */ - -/* Private typedef -----------------------------------------------------------*/ -/* USER CODE BEGIN TD */ - -/* USER CODE END TD */ - -/* Private define ------------------------------------------------------------*/ -/* USER CODE BEGIN PD */ - -/* USER CODE END PD */ - -/* Private macro -------------------------------------------------------------*/ -/* USER CODE BEGIN PM */ - -/* USER CODE END PM */ - -/* Private variables ---------------------------------------------------------*/ -/* USER CODE BEGIN PV */ - -/* USER CODE END PV */ - -/* Private function prototypes -----------------------------------------------*/ -/* USER CODE BEGIN PFP */ - -/* USER CODE END PFP */ - -/* Private user code ---------------------------------------------------------*/ -/* USER CODE BEGIN 0 */ - -/* USER CODE END 0 */ - -/* External variables --------------------------------------------------------*/ -extern PCD_HandleTypeDef hpcd_USB_FS; -extern ADC_HandleTypeDef hadc1; -extern COMP_HandleTypeDef hcomp1; -extern RTC_HandleTypeDef hrtc; -extern TIM_HandleTypeDef htim1; -extern TIM_HandleTypeDef htim2; -/* USER CODE BEGIN EV */ - -/* USER CODE END EV */ - -/******************************************************************************/ -/* Cortex Processor Interruption and Exception Handlers */ -/******************************************************************************/ -/** - * @brief This function handles Non maskable interrupt. - */ -void NMI_Handler(void) { - /* USER CODE BEGIN NonMaskableInt_IRQn 0 */ - - /* USER CODE END NonMaskableInt_IRQn 0 */ - /* USER CODE BEGIN NonMaskableInt_IRQn 1 */ - while(1) { - } - /* USER CODE END NonMaskableInt_IRQn 1 */ -} - -/** - * @brief This function handles Hard fault interrupt. - */ -void HardFault_Handler(void) { - /* USER CODE BEGIN HardFault_IRQn 0 */ - - /* USER CODE END HardFault_IRQn 0 */ - while(1) { - /* USER CODE BEGIN W1_HardFault_IRQn 0 */ - /* USER CODE END W1_HardFault_IRQn 0 */ - } -} - -/** - * @brief This function handles Memory management fault. - */ -void MemManage_Handler(void) { - /* USER CODE BEGIN MemoryManagement_IRQn 0 */ - - /* USER CODE END MemoryManagement_IRQn 0 */ - while(1) { - /* USER CODE BEGIN W1_MemoryManagement_IRQn 0 */ - /* USER CODE END W1_MemoryManagement_IRQn 0 */ - } -} - -/** - * @brief This function handles Prefetch fault, memory access fault. - */ -void BusFault_Handler(void) { - /* USER CODE BEGIN BusFault_IRQn 0 */ - - /* USER CODE END BusFault_IRQn 0 */ - while(1) { - /* USER CODE BEGIN W1_BusFault_IRQn 0 */ - /* USER CODE END W1_BusFault_IRQn 0 */ - } -} - -/** - * @brief This function handles Undefined instruction or illegal state. - */ -void UsageFault_Handler(void) { - /* USER CODE BEGIN UsageFault_IRQn 0 */ - - /* USER CODE END UsageFault_IRQn 0 */ - while(1) { - /* USER CODE BEGIN W1_UsageFault_IRQn 0 */ - /* USER CODE END W1_UsageFault_IRQn 0 */ - } -} - -/** - * @brief This function handles Debug monitor. - */ -void DebugMon_Handler(void) { - /* USER CODE BEGIN DebugMonitor_IRQn 0 */ - - /* USER CODE END DebugMonitor_IRQn 0 */ - /* USER CODE BEGIN DebugMonitor_IRQn 1 */ - - /* USER CODE END DebugMonitor_IRQn 1 */ -} - -/** - * @brief This function handles System tick timer. - */ -void SysTick_Handler(void) { - /* USER CODE BEGIN SysTick_IRQn 0 */ - - /* USER CODE END SysTick_IRQn 0 */ - /* USER CODE BEGIN SysTick_IRQn 1 */ - - /* USER CODE END SysTick_IRQn 1 */ -} - -/******************************************************************************/ -/* STM32WBxx Peripheral Interrupt Handlers */ -/* Add here the Interrupt Handlers for the used peripherals. */ -/* For the available peripheral interrupt handler names, */ -/* please refer to the startup file (startup_stm32wbxx.s). */ -/******************************************************************************/ - -/** - * @brief This function handles RTC tamper and time stamp, CSS on LSE interrupts through EXTI line 18. - */ -void TAMP_STAMP_LSECSS_IRQHandler(void) { - /* USER CODE BEGIN TAMP_STAMP_LSECSS_IRQn 0 */ - - /* USER CODE END TAMP_STAMP_LSECSS_IRQn 0 */ - /* USER CODE BEGIN TAMP_STAMP_LSECSS_IRQn 1 */ - - /* USER CODE END TAMP_STAMP_LSECSS_IRQn 1 */ -} - -/** - * @brief This function handles RCC global interrupt. - */ -void RCC_IRQHandler(void) { - /* USER CODE BEGIN RCC_IRQn 0 */ - - /* USER CODE END RCC_IRQn 0 */ - /* USER CODE BEGIN RCC_IRQn 1 */ - - /* USER CODE END RCC_IRQn 1 */ -} - -/** - * @brief This function handles EXTI line3 interrupt. - */ -void EXTI3_IRQHandler(void) { - /* USER CODE BEGIN EXTI3_IRQn 0 */ - - /* USER CODE END EXTI3_IRQn 0 */ - HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_3); - /* USER CODE BEGIN EXTI3_IRQn 1 */ - - /* USER CODE END EXTI3_IRQn 1 */ -} - -/** - * @brief This function handles ADC1 global interrupt. - */ -void ADC1_IRQHandler(void) { - /* USER CODE BEGIN ADC1_IRQn 0 */ - - /* USER CODE END ADC1_IRQn 0 */ - HAL_ADC_IRQHandler(&hadc1); - /* USER CODE BEGIN ADC1_IRQn 1 */ - - /* USER CODE END ADC1_IRQn 1 */ -} - -/** - * @brief This function handles USB low priority interrupt, USB wake-up interrupt through EXTI line 28. - */ -void USB_LP_IRQHandler(void) { - /* USER CODE BEGIN USB_LP_IRQn 0 */ - - /* USER CODE END USB_LP_IRQn 0 */ - HAL_PCD_IRQHandler(&hpcd_USB_FS); - /* USER CODE BEGIN USB_LP_IRQn 1 */ - - /* USER CODE END USB_LP_IRQn 1 */ -} - -/** - * @brief This function handles COMP1 and COMP2 interrupts through EXTI lines 20 and 21. - */ -void COMP_IRQHandler(void) { - /* USER CODE BEGIN COMP_IRQn 0 */ - - /* USER CODE END COMP_IRQn 0 */ - HAL_COMP_IRQHandler(&hcomp1); - /* USER CODE BEGIN COMP_IRQn 1 */ - - /* USER CODE END COMP_IRQn 1 */ -} - -/** - * @brief This function handles TIM1 trigger and commutation interrupts and TIM17 global interrupt. - */ -void TIM1_TRG_COM_TIM17_IRQHandler(void) { - /* USER CODE BEGIN TIM1_TRG_COM_TIM17_IRQn 0 */ - - /* USER CODE END TIM1_TRG_COM_TIM17_IRQn 0 */ - HAL_TIM_IRQHandler(&htim1); - /* USER CODE BEGIN TIM1_TRG_COM_TIM17_IRQn 1 */ - - /* USER CODE END TIM1_TRG_COM_TIM17_IRQn 1 */ -} - -/** - * @brief This function handles TIM2 global interrupt. - */ -void TIM2_IRQHandler(void) { - /* USER CODE BEGIN TIM2_IRQn 0 */ - - /* USER CODE END TIM2_IRQn 0 */ - HAL_TIM_IRQHandler(&htim2); - /* USER CODE BEGIN TIM2_IRQn 1 */ - - /* USER CODE END TIM2_IRQn 1 */ -} - -/** - * @brief This function handles EXTI line[15:10] interrupts. - */ -void EXTI15_10_IRQHandler(void) { - /* USER CODE BEGIN EXTI15_10_IRQn 0 */ - - /* USER CODE END EXTI15_10_IRQn 0 */ - HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_10); - HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_11); - HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_12); - HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_13); - /* USER CODE BEGIN EXTI15_10_IRQn 1 */ - - /* USER CODE END EXTI15_10_IRQn 1 */ -} - -/** - * @brief This function handles HSEM global interrupt. - */ -void HSEM_IRQHandler(void) { - /* USER CODE BEGIN HSEM_IRQn 0 */ - - /* USER CODE END HSEM_IRQn 0 */ - HAL_HSEM_IRQHandler(); - /* USER CODE BEGIN HSEM_IRQn 1 */ - - /* USER CODE END HSEM_IRQn 1 */ -} - -/* USER CODE BEGIN 1 */ - -/* USER CODE END 1 */ -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/firmware/targets/f7/cube/Src/system_stm32wbxx.c b/firmware/targets/f7/cube/Src/system_stm32wbxx.c deleted file mode 100644 index ff09f34ce64..00000000000 --- a/firmware/targets/f7/cube/Src/system_stm32wbxx.c +++ /dev/null @@ -1,384 +0,0 @@ -/** - ****************************************************************************** - * @file system_stm32wbxx.c - * @author MCD Application Team - * @brief CMSIS Cortex Device Peripheral Access Layer System Source File - * - * This file provides two functions and one global variable to be called from - * user application: - * - SystemInit(): This function is called at startup just after reset and - * before branch to main program. This call is made inside - * the "startup_stm32wbxx.s" file. - * - * - SystemCoreClock variable: Contains the core clock (HCLK), it can be used - * by the user application to setup the SysTick - * timer or configure other parameters. - * - * - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must - * be called whenever the core clock is changed - * during program execution. - * - * After each device reset the MSI (4 MHz) is used as system clock source. - * Then SystemInit() function is called, in "startup_stm32wbxx.s" file, to - * configure the system clock before to branch to main program. - * - * This file configures the system clock as follows: - *============================================================================= - *----------------------------------------------------------------------------- - * System Clock source | MSI - *----------------------------------------------------------------------------- - * SYSCLK(Hz) | 4000000 - *----------------------------------------------------------------------------- - * HCLK(Hz) | 4000000 - *----------------------------------------------------------------------------- - * AHB Prescaler | 1 - *----------------------------------------------------------------------------- - * APB1 Prescaler | 1 - *----------------------------------------------------------------------------- - * APB2 Prescaler | 1 - *----------------------------------------------------------------------------- - * PLL_M | 1 - *----------------------------------------------------------------------------- - * PLL_N | 8 - *----------------------------------------------------------------------------- - * PLL_P | 7 - *----------------------------------------------------------------------------- - * PLL_Q | 2 - *----------------------------------------------------------------------------- - * PLL_R | 2 - *----------------------------------------------------------------------------- - * PLLSAI1_P | NA - *----------------------------------------------------------------------------- - * PLLSAI1_Q | NA - *----------------------------------------------------------------------------- - * PLLSAI1_R | NA - *----------------------------------------------------------------------------- - * Require 48MHz for USB OTG FS, | Disabled - * SDIO and RNG clock | - *----------------------------------------------------------------------------- - *============================================================================= - ****************************************************************************** - * @attention - * - * Copyright (c) 2019-2021 STMicroelectronics. - * All rights reserved. - * - * This software is licensed under terms that can be found in the LICENSE file - * in the root directory of this software component. - * If no LICENSE file comes with this software, it is provided AS-IS. - * - ****************************************************************************** - */ - -/** @addtogroup CMSIS - * @{ - */ - -/** @addtogroup stm32WBxx_system - * @{ - */ - -/** @addtogroup stm32WBxx_System_Private_Includes - * @{ - */ - -#include "stm32wbxx.h" - -#if !defined(HSE_VALUE) -#define HSE_VALUE (32000000UL) /*!< Value of the External oscillator in Hz */ -#endif /* HSE_VALUE */ - -#if !defined(MSI_VALUE) -#define MSI_VALUE (4000000UL) /*!< Value of the Internal oscillator in Hz*/ -#endif /* MSI_VALUE */ - -#if !defined(HSI_VALUE) -#define HSI_VALUE (16000000UL) /*!< Value of the Internal oscillator in Hz*/ -#endif /* HSI_VALUE */ - -#if !defined(LSI_VALUE) -#define LSI_VALUE (32000UL) /*!< Value of LSI in Hz*/ -#endif /* LSI_VALUE */ - -#if !defined(LSE_VALUE) -#define LSE_VALUE (32768UL) /*!< Value of LSE in Hz*/ -#endif /* LSE_VALUE */ - -/** - * @} - */ - -/** @addtogroup STM32WBxx_System_Private_TypesDefinitions - * @{ - */ - -/** - * @} - */ - -/** @addtogroup STM32WBxx_System_Private_Defines - * @{ - */ - -/* Note: Following vector table addresses must be defined in line with linker - configuration. */ -/*!< Uncomment the following line if you need to relocate CPU1 CM4 and/or CPU2 - CM0+ vector table anywhere in Sram or Flash. Else vector table will be kept - at address 0x00 which correspond to automatic remap of boot address selected */ -/* #define USER_VECT_TAB_ADDRESS */ -#if defined(USER_VECT_TAB_ADDRESS) -/*!< Uncomment this line for user vector table remap in Sram else user remap - will be done in Flash. */ -/* #define VECT_TAB_SRAM */ -#if defined(VECT_TAB_SRAM) -#define VECT_TAB_BASE_ADDRESS \ - SRAM1_BASE /*!< Vector Table base address field. - This value must be a multiple of 0x200. */ -#define VECT_TAB_OFFSET \ - 0x00000000U /*!< Vector Table base offset field. - This value must be a multiple of 0x200. */ -#else -#define VECT_TAB_BASE_ADDRESS \ - FLASH_BASE /*!< Vector Table base address field. - This value must be a multiple of 0x200. */ -#define VECT_TAB_OFFSET \ - 0x00000000U /*!< Vector Table base offset field. - This value must be a multiple of 0x200. */ -#endif -#endif - -/** - * @} - */ - -/** @addtogroup STM32WBxx_System_Private_Macros - * @{ - */ - -/** - * @} - */ - -/** @addtogroup STM32WBxx_System_Private_Variables - * @{ - */ -/* The SystemCoreClock variable is updated in three ways: - 1) by calling CMSIS function SystemCoreClockUpdate() - 2) by calling HAL API function HAL_RCC_GetHCLKFreq() - 3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency - Note: If you use this function to configure the system clock; then there - is no need to call the 2 first functions listed above, since SystemCoreClock - variable is updated automatically. - */ -uint32_t SystemCoreClock = 4000000UL; /*CPU1: M4 on MSI clock after startup (4MHz)*/ - -const uint32_t AHBPrescTable[16UL] = - {1UL, 3UL, 5UL, 1UL, 1UL, 6UL, 10UL, 32UL, 2UL, 4UL, 8UL, 16UL, 64UL, 128UL, 256UL, 512UL}; - -const uint32_t APBPrescTable[8UL] = {0UL, 0UL, 0UL, 0UL, 1UL, 2UL, 3UL, 4UL}; - -const uint32_t MSIRangeTable[16UL] = { - 100000UL, - 200000UL, - 400000UL, - 800000UL, - 1000000UL, - 2000000UL, - 4000000UL, - 8000000UL, - 16000000UL, - 24000000UL, - 32000000UL, - 48000000UL, - 0UL, - 0UL, - 0UL, - 0UL}; /* 0UL values are incorrect cases */ - -#if defined(STM32WB55xx) || defined(STM32WB5Mxx) || defined(STM32WB35xx) || \ - defined(STM32WB15xx) || defined(STM32WB10xx) -const uint32_t SmpsPrescalerTable[4UL][6UL] = { - {1UL, 3UL, 2UL, 2UL, 1UL, 2UL}, - {2UL, 6UL, 4UL, 3UL, 2UL, 4UL}, - {4UL, 12UL, 8UL, 6UL, 4UL, 8UL}, - {4UL, 12UL, 8UL, 6UL, 4UL, 8UL}}; -#endif - -/** - * @} - */ - -/** @addtogroup STM32WBxx_System_Private_FunctionPrototypes - * @{ - */ - -/** - * @} - */ - -/** @addtogroup STM32WBxx_System_Private_Functions - * @{ - */ - -/** - * @brief Setup the microcontroller system. - * @param None - * @retval None - */ -void SystemInit(void) { -#if defined(USER_VECT_TAB_ADDRESS) - /* Configure the Vector Table location add offset address ------------------*/ - SCB->VTOR = VECT_TAB_BASE_ADDRESS | VECT_TAB_OFFSET; -#endif - -/* FPU settings ------------------------------------------------------------*/ -#if(__FPU_PRESENT == 1) && (__FPU_USED == 1) - SCB->CPACR |= - ((3UL << (10UL * 2UL)) | (3UL << (11UL * 2UL))); /* set CP10 and CP11 Full Access */ -#endif - - /* Reset the RCC clock configuration to the default reset state ------------*/ - /* Set MSION bit */ - RCC->CR |= RCC_CR_MSION; - - /* Reset CFGR register */ - RCC->CFGR = 0x00070000U; - - /* Reset PLLSAI1ON, PLLON, HSECSSON, HSEON, HSION, and MSIPLLON bits */ - RCC->CR &= (uint32_t)0xFAF6FEFBU; - - /*!< Reset LSI1 and LSI2 bits */ - RCC->CSR &= (uint32_t)0xFFFFFFFAU; - - /*!< Reset HSI48ON bit */ - RCC->CRRCR &= (uint32_t)0xFFFFFFFEU; - - /* Reset PLLCFGR register */ - RCC->PLLCFGR = 0x22041000U; - -#if defined(STM32WB55xx) || defined(STM32WB5Mxx) - /* Reset PLLSAI1CFGR register */ - RCC->PLLSAI1CFGR = 0x22041000U; -#endif - - /* Reset HSEBYP bit */ - RCC->CR &= 0xFFFBFFFFU; - - /* Disable all interrupts */ - RCC->CIER = 0x00000000; -} - -/** - * @brief Update SystemCoreClock variable according to Clock Register Values. - * The SystemCoreClock variable contains the core clock (HCLK), it can - * be used by the user application to setup the SysTick timer or configure - * other parameters. - * - * @note Each time the core clock (HCLK) changes, this function must be called - * to update SystemCoreClock variable value. Otherwise, any configuration - * based on this variable will be incorrect. - * - * @note - The system frequency computed by this function is not the real - * frequency in the chip. It is calculated based on the predefined - * constant and the selected clock source: - * - * - If SYSCLK source is MSI, SystemCoreClock will contain the MSI_VALUE(*) - * - * - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(**) - * - * - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(***) - * - * - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(***) - * or HSI_VALUE(*) or MSI_VALUE(*) multiplied/divided by the PLL factors. - * - * (*) MSI_VALUE is a constant defined in stm32wbxx_hal.h file (default value - * 4 MHz) but the real value may vary depending on the variations - * in voltage and temperature. - * - * (**) HSI_VALUE is a constant defined in stm32wbxx_hal_conf.h file (default value - * 16 MHz) but the real value may vary depending on the variations - * in voltage and temperature. - * - * (***) HSE_VALUE is a constant defined in stm32wbxx_hal_conf.h file (default value - * 32 MHz), user has to ensure that HSE_VALUE is same as the real - * frequency of the crystal used. Otherwise, this function may - * have wrong result. - * - * - The result of this function could be not correct when using fractional - * value for HSE crystal. - * - * @param None - * @retval None - */ -void SystemCoreClockUpdate(void) { - uint32_t tmp, msirange, pllvco, pllr, pllsource, pllm; - - /* Get MSI Range frequency--------------------------------------------------*/ - - /*MSI frequency range in Hz*/ - msirange = MSIRangeTable[(RCC->CR & RCC_CR_MSIRANGE) >> RCC_CR_MSIRANGE_Pos]; - - /* Get SYSCLK source -------------------------------------------------------*/ - switch(RCC->CFGR & RCC_CFGR_SWS) { - case 0x00: /* MSI used as system clock source */ - SystemCoreClock = msirange; - break; - - case 0x04: /* HSI used as system clock source */ - /* HSI used as system clock source */ - SystemCoreClock = HSI_VALUE; - break; - - case 0x08: /* HSE used as system clock source */ - SystemCoreClock = HSE_VALUE; - break; - - case 0x0C: /* PLL used as system clock source */ - /* PLL_VCO = (HSE_VALUE or HSI_VALUE or MSI_VALUE/ PLLM) * PLLN - SYSCLK = PLL_VCO / PLLR - */ - pllsource = (RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC); - pllm = ((RCC->PLLCFGR & RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1UL; - - if(pllsource == 0x02UL) /* HSI used as PLL clock source */ - { - pllvco = (HSI_VALUE / pllm); - } else if(pllsource == 0x03UL) /* HSE used as PLL clock source */ - { - pllvco = (HSE_VALUE / pllm); - } else /* MSI used as PLL clock source */ - { - pllvco = (msirange / pllm); - } - - pllvco = pllvco * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos); - pllr = (((RCC->PLLCFGR & RCC_PLLCFGR_PLLR) >> RCC_PLLCFGR_PLLR_Pos) + 1UL); - - SystemCoreClock = pllvco / pllr; - break; - - default: - SystemCoreClock = msirange; - break; - } - - /* Compute HCLK clock frequency --------------------------------------------*/ - /* Get HCLK1 prescaler */ - tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> RCC_CFGR_HPRE_Pos)]; - /* HCLK clock frequency */ - SystemCoreClock = SystemCoreClock / tmp; -} - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/firmware/targets/f7/cube/Src/tim.c b/firmware/targets/f7/cube/Src/tim.c deleted file mode 100644 index 1182d420328..00000000000 --- a/firmware/targets/f7/cube/Src/tim.c +++ /dev/null @@ -1,347 +0,0 @@ -/** - ****************************************************************************** - * @file tim.c - * @brief This file provides code for the configuration - * of the TIM instances. - ****************************************************************************** - * @attention - * - *

© Copyright (c) 2021 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "tim.h" - -/* USER CODE BEGIN 0 */ - -/* USER CODE END 0 */ - -TIM_HandleTypeDef htim1; -TIM_HandleTypeDef htim2; -TIM_HandleTypeDef htim16; - -/* TIM1 init function */ -void MX_TIM1_Init(void) { - /* USER CODE BEGIN TIM1_Init 0 */ - - /* USER CODE END TIM1_Init 0 */ - - TIM_ClockConfigTypeDef sClockSourceConfig = {0}; - TIM_MasterConfigTypeDef sMasterConfig = {0}; - TIM_OC_InitTypeDef sConfigOC = {0}; - TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig = {0}; - - /* USER CODE BEGIN TIM1_Init 1 */ - - /* USER CODE END TIM1_Init 1 */ - htim1.Instance = TIM1; - htim1.Init.Prescaler = 0; - htim1.Init.CounterMode = TIM_COUNTERMODE_UP; - htim1.Init.Period = 65535; - htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; - htim1.Init.RepetitionCounter = 0; - htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; - if(HAL_TIM_Base_Init(&htim1) != HAL_OK) { - Error_Handler(); - } - sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL; - if(HAL_TIM_ConfigClockSource(&htim1, &sClockSourceConfig) != HAL_OK) { - Error_Handler(); - } - if(HAL_TIM_OC_Init(&htim1) != HAL_OK) { - Error_Handler(); - } - if(HAL_TIM_PWM_Init(&htim1) != HAL_OK) { - Error_Handler(); - } - sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; - sMasterConfig.MasterOutputTrigger2 = TIM_TRGO2_RESET; - sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; - if(HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK) { - Error_Handler(); - } - sConfigOC.OCMode = TIM_OCMODE_TIMING; - sConfigOC.Pulse = 0; - sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH; - sConfigOC.OCNPolarity = TIM_OCNPOLARITY_HIGH; - sConfigOC.OCFastMode = TIM_OCFAST_DISABLE; - sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET; - sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET; - if(HAL_TIM_OC_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_1) != HAL_OK) { - Error_Handler(); - } - sConfigOC.OCMode = TIM_OCMODE_PWM1; - if(HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_3) != HAL_OK) { - Error_Handler(); - } - sBreakDeadTimeConfig.OffStateRunMode = TIM_OSSR_DISABLE; - sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_DISABLE; - sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_OFF; - sBreakDeadTimeConfig.DeadTime = 0; - sBreakDeadTimeConfig.BreakState = TIM_BREAK_DISABLE; - sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_HIGH; - sBreakDeadTimeConfig.BreakFilter = 0; - sBreakDeadTimeConfig.BreakAFMode = TIM_BREAK_AFMODE_INPUT; - sBreakDeadTimeConfig.Break2State = TIM_BREAK2_DISABLE; - sBreakDeadTimeConfig.Break2Polarity = TIM_BREAK2POLARITY_HIGH; - sBreakDeadTimeConfig.Break2Filter = 0; - sBreakDeadTimeConfig.Break2AFMode = TIM_BREAK_AFMODE_INPUT; - sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_DISABLE; - if(HAL_TIMEx_ConfigBreakDeadTime(&htim1, &sBreakDeadTimeConfig) != HAL_OK) { - Error_Handler(); - } - /* USER CODE BEGIN TIM1_Init 2 */ - - /* USER CODE END TIM1_Init 2 */ - HAL_TIM_MspPostInit(&htim1); -} -/* TIM2 init function */ -void MX_TIM2_Init(void) { - /* USER CODE BEGIN TIM2_Init 0 */ - - /* USER CODE END TIM2_Init 0 */ - - TIM_ClockConfigTypeDef sClockSourceConfig = {0}; - TIM_MasterConfigTypeDef sMasterConfig = {0}; - TIM_IC_InitTypeDef sConfigIC = {0}; - - /* USER CODE BEGIN TIM2_Init 1 */ - - /* USER CODE END TIM2_Init 1 */ - htim2.Instance = TIM2; - htim2.Init.Prescaler = 64 - 1; - htim2.Init.CounterMode = TIM_COUNTERMODE_UP; - htim2.Init.Period = 4294967295; - htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; - htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE; - if(HAL_TIM_Base_Init(&htim2) != HAL_OK) { - Error_Handler(); - } - sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL; - if(HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK) { - Error_Handler(); - } - if(HAL_TIM_IC_Init(&htim2) != HAL_OK) { - Error_Handler(); - } - sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; - sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; - if(HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK) { - Error_Handler(); - } - sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_FALLING; - sConfigIC.ICSelection = TIM_ICSELECTION_DIRECTTI; - sConfigIC.ICPrescaler = TIM_ICPSC_DIV1; - sConfigIC.ICFilter = 0; - if(HAL_TIM_IC_ConfigChannel(&htim2, &sConfigIC, TIM_CHANNEL_1) != HAL_OK) { - Error_Handler(); - } - sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_RISING; - sConfigIC.ICSelection = TIM_ICSELECTION_INDIRECTTI; - if(HAL_TIM_IC_ConfigChannel(&htim2, &sConfigIC, TIM_CHANNEL_2) != HAL_OK) { - Error_Handler(); - } - /* USER CODE BEGIN TIM2_Init 2 */ - - /* USER CODE END TIM2_Init 2 */ -} -/* TIM16 init function */ -void MX_TIM16_Init(void) { - /* USER CODE BEGIN TIM16_Init 0 */ - - /* USER CODE END TIM16_Init 0 */ - - TIM_OC_InitTypeDef sConfigOC = {0}; - TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig = {0}; - - /* USER CODE BEGIN TIM16_Init 1 */ - - /* USER CODE END TIM16_Init 1 */ - htim16.Instance = TIM16; - htim16.Init.Prescaler = 500 - 1; - htim16.Init.CounterMode = TIM_COUNTERMODE_UP; - htim16.Init.Period = 291; - htim16.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; - htim16.Init.RepetitionCounter = 0; - htim16.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; - if(HAL_TIM_Base_Init(&htim16) != HAL_OK) { - Error_Handler(); - } - if(HAL_TIM_PWM_Init(&htim16) != HAL_OK) { - Error_Handler(); - } - sConfigOC.OCMode = TIM_OCMODE_PWM1; - sConfigOC.Pulse = 145; - sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH; - sConfigOC.OCNPolarity = TIM_OCNPOLARITY_HIGH; - sConfigOC.OCFastMode = TIM_OCFAST_DISABLE; - sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET; - sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET; - if(HAL_TIM_PWM_ConfigChannel(&htim16, &sConfigOC, TIM_CHANNEL_1) != HAL_OK) { - Error_Handler(); - } - sBreakDeadTimeConfig.OffStateRunMode = TIM_OSSR_DISABLE; - sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_DISABLE; - sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_OFF; - sBreakDeadTimeConfig.DeadTime = 0; - sBreakDeadTimeConfig.BreakState = TIM_BREAK_DISABLE; - sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_HIGH; - sBreakDeadTimeConfig.BreakFilter = 0; - sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_DISABLE; - if(HAL_TIMEx_ConfigBreakDeadTime(&htim16, &sBreakDeadTimeConfig) != HAL_OK) { - Error_Handler(); - } - /* USER CODE BEGIN TIM16_Init 2 */ - - /* USER CODE END TIM16_Init 2 */ - HAL_TIM_MspPostInit(&htim16); -} - -void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* tim_baseHandle) { - GPIO_InitTypeDef GPIO_InitStruct = {0}; - if(tim_baseHandle->Instance == TIM1) { - /* USER CODE BEGIN TIM1_MspInit 0 */ - - /* USER CODE END TIM1_MspInit 0 */ - /* TIM1 clock enable */ - __HAL_RCC_TIM1_CLK_ENABLE(); - - /* TIM1 interrupt Init */ - HAL_NVIC_SetPriority(TIM1_TRG_COM_TIM17_IRQn, 5, 0); - HAL_NVIC_EnableIRQ(TIM1_TRG_COM_TIM17_IRQn); - /* USER CODE BEGIN TIM1_MspInit 1 */ - - /* USER CODE END TIM1_MspInit 1 */ - } else if(tim_baseHandle->Instance == TIM2) { - /* USER CODE BEGIN TIM2_MspInit 0 */ - - /* USER CODE END TIM2_MspInit 0 */ - /* TIM2 clock enable */ - __HAL_RCC_TIM2_CLK_ENABLE(); - - __HAL_RCC_GPIOA_CLK_ENABLE(); - /**TIM2 GPIO Configuration - PA0 ------> TIM2_CH1 - */ - GPIO_InitStruct.Pin = IR_RX_Pin; - GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; - GPIO_InitStruct.Pull = GPIO_NOPULL; - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; - GPIO_InitStruct.Alternate = GPIO_AF1_TIM2; - HAL_GPIO_Init(IR_RX_GPIO_Port, &GPIO_InitStruct); - - /* TIM2 interrupt Init */ - HAL_NVIC_SetPriority(TIM2_IRQn, 5, 0); - HAL_NVIC_EnableIRQ(TIM2_IRQn); - /* USER CODE BEGIN TIM2_MspInit 1 */ - - /* USER CODE END TIM2_MspInit 1 */ - } else if(tim_baseHandle->Instance == TIM16) { - /* USER CODE BEGIN TIM16_MspInit 0 */ - - /* USER CODE END TIM16_MspInit 0 */ - /* TIM16 clock enable */ - __HAL_RCC_TIM16_CLK_ENABLE(); - /* USER CODE BEGIN TIM16_MspInit 1 */ - - /* USER CODE END TIM16_MspInit 1 */ - } -} -void HAL_TIM_MspPostInit(TIM_HandleTypeDef* timHandle) { - GPIO_InitTypeDef GPIO_InitStruct = {0}; - if(timHandle->Instance == TIM1) { - /* USER CODE BEGIN TIM1_MspPostInit 0 */ - - /* USER CODE END TIM1_MspPostInit 0 */ - __HAL_RCC_GPIOB_CLK_ENABLE(); - /**TIM1 GPIO Configuration - PB9 ------> TIM1_CH3N - PB13 ------> TIM1_CH1N - */ - GPIO_InitStruct.Pin = IR_TX_Pin | RFID_OUT_Pin; - GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; - GPIO_InitStruct.Pull = GPIO_NOPULL; - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; - GPIO_InitStruct.Alternate = GPIO_AF1_TIM1; - HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); - - /* USER CODE BEGIN TIM1_MspPostInit 1 */ - - /* USER CODE END TIM1_MspPostInit 1 */ - } else if(timHandle->Instance == TIM16) { - /* USER CODE BEGIN TIM16_MspPostInit 0 */ - - /* USER CODE END TIM16_MspPostInit 0 */ - - __HAL_RCC_GPIOB_CLK_ENABLE(); - /**TIM16 GPIO Configuration - PB8 ------> TIM16_CH1 - */ - GPIO_InitStruct.Pin = SPEAKER_Pin; - GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; - GPIO_InitStruct.Pull = GPIO_NOPULL; - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; - GPIO_InitStruct.Alternate = GPIO_AF14_TIM16; - HAL_GPIO_Init(SPEAKER_GPIO_Port, &GPIO_InitStruct); - - /* USER CODE BEGIN TIM16_MspPostInit 1 */ - - /* USER CODE END TIM16_MspPostInit 1 */ - } -} - -void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef* tim_baseHandle) { - if(tim_baseHandle->Instance == TIM1) { - /* USER CODE BEGIN TIM1_MspDeInit 0 */ - - /* USER CODE END TIM1_MspDeInit 0 */ - /* Peripheral clock disable */ - __HAL_RCC_TIM1_CLK_DISABLE(); - - /* TIM1 interrupt Deinit */ - HAL_NVIC_DisableIRQ(TIM1_TRG_COM_TIM17_IRQn); - /* USER CODE BEGIN TIM1_MspDeInit 1 */ - - /* USER CODE END TIM1_MspDeInit 1 */ - } else if(tim_baseHandle->Instance == TIM2) { - /* USER CODE BEGIN TIM2_MspDeInit 0 */ - - /* USER CODE END TIM2_MspDeInit 0 */ - /* Peripheral clock disable */ - __HAL_RCC_TIM2_CLK_DISABLE(); - - /**TIM2 GPIO Configuration - PA0 ------> TIM2_CH1 - */ - HAL_GPIO_DeInit(IR_RX_GPIO_Port, IR_RX_Pin); - - /* TIM2 interrupt Deinit */ - HAL_NVIC_DisableIRQ(TIM2_IRQn); - /* USER CODE BEGIN TIM2_MspDeInit 1 */ - - /* USER CODE END TIM2_MspDeInit 1 */ - } else if(tim_baseHandle->Instance == TIM16) { - /* USER CODE BEGIN TIM16_MspDeInit 0 */ - - /* USER CODE END TIM16_MspDeInit 0 */ - /* Peripheral clock disable */ - __HAL_RCC_TIM16_CLK_DISABLE(); - /* USER CODE BEGIN TIM16_MspDeInit 1 */ - - /* USER CODE END TIM16_MspDeInit 1 */ - } -} - -/* USER CODE BEGIN 1 */ - -/* USER CODE END 1 */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/firmware/targets/f7/cube/Src/usart.c b/firmware/targets/f7/cube/Src/usart.c deleted file mode 100644 index c0b3eceeddd..00000000000 --- a/firmware/targets/f7/cube/Src/usart.c +++ /dev/null @@ -1,91 +0,0 @@ -/** - ****************************************************************************** - * @file usart.c - * @brief This file provides code for the configuration - * of the USART instances. - ****************************************************************************** - * @attention - * - *

© Copyright (c) 2021 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "usart.h" - -/* USER CODE BEGIN 0 */ - -/* USER CODE END 0 */ - -/* USART1 init function */ - -void MX_USART1_UART_Init(void) { - /* USER CODE BEGIN USART1_Init 0 */ - - /* USER CODE END USART1_Init 0 */ - - LL_USART_InitTypeDef USART_InitStruct = {0}; - - LL_GPIO_InitTypeDef GPIO_InitStruct = {0}; - - /* Peripheral clock enable */ - LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_USART1); - - LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOB); - /**USART1 GPIO Configuration - PB6 ------> USART1_TX - PB7 ------> USART1_RX - */ - GPIO_InitStruct.Pin = LL_GPIO_PIN_6 | LL_GPIO_PIN_7; - GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; - GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW; - GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; - GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; - GPIO_InitStruct.Alternate = LL_GPIO_AF_7; - LL_GPIO_Init(GPIOB, &GPIO_InitStruct); - - /* USER CODE BEGIN USART1_Init 1 */ - - /* USER CODE END USART1_Init 1 */ - USART_InitStruct.PrescalerValue = LL_USART_PRESCALER_DIV1; - USART_InitStruct.BaudRate = 115200; - USART_InitStruct.DataWidth = LL_USART_DATAWIDTH_8B; - USART_InitStruct.StopBits = LL_USART_STOPBITS_1; - USART_InitStruct.Parity = LL_USART_PARITY_NONE; - USART_InitStruct.TransferDirection = LL_USART_DIRECTION_TX; - USART_InitStruct.HardwareFlowControl = LL_USART_HWCONTROL_NONE; - USART_InitStruct.OverSampling = LL_USART_OVERSAMPLING_16; - LL_USART_Init(USART1, &USART_InitStruct); - LL_USART_SetTXFIFOThreshold(USART1, LL_USART_FIFOTHRESHOLD_1_8); - LL_USART_SetRXFIFOThreshold(USART1, LL_USART_FIFOTHRESHOLD_1_8); - LL_USART_DisableFIFO(USART1); - LL_USART_EnableAutoBaudRate(USART1); - LL_USART_SetAutoBaudRateMode(USART1, LL_USART_AUTOBAUD_DETECT_ON_STARTBIT); - LL_USART_ConfigAsyncMode(USART1); - - /* USER CODE BEGIN WKUPType USART1 */ - - /* USER CODE END WKUPType USART1 */ - - LL_USART_Enable(USART1); - - /* Polling USART1 initialisation */ - while(!(LL_USART_IsActiveFlag_TEACK(USART1))) { - } - /* USER CODE BEGIN USART1_Init 2 */ - - /* USER CODE END USART1_Init 2 */ -} - -/* USER CODE BEGIN 1 */ - -/* USER CODE END 1 */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/firmware/targets/f7/cube/Src/usb_device.c b/firmware/targets/f7/cube/Src/usb_device.c deleted file mode 100644 index d6d02cd65ea..00000000000 --- a/firmware/targets/f7/cube/Src/usb_device.c +++ /dev/null @@ -1,98 +0,0 @@ -/* USER CODE BEGIN Header */ -/** - ****************************************************************************** - * @file : usb_device.c - * @version : v3.0_Cube - * @brief : This file implements the USB Device - ****************************************************************************** - * @attention - * - *

© Copyright (c) 2021 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ -/* USER CODE END Header */ - -/* Includes ------------------------------------------------------------------*/ - -#include "usb_device.h" -#include "usbd_core.h" -#include "usbd_desc.h" -#include "usbd_cdc.h" -#include "usbd_cdc_if.h" - -/* USER CODE BEGIN Includes */ - -/* USER CODE END Includes */ - -/* USER CODE BEGIN PV */ -/* Private variables ---------------------------------------------------------*/ - -/* USER CODE END PV */ - -/* USER CODE BEGIN PFP */ -/* Private function prototypes -----------------------------------------------*/ - -/* USER CODE END PFP */ - -extern void Error_Handler(void); -/* USB Device Core handle declaration. */ -USBD_HandleTypeDef hUsbDeviceFS; -extern USBD_DescriptorsTypeDef CDC_Desc; - -/* - * -- Insert your variables declaration here -- - */ -/* USER CODE BEGIN 0 */ - -/* USER CODE END 0 */ - -/* - * -- Insert your external function declaration here -- - */ -/* USER CODE BEGIN 1 */ - -/* USER CODE END 1 */ - -/** - * Init USB device Library, add supported class and start the library - * @retval None - */ -void MX_USB_Device_Init(void) { - /* USER CODE BEGIN USB_Device_Init_PreTreatment */ - - /* USER CODE END USB_Device_Init_PreTreatment */ - - /* Init Device Library, add supported class and start the library. */ - if(USBD_Init(&hUsbDeviceFS, &CDC_Desc, DEVICE_FS) != USBD_OK) { - Error_Handler(); - } - if(USBD_RegisterClass(&hUsbDeviceFS, &USBD_CDC) != USBD_OK) { - Error_Handler(); - } - if(USBD_CDC_RegisterInterface(&hUsbDeviceFS, &USBD_Interface_fops_FS) != USBD_OK) { - Error_Handler(); - } - if(USBD_Start(&hUsbDeviceFS) != USBD_OK) { - Error_Handler(); - } - /* USER CODE BEGIN USB_Device_Init_PostTreatment */ - - /* USER CODE END USB_Device_Init_PostTreatment */ -} - -/** - * @} - */ - -/** - * @} - */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/firmware/targets/f7/cube/Src/usbd_cdc_if.c b/firmware/targets/f7/cube/Src/usbd_cdc_if.c deleted file mode 100644 index e0d92f27212..00000000000 --- a/firmware/targets/f7/cube/Src/usbd_cdc_if.c +++ /dev/null @@ -1,318 +0,0 @@ -/* USER CODE BEGIN Header */ -/** - ****************************************************************************** - * @file : usbd_cdc_if.c - * @version : v3.0_Cube - * @brief : Usb device for Virtual Com Port. - ****************************************************************************** - * @attention - * - *

© Copyright (c) 2021 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ -/* USER CODE END Header */ - -/* Includes ------------------------------------------------------------------*/ -#include "usbd_cdc_if.h" - -/* USER CODE BEGIN INCLUDE */ - -/* USER CODE END INCLUDE */ - -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ -/* Private macro -------------------------------------------------------------*/ - -/* USER CODE BEGIN PV */ -/* Private variables ---------------------------------------------------------*/ - -/* USER CODE END PV */ - -/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY - * @brief Usb device library. - * @{ - */ - -/** @addtogroup USBD_CDC_IF - * @{ - */ - -/** @defgroup USBD_CDC_IF_Private_TypesDefinitions USBD_CDC_IF_Private_TypesDefinitions - * @brief Private types. - * @{ - */ - -/* USER CODE BEGIN PRIVATE_TYPES */ - -/* USER CODE END PRIVATE_TYPES */ - -/** - * @} - */ - -/** @defgroup USBD_CDC_IF_Private_Defines USBD_CDC_IF_Private_Defines - * @brief Private defines. - * @{ - */ - -/* USER CODE BEGIN PRIVATE_DEFINES */ -/* USER CODE END PRIVATE_DEFINES */ - -/** - * @} - */ - -/** @defgroup USBD_CDC_IF_Private_Macros USBD_CDC_IF_Private_Macros - * @brief Private macros. - * @{ - */ - -/* USER CODE BEGIN PRIVATE_MACRO */ - -/* USER CODE END PRIVATE_MACRO */ - -/** - * @} - */ - -/** @defgroup USBD_CDC_IF_Private_Variables USBD_CDC_IF_Private_Variables - * @brief Private variables. - * @{ - */ -/* Create buffer for reception and transmission */ -/* It's up to user to redefine and/or remove those define */ -/** Received data over USB are stored in this buffer */ -uint8_t UserRxBufferFS[APP_RX_DATA_SIZE]; - -/** Data to send over USB CDC are stored in this buffer */ -uint8_t UserTxBufferFS[APP_TX_DATA_SIZE]; - -/* USER CODE BEGIN PRIVATE_VARIABLES */ - -/* USER CODE END PRIVATE_VARIABLES */ - -/** - * @} - */ - -/** @defgroup USBD_CDC_IF_Exported_Variables USBD_CDC_IF_Exported_Variables - * @brief Public variables. - * @{ - */ - -extern USBD_HandleTypeDef hUsbDeviceFS; - -/* USER CODE BEGIN EXPORTED_VARIABLES */ - -/* USER CODE END EXPORTED_VARIABLES */ - -/** - * @} - */ - -/** @defgroup USBD_CDC_IF_Private_FunctionPrototypes USBD_CDC_IF_Private_FunctionPrototypes - * @brief Private functions declaration. - * @{ - */ - -static int8_t CDC_Init_FS(void); -static int8_t CDC_DeInit_FS(void); -static int8_t CDC_Control_FS(uint8_t cmd, uint8_t* pbuf, uint16_t length); -static int8_t CDC_Receive_FS(uint8_t* pbuf, uint32_t* Len); -static int8_t CDC_TransmitCplt_FS(uint8_t* pbuf, uint32_t* Len, uint8_t epnum); - -/* USER CODE BEGIN PRIVATE_FUNCTIONS_DECLARATION */ - -/* USER CODE END PRIVATE_FUNCTIONS_DECLARATION */ - -/** - * @} - */ - -USBD_CDC_ItfTypeDef USBD_Interface_fops_FS = - {CDC_Init_FS, CDC_DeInit_FS, CDC_Control_FS, CDC_Receive_FS, CDC_TransmitCplt_FS}; - -/* Private functions ---------------------------------------------------------*/ -/** - * @brief Initializes the CDC media low layer over the FS USB IP - * @retval USBD_OK if all operations are OK else USBD_FAIL - */ -static int8_t CDC_Init_FS(void) { - /* USER CODE BEGIN 3 */ - /* Set Application Buffers */ - USBD_CDC_SetTxBuffer(&hUsbDeviceFS, UserTxBufferFS, 0); - USBD_CDC_SetRxBuffer(&hUsbDeviceFS, UserRxBufferFS); - return (USBD_OK); - /* USER CODE END 3 */ -} - -/** - * @brief DeInitializes the CDC media low layer - * @retval USBD_OK if all operations are OK else USBD_FAIL - */ -static int8_t CDC_DeInit_FS(void) { - /* USER CODE BEGIN 4 */ - return (USBD_OK); - /* USER CODE END 4 */ -} - -/** - * @brief Manage the CDC class requests - * @param cmd: Command code - * @param pbuf: Buffer containing command data (request parameters) - * @param length: Number of data to be sent (in bytes) - * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL - */ -static int8_t CDC_Control_FS(uint8_t cmd, uint8_t* pbuf, uint16_t length) { - /* USER CODE BEGIN 5 */ - switch(cmd) { - case CDC_SEND_ENCAPSULATED_COMMAND: - - break; - - case CDC_GET_ENCAPSULATED_RESPONSE: - - break; - - case CDC_SET_COMM_FEATURE: - - break; - - case CDC_GET_COMM_FEATURE: - - break; - - case CDC_CLEAR_COMM_FEATURE: - - break; - - /*******************************************************************************/ - /* Line Coding Structure */ - /*-----------------------------------------------------------------------------*/ - /* Offset | Field | Size | Value | Description */ - /* 0 | dwDTERate | 4 | Number |Data terminal rate, in bits per second*/ - /* 4 | bCharFormat | 1 | Number | Stop bits */ - /* 0 - 1 Stop bit */ - /* 1 - 1.5 Stop bits */ - /* 2 - 2 Stop bits */ - /* 5 | bParityType | 1 | Number | Parity */ - /* 0 - None */ - /* 1 - Odd */ - /* 2 - Even */ - /* 3 - Mark */ - /* 4 - Space */ - /* 6 | bDataBits | 1 | Number Data bits (5, 6, 7, 8 or 16). */ - /*******************************************************************************/ - case CDC_SET_LINE_CODING: - - break; - - case CDC_GET_LINE_CODING: - - break; - - case CDC_SET_CONTROL_LINE_STATE: - - break; - - case CDC_SEND_BREAK: - - break; - - default: - break; - } - - return (USBD_OK); - /* USER CODE END 5 */ -} - -/** - * @brief Data received over USB OUT endpoint are sent over CDC interface - * through this function. - * - * @note - * This function will issue a NAK packet on any OUT packet received on - * USB endpoint until exiting this function. If you exit this function - * before transfer is complete on CDC interface (ie. using DMA controller) - * it will result in receiving more data while previous ones are still - * not sent. - * - * @param Buf: Buffer of data to be received - * @param Len: Number of data received (in bytes) - * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL - */ -static int8_t CDC_Receive_FS(uint8_t* Buf, uint32_t* Len) { - /* USER CODE BEGIN 6 */ - USBD_CDC_SetRxBuffer(&hUsbDeviceFS, &Buf[0]); - USBD_CDC_ReceivePacket(&hUsbDeviceFS); - return (USBD_OK); - /* USER CODE END 6 */ -} - -/** - * @brief CDC_Transmit_FS - * Data to send over USB IN endpoint are sent over CDC interface - * through this function. - * @note - * - * - * @param Buf: Buffer of data to be sent - * @param Len: Number of data to be sent (in bytes) - * @retval USBD_OK if all operations are OK else USBD_FAIL or USBD_BUSY - */ -uint8_t CDC_Transmit_FS(uint8_t* Buf, uint16_t Len) { - uint8_t result = USBD_OK; - /* USER CODE BEGIN 7 */ - USBD_CDC_HandleTypeDef* hcdc = (USBD_CDC_HandleTypeDef*)hUsbDeviceFS.pClassData; - if(hcdc->TxState != 0) { - return USBD_BUSY; - } - USBD_CDC_SetTxBuffer(&hUsbDeviceFS, Buf, Len); - result = USBD_CDC_TransmitPacket(&hUsbDeviceFS); - /* USER CODE END 7 */ - return result; -} - -/** - * @brief CDC_TransmitCplt_FS - * Data transmitted callback - * - * @note - * This function is IN transfer complete callback used to inform user that - * the submitted Data is successfully sent over USB. - * - * @param Buf: Buffer of data to be received - * @param Len: Number of data received (in bytes) - * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL - */ -static int8_t CDC_TransmitCplt_FS(uint8_t* Buf, uint32_t* Len, uint8_t epnum) { - uint8_t result = USBD_OK; - /* USER CODE BEGIN 13 */ - UNUSED(Buf); - UNUSED(Len); - UNUSED(epnum); - /* USER CODE END 13 */ - return result; -} - -/* USER CODE BEGIN PRIVATE_FUNCTIONS_IMPLEMENTATION */ - -/* USER CODE END PRIVATE_FUNCTIONS_IMPLEMENTATION */ - -/** - * @} - */ - -/** - * @} - */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/firmware/targets/f7/cube/Src/usbd_conf.c b/firmware/targets/f7/cube/Src/usbd_conf.c deleted file mode 100644 index 667164ebb9d..00000000000 --- a/firmware/targets/f7/cube/Src/usbd_conf.c +++ /dev/null @@ -1,783 +0,0 @@ -/* USER CODE BEGIN Header */ -/** - ****************************************************************************** - * @file : usbd_conf.c - * @version : v3.0_Cube - * @brief : This file implements the board support package for the USB device library - ****************************************************************************** - * @attention - * - *

© Copyright (c) 2021 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ -/* USER CODE END Header */ - -/* Includes ------------------------------------------------------------------*/ -#include "stm32wbxx.h" -#include "stm32wbxx_hal.h" -#include "usbd_def.h" -#include "usbd_core.h" - -#include "usbd_cdc.h" - -/* USER CODE BEGIN Includes */ - -/* USER CODE END Includes */ - -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ -/* Private macro -------------------------------------------------------------*/ - -/* Private variables ---------------------------------------------------------*/ -/* USER CODE BEGIN PV */ - -/* USER CODE END PV */ - -PCD_HandleTypeDef hpcd_USB_FS; -void Error_Handler(void); - -/* USER CODE BEGIN 0 */ - -/* USER CODE END 0 */ - -/* Exported function prototypes ----------------------------------------------*/ - -/* USER CODE BEGIN PFP */ -/* Private function prototypes -----------------------------------------------*/ - -/* USER CODE END PFP */ - -/* Private functions ---------------------------------------------------------*/ -static USBD_StatusTypeDef USBD_Get_USB_Status(HAL_StatusTypeDef hal_status); -/* USER CODE BEGIN 1 */ -static void SystemClockConfig_Resume(void); - -/* USER CODE END 1 */ -extern void SystemClock_Config(void); - -/******************************************************************************* - LL Driver Callbacks (PCD -> USB Device Library) -*******************************************************************************/ -/* MSP Init */ - -#if(USE_HAL_PCD_REGISTER_CALLBACK == 1U) -static void HAL_PCD_MspInit(PCD_HandleTypeDef* pcdHandle) -#else -void HAL_PCD_MspInit(PCD_HandleTypeDef* pcdHandle) -#endif /* USE_HAL_PCD_REGISTER_CALLBACK */ -{ - GPIO_InitTypeDef GPIO_InitStruct = {0}; - if(pcdHandle->Instance == USB) { - /* USER CODE BEGIN USB_MspInit 0 */ - - /* USER CODE END USB_MspInit 0 */ - - __HAL_RCC_GPIOA_CLK_ENABLE(); - /**USB GPIO Configuration - PA11 ------> USB_DM - PA12 ------> USB_DP - */ - GPIO_InitStruct.Pin = GPIO_PIN_11 | GPIO_PIN_12; - GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; - GPIO_InitStruct.Pull = GPIO_NOPULL; - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; - GPIO_InitStruct.Alternate = GPIO_AF10_USB; - HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); - - /* Peripheral clock enable */ - __HAL_RCC_USB_CLK_ENABLE(); - - /* Peripheral interrupt init */ - HAL_NVIC_SetPriority(USB_LP_IRQn, 5, 0); - HAL_NVIC_EnableIRQ(USB_LP_IRQn); - /* USER CODE BEGIN USB_MspInit 1 */ - - /* USER CODE END USB_MspInit 1 */ - } -} - -#if(USE_HAL_PCD_REGISTER_CALLBACK == 1U) -static void HAL_PCD_MspDeInit(PCD_HandleTypeDef* pcdHandle) -#else -void HAL_PCD_MspDeInit(PCD_HandleTypeDef* pcdHandle) -#endif /* USE_HAL_PCD_REGISTER_CALLBACK */ -{ - if(pcdHandle->Instance == USB) { - /* USER CODE BEGIN USB_MspDeInit 0 */ - - /* USER CODE END USB_MspDeInit 0 */ - /* Peripheral clock disable */ - __HAL_RCC_USB_CLK_DISABLE(); - - /**USB GPIO Configuration - PA11 ------> USB_DM - PA12 ------> USB_DP - */ - HAL_GPIO_DeInit(GPIOA, GPIO_PIN_11 | GPIO_PIN_12); - - /* Peripheral interrupt Deinit*/ - HAL_NVIC_DisableIRQ(USB_LP_IRQn); - - /* USER CODE BEGIN USB_MspDeInit 1 */ - - /* USER CODE END USB_MspDeInit 1 */ - } -} - -/** - * @brief Setup stage callback - * @param hpcd: PCD handle - * @retval None - */ -#if(USE_HAL_PCD_REGISTER_CALLBACKS == 1U) -static void PCD_SetupStageCallback(PCD_HandleTypeDef* hpcd) -#else -void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef* hpcd) -#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ -{ - /* USER CODE BEGIN HAL_PCD_SetupStageCallback_PreTreatment */ - - /* USER CODE END HAL_PCD_SetupStageCallback_PreTreatment */ - USBD_LL_SetupStage((USBD_HandleTypeDef*)hpcd->pData, (uint8_t*)hpcd->Setup); - /* USER CODE BEGIN HAL_PCD_SetupStageCallback_PostTreatment */ - - /* USER CODE END HAL_PCD_SetupStageCallback_PostTreatment */ -} - -/** - * @brief Data Out stage callback. - * @param hpcd: PCD handle - * @param epnum: Endpoint number - * @retval None - */ -#if(USE_HAL_PCD_REGISTER_CALLBACKS == 1U) -static void PCD_DataOutStageCallback(PCD_HandleTypeDef* hpcd, uint8_t epnum) -#else -void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef* hpcd, uint8_t epnum) -#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ -{ - /* USER CODE BEGIN HAL_PCD_DataOutStageCallback_PreTreatment */ - - /* USER CODE END HAL_PCD_DataOutStageCallback_PreTreatment */ - USBD_LL_DataOutStage((USBD_HandleTypeDef*)hpcd->pData, epnum, hpcd->OUT_ep[epnum].xfer_buff); - /* USER CODE BEGIN HAL_PCD_DataOutStageCallback_PostTreatment */ - - /* USER CODE END HAL_PCD_DataOutStageCallback_PostTreatment */ -} - -/** - * @brief Data In stage callback. - * @param hpcd: PCD handle - * @param epnum: Endpoint number - * @retval None - */ -#if(USE_HAL_PCD_REGISTER_CALLBACKS == 1U) -static void PCD_DataInStageCallback(PCD_HandleTypeDef* hpcd, uint8_t epnum) -#else -void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef* hpcd, uint8_t epnum) -#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ -{ - /* USER CODE BEGIN HAL_PCD_DataInStageCallback_PreTreatment */ - - /* USER CODE END HAL_PCD_DataInStageCallback_PreTreatment */ - USBD_LL_DataInStage((USBD_HandleTypeDef*)hpcd->pData, epnum, hpcd->IN_ep[epnum].xfer_buff); - /* USER CODE BEGIN HAL_PCD_DataInStageCallback_PostTreatment */ - - /* USER CODE END HAL_PCD_DataInStageCallback_PostTreatment */ -} - -/** - * @brief SOF callback. - * @param hpcd: PCD handle - * @retval None - */ -#if(USE_HAL_PCD_REGISTER_CALLBACKS == 1U) -static void PCD_SOFCallback(PCD_HandleTypeDef* hpcd) -#else -void HAL_PCD_SOFCallback(PCD_HandleTypeDef* hpcd) -#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ -{ - /* USER CODE BEGIN HAL_PCD_SOFCallback_PreTreatment */ - - /* USER CODE END HAL_PCD_SOFCallback_PreTreatment */ - USBD_LL_SOF((USBD_HandleTypeDef*)hpcd->pData); - /* USER CODE BEGIN HAL_PCD_SOFCallback_PostTreatment */ - - /* USER CODE END HAL_PCD_SOFCallback_PostTreatment */ -} - -/** - * @brief Reset callback. - * @param hpcd: PCD handle - * @retval None - */ -#if(USE_HAL_PCD_REGISTER_CALLBACKS == 1U) -static void PCD_ResetCallback(PCD_HandleTypeDef* hpcd) -#else -void HAL_PCD_ResetCallback(PCD_HandleTypeDef* hpcd) -#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ -{ - /* USER CODE BEGIN HAL_PCD_ResetCallback_PreTreatment */ - - /* USER CODE END HAL_PCD_ResetCallback_PreTreatment */ - USBD_SpeedTypeDef speed = USBD_SPEED_FULL; - - if(hpcd->Init.speed != PCD_SPEED_FULL) { - Error_Handler(); - } - /* Set Speed. */ - USBD_LL_SetSpeed((USBD_HandleTypeDef*)hpcd->pData, speed); - - /* Reset Device. */ - USBD_LL_Reset((USBD_HandleTypeDef*)hpcd->pData); - /* USER CODE BEGIN HAL_PCD_ResetCallback_PostTreatment */ - - /* USER CODE END HAL_PCD_ResetCallback_PostTreatment */ -} - -/** - * @brief Suspend callback. - * When Low power mode is enabled the debug cannot be used (IAR, Keil doesn't support it) - * @param hpcd: PCD handle - * @retval None - */ -#if(USE_HAL_PCD_REGISTER_CALLBACKS == 1U) -static void PCD_SuspendCallback(PCD_HandleTypeDef* hpcd) -#else -void HAL_PCD_SuspendCallback(PCD_HandleTypeDef* hpcd) -#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ -{ - /* USER CODE BEGIN HAL_PCD_SuspendCallback_PreTreatment */ - - /* USER CODE END HAL_PCD_SuspendCallback_PreTreatment */ - /* Inform USB library that core enters in suspend Mode. */ - USBD_LL_Suspend((USBD_HandleTypeDef*)hpcd->pData); - /* Enter in STOP mode. */ - /* USER CODE BEGIN 2 */ - if(hpcd->Init.low_power_enable) { - /* Set SLEEPDEEP bit and SleepOnExit of Cortex System Control Register. */ - SCB->SCR |= (uint32_t)((uint32_t)(SCB_SCR_SLEEPDEEP_Msk | SCB_SCR_SLEEPONEXIT_Msk)); - } - /* USER CODE END 2 */ - /* USER CODE BEGIN HAL_PCD_SuspendCallback_PostTreatment */ - - /* USER CODE END HAL_PCD_SuspendCallback_PostTreatment */ -} - -/** - * @brief Resume callback. - * When Low power mode is enabled the debug cannot be used (IAR, Keil doesn't support it) - * @param hpcd: PCD handle - * @retval None - */ -#if(USE_HAL_PCD_REGISTER_CALLBACKS == 1U) -static void PCD_ResumeCallback(PCD_HandleTypeDef* hpcd) -#else -void HAL_PCD_ResumeCallback(PCD_HandleTypeDef* hpcd) -#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ -{ - /* USER CODE BEGIN HAL_PCD_ResumeCallback_PreTreatment */ - - /* USER CODE END HAL_PCD_ResumeCallback_PreTreatment */ - - /* USER CODE BEGIN 3 */ - if(hpcd->Init.low_power_enable) { - /* Reset SLEEPDEEP bit of Cortex System Control Register. */ - SCB->SCR &= (uint32_t) ~((uint32_t)(SCB_SCR_SLEEPDEEP_Msk | SCB_SCR_SLEEPONEXIT_Msk)); - SystemClockConfig_Resume(); - } - /* USER CODE END 3 */ - - USBD_LL_Resume((USBD_HandleTypeDef*)hpcd->pData); - /* USER CODE BEGIN HAL_PCD_ResumeCallback_PostTreatment */ - - /* USER CODE END HAL_PCD_ResumeCallback_PostTreatment */ -} - -/** - * @brief ISOOUTIncomplete callback. - * @param hpcd: PCD handle - * @param epnum: Endpoint number - * @retval None - */ -#if(USE_HAL_PCD_REGISTER_CALLBACKS == 1U) -static void PCD_ISOOUTIncompleteCallback(PCD_HandleTypeDef* hpcd, uint8_t epnum) -#else -void HAL_PCD_ISOOUTIncompleteCallback(PCD_HandleTypeDef* hpcd, uint8_t epnum) -#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ -{ - /* USER CODE BEGIN HAL_PCD_ISOOUTIncompleteCallback_PreTreatment */ - - /* USER CODE END HAL_PCD_ISOOUTIncompleteCallback_PreTreatment */ - USBD_LL_IsoOUTIncomplete((USBD_HandleTypeDef*)hpcd->pData, epnum); - /* USER CODE BEGIN HAL_PCD_ISOOUTIncompleteCallback_PostTreatment */ - - /* USER CODE END HAL_PCD_ISOOUTIncompleteCallback_PostTreatment */ -} - -/** - * @brief ISOINIncomplete callback. - * @param hpcd: PCD handle - * @param epnum: Endpoint number - * @retval None - */ -#if(USE_HAL_PCD_REGISTER_CALLBACKS == 1U) -static void PCD_ISOINIncompleteCallback(PCD_HandleTypeDef* hpcd, uint8_t epnum) -#else -void HAL_PCD_ISOINIncompleteCallback(PCD_HandleTypeDef* hpcd, uint8_t epnum) -#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ -{ - /* USER CODE BEGIN HAL_PCD_ISOINIncompleteCallback_PreTreatment */ - - /* USER CODE END HAL_PCD_ISOINIncompleteCallback_PreTreatment */ - USBD_LL_IsoINIncomplete((USBD_HandleTypeDef*)hpcd->pData, epnum); - /* USER CODE BEGIN HAL_PCD_ISOINIncompleteCallback_PostTreatment */ - - /* USER CODE END HAL_PCD_ISOINIncompleteCallback_PostTreatment */ -} - -/** - * @brief Connect callback. - * @param hpcd: PCD handle - * @retval None - */ -#if(USE_HAL_PCD_REGISTER_CALLBACKS == 1U) -static void PCD_ConnectCallback(PCD_HandleTypeDef* hpcd) -#else -void HAL_PCD_ConnectCallback(PCD_HandleTypeDef* hpcd) -#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ -{ - /* USER CODE BEGIN HAL_PCD_ConnectCallback_PreTreatment */ - - /* USER CODE END HAL_PCD_ConnectCallback_PreTreatment */ - USBD_LL_DevConnected((USBD_HandleTypeDef*)hpcd->pData); - /* USER CODE BEGIN HAL_PCD_ConnectCallback_PostTreatment */ - - /* USER CODE END HAL_PCD_ConnectCallback_PostTreatment */ -} - -/** - * @brief Disconnect callback. - * @param hpcd: PCD handle - * @retval None - */ -#if(USE_HAL_PCD_REGISTER_CALLBACKS == 1U) -static void PCD_DisconnectCallback(PCD_HandleTypeDef* hpcd) -#else -void HAL_PCD_DisconnectCallback(PCD_HandleTypeDef* hpcd) -#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ -{ - /* USER CODE BEGIN HAL_PCD_DisconnectCallback_PreTreatment */ - - /* USER CODE END HAL_PCD_DisconnectCallback_PreTreatment */ - USBD_LL_DevDisconnected((USBD_HandleTypeDef*)hpcd->pData); - /* USER CODE BEGIN HAL_PCD_DisconnectCallback_PostTreatment */ - - /* USER CODE END HAL_PCD_DisconnectCallback_PostTreatment */ -} - -/* USER CODE BEGIN LowLevelInterface */ - -/* USER CODE END LowLevelInterface */ - -/******************************************************************************* - LL Driver Interface (USB Device Library --> PCD) -*******************************************************************************/ - -/** - * @brief Initializes the low level portion of the device driver. - * @param pdev: Device handle - * @retval USBD status - */ -USBD_StatusTypeDef USBD_LL_Init(USBD_HandleTypeDef* pdev) { - /* Init USB Ip. */ - hpcd_USB_FS.pData = pdev; - /* Link the driver to the stack. */ - pdev->pData = &hpcd_USB_FS; - /* Enable USB power on Pwrctrl CR2 register. */ - HAL_PWREx_EnableVddUSB(); - - hpcd_USB_FS.Instance = USB; - hpcd_USB_FS.Init.dev_endpoints = 8; - hpcd_USB_FS.Init.speed = PCD_SPEED_FULL; - hpcd_USB_FS.Init.phy_itface = PCD_PHY_EMBEDDED; - hpcd_USB_FS.Init.Sof_enable = DISABLE; - hpcd_USB_FS.Init.low_power_enable = DISABLE; - hpcd_USB_FS.Init.lpm_enable = DISABLE; - hpcd_USB_FS.Init.battery_charging_enable = DISABLE; - -#if(USE_HAL_PCD_REGISTER_CALLBACKS == 1U) - /* register Msp Callbacks (before the Init) */ - HAL_PCD_RegisterCallback(&hpcd_USB_FS, HAL_PCD_MSPINIT_CB_ID, PCD_MspInit); - HAL_PCD_RegisterCallback(&hpcd_USB_FS, HAL_PCD_MSPDEINIT_CB_ID, PCD_MspDeInit); -#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ - - if(HAL_PCD_Init(&hpcd_USB_FS) != HAL_OK) { - Error_Handler(); - } - -#if(USE_HAL_PCD_REGISTER_CALLBACKS == 1U) - /* Register USB PCD CallBacks */ - HAL_PCD_RegisterCallback(&hpcd_USB_FS, HAL_PCD_SOF_CB_ID, PCD_SOFCallback); - HAL_PCD_RegisterCallback(&hpcd_USB_FS, HAL_PCD_SETUPSTAGE_CB_ID, PCD_SetupStageCallback); - HAL_PCD_RegisterCallback(&hpcd_USB_FS, HAL_PCD_RESET_CB_ID, PCD_ResetCallback); - HAL_PCD_RegisterCallback(&hpcd_USB_FS, HAL_PCD_SUSPEND_CB_ID, PCD_SuspendCallback); - HAL_PCD_RegisterCallback(&hpcd_USB_FS, HAL_PCD_RESUME_CB_ID, PCD_ResumeCallback); - HAL_PCD_RegisterCallback(&hpcd_USB_FS, HAL_PCD_CONNECT_CB_ID, PCD_ConnectCallback); - HAL_PCD_RegisterCallback(&hpcd_USB_FS, HAL_PCD_DISCONNECT_CB_ID, PCD_DisconnectCallback); - /* USER CODE BEGIN RegisterCallBackFirstPart */ - - /* USER CODE END RegisterCallBackFirstPart */ - HAL_PCD_RegisterLpmCallback(&hpcd_USB_FS, PCDEx_LPM_Callback); - HAL_PCD_RegisterDataOutStageCallback(&hpcd_USB_FS, PCD_DataOutStageCallback); - HAL_PCD_RegisterDataInStageCallback(&hpcd_USB_FS, PCD_DataInStageCallback); - HAL_PCD_RegisterIsoOutIncpltCallback(&hpcd_USB_FS, PCD_ISOOUTIncompleteCallback); - HAL_PCD_RegisterIsoInIncpltCallback(&hpcd_USB_FS, PCD_ISOINIncompleteCallback); - /* USER CODE BEGIN RegisterCallBackSecondPart */ - - /* USER CODE END RegisterCallBackSecondPart */ -#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ - /* USER CODE BEGIN EndPoint_Configuration */ - HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData, 0x00, PCD_SNG_BUF, 0x18); - HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData, 0x80, PCD_SNG_BUF, 0x58); - /* USER CODE END EndPoint_Configuration */ - /* USER CODE BEGIN EndPoint_Configuration_CDC */ - HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData, 0x81, PCD_SNG_BUF, 0xC0); - HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData, 0x01, PCD_SNG_BUF, 0x110); - HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData, 0x82, PCD_SNG_BUF, 0x100); - /* USER CODE END EndPoint_Configuration_CDC */ - return USBD_OK; -} - -/** - * @brief De-Initializes the low level portion of the device driver. - * @param pdev: Device handle - * @retval USBD status - */ -USBD_StatusTypeDef USBD_LL_DeInit(USBD_HandleTypeDef* pdev) { - HAL_StatusTypeDef hal_status = HAL_OK; - USBD_StatusTypeDef usb_status = USBD_OK; - - hal_status = HAL_PCD_DeInit(pdev->pData); - - usb_status = USBD_Get_USB_Status(hal_status); - - return usb_status; -} - -/** - * @brief Starts the low level portion of the device driver. - * @param pdev: Device handle - * @retval USBD status - */ -USBD_StatusTypeDef USBD_LL_Start(USBD_HandleTypeDef* pdev) { - HAL_StatusTypeDef hal_status = HAL_OK; - USBD_StatusTypeDef usb_status = USBD_OK; - - hal_status = HAL_PCD_Start(pdev->pData); - - usb_status = USBD_Get_USB_Status(hal_status); - - return usb_status; -} - -/** - * @brief Stops the low level portion of the device driver. - * @param pdev: Device handle - * @retval USBD status - */ -USBD_StatusTypeDef USBD_LL_Stop(USBD_HandleTypeDef* pdev) { - HAL_StatusTypeDef hal_status = HAL_OK; - USBD_StatusTypeDef usb_status = USBD_OK; - - hal_status = HAL_PCD_Stop(pdev->pData); - - usb_status = USBD_Get_USB_Status(hal_status); - - return usb_status; -} - -/** - * @brief Opens an endpoint of the low level driver. - * @param pdev: Device handle - * @param ep_addr: Endpoint number - * @param ep_type: Endpoint type - * @param ep_mps: Endpoint max packet size - * @retval USBD status - */ -USBD_StatusTypeDef - USBD_LL_OpenEP(USBD_HandleTypeDef* pdev, uint8_t ep_addr, uint8_t ep_type, uint16_t ep_mps) { - HAL_StatusTypeDef hal_status = HAL_OK; - USBD_StatusTypeDef usb_status = USBD_OK; - - hal_status = HAL_PCD_EP_Open(pdev->pData, ep_addr, ep_mps, ep_type); - - usb_status = USBD_Get_USB_Status(hal_status); - - return usb_status; -} - -/** - * @brief Closes an endpoint of the low level driver. - * @param pdev: Device handle - * @param ep_addr: Endpoint number - * @retval USBD status - */ -USBD_StatusTypeDef USBD_LL_CloseEP(USBD_HandleTypeDef* pdev, uint8_t ep_addr) { - HAL_StatusTypeDef hal_status = HAL_OK; - USBD_StatusTypeDef usb_status = USBD_OK; - - hal_status = HAL_PCD_EP_Close(pdev->pData, ep_addr); - - usb_status = USBD_Get_USB_Status(hal_status); - - return usb_status; -} - -/** - * @brief Flushes an endpoint of the Low Level Driver. - * @param pdev: Device handle - * @param ep_addr: Endpoint number - * @retval USBD status - */ -USBD_StatusTypeDef USBD_LL_FlushEP(USBD_HandleTypeDef* pdev, uint8_t ep_addr) { - HAL_StatusTypeDef hal_status = HAL_OK; - USBD_StatusTypeDef usb_status = USBD_OK; - - hal_status = HAL_PCD_EP_Flush(pdev->pData, ep_addr); - - usb_status = USBD_Get_USB_Status(hal_status); - - return usb_status; -} - -/** - * @brief Sets a Stall condition on an endpoint of the Low Level Driver. - * @param pdev: Device handle - * @param ep_addr: Endpoint number - * @retval USBD status - */ -USBD_StatusTypeDef USBD_LL_StallEP(USBD_HandleTypeDef* pdev, uint8_t ep_addr) { - HAL_StatusTypeDef hal_status = HAL_OK; - USBD_StatusTypeDef usb_status = USBD_OK; - - hal_status = HAL_PCD_EP_SetStall(pdev->pData, ep_addr); - - usb_status = USBD_Get_USB_Status(hal_status); - - return usb_status; -} - -/** - * @brief Clears a Stall condition on an endpoint of the Low Level Driver. - * @param pdev: Device handle - * @param ep_addr: Endpoint number - * @retval USBD status - */ -USBD_StatusTypeDef USBD_LL_ClearStallEP(USBD_HandleTypeDef* pdev, uint8_t ep_addr) { - HAL_StatusTypeDef hal_status = HAL_OK; - USBD_StatusTypeDef usb_status = USBD_OK; - - hal_status = HAL_PCD_EP_ClrStall(pdev->pData, ep_addr); - - usb_status = USBD_Get_USB_Status(hal_status); - - return usb_status; -} - -/** - * @brief Returns Stall condition. - * @param pdev: Device handle - * @param ep_addr: Endpoint number - * @retval Stall (1: Yes, 0: No) - */ -uint8_t USBD_LL_IsStallEP(USBD_HandleTypeDef* pdev, uint8_t ep_addr) { - PCD_HandleTypeDef* hpcd = (PCD_HandleTypeDef*)pdev->pData; - - if((ep_addr & 0x80) == 0x80) { - return hpcd->IN_ep[ep_addr & 0x7F].is_stall; - } else { - return hpcd->OUT_ep[ep_addr & 0x7F].is_stall; - } -} - -/** - * @brief Assigns a USB address to the device. - * @param pdev: Device handle - * @param dev_addr: Device address - * @retval USBD status - */ -USBD_StatusTypeDef USBD_LL_SetUSBAddress(USBD_HandleTypeDef* pdev, uint8_t dev_addr) { - HAL_StatusTypeDef hal_status = HAL_OK; - USBD_StatusTypeDef usb_status = USBD_OK; - - hal_status = HAL_PCD_SetAddress(pdev->pData, dev_addr); - - usb_status = USBD_Get_USB_Status(hal_status); - - return usb_status; -} - -/** - * @brief Transmits data over an endpoint. - * @param pdev: Device handle - * @param ep_addr: Endpoint number - * @param pbuf: Pointer to data to be sent - * @param size: Data size - * @retval USBD status - */ -USBD_StatusTypeDef - USBD_LL_Transmit(USBD_HandleTypeDef* pdev, uint8_t ep_addr, uint8_t* pbuf, uint32_t size) { - HAL_StatusTypeDef hal_status = HAL_OK; - USBD_StatusTypeDef usb_status = USBD_OK; - - hal_status = HAL_PCD_EP_Transmit(pdev->pData, ep_addr, pbuf, size); - - usb_status = USBD_Get_USB_Status(hal_status); - - return usb_status; -} - -/** - * @brief Prepares an endpoint for reception. - * @param pdev: Device handle - * @param ep_addr: Endpoint number - * @param pbuf: Pointer to data to be received - * @param size: Data size - * @retval USBD status - */ -USBD_StatusTypeDef USBD_LL_PrepareReceive( - USBD_HandleTypeDef* pdev, - uint8_t ep_addr, - uint8_t* pbuf, - uint32_t size) { - HAL_StatusTypeDef hal_status = HAL_OK; - USBD_StatusTypeDef usb_status = USBD_OK; - - hal_status = HAL_PCD_EP_Receive(pdev->pData, ep_addr, pbuf, size); - - usb_status = USBD_Get_USB_Status(hal_status); - - return usb_status; -} - -/** - * @brief Returns the last transferred packet size. - * @param pdev: Device handle - * @param ep_addr: Endpoint number - * @retval Received Data Size - */ -uint32_t USBD_LL_GetRxDataSize(USBD_HandleTypeDef* pdev, uint8_t ep_addr) { - return HAL_PCD_EP_GetRxCount((PCD_HandleTypeDef*)pdev->pData, ep_addr); -} - -/** - * @brief Send LPM message to user layer - * @param hpcd: PCD handle - * @param msg: LPM message - * @retval None - */ -#if(USE_HAL_PCD_REGISTER_CALLBACKS == 1U) -static void PCDEx_LPM_Callback(PCD_HandleTypeDef* hpcd, PCD_LPM_MsgTypeDef msg) -#else -void HAL_PCDEx_LPM_Callback(PCD_HandleTypeDef* hpcd, PCD_LPM_MsgTypeDef msg) -#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ -{ - /* USER CODE BEGIN LPM_Callback */ - switch(msg) { - case PCD_LPM_L0_ACTIVE: - if(hpcd->Init.low_power_enable) { - SystemClockConfig_Resume(); - - /* Reset SLEEPDEEP bit of Cortex System Control Register. */ - SCB->SCR &= (uint32_t) ~((uint32_t)(SCB_SCR_SLEEPDEEP_Msk | SCB_SCR_SLEEPONEXIT_Msk)); - } - USBD_LL_Resume(hpcd->pData); - break; - - case PCD_LPM_L1_ACTIVE: - USBD_LL_Suspend(hpcd->pData); - - /* Enter in STOP mode. */ - if(hpcd->Init.low_power_enable) { - /* Set SLEEPDEEP bit and SleepOnExit of Cortex System Control Register. */ - SCB->SCR |= (uint32_t)((uint32_t)(SCB_SCR_SLEEPDEEP_Msk | SCB_SCR_SLEEPONEXIT_Msk)); - } - break; - } - /* USER CODE END LPM_Callback */ -} - -/** - * @brief Delays routine for the USB Device Library. - * @param Delay: Delay in ms - * @retval None - */ -void USBD_LL_Delay(uint32_t Delay) { - HAL_Delay(Delay); -} - -/** - * @brief Static single allocation. - * @param size: Size of allocated memory - * @retval None - */ -void* USBD_static_malloc(uint32_t size) { - static uint32_t mem[(sizeof(USBD_CDC_HandleTypeDef) / 4) + 1]; /* On 32-bit boundary */ - return mem; -} - -/** - * @brief Dummy memory free - * @param p: Pointer to allocated memory address - * @retval None - */ -void USBD_static_free(void* p) { -} - -/* USER CODE BEGIN 5 */ -/** - * @brief Configures system clock after wake-up from USB resume callBack: - * enable HSI, PLL and select PLL as system clock source. - * @retval None - */ -static void SystemClockConfig_Resume(void) { - SystemClock_Config(); -} -/* USER CODE END 5 */ - -/** - * @brief Returns the USB status depending on the HAL status: - * @param hal_status: HAL status - * @retval USB status - */ -USBD_StatusTypeDef USBD_Get_USB_Status(HAL_StatusTypeDef hal_status) { - USBD_StatusTypeDef usb_status = USBD_OK; - - switch(hal_status) { - case HAL_OK: - usb_status = USBD_OK; - break; - case HAL_ERROR: - usb_status = USBD_FAIL; - break; - case HAL_BUSY: - usb_status = USBD_BUSY; - break; - case HAL_TIMEOUT: - usb_status = USBD_FAIL; - break; - default: - usb_status = USBD_FAIL; - break; - } - return usb_status; -} -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/firmware/targets/f7/cube/Src/usbd_desc.c b/firmware/targets/f7/cube/Src/usbd_desc.c deleted file mode 100644 index 6e466cd325b..00000000000 --- a/firmware/targets/f7/cube/Src/usbd_desc.c +++ /dev/null @@ -1,368 +0,0 @@ -/* USER CODE BEGIN Header */ -/** - ****************************************************************************** - * @file : usbd_desc.c - * @version : v3.0_Cube - * @brief : This file implements the USB device descriptors. - ****************************************************************************** - * @attention - * - *

© Copyright (c) 2021 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ -/* USER CODE END Header */ - -/* Includes ------------------------------------------------------------------*/ -#include "usbd_core.h" -#include "usbd_desc.h" -#include "usbd_conf.h" - -/* USER CODE BEGIN INCLUDE */ - -/* USER CODE END INCLUDE */ - -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ -/* Private macro -------------------------------------------------------------*/ - -/* USER CODE BEGIN PV */ -/* Private variables ---------------------------------------------------------*/ - -/* USER CODE END PV */ - -/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY - * @{ - */ - -/** @addtogroup USBD_DESC - * @{ - */ - -/** @defgroup USBD_DESC_Private_TypesDefinitions USBD_DESC_Private_TypesDefinitions - * @brief Private types. - * @{ - */ - -/* USER CODE BEGIN PRIVATE_TYPES */ - -/* USER CODE END PRIVATE_TYPES */ - -/** - * @} - */ - -/** @defgroup USBD_DESC_Private_Defines USBD_DESC_Private_Defines - * @brief Private defines. - * @{ - */ - -#define USBD_VID 1155 -#define USBD_LANGID_STRING 1033 -#define USBD_MANUFACTURER_STRING "Flipper" -#define USBD_PID 22336 -#define USBD_PRODUCT_STRING "Flipper Control Virtual ComPort" -#define USBD_CONFIGURATION_STRING "CDC Config" -#define USBD_INTERFACE_STRING "CDC Interface" - -/* USER CODE BEGIN PRIVATE_DEFINES */ - -/* USER CODE END PRIVATE_DEFINES */ - -/** - * @} - */ - -/* USER CODE BEGIN 0 */ - -/* USER CODE END 0 */ - -/** @defgroup USBD_DESC_Private_Macros USBD_DESC_Private_Macros - * @brief Private macros. - * @{ - */ - -/* USER CODE BEGIN PRIVATE_MACRO */ - -/* USER CODE END PRIVATE_MACRO */ - -/** - * @} - */ - -/** @defgroup USBD_DESC_Private_FunctionPrototypes USBD_DESC_Private_FunctionPrototypes - * @brief Private functions declaration. - * @{ - */ - -static void Get_SerialNum(void); -static void IntToUnicode(uint32_t value, uint8_t* pbuf, uint8_t len); - -/** - * @} - */ - -/** @defgroup USBD_DESC_Private_FunctionPrototypes USBD_DESC_Private_FunctionPrototypes - * @brief Private functions declaration. - * @{ - */ - -uint8_t* USBD_CDC_DeviceDescriptor(USBD_SpeedTypeDef speed, uint16_t* length); -uint8_t* USBD_CDC_LangIDStrDescriptor(USBD_SpeedTypeDef speed, uint16_t* length); -uint8_t* USBD_CDC_ManufacturerStrDescriptor(USBD_SpeedTypeDef speed, uint16_t* length); -uint8_t* USBD_CDC_ProductStrDescriptor(USBD_SpeedTypeDef speed, uint16_t* length); -uint8_t* USBD_CDC_SerialStrDescriptor(USBD_SpeedTypeDef speed, uint16_t* length); -uint8_t* USBD_CDC_ConfigStrDescriptor(USBD_SpeedTypeDef speed, uint16_t* length); -uint8_t* USBD_CDC_InterfaceStrDescriptor(USBD_SpeedTypeDef speed, uint16_t* length); - -/** - * @} - */ - -/** @defgroup USBD_DESC_Private_Variables USBD_DESC_Private_Variables - * @brief Private variables. - * @{ - */ - -USBD_DescriptorsTypeDef CDC_Desc = { - USBD_CDC_DeviceDescriptor, - USBD_CDC_LangIDStrDescriptor, - USBD_CDC_ManufacturerStrDescriptor, - USBD_CDC_ProductStrDescriptor, - USBD_CDC_SerialStrDescriptor, - USBD_CDC_ConfigStrDescriptor, - USBD_CDC_InterfaceStrDescriptor}; - -#if defined(__ICCARM__) /* IAR Compiler */ -#pragma data_alignment = 4 -#endif /* defined ( __ICCARM__ ) */ -/** USB standard device descriptor. */ -__ALIGN_BEGIN uint8_t USBD_CDC_DeviceDesc[USB_LEN_DEV_DESC] __ALIGN_END = { - 0x12, /*bLength */ - USB_DESC_TYPE_DEVICE, /*bDescriptorType*/ - 0x00, /*bcdUSB */ - 0x02, - 0x02, /*bDeviceClass*/ - 0x02, /*bDeviceSubClass*/ - 0x00, /*bDeviceProtocol*/ - USB_MAX_EP0_SIZE, /*bMaxPacketSize*/ - LOBYTE(USBD_VID), /*idVendor*/ - HIBYTE(USBD_VID), /*idVendor*/ - LOBYTE(USBD_PID), /*idProduct*/ - HIBYTE(USBD_PID), /*idProduct*/ - 0x00, /*bcdDevice rel. 2.00*/ - 0x02, - USBD_IDX_MFC_STR, /*Index of manufacturer string*/ - USBD_IDX_PRODUCT_STR, /*Index of product string*/ - USBD_IDX_SERIAL_STR, /*Index of serial number string*/ - USBD_MAX_NUM_CONFIGURATION /*bNumConfigurations*/ -}; - -/* USB_DeviceDescriptor */ - -/** - * @} - */ - -/** @defgroup USBD_DESC_Private_Variables USBD_DESC_Private_Variables - * @brief Private variables. - * @{ - */ - -#if defined(__ICCARM__) /* IAR Compiler */ -#pragma data_alignment = 4 -#endif /* defined ( __ICCARM__ ) */ - -/** USB lang identifier descriptor. */ -__ALIGN_BEGIN uint8_t USBD_LangIDDesc[USB_LEN_LANGID_STR_DESC] __ALIGN_END = { - USB_LEN_LANGID_STR_DESC, - USB_DESC_TYPE_STRING, - LOBYTE(USBD_LANGID_STRING), - HIBYTE(USBD_LANGID_STRING)}; - -#if defined(__ICCARM__) /* IAR Compiler */ -#pragma data_alignment = 4 -#endif /* defined ( __ICCARM__ ) */ -/* Internal string descriptor. */ -__ALIGN_BEGIN uint8_t USBD_StrDesc[USBD_MAX_STR_DESC_SIZ] __ALIGN_END; - -#if defined(__ICCARM__) /*!< IAR Compiler */ -#pragma data_alignment = 4 -#endif -__ALIGN_BEGIN uint8_t USBD_StringSerial[USB_SIZ_STRING_SERIAL] __ALIGN_END = { - USB_SIZ_STRING_SERIAL, - USB_DESC_TYPE_STRING, -}; - -/** - * @} - */ - -/** @defgroup USBD_DESC_Private_Functions USBD_DESC_Private_Functions - * @brief Private functions. - * @{ - */ - -/** - * @brief Return the device descriptor - * @param speed : Current device speed - * @param length : Pointer to data length variable - * @retval Pointer to descriptor buffer - */ -uint8_t* USBD_CDC_DeviceDescriptor(USBD_SpeedTypeDef speed, uint16_t* length) { - UNUSED(speed); - *length = sizeof(USBD_CDC_DeviceDesc); - return USBD_CDC_DeviceDesc; -} - -/** - * @brief Return the LangID string descriptor - * @param speed : Current device speed - * @param length : Pointer to data length variable - * @retval Pointer to descriptor buffer - */ -uint8_t* USBD_CDC_LangIDStrDescriptor(USBD_SpeedTypeDef speed, uint16_t* length) { - UNUSED(speed); - *length = sizeof(USBD_LangIDDesc); - return USBD_LangIDDesc; -} - -/** - * @brief Return the product string descriptor - * @param speed : Current device speed - * @param length : Pointer to data length variable - * @retval Pointer to descriptor buffer - */ -uint8_t* USBD_CDC_ProductStrDescriptor(USBD_SpeedTypeDef speed, uint16_t* length) { - if(speed == 0) { - USBD_GetString((uint8_t*)USBD_PRODUCT_STRING, USBD_StrDesc, length); - } else { - USBD_GetString((uint8_t*)USBD_PRODUCT_STRING, USBD_StrDesc, length); - } - return USBD_StrDesc; -} - -/** - * @brief Return the manufacturer string descriptor - * @param speed : Current device speed - * @param length : Pointer to data length variable - * @retval Pointer to descriptor buffer - */ -uint8_t* USBD_CDC_ManufacturerStrDescriptor(USBD_SpeedTypeDef speed, uint16_t* length) { - UNUSED(speed); - USBD_GetString((uint8_t*)USBD_MANUFACTURER_STRING, USBD_StrDesc, length); - return USBD_StrDesc; -} - -/** - * @brief Return the serial number string descriptor - * @param speed : Current device speed - * @param length : Pointer to data length variable - * @retval Pointer to descriptor buffer - */ -uint8_t* USBD_CDC_SerialStrDescriptor(USBD_SpeedTypeDef speed, uint16_t* length) { - UNUSED(speed); - *length = USB_SIZ_STRING_SERIAL; - - /* Update the serial number string descriptor with the data from the unique - * ID */ - Get_SerialNum(); - - /* USER CODE BEGIN USBD_CDC_SerialStrDescriptor */ - - /* USER CODE END USBD_CDC_SerialStrDescriptor */ - - return (uint8_t*)USBD_StringSerial; -} - -/** - * @brief Return the configuration string descriptor - * @param speed : Current device speed - * @param length : Pointer to data length variable - * @retval Pointer to descriptor buffer - */ -uint8_t* USBD_CDC_ConfigStrDescriptor(USBD_SpeedTypeDef speed, uint16_t* length) { - if(speed == USBD_SPEED_HIGH) { - USBD_GetString((uint8_t*)USBD_CONFIGURATION_STRING, USBD_StrDesc, length); - } else { - USBD_GetString((uint8_t*)USBD_CONFIGURATION_STRING, USBD_StrDesc, length); - } - return USBD_StrDesc; -} - -/** - * @brief Return the interface string descriptor - * @param speed : Current device speed - * @param length : Pointer to data length variable - * @retval Pointer to descriptor buffer - */ -uint8_t* USBD_CDC_InterfaceStrDescriptor(USBD_SpeedTypeDef speed, uint16_t* length) { - if(speed == 0) { - USBD_GetString((uint8_t*)USBD_INTERFACE_STRING, USBD_StrDesc, length); - } else { - USBD_GetString((uint8_t*)USBD_INTERFACE_STRING, USBD_StrDesc, length); - } - return USBD_StrDesc; -} - -/** - * @brief Create the serial number string descriptor - * @param None - * @retval None - */ -static void Get_SerialNum(void) { - uint32_t deviceserial0, deviceserial1, deviceserial2; - - deviceserial0 = *(uint32_t*)DEVICE_ID1; - deviceserial1 = *(uint32_t*)DEVICE_ID2; - deviceserial2 = *(uint32_t*)DEVICE_ID3; - - deviceserial0 += deviceserial2; - - if(deviceserial0 != 0) { - IntToUnicode(deviceserial0, &USBD_StringSerial[2], 8); - IntToUnicode(deviceserial1, &USBD_StringSerial[18], 4); - } -} - -/** - * @brief Convert Hex 32Bits value into char - * @param value: value to convert - * @param pbuf: pointer to the buffer - * @param len: buffer length - * @retval None - */ -static void IntToUnicode(uint32_t value, uint8_t* pbuf, uint8_t len) { - uint8_t idx = 0; - - for(idx = 0; idx < len; idx++) { - if(((value >> 28)) < 0xA) { - pbuf[2 * idx] = (value >> 28) + '0'; - } else { - pbuf[2 * idx] = (value >> 28) + 'A' - 10; - } - - value = value << 4; - - pbuf[2 * idx + 1] = 0; - } -} -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/firmware/targets/f7/cube/f7.ioc b/firmware/targets/f7/cube/f7.ioc deleted file mode 100644 index e55ecca43fe..00000000000 --- a/firmware/targets/f7/cube/f7.ioc +++ /dev/null @@ -1,598 +0,0 @@ -#MicroXplorer Configuration settings - do not modify -ADC1.Channel-0\#ChannelRegularConversion=ADC_CHANNEL_14 -ADC1.ContinuousConvMode=DISABLE -ADC1.EnableAnalogWatchDog1=false -ADC1.IPParameters=Rank-0\#ChannelRegularConversion,Channel-0\#ChannelRegularConversion,SamplingTime-0\#ChannelRegularConversion,OffsetNumber-0\#ChannelRegularConversion,NbrOfConversionFlag,master,EnableAnalogWatchDog1,ContinuousConvMode -ADC1.NbrOfConversionFlag=1 -ADC1.OffsetNumber-0\#ChannelRegularConversion=ADC_OFFSET_NONE -ADC1.Rank-0\#ChannelRegularConversion=1 -ADC1.SamplingTime-0\#ChannelRegularConversion=ADC_SAMPLETIME_2CYCLES_5 -ADC1.master=1 -COMP1.Hysteresis=COMP_HYSTERESIS_HIGH -COMP1.IPParameters=TriggerMode,Hysteresis,Mode -COMP1.Mode=COMP_POWERMODE_MEDIUMSPEED -COMP1.TriggerMode=COMP_TRIGGERMODE_IT_RISING_FALLING -FREERTOS.FootprintOK=true -FREERTOS.HEAP_NUMBER=4 -FREERTOS.INCLUDE_vTaskCleanUpResources=1 -FREERTOS.IPParameters=Tasks01,configTOTAL_HEAP_SIZE,HEAP_NUMBER,configUSE_TIMERS,configUSE_IDLE_HOOK,FootprintOK,configCHECK_FOR_STACK_OVERFLOW,configRECORD_STACK_HIGH_ADDRESS,configGENERATE_RUN_TIME_STATS,configENABLE_FPU,configUSE_TICKLESS_IDLE,configENABLE_BACKWARD_COMPATIBILITY,INCLUDE_vTaskCleanUpResources,configTICK_RATE_HZ -FREERTOS.Tasks01=app_main,24,1024,app,As weak,NULL,Dynamic,NULL,NULL -FREERTOS.configCHECK_FOR_STACK_OVERFLOW=1 -FREERTOS.configENABLE_BACKWARD_COMPATIBILITY=0 -FREERTOS.configENABLE_FPU=1 -FREERTOS.configGENERATE_RUN_TIME_STATS=1 -FREERTOS.configRECORD_STACK_HIGH_ADDRESS=1 -FREERTOS.configTICK_RATE_HZ=1000 -FREERTOS.configTOTAL_HEAP_SIZE=40960 -FREERTOS.configUSE_IDLE_HOOK=1 -FREERTOS.configUSE_TICKLESS_IDLE=2 -FREERTOS.configUSE_TIMERS=1 -File.Version=6 -GPIO.groupedBy=Show All -I2C1.CustomTiming=Disabled -I2C1.I2C_Fall_Time=0 -I2C1.I2C_Rise_Time=0 -I2C1.IPParameters=Timing,CustomTiming,I2C_Rise_Time,I2C_Fall_Time -I2C1.Timing=0x10707DBC -KeepUserPlacement=false -Mcu.Family=STM32WB -Mcu.IP0=ADC1 -Mcu.IP1=AES1 -Mcu.IP10=RCC -Mcu.IP11=RF -Mcu.IP12=RNG -Mcu.IP13=RTC -Mcu.IP14=SPI1 -Mcu.IP15=SPI2 -Mcu.IP16=SYS -Mcu.IP17=TIM1 -Mcu.IP18=TIM2 -Mcu.IP19=TIM16 -Mcu.IP2=AES2 -Mcu.IP20=USART1 -Mcu.IP21=USB -Mcu.IP22=USB_DEVICE -Mcu.IP3=COMP1 -Mcu.IP4=CRC -Mcu.IP5=FREERTOS -Mcu.IP6=HSEM -Mcu.IP7=I2C1 -Mcu.IP8=NVIC -Mcu.IP9=PKA -Mcu.IPNb=23 -Mcu.Name=STM32WB55RGVx -Mcu.Package=VFQFPN68 -Mcu.Pin0=PC13 -Mcu.Pin1=PC14-OSC32_IN -Mcu.Pin10=PA0 -Mcu.Pin11=PA1 -Mcu.Pin12=PA2 -Mcu.Pin13=PA3 -Mcu.Pin14=PA4 -Mcu.Pin15=PA5 -Mcu.Pin16=PA6 -Mcu.Pin17=PA7 -Mcu.Pin18=PA8 -Mcu.Pin19=PA9 -Mcu.Pin2=PC15-OSC32_OUT -Mcu.Pin20=PC4 -Mcu.Pin21=PC5 -Mcu.Pin22=PB2 -Mcu.Pin23=PB10 -Mcu.Pin24=PB11 -Mcu.Pin25=RF1 -Mcu.Pin26=OSC_OUT -Mcu.Pin27=OSC_IN -Mcu.Pin28=PB0 -Mcu.Pin29=PB1 -Mcu.Pin3=PH3-BOOT0 -Mcu.Pin30=PE4 -Mcu.Pin31=PB12 -Mcu.Pin32=PB13 -Mcu.Pin33=PB14 -Mcu.Pin34=PB15 -Mcu.Pin35=PC6 -Mcu.Pin36=PA10 -Mcu.Pin37=PA11 -Mcu.Pin38=PA12 -Mcu.Pin39=PA13 -Mcu.Pin4=PB8 -Mcu.Pin40=PA14 -Mcu.Pin41=PA15 -Mcu.Pin42=PC10 -Mcu.Pin43=PC11 -Mcu.Pin44=PC12 -Mcu.Pin45=PD0 -Mcu.Pin46=PD1 -Mcu.Pin47=PB3 -Mcu.Pin48=PB4 -Mcu.Pin49=PB5 -Mcu.Pin5=PB9 -Mcu.Pin50=PB6 -Mcu.Pin51=PB7 -Mcu.Pin52=VP_ADC1_TempSens_Input -Mcu.Pin53=VP_ADC1_Vref_Input -Mcu.Pin54=VP_AES1_VS_AES -Mcu.Pin55=VP_AES2_VS_AES -Mcu.Pin56=VP_COMP1_VS_VREFINT14 -Mcu.Pin57=VP_CRC_VS_CRC -Mcu.Pin58=VP_FREERTOS_VS_CMSIS_V2 -Mcu.Pin59=VP_HSEM_VS_HSEM -Mcu.Pin6=PC0 -Mcu.Pin60=VP_PKA_VS_PKA -Mcu.Pin61=VP_RNG_VS_RNG -Mcu.Pin62=VP_RTC_VS_RTC_Activate -Mcu.Pin63=VP_RTC_VS_RTC_Calendar -Mcu.Pin64=VP_SYS_VS_Systick -Mcu.Pin65=VP_TIM1_VS_ClockSourceINT -Mcu.Pin66=VP_TIM2_VS_ClockSourceINT -Mcu.Pin67=VP_TIM16_VS_ClockSourceINT -Mcu.Pin68=VP_USB_DEVICE_VS_USB_DEVICE_CDC_FS -Mcu.Pin7=PC1 -Mcu.Pin8=PC2 -Mcu.Pin9=PC3 -Mcu.PinsNb=69 -Mcu.ThirdPartyNb=0 -Mcu.UserConstants= -Mcu.UserName=STM32WB55RGVx -MxCube.Version=6.3.0 -MxDb.Version=DB.6.0.30 -NVIC.ADC1_IRQn=true\:5\:0\:true\:false\:true\:false\:true\:true -NVIC.BusFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false -NVIC.COMP_IRQn=true\:5\:0\:true\:false\:true\:false\:false\:true -NVIC.DebugMonitor_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false -NVIC.EXTI15_10_IRQn=true\:5\:0\:true\:false\:true\:false\:true\:true -NVIC.EXTI3_IRQn=true\:5\:0\:true\:false\:true\:false\:true\:true -NVIC.ForceEnableDMAVector=true -NVIC.HSEM_IRQn=true\:5\:0\:true\:false\:true\:false\:false\:true -NVIC.HardFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false -NVIC.MemoryManagement_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false -NVIC.NonMaskableInt_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:true -NVIC.PendSV_IRQn=true\:15\:0\:false\:false\:false\:true\:false\:false -NVIC.PriorityGroup=NVIC_PRIORITYGROUP_4 -NVIC.RCC_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:false -NVIC.SVCall_IRQn=true\:0\:0\:false\:false\:false\:false\:false\:false -NVIC.SavedPendsvIrqHandlerGenerated=false -NVIC.SavedSvcallIrqHandlerGenerated=false -NVIC.SavedSystickIrqHandlerGenerated=true -NVIC.SysTick_IRQn=true\:15\:0\:false\:false\:true\:true\:false\:false -NVIC.TAMP_STAMP_LSECSS_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true -NVIC.TIM1_TRG_COM_TIM17_IRQn=true\:5\:0\:false\:false\:true\:false\:false\:true -NVIC.TIM2_IRQn=true\:5\:0\:true\:false\:true\:false\:true\:true -NVIC.USB_LP_IRQn=true\:5\:0\:true\:false\:true\:false\:false\:true -NVIC.UsageFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false -OSC_IN.GPIOParameters=GPIO_Label -OSC_IN.GPIO_Label=QUARTZ_32KHZ_IN -OSC_IN.Locked=true -OSC_IN.Mode=HSE-External-Oscillator -OSC_IN.Signal=RCC_OSC_IN -OSC_OUT.GPIOParameters=GPIO_Label -OSC_OUT.GPIO_Label=QUARTZ_32KHZ_OUT -OSC_OUT.Locked=true -OSC_OUT.Mode=HSE-External-Oscillator -OSC_OUT.Signal=RCC_OSC_OUT -PA0.GPIOParameters=GPIO_Label -PA0.GPIO_Label=IR_RX -PA0.Signal=S_TIM2_CH1 -PA1.GPIOParameters=GPIO_Label -PA1.GPIO_Label=CC1101_G0 -PA1.Locked=true -PA1.Signal=GPIO_Analog -PA10.GPIOParameters=GPIO_Speed,GPIO_Label,GPIO_Pu -PA10.GPIO_Label=I2C_SDA -PA10.GPIO_Pu=GPIO_PULLUP -PA10.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH -PA10.Locked=true -PA10.Mode=I2C -PA10.Signal=I2C1_SDA -PA11.GPIOParameters=GPIO_Speed -PA11.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH -PA11.Locked=true -PA11.Mode=Device -PA11.Signal=USB_DM -PA12.GPIOParameters=GPIO_Speed -PA12.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH -PA12.Locked=true -PA12.Mode=Device -PA12.Signal=USB_DP -PA13.Locked=true -PA13.Mode=Serial_Wire -PA13.Signal=SYS_JTMS-SWDIO -PA14.Locked=true -PA14.Mode=Serial_Wire -PA14.Signal=SYS_JTCK-SWCLK -PA15.GPIOParameters=GPIO_Label -PA15.GPIO_Label=RFID_CARRIER -PA15.Locked=true -PA15.Signal=GPIO_Analog -PA2.GPIOParameters=GPIO_Label -PA2.GPIO_Label=RFID_PULL -PA2.Locked=true -PA2.Signal=GPIO_Output -PA3.GPIOParameters=GPIO_Speed,PinState,GPIO_Label,GPIO_ModeDefaultOutputPP -PA3.GPIO_Label=PERIPH_POWER -PA3.GPIO_ModeDefaultOutputPP=GPIO_MODE_OUTPUT_OD -PA3.GPIO_Speed=GPIO_SPEED_FREQ_LOW -PA3.Locked=true -PA3.PinState=GPIO_PIN_SET -PA3.Signal=GPIO_Output -PA4.GPIOParameters=GPIO_Label -PA4.GPIO_Label=PA4 -PA4.Signal=GPIO_Analog -PA5.GPIOParameters=GPIO_Label -PA5.GPIO_Label=SPI_R_SCK -PA5.Locked=true -PA5.Mode=Full_Duplex_Master -PA5.Signal=SPI1_SCK -PA6.GPIOParameters=GPIO_Label -PA6.GPIO_Label=PA6 -PA6.Signal=GPIO_Analog -PA7.GPIOParameters=GPIO_Label -PA7.GPIO_Label=PA7 -PA7.Signal=GPIO_Analog -PA8.GPIOParameters=GPIO_Label -PA8.GPIO_Label=VIBRO -PA8.Locked=true -PA8.Signal=GPIO_Output -PA9.GPIOParameters=GPIO_Speed,GPIO_Label,GPIO_Pu -PA9.GPIO_Label=I2C_SCL -PA9.GPIO_Pu=GPIO_PULLUP -PA9.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH -PA9.Locked=true -PA9.Mode=I2C -PA9.Signal=I2C1_SCL -PB0.GPIOParameters=GPIO_Label -PB0.GPIO_Label=DISPLAY_RST -PB0.Locked=true -PB0.Signal=GPIO_Output -PB1.GPIOParameters=GPIO_Label -PB1.GPIO_Label=DISPLAY_DI -PB1.Locked=true -PB1.Signal=GPIO_Output -PB10.GPIOParameters=GPIO_PuPd,GPIO_Label,GPIO_ModeDefaultEXTI -PB10.GPIO_Label=BUTTON_UP -PB10.GPIO_ModeDefaultEXTI=GPIO_MODE_IT_RISING_FALLING -PB10.GPIO_PuPd=GPIO_PULLUP -PB10.Locked=true -PB10.Signal=GPXTI10 -PB11.GPIOParameters=GPIO_PuPd,GPIO_Label,GPIO_ModeDefaultEXTI -PB11.GPIO_Label=BUTTON_LEFT -PB11.GPIO_ModeDefaultEXTI=GPIO_MODE_IT_RISING_FALLING -PB11.GPIO_PuPd=GPIO_PULLUP -PB11.Locked=true -PB11.Signal=GPXTI11 -PB12.GPIOParameters=GPIO_PuPd,GPIO_Label,GPIO_ModeDefaultEXTI -PB12.GPIO_Label=BUTTON_RIGHT -PB12.GPIO_ModeDefaultEXTI=GPIO_MODE_IT_RISING_FALLING -PB12.GPIO_PuPd=GPIO_PULLUP -PB12.Locked=true -PB12.Signal=GPXTI12 -PB13.GPIOParameters=GPIO_Label -PB13.GPIO_Label=RFID_OUT -PB13.Locked=true -PB13.Mode=Output Compare1 CH1N -PB13.Signal=TIM1_CH1N -PB14.GPIOParameters=GPIO_Label -PB14.GPIO_Label=iBTN -PB14.Signal=GPIO_Analog -PB15.GPIOParameters=GPIO_Label -PB15.GPIO_Label=SPI_D_MOSI -PB15.Locked=true -PB15.Mode=Full_Duplex_Master -PB15.Signal=SPI2_MOSI -PB2.GPIOParameters=GPIO_Label -PB2.GPIO_Label=PB2 -PB2.Signal=GPIO_Analog -PB3.GPIOParameters=GPIO_Label -PB3.GPIO_Label=PB3 -PB3.Locked=true -PB3.Signal=GPIO_Analog -PB4.GPIOParameters=GPIO_Label -PB4.GPIO_Label=SPI_R_MISO -PB4.Locked=true -PB4.Mode=Full_Duplex_Master -PB4.Signal=SPI1_MISO -PB5.GPIOParameters=GPIO_Label -PB5.GPIO_Label=SPI_R_MOSI -PB5.Locked=true -PB5.Mode=Full_Duplex_Master -PB5.Signal=SPI1_MOSI -PB6.Locked=true -PB6.Mode=Asynchronous -PB6.Signal=USART1_TX -PB7.Locked=true -PB7.Mode=Asynchronous -PB7.Signal=USART1_RX -PB8.GPIOParameters=GPIO_Label -PB8.GPIO_Label=SPEAKER -PB8.Locked=true -PB8.Signal=S_TIM16_CH1 -PB9.GPIOParameters=GPIO_Label -PB9.GPIO_Label=IR_TX -PB9.Locked=true -PB9.Mode=PWM Generation3 CH3N -PB9.Signal=TIM1_CH3N -PC0.GPIOParameters=GPIO_Label -PC0.GPIO_Label=PC0 -PC0.Locked=true -PC0.Signal=GPIO_Analog -PC1.GPIOParameters=GPIO_Label -PC1.GPIO_Label=PC1 -PC1.Locked=true -PC1.Signal=GPIO_Analog -PC10.GPIOParameters=GPIO_Label -PC10.GPIO_Label=SD_CD -PC10.Locked=true -PC10.Signal=GPIO_Input -PC11.GPIOParameters=PinState,GPIO_Label -PC11.GPIO_Label=DISPLAY_CS -PC11.Locked=true -PC11.PinState=GPIO_PIN_SET -PC11.Signal=GPIO_Output -PC12.GPIOParameters=GPIO_Speed,PinState,GPIO_Label -PC12.GPIO_Label=SD_CS -PC12.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH -PC12.Locked=true -PC12.PinState=GPIO_PIN_SET -PC12.Signal=GPIO_Output -PC13.GPIOParameters=GPIO_PuPd,GPIO_Label,GPIO_ModeDefaultEXTI -PC13.GPIO_Label=BUTTON_BACK -PC13.GPIO_ModeDefaultEXTI=GPIO_MODE_IT_RISING_FALLING -PC13.GPIO_PuPd=GPIO_PULLUP -PC13.Locked=true -PC13.Signal=GPXTI13 -PC14-OSC32_IN.GPIOParameters=GPIO_Label -PC14-OSC32_IN.GPIO_Label=QUARTZ_32MHZ_IN -PC14-OSC32_IN.Locked=true -PC14-OSC32_IN.Mode=LSE-External-Oscillator -PC14-OSC32_IN.Signal=RCC_OSC32_IN -PC15-OSC32_OUT.GPIOParameters=GPIO_Label -PC15-OSC32_OUT.GPIO_Label=QUARTZ_32MHZ_OUT -PC15-OSC32_OUT.Locked=true -PC15-OSC32_OUT.Mode=LSE-External-Oscillator -PC15-OSC32_OUT.Signal=RCC_OSC32_OUT -PC2.GPIOParameters=GPIO_Label -PC2.GPIO_Label=SPI_D_MISO -PC2.Locked=true -PC2.Mode=Full_Duplex_Master -PC2.Signal=SPI2_MISO -PC3.GPIOParameters=GPIO_Label -PC3.GPIO_Label=PC3 -PC3.Signal=GPIO_Analog -PC4.GPIOParameters=GPIO_Label -PC4.GPIO_Label=RF_SW_0 -PC4.Locked=true -PC4.Signal=GPIO_Output -PC5.GPIOParameters=GPIO_Label -PC5.GPIO_Label=RFID_RF_IN -PC5.Locked=true -PC5.Signal=SharedAnalog_PC5 -PC6.GPIOParameters=GPIO_Label -PC6.GPIO_Label=BUTTON_DOWN -PC6.Locked=true -PC6.Signal=GPIO_Input -PCC.Ble.ConnectionInterval=1000.0 -PCC.Ble.DataLength=6 -PCC.Ble.IsUsed=false -PCC.Ble.Mode=NOT_SELECTED -PCC.Ble.PowerLevel=Min -PCC.Zigbee.IsUsed=false -PCC.Zigbee.Mode=Sleepy End Device -PCC.Zigbee.Payload=15 -PCC.Zigbee.PoolPeriodicity=480.0 -PCC.Zigbee.PowerLevel=Min -PCC.Zigbee.RequestPeriodicity=1500.0 -PD0.GPIOParameters=GPIO_Speed,PinState,GPIO_Label -PD0.GPIO_Label=CC1101_CS -PD0.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH -PD0.Locked=true -PD0.PinState=GPIO_PIN_SET -PD0.Signal=GPIO_Output -PD1.GPIOParameters=GPIO_Label -PD1.GPIO_Label=SPI_D_SCK -PD1.Locked=true -PD1.Mode=Full_Duplex_Master -PD1.Signal=SPI2_SCK -PE4.GPIOParameters=GPIO_Speed,PinState,GPIO_Label -PE4.GPIO_Label=NFC_CS -PE4.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH -PE4.Locked=true -PE4.PinState=GPIO_PIN_SET -PE4.Signal=GPIO_Output -PH3-BOOT0.GPIOParameters=GPIO_Label,GPIO_ModeDefaultEXTI -PH3-BOOT0.GPIO_Label=BUTTON_OK -PH3-BOOT0.GPIO_ModeDefaultEXTI=GPIO_MODE_IT_RISING_FALLING -PH3-BOOT0.Locked=true -PH3-BOOT0.Signal=GPXTI3 -PinOutPanel.RotationAngle=0 -ProjectManager.AskForMigrate=true -ProjectManager.BackupPrevious=false -ProjectManager.CompilerOptimize=6 -ProjectManager.ComputerToolchain=false -ProjectManager.CoupleFile=true -ProjectManager.CustomerFirmwarePackage=../../../../lib/STM32CubeWB -ProjectManager.DefaultFWLocation=false -ProjectManager.DeletePrevious=true -ProjectManager.DeviceId=STM32WB55RGVx -ProjectManager.FirmwarePackage=STM32Cube FW_WB V1.12.1 -ProjectManager.FreePins=false -ProjectManager.HalAssertFull=false -ProjectManager.HeapSize=0x400 -ProjectManager.KeepUserCode=true -ProjectManager.LastFirmware=true -ProjectManager.LibraryCopy=2 -ProjectManager.MainLocation=Src -ProjectManager.NoMain=false -ProjectManager.PreviousToolchain= -ProjectManager.ProjectBuild=false -ProjectManager.ProjectFileName=f7.ioc -ProjectManager.ProjectName=f7 -ProjectManager.RegisterCallBack= -ProjectManager.StackSize=0x1000 -ProjectManager.TargetToolchain=Makefile -ProjectManager.ToolChainLocation= -ProjectManager.UnderRoot=false -ProjectManager.functionlistsort=1-MX_GPIO_Init-GPIO-false-HAL-true,2-SystemClock_Config-RCC-false-LL-false,3-MX_ADC1_Init-ADC1-false-HAL-true,4-MX_I2C1_Init-I2C1-false-LL-true,5-MX_RTC_Init-RTC-false-HAL-true,6-MX_SPI1_Init-SPI1-false-HAL-true,7-MX_SPI2_Init-SPI2-false-HAL-true,8-MX_USB_Device_Init-USB_DEVICE-false-HAL-false,9-MX_TIM1_Init-TIM1-false-HAL-true,10-MX_TIM2_Init-TIM2-false-HAL-true,11-MX_TIM16_Init-TIM16-false-HAL-true,12-MX_COMP1_Init-COMP1-false-HAL-true,13-MX_RF_Init-RF-false-HAL-true,14-MX_PKA_Init-PKA-false-HAL-true,15-MX_RNG_Init-RNG-false-HAL-true,16-MX_AES1_Init-AES1-false-HAL-true,17-MX_AES2_Init-AES2-false-HAL-true,18-MX_CRC_Init-CRC-false-HAL-true,19-MX_USART1_UART_Init-USART1-false-LL-true,0-MX_HSEM_Init-HSEM-false-HAL-true -RCC.ADCFreq_Value=48000000 -RCC.AHB2CLKDivider=RCC_SYSCLK_DIV2 -RCC.AHBFreq_Value=64000000 -RCC.APB1Freq_Value=64000000 -RCC.APB1TimFreq_Value=64000000 -RCC.APB2Freq_Value=64000000 -RCC.APB2TimFreq_Value=64000000 -RCC.APB3Freq_Value=16000000 -RCC.Cortex2Freq_Value=32000000 -RCC.CortexFreq_Value=64000000 -RCC.EnableCSSLSE=true -RCC.EnbaleCSS=true -RCC.FCLK2Freq_Value=32000000 -RCC.FCLKCortexFreq_Value=64000000 -RCC.FamilyName=M -RCC.HCLK2Freq_Value=32000000 -RCC.HCLK3Freq_Value=64000000 -RCC.HCLKFreq_Value=64000000 -RCC.HCLKRFFreq_Value=16000000 -RCC.HSE_VALUE=32000000 -RCC.HSI48_VALUE=48000000 -RCC.HSI_VALUE=16000000 -RCC.I2C1Freq_Value=64000000 -RCC.I2C3Freq_Value=64000000 -RCC.IPParameters=ADCFreq_Value,AHB2CLKDivider,AHBFreq_Value,APB1Freq_Value,APB1TimFreq_Value,APB2Freq_Value,APB2TimFreq_Value,APB3Freq_Value,Cortex2Freq_Value,CortexFreq_Value,EnableCSSLSE,EnbaleCSS,FCLK2Freq_Value,FCLKCortexFreq_Value,FamilyName,HCLK2Freq_Value,HCLK3Freq_Value,HCLKFreq_Value,HCLKRFFreq_Value,HSE_VALUE,HSI48_VALUE,HSI_VALUE,I2C1Freq_Value,I2C3Freq_Value,LCDFreq_Value,LPTIM1CLockSelection,LPTIM1Freq_Value,LPTIM2Freq_Value,LPUART1Freq_Value,LSCOPinFreq_Value,LSE_Drive_Capability,LSE_Timout,LSI_VALUE,MCO1PinFreq_Value,MSIOscState,PLLM,PLLPoutputFreq_Value,PLLQoutputFreq_Value,PLLRCLKFreq_Value,PLLSAI1N,PLLSAI1PoutputFreq_Value,PLLSAI1QoutputFreq_Value,PLLSAI1RoutputFreq_Value,PLLSourceVirtual,PREFETCH_ENABLE,PWRFreq_Value,RFWKPClockSelection,RFWKPFreq_Value,RNGCLockSelection,RNGFreq_Value,RTCClockSelection,RTCFreq_Value,SAI1Freq_Value,SMPS1Freq_Value,SMPSCLockSelectionVirtual,SMPSDivider,SMPSFreq_Value,SYSCLKFreq_VALUE,SYSCLKSource,USART1Freq_Value,USBFreq_Value,VCOInputFreq_Value,VCOOutputFreq_Value,VCOSAI1OutputFreq_Value -RCC.LCDFreq_Value=32768 -RCC.LPTIM1CLockSelection=RCC_LPTIM1CLKSOURCE_LSE -RCC.LPTIM1Freq_Value=32768 -RCC.LPTIM2Freq_Value=64000000 -RCC.LPUART1Freq_Value=64000000 -RCC.LSCOPinFreq_Value=32000 -RCC.LSE_Drive_Capability=RCC_LSEDRIVE_MEDIUMLOW -RCC.LSE_Timout=1000 -RCC.LSI_VALUE=32000 -RCC.MCO1PinFreq_Value=64000000 -RCC.MSIOscState=DISABLED -RCC.PLLM=RCC_PLLM_DIV2 -RCC.PLLPoutputFreq_Value=64000000 -RCC.PLLQoutputFreq_Value=64000000 -RCC.PLLRCLKFreq_Value=64000000 -RCC.PLLSAI1N=6 -RCC.PLLSAI1PoutputFreq_Value=48000000 -RCC.PLLSAI1QoutputFreq_Value=48000000 -RCC.PLLSAI1RoutputFreq_Value=48000000 -RCC.PLLSourceVirtual=RCC_PLLSOURCE_HSE -RCC.PREFETCH_ENABLE=1 -RCC.PWRFreq_Value=64000000 -RCC.RFWKPClockSelection=RCC_RFWKPCLKSOURCE_LSE -RCC.RFWKPFreq_Value=32768 -RCC.RNGCLockSelection=RCC_RNGCLKSOURCE_CLK48 -RCC.RNGFreq_Value=16000000 -RCC.RTCClockSelection=RCC_RTCCLKSOURCE_LSE -RCC.RTCFreq_Value=32768 -RCC.SAI1Freq_Value=48000000 -RCC.SMPS1Freq_Value=8000000 -RCC.SMPSCLockSelectionVirtual=RCC_SMPSCLKSOURCE_HSE -RCC.SMPSDivider=4 -RCC.SMPSFreq_Value=4000000 -RCC.SYSCLKFreq_VALUE=64000000 -RCC.SYSCLKSource=RCC_SYSCLKSOURCE_PLLCLK -RCC.USART1Freq_Value=64000000 -RCC.USBFreq_Value=48000000 -RCC.VCOInputFreq_Value=16000000 -RCC.VCOOutputFreq_Value=128000000 -RCC.VCOSAI1OutputFreq_Value=96000000 -RF1.Locked=true -RF1.Mode=RF1_Activate -RF1.Signal=RF_RF1 -SH.GPXTI10.0=GPIO_EXTI10 -SH.GPXTI10.ConfNb=1 -SH.GPXTI11.0=GPIO_EXTI11 -SH.GPXTI11.ConfNb=1 -SH.GPXTI12.0=GPIO_EXTI12 -SH.GPXTI12.ConfNb=1 -SH.GPXTI13.0=GPIO_EXTI13 -SH.GPXTI13.ConfNb=1 -SH.GPXTI3.0=GPIO_EXTI3 -SH.GPXTI3.ConfNb=1 -SH.S_TIM16_CH1.0=TIM16_CH1,PWM Generation1 CH1 -SH.S_TIM16_CH1.ConfNb=1 -SH.S_TIM2_CH1.0=TIM2_CH1,Input_Capture1_from_TI1 -SH.S_TIM2_CH1.1=TIM2_CH1,Input_Capture2_from_TI1 -SH.S_TIM2_CH1.ConfNb=2 -SH.SharedAnalog_PC5.0=COMP1_INP,INP -SH.SharedAnalog_PC5.1=ADC1_IN14,IN14-Single-Ended -SH.SharedAnalog_PC5.ConfNb=2 -SPI1.BaudRatePrescaler=SPI_BAUDRATEPRESCALER_16 -SPI1.CLKPhase=SPI_PHASE_2EDGE -SPI1.CalculateBaudRate=4.0 MBits/s -SPI1.DataSize=SPI_DATASIZE_8BIT -SPI1.Direction=SPI_DIRECTION_2LINES -SPI1.IPParameters=VirtualType,Mode,Direction,CalculateBaudRate,DataSize,CLKPhase,BaudRatePrescaler -SPI1.Mode=SPI_MODE_MASTER -SPI1.VirtualType=VM_MASTER -SPI2.BaudRatePrescaler=SPI_BAUDRATEPRESCALER_16 -SPI2.CLKPhase=SPI_PHASE_1EDGE -SPI2.CalculateBaudRate=4.0 MBits/s -SPI2.DataSize=SPI_DATASIZE_8BIT -SPI2.Direction=SPI_DIRECTION_2LINES -SPI2.IPParameters=VirtualType,Mode,Direction,CalculateBaudRate,DataSize,BaudRatePrescaler,CLKPhase -SPI2.Mode=SPI_MODE_MASTER -SPI2.VirtualType=VM_MASTER -TIM1.Channel-Output\ Compare1\ CH1N=TIM_CHANNEL_1 -TIM1.Channel-PWM\ Generation3\ CH3N=TIM_CHANNEL_3 -TIM1.IPParameters=Channel-Output Compare1 CH1N,Channel-PWM Generation3 CH3N -TIM16.Channel=TIM_CHANNEL_1 -TIM16.IPParameters=Channel,Pulse,Prescaler,Period -TIM16.Period=291 -TIM16.Prescaler=500 - 1 -TIM16.Pulse=145 -TIM2.AutoReloadPreload=TIM_AUTORELOAD_PRELOAD_ENABLE -TIM2.Channel-Input_Capture1_from_TI1=TIM_CHANNEL_1 -TIM2.Channel-Input_Capture2_from_TI1=TIM_CHANNEL_2 -TIM2.ICPolarity_CH1=TIM_INPUTCHANNELPOLARITY_FALLING -TIM2.IPParameters=Channel-Input_Capture1_from_TI1,ICPolarity_CH1,AutoReloadPreload,Prescaler,Channel-Input_Capture2_from_TI1 -TIM2.Prescaler=64-1 -USART1.AutoBaudRateEnableParam=UART_ADVFEATURE_AUTOBAUDRATE_ENABLE -USART1.IPParameters=VirtualMode-Asynchronous,Mode,AutoBaudRateEnableParam -USART1.Mode=MODE_TX -USART1.VirtualMode-Asynchronous=VM_ASYNC -USB_DEVICE.APP_RX_DATA_SIZE=512 -USB_DEVICE.APP_TX_DATA_SIZE=512 -USB_DEVICE.CLASS_NAME_FS=CDC -USB_DEVICE.IPParameters=VirtualMode,VirtualModeFS,CLASS_NAME_FS,MANUFACTURER_STRING,PRODUCT_STRING_CDC_FS,APP_RX_DATA_SIZE,APP_TX_DATA_SIZE -USB_DEVICE.MANUFACTURER_STRING=Flipper -USB_DEVICE.PRODUCT_STRING_CDC_FS=Flipper Control Virtual ComPort -USB_DEVICE.VirtualMode=Cdc -USB_DEVICE.VirtualModeFS=Cdc_FS -VP_ADC1_TempSens_Input.Mode=IN-TempSens -VP_ADC1_TempSens_Input.Signal=ADC1_TempSens_Input -VP_ADC1_Vref_Input.Mode=IN-Vrefint -VP_ADC1_Vref_Input.Signal=ADC1_Vref_Input -VP_AES1_VS_AES.Mode=AES_Activate -VP_AES1_VS_AES.Signal=AES1_VS_AES -VP_AES2_VS_AES.Mode=AES_Activate -VP_AES2_VS_AES.Signal=AES2_VS_AES -VP_COMP1_VS_VREFINT14.Mode=VREFINT_14 -VP_COMP1_VS_VREFINT14.Signal=COMP1_VS_VREFINT14 -VP_CRC_VS_CRC.Mode=CRC_Activate -VP_CRC_VS_CRC.Signal=CRC_VS_CRC -VP_FREERTOS_VS_CMSIS_V2.Mode=CMSIS_V2 -VP_FREERTOS_VS_CMSIS_V2.Signal=FREERTOS_VS_CMSIS_V2 -VP_HSEM_VS_HSEM.Mode=HSEM_Activate -VP_HSEM_VS_HSEM.Signal=HSEM_VS_HSEM -VP_PKA_VS_PKA.Mode=PKA_Activate -VP_PKA_VS_PKA.Signal=PKA_VS_PKA -VP_RNG_VS_RNG.Mode=RNG_Activate -VP_RNG_VS_RNG.Signal=RNG_VS_RNG -VP_RTC_VS_RTC_Activate.Mode=RTC_Enabled -VP_RTC_VS_RTC_Activate.Signal=RTC_VS_RTC_Activate -VP_RTC_VS_RTC_Calendar.Mode=RTC_Calendar -VP_RTC_VS_RTC_Calendar.Signal=RTC_VS_RTC_Calendar -VP_SYS_VS_Systick.Mode=SysTick -VP_SYS_VS_Systick.Signal=SYS_VS_Systick -VP_TIM16_VS_ClockSourceINT.Mode=Enable_Timer -VP_TIM16_VS_ClockSourceINT.Signal=TIM16_VS_ClockSourceINT -VP_TIM1_VS_ClockSourceINT.Mode=Internal -VP_TIM1_VS_ClockSourceINT.Signal=TIM1_VS_ClockSourceINT -VP_TIM2_VS_ClockSourceINT.Mode=Internal -VP_TIM2_VS_ClockSourceINT.Signal=TIM2_VS_ClockSourceINT -VP_USB_DEVICE_VS_USB_DEVICE_CDC_FS.Mode=CDC_FS -VP_USB_DEVICE_VS_USB_DEVICE_CDC_FS.Signal=USB_DEVICE_VS_USB_DEVICE_CDC_FS -board=custom diff --git a/firmware/targets/f7/cube/startup_stm32wb55xx_cm4.s b/firmware/targets/f7/cube/startup_stm32wb55xx_cm4.s deleted file mode 100644 index 053db01e424..00000000000 --- a/firmware/targets/f7/cube/startup_stm32wb55xx_cm4.s +++ /dev/null @@ -1,446 +0,0 @@ -/** - ****************************************************************************** - * @file startup_stm32wb55xx_cm4.s - * @author MCD Application Team - * @brief STM32WB55xx devices vector table GCC toolchain. - * This module performs: - * - Set the initial SP - * - Set the initial PC == Reset_Handler, - * - Set the vector table entries with the exceptions ISR address - * - Branches to main in the C library (which eventually - * calls main()). - * After Reset the Cortex-M4 processor is in Thread mode, - * priority is Privileged, and the Stack is set to Main. - ****************************************************************************** - * @attention - * - * Copyright (c) 2019-2021 STMicroelectronics. - * All rights reserved. - * - * This software is licensed under terms that can be found in the LICENSE file - * in the root directory of this software component. - * If no LICENSE file comes with this software, it is provided AS-IS. - * - ****************************************************************************** - */ - -.syntax unified -.cpu cortex-m4 -.fpu softvfp -.thumb - -.global g_pfnVectors -.global Default_Handler - -/* start address for the initialization values of the .data section. -defined in linker script */ -.word _sidata -/* start address for the .data section. defined in linker script */ -.word _sdata -/* end address for the .data section. defined in linker script */ -.word _edata -/* start address for the .bss section. defined in linker script */ -.word _sbss -/* end address for the .bss section. defined in linker script */ -.word _ebss -/* start address for the .MB_MEM2 section. defined in linker script */ -.word _sMB_MEM2 -/* end address for the .MB_MEM2 section. defined in linker script */ -.word _eMB_MEM2 - -/* INIT_BSS macro is used to fill the specified region [start : end] with zeros */ -.macro INIT_BSS start, end - ldr r0, =\start - ldr r1, =\end - movs r3, #0 - bl LoopFillZerobss -.endm - -/* INIT_DATA macro is used to copy data in the region [start : end] starting from 'src' */ -.macro INIT_DATA start, end, src - ldr r0, =\start - ldr r1, =\end - ldr r2, =\src - movs r3, #0 - bl LoopCopyDataInit -.endm - -.section .text.data_initializers -CopyDataInit: - ldr r4, [r2, r3] - str r4, [r0, r3] - adds r3, r3, #4 - -LoopCopyDataInit: - adds r4, r0, r3 - cmp r4, r1 - bcc CopyDataInit - bx lr - -FillZerobss: - str r3, [r0] - adds r0, r0, #4 - -LoopFillZerobss: - cmp r0, r1 - bcc FillZerobss - bx lr - - -.section .text.Reset_Handler -.weak Reset_Handler -.type Reset_Handler, %function - -Reset_Handler: - ldr r0, =_estack - mov sp, r0 /* set stack pointer */ - /* Call the clock system intitialization function.*/ - bl SystemInit - -/* Copy the data segment initializers from flash to SRAM */ - INIT_DATA _sdata, _edata, _sidata - -/* Zero fill the bss segments. */ - INIT_BSS _sbss, _ebss - INIT_BSS _sMB_MEM2, _eMB_MEM2 - -/* Call static constructors */ - bl __libc_init_array -/* Call the application s entry point.*/ - bl main - -LoopForever: - b LoopForever - -.size Reset_Handler, .-Reset_Handler - -/** - * @brief This is the code that gets called when the processor receives an - * unexpected interrupt. This simply enters an infinite loop, preserving - * the system state for examination by a debugger. - * - * @param None - * @retval None -*/ - .section .text.Default_Handler,"ax",%progbits -Default_Handler: -Infinite_Loop: - b Infinite_Loop - .size Default_Handler, .-Default_Handler -/****************************************************************************** -* -* The minimal vector table for a Cortex-M4. Note that the proper constructs -* must be placed on this to ensure that it ends up at physical address -* 0x0000.0000. -* -******************************************************************************/ - .section .isr_vector,"a",%progbits - .type g_pfnVectors, %object - .size g_pfnVectors, .-g_pfnVectors - - -g_pfnVectors: - .word _estack - .word Reset_Handler - .word NMI_Handler - .word HardFault_Handler - .word MemManage_Handler - .word BusFault_Handler - .word UsageFault_Handler - .word 0 - .word 0 - .word 0 - .word 0 - .word SVC_Handler - .word DebugMon_Handler - .word 0 - .word PendSV_Handler - .word SysTick_Handler - .word WWDG_IRQHandler - .word PVD_PVM_IRQHandler - .word TAMP_STAMP_LSECSS_IRQHandler - .word RTC_WKUP_IRQHandler - .word FLASH_IRQHandler - .word RCC_IRQHandler - .word EXTI0_IRQHandler - .word EXTI1_IRQHandler - .word EXTI2_IRQHandler - .word EXTI3_IRQHandler - .word EXTI4_IRQHandler - .word DMA1_Channel1_IRQHandler - .word DMA1_Channel2_IRQHandler - .word DMA1_Channel3_IRQHandler - .word DMA1_Channel4_IRQHandler - .word DMA1_Channel5_IRQHandler - .word DMA1_Channel6_IRQHandler - .word DMA1_Channel7_IRQHandler - .word ADC1_IRQHandler - .word USB_HP_IRQHandler - .word USB_LP_IRQHandler - .word C2SEV_PWR_C2H_IRQHandler - .word COMP_IRQHandler - .word EXTI9_5_IRQHandler - .word TIM1_BRK_IRQHandler - .word TIM1_UP_TIM16_IRQHandler - .word TIM1_TRG_COM_TIM17_IRQHandler - .word TIM1_CC_IRQHandler - .word TIM2_IRQHandler - .word PKA_IRQHandler - .word I2C1_EV_IRQHandler - .word I2C1_ER_IRQHandler - .word I2C3_EV_IRQHandler - .word I2C3_ER_IRQHandler - .word SPI1_IRQHandler - .word SPI2_IRQHandler - .word USART1_IRQHandler - .word LPUART1_IRQHandler - .word SAI1_IRQHandler - .word TSC_IRQHandler - .word EXTI15_10_IRQHandler - .word RTC_Alarm_IRQHandler - .word CRS_IRQHandler - .word PWR_SOTF_BLEACT_802ACT_RFPHASE_IRQHandler - .word IPCC_C1_RX_IRQHandler - .word IPCC_C1_TX_IRQHandler - .word HSEM_IRQHandler - .word LPTIM1_IRQHandler - .word LPTIM2_IRQHandler - .word LCD_IRQHandler - .word QUADSPI_IRQHandler - .word AES1_IRQHandler - .word AES2_IRQHandler - .word RNG_IRQHandler - .word FPU_IRQHandler - .word DMA2_Channel1_IRQHandler - .word DMA2_Channel2_IRQHandler - .word DMA2_Channel3_IRQHandler - .word DMA2_Channel4_IRQHandler - .word DMA2_Channel5_IRQHandler - .word DMA2_Channel6_IRQHandler - .word DMA2_Channel7_IRQHandler - .word DMAMUX1_OVR_IRQHandler - -/******************************************************************************* -* -* Provide weak aliases for each Exception handler to the Default_Handler. -* As they are weak aliases, any function with the same name will override -* this definition. -* -*******************************************************************************/ - .weak NMI_Handler - .thumb_set NMI_Handler,Default_Handler - - .weak HardFault_Handler - .thumb_set HardFault_Handler,Default_Handler - - .weak MemManage_Handler - .thumb_set MemManage_Handler,Default_Handler - - .weak BusFault_Handler - .thumb_set BusFault_Handler,Default_Handler - - .weak UsageFault_Handler - .thumb_set UsageFault_Handler,Default_Handler - - .weak SVC_Handler - .thumb_set SVC_Handler,Default_Handler - - .weak DebugMon_Handler - .thumb_set DebugMon_Handler,Default_Handler - - .weak PendSV_Handler - .thumb_set PendSV_Handler,Default_Handler - - .weak SysTick_Handler - .thumb_set SysTick_Handler,Default_Handler - - .weak WWDG_IRQHandler - .thumb_set WWDG_IRQHandler,Default_Handler - - .weak PVD_PVM_IRQHandler - .thumb_set PVD_PVM_IRQHandler,Default_Handler - - .weak TAMP_STAMP_LSECSS_IRQHandler - .thumb_set TAMP_STAMP_LSECSS_IRQHandler,Default_Handler - - .weak RTC_WKUP_IRQHandler - .thumb_set RTC_WKUP_IRQHandler,Default_Handler - - .weak FLASH_IRQHandler - .thumb_set FLASH_IRQHandler,Default_Handler - - .weak RCC_IRQHandler - .thumb_set RCC_IRQHandler,Default_Handler - - .weak EXTI0_IRQHandler - .thumb_set EXTI0_IRQHandler,Default_Handler - - .weak EXTI1_IRQHandler - .thumb_set EXTI1_IRQHandler,Default_Handler - - .weak EXTI2_IRQHandler - .thumb_set EXTI2_IRQHandler,Default_Handler - - .weak EXTI3_IRQHandler - .thumb_set EXTI3_IRQHandler,Default_Handler - - .weak EXTI4_IRQHandler - .thumb_set EXTI4_IRQHandler,Default_Handler - - .weak DMA1_Channel1_IRQHandler - .thumb_set DMA1_Channel1_IRQHandler,Default_Handler - - .weak DMA1_Channel2_IRQHandler - .thumb_set DMA1_Channel2_IRQHandler,Default_Handler - - .weak DMA1_Channel3_IRQHandler - .thumb_set DMA1_Channel3_IRQHandler,Default_Handler - - .weak DMA1_Channel4_IRQHandler - .thumb_set DMA1_Channel4_IRQHandler,Default_Handler - - .weak DMA1_Channel5_IRQHandler - .thumb_set DMA1_Channel5_IRQHandler,Default_Handler - - .weak DMA1_Channel6_IRQHandler - .thumb_set DMA1_Channel6_IRQHandler,Default_Handler - - .weak DMA1_Channel7_IRQHandler - .thumb_set DMA1_Channel7_IRQHandler,Default_Handler - - .weak ADC1_IRQHandler - .thumb_set ADC1_IRQHandler,Default_Handler - - .weak USB_HP_IRQHandler - .thumb_set USB_HP_IRQHandler,Default_Handler - - .weak USB_LP_IRQHandler - .thumb_set USB_LP_IRQHandler,Default_Handler - - .weak C2SEV_PWR_C2H_IRQHandler - .thumb_set C2SEV_PWR_C2H_IRQHandler,Default_Handler - - .weak COMP_IRQHandler - .thumb_set COMP_IRQHandler,Default_Handler - - .weak EXTI9_5_IRQHandler - .thumb_set EXTI9_5_IRQHandler,Default_Handler - - .weak TIM1_BRK_IRQHandler - .thumb_set TIM1_BRK_IRQHandler,Default_Handler - - .weak TIM1_UP_TIM16_IRQHandler - .thumb_set TIM1_UP_TIM16_IRQHandler,Default_Handler - - .weak TIM1_TRG_COM_TIM17_IRQHandler - .thumb_set TIM1_TRG_COM_TIM17_IRQHandler,Default_Handler - - .weak TIM1_CC_IRQHandler - .thumb_set TIM1_CC_IRQHandler,Default_Handler - - .weak TIM2_IRQHandler - .thumb_set TIM2_IRQHandler,Default_Handler - - .weak PKA_IRQHandler - .thumb_set PKA_IRQHandler,Default_Handler - - .weak I2C1_EV_IRQHandler - .thumb_set I2C1_EV_IRQHandler,Default_Handler - - .weak I2C1_ER_IRQHandler - .thumb_set I2C1_ER_IRQHandler,Default_Handler - - .weak I2C3_EV_IRQHandler - .thumb_set I2C3_EV_IRQHandler,Default_Handler - - .weak I2C3_ER_IRQHandler - .thumb_set I2C3_ER_IRQHandler,Default_Handler - - .weak SPI1_IRQHandler - .thumb_set SPI1_IRQHandler,Default_Handler - - .weak SPI2_IRQHandler - .thumb_set SPI2_IRQHandler,Default_Handler - - .weak USART1_IRQHandler - .thumb_set USART1_IRQHandler,Default_Handler - - .weak LPUART1_IRQHandler - .thumb_set LPUART1_IRQHandler,Default_Handler - - .weak SAI1_IRQHandler - .thumb_set SAI1_IRQHandler,Default_Handler - - .weak TSC_IRQHandler - .thumb_set TSC_IRQHandler,Default_Handler - - .weak EXTI15_10_IRQHandler - .thumb_set EXTI15_10_IRQHandler,Default_Handler - - .weak RTC_Alarm_IRQHandler - .thumb_set RTC_Alarm_IRQHandler,Default_Handler - - .weak CRS_IRQHandler - .thumb_set CRS_IRQHandler,Default_Handler - - .weak PWR_SOTF_BLEACT_802ACT_RFPHASE_IRQHandler - .thumb_set PWR_SOTF_BLEACT_802ACT_RFPHASE_IRQHandler,Default_Handler - - .weak IPCC_C1_RX_IRQHandler - .thumb_set IPCC_C1_RX_IRQHandler,Default_Handler - - .weak IPCC_C1_TX_IRQHandler - .thumb_set IPCC_C1_TX_IRQHandler,Default_Handler - - .weak HSEM_IRQHandler - .thumb_set HSEM_IRQHandler,Default_Handler - - .weak LPTIM1_IRQHandler - .thumb_set LPTIM1_IRQHandler,Default_Handler - - .weak LPTIM2_IRQHandler - .thumb_set LPTIM2_IRQHandler,Default_Handler - - .weak LCD_IRQHandler - .thumb_set LCD_IRQHandler,Default_Handler - - .weak QUADSPI_IRQHandler - .thumb_set QUADSPI_IRQHandler,Default_Handler - - .weak AES1_IRQHandler - .thumb_set AES1_IRQHandler,Default_Handler - - .weak AES2_IRQHandler - .thumb_set AES2_IRQHandler,Default_Handler - - .weak RNG_IRQHandler - .thumb_set RNG_IRQHandler,Default_Handler - - .weak FPU_IRQHandler - .thumb_set FPU_IRQHandler,Default_Handler - - .weak DMA2_Channel1_IRQHandler - .thumb_set DMA2_Channel1_IRQHandler,Default_Handler - - .weak DMA2_Channel2_IRQHandler - .thumb_set DMA2_Channel2_IRQHandler,Default_Handler - - .weak DMA2_Channel3_IRQHandler - .thumb_set DMA2_Channel3_IRQHandler,Default_Handler - - .weak DMA2_Channel4_IRQHandler - .thumb_set DMA2_Channel4_IRQHandler,Default_Handler - - .weak DMA2_Channel5_IRQHandler - .thumb_set DMA2_Channel5_IRQHandler,Default_Handler - - .weak DMA2_Channel6_IRQHandler - .thumb_set DMA2_Channel6_IRQHandler,Default_Handler - - .weak DMA2_Channel7_IRQHandler - .thumb_set DMA2_Channel7_IRQHandler,Default_Handler - - .weak DMAMUX1_OVR_IRQHandler - .thumb_set DMAMUX1_OVR_IRQHandler,Default_Handler - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/firmware/targets/f7/cube/stm32wb55xx_flash_cm4.ld b/firmware/targets/f7/cube/stm32wb55xx_flash_cm4.ld deleted file mode 100644 index caa19463d1f..00000000000 --- a/firmware/targets/f7/cube/stm32wb55xx_flash_cm4.ld +++ /dev/null @@ -1,187 +0,0 @@ -/** -***************************************************************************** -** -** File : stm32wb55xx_flash_cm4.ld -** -** Abstract : System Workbench Minimal System calls file -** -** For more information about which c-functions -** need which of these lowlevel functions -** please consult the Newlib libc-manual -** -** Environment : System Workbench for MCU -** -** Distribution: The file is distributed “as is,” without any warranty -** of any kind. -** -***************************************************************************** -** -**

© COPYRIGHT(c) 2019 Ac6

-** -** Redistribution and use in source and binary forms, with or without modification, -** are permitted provided that the following conditions are met: -** 1. Redistributions of source code must retain the above copyright notice, -** this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright notice, -** this list of conditions and the following disclaimer in the documentation -** and/or other materials provided with the distribution. -** 3. Neither the name of Ac6 nor the names of its contributors -** may be used to endorse or promote products derived from this software -** without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -** SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -** OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -** -***************************************************************************** -*/ - -/* Entry Point */ -ENTRY(Reset_Handler) - -/* Highest address of the user mode stack */ -_estack = 0x20030000; /* end of RAM */ -/* Generate a link error if heap and stack don't fit into RAM */ -_Min_Heap_Size = 0x400; /* required amount of heap */ -_Min_Stack_Size = 0x1000; /* required amount of stack */ - -/* Specify the memory areas */ -MEMORY -{ -FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 512K -RAM1 (xrw) : ORIGIN = 0x20000008, LENGTH = 0x2FFF8 -RAM_SHARED (xrw) : ORIGIN = 0x20030000, LENGTH = 10K -} - -/* Define output sections */ -SECTIONS -{ - /* The startup code goes first into FLASH */ - .isr_vector : - { - . = ALIGN(4); - KEEP(*(.isr_vector)) /* Startup code */ - . = ALIGN(4); - } >FLASH - - /* The program code and other data goes into FLASH */ - .text : - { - . = ALIGN(4); - *(.text) /* .text sections (code) */ - *(.text*) /* .text* sections (code) */ - *(.glue_7) /* glue arm to thumb code */ - *(.glue_7t) /* glue thumb to arm code */ - *(.eh_frame) - - KEEP (*(.init)) - KEEP (*(.fini)) - - . = ALIGN(4); - _etext = .; /* define a global symbols at end of code */ - } >FLASH - - /* Constant data goes into FLASH */ - .rodata : - { - . = ALIGN(4); - *(.rodata) /* .rodata sections (constants, strings, etc.) */ - *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ - . = ALIGN(4); - } >FLASH - - .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH - .ARM : { - __exidx_start = .; - *(.ARM.exidx*) - __exidx_end = .; - } >FLASH - - .preinit_array : - { - PROVIDE_HIDDEN (__preinit_array_start = .); - KEEP (*(.preinit_array*)) - PROVIDE_HIDDEN (__preinit_array_end = .); - } >FLASH - .init_array : - { - PROVIDE_HIDDEN (__init_array_start = .); - KEEP (*(SORT(.init_array.*))) - KEEP (*(.init_array*)) - PROVIDE_HIDDEN (__init_array_end = .); - } >FLASH - .fini_array : - { - PROVIDE_HIDDEN (__fini_array_start = .); - KEEP (*(SORT(.fini_array.*))) - KEEP (*(.fini_array*)) - PROVIDE_HIDDEN (__fini_array_end = .); - } >FLASH - - /* used by the startup to initialize data */ - _sidata = LOADADDR(.data); - - /* Initialized data sections goes into RAM, load LMA copy after code */ - .data : - { - . = ALIGN(4); - _sdata = .; /* create a global symbol at data start */ - *(.data) /* .data sections */ - *(.data*) /* .data* sections */ - - . = ALIGN(4); - _edata = .; /* define a global symbol at data end */ - } >RAM1 AT> FLASH - - - /* Uninitialized data section */ - . = ALIGN(4); - .bss : - { - /* This is used by the startup in order to initialize the .bss secion */ - _sbss = .; /* define a global symbol at bss start */ - __bss_start__ = _sbss; - *(.bss) - *(.bss*) - *(COMMON) - - . = ALIGN(4); - _ebss = .; /* define a global symbol at bss end */ - __bss_end__ = _ebss; - } >RAM1 - - /* User_heap_stack section, used to check that there is enough RAM left */ - ._user_heap_stack : - { - . = ALIGN(8); - PROVIDE ( end = . ); - PROVIDE ( _end = . ); - . = . + _Min_Heap_Size; - . = . + _Min_Stack_Size; - . = ALIGN(8); - } >RAM1 - - - - /* Remove information from the standard libraries */ - /DISCARD/ : - { - libc.a ( * ) - libm.a ( * ) - libgcc.a ( * ) - } - - .ARM.attributes 0 : { *(.ARM.attributes) } - MAPPING_TABLE (NOLOAD) : { *(MAPPING_TABLE) } >RAM_SHARED - MB_MEM1 (NOLOAD) : { *(MB_MEM1) } >RAM_SHARED - MB_MEM2 (NOLOAD) : { _sMB_MEM2 = . ; *(MB_MEM2) ; _eMB_MEM2 = . ; } >RAM_SHARED -} - - diff --git a/firmware/targets/f7/fatfs/ffconf.h b/firmware/targets/f7/fatfs/ffconf.h index 91c6c00c141..83bcfc783c0 100644 --- a/firmware/targets/f7/fatfs/ffconf.h +++ b/firmware/targets/f7/fatfs/ffconf.h @@ -27,8 +27,11 @@ /*-----------------------------------------------------------------------------/ / Function Configurations /-----------------------------------------------------------------------------*/ - +#ifdef FURI_RAM_EXEC +#define _FS_READONLY 1 /* 0:Read/Write or 1:Read only */ +#else #define _FS_READONLY 0 /* 0:Read/Write or 1:Read only */ +#endif /* This option switches read-only configuration. (0:Read/Write or 1:Read-only) / Read-only configuration removes writing API functions, f_write(), f_sync(), / f_unlink(), f_mkdir(), f_chmod(), f_rename(), f_truncate(), f_getfree() @@ -55,7 +58,11 @@ /* This option switches filtered directory read functions, f_findfirst() and / f_findnext(). (0:Disable, 1:Enable 2:Enable with matching altname[] too) */ +#ifdef FURI_RAM_EXEC +#define _USE_MKFS 0 +#else #define _USE_MKFS 1 +#endif /* This option switches f_mkfs() function. (0:Disable or 1:Enable) */ #define _USE_FASTSEEK 1 diff --git a/firmware/targets/f7/furi_hal/furi_hal.c b/firmware/targets/f7/furi_hal/furi_hal.c index a8be527b5be..e671dd8cd8b 100644 --- a/firmware/targets/f7/furi_hal/furi_hal.c +++ b/firmware/targets/f7/furi_hal/furi_hal.c @@ -6,15 +6,43 @@ #define TAG "FuriHal" +void furi_hal_init_early() { + furi_hal_clock_init_early(); + furi_hal_delay_init(); + + furi_hal_resources_init_early(); + + furi_hal_spi_init_early(); + + furi_hal_i2c_init_early(); + furi_hal_light_init(); + + furi_hal_rtc_init_early(); +} + +void furi_hal_deinit_early() { + furi_hal_rtc_deinit_early(); + + furi_hal_i2c_deinit_early(); + furi_hal_spi_deinit_early(); + + furi_hal_resources_deinit_early(); + + furi_hal_clock_deinit_early(); +} + void furi_hal_init() { + furi_hal_clock_init(); + furi_hal_console_init(); furi_hal_rtc_init(); + furi_hal_interrupt_init(); - furi_hal_delay_init(); + + furi_hal_flash_init(); furi_hal_resources_init(); FURI_LOG_I(TAG, "GPIO OK"); - furi_hal_bootloader_init(); furi_hal_version_init(); furi_hal_spi_init(); @@ -25,21 +53,26 @@ void furi_hal_init() { FURI_LOG_I(TAG, "Speaker OK"); furi_hal_crypto_init(); + furi_hal_crc_init(true); // VCP + USB +#ifndef FURI_RAM_EXEC furi_hal_usb_init(); furi_hal_vcp_init(); FURI_LOG_I(TAG, "USB OK"); +#endif furi_hal_i2c_init(); // High Level furi_hal_power_init(); furi_hal_light_init(); +#ifndef FURI_RAM_EXEC furi_hal_vibro_init(); furi_hal_subghz_init(); furi_hal_nfc_init(); furi_hal_rfid_init(); +#endif furi_hal_bt_init(); furi_hal_compress_icon_init(); @@ -62,7 +95,13 @@ void furi_hal_init() { LL_MPU_Enable(LL_MPU_CTRL_PRIVILEGED_DEFAULT); } -void furi_hal_init_critical() { - furi_hal_clock_init(); - furi_hal_console_init(); +void furi_hal_switch(void* address) { + __set_BASEPRI(0); + asm volatile("ldr r3, [%0] \n" + "msr msp, r3 \n" + "ldr r3, [%1] \n" + "mov pc, r3 \n" + : + : "r"(address), "r"(address + 0x4) + : "r3"); } diff --git a/firmware/targets/f7/furi_hal/furi_hal_bootloader.c b/firmware/targets/f7/furi_hal/furi_hal_bootloader.c deleted file mode 100644 index 3b5499559dc..00000000000 --- a/firmware/targets/f7/furi_hal/furi_hal_bootloader.c +++ /dev/null @@ -1,25 +0,0 @@ -#include -#include -#include - -#define TAG "FuriHalBoot" - -// Boot request enum -#define BOOT_REQUEST_TAINTED 0x00000000 -#define BOOT_REQUEST_CLEAN 0xDADEDADE -#define BOOT_REQUEST_DFU 0xDF00B000 - -void furi_hal_bootloader_init() { -#ifndef DEBUG - furi_hal_rtc_set_register(FuriHalRtcRegisterBoot, BOOT_REQUEST_TAINTED); -#endif - FURI_LOG_I(TAG, "Init OK"); -} - -void furi_hal_bootloader_set_mode(FuriHalBootloaderMode mode) { - if(mode == FuriHalBootloaderModeNormal) { - furi_hal_rtc_set_register(FuriHalRtcRegisterBoot, BOOT_REQUEST_CLEAN); - } else if(mode == FuriHalBootloaderModeDFU) { - furi_hal_rtc_set_register(FuriHalRtcRegisterBoot, BOOT_REQUEST_DFU); - } -} diff --git a/firmware/targets/f7/furi_hal/furi_hal_clock.c b/firmware/targets/f7/furi_hal/furi_hal_clock.c index 962f2123744..ca5e56497d7 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_clock.c +++ b/firmware/targets/f7/furi_hal/furi_hal_clock.c @@ -13,6 +13,39 @@ #define HS_CLOCK_IS_READY() (LL_RCC_HSE_IsReady() && LL_RCC_HSI_IsReady()) #define LS_CLOCK_IS_READY() (LL_RCC_LSE_IsReady() && LL_RCC_LSI1_IsReady()) +void furi_hal_clock_init_early() { + LL_Init1msTick(4000000); + LL_SetSystemCoreClock(4000000); + + LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOA); + LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOB); + LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOC); + LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOD); + LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOE); + LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOH); + + LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_SPI1); + LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_SPI2); + + LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_I2C1); + LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_I2C3); +} + +void furi_hal_clock_deinit_early() { + LL_APB1_GRP1_DisableClock(LL_APB1_GRP1_PERIPH_I2C1); + LL_APB1_GRP1_DisableClock(LL_APB1_GRP1_PERIPH_I2C3); + + LL_APB2_GRP1_DisableClock(LL_APB2_GRP1_PERIPH_SPI1); + LL_APB1_GRP1_DisableClock(LL_APB1_GRP1_PERIPH_SPI2); + + LL_AHB2_GRP1_DisableClock(LL_AHB2_GRP1_PERIPH_GPIOA); + LL_AHB2_GRP1_DisableClock(LL_AHB2_GRP1_PERIPH_GPIOB); + LL_AHB2_GRP1_DisableClock(LL_AHB2_GRP1_PERIPH_GPIOC); + LL_AHB2_GRP1_DisableClock(LL_AHB2_GRP1_PERIPH_GPIOD); + LL_AHB2_GRP1_DisableClock(LL_AHB2_GRP1_PERIPH_GPIOE); + LL_AHB2_GRP1_DisableClock(LL_AHB2_GRP1_PERIPH_GPIOH); +} + void furi_hal_clock_init() { /* Prepare Flash memory for 64mHz system clock */ LL_FLASH_SetLatency(LL_FLASH_LATENCY_3); diff --git a/firmware/targets/f7/furi_hal/furi_hal_clock.h b/firmware/targets/f7/furi_hal/furi_hal_clock.h index 3ec59205113..0a1099acbd7 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_clock.h +++ b/firmware/targets/f7/furi_hal/furi_hal_clock.h @@ -1,5 +1,11 @@ #pragma once +/** Early initialization */ +void furi_hal_clock_init_early(); + +/** Early deinitialization */ +void furi_hal_clock_deinit_early(); + /** Initialize clocks */ void furi_hal_clock_init(); diff --git a/firmware/targets/f7/furi_hal/furi_hal_crc.c b/firmware/targets/f7/furi_hal/furi_hal_crc.c new file mode 100644 index 00000000000..321809d9116 --- /dev/null +++ b/firmware/targets/f7/furi_hal/furi_hal_crc.c @@ -0,0 +1,88 @@ +#include +#include + +typedef enum { + CRC_State_Reset, + CRC_State_Ready, + CRC_State_Busy, +} CRC_State; + +typedef struct { + CRC_State state; + osMutexId_t mtx; +} HAL_CRC_Control; + +static volatile HAL_CRC_Control hal_crc_control = { + .state = CRC_State_Reset, + .mtx = NULL, +}; + +void furi_hal_crc_init(bool synchronize) { + /* initialize peripheral with default generating polynomial */ + LL_CRC_SetInputDataReverseMode(CRC, LL_CRC_INDATA_REVERSE_BYTE); + LL_CRC_SetOutputDataReverseMode(CRC, LL_CRC_OUTDATA_REVERSE_BIT); + LL_CRC_SetPolynomialCoef(CRC, LL_CRC_DEFAULT_CRC32_POLY); + LL_CRC_SetPolynomialSize(CRC, LL_CRC_POLYLENGTH_32B); + LL_CRC_SetInitialData(CRC, LL_CRC_DEFAULT_CRC_INITVALUE); + + if(synchronize) { + hal_crc_control.mtx = osMutexNew(NULL); + } + hal_crc_control.state = CRC_State_Ready; +} + +void furi_hal_crc_reset() { + furi_check(hal_crc_control.state == CRC_State_Ready); + if(hal_crc_control.mtx) { + osMutexRelease(hal_crc_control.mtx); + } + LL_CRC_ResetCRCCalculationUnit(CRC); +} + +static uint32_t furi_hal_crc_handle_8(uint8_t pBuffer[], uint32_t BufferLength) { + uint32_t i; /* input data buffer index */ + hal_crc_control.state = CRC_State_Busy; + /* Processing time optimization: 4 bytes are entered in a row with a single word write, + * last bytes must be carefully fed to the CRC calculator to ensure a correct type + * handling by the peripheral */ + for(i = 0U; i < (BufferLength / 4U); i++) { + LL_CRC_FeedData32( + CRC, + ((uint32_t)pBuffer[4U * i] << 24U) | ((uint32_t)pBuffer[(4U * i) + 1U] << 16U) | + ((uint32_t)pBuffer[(4U * i) + 2U] << 8U) | (uint32_t)pBuffer[(4U * i) + 3U]); + } + /* last bytes specific handling */ + if((BufferLength % 4U) != 0U) { + if((BufferLength % 4U) == 1U) { + LL_CRC_FeedData8(CRC, pBuffer[4U * i]); + } else if((BufferLength % 4U) == 2U) { + LL_CRC_FeedData16( + CRC, ((uint16_t)(pBuffer[4U * i]) << 8U) | (uint16_t)pBuffer[(4U * i) + 1U]); + } else if((BufferLength % 4U) == 3U) { + LL_CRC_FeedData16( + CRC, ((uint16_t)(pBuffer[4U * i]) << 8U) | (uint16_t)pBuffer[(4U * i) + 1U]); + LL_CRC_FeedData8(CRC, pBuffer[(4U * i) + 2U]); + } + } + + hal_crc_control.state = CRC_State_Ready; + /* Return the CRC computed value */ + return LL_CRC_ReadData32(CRC); +} + +static uint32_t furi_hal_crc_accumulate(uint32_t pBuffer[], uint32_t BufferLength) { + furi_check(hal_crc_control.state == CRC_State_Ready); + if(hal_crc_control.mtx) { + furi_check(osMutexGetOwner(hal_crc_control.mtx) != NULL); + } + return furi_hal_crc_handle_8((uint8_t*)pBuffer, BufferLength); +} + +uint32_t furi_hal_crc_feed(void* data, uint16_t length) { + return ~furi_hal_crc_accumulate(data, length); +} + +bool furi_hal_crc_acquire(uint32_t timeout) { + furi_assert(hal_crc_control.mtx); + return osMutexAcquire(hal_crc_control.mtx, timeout) == osOK; +} diff --git a/firmware/targets/f7/furi_hal/furi_hal_crc.h b/firmware/targets/f7/furi_hal/furi_hal_crc.h new file mode 100644 index 00000000000..110e6c05fa3 --- /dev/null +++ b/firmware/targets/f7/furi_hal/furi_hal_crc.h @@ -0,0 +1,35 @@ +#pragma once + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** Configure for CRC32 calculation + * @param synchronize enforce acquisition & release in multithreaded environment + */ +void furi_hal_crc_init(bool synchronize); + +/** Blocking call to get control of CRC block. Mandatory while RTOS is running + * @param timeout time to wait for CRC to be available. Can be osWaitForever + * @return bool acquisition success + */ +bool furi_hal_crc_acquire(uint32_t timeout); + +/** Reset current calculation state and release CRC block + */ +void furi_hal_crc_reset(); + +/** Process data block. Does not reset current state, + * allowing to process arbitrary data lengths + * @param data pointer to data + * @param length data length + * @return uint32_t CRC32 value + */ +uint32_t furi_hal_crc_feed(void* data, uint16_t length); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/firmware/targets/f7/furi_hal/furi_hal_delay.c b/firmware/targets/f7/furi_hal/furi_hal_delay.c index bb852ca97cb..8a26d8dc946 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_delay.c +++ b/firmware/targets/f7/furi_hal/furi_hal_delay.c @@ -2,17 +2,20 @@ #include #include +#include #define TAG "FuriHalDelay" -uint32_t instructions_per_us; + static volatile uint32_t tick_cnt = 0; -void furi_hal_delay_init(void) { +void furi_hal_delay_init() { CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk; DWT->CYCCNT = 0U; - instructions_per_us = SystemCoreClock / 1000000.0f; - FURI_LOG_I(TAG, "Init OK"); +} + +uint32_t furi_hal_delay_instructions_per_microsecond() { + return SystemCoreClock / 1000000; } void furi_hal_tick(void) { @@ -25,7 +28,7 @@ uint32_t furi_hal_get_tick(void) { void furi_hal_delay_us(float microseconds) { uint32_t start = DWT->CYCCNT; - uint32_t time_ticks = microseconds * instructions_per_us; + uint32_t time_ticks = microseconds * furi_hal_delay_instructions_per_microsecond(); while((DWT->CYCCNT - start) < time_ticks) { }; } @@ -33,8 +36,12 @@ void furi_hal_delay_us(float microseconds) { // cannot be used in ISR // TODO add delay_ISR variant void furi_hal_delay_ms(float milliseconds) { - uint32_t ticks = milliseconds / (1000.0f / osKernelGetTickFreq()); - osStatus_t result = osDelay(ticks); - (void)result; - furi_assert(result == osOK); + if(!FURI_IS_ISR() && osKernelGetState() == osKernelRunning) { + uint32_t ticks = milliseconds / (1000.0f / osKernelGetTickFreq()); + osStatus_t result = osDelay(ticks); + (void)result; + furi_assert(result == osOK); + } else { + furi_hal_delay_us(milliseconds * 1000); + } } diff --git a/firmware/targets/f7/furi_hal/furi_hal_flash.c b/firmware/targets/f7/furi_hal/furi_hal_flash.c index fc1dbd2f886..aaf7f1a2517 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_flash.c +++ b/firmware/targets/f7/furi_hal/furi_hal_flash.c @@ -14,7 +14,9 @@ #define FURI_HAL_FLASH_CYCLES_COUNT 10000 #define FURI_HAL_FLASH_TIMEOUT 1000 #define FURI_HAL_FLASH_KEY1 0x45670123U + #define FURI_HAL_FLASH_KEY2 0xCDEF89ABU +#define FURI_HAL_FLASH_TOTAL_PAGES 256 #define FURI_HAL_FLASH_SR_ERRORS \ (FLASH_SR_OPERR | FLASH_SR_PROGERR | FLASH_SR_WRPERR | FLASH_SR_PGAERR | FLASH_SR_SIZERR | \ FLASH_SR_PGSERR | FLASH_SR_MISERR | FLASH_SR_FASTERR | FLASH_SR_RDERR | FLASH_SR_OPTVERR) @@ -72,6 +74,12 @@ size_t furi_hal_flash_get_free_page_count() { return (end - page_start) / FURI_HAL_FLASH_PAGE_SIZE; } +void furi_hal_flash_init() { + // Errata 2.2.9, Flash OPTVERR flag is always set after system reset + WRITE_REG(FLASH->SR, FLASH_SR_OPTVERR); + //__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_OPTVERR); +} + static void furi_hal_flash_unlock() { /* verify Flash is locked */ furi_check(READ_BIT(FLASH->CR, FLASH_CR_LOCK) != 0U); @@ -283,6 +291,22 @@ bool furi_hal_flash_erase(uint8_t page) { return true; } +static inline bool furi_hal_flash_write_dword_internal(size_t address, uint64_t* data) { + /* Program first word */ + *(uint32_t*)address = (uint32_t)*data; + + // Barrier to ensure programming is performed in 2 steps, in right order + // (independently of compiler optimization behavior) + __ISB(); + + /* Program second word */ + *(uint32_t*)(address + 4U) = (uint32_t)(*data >> 32U); + + /* Wait for last operation to be completed */ + furi_check(furi_hal_flash_wait_last_operation(FURI_HAL_FLASH_TIMEOUT)); + return true; +} + bool furi_hal_flash_write_dword(size_t address, uint64_t data) { furi_hal_flash_begin(false); @@ -296,23 +320,70 @@ bool furi_hal_flash_write_dword(size_t address, uint64_t data) { /* Set PG bit */ SET_BIT(FLASH->CR, FLASH_CR_PG); - /* Program first word */ - *(uint32_t*)address = (uint32_t)data; + /* Do the thing */ + furi_check(furi_hal_flash_write_dword_internal(address, &data)); - // Barrier to ensure programming is performed in 2 steps, in right order - // (independently of compiler optimization behavior) - __ISB(); + /* If the program operation is completed, disable the PG or FSTPG Bit */ + CLEAR_BIT(FLASH->CR, FLASH_CR_PG); - /* Program second word */ - *(uint32_t*)(address + 4U) = (uint32_t)(data >> 32U); + furi_hal_flash_end(false); /* Wait for last operation to be completed */ furi_check(furi_hal_flash_wait_last_operation(FURI_HAL_FLASH_TIMEOUT)); + return true; +} + +static size_t furi_hal_flash_get_page_address(uint8_t page) { + return furi_hal_flash_get_base() + page * FURI_HAL_FLASH_PAGE_SIZE; +} + +bool furi_hal_flash_program_page(const uint8_t page, const uint8_t* data, uint16_t _length) { + uint16_t length = _length; + furi_check(length <= FURI_HAL_FLASH_PAGE_SIZE); + + furi_hal_flash_erase(page); + + furi_hal_flash_begin(false); + + // Ensure that controller state is valid + furi_check(FLASH->SR == 0); + + size_t page_start_address = furi_hal_flash_get_page_address(page); + + /* Set PG bit */ + SET_BIT(FLASH->CR, FLASH_CR_PG); + size_t i_dwords = 0; + for(i_dwords = 0; i_dwords < (length / 8); ++i_dwords) { + /* Do the thing */ + size_t data_offset = i_dwords * 8; + furi_check(furi_hal_flash_write_dword_internal( + page_start_address + data_offset, (uint64_t*)&data[data_offset])); + } + if((length % 8) != 0) { + /* there are more bytes, not fitting into dwords */ + uint64_t tail_data = 0; + size_t data_offset = i_dwords * 8; + for(int32_t tail_i = 0; tail_i < (length % 8); ++tail_i) { + tail_data |= (((uint64_t)data[data_offset + tail_i]) << (tail_i * 8)); + } + + furi_check( + furi_hal_flash_write_dword_internal(page_start_address + data_offset, &tail_data)); + } /* If the program operation is completed, disable the PG or FSTPG Bit */ CLEAR_BIT(FLASH->CR, FLASH_CR_PG); furi_hal_flash_end(false); - return true; } + +int16_t furi_hal_flash_get_page_number(size_t address) { + const size_t flash_base = furi_hal_flash_get_base(); + if((address < flash_base) || + (address > flash_base + FURI_HAL_FLASH_TOTAL_PAGES * FURI_HAL_FLASH_PAGE_SIZE)) { + return -1; + } + + return (address - flash_base) / FURI_HAL_FLASH_PAGE_SIZE; +} \ No newline at end of file diff --git a/firmware/targets/f7/furi_hal/furi_hal_flash.h b/firmware/targets/f7/furi_hal/furi_hal_flash.h index 37f714b8a00..004c1340571 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_flash.h +++ b/firmware/targets/f7/furi_hal/furi_hal_flash.h @@ -4,6 +4,10 @@ #include #include +/** Init flash, applying necessary workarounds + */ +void furi_hal_flash_init(); + /** Get flash base address * * @return pointer to flash base @@ -78,3 +82,22 @@ bool furi_hal_flash_erase(uint8_t page); * @return true on success */ bool furi_hal_flash_write_dword(size_t address, uint64_t data); + +/** Write aligned page data (up to page size) + * + * @warning locking operation with critical section, stales execution + * + * @param address destination address, must be page aligned. + * @param data data to write + * @param length data length + * + * @return true on success + */ +bool furi_hal_flash_program_page(const uint8_t page, const uint8_t* data, uint16_t length); + +/** Get flash page number for address + * + * @return page number, -1 for invalid address + */ + +int16_t furi_hal_flash_get_page_number(size_t address); \ No newline at end of file diff --git a/firmware/targets/f7/furi_hal/furi_hal_i2c.c b/firmware/targets/f7/furi_hal/furi_hal_i2c.c index 03c39a44c1b..7e0bee58b64 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_i2c.c +++ b/firmware/targets/f7/furi_hal/furi_hal_i2c.c @@ -9,8 +9,15 @@ #define TAG "FuriHalI2C" -void furi_hal_i2c_init() { +void furi_hal_i2c_init_early() { furi_hal_i2c_bus_power.callback(&furi_hal_i2c_bus_power, FuriHalI2cBusEventInit); +} + +void furi_hal_i2c_deinit_early() { + furi_hal_i2c_bus_power.callback(&furi_hal_i2c_bus_power, FuriHalI2cBusEventDeinit); +} + +void furi_hal_i2c_init() { furi_hal_i2c_bus_external.callback(&furi_hal_i2c_bus_external, FuriHalI2cBusEventInit); FURI_LOG_I(TAG, "Init OK"); } diff --git a/firmware/targets/f7/furi_hal/furi_hal_i2c_config.c b/firmware/targets/f7/furi_hal/furi_hal_i2c_config.c index 84cada611b3..2cdef23ac76 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_i2c_config.c +++ b/firmware/targets/f7/furi_hal/furi_hal_i2c_config.c @@ -27,7 +27,11 @@ static void furi_hal_i2c_bus_power_event(FuriHalI2cBus* bus, FuriHalI2cBusEvent FURI_CRITICAL_EXIT(); bus->current_handle = NULL; } else if(event == FuriHalI2cBusEventDeinit) { - osMutexDelete(furi_hal_i2c_bus_power_mutex); + furi_check(osMutexDelete(furi_hal_i2c_bus_power_mutex) == osOK); + FURI_CRITICAL_ENTER(); + LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_I2C1); + LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_I2C1); + FURI_CRITICAL_EXIT(); } else if(event == FuriHalI2cBusEventLock) { furi_check(osMutexAcquire(furi_hal_i2c_bus_power_mutex, osWaitForever) == osOK); } else if(event == FuriHalI2cBusEventUnlock) { @@ -51,7 +55,24 @@ FuriHalI2cBus furi_hal_i2c_bus_power = { osMutexId_t furi_hal_i2c_bus_external_mutex = NULL; static void furi_hal_i2c_bus_external_event(FuriHalI2cBus* bus, FuriHalI2cBusEvent event) { - if(event == FuriHalI2cBusEventActivate) { + if(event == FuriHalI2cBusEventInit) { + furi_hal_i2c_bus_external_mutex = osMutexNew(NULL); + FURI_CRITICAL_ENTER(); + LL_RCC_SetI2CClockSource(LL_RCC_I2C3_CLKSOURCE_PCLK1); + LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_I2C3); + FURI_CRITICAL_EXIT(); + bus->current_handle = NULL; + } else if(event == FuriHalI2cBusEventDeinit) { + furi_check(osMutexDelete(furi_hal_i2c_bus_external_mutex) == osOK); + FURI_CRITICAL_ENTER(); + LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_I2C3); + LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_I2C3); + FURI_CRITICAL_EXIT(); + } else if(event == FuriHalI2cBusEventLock) { + furi_check(osMutexAcquire(furi_hal_i2c_bus_external_mutex, osWaitForever) == osOK); + } else if(event == FuriHalI2cBusEventUnlock) { + furi_check(osMutexRelease(furi_hal_i2c_bus_external_mutex) == osOK); + } else if(event == FuriHalI2cBusEventActivate) { FURI_CRITICAL_ENTER(); LL_RCC_SetI2CClockSource(LL_RCC_I2C3_CLKSOURCE_PCLK1); LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_I2C3); diff --git a/firmware/targets/f7/furi_hal/furi_hal_info.c b/firmware/targets/f7/furi_hal/furi_hal_info.c index 893716db702..77eab1282cd 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_info.c +++ b/firmware/targets/f7/furi_hal/furi_hal_info.c @@ -50,22 +50,14 @@ void furi_hal_info_get(FuriHalInfoValueCallback out, void* context) { out("hardware_name", name, false, context); } - // Bootloader Version - const Version* bootloader_version = furi_hal_version_get_bootloader_version(); - if(bootloader_version) { - out("bootloader_commit", version_get_githash(bootloader_version), false, context); - out("bootloader_branch", version_get_gitbranch(bootloader_version), false, context); - out("bootloader_branch_num", version_get_gitbranchnum(bootloader_version), false, context); - out("bootloader_version", version_get_version(bootloader_version), false, context); - out("bootloader_build_date", version_get_builddate(bootloader_version), false, context); - string_printf(value, "%d", version_get_target(bootloader_version)); - out("bootloader_target", string_get_cstr(value), false, context); - } - // Firmware version const Version* firmware_version = furi_hal_version_get_firmware_version(); if(firmware_version) { out("firmware_commit", version_get_githash(firmware_version), false, context); + out("firmware_commit_dirty", + version_get_dirty_flag(firmware_version) ? "true" : "false", + false, + context); out("firmware_branch", version_get_gitbranch(firmware_version), false, context); out("firmware_branch_num", version_get_gitbranchnum(firmware_version), false, context); out("firmware_version", version_get_version(firmware_version), false, context); @@ -139,4 +131,4 @@ void furi_hal_info_get(FuriHalInfoValueCallback out, void* context) { out("protobuf_version_minor", string_get_cstr(value), true, context); string_clear(value); -} +} \ No newline at end of file diff --git a/firmware/targets/f7/furi_hal/furi_hal_interrupt.c b/firmware/targets/f7/furi_hal/furi_hal_interrupt.c index 5bee8067b7b..e9fc023b001 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_interrupt.c +++ b/firmware/targets/f7/furi_hal/furi_hal_interrupt.c @@ -253,7 +253,9 @@ void SysTick_Handler(void) { } void USB_LP_IRQHandler(void) { +#ifndef FURI_RAM_EXEC usbd_poll(&udev); +#endif } void IPCC_C1_TX_IRQHandler(void) { @@ -262,4 +264,4 @@ void IPCC_C1_TX_IRQHandler(void) { void IPCC_C1_RX_IRQHandler(void) { HW_IPCC_Rx_Handler(); -} +} \ No newline at end of file diff --git a/firmware/targets/f7/furi_hal/furi_hal_light.c b/firmware/targets/f7/furi_hal/furi_hal_light.c index 1bd1adad6d2..864b3c6e7be 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_light.c +++ b/firmware/targets/f7/furi_hal/furi_hal_light.c @@ -1,4 +1,5 @@ #include +#include #include #define LED_CURRENT_RED 50 @@ -50,3 +51,30 @@ void furi_hal_light_set(Light light, uint8_t value) { } furi_hal_i2c_release(&furi_hal_i2c_handle_power); } + +void furi_hal_light_sequence(const char* sequence) { + do { + if(*sequence == 'R') { + furi_hal_light_set(LightRed, 0xFF); + } else if(*sequence == 'r') { + furi_hal_light_set(LightRed, 0x00); + } else if(*sequence == 'G') { + furi_hal_light_set(LightGreen, 0xFF); + } else if(*sequence == 'g') { + furi_hal_light_set(LightGreen, 0x00); + } else if(*sequence == 'B') { + furi_hal_light_set(LightBlue, 0xFF); + } else if(*sequence == 'b') { + furi_hal_light_set(LightBlue, 0x00); + } else if(*sequence == 'W') { + furi_hal_light_set(LightBacklight, 0xFF); + } else if(*sequence == 'w') { + furi_hal_light_set(LightBacklight, 0x00); + } else if(*sequence == '.') { + furi_hal_delay_ms(250); + } else if(*sequence == '-') { + furi_hal_delay_ms(500); + } + sequence++; + } while(*sequence != 0); +} diff --git a/firmware/targets/f7/furi_hal/furi_hal_resources.c b/firmware/targets/f7/furi_hal/furi_hal_resources.c index 734967b745f..901955856c7 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_resources.c +++ b/firmware/targets/f7/furi_hal/furi_hal_resources.c @@ -56,6 +56,9 @@ const GpioPin gpio_speaker = {.port = GPIOB, .pin = LL_GPIO_PIN_8}; const GpioPin periph_power = {.port = PERIPH_POWER_GPIO_Port, .pin = PERIPH_POWER_Pin}; +const GpioPin gpio_usb_dm = {.port = GPIOA, .pin = LL_GPIO_PIN_11}; +const GpioPin gpio_usb_dp = {.port = GPIOA, .pin = LL_GPIO_PIN_12}; + const InputPin input_pins[] = { {.gpio = &gpio_button_up, .key = InputKeyUp, .inverted = true, .name = "Up"}, {.gpio = &gpio_button_down, .key = InputKeyDown, .inverted = true, .name = "Down"}, @@ -67,7 +70,22 @@ const InputPin input_pins[] = { const size_t input_pins_count = sizeof(input_pins) / sizeof(InputPin); -void furi_hal_resources_init(void) { +void furi_hal_resources_init_early() { + furi_hal_gpio_init(&gpio_button_left, GpioModeInput, GpioPullUp, GpioSpeedLow); + furi_hal_gpio_init_simple(&gpio_display_rst, GpioModeOutputPushPull); + furi_hal_gpio_init_simple(&gpio_display_di, GpioModeOutputPushPull); + + // Hard reset USB + furi_hal_gpio_init_simple(&gpio_usb_dm, GpioModeOutputOpenDrain); + furi_hal_gpio_init_simple(&gpio_usb_dp, GpioModeOutputOpenDrain); + furi_hal_gpio_write(&gpio_usb_dm, 0); + furi_hal_gpio_write(&gpio_usb_dp, 0); +} + +void furi_hal_resources_deinit_early() { +} + +void furi_hal_resources_init() { // Button pins for(size_t i = 0; i < input_pins_count; i++) { furi_hal_gpio_init( diff --git a/firmware/targets/f7/furi_hal/furi_hal_resources.h b/firmware/targets/f7/furi_hal/furi_hal_resources.h index 1f3a4bce209..eaafd7c524e 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_resources.h +++ b/firmware/targets/f7/furi_hal/furi_hal_resources.h @@ -54,6 +54,13 @@ extern const GpioPin gpio_sdcard_cs; extern const GpioPin gpio_sdcard_cd; extern const GpioPin gpio_nfc_cs; +extern const GpioPin gpio_button_up; +extern const GpioPin gpio_button_down; +extern const GpioPin gpio_button_right; +extern const GpioPin gpio_button_left; +extern const GpioPin gpio_button_ok; +extern const GpioPin gpio_button_back; + extern const GpioPin gpio_spi_d_miso; extern const GpioPin gpio_spi_d_mosi; extern const GpioPin gpio_spi_d_sck; @@ -87,6 +94,9 @@ extern const GpioPin gpio_speaker; extern const GpioPin periph_power; +extern const GpioPin gpio_usb_dm; +extern const GpioPin gpio_usb_dp; + #define BUTTON_BACK_GPIO_Port GPIOC #define BUTTON_BACK_Pin LL_GPIO_PIN_13 #define BUTTON_DOWN_GPIO_Port GPIOC @@ -193,7 +203,11 @@ extern const GpioPin periph_power; #define NFC_IRQ_Pin RFID_PULL_Pin #define NFC_IRQ_GPIO_Port RFID_PULL_GPIO_Port -void furi_hal_resources_init(void); +void furi_hal_resources_init_early(); + +void furi_hal_resources_deinit_early(); + +void furi_hal_resources_init(); #ifdef __cplusplus } diff --git a/firmware/targets/f7/furi_hal/furi_hal_rtc.c b/firmware/targets/f7/furi_hal/furi_hal_rtc.c index 33fc9307947..748d7e41c28 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_rtc.c +++ b/firmware/targets/f7/furi_hal/furi_hal_rtc.c @@ -1,20 +1,84 @@ #include +#include + +#include +#include #include #include +#include #include #define TAG "FuriHalRtc" +#define RTC_CLOCK_IS_READY() (LL_RCC_LSE_IsReady() && LL_RCC_LSI1_IsReady()) + +#define FURI_HAL_RTC_HEADER_MAGIC 0x10F1 +#define FURI_HAL_RTC_HEADER_VERSION 0 + +typedef struct { + uint16_t magic; + uint8_t version; + uint8_t unused; +} FuriHalRtcHeader; + typedef struct { uint8_t log_level : 4; uint8_t log_reserved : 4; uint8_t flags; - uint16_t reserved; + uint8_t boot_mode : 4; + uint16_t reserved : 12; } DeveloperReg; _Static_assert(sizeof(DeveloperReg) == 4, "DeveloperReg size mismatch"); +void furi_hal_rtc_init_early() { + // LSE and RTC + LL_PWR_EnableBkUpAccess(); + if(!RTC_CLOCK_IS_READY()) { + // Start LSI1 needed for CSS + LL_RCC_LSI1_Enable(); + // Try to start LSE normal way + LL_RCC_LSE_SetDriveCapability(LL_RCC_LSEDRIVE_HIGH); + LL_RCC_LSE_Enable(); + uint32_t c = 0; + while(!RTC_CLOCK_IS_READY() && c < 200) { + LL_mDelay(10); + c++; + } + // Plan B: reset backup domain + if(!RTC_CLOCK_IS_READY()) { + furi_hal_light_sequence("rgb R.r.R.r.R"); + LL_RCC_ForceBackupDomainReset(); + LL_RCC_ReleaseBackupDomainReset(); + NVIC_SystemReset(); + } + // Set RTC domain clock to LSE + LL_RCC_SetRTCClockSource(LL_RCC_RTC_CLKSOURCE_LSE); + // Enable LSE CSS + LL_RCC_LSE_EnableCSS(); + } + // Enable clocking + LL_RCC_EnableRTC(); + LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_RTCAPB); + + // Verify header register + uint32_t data_reg = furi_hal_rtc_get_register(FuriHalRtcRegisterHeader); + FuriHalRtcHeader* data = (FuriHalRtcHeader*)&data_reg; + if(data->magic != FURI_HAL_RTC_HEADER_MAGIC || data->version != FURI_HAL_RTC_HEADER_VERSION) { + // Reset all our registers to ensure consistency + for(size_t i = 0; i < FuriHalRtcRegisterMAX; i++) { + furi_hal_rtc_set_register(i, 0); + } + data->magic = FURI_HAL_RTC_HEADER_MAGIC; + data->version = FURI_HAL_RTC_HEADER_VERSION; + furi_hal_rtc_set_register(FuriHalRtcRegisterHeader, data_reg); + } +} + +void furi_hal_rtc_deinit_early() { +} + void furi_hal_rtc_init() { if(LL_RCC_GetRTCClockSource() != LL_RCC_RTC_CLKSOURCE_LSE) { LL_RCC_ForceBackupDomainReset(); @@ -77,6 +141,19 @@ bool furi_hal_rtc_is_flag_set(FuriHalRtcFlag flag) { return data->flags & flag; } +void furi_hal_rtc_set_boot_mode(FuriHalRtcBootMode mode) { + uint32_t data_reg = furi_hal_rtc_get_register(FuriHalRtcRegisterSystem); + DeveloperReg* data = (DeveloperReg*)&data_reg; + data->boot_mode = mode; + furi_hal_rtc_set_register(FuriHalRtcRegisterSystem, data_reg); +} + +FuriHalRtcBootMode furi_hal_rtc_get_boot_mode() { + uint32_t data_reg = furi_hal_rtc_get_register(FuriHalRtcRegisterSystem); + DeveloperReg* data = (DeveloperReg*)&data_reg; + return (FuriHalRtcBootMode)data->boot_mode; +} + void furi_hal_rtc_set_datetime(FuriHalRtcDateTime* datetime) { furi_assert(datetime); diff --git a/firmware/targets/f7/furi_hal/furi_hal_spi.c b/firmware/targets/f7/furi_hal/furi_hal_spi.c index 8af2879f0df..d74a394a7cc 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_spi.c +++ b/firmware/targets/f7/furi_hal/furi_hal_spi.c @@ -11,13 +11,21 @@ #define TAG "FuriHalSpi" +void furi_hal_spi_init_early() { + furi_hal_spi_bus_init(&furi_hal_spi_bus_d); + furi_hal_spi_bus_handle_init(&furi_hal_spi_bus_handle_display); +} + +void furi_hal_spi_deinit_early() { + furi_hal_spi_bus_handle_deinit(&furi_hal_spi_bus_handle_display); + furi_hal_spi_bus_deinit(&furi_hal_spi_bus_d); +} + void furi_hal_spi_init() { furi_hal_spi_bus_init(&furi_hal_spi_bus_r); - furi_hal_spi_bus_init(&furi_hal_spi_bus_d); furi_hal_spi_bus_handle_init(&furi_hal_spi_bus_handle_subghz); furi_hal_spi_bus_handle_init(&furi_hal_spi_bus_handle_nfc); - furi_hal_spi_bus_handle_init(&furi_hal_spi_bus_handle_display); furi_hal_spi_bus_handle_init(&furi_hal_spi_bus_handle_sd_fast); furi_hal_spi_bus_handle_init(&furi_hal_spi_bus_handle_sd_slow); diff --git a/firmware/targets/f7/furi_hal/furi_hal_spi_config.c b/firmware/targets/f7/furi_hal/furi_hal_spi_config.c index 440a64a0d01..0bdb25082a1 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_spi_config.c +++ b/firmware/targets/f7/furi_hal/furi_hal_spi_config.c @@ -80,7 +80,11 @@ static void furi_hal_spi_bus_r_event_callback(FuriHalSpiBus* bus, FuriHalSpiBusE FURI_CRITICAL_EXIT(); bus->current_handle = NULL; } else if(event == FuriHalSpiBusEventDeinit) { - furi_check(osMutexDelete(furi_hal_spi_bus_r_mutex)); + furi_check(osMutexDelete(furi_hal_spi_bus_r_mutex) == osOK); + FURI_CRITICAL_ENTER(); + LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_SPI1); + LL_APB2_GRP1_ReleaseReset(LL_APB2_GRP1_PERIPH_SPI1); + FURI_CRITICAL_EXIT(); } else if(event == FuriHalSpiBusEventLock) { furi_check(osMutexAcquire(furi_hal_spi_bus_r_mutex, osWaitForever) == osOK); } else if(event == FuriHalSpiBusEventUnlock) { @@ -111,7 +115,11 @@ static void furi_hal_spi_bus_d_event_callback(FuriHalSpiBus* bus, FuriHalSpiBusE FURI_CRITICAL_EXIT(); bus->current_handle = NULL; } else if(event == FuriHalSpiBusEventDeinit) { - furi_check(osMutexDelete(furi_hal_spi_bus_d_mutex)); + furi_check(osMutexDelete(furi_hal_spi_bus_d_mutex) == osOK); + FURI_CRITICAL_ENTER(); + LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_SPI2); + LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_SPI2); + FURI_CRITICAL_EXIT(); } else if(event == FuriHalSpiBusEventLock) { furi_check(osMutexAcquire(furi_hal_spi_bus_d_mutex, osWaitForever) == osOK); } else if(event == FuriHalSpiBusEventUnlock) { diff --git a/firmware/targets/f7/furi_hal/furi_hal_vcp.c b/firmware/targets/f7/furi_hal/furi_hal_vcp.c index b0edf9db2e2..5040deed501 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_vcp.c +++ b/firmware/targets/f7/furi_hal/furi_hal_vcp.c @@ -64,6 +64,11 @@ void furi_hal_vcp_init() { vcp->tx_stream = xStreamBufferCreate(VCP_TX_BUF_SIZE, 1); vcp->rx_stream = xStreamBufferCreate(VCP_RX_BUF_SIZE, 1); + if(furi_hal_rtc_get_boot_mode() != FuriHalRtcBootModeNormal) { + FURI_LOG_W(TAG, "Skipped worker init: device in special startup mode="); + return; + } + vcp->thread = furi_thread_alloc(); furi_thread_set_name(vcp->thread, "VcpDriver"); furi_thread_set_stack_size(vcp->thread, 1024); diff --git a/firmware/targets/f7/furi_hal/furi_hal_version.c b/firmware/targets/f7/furi_hal/furi_hal_version.c index 821de05a4cf..be92b348bd3 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_version.c +++ b/firmware/targets/f7/furi_hal/furi_hal_version.c @@ -192,7 +192,7 @@ void furi_hal_version_init() { furi_crash(NULL); } - furi_hal_rtc_set_register(FuriHalRtcRegisterSystemVersion, (uint32_t)version_get()); + furi_hal_rtc_set_register(FuriHalRtcRegisterVersion, (uint32_t)version_get()); FURI_LOG_I(TAG, "Init OK"); } @@ -280,15 +280,6 @@ const struct Version* furi_hal_version_get_firmware_version(void) { return version_get(); } -const struct Version* furi_hal_version_get_bootloader_version(void) { -#ifdef NO_BOOTLOADER - return 0; -#else - /* Backup register which points to structure in flash memory */ - return (const struct Version*)furi_hal_rtc_get_register(FuriHalRtcRegisterBootVersion); -#endif -} - size_t furi_hal_version_uid_size() { return 64 / 8; } diff --git a/firmware/targets/f7/stm32wb55xx_flash_cm4_no_bootloader.ld b/firmware/targets/f7/stm32wb55xx_flash.ld similarity index 100% rename from firmware/targets/f7/stm32wb55xx_flash_cm4_no_bootloader.ld rename to firmware/targets/f7/stm32wb55xx_flash.ld diff --git a/firmware/targets/f7/stm32wb55xx_flash_cm4_with_bootloader.ld b/firmware/targets/f7/stm32wb55xx_ram_fw.ld similarity index 95% rename from firmware/targets/f7/stm32wb55xx_flash_cm4_with_bootloader.ld rename to firmware/targets/f7/stm32wb55xx_ram_fw.ld index e2a2171674f..8c4d41c5b2a 100644 --- a/firmware/targets/f7/stm32wb55xx_flash_cm4_with_bootloader.ld +++ b/firmware/targets/f7/stm32wb55xx_ram_fw.ld @@ -55,8 +55,8 @@ _Min_Stack_Size = 0x1000; /* required amount of stack */ /* Specify the memory areas */ MEMORY { -FLASH (rx) : ORIGIN = 0x08008000, LENGTH = 992K -RAM1 (xrw) : ORIGIN = 0x20000008, LENGTH = 0x2FFF8 +FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 1024K +RAM1 (xrw) : ORIGIN = 0x20000000, LENGTH = 0x30000 RAM_SHARED (xrw) : ORIGIN = 0x20030000, LENGTH = 10K } @@ -69,7 +69,7 @@ SECTIONS . = ALIGN(4); KEEP(*(.isr_vector)) /* Startup code */ . = ALIGN(4); - } >FLASH + } >RAM1 /* The program code and other data goes into FLASH */ .text : @@ -86,7 +86,7 @@ SECTIONS . = ALIGN(4); _etext = .; /* define a global symbols at end of code */ - } >FLASH + } >RAM1 /* Constant data goes into FLASH */ .rodata : @@ -95,35 +95,35 @@ SECTIONS *(.rodata) /* .rodata sections (constants, strings, etc.) */ *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ . = ALIGN(4); - } >FLASH + } >RAM1 .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH .ARM : { __exidx_start = .; *(.ARM.exidx*) __exidx_end = .; - } >FLASH + } >RAM1 .preinit_array : { PROVIDE_HIDDEN (__preinit_array_start = .); KEEP (*(.preinit_array*)) PROVIDE_HIDDEN (__preinit_array_end = .); - } >FLASH + } >RAM1 .init_array : { PROVIDE_HIDDEN (__init_array_start = .); KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array*)) PROVIDE_HIDDEN (__init_array_end = .); - } >FLASH + } >RAM1 .fini_array : { PROVIDE_HIDDEN (__fini_array_start = .); KEEP (*(SORT(.fini_array.*))) KEEP (*(.fini_array*)) PROVIDE_HIDDEN (__fini_array_end = .); - } >FLASH + } >RAM1 /* used by the startup to initialize data */ _sidata = LOADADDR(.data); @@ -138,7 +138,7 @@ SECTIONS . = ALIGN(4); _edata = .; /* define a global symbol at data end */ - } >RAM1 AT> FLASH + } >RAM1 AT> RAM1 /* Uninitialized data section */ @@ -169,11 +169,11 @@ SECTIONS } >RAM1 /* Free Flash space, that can be used for internal storage */ - .free_flash(NOLOAD): + /*.free_flash(NOLOAD): { __free_flash_start__ = .; . = ORIGIN(FLASH) + LENGTH(FLASH); - } >FLASH + } >FLASH*/ /* Remove information from the standard libraries */ /DISCARD/ : diff --git a/firmware/targets/f7/target.mk b/firmware/targets/f7/target.mk index 6f010890a00..1822b6284e1 100644 --- a/firmware/targets/f7/target.mk +++ b/firmware/targets/f7/target.mk @@ -1,17 +1,12 @@ TOOLCHAIN = arm -BOOT_ADDRESS = 0x08000000 -FW_ADDRESS = 0x08008000 -OS_OFFSET = 0x00008000 -FLASH_ADDRESS = 0x08008000 - -NO_BOOTLOADER ?= 0 -ifeq ($(NO_BOOTLOADER), 1) -BOOT_ADDRESS = 0x08000000 -FW_ADDRESS = 0x08000000 -OS_OFFSET = 0x00000000 FLASH_ADDRESS = 0x08000000 -CFLAGS += -DNO_BOOTLOADER + +RAM_EXEC ?= 0 +ifeq ($(RAM_EXEC), 1) +CFLAGS += -DFURI_RAM_EXEC -DVECT_TAB_SRAM -DFLIPPER_STREAM_LITE +else +LDFLAGS += -u _printf_float endif DEBUG_RTOS_THREADS ?= 1 @@ -21,11 +16,10 @@ else OPENOCD_OPTS = -f interface/stlink.cfg -c "transport select hla_swd" -f ../debug/stm32wbx.cfg -c "init" endif -BOOT_CFLAGS = -DBOOT_ADDRESS=$(BOOT_ADDRESS) -DFW_ADDRESS=$(FW_ADDRESS) -DOS_OFFSET=$(OS_OFFSET) MCU_FLAGS = -mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=hard -CFLAGS += $(MCU_FLAGS) $(BOOT_CFLAGS) -DSTM32WB55xx -Wall -fdata-sections -ffunction-sections -LDFLAGS += $(MCU_FLAGS) -specs=nosys.specs -specs=nano.specs -u _printf_float +CFLAGS += $(MCU_FLAGS) -DSTM32WB55xx -Wall -fdata-sections -ffunction-sections +LDFLAGS += $(MCU_FLAGS) -specs=nosys.specs -specs=nano.specs CPPFLAGS += -fno-rtti -fno-use-cxa-atexit -fno-exceptions LDFLAGS += -Wl,--start-group -lstdc++ -lsupc++ -Wl,--end-group @@ -146,11 +140,11 @@ C_SOURCES += \ $(wildcard $(MXPROJECT_DIR)/Src/*.c) \ $(wildcard $(MXPROJECT_DIR)/fatfs/*.c) +ifeq ($(RAM_EXEC), 1) +LDFLAGS += -T$(MXPROJECT_DIR)/stm32wb55xx_ram_fw.ld +else # RAM_EXEC # Linker options -ifeq ($(NO_BOOTLOADER), 1) -LDFLAGS += -T$(MXPROJECT_DIR)/stm32wb55xx_flash_cm4_no_bootloader.ld -else -LDFLAGS += -T$(MXPROJECT_DIR)/stm32wb55xx_flash_cm4_with_bootloader.ld -endif +LDFLAGS += -T$(MXPROJECT_DIR)/stm32wb55xx_flash.ld +endif # RAM_EXEC SVD_FILE = ../debug/STM32WB55_CM4.svd diff --git a/firmware/targets/furi_hal_include/furi_hal.h b/firmware/targets/furi_hal_include/furi_hal.h index 59e9e89b4d7..76e96ef6cea 100644 --- a/firmware/targets/furi_hal_include/furi_hal.h +++ b/firmware/targets/furi_hal_include/furi_hal.h @@ -9,7 +9,6 @@ template struct STOP_EXTERNING_ME {}; #endif -#include "furi_hal_bootloader.h" #include "furi_hal_clock.h" #include "furi_hal_crypto.h" #include "furi_hal_console.h" @@ -40,12 +39,27 @@ template struct STOP_EXTERNING_ME {}; #include "furi_hal_uart.h" #include "furi_hal_info.h" #include "furi_hal_random.h" +#include "furi_hal_crc.h" -/** Init furi_hal */ +#ifdef __cplusplus +extern "C" { +#endif + +/** Early FuriHal init, only essential subsystems */ +void furi_hal_init_early(); + +/** Early FuriHal deinit */ +void furi_hal_deinit_early(); + +/** Init FuriHal */ void furi_hal_init(); -/** - * Init critical parts of furi_hal - * That code should not use memory allocations +/** Transfer execution to address + * + * @param[in] address pointer to new executable */ -void furi_hal_init_critical(); +void furi_hal_switch(void* address); + +#ifdef __cplusplus +} +#endif diff --git a/firmware/targets/furi_hal_include/furi_hal_bootloader.h b/firmware/targets/furi_hal_include/furi_hal_bootloader.h deleted file mode 100644 index 51a9c4e811d..00000000000 --- a/firmware/targets/furi_hal_include/furi_hal_bootloader.h +++ /dev/null @@ -1,29 +0,0 @@ -/** - * @file furi_hal_bootloader.h - * Bootloader HAL API - */ - -#pragma once - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** Boot modes */ -typedef enum { FuriHalBootloaderModeNormal, FuriHalBootloaderModeDFU } FuriHalBootloaderMode; - -/** Initialize boot subsystem - */ -void furi_hal_bootloader_init(); - -/** Set bootloader mode - * - * @param[in] mode FuriHalBootloaderMode - */ -void furi_hal_bootloader_set_mode(FuriHalBootloaderMode mode); - -#ifdef __cplusplus -} -#endif diff --git a/firmware/targets/furi_hal_include/furi_hal_delay.h b/firmware/targets/furi_hal_include/furi_hal_delay.h index d0e216f8301..58b4ed9b332 100644 --- a/firmware/targets/furi_hal_include/furi_hal_delay.h +++ b/firmware/targets/furi_hal_include/furi_hal_delay.h @@ -6,16 +6,17 @@ #pragma once #include +#include #ifdef __cplusplus extern "C" { #endif -extern uint32_t instructions_per_us; +/** Init Delay subsystem */ +void furi_hal_delay_init(); -/** Init DWT - */ -void furi_hal_delay_init(void); +/** Get instructions per microsecond count */ +uint32_t furi_hal_delay_instructions_per_microsecond(); /** Increase tick counter. * Should be called from SysTick ISR diff --git a/firmware/targets/furi_hal_include/furi_hal_i2c.h b/firmware/targets/furi_hal_include/furi_hal_i2c.h index 5550ab08259..566574ab826 100644 --- a/firmware/targets/furi_hal_include/furi_hal_i2c.h +++ b/firmware/targets/furi_hal_include/furi_hal_i2c.h @@ -13,8 +13,13 @@ extern "C" { #endif -/** Init I2C - */ +/** Early Init I2C */ +void furi_hal_i2c_init_early(); + +/** Early DeInit I2C */ +void furi_hal_i2c_deinit_early(); + +/** Init I2C */ void furi_hal_i2c_init(); /** Acquire i2c bus handle diff --git a/firmware/targets/furi_hal_include/furi_hal_light.h b/firmware/targets/furi_hal_include/furi_hal_light.h index 569778d0546..e3d244c3cbc 100644 --- a/firmware/targets/furi_hal_include/furi_hal_light.h +++ b/firmware/targets/furi_hal_include/furi_hal_light.h @@ -24,6 +24,12 @@ void furi_hal_light_init(); */ void furi_hal_light_set(Light light, uint8_t value); +/** Execute sequence + * + * @param sequence Sequence to execute + */ +void furi_hal_light_sequence(const char* sequence); + #ifdef __cplusplus } #endif diff --git a/firmware/targets/furi_hal_include/furi_hal_rtc.h b/firmware/targets/furi_hal_include/furi_hal_rtc.h index e06978e1fc1..5b6a778076f 100644 --- a/firmware/targets/furi_hal_include/furi_hal_rtc.h +++ b/firmware/targets/furi_hal_include/furi_hal_rtc.h @@ -31,15 +31,32 @@ typedef enum { } FuriHalRtcFlag; typedef enum { - FuriHalRtcRegisterBoot, - FuriHalRtcRegisterBootVersion, - FuriHalRtcRegisterSystem, - FuriHalRtcRegisterSystemVersion, - FuriHalRtcRegisterLfsFingerprint, - FuriHalRtcRegisterFaultData, - FuriHalRtcRegisterPinFails, + FuriHalRtcBootModeNormal = 0, /**< Normal boot mode, default value */ + FuriHalRtcBootModeDfu, /**< Boot to DFU (MCU bootloader by ST) */ + FuriHalRtcBootModePreUpdate, /**< Boot to Update, pre update */ + FuriHalRtcBootModeUpdate, /**< Boot to Update, main */ + FuriHalRtcBootModePostUpdate, /**< Boot to Update, post update */ +} FuriHalRtcBootMode; + +typedef enum { + FuriHalRtcRegisterHeader, /**< RTC structure header */ + FuriHalRtcRegisterSystem, /**< Various system bits */ + FuriHalRtcRegisterVersion, /**< Pointer to Version */ + FuriHalRtcRegisterLfsFingerprint, /**< LFS geometry fingerprint */ + FuriHalRtcRegisterFaultData, /**< Pointer to last fault message */ + FuriHalRtcRegisterPinFails, /**< Failed pins count */ + /* Index of FS directory entry corresponding to FW update to be applied */ + FuriHalRtcRegisterUpdateFolderFSIndex, + + FuriHalRtcRegisterMAX, /**< Service value, do not use */ } FuriHalRtcRegister; +/** Early initialization */ +void furi_hal_rtc_init_early(); + +/** Early deinitialization */ +void furi_hal_rtc_deinit_early(); + /** Initialize RTC subsystem */ void furi_hal_rtc_init(); @@ -57,6 +74,10 @@ void furi_hal_rtc_reset_flag(FuriHalRtcFlag flag); bool furi_hal_rtc_is_flag_set(FuriHalRtcFlag flag); +void furi_hal_rtc_set_boot_mode(FuriHalRtcBootMode mode); + +FuriHalRtcBootMode furi_hal_rtc_get_boot_mode(); + void furi_hal_rtc_set_datetime(FuriHalRtcDateTime* datetime); void furi_hal_rtc_get_datetime(FuriHalRtcDateTime* datetime); diff --git a/firmware/targets/furi_hal_include/furi_hal_spi.h b/firmware/targets/furi_hal_include/furi_hal_spi.h index be31727f063..df7ffa93d23 100644 --- a/firmware/targets/furi_hal_include/furi_hal_spi.h +++ b/firmware/targets/furi_hal_include/furi_hal_spi.h @@ -7,6 +7,12 @@ extern "C" { #endif +/** Early initialize SPI HAL */ +void furi_hal_spi_init_early(); + +/** Early deinitialize SPI HAL */ +void furi_hal_spi_deinit_early(); + /** Initialize SPI HAL */ void furi_hal_spi_init(); @@ -99,4 +105,4 @@ bool furi_hal_spi_bus_trx( #ifdef __cplusplus } -#endif \ No newline at end of file +#endif diff --git a/firmware/targets/furi_hal_include/furi_hal_version.h b/firmware/targets/furi_hal_include/furi_hal_version.h index 62f0147f26a..f174ade82e6 100644 --- a/firmware/targets/furi_hal_include/furi_hal_version.h +++ b/firmware/targets/furi_hal_include/furi_hal_version.h @@ -70,55 +70,55 @@ const char* furi_hal_version_get_model_name(); * * @return OTP Version */ -const FuriHalVersionOtpVersion furi_hal_version_get_otp_version(); +FuriHalVersionOtpVersion furi_hal_version_get_otp_version(); /** Get hardware version * * @return Hardware Version */ -const uint8_t furi_hal_version_get_hw_version(); +uint8_t furi_hal_version_get_hw_version(); /** Get hardware target * * @return Hardware Target */ -const uint8_t furi_hal_version_get_hw_target(); +uint8_t furi_hal_version_get_hw_target(); /** Get hardware body * * @return Hardware Body */ -const uint8_t furi_hal_version_get_hw_body(); +uint8_t furi_hal_version_get_hw_body(); /** Get hardware body color * * @return Hardware Color */ -const FuriHalVersionColor furi_hal_version_get_hw_color(); +FuriHalVersionColor furi_hal_version_get_hw_color(); /** Get hardware connect * * @return Hardware Interconnect */ -const uint8_t furi_hal_version_get_hw_connect(); +uint8_t furi_hal_version_get_hw_connect(); /** Get hardware region * * @return Hardware Region */ -const FuriHalVersionRegion furi_hal_version_get_hw_region(); +FuriHalVersionRegion furi_hal_version_get_hw_region(); /** Get hardware display id * * @return Display id */ -const FuriHalVersionDisplay furi_hal_version_get_hw_display(); +FuriHalVersionDisplay furi_hal_version_get_hw_display(); /** Get hardware timestamp * * @return Hardware Manufacture timestamp */ -const uint32_t furi_hal_version_get_hw_timestamp(); +uint32_t furi_hal_version_get_hw_timestamp(); /** Get pointer to target name * @@ -144,12 +144,6 @@ const char* furi_hal_version_get_ble_local_device_name_ptr(); */ const uint8_t* furi_hal_version_get_ble_mac(); -/** Get address of version structure of bootloader, stored in chip flash. - * - * @return Address of boot version structure. - */ -const struct Version* furi_hal_version_get_bootloader_version(); - /** Get address of version structure of firmware. * * @return Address of firmware version structure. diff --git a/lib/ReadMe.md b/lib/ReadMe.md index 89a09f411e6..0bdf3d63a85 100644 --- a/lib/ReadMe.md +++ b/lib/ReadMe.md @@ -3,20 +3,20 @@ - `app-scened-template` - Scened template app library - `app-template` - Template app library - `callback-connector` - Callback connector library -- `common-api` - Common api declaration library -- `cyfral` - Cyfral library - `drivers` - Drivers that we wrote - `fatfs` - External storage file system -- `flipper_file` - Flipper File Format library +- `flipper_format` - Flipper File Format library - `fnv1a-hash` - Fnv1a hash library +- `heatshrink` - Image compression library - `infrared` - Infrared library - `libusb_stm32` - STM32 USB library - `littlefs` - Internal storage file system -- `micro-ecc` - Elyptic Curve Crpytography library +- `micro-ecc` - Elliptic Curve Crpytography library +- `microtar` - TAR archive support library - `mlib` - Algorithms and containers - `nanopb` - Nano Protobuf library - `nfc_protocols` - Nfc protocols library -- `onewire` - One wire library +- `one_wire` - One wire library - `qrcode` - Qr code generator library - `ST25RFAL002` - ST253916 driver and NFC hal - `STM32CubeWB` - STM32WB series cube package diff --git a/lib/flipper_format/flipper_format_stream.c b/lib/flipper_format/flipper_format_stream.c index bc12cd17004..b3a085904b1 100644 --- a/lib/flipper_format/flipper_format_stream.c +++ b/lib/flipper_format/flipper_format_stream.c @@ -273,10 +273,12 @@ bool flipper_format_stream_write_value_line(Stream* stream, FlipperStreamWriteDa const uint8_t* data = write_data->data; string_printf(value, "%02X", data[i]); }; break; +#ifndef FLIPPER_STREAM_LITE case FlipperStreamValueFloat: { const float* data = write_data->data; string_printf(value, "%f", data[i]); }; break; +#endif case FlipperStreamValueInt32: { const int32_t* data = write_data->data; string_printf(value, "%" PRIi32, data[i]); @@ -357,6 +359,7 @@ bool flipper_format_stream_read_value_line( } } }; break; +#ifndef FLIPPER_STREAM_LITE case FlipperStreamValueFloat: { float* data = _data; // newlib-nano does not have sscanf for floats @@ -368,6 +371,7 @@ bool flipper_format_stream_read_value_line( scan_values = 1; } }; break; +#endif case FlipperStreamValueInt32: { int32_t* data = _data; scan_values = sscanf(string_get_cstr(value), "%" PRIi32, &data[i]); @@ -503,4 +507,4 @@ bool flipper_format_stream_write_comment_cstr(Stream* stream, const char* data) } while(false); return result; -} +} \ No newline at end of file diff --git a/lib/lib.mk b/lib/lib.mk index 7d22133113e..c1ee2cc0fbf 100644 --- a/lib/lib.mk +++ b/lib/lib.mk @@ -123,3 +123,10 @@ C_SOURCES += $(wildcard $(LIB_DIR)/micro-ecc/*.c) C_SOURCES += $(wildcard $(LIB_DIR)/one_wire/*.c) C_SOURCES += $(wildcard $(LIB_DIR)/one_wire/*/*.c) C_SOURCES += $(wildcard $(LIB_DIR)/one_wire/*/*/*.c) + +# microtar +CFLAGS += -I$(LIB_DIR)/microtar/src +C_SOURCES += $(wildcard $(LIB_DIR)/microtar/src/*.c) + +# Update-related common code +C_SOURCES += $(wildcard $(LIB_DIR)/update_util/*.c) diff --git a/lib/microtar b/lib/microtar new file mode 160000 index 00000000000..1e921369b2c --- /dev/null +++ b/lib/microtar @@ -0,0 +1 @@ +Subproject commit 1e921369b2c92bb219fcef84a37d4d2347794c0f diff --git a/lib/one_wire/ibutton/encoder/encoder_cyfral.c b/lib/one_wire/ibutton/encoder/encoder_cyfral.c index 717bf8988cb..f6cbe63019a 100644 --- a/lib/one_wire/ibutton/encoder/encoder_cyfral.c +++ b/lib/one_wire/ibutton/encoder/encoder_cyfral.c @@ -2,7 +2,7 @@ #include #define CYFRAL_DATA_SIZE sizeof(uint16_t) -#define CYFRAL_PERIOD (125 * instructions_per_us) +#define CYFRAL_PERIOD (125 * furi_hal_delay_instructions_per_microsecond()) #define CYFRAL_0_LOW (CYFRAL_PERIOD * 0.66f) #define CYFRAL_0_HI (CYFRAL_PERIOD * 0.33f) #define CYFRAL_1_LOW (CYFRAL_PERIOD * 0.33f) diff --git a/lib/one_wire/ibutton/encoder/encoder_metakom.c b/lib/one_wire/ibutton/encoder/encoder_metakom.c index ea2a28f0b47..3b597e7cbd6 100644 --- a/lib/one_wire/ibutton/encoder/encoder_metakom.c +++ b/lib/one_wire/ibutton/encoder/encoder_metakom.c @@ -2,7 +2,7 @@ #include #define METAKOM_DATA_SIZE sizeof(uint32_t) -#define METAKOM_PERIOD (125 * instructions_per_us) +#define METAKOM_PERIOD (125 * furi_hal_delay_instructions_per_microsecond()) #define METAKOM_0_LOW (METAKOM_PERIOD * 0.33f) #define METAKOM_0_HI (METAKOM_PERIOD * 0.66f) #define METAKOM_1_LOW (METAKOM_PERIOD * 0.66f) diff --git a/lib/one_wire/ibutton/pulse_protocols/protocol_cyfral.c b/lib/one_wire/ibutton/pulse_protocols/protocol_cyfral.c index 09635edff8d..a992f00d722 100644 --- a/lib/one_wire/ibutton/pulse_protocols/protocol_cyfral.c +++ b/lib/one_wire/ibutton/pulse_protocols/protocol_cyfral.c @@ -104,7 +104,7 @@ static void cyfral_reset(void* context) { cyfral->nibble = 0; cyfral->data_valid = true; - cyfral->max_period = CYFRAL_MAX_PERIOD_US * instructions_per_us; + cyfral->max_period = CYFRAL_MAX_PERIOD_US * furi_hal_delay_instructions_per_microsecond(); } static bool cyfral_process_bit( diff --git a/lib/one_wire/one_wire_slave.c b/lib/one_wire/one_wire_slave.c index 4e385e9e1db..e8cc5ac12aa 100644 --- a/lib/one_wire/one_wire_slave.c +++ b/lib/one_wire/one_wire_slave.c @@ -38,14 +38,14 @@ struct OneWireSlave { uint32_t onewire_slave_wait_while_gpio_is(OneWireSlave* bus, uint32_t time, const bool pin_value) { uint32_t start = DWT->CYCCNT; - uint32_t time_ticks = time * instructions_per_us; + uint32_t time_ticks = time * furi_hal_delay_instructions_per_microsecond(); uint32_t time_captured; do { time_captured = DWT->CYCCNT; if(furi_hal_ibutton_pin_get_level() != pin_value) { uint32_t remaining_time = time_ticks - (time_captured - start); - remaining_time /= instructions_per_us; + remaining_time /= furi_hal_delay_instructions_per_microsecond(); return remaining_time; } } while((time_captured - start) < time_ticks); @@ -211,7 +211,7 @@ static void exti_cb(void* context) { static uint32_t pulse_start = 0; if(input_state) { - uint32_t pulse_length = (DWT->CYCCNT - pulse_start) / instructions_per_us; + uint32_t pulse_length = (DWT->CYCCNT - pulse_start) / furi_hal_delay_instructions_per_microsecond(); if(pulse_length >= OWS_RESET_MIN) { if(pulse_length <= OWS_RESET_MAX) { // reset cycle ok diff --git a/lib/subghz/subghz_keystore.c b/lib/subghz/subghz_keystore.c index af953f9520a..1acb6ba5416 100644 --- a/lib/subghz/subghz_keystore.c +++ b/lib/subghz/subghz_keystore.c @@ -85,7 +85,7 @@ static void subghz_keystore_mess_with_iv(uint8_t* iv) { // Sharing them will bring some discomfort to legal owners // And potential legal action against you // While you reading this code think about your own personal responsibility - asm volatile("nani: \n" + asm volatile("nani%=: \n" "ldrd r0, r2, [%0, #0x0] \n" "lsl r1, r0, #8 \n" "lsl r3, r2, #8 \n" @@ -601,4 +601,4 @@ bool subghz_keystore_raw_get_data(const char* file_name, size_t offset, uint8_t* string_clear(str_temp); return result; -} +} \ No newline at end of file diff --git a/lib/toolbox/path.c b/lib/toolbox/path.c index 07318801fcd..4fd042e4197 100644 --- a/lib/toolbox/path.c +++ b/lib/toolbox/path.c @@ -18,3 +18,43 @@ void path_extract_filename_no_ext(const char* path, string_t filename) { string_mid(filename, start_position, end_position - start_position); } + +static inline void path_cleanup(string_t path) { + string_strim(path); + while(string_end_with_str_p(path, "/")) { + string_left(path, string_size(path) - 1); + } +} + +void path_extract_basename(const char* path, string_t basename) { + string_set(basename, path); + path_cleanup(basename); + size_t pos = string_search_rchar(basename, '/'); + if(pos != STRING_FAILURE) { + string_right(basename, pos); + } +} + +void path_extract_dirname(const char* path, string_t dirname) { + string_set(dirname, path); + path_cleanup(dirname); + size_t pos = string_search_rchar(dirname, '/'); + if(pos != STRING_FAILURE) { + string_left(dirname, pos); + } +} + +void path_append(string_t path, const char* suffix) { + path_cleanup(path); + string_t suffix_str; + string_init_set(suffix_str, suffix); + string_strim(suffix_str); + string_strim(suffix_str, "/"); + string_cat_printf(path, "/%s", string_get_cstr(suffix_str)); + string_clear(suffix_str); +} + +void path_concat(const char* path, const char* suffix, string_t out_path) { + string_set(out_path, path); + path_append(out_path, suffix); +} diff --git a/lib/toolbox/path.h b/lib/toolbox/path.h index da9b703daf8..0de63bb2ba2 100644 --- a/lib/toolbox/path.h +++ b/lib/toolbox/path.h @@ -14,6 +14,39 @@ extern "C" { */ void path_extract_filename_no_ext(const char* path, string_t filename); +/** + * @brief Extract last path component + * + * @param path path string + * @param filename output string. Must be initialized before. + */ +void path_extract_basename(const char* path, string_t basename); + +/** + * @brief Extract path, except for last component + * + * @param path path string + * @param filename output string. Must be initialized before. + */ +void path_extract_dirname(const char* path, string_t dirname); + +/** + * @brief Appends new component to path, adding path delimiter + * + * @param path path string + * @param suffix path part to apply + */ +void path_append(string_t path, const char* suffix); + +/** + * @brief Appends new component to path, adding path delimiter + * + * @param path first path part + * @param suffix second path part + * @param out_path output string to combine parts into. Must be initialized + */ +void path_concat(const char* path, const char* suffix, string_t out_path); + #ifdef __cplusplus } -#endif \ No newline at end of file +#endif diff --git a/lib/toolbox/tar/tar_archive.c b/lib/toolbox/tar/tar_archive.c new file mode 100644 index 00000000000..7be68bd8f64 --- /dev/null +++ b/lib/toolbox/tar/tar_archive.c @@ -0,0 +1,306 @@ +#include "tar_archive.h" + +#include +#include +#include +#include + +#define TAG "TarArch" +#define MAX_NAME_LEN 255 +#define FILE_BLOCK_SIZE 512 + +#define FILE_OPEN_NTRIES 10 +#define FILE_OPEN_RETRY_DELAY 25 + +typedef struct TarArchive { + Storage* storage; + mtar_t tar; +} TarArchive; + +/* API WRAPPER */ +static int mtar_storage_file_write(void* stream, const void* data, unsigned size) { + uint16_t bytes_written = storage_file_write(stream, data, size); + return (bytes_written == size) ? bytes_written : MTAR_EWRITEFAIL; +} + +static int mtar_storage_file_read(void* stream, void* data, unsigned size) { + uint16_t bytes_read = storage_file_read(stream, data, size); + return (bytes_read == size) ? bytes_read : MTAR_EREADFAIL; +} + +static int mtar_storage_file_seek(void* stream, unsigned offset) { + bool res = storage_file_seek(stream, offset, true); + return res ? MTAR_ESUCCESS : MTAR_ESEEKFAIL; +} + +static int mtar_storage_file_close(void* stream) { + if(stream) { + storage_file_close(stream); + } + return MTAR_ESUCCESS; +} + +const struct mtar_ops filesystem_ops = { + .read = mtar_storage_file_read, + .write = mtar_storage_file_write, + .seek = mtar_storage_file_seek, + .close = mtar_storage_file_close, +}; + +TarArchive* tar_archive_alloc(Storage* storage) { + furi_check(storage); + TarArchive* archive = malloc(sizeof(TarArchive)); + archive->storage = storage; + return archive; +} + +bool tar_archive_open(TarArchive* archive, const char* path, TarOpenMode mode) { + furi_assert(archive); + FS_AccessMode access_mode; + FS_OpenMode open_mode; + int mtar_access = 0; + + switch(mode) { + case TAR_OPEN_MODE_READ: + mtar_access = MTAR_READ; + access_mode = FSAM_READ; + open_mode = FSOM_OPEN_EXISTING; + break; + case TAR_OPEN_MODE_WRITE: + mtar_access = MTAR_WRITE; + access_mode = FSAM_WRITE; + open_mode = FSOM_CREATE_ALWAYS; + break; + default: + return false; + } + + File* stream = storage_file_alloc(archive->storage); + if(!storage_file_open(stream, path, access_mode, open_mode)) { + storage_file_free(stream); + return false; + } + mtar_init(&archive->tar, mtar_access, &filesystem_ops, stream); + + return true; +} + +void tar_archive_free(TarArchive* archive) { + furi_assert(archive); + if(mtar_is_open(&archive->tar)) { + mtar_close(&archive->tar); + } +} + +bool tar_archive_dir_add_element(TarArchive* archive, const char* dirpath) { + furi_assert(archive); + return (mtar_write_dir_header(&archive->tar, dirpath) == MTAR_ESUCCESS); +} + +bool tar_archive_finalize(TarArchive* archive) { + furi_assert(archive); + return (mtar_finalize(&archive->tar) == MTAR_ESUCCESS); +} + +bool tar_archive_store_data( + TarArchive* archive, + const char* path, + const uint8_t* data, + const int32_t data_len) { + furi_assert(archive); + + return ( + tar_archive_file_add_header(archive, path, data_len) && + tar_archive_file_add_data_block(archive, data, data_len) && + tar_archive_file_finalize(archive)); +} + +bool tar_archive_file_add_header(TarArchive* archive, const char* path, const int32_t data_len) { + furi_assert(archive); + + return (mtar_write_file_header(&archive->tar, path, data_len) == MTAR_ESUCCESS); +} + +bool tar_archive_file_add_data_block( + TarArchive* archive, + const uint8_t* data_block, + const int32_t block_len) { + furi_assert(archive); + + return (mtar_write_data(&archive->tar, data_block, block_len) == block_len); +} + +bool tar_archive_file_finalize(TarArchive* archive) { + furi_assert(archive); + return (mtar_end_data(&archive->tar) == MTAR_ESUCCESS); +} + +typedef struct { + TarArchive* archive; + const char* work_dir; +} TarArchiveDirectoryOpParams; + +static int archive_extract_foreach_cb(mtar_t* tar, const mtar_header_t* header, void* param) { + TarArchiveDirectoryOpParams* op_params = param; + string_t fname; + + if(header->type == MTAR_TDIR) { + string_init(fname); + path_concat(op_params->work_dir, header->name, fname); + + bool create_res = + storage_simply_mkdir(op_params->archive->storage, string_get_cstr(fname)); + string_clear(fname); + return create_res ? 0 : -1; + } + + if(header->type != MTAR_TREG) { + FURI_LOG_W(TAG, "not extracting unsupported type \"%s\"", header->name); + return 0; + } + + string_init(fname); + path_concat(op_params->work_dir, header->name, fname); + FURI_LOG_I(TAG, "Extracting %d bytes to '%s'", header->size, header->name); + File* out_file = storage_file_alloc(op_params->archive->storage); + uint8_t* readbuf = malloc(FILE_BLOCK_SIZE); + + bool failed = false; + uint8_t n_tries = FILE_OPEN_NTRIES; + do { + while( + (n_tries-- > 0) && + !storage_file_open(out_file, string_get_cstr(fname), FSAM_WRITE, FSOM_CREATE_ALWAYS)) { + FURI_LOG_W(TAG, "Failed to open '%s', reties: %d", string_get_cstr(fname), n_tries); + osDelay(FILE_OPEN_RETRY_DELAY); + continue; + } + + 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(fname); + return failed ? -1 : 0; +} + +bool tar_archive_unpack_to(TarArchive* archive, const char* destination) { + furi_assert(archive); + TarArchiveDirectoryOpParams param = { + .archive = archive, + .work_dir = destination, + }; + + FURI_LOG_I(TAG, "Restoring '%s'", destination); + + return (mtar_foreach(&archive->tar, archive_extract_foreach_cb, ¶m) == MTAR_ESUCCESS); +}; + +bool tar_archive_add_file( + TarArchive* archive, + const char* fs_file_path, + const char* archive_fname, + const int32_t file_size) { + furi_assert(archive); + uint8_t* file_buffer = malloc(FILE_BLOCK_SIZE); + bool success = false; + File* src_file = storage_file_alloc(archive->storage); + uint8_t n_tries = FILE_OPEN_NTRIES; + do { + while((n_tries-- > 0) && + !storage_file_open(src_file, fs_file_path, FSAM_READ, FSOM_OPEN_EXISTING)) { + FURI_LOG_W(TAG, "Failed to open '%s', reties: %d", fs_file_path, n_tries); + osDelay(FILE_OPEN_RETRY_DELAY); + continue; + } + + if(!storage_file_is_open(src_file) || + !tar_archive_file_add_header(archive, archive_fname, file_size)) { + break; + } + + uint16_t bytes_read = 0; + while((bytes_read = storage_file_read(src_file, file_buffer, FILE_BLOCK_SIZE))) { + success = tar_archive_file_add_data_block(archive, file_buffer, bytes_read); + if(!success) { + break; + } + } + + success = success && tar_archive_file_finalize(archive); + } while(false); + + storage_file_free(src_file); + free(file_buffer); + return success; +} + +bool tar_archive_add_dir(TarArchive* archive, const char* fs_full_path, const char* path_prefix) { + furi_assert(archive); + furi_check(path_prefix); + File* directory = storage_file_alloc(archive->storage); + FileInfo file_info; + + FURI_LOG_I(TAG, "Backing up '%s', '%s'", fs_full_path, path_prefix); + char* name = malloc(MAX_NAME_LEN); + bool success = false; + + do { + if(!storage_dir_open(directory, fs_full_path)) { + break; + } + + while(true) { + if(!storage_dir_read(directory, &file_info, name, MAX_NAME_LEN)) { + success = true; /* empty dir / no more files */ + break; + } + + string_t element_name, element_fs_abs_path; + string_init(element_name); + string_init(element_fs_abs_path); + path_concat(fs_full_path, name, element_fs_abs_path); + if(strlen(path_prefix)) { + path_concat(path_prefix, name, element_name); + } else { + string_init_set(element_name, name); + } + + if(file_info.flags & FSF_DIRECTORY) { + success = tar_archive_dir_add_element(archive, string_get_cstr(element_name)) && + tar_archive_add_dir( + archive, + string_get_cstr(element_fs_abs_path), + string_get_cstr(element_name)); + } else { + success = tar_archive_add_file( + archive, + string_get_cstr(element_fs_abs_path), + string_get_cstr(element_name), + file_info.size); + } + string_clear(element_name); + string_clear(element_fs_abs_path); + + if(!success) { + break; + } + } + } while(false); + + free(name); + storage_file_free(directory); + return success; +} \ No newline at end of file diff --git a/lib/toolbox/tar/tar_archive.h b/lib/toolbox/tar/tar_archive.h new file mode 100644 index 00000000000..fe3e248ea8c --- /dev/null +++ b/lib/toolbox/tar/tar_archive.h @@ -0,0 +1,59 @@ +#pragma once + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct TarArchive TarArchive; + +typedef struct Storage Storage; + +typedef enum { + TAR_OPEN_MODE_READ = 'r', + TAR_OPEN_MODE_WRITE = 'w', + TAR_OPEN_MODE_STDOUT = 's' /* to be implemented */ +} TarOpenMode; + +TarArchive* tar_archive_alloc(Storage* storage); + +bool tar_archive_open(TarArchive* archive, const char* path, TarOpenMode mode); + +void tar_archive_free(TarArchive* archive); + +/* High-level API - assumes archive is open */ +bool tar_archive_unpack_to(TarArchive* archive, const char* destination); + +bool tar_archive_add_file( + TarArchive* archive, + const char* fs_file_path, + const char* archive_fname, + const int32_t file_size); + +bool tar_archive_add_dir(TarArchive* archive, const char* fs_full_path, const char* path_prefix); + +/* Low-level API */ +bool tar_archive_dir_add_element(TarArchive* archive, const char* dirpath); + +bool tar_archive_file_add_header(TarArchive* archive, const char* path, const int32_t data_len); + +bool tar_archive_file_add_data_block( + TarArchive* archive, + const uint8_t* data_block, + const int32_t block_len); + +bool tar_archive_file_finalize(TarArchive* archive); + +bool tar_archive_store_data( + TarArchive* archive, + const char* path, + const uint8_t* data, + const int32_t data_len); + +bool tar_archive_finalize(TarArchive* archive); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/lib/toolbox/version.c b/lib/toolbox/version.c index ddf8e7ef68d..902be876c22 100644 --- a/lib/toolbox/version.c +++ b/lib/toolbox/version.c @@ -7,6 +7,7 @@ struct Version { const char* build_date; const char* version; const uint8_t target; + const bool build_is_dirty; }; /* version of current running firmware (bootloader/flipper) */ @@ -15,8 +16,13 @@ static const Version version = { .git_branch = GIT_BRANCH, .git_branch_num = GIT_BRANCH_NUM, .build_date = BUILD_DATE, - .version = VERSION, + .version = VERSION +#ifdef FURI_RAM_EXEC + " (RAM)" +#endif + , .target = TARGET, + .build_is_dirty = BUILD_DIRTY, }; const Version* version_get(void) { @@ -43,6 +49,10 @@ const char* version_get_version(const Version* v) { return v ? v->version : version.version; } -const uint8_t version_get_target(const Version* v) { +uint8_t version_get_target(const Version* v) { return v ? v->target : version.target; } + +bool version_get_dirty_flag(const Version* v) { + return v ? v->build_is_dirty : version.build_is_dirty; +} \ No newline at end of file diff --git a/lib/toolbox/version.h b/lib/toolbox/version.h index 545358a5bab..7e82e45d4bd 100644 --- a/lib/toolbox/version.h +++ b/lib/toolbox/version.h @@ -1,6 +1,7 @@ #pragma once #include +#include #ifdef __cplusplus extern "C" { @@ -70,8 +71,17 @@ const char* version_get_version(const Version* v); * * @return build date */ -const uint8_t version_get_target(const Version* v); +uint8_t version_get_target(const Version* v); + +/** Get flag indicating if this build is "dirty" (source code had uncommited changes) + * + * @param v pointer to Version data. NULL for currently running + * software. + * + * @return build date + */ +bool version_get_dirty_flag(const Version* v); #ifdef __cplusplus } -#endif +#endif \ No newline at end of file diff --git a/lib/update_util/dfu_file.c b/lib/update_util/dfu_file.c new file mode 100644 index 00000000000..2fcf95acd84 --- /dev/null +++ b/lib/update_util/dfu_file.c @@ -0,0 +1,183 @@ +#include "dfu_file.h" +#include + +#define VALID_WHOLE_FILE_CRC 0xFFFFFFFF +#define DFU_SUFFIX_VERSION 0x011A +#define DFU_DATA_BUFFER_MAX_LEN 512 +#define DFU_SIGNATURE "DfuSe" + +bool dfu_file_validate_crc(File* dfuf, const DfuPageTaskProgressCb progress_cb, void* context) { + if(!storage_file_is_open(dfuf) || !storage_file_seek(dfuf, 0, true)) { + return false; + } + + furi_hal_crc_reset(); + + uint32_t file_crc = 0; + + uint8_t* data_buffer = malloc(DFU_DATA_BUFFER_MAX_LEN); + uint16_t data_buffer_valid_len; + + uint32_t file_size = storage_file_size(dfuf); + + /* Feed file contents per sector into CRC calc */ + furi_hal_crc_acquire(osWaitForever); + for(uint32_t fptr = 0; fptr < file_size;) { + data_buffer_valid_len = storage_file_read(dfuf, data_buffer, DFU_DATA_BUFFER_MAX_LEN); + if(data_buffer_valid_len == 0) { + break; + } + fptr += data_buffer_valid_len; + + if((fptr % DFU_DATA_BUFFER_MAX_LEN == 0)) { + progress_cb(fptr * 100 / file_size, context); + } + + file_crc = furi_hal_crc_feed(data_buffer, data_buffer_valid_len); + } + furi_hal_crc_reset(); + free(data_buffer); + + /* Last 4 bytes of DFU file = CRC of previous file contents, inverted + * If we calculate whole file CRC32, incl. embedded CRC, + * that should give us 0xFFFFFFFF + */ + return file_crc == VALID_WHOLE_FILE_CRC; +} + +uint8_t dfu_file_validate_headers(File* dfuf, const DfuValidationParams* reference_params) { + furi_assert(reference_params); + + DfuPrefix dfu_prefix = {0}; + DfuSuffix dfu_suffix = {0}; + uint16_t bytes_read = 0; + + if(!storage_file_is_open(dfuf) || !storage_file_seek(dfuf, 0, true)) { + return 0; + } + + const uint32_t dfu_suffix_offset = storage_file_size(dfuf) - sizeof(DfuSuffix); + + bytes_read = storage_file_read(dfuf, &dfu_prefix, sizeof(DfuPrefix)); + if(bytes_read != sizeof(DfuPrefix)) { + return 0; + } + + if(memcmp(dfu_prefix.szSignature, DFU_SIGNATURE, sizeof(dfu_prefix.szSignature))) { + return 0; + } + + if((dfu_prefix.bVersion != 1) || (dfu_prefix.DFUImageSize != dfu_suffix_offset)) { + return 0; + } + + if(!storage_file_seek(dfuf, dfu_suffix_offset, true)) { + return 0; + } + + bytes_read = storage_file_read(dfuf, &dfu_suffix, sizeof(DfuSuffix)); + if(bytes_read != sizeof(DfuSuffix)) { + return 0; + } + + if((dfu_suffix.bLength != sizeof(DfuSuffix)) || (dfu_suffix.bcdDFU != DFU_SUFFIX_VERSION)) { + return 0; + } + /* TODO: check DfuSignature?.. */ + + if((dfu_suffix.idVendor != reference_params->vendor) || + (dfu_suffix.idProduct != reference_params->product) || + (dfu_suffix.bcdDevice != reference_params->device)) { + return 0; + } + + return dfu_prefix.bTargets; +} + +/* Assumes file is open, valid and read pointer is set at the start of image data + */ +static DfuUpdateBlockResult dfu_file_perform_task_for_update_pages( + const DfuUpdateTask* task, + File* dfuf, + const ImageElementHeader* header) { + furi_assert(task); + furi_assert(header); + task->progress_cb(0, task->context); + const size_t FLASH_PAGE_SIZE = furi_hal_flash_get_page_size(); + const size_t FLASH_PAGE_ALIGNMENT_MASK = FLASH_PAGE_SIZE - 1; + if((header->dwElementAddress & FLASH_PAGE_ALIGNMENT_MASK) != 0) { + /* start address is not aligned by page boundary -- we don't support that. Yet. */ + return UpdateBlockResult_Failed; + } + + if(task->address_cb && (!task->address_cb(header->dwElementAddress) || + !task->address_cb(header->dwElementAddress + header->dwElementSize))) { + storage_file_seek(dfuf, header->dwElementSize, false); + task->progress_cb(100, task->context); + return UpdateBlockResult_Skipped; + } + + uint8_t* fw_block = malloc(FLASH_PAGE_SIZE); + uint16_t bytes_read = 0; + uint32_t element_offs = 0; + + while(element_offs < header->dwElementSize) { + uint32_t n_bytes_to_read = FLASH_PAGE_SIZE; + if((element_offs + n_bytes_to_read) > header->dwElementSize) { + n_bytes_to_read = header->dwElementSize - element_offs; + } + + bytes_read = storage_file_read(dfuf, fw_block, n_bytes_to_read); + if(bytes_read == 0) { + break; + } + + int16_t i_page = furi_hal_flash_get_page_number(header->dwElementAddress + element_offs); + if(i_page < 0) { + break; + } + + if(!task->task_cb(i_page, fw_block, bytes_read)) { + break; + } + + element_offs += bytes_read; + task->progress_cb(element_offs * 100 / header->dwElementSize, task->context); + } + + free(fw_block); + return (element_offs == header->dwElementSize) ? UpdateBlockResult_OK : + UpdateBlockResult_Failed; +} + +bool dfu_file_process_targets(const DfuUpdateTask* task, File* dfuf, const uint8_t n_targets) { + TargetPrefix target_prefix = {0}; + ImageElementHeader image_element = {0}; + uint16_t bytes_read = 0; + + if(!storage_file_seek(dfuf, sizeof(DfuPrefix), true)) { + return UpdateBlockResult_Failed; + }; + + for(uint8_t i_target = 0; i_target < n_targets; ++i_target) { + bytes_read = storage_file_read(dfuf, &target_prefix, sizeof(TargetPrefix)); + if(bytes_read != sizeof(TargetPrefix)) { + return UpdateBlockResult_Failed; + } + + /* TODO: look into TargetPrefix and validate/filter?.. */ + for(uint32_t i_element = 0; i_element < target_prefix.dwNbElements; ++i_element) { + bytes_read = storage_file_read(dfuf, &image_element, sizeof(ImageElementHeader)); + if(bytes_read != sizeof(ImageElementHeader)) { + return UpdateBlockResult_Failed; + } + + if(dfu_file_perform_task_for_update_pages(task, dfuf, &image_element) == + UpdateBlockResult_Failed) { + return false; + } + } + } + + return true; +} diff --git a/lib/update_util/dfu_file.h b/lib/update_util/dfu_file.h new file mode 100644 index 00000000000..81a6887cf6d --- /dev/null +++ b/lib/update_util/dfu_file.h @@ -0,0 +1,40 @@ +#pragma once + +#include "dfu_headers.h" + +#include +#include + +typedef enum { + UpdateBlockResult_Unknown, + UpdateBlockResult_OK, + UpdateBlockResult_Skipped, + UpdateBlockResult_Failed +} DfuUpdateBlockResult; + +typedef bool ( + *DfuPageTaskCb)(const uint8_t i_page, const uint8_t* update_block, uint16_t update_block_len); +typedef void (*DfuPageTaskProgressCb)(const uint8_t progress, void* context); +typedef bool (*DfuAddressValidationCb)(const size_t address); + +typedef struct { + DfuPageTaskCb task_cb; + DfuPageTaskProgressCb progress_cb; + DfuAddressValidationCb address_cb; + void* context; +} DfuUpdateTask; + +typedef struct { + uint16_t vendor; + uint16_t product; + uint16_t device; +} DfuValidationParams; + +bool dfu_file_validate_crc(File* dfuf, const DfuPageTaskProgressCb progress_cb, void* context); + +/* Returns number of valid targets from file header + * If file is invalid, returns 0 + */ +uint8_t dfu_file_validate_headers(File* dfuf, const DfuValidationParams* reference_params); + +bool dfu_file_process_targets(const DfuUpdateTask* task, File* dfuf, const uint8_t n_targets); diff --git a/lib/update_util/dfu_headers.h b/lib/update_util/dfu_headers.h new file mode 100644 index 00000000000..79726deadb9 --- /dev/null +++ b/lib/update_util/dfu_headers.h @@ -0,0 +1,41 @@ +#pragma once + +#include + +#pragma pack(push, 1) + +typedef struct { + char szSignature[5]; + uint8_t bVersion; + uint32_t DFUImageSize; + uint8_t bTargets; +} DfuPrefix; + +typedef struct { + uint16_t bcdDevice; + uint16_t idProduct; + uint16_t idVendor; + uint16_t bcdDFU; + uint8_t ucDfuSignature_U; + uint8_t ucDfuSignature_F; + uint8_t ucDfuSignature_D; + uint8_t bLength; + uint32_t dwCRC; +} DfuSuffix; + +typedef struct { + char szSignature[6]; + uint8_t bAlternateSetting; + uint8_t bTargetNamed; + uint8_t _pad[3]; + char szTargetName[255]; + uint32_t dwTargetSize; + uint32_t dwNbElements; +} TargetPrefix; + +typedef struct { + uint32_t dwElementAddress; + uint32_t dwElementSize; +} ImageElementHeader; + +#pragma pack(pop) diff --git a/lib/update_util/lfs_backup.c b/lib/update_util/lfs_backup.c new file mode 100644 index 00000000000..fa9141df641 --- /dev/null +++ b/lib/update_util/lfs_backup.c @@ -0,0 +1,22 @@ +#include "lfs_backup.h" + +#include + +#define LFS_BACKUP_DEFAULT_LOCATION "/ext/" LFS_BACKUP_DEFAULT_FILENAME + +bool lfs_backup_create(Storage* storage, const char* destination) { + const char* final_destination = + destination && strlen(destination) ? destination : LFS_BACKUP_DEFAULT_LOCATION; + return storage_int_backup(storage, final_destination) == FSE_OK; +} + +bool lfs_backup_exists(Storage* storage, const char* source) { + const char* final_source = source && strlen(source) ? source : LFS_BACKUP_DEFAULT_LOCATION; + FileInfo fi; + return storage_common_stat(storage, final_source, &fi) == FSE_OK; +} + +bool lfs_backup_unpack(Storage* storage, const char* source) { + const char* final_source = source && strlen(source) ? source : LFS_BACKUP_DEFAULT_LOCATION; + return storage_int_restore(storage, final_source) == FSE_OK; +} diff --git a/lib/update_util/lfs_backup.h b/lib/update_util/lfs_backup.h new file mode 100644 index 00000000000..5a7738c86ed --- /dev/null +++ b/lib/update_util/lfs_backup.h @@ -0,0 +1,18 @@ +#pragma once + +#include +#include + +#define LFS_BACKUP_DEFAULT_FILENAME "backup.tar" + +#ifdef __cplusplus +extern "C" { +#endif + +bool lfs_backup_create(Storage* storage, const char* destination); +bool lfs_backup_exists(Storage* storage, const char* source); +bool lfs_backup_unpack(Storage* storage, const char* source); + +#ifdef __cplusplus +} +#endif diff --git a/lib/update_util/update_manifest.c b/lib/update_util/update_manifest.c new file mode 100644 index 00000000000..2ae52f17746 --- /dev/null +++ b/lib/update_util/update_manifest.c @@ -0,0 +1,86 @@ +#include "update_manifest.h" + +#include +#include +#include + +UpdateManifest* update_manifest_alloc() { + UpdateManifest* update_manifest = malloc(sizeof(UpdateManifest)); + string_init(update_manifest->version); + string_init(update_manifest->firmware_dfu_image); + string_init(update_manifest->radio_image); + string_init(update_manifest->staged_loader_file); + update_manifest->target = 0; + update_manifest->valid = false; + return update_manifest; +} + +void update_manifest_free(UpdateManifest* update_manifest) { + furi_assert(update_manifest); + string_clear(update_manifest->version); + string_clear(update_manifest->firmware_dfu_image); + string_clear(update_manifest->radio_image); + string_clear(update_manifest->staged_loader_file); + free(update_manifest); +} + +static bool + update_manifest_init_from_ff(UpdateManifest* update_manifest, FlipperFormat* flipper_file) { + furi_assert(update_manifest); + furi_assert(flipper_file); + + string_t filetype; + uint32_t version = 0; + + // TODO: compare filetype? + string_init(filetype); + update_manifest->valid = + flipper_format_read_header(flipper_file, filetype, &version) && + flipper_format_read_string(flipper_file, "Info", update_manifest->version) && + flipper_format_read_uint32(flipper_file, "Target", &update_manifest->target, 1) && + flipper_format_read_string(flipper_file, "Loader", update_manifest->staged_loader_file) && + flipper_format_read_hex( + flipper_file, + "Loader CRC", + (uint8_t*)&update_manifest->staged_loader_crc, + sizeof(uint32_t)); + string_clear(filetype); + + /* Optional fields - we can have dfu, radio, or both */ + flipper_format_read_string(flipper_file, "Firmware", update_manifest->firmware_dfu_image); + flipper_format_read_string(flipper_file, "Radio", update_manifest->radio_image); + flipper_format_read_hex( + flipper_file, "Radio address", (uint8_t*)&update_manifest->radio_address, sizeof(uint32_t)); + + return update_manifest->valid; +} + +bool update_manifest_init(UpdateManifest* update_manifest, const char* manifest_filename) { + Storage* storage = furi_record_open("storage"); + FlipperFormat* flipper_file = flipper_format_file_alloc(storage); + if(flipper_format_file_open_existing(flipper_file, manifest_filename)) { + update_manifest_init_from_ff(update_manifest, flipper_file); + } + + flipper_format_free(flipper_file); + furi_record_close("storage"); + + return update_manifest->valid; +} + +bool update_manifest_init_mem( + UpdateManifest* update_manifest, + const uint8_t* manifest_data, + const uint16_t length) { + FlipperFormat* flipper_file = flipper_format_string_alloc(); + Stream* sstream = flipper_format_get_raw_stream(flipper_file); + + stream_write(sstream, manifest_data, length); + stream_seek(sstream, 0, StreamOffsetFromStart); + + update_manifest_init_from_ff(update_manifest, flipper_file); + + flipper_format_free(flipper_file); + + return update_manifest->valid; +} diff --git a/lib/update_util/update_manifest.h b/lib/update_util/update_manifest.h new file mode 100644 index 00000000000..7b60f58a24b --- /dev/null +++ b/lib/update_util/update_manifest.h @@ -0,0 +1,40 @@ +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include + +/* Paths don't include /ext -- because at startup SD card is mounted as root */ +#define UPDATE_DIR_DEFAULT_REL_PATH "/update" +#define UPDATE_MANIFEST_DEFAULT_NAME "update.fuf" +#define UPDATE_MAINFEST_DEFAULT_PATH UPDATE_DIR_DEFAULT_REL_PATH "/" UPDATE_MANIFEST_DEFAULT_NAME + +typedef struct { + string_t version; + uint32_t target; + string_t staged_loader_file; + uint32_t staged_loader_crc; + string_t firmware_dfu_image; + string_t radio_image; + uint32_t radio_address; + bool valid; +} UpdateManifest; + +UpdateManifest* update_manifest_alloc(); + +void update_manifest_free(UpdateManifest* update_manifest); + +bool update_manifest_init(UpdateManifest* update_manifest, const char* manifest_filename); + +bool update_manifest_init_mem( + UpdateManifest* update_manifest, + const uint8_t* manifest_data, + const uint16_t length); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/lib/update_util/update_operation.c b/lib/update_util/update_operation.c new file mode 100644 index 00000000000..2fd510b5e0f --- /dev/null +++ b/lib/update_util/update_operation.c @@ -0,0 +1,207 @@ +#include "update_operation.h" + +#include "update_manifest.h" + +#include +#include +#include +#include +#include + +static const char* UPDATE_ROOT_DIR = "/ext" UPDATE_DIR_DEFAULT_REL_PATH; +static const char* UPDATE_PREFIX = "/ext" UPDATE_DIR_DEFAULT_REL_PATH "/"; +static const char* UPDATE_SUFFIX = "/" UPDATE_MANIFEST_DEFAULT_NAME; +static const uint32_t MAX_DIR_NAME_LEN = 250; + +static const char* update_prepare_result_descr[] = { + [UpdatePrepareResultOK] = "OK", + [UpdatePrepareResultManifestPathInvalid] = "Invalid manifest name or location", + [UpdatePrepareResultManifestFolderNotFound] = "Update folder not found", + [UpdatePrepareResultManifestInvalid] = "Invalid manifest data", + [UpdatePrepareResultStageMissing] = "Missing Stage2 loader", + [UpdatePrepareResultStageIntegrityError] = "Corrupted Stage2 loader", +}; + +const char* update_operation_describe_preparation_result(const UpdatePrepareResult value) { + if(value >= COUNT_OF(update_prepare_result_descr)) { + return "..."; + } else { + return update_prepare_result_descr[value]; + } +} + +bool update_operation_get_package_dir_name(const char* full_path, string_t out_manifest_dir) { + bool path_ok = false; + string_t full_path_str; + string_init_set(full_path_str, full_path); + string_reset(out_manifest_dir); + bool start_end_ok = string_start_with_str_p(full_path_str, UPDATE_PREFIX) && + string_end_with_str_p(full_path_str, UPDATE_SUFFIX); + int16_t dir_name_len = + strlen(full_path) - strlen(UPDATE_PREFIX) - strlen(UPDATE_MANIFEST_DEFAULT_NAME) - 1; + if(dir_name_len == -1) { + path_ok = true; + } else if(start_end_ok && (dir_name_len > 0)) { + string_set_n(out_manifest_dir, full_path_str, strlen(UPDATE_PREFIX), dir_name_len); + path_ok = true; + if(string_search_char(out_manifest_dir, '/') != STRING_FAILURE) { + string_reset(out_manifest_dir); + path_ok = false; + } + } + string_clear(full_path_str); + return path_ok; +} + +int32_t update_operation_get_package_index(Storage* storage, const char* update_package_dir) { + furi_assert(storage); + furi_assert(update_package_dir); + + if(strlen(update_package_dir) == 0) { + return 0; + } + + bool found = false; + int32_t index = 0; + File* dir = storage_file_alloc(storage); + FileInfo fi = {0}; + char* name_buffer = malloc(MAX_DIR_NAME_LEN); + do { + if(!storage_dir_open(dir, UPDATE_ROOT_DIR)) { + break; + } + + while(storage_dir_read(dir, &fi, name_buffer, MAX_DIR_NAME_LEN)) { + index++; + if(strcmp(name_buffer, update_package_dir)) { + continue; + } else { + found = true; + break; + } + } + } while(false); + + free(name_buffer); + storage_file_free(dir); + + return found ? index : -1; +} + +bool update_operation_get_current_package_path(Storage* storage, string_t out_path) { + uint32_t update_index = furi_hal_rtc_get_register(FuriHalRtcRegisterUpdateFolderFSIndex); + string_set_str(out_path, UPDATE_ROOT_DIR); + if(update_index == 0) { + return true; + } + + bool found = false; + uint32_t iter_index = 0; + File* dir = storage_file_alloc(storage); + FileInfo fi = {0}; + char* name_buffer = malloc(MAX_DIR_NAME_LEN); + do { + if(!storage_dir_open(dir, UPDATE_ROOT_DIR)) { + break; + } + + while(storage_dir_read(dir, &fi, name_buffer, MAX_DIR_NAME_LEN)) { + if(++iter_index == update_index) { + found = true; + path_append(out_path, name_buffer); + break; + } + } + } while(false); + + free(name_buffer); + storage_file_free(dir); + if(!found) { + string_reset(out_path); + } + + return found; +} + +UpdatePrepareResult update_operation_prepare(const char* manifest_file_path) { + string_t update_folder; + string_init(update_folder); + if(!update_operation_get_package_dir_name(manifest_file_path, update_folder)) { + string_clear(update_folder); + return UpdatePrepareResultManifestPathInvalid; + } + + Storage* storage = furi_record_open("storage"); + int32_t update_index = + update_operation_get_package_index(storage, string_get_cstr(update_folder)); + string_clear(update_folder); + + if(update_index < 0) { + furi_record_close("storage"); + return UpdatePrepareResultManifestFolderNotFound; + } + + string_t update_dir_path; + string_init(update_dir_path); + path_extract_dirname(manifest_file_path, update_dir_path); + + UpdatePrepareResult result = UpdatePrepareResultManifestInvalid; + UpdateManifest* manifest = update_manifest_alloc(); + if(update_manifest_init(manifest, manifest_file_path)) { + result = UpdatePrepareResultStageMissing; + File* file = storage_file_alloc(storage); + + string_t stage_path; + string_init(stage_path); + path_extract_dirname(manifest_file_path, stage_path); + path_append(stage_path, string_get_cstr(manifest->staged_loader_file)); + + const uint16_t READ_BLOCK = 0x1000; + uint8_t* read_buffer = malloc(READ_BLOCK); + uint32_t crc = 0; + do { + if(!storage_file_open( + file, string_get_cstr(stage_path), FSAM_READ, FSOM_OPEN_EXISTING)) { + break; + } + + result = UpdatePrepareResultStageIntegrityError; + furi_hal_crc_acquire(osWaitForever); + + uint16_t bytes_read = 0; + do { + bytes_read = storage_file_read(file, read_buffer, READ_BLOCK); + crc = furi_hal_crc_feed(read_buffer, bytes_read); + } while(bytes_read == READ_BLOCK); + + furi_hal_crc_reset(); + } while(false); + + string_clear(stage_path); + free(read_buffer); + storage_file_free(file); + + if(crc == manifest->staged_loader_crc) { + furi_hal_rtc_set_boot_mode(FuriHalRtcBootModePreUpdate); + update_operation_persist_package_index(update_index); + result = UpdatePrepareResultOK; + } + } + furi_record_close("storage"); + update_manifest_free(manifest); + + return result; +} + +bool update_operation_is_armed() { + return furi_hal_rtc_get_boot_mode() == FuriHalRtcBootModePreUpdate; +} + +void update_operation_disarm() { + furi_hal_rtc_set_boot_mode(FuriHalRtcBootModeNormal); + furi_hal_rtc_set_register(FuriHalRtcRegisterUpdateFolderFSIndex, 0); +} + +void update_operation_persist_package_index(uint32_t index) { + furi_hal_rtc_set_register(FuriHalRtcRegisterUpdateFolderFSIndex, index); +} \ No newline at end of file diff --git a/lib/update_util/update_operation.h b/lib/update_util/update_operation.h new file mode 100644 index 00000000000..6b6ab7305e3 --- /dev/null +++ b/lib/update_util/update_operation.h @@ -0,0 +1,72 @@ +#pragma once + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Checks if supplied full manifest path is valid + * @param full_path Full path to manifest file. Must be named UPDATE_MANIFEST_DEFAULT_NAME + * @param out_manifest_dir Directory to apply update from, if supplied path is valid. + * May be empty if update is in root update directory + * @return bool if supplied path is valid and out_manifest_dir contains dir to apply + */ +bool update_operation_get_package_dir_name(const char* full_path, string_t out_manifest_dir); + +typedef enum { + UpdatePrepareResultOK, + UpdatePrepareResultManifestPathInvalid, + UpdatePrepareResultManifestFolderNotFound, + UpdatePrepareResultManifestInvalid, + UpdatePrepareResultStageMissing, + UpdatePrepareResultStageIntegrityError, +} UpdatePrepareResult; + +const char* update_operation_describe_preparation_result(const UpdatePrepareResult value); + +/* + * Validates next stage and sets up registers to apply update after restart + * @param manifest_dir_path Full path to manifest for update to apply + * @return UpdatePrepareResult validation & arm result + */ +UpdatePrepareResult update_operation_prepare(const char* manifest_file_path); + +/* + * Gets update package index to pass in RTC registers + * @param storage Storage API + * @param update_package_dir Package directory name + * @return int32_t <0 - error, >= 0 - update index value + */ +int32_t update_operation_get_package_index(Storage* storage, const char* update_package_dir); + +/* + * Gets filesystem path for current update package + * @param storage Storage API + * @param out_path Path to directory with manifest & related files. Must be initialized + * @return true if path was restored successfully + */ +bool update_operation_get_current_package_path(Storage* storage, string_t out_path); + +/* + * Stores given update index in RTC registers + * @param index Value to store + */ +void update_operation_persist_package_index(uint32_t index); + +/* + * Sets up update operation to be performed on reset + */ +bool update_operation_is_armed(); + +/* + * Cancels pending update operation + */ +void update_operation_disarm(); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/make/git.mk b/make/git.mk index dd8842e80fa..e58876a8c75 100644 --- a/make/git.mk +++ b/make/git.mk @@ -2,7 +2,14 @@ GIT_COMMIT := $(shell git rev-parse --short HEAD || echo 'unknown') GIT_BRANCH := $(shell echo $${WORKFLOW_BRANCH_OR_TAG-$$(git rev-parse --abbrev-ref HEAD || echo 'unknown')}) GIT_BRANCH_NUM := $(shell git rev-list --count HEAD || echo 'nan') BUILD_DATE := $(shell date '+%d-%m-%Y' || echo 'unknown') +BUILD_TIME := $(shell date '+%H:%M:%S' || echo 'unknown') VERSION := $(shell git describe --tags --abbrev=0 --exact-match 2>/dev/null || echo 'unknown') +GIT_DIRTY_BUILD := $(shell git diff --quiet ; echo $$?) + +GIT_DIRTY_SUFFIX := +ifeq ($(GIT_DIRTY_BUILD), 1) + GIT_DIRTY_SUFFIX := -dirty +endif CFLAGS += \ -DGIT_COMMIT=\"$(GIT_COMMIT)\" \ @@ -10,4 +17,16 @@ CFLAGS += \ -DGIT_BRANCH_NUM=\"$(GIT_BRANCH_NUM)\" \ -DBUILD_DATE=\"$(BUILD_DATE)\" \ -DVERSION=\"$(VERSION)\" \ - -DTARGET=$(HARDWARE_TARGET) \ No newline at end of file + -DTARGET=$(HARDWARE_TARGET) \ + -DBUILD_DIRTY=$(GIT_DIRTY_BUILD) + +# if suffix is set in environment (by Github), use it +ifeq (${DIST_SUFFIX},) + DIST_SUFFIX := local-$(GIT_COMMIT)$(GIT_DIRTY_SUFFIX) +else + DIST_SUFFIX := ${DIST_SUFFIX}$(GIT_DIRTY_SUFFIX) +endif + +#VERSION_STRING := $(VERSION) ($(GIT_BRANCH) @ $(GIT_COMMIT)), built $(BUILD_DATE) $(BUILD_TIME) +VERSION_STRING := $(DIST_SUFFIX), $(GIT_BRANCH) + diff --git a/make/rules.mk b/make/rules.mk index 16904333c11..e907b0eb8ea 100644 --- a/make/rules.mk +++ b/make/rules.mk @@ -1,4 +1,4 @@ -OBJ_DIR := $(OBJ_DIR)/$(TARGET) +OBJ_DIR := $(OBJ_DIR)/$(TARGET)-$(PROJECT) # Include source folder paths to virtual paths C_SOURCES := $(abspath ${C_SOURCES}) @@ -22,6 +22,7 @@ endif $(foreach dir, $(OBJECT_DIRS),$(shell mkdir -p $(dir))) BUILD_FLAGS_SHELL=\ + echo $(OBJ_DIR) ;\ echo "$(CFLAGS)" > $(OBJ_DIR)/BUILD_FLAGS.tmp; \ diff -u $(OBJ_DIR)/BUILD_FLAGS $(OBJ_DIR)/BUILD_FLAGS.tmp 2>&1 > /dev/null \ && ( echo "CFLAGS ok"; rm $(OBJ_DIR)/BUILD_FLAGS.tmp) \ @@ -48,7 +49,7 @@ $(OBJ_DIR)/$(PROJECT).elf: $(OBJECTS) $(OBJ_DIR)/$(PROJECT).hex: $(OBJ_DIR)/$(PROJECT).elf @echo "\tHEX\t" $@ @$(HEX) $< $@ - + $(OBJ_DIR)/$(PROJECT).bin: $(OBJ_DIR)/$(PROJECT).elf @echo "\tBIN\t" $@ @$(BIN) $< $@ diff --git a/make/toolchain.mk b/make/toolchain.mk index 04144a3ce9b..2946a2e20e6 100644 --- a/make/toolchain.mk +++ b/make/toolchain.mk @@ -4,12 +4,14 @@ OS := $(shell uname -s) ifeq ($(TOOLCHAIN), arm) PREFIX = arm-none-eabi- ifdef GCC_PATH -PREFIX = $(GCC_PATH)/$(PREFIX) +PREFIX := $(GCC_PATH)/$(PREFIX) endif endif -CC = $(PREFIX)gcc -std=gnu17 -CPP = $(PREFIX)g++ -std=gnu++17 +CCACHE := $(shell which ccache) + +CC = $(CCACHE) $(PREFIX)gcc -std=gnu17 +CPP = $(CCACHE) $(PREFIX)g++ -std=gnu++17 LD = $(PREFIX)g++ AS = $(PREFIX)gcc -x assembler-with-cpp CP = $(PREFIX)objcopy @@ -17,6 +19,7 @@ SZ = $(PREFIX)size HEX = $(CP) -O ihex BIN = $(CP) -O binary -S + ifeq ($(OS), Darwin) GDB = gdb else diff --git a/scripts/dist.py b/scripts/dist.py new file mode 100755 index 00000000000..b149678b9be --- /dev/null +++ b/scripts/dist.py @@ -0,0 +1,92 @@ +#!/usr/bin/env python3 + +from flipper.app import App +from os.path import join, exists +from os import makedirs +from update import Main as UpdateMain +import shutil + + +class Main(App): + def init(self): + self.subparsers = self.parser.add_subparsers(help="sub-command help") + + self.parser_copy = self.subparsers.add_parser( + "copy", help="Copy firmware binaries & metadata" + ) + + self.parser_copy.add_argument("-t", dest="target", required=True) + self.parser_copy.add_argument("-p", dest="projects", nargs="+", required=True) + self.parser_copy.add_argument("-s", dest="suffix", required=True) + self.parser_copy.add_argument( + "--bundlever", + dest="version", + help="If set, bundle update package for self-update", + required=False, + ) + self.parser_copy.add_argument( + "--noclean", + dest="noclean", + action="store_true", + help="Don't clean output directory", + required=False, + ) + self.parser_copy.set_defaults(func=self.copy) + + def get_project_filename(self, project, filetype): + return f"flipper-z-{self.args.target}-{project}-{self.args.suffix}.{filetype}" + + def get_dist_filepath(self, filename): + return join(self.output_dir_path, filename) + + def copy_single_project(self, project): + target_project = f"{self.args.target}-{project}" + obj_directory = join("firmware", ".obj", target_project) + + for filetype in ("elf", "bin", "dfu", "json"): + shutil.copyfile( + join(obj_directory, f"{project}.{filetype}"), + self.get_dist_filepath(self.get_project_filename(project, filetype)), + ) + + def copy(self): + self.output_dir_path = join("dist", self.args.target) + if exists(self.output_dir_path) and not self.args.noclean: + shutil.rmtree(self.output_dir_path) + + if not exists(self.output_dir_path): + makedirs(self.output_dir_path) + + for project in self.args.projects: + self.copy_single_project(project) + + self.logger.info( + f"Firmware binaries can be found at:\n\t{self.output_dir_path}" + ) + if self.args.version: + bundle_dir = join( + self.output_dir_path, f"{self.args.target}-update-{self.args.suffix}" + ) + bundle_args = [ + "generate", + "-d", + bundle_dir, + "-v", + self.args.version, + "-t", + self.args.target, + "-dfu", + self.get_dist_filepath(self.get_project_filename("firmware", "dfu")), + "-stage", + self.get_dist_filepath(self.get_project_filename("updater", "bin")), + ] + self.logger.info( + f"Use this directory to self-update your Flipper:\n\t{bundle_dir}" + ) + return UpdateMain(no_exit=True)(bundle_args) + + return 0 + + +if __name__ == "__main__": + Main()() diff --git a/scripts/dist.sh b/scripts/dist.sh deleted file mode 100755 index 03ee5e7e4b5..00000000000 --- a/scripts/dist.sh +++ /dev/null @@ -1,52 +0,0 @@ -#!/usr/bin/env bash - -set -e - -suffix="${DIST_SUFFIX:=local}" - -rm -rf "dist/${TARGET}" -mkdir -p "dist/${TARGET}" - -# copy build outputs -cp bootloader/.obj/${TARGET}/bootloader.elf \ - dist/${TARGET}/flipper-z-${TARGET}-bootloader-${suffix}.elf -cp bootloader/.obj/${TARGET}/bootloader.bin \ - dist/${TARGET}/flipper-z-${TARGET}-bootloader-${suffix}.bin -cp bootloader/.obj/${TARGET}/bootloader.dfu \ - dist/${TARGET}/flipper-z-${TARGET}-bootloader-${suffix}.dfu -cp bootloader/.obj/${TARGET}/bootloader.json \ - dist/${TARGET}/flipper-z-${TARGET}-bootloader-${suffix}.json -cp firmware/.obj/${TARGET}/firmware.elf \ - dist/${TARGET}/flipper-z-${TARGET}-firmware-${suffix}.elf -cp firmware/.obj/${TARGET}/firmware.bin \ - dist/${TARGET}/flipper-z-${TARGET}-firmware-${suffix}.bin -cp firmware/.obj/${TARGET}/firmware.dfu \ - dist/${TARGET}/flipper-z-${TARGET}-firmware-${suffix}.dfu -cp firmware/.obj/${TARGET}/firmware.json \ - dist/${TARGET}/flipper-z-${TARGET}-firmware-${suffix}.json - -# generate full.bin -cp dist/${TARGET}/flipper-z-${TARGET}-bootloader-${suffix}.bin \ - dist/${TARGET}/flipper-z-${TARGET}-full-${suffix}.bin -dd if=/dev/null of=dist/${TARGET}/flipper-z-${TARGET}-full-${suffix}.bin bs=1 count=0 seek=32768 2> /dev/null -cat dist/${TARGET}/flipper-z-${TARGET}-firmware-${suffix}.bin \ - >>dist/${TARGET}/flipper-z-${TARGET}-full-${suffix}.bin \ - 2> /dev/null - -# generate full.dfu -./scripts/bin2dfu.py \ - -i dist/${TARGET}/flipper-z-${TARGET}-full-${suffix}.bin \ - -o dist/${TARGET}/flipper-z-${TARGET}-full-${suffix}.dfu \ - -a 0x08000000 \ - -l "Flipper Zero $(echo ${TARGET} | tr a-z A-Z)" - -# generate full.json -./scripts/meta.py merge \ - -i dist/${TARGET}/flipper-z-${TARGET}-bootloader-${suffix}.json \ - dist/${TARGET}/flipper-z-${TARGET}-firmware-${suffix}.json \ - >dist/${TARGET}/flipper-z-${TARGET}-full-${suffix}.json - -echo "Firmware binaries can be found at:" -echo -e "\t$(pwd)/dist/${TARGET}" -echo "Use this file to flash your Flipper:" -echo -e "\tflipper-z-${TARGET}-full-${suffix}.dfu" diff --git a/scripts/flipper/app.py b/scripts/flipper/app.py index 3c911bc4ddd..ea62f674e41 100644 --- a/scripts/flipper/app.py +++ b/scripts/flipper/app.py @@ -5,8 +5,9 @@ class App: - def __init__(self): + def __init__(self, no_exit=False): # Argument Parser + self.no_exit = no_exit self.parser = argparse.ArgumentParser() self.parser.add_argument("-d", "--debug", action="store_true", help="Debug") # Logging @@ -14,8 +15,8 @@ def __init__(self): # Application specific initialization self.init() - def __call__(self): - self.args, _ = self.parser.parse_known_args() + def __call__(self, args=None): + self.args, _ = self.parser.parse_known_args(args=args) # configure log output self.log_level = logging.DEBUG if self.args.debug else logging.INFO self.logger.setLevel(self.log_level) @@ -30,10 +31,15 @@ def __call__(self): return_code = self.call() self.after() if isinstance(return_code, int): - exit(return_code) + return self._exit(return_code) else: self.logger.error(f"Missing return code") - exit(255) + return self._exit(255) + + def _exit(self, code): + if self.no_exit: + return code + exit(code) def call(self): if "func" not in self.args: diff --git a/scripts/flipper/utils/fff.py b/scripts/flipper/utils/fff.py index e44d3430811..b7f89321a56 100644 --- a/scripts/flipper/utils/fff.py +++ b/scripts/flipper/utils/fff.py @@ -95,9 +95,9 @@ def setHeader(self, filetype: str, version: int): self.writeKey("Version", version) def load(self, filename: str): - file = open(filename, "r") - self.lines = file.readlines() + with open(filename, "r") as file: + self.lines = file.readlines() def save(self, filename: str): - file = open(filename, "w") - file.write("\n".join(self.lines)) + with open(filename, "w") as file: + file.write("\n".join(self.lines)) diff --git a/scripts/lint.py b/scripts/lint.py index 6537b548cc9..bf1f5e680ed 100755 --- a/scripts/lint.py +++ b/scripts/lint.py @@ -83,7 +83,7 @@ def _format_sources(self, sources: list, dry_run: bool = False): pool = multiprocessing.Pool() results = pool.map(self._format_source, tasks) - return not False in results + return all(results) def _fix_filename(self, filename: str): return filename.replace("-", "_") diff --git a/scripts/update.py b/scripts/update.py new file mode 100755 index 00000000000..7e49aad09ad --- /dev/null +++ b/scripts/update.py @@ -0,0 +1,77 @@ +#!/usr/bin/env python3 + +from flipper.app import App +from flipper.utils.fff import FlipperFormatFile +from os.path import basename, join, exists +from os import makedirs +import shutil +import zlib + + +class Main(App): + def init(self): + self.subparsers = self.parser.add_subparsers(help="sub-command help") + + # generate + self.parser_generate = self.subparsers.add_parser( + "generate", help="Generate update description file" + ) + + self.parser_generate.add_argument("-d", dest="directory", required=True) + self.parser_generate.add_argument("-v", dest="version", required=True) + self.parser_generate.add_argument("-t", dest="target", required=True) + self.parser_generate.add_argument("-dfu", dest="dfu", required=True) + self.parser_generate.add_argument("-stage", dest="stage", required=True) + self.parser_generate.add_argument("-radio", dest="radiobin", required=False) + self.parser_generate.add_argument( + "-radioaddr", dest="radioaddr", required=False + ) + + self.parser_generate.set_defaults(func=self.generate) + + def generate(self): + stage_basename = basename(self.args.stage) + dfu_basename = basename(self.args.dfu) + + if not exists(self.args.directory): + makedirs(self.args.directory) + + shutil.copyfile(self.args.stage, join(self.args.directory, stage_basename)) + shutil.copyfile(self.args.dfu, join(self.args.directory, dfu_basename)) + + file = FlipperFormatFile() + file.setHeader("Flipper firmware upgrade configuration", 1) + file.writeKey("Info", self.args.version) + file.writeKey("Target", self.args.target[1:]) # dirty 'f' strip + file.writeKey("Loader", stage_basename) + file.writeComment("little-endian hex!") + file.writeKey("Loader CRC", self.int2ffhex(self.crc(self.args.stage))) + file.writeKey("Firmware", dfu_basename) + file.writeKey("Radio", self.args.radiobin or "") + file.writeKey("Radio address", self.int2ffhex(self.args.radioaddr or 0)) + file.save("%s/update.fuf" % self.args.directory) + + return 0 + + @staticmethod + def int2ffhex(value: int): + hexstr = "%08X" % value + return " ".join(list(Main.batch(hexstr, 2))[::-1]) + + @staticmethod + def crc(fileName): + prev = 0 + with open(fileName, "rb") as file: + for eachLine in file: + prev = zlib.crc32(eachLine, prev) + return prev & 0xFFFFFFFF + + @staticmethod + def batch(iterable, n=1): + l = len(iterable) + for ndx in range(0, l, n): + yield iterable[ndx : min(ndx + n, l)] + + +if __name__ == "__main__": + Main()() From fed18f7c42ad27f7a0f5ba40232e3f9095bace86 Mon Sep 17 00:00:00 2001 From: hedger Date: Thu, 14 Apr 2022 00:29:58 +0300 Subject: [PATCH 05/20] [FL-2457] Changed dist names for firmware files #1109 --- scripts/dist.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/scripts/dist.py b/scripts/dist.py index b149678b9be..172ecc01be7 100755 --- a/scripts/dist.py +++ b/scripts/dist.py @@ -34,6 +34,9 @@ def init(self): self.parser_copy.set_defaults(func=self.copy) def get_project_filename(self, project, filetype): + # Temporary fix + if project == "firmware" and filetype != "elf": + project = "full" return f"flipper-z-{self.args.target}-{project}-{self.args.suffix}.{filetype}" def get_dist_filepath(self, filename): From 72a6bbb8ad653ab346bb02d9c5d2e672da8ce034 Mon Sep 17 00:00:00 2001 From: Nikolay Minaylov Date: Thu, 14 Apr 2022 14:28:59 +0300 Subject: [PATCH 06/20] [FL-2433, FL-2408] Get rid of file_worker in archive and various fixes (#1105) * Archive: get rid of file_worker and various fixes * USB init moved to CLI service --- applications/archive/helpers/archive_apps.c | 26 ++- .../archive/helpers/archive_browser.c | 11 ++ .../archive/helpers/archive_browser.h | 1 + .../archive/helpers/archive_favorites.c | 156 ++++++++++++------ .../archive/helpers/archive_favorites.h | 3 +- applications/archive/helpers/archive_files.c | 16 +- applications/archive/helpers/archive_files.h | 4 +- .../archive/views/archive_browser_view.c | 8 +- applications/cli/cli.c | 2 + firmware/targets/f7/furi_hal/furi_hal.c | 3 +- firmware/targets/f7/furi_hal/furi_hal_usb.c | 2 +- firmware/targets/f7/furi_hal/furi_hal_vcp.c | 17 +- lib/FreeRTOS-glue/cmsis_os2.c | 6 +- 13 files changed, 172 insertions(+), 83 deletions(-) diff --git a/applications/archive/helpers/archive_apps.c b/applications/archive/helpers/archive_apps.c index d3cabd5647a..e1c429a78ee 100644 --- a/applications/archive/helpers/archive_apps.c +++ b/applications/archive/helpers/archive_apps.c @@ -21,13 +21,23 @@ bool archive_app_is_available(void* context, const char* path) { ArchiveAppTypeEnum app = archive_get_app_type(path); if(app == ArchiveAppTypeU2f) { - FileWorker* file_worker = file_worker_alloc(true); bool file_exists = false; - file_worker_is_file_exist(file_worker, "/any/u2f/key.u2f", &file_exists); + Storage* fs_api = furi_record_open("storage"); + File* file = storage_file_alloc(fs_api); + + file_exists = storage_file_open(file, "/any/u2f/key.u2f", FSAM_READ, FSOM_OPEN_EXISTING); if(file_exists) { - file_worker_is_file_exist(file_worker, "/any/u2f/cnt.u2f", &file_exists); + storage_file_close(file); + file_exists = + storage_file_open(file, "/any/u2f/cnt.u2f", FSAM_READ, FSOM_OPEN_EXISTING); + if(file_exists) { + storage_file_close(file); + } } - file_worker_free(file_worker); + + storage_file_free(file); + furi_record_close("storage"); + return file_exists; } else { return false; @@ -60,10 +70,10 @@ void archive_app_delete_file(void* context, const char* path) { bool res = false; if(app == ArchiveAppTypeU2f) { - FileWorker* file_worker = file_worker_alloc(true); - res = file_worker_remove(file_worker, "/any/u2f/key.u2f"); - res |= file_worker_remove(file_worker, "/any/u2f/cnt.u2f"); - file_worker_free(file_worker); + Storage* fs_api = furi_record_open("storage"); + res = (storage_common_remove(fs_api, "/any/u2f/key.u2f") == FSE_OK); + res |= (storage_common_remove(fs_api, "/any/u2f/cnt.u2f") == FSE_OK); + furi_record_close("storage"); if(archive_is_favorite("/app:u2f/U2F Token")) { archive_favorites_delete("/app:u2f/U2F Token"); diff --git a/applications/archive/helpers/archive_browser.c b/applications/archive/helpers/archive_browser.c index c8e78dcaa66..418fdb47b6d 100644 --- a/applications/archive/helpers/archive_browser.c +++ b/applications/archive/helpers/archive_browser.c @@ -392,6 +392,17 @@ void archive_enter_dir(ArchiveBrowserView* browser, string_t name) { furi_assert(browser); furi_assert(name); + uint8_t browser_depth = 0; + with_view_model( + browser->view, (ArchiveBrowserViewModel * model) { + browser_depth = idx_last_array_size(model->idx_last); + return false; + }); + + if(browser_depth > BROWSER_DEPTH_MAX) { + return; + } + archive_dir_count_items(browser, string_get_cstr(name)); with_view_model( diff --git a/applications/archive/helpers/archive_browser.h b/applications/archive/helpers/archive_browser.h index 593a9be0db7..e74357f8d4b 100644 --- a/applications/archive/helpers/archive_browser.h +++ b/applications/archive/helpers/archive_browser.h @@ -4,6 +4,7 @@ #define TAB_RIGHT InputKeyRight //default tab swith direction #define FILE_LIST_BUF_LEN 100 +#define BROWSER_DEPTH_MAX 8 static const char* tab_default_paths[] = { [ArchiveTabFavorites] = "/any/favorites", diff --git a/applications/archive/helpers/archive_favorites.c b/applications/archive/helpers/archive_favorites.c index e2777f5e1d4..ef8f1b2257c 100644 --- a/applications/archive/helpers/archive_favorites.c +++ b/applications/archive/helpers/archive_favorites.c @@ -4,20 +4,63 @@ #include "archive_apps.h" #include "archive_browser.h" +#define ARCHIVE_FAV_FILE_BUF_LEN 32 + +static bool archive_favorites_read_line(File* file, string_t str_result) { + string_reset(str_result); + uint8_t buffer[ARCHIVE_FAV_FILE_BUF_LEN]; + bool result = false; + + do { + uint16_t read_count = storage_file_read(file, buffer, ARCHIVE_FAV_FILE_BUF_LEN); + if(storage_file_get_error(file) != FSE_OK) { + return false; + } + + for(uint16_t i = 0; i < read_count; i++) { + if(buffer[i] == '\n') { + uint32_t position = storage_file_tell(file); + if(storage_file_get_error(file) != FSE_OK) { + return false; + } + + position = position - read_count + i + 1; + + storage_file_seek(file, position, true); + if(storage_file_get_error(file) != FSE_OK) { + return false; + } + + result = true; + break; + } else { + string_push_back(str_result, buffer[i]); + } + } + + if(result || read_count == 0) { + break; + } + } while(true); + + return result; +} + uint16_t archive_favorites_count(void* context) { furi_assert(context); - FileWorker* file_worker = file_worker_alloc(true); + Storage* fs_api = furi_record_open("storage"); + File* file = storage_file_alloc(fs_api); string_t buffer; string_init(buffer); - bool result = file_worker_open(file_worker, ARCHIVE_FAV_PATH, FSAM_READ, FSOM_OPEN_EXISTING); + bool result = storage_file_open(file, ARCHIVE_FAV_PATH, FSAM_READ, FSOM_OPEN_EXISTING); uint16_t lines = 0; if(result) { while(1) { - if(!file_worker_read_until(file_worker, buffer, '\n')) { + if(!archive_favorites_read_line(file, buffer)) { break; } if(!string_size(buffer)) { @@ -27,21 +70,26 @@ uint16_t archive_favorites_count(void* context) { } } + storage_file_close(file); + string_clear(buffer); - file_worker_close(file_worker); - file_worker_free(file_worker); + storage_file_free(file); + furi_record_close("storage"); + return lines; } static bool archive_favourites_rescan() { string_t buffer; string_init(buffer); - FileWorker* file_worker = file_worker_alloc(true); + Storage* fs_api = furi_record_open("storage"); + File* file = storage_file_alloc(fs_api); + File* fav_item_file = storage_file_alloc(fs_api); - bool result = file_worker_open(file_worker, ARCHIVE_FAV_PATH, FSAM_READ, FSOM_OPEN_EXISTING); + bool result = storage_file_open(file, ARCHIVE_FAV_PATH, FSAM_READ, FSOM_OPEN_EXISTING); if(result) { while(1) { - if(!file_worker_read_until(file_worker, buffer, '\n')) { + if(!archive_favorites_read_line(file, buffer)) { break; } if(!string_size(buffer)) { @@ -53,9 +101,10 @@ static bool archive_favourites_rescan() { archive_file_append(ARCHIVE_FAV_TEMP_PATH, "%s\n", string_get_cstr(buffer)); } } else { - bool file_exists = false; - file_worker_is_file_exist(file_worker, string_get_cstr(buffer), &file_exists); + bool file_exists = storage_file_open( + fav_item_file, string_get_cstr(buffer), FSAM_READ, FSOM_OPEN_EXISTING); if(file_exists) { + storage_file_close(fav_item_file); archive_file_append(ARCHIVE_FAV_TEMP_PATH, "%s\n", string_get_cstr(buffer)); } } @@ -64,11 +113,13 @@ static bool archive_favourites_rescan() { string_clear(buffer); - file_worker_close(file_worker); - file_worker_remove(file_worker, ARCHIVE_FAV_PATH); - file_worker_rename(file_worker, ARCHIVE_FAV_TEMP_PATH, ARCHIVE_FAV_PATH); + storage_file_close(file); + storage_common_remove(fs_api, ARCHIVE_FAV_PATH); + storage_common_rename(fs_api, ARCHIVE_FAV_TEMP_PATH, ARCHIVE_FAV_PATH); - file_worker_free(file_worker); + storage_file_free(file); + storage_file_free(fav_item_file); + furi_record_close("storage"); return result; } @@ -77,7 +128,9 @@ bool archive_favorites_read(void* context) { furi_assert(context); ArchiveBrowserView* browser = context; - FileWorker* file_worker = file_worker_alloc(true); + Storage* fs_api = furi_record_open("storage"); + File* file = storage_file_alloc(fs_api); + File* fav_item_file = storage_file_alloc(fs_api); string_t buffer; FileInfo file_info; @@ -88,11 +141,11 @@ bool archive_favorites_read(void* context) { archive_file_array_rm_all(browser); - bool result = file_worker_open(file_worker, ARCHIVE_FAV_PATH, FSAM_READ, FSOM_OPEN_EXISTING); + bool result = storage_file_open(file, ARCHIVE_FAV_PATH, FSAM_READ, FSOM_OPEN_EXISTING); if(result) { while(1) { - if(!file_worker_read_until(file_worker, buffer, '\n')) { + if(!archive_favorites_read_line(file, buffer)) { break; } if(!string_size(buffer)) { @@ -107,10 +160,10 @@ bool archive_favorites_read(void* context) { need_refresh = true; } } else { - bool file_exists = false; - file_worker_is_file_exist(file_worker, string_get_cstr(buffer), &file_exists); - + bool file_exists = storage_file_open( + fav_item_file, string_get_cstr(buffer), FSAM_READ, FSOM_OPEN_EXISTING); if(file_exists) { + storage_file_close(fav_item_file); archive_add_file_item(browser, &file_info, string_get_cstr(buffer)); file_count++; } else { @@ -121,9 +174,11 @@ bool archive_favorites_read(void* context) { string_reset(buffer); } } + storage_file_close(file); string_clear(buffer); - file_worker_close(file_worker); - file_worker_free(file_worker); + storage_file_free(file); + storage_file_free(fav_item_file); + furi_record_close("storage"); archive_set_item_count(browser, file_count); @@ -143,12 +198,14 @@ bool archive_favorites_delete(const char* format, ...) { va_end(args); string_init(buffer); - FileWorker* file_worker = file_worker_alloc(true); + Storage* fs_api = furi_record_open("storage"); + File* file = storage_file_alloc(fs_api); + + bool result = storage_file_open(file, ARCHIVE_FAV_PATH, FSAM_READ, FSOM_OPEN_EXISTING); - bool result = file_worker_open(file_worker, ARCHIVE_FAV_PATH, FSAM_READ, FSOM_OPEN_EXISTING); if(result) { while(1) { - if(!file_worker_read_until(file_worker, buffer, '\n')) { + if(!archive_favorites_read_line(file, buffer)) { break; } if(!string_size(buffer)) { @@ -164,11 +221,12 @@ bool archive_favorites_delete(const char* format, ...) { string_clear(buffer); string_clear(filename); - file_worker_close(file_worker); - file_worker_remove(file_worker, ARCHIVE_FAV_PATH); - file_worker_rename(file_worker, ARCHIVE_FAV_TEMP_PATH, ARCHIVE_FAV_PATH); + storage_file_close(file); + storage_common_remove(fs_api, ARCHIVE_FAV_PATH); + storage_common_rename(fs_api, ARCHIVE_FAV_TEMP_PATH, ARCHIVE_FAV_PATH); - file_worker_free(file_worker); + storage_file_free(file); + furi_record_close("storage"); return result; } @@ -182,14 +240,15 @@ bool archive_is_favorite(const char* format, ...) { va_end(args); string_init(buffer); - FileWorker* file_worker = file_worker_alloc(true); + Storage* fs_api = furi_record_open("storage"); + File* file = storage_file_alloc(fs_api); bool found = false; - bool result = file_worker_open(file_worker, ARCHIVE_FAV_PATH, FSAM_READ, FSOM_OPEN_EXISTING); + bool result = storage_file_open(file, ARCHIVE_FAV_PATH, FSAM_READ, FSOM_OPEN_EXISTING); if(result) { while(1) { - if(!file_worker_read_until(file_worker, buffer, '\n')) { + if(!archive_favorites_read_line(file, buffer)) { break; } if(!string_size(buffer)) { @@ -202,10 +261,11 @@ bool archive_is_favorite(const char* format, ...) { } } + storage_file_close(file); string_clear(buffer); string_clear(filename); - file_worker_close(file_worker); - file_worker_free(file_worker); + storage_file_free(file); + furi_record_close("storage"); return found; } @@ -214,7 +274,8 @@ bool archive_favorites_rename(const char* src, const char* dst) { furi_assert(src); furi_assert(dst); - FileWorker* file_worker = file_worker_alloc(true); + Storage* fs_api = furi_record_open("storage"); + File* file = storage_file_alloc(fs_api); string_t path; string_t buffer; @@ -223,11 +284,11 @@ bool archive_favorites_rename(const char* src, const char* dst) { string_init(path); string_printf(path, "%s", src); - bool result = file_worker_open(file_worker, ARCHIVE_FAV_PATH, FSAM_READ, FSOM_OPEN_EXISTING); + bool result = storage_file_open(file, ARCHIVE_FAV_PATH, FSAM_READ, FSOM_OPEN_EXISTING); if(result) { while(1) { - if(!file_worker_read_until(file_worker, buffer, '\n')) { + if(!archive_favorites_read_line(file, buffer)) { break; } if(!string_size(buffer)) { @@ -244,11 +305,12 @@ bool archive_favorites_rename(const char* src, const char* dst) { string_clear(buffer); string_clear(path); - file_worker_close(file_worker); - file_worker_remove(file_worker, ARCHIVE_FAV_PATH); - file_worker_rename(file_worker, ARCHIVE_FAV_TEMP_PATH, ARCHIVE_FAV_PATH); + storage_file_close(file); + storage_common_remove(fs_api, ARCHIVE_FAV_PATH); + storage_common_rename(fs_api, ARCHIVE_FAV_TEMP_PATH, ARCHIVE_FAV_PATH); - file_worker_free(file_worker); + storage_file_free(file); + furi_record_close("storage"); return result; } @@ -263,15 +325,17 @@ void archive_favorites_save(void* context) { furi_assert(context); ArchiveBrowserView* browser = context; - FileWorker* file_worker = file_worker_alloc(true); + Storage* fs_api = furi_record_open("storage"); + File* file = storage_file_alloc(fs_api); for(size_t i = 0; i < archive_file_get_array_size(browser); i++) { ArchiveFile_t* item = archive_get_file_at(browser, i); archive_file_append(ARCHIVE_FAV_TEMP_PATH, "%s\n", string_get_cstr(item->name)); } - file_worker_remove(file_worker, ARCHIVE_FAV_PATH); - file_worker_rename(file_worker, ARCHIVE_FAV_TEMP_PATH, ARCHIVE_FAV_PATH); + storage_common_remove(fs_api, ARCHIVE_FAV_PATH); + storage_common_rename(fs_api, ARCHIVE_FAV_TEMP_PATH, ARCHIVE_FAV_PATH); - file_worker_free(file_worker); -} \ No newline at end of file + storage_file_free(file); + furi_record_close("storage"); +} diff --git a/applications/archive/helpers/archive_favorites.h b/applications/archive/helpers/archive_favorites.h index 3a517f4bc95..681d0ec6910 100644 --- a/applications/archive/helpers/archive_favorites.h +++ b/applications/archive/helpers/archive_favorites.h @@ -1,5 +1,6 @@ #pragma once -#include "file_worker.h" + +#include #define ARCHIVE_FAV_PATH "/any/favorites.txt" #define ARCHIVE_FAV_TEMP_PATH "/any/favorites.tmp" diff --git a/applications/archive/helpers/archive_files.c b/applications/archive/helpers/archive_files.c index 9628651938d..156e66f5d4b 100644 --- a/applications/archive/helpers/archive_files.c +++ b/applications/archive/helpers/archive_files.c @@ -201,18 +201,18 @@ void archive_file_append(const char* path, const char* format, ...) { string_init_vprintf(string, format, args); va_end(args); - FileWorker* file_worker = file_worker_alloc(false); + Storage* fs_api = furi_record_open("storage"); + File* file = storage_file_alloc(fs_api); - if(!file_worker_open(file_worker, path, FSAM_WRITE, FSOM_OPEN_APPEND)) { - FURI_LOG_E(TAG, "Append open error"); - } + bool res = storage_file_open(file, path, FSAM_WRITE, FSOM_OPEN_APPEND); - if(!file_worker_write(file_worker, string_get_cstr(string), string_size(string))) { - FURI_LOG_E(TAG, "Append write error"); + if(res) { + storage_file_write(file, string_get_cstr(string), string_size(string)); } - file_worker_close(file_worker); - file_worker_free(file_worker); + storage_file_close(file); + storage_file_free(file); + furi_record_close("storage"); } void archive_delete_file(void* context, const char* format, ...) { diff --git a/applications/archive/helpers/archive_files.h b/applications/archive/helpers/archive_files.h index b65f96aefd5..58dd00115f1 100644 --- a/applications/archive/helpers/archive_files.h +++ b/applications/archive/helpers/archive_files.h @@ -1,6 +1,8 @@ #pragma once -#include "file_worker.h" + #include +#include +#include typedef enum { ArchiveFileTypeIButton, diff --git a/applications/archive/views/archive_browser_view.c b/applications/archive/views/archive_browser_view.c index 34588f33a21..ed75621d87c 100644 --- a/applications/archive/views/archive_browser_view.c +++ b/applications/archive/views/archive_browser_view.c @@ -54,6 +54,10 @@ static void render_item_menu(Canvas* canvas, ArchiveBrowserViewModel* model) { ArchiveFile_t* selected = files_array_get(model->files, model->item_idx - model->array_offset); + if((selected->fav) || (model->tab_idx == ArchiveTabFavorites)) { + string_set_str(menu[1], "Unpin"); + } + if(!archive_is_known_app(selected->type)) { string_set_str(menu[0], "---"); string_set_str(menu[1], "---"); @@ -67,10 +71,6 @@ static void render_item_menu(Canvas* canvas, ArchiveBrowserViewModel* model) { } } - if((selected->fav) || (model->tab_idx == ArchiveTabFavorites)) { - string_set_str(menu[1], "Unpin"); - } - for(size_t i = 0; i < MENU_ITEMS; i++) { canvas_draw_str(canvas, 82, 27 + i * 11, string_get_cstr(menu[i])); string_clear(menu[i]); diff --git a/applications/cli/cli.c b/applications/cli/cli.c index 0453fb66925..091d37f8b2a 100644 --- a/applications/cli/cli.c +++ b/applications/cli/cli.c @@ -401,6 +401,8 @@ void cli_delete_command(Cli* cli, const char* name) { int32_t cli_srv(void* p) { Cli* cli = cli_alloc(); + furi_hal_vcp_init(); + // Init basic cli commands cli_commands_init(cli); diff --git a/firmware/targets/f7/furi_hal/furi_hal.c b/firmware/targets/f7/furi_hal/furi_hal.c index e671dd8cd8b..a2e78bfe375 100644 --- a/firmware/targets/f7/furi_hal/furi_hal.c +++ b/firmware/targets/f7/furi_hal/furi_hal.c @@ -55,10 +55,9 @@ void furi_hal_init() { furi_hal_crypto_init(); furi_hal_crc_init(true); - // VCP + USB + // USB #ifndef FURI_RAM_EXEC furi_hal_usb_init(); - furi_hal_vcp_init(); FURI_LOG_I(TAG, "USB OK"); #endif diff --git a/firmware/targets/f7/furi_hal/furi_hal_usb.c b/firmware/targets/f7/furi_hal/furi_hal_usb.c index c2bfb969e2f..f1044c36bba 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_usb.c +++ b/firmware/targets/f7/furi_hal/furi_hal_usb.c @@ -268,8 +268,8 @@ static int32_t furi_hal_usb_thread(void* context) { usbd_reg_event(&udev, usbd_evt_reset, reset_evt); FURI_LOG_I(TAG, "USB Mode change done"); usb.enabled = true; - usb.if_cur = if_new; } + usb.if_cur = if_new; } if(flags & EventEnable) { if((!usb.enabled) && (usb.if_cur != NULL)) { diff --git a/firmware/targets/f7/furi_hal/furi_hal_vcp.c b/firmware/targets/f7/furi_hal/furi_hal_vcp.c index 5040deed501..a4694625e7c 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_vcp.c +++ b/firmware/targets/f7/furi_hal/furi_hal_vcp.c @@ -12,15 +12,14 @@ #define VCP_IF_NUM 0 typedef enum { - VcpEvtReserved = (1 << 0), // Reserved for StreamBuffer internal event - VcpEvtEnable = (1 << 1), - VcpEvtDisable = (1 << 2), - VcpEvtConnect = (1 << 3), - VcpEvtDisconnect = (1 << 4), - VcpEvtStreamRx = (1 << 5), - VcpEvtRx = (1 << 6), - VcpEvtStreamTx = (1 << 7), - VcpEvtTx = (1 << 8), + VcpEvtEnable = (1 << 0), + VcpEvtDisable = (1 << 1), + VcpEvtConnect = (1 << 2), + VcpEvtDisconnect = (1 << 3), + VcpEvtStreamRx = (1 << 4), + VcpEvtRx = (1 << 5), + VcpEvtStreamTx = (1 << 6), + VcpEvtTx = (1 << 7), } WorkerEvtFlags; #define VCP_THREAD_FLAG_ALL \ diff --git a/lib/FreeRTOS-glue/cmsis_os2.c b/lib/FreeRTOS-glue/cmsis_os2.c index 82c76525336..4e59fb54dc4 100644 --- a/lib/FreeRTOS-glue/cmsis_os2.c +++ b/lib/FreeRTOS-glue/cmsis_os2.c @@ -1225,7 +1225,7 @@ osStatus_t osTimerStart (osTimerId_t timer_id, uint32_t ticks) { stat = osErrorParameter; } else { - if (xTimerChangePeriod (hTimer, ticks, 0) == pdPASS) { + if (xTimerChangePeriod (hTimer, ticks, portMAX_DELAY) == pdPASS) { stat = osOK; } else { stat = osErrorResource; @@ -1254,7 +1254,7 @@ osStatus_t osTimerStop (osTimerId_t timer_id) { stat = osErrorResource; } else { - if (xTimerStop (hTimer, 0) == pdPASS) { + if (xTimerStop (hTimer, portMAX_DELAY) == pdPASS) { stat = osOK; } else { stat = osError; @@ -1305,7 +1305,7 @@ osStatus_t osTimerDelete (osTimerId_t timer_id) { callb = (TimerCallback_t *)pvTimerGetTimerID (hTimer); #endif - if (xTimerDelete (hTimer, 0) == pdPASS) { + if (xTimerDelete (hTimer, portMAX_DELAY) == pdPASS) { #if (configSUPPORT_DYNAMIC_ALLOCATION == 1) if ((uint32_t)callb & 1U) { /* Callback memory was allocated from dynamic pool, clear flag */ From 779d3190695d2365714157fadf8a5843a409a928 Mon Sep 17 00:00:00 2001 From: Nikolay Minaylov Date: Thu, 14 Apr 2022 15:03:47 +0300 Subject: [PATCH 07/20] [FL-2220, FL-2221, FL-1883] RFID and iButton GUI update (#1107) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * RFID and iButton gui update * Grammar nazi: readed -> read * Grammar nazi pt.2: writed -> written Co-authored-by: あく --- applications/ibutton/ibutton_app.h | 12 +++- .../scene/ibutton_scene_delete_success.cpp | 2 +- .../scene/ibutton_scene_exit_confirm.cpp | 51 ++++++++++++++++ .../scene/ibutton_scene_exit_confirm.h | 9 +++ .../ibutton/scene/ibutton_scene_read.cpp | 9 ++- .../scene/ibutton_scene_read_crc_error.cpp | 2 +- ...nu.cpp => ibutton_scene_read_key_menu.cpp} | 15 ++--- ...y_menu.h => ibutton_scene_read_key_menu.h} | 2 +- .../ibutton_scene_read_not_key_error.cpp | 2 +- .../scene/ibutton_scene_read_success.cpp | 12 ++-- .../scene/ibutton_scene_retry_confirm.cpp | 51 ++++++++++++++++ .../scene/ibutton_scene_retry_confirm.h | 9 +++ .../ibutton/scene/ibutton_scene_save_name.cpp | 2 +- .../scene/ibutton_scene_save_success.cpp | 4 +- .../scene/ibutton_scene_write_success.cpp | 2 +- .../infrared_app_scene_edit_rename_done.cpp | 1 - .../lfrfid/helpers/decoder_emmarin.cpp | 8 +-- applications/lfrfid/helpers/decoder_emmarin.h | 2 +- applications/lfrfid/helpers/rfid_reader.cpp | 28 ++++----- applications/lfrfid/helpers/rfid_reader.h | 6 +- applications/lfrfid/lfrfid_app.cpp | 8 ++- applications/lfrfid/lfrfid_app.h | 6 +- .../scene/lfrfid_app_scene_delete_confirm.cpp | 7 ++- .../scene/lfrfid_app_scene_delete_success.cpp | 2 +- .../scene/lfrfid_app_scene_exit_confirm.cpp | 59 +++++++++++++++++++ .../scene/lfrfid_app_scene_exit_confirm.h | 13 ++++ ...enu.cpp => lfrfid_app_scene_read_menu.cpp} | 12 ++-- ...ed_menu.h => lfrfid_app_scene_read_menu.h} | 2 +- .../scene/lfrfid_app_scene_read_success.cpp | 10 +++- .../scene/lfrfid_app_scene_retry_confirm.cpp | 59 +++++++++++++++++++ .../scene/lfrfid_app_scene_retry_confirm.h | 13 ++++ .../scene/lfrfid_app_scene_save_name.cpp | 2 +- .../scene/lfrfid_app_scene_save_success.cpp | 6 +- .../scene/lfrfid_app_scene_write_success.cpp | 2 +- applications/rpc/rpc_storage.c | 10 ++-- .../storage/filesystem_api_internal.h | 8 +-- applications/storage/storage.h | 6 +- applications/storage/storage_cli.c | 56 +++++++++--------- applications/storage/storages/storage_ext.c | 6 +- applications/storage/storages/storage_int.c | 6 +- lib/nfc_protocols/mifare_ultralight.c | 10 ++-- lib/nfc_protocols/mifare_ultralight.h | 2 +- lib/one_wire/ibutton/ibutton_writer.c | 4 +- scripts/flipper/storage.py | 12 ++-- 44 files changed, 419 insertions(+), 131 deletions(-) create mode 100644 applications/ibutton/scene/ibutton_scene_exit_confirm.cpp create mode 100644 applications/ibutton/scene/ibutton_scene_exit_confirm.h rename applications/ibutton/scene/{ibutton_scene_readed_key_menu.cpp => ibutton_scene_read_key_menu.cpp} (76%) rename applications/ibutton/scene/{ibutton_scene_readed_key_menu.h => ibutton_scene_read_key_menu.h} (81%) create mode 100644 applications/ibutton/scene/ibutton_scene_retry_confirm.cpp create mode 100644 applications/ibutton/scene/ibutton_scene_retry_confirm.h create mode 100644 applications/lfrfid/scene/lfrfid_app_scene_exit_confirm.cpp create mode 100644 applications/lfrfid/scene/lfrfid_app_scene_exit_confirm.h rename applications/lfrfid/scene/{lfrfid_app_scene_readed_menu.cpp => lfrfid_app_scene_read_menu.cpp} (77%) rename applications/lfrfid/scene/{lfrfid_app_scene_readed_menu.h => lfrfid_app_scene_read_menu.h} (83%) create mode 100644 applications/lfrfid/scene/lfrfid_app_scene_retry_confirm.cpp create mode 100644 applications/lfrfid/scene/lfrfid_app_scene_retry_confirm.h diff --git a/applications/ibutton/ibutton_app.h b/applications/ibutton/ibutton_app.h index ddaadfcda0e..5b529a1e2c5 100644 --- a/applications/ibutton/ibutton_app.h +++ b/applications/ibutton/ibutton_app.h @@ -9,7 +9,9 @@ #include "scene/ibutton_scene_read_crc_error.h" #include "scene/ibutton_scene_read_not_key_error.h" #include "scene/ibutton_scene_read_success.h" -#include "scene/ibutton_scene_readed_key_menu.h" +#include "scene/ibutton_scene_retry_confirm.h" +#include "scene/ibutton_scene_exit_confirm.h" +#include "scene/ibutton_scene_read_key_menu.h" #include "scene/ibutton_scene_write.h" #include "scene/ibutton_scene_write_success.h" #include "scene/ibutton_scene_saved_key_menu.h" @@ -42,7 +44,9 @@ class iButtonApp { SceneReadNotKeyError, SceneReadCRCError, SceneReadSuccess, - SceneReadedKeyMenu, + SceneRetryConfirm, + SceneExitConfirm, + SceneReadKeyMenu, SceneWrite, SceneWriteSuccess, SceneEmulate, @@ -105,7 +109,9 @@ class iButtonApp { {Scene::SceneReadCRCError, new iButtonSceneReadCRCError()}, {Scene::SceneReadNotKeyError, new iButtonSceneReadNotKeyError()}, {Scene::SceneReadSuccess, new iButtonSceneReadSuccess()}, - {Scene::SceneReadedKeyMenu, new iButtonSceneReadedKeyMenu()}, + {Scene::SceneRetryConfirm, new iButtonSceneRetryConfirm()}, + {Scene::SceneExitConfirm, new iButtonSceneExitConfirm()}, + {Scene::SceneReadKeyMenu, new iButtonSceneReadKeyMenu()}, {Scene::SceneWrite, new iButtonSceneWrite()}, {Scene::SceneWriteSuccess, new iButtonSceneWriteSuccess()}, {Scene::SceneEmulate, new iButtonSceneEmulate()}, diff --git a/applications/ibutton/scene/ibutton_scene_delete_success.cpp b/applications/ibutton/scene/ibutton_scene_delete_success.cpp index b2241141a95..8c645a5f5e5 100644 --- a/applications/ibutton/scene/ibutton_scene_delete_success.cpp +++ b/applications/ibutton/scene/ibutton_scene_delete_success.cpp @@ -14,7 +14,7 @@ void iButtonSceneDeleteSuccess::on_enter(iButtonApp* app) { Popup* popup = view_manager->get_popup(); popup_set_icon(popup, 0, 2, &I_DolphinMafia_115x62); - popup_set_text(popup, "Deleted", 83, 19, AlignLeft, AlignBottom); + popup_set_header(popup, "Deleted", 83, 19, AlignLeft, AlignBottom); popup_set_callback(popup, popup_callback); popup_set_context(popup, app); diff --git a/applications/ibutton/scene/ibutton_scene_exit_confirm.cpp b/applications/ibutton/scene/ibutton_scene_exit_confirm.cpp new file mode 100644 index 00000000000..2c9fe94cb3f --- /dev/null +++ b/applications/ibutton/scene/ibutton_scene_exit_confirm.cpp @@ -0,0 +1,51 @@ +#include "ibutton_scene_exit_confirm.h" +#include "../ibutton_app.h" + +static void widget_callback(GuiButtonType result, InputType type, void* context) { + furi_assert(context); + iButtonApp* app = static_cast(context); + iButtonEvent event; + + if(type == InputTypeShort) { + event.type = iButtonEvent::Type::EventTypeWidgetButtonResult; + event.payload.widget_button_result = result; + app->get_view_manager()->send_event(&event); + } +} + +void iButtonSceneExitConfirm::on_enter(iButtonApp* app) { + iButtonAppViewManager* view_manager = app->get_view_manager(); + Widget* widget = view_manager->get_widget(); + + widget_add_button_element(widget, GuiButtonTypeLeft, "Exit", widget_callback, app); + widget_add_button_element(widget, GuiButtonTypeRight, "Stay", widget_callback, app); + widget_add_string_element( + widget, 64, 19, AlignCenter, AlignBottom, FontPrimary, "Exit to iButton menu"); + widget_add_string_element( + widget, 64, 29, AlignCenter, AlignBottom, FontSecondary, "All unsaved data will be lost"); + + view_manager->switch_to(iButtonAppViewManager::Type::iButtonAppViewWidget); +} + +bool iButtonSceneExitConfirm::on_event(iButtonApp* app, iButtonEvent* event) { + bool consumed = false; + + if(event->type == iButtonEvent::Type::EventTypeWidgetButtonResult) { + if(event->payload.widget_button_result == GuiButtonTypeLeft) { + app->search_and_switch_to_previous_scene({iButtonApp::Scene::SceneStart}); + } else if(event->payload.widget_button_result == GuiButtonTypeRight) { + app->switch_to_previous_scene(); + } + consumed = true; + } else if(event->type == iButtonEvent::Type::EventTypeBack) { + consumed = true; + } + + return consumed; +} + +void iButtonSceneExitConfirm::on_exit(iButtonApp* app) { + iButtonAppViewManager* view_manager = app->get_view_manager(); + Widget* widget = view_manager->get_widget(); + widget_reset(widget); +} diff --git a/applications/ibutton/scene/ibutton_scene_exit_confirm.h b/applications/ibutton/scene/ibutton_scene_exit_confirm.h new file mode 100644 index 00000000000..dc5981e13e9 --- /dev/null +++ b/applications/ibutton/scene/ibutton_scene_exit_confirm.h @@ -0,0 +1,9 @@ +#pragma once +#include "ibutton_scene_generic.h" + +class iButtonSceneExitConfirm : public iButtonScene { +public: + void on_enter(iButtonApp* app) final; + bool on_event(iButtonApp* app, iButtonEvent* event) final; + void on_exit(iButtonApp* app) final; +}; \ No newline at end of file diff --git a/applications/ibutton/scene/ibutton_scene_read.cpp b/applications/ibutton/scene/ibutton_scene_read.cpp index 1353ef96e26..8a2abe617fc 100644 --- a/applications/ibutton/scene/ibutton_scene_read.cpp +++ b/applications/ibutton/scene/ibutton_scene_read.cpp @@ -34,15 +34,22 @@ bool iButtonSceneRead::on_event(iButtonApp* app, iButtonEvent* event) { consumed = true; iButtonKey* key = app->get_key(); + bool success = false; if(ibutton_key_get_type(key) == iButtonKeyDS1990) { if(!ibutton_key_dallas_crc_is_valid(key)) { app->switch_to_next_scene(iButtonApp::Scene::SceneReadCRCError); } else if(!ibutton_key_dallas_is_1990_key(key)) { app->switch_to_next_scene(iButtonApp::Scene::SceneReadNotKeyError); } else { - app->switch_to_next_scene(iButtonApp::Scene::SceneReadSuccess); + success = true; } } else { + success = true; + } + if(success) { + app->notify_success(); + app->notify_green_on(); + DOLPHIN_DEED(DolphinDeedIbuttonReadSuccess); app->switch_to_next_scene(iButtonApp::Scene::SceneReadSuccess); } } else if(event->type == iButtonEvent::Type::EventTypeTick) { diff --git a/applications/ibutton/scene/ibutton_scene_read_crc_error.cpp b/applications/ibutton/scene/ibutton_scene_read_crc_error.cpp index 1371334b08d..213266cbb4e 100644 --- a/applications/ibutton/scene/ibutton_scene_read_crc_error.cpp +++ b/applications/ibutton/scene/ibutton_scene_read_crc_error.cpp @@ -47,7 +47,7 @@ bool iButtonSceneReadCRCError::on_event(iButtonApp* app, iButtonEvent* event) { if(event->type == iButtonEvent::Type::EventTypeDialogResult) { if(event->payload.dialog_result == DialogExResultRight) { - app->switch_to_next_scene(iButtonApp::Scene::SceneReadedKeyMenu); + app->switch_to_next_scene(iButtonApp::Scene::SceneReadKeyMenu); } else { app->switch_to_previous_scene(); } diff --git a/applications/ibutton/scene/ibutton_scene_readed_key_menu.cpp b/applications/ibutton/scene/ibutton_scene_read_key_menu.cpp similarity index 76% rename from applications/ibutton/scene/ibutton_scene_readed_key_menu.cpp rename to applications/ibutton/scene/ibutton_scene_read_key_menu.cpp index 02d540a24ba..b77572249fd 100644 --- a/applications/ibutton/scene/ibutton_scene_readed_key_menu.cpp +++ b/applications/ibutton/scene/ibutton_scene_read_key_menu.cpp @@ -1,11 +1,10 @@ -#include "ibutton_scene_readed_key_menu.h" +#include "ibutton_scene_read_key_menu.h" #include "../ibutton_app.h" typedef enum { SubmenuIndexWrite, SubmenuIndexEmulate, SubmenuIndexSave, - SubmenuIndexReadNewKey, } SubmenuIndex; static void submenu_callback(void* context, uint32_t index) { @@ -19,7 +18,7 @@ static void submenu_callback(void* context, uint32_t index) { app->get_view_manager()->send_event(&event); } -void iButtonSceneReadedKeyMenu::on_enter(iButtonApp* app) { +void iButtonSceneReadKeyMenu::on_enter(iButtonApp* app) { iButtonAppViewManager* view_manager = app->get_view_manager(); Submenu* submenu = view_manager->get_submenu(); @@ -28,13 +27,12 @@ void iButtonSceneReadedKeyMenu::on_enter(iButtonApp* app) { } submenu_add_item(submenu, "Save", SubmenuIndexSave, submenu_callback, app); submenu_add_item(submenu, "Emulate", SubmenuIndexEmulate, submenu_callback, app); - submenu_add_item(submenu, "Read new key", SubmenuIndexReadNewKey, submenu_callback, app); submenu_set_selected_item(submenu, submenu_item_selected); view_manager->switch_to(iButtonAppViewManager::Type::iButtonAppViewSubmenu); } -bool iButtonSceneReadedKeyMenu::on_event(iButtonApp* app, iButtonEvent* event) { +bool iButtonSceneReadKeyMenu::on_event(iButtonApp* app, iButtonEvent* event) { bool consumed = false; if(event->type == iButtonEvent::Type::EventTypeMenuSelected) { @@ -49,20 +47,17 @@ bool iButtonSceneReadedKeyMenu::on_event(iButtonApp* app, iButtonEvent* event) { case SubmenuIndexSave: app->switch_to_next_scene(iButtonApp::Scene::SceneSaveName); break; - case SubmenuIndexReadNewKey: - app->search_and_switch_to_previous_scene({iButtonApp::Scene::SceneRead}); - break; } consumed = true; } else if(event->type == iButtonEvent::Type::EventTypeBack) { - app->search_and_switch_to_previous_scene({iButtonApp::Scene::SceneStart}); + app->switch_to_previous_scene(); consumed = true; } return consumed; } -void iButtonSceneReadedKeyMenu::on_exit(iButtonApp* app) { +void iButtonSceneReadKeyMenu::on_exit(iButtonApp* app) { iButtonAppViewManager* view = app->get_view_manager(); Submenu* submenu = view->get_submenu(); diff --git a/applications/ibutton/scene/ibutton_scene_readed_key_menu.h b/applications/ibutton/scene/ibutton_scene_read_key_menu.h similarity index 81% rename from applications/ibutton/scene/ibutton_scene_readed_key_menu.h rename to applications/ibutton/scene/ibutton_scene_read_key_menu.h index caa9ad43129..e85ad815d4d 100644 --- a/applications/ibutton/scene/ibutton_scene_readed_key_menu.h +++ b/applications/ibutton/scene/ibutton_scene_read_key_menu.h @@ -1,7 +1,7 @@ #pragma once #include "ibutton_scene_generic.h" -class iButtonSceneReadedKeyMenu : public iButtonScene { +class iButtonSceneReadKeyMenu : public iButtonScene { public: void on_enter(iButtonApp* app) final; bool on_event(iButtonApp* app, iButtonEvent* event) final; diff --git a/applications/ibutton/scene/ibutton_scene_read_not_key_error.cpp b/applications/ibutton/scene/ibutton_scene_read_not_key_error.cpp index b88f4655db9..7d0a235f1dd 100644 --- a/applications/ibutton/scene/ibutton_scene_read_not_key_error.cpp +++ b/applications/ibutton/scene/ibutton_scene_read_not_key_error.cpp @@ -47,7 +47,7 @@ bool iButtonSceneReadNotKeyError::on_event(iButtonApp* app, iButtonEvent* event) if(event->type == iButtonEvent::Type::EventTypeDialogResult) { if(event->payload.dialog_result == DialogExResultRight) { - app->switch_to_next_scene(iButtonApp::Scene::SceneReadedKeyMenu); + app->switch_to_next_scene(iButtonApp::Scene::SceneReadKeyMenu); } else { app->switch_to_previous_scene(); } diff --git a/applications/ibutton/scene/ibutton_scene_read_success.cpp b/applications/ibutton/scene/ibutton_scene_read_success.cpp index 6eb95721a5e..edf7d914e12 100644 --- a/applications/ibutton/scene/ibutton_scene_read_success.cpp +++ b/applications/ibutton/scene/ibutton_scene_read_success.cpp @@ -18,7 +18,6 @@ void iButtonSceneReadSuccess::on_enter(iButtonApp* app) { DialogEx* dialog_ex = view_manager->get_dialog_ex(); iButtonKey* key = app->get_key(); const uint8_t* key_data = ibutton_key_get_data_p(key); - DOLPHIN_DEED(DolphinDeedIbuttonReadSuccess); switch(ibutton_key_get_type(key)) { case iButtonKeyDS1990: @@ -50,9 +49,6 @@ void iButtonSceneReadSuccess::on_enter(iButtonApp* app) { dialog_ex_set_context(dialog_ex, app); view_manager->switch_to(iButtonAppViewManager::Type::iButtonAppViewDialogEx); - - app->notify_success(); - app->notify_green_on(); } bool iButtonSceneReadSuccess::on_event(iButtonApp* app, iButtonEvent* event) { @@ -60,11 +56,13 @@ bool iButtonSceneReadSuccess::on_event(iButtonApp* app, iButtonEvent* event) { if(event->type == iButtonEvent::Type::EventTypeDialogResult) { if(event->payload.dialog_result == DialogExResultRight) { - app->switch_to_next_scene(iButtonApp::Scene::SceneReadedKeyMenu); + app->switch_to_next_scene(iButtonApp::Scene::SceneReadKeyMenu); } else { - app->switch_to_previous_scene(); + app->switch_to_next_scene(iButtonApp::Scene::SceneRetryConfirm); } - + consumed = true; + } else if(event->type == iButtonEvent::Type::EventTypeBack) { + app->switch_to_next_scene(iButtonApp::Scene::SceneExitConfirm); consumed = true; } diff --git a/applications/ibutton/scene/ibutton_scene_retry_confirm.cpp b/applications/ibutton/scene/ibutton_scene_retry_confirm.cpp new file mode 100644 index 00000000000..aa3483b3d39 --- /dev/null +++ b/applications/ibutton/scene/ibutton_scene_retry_confirm.cpp @@ -0,0 +1,51 @@ +#include "ibutton_scene_retry_confirm.h" +#include "../ibutton_app.h" + +static void widget_callback(GuiButtonType result, InputType type, void* context) { + furi_assert(context); + iButtonApp* app = static_cast(context); + iButtonEvent event; + + if(type == InputTypeShort) { + event.type = iButtonEvent::Type::EventTypeWidgetButtonResult; + event.payload.widget_button_result = result; + app->get_view_manager()->send_event(&event); + } +} + +void iButtonSceneRetryConfirm::on_enter(iButtonApp* app) { + iButtonAppViewManager* view_manager = app->get_view_manager(); + Widget* widget = view_manager->get_widget(); + + widget_add_button_element(widget, GuiButtonTypeLeft, "Exit", widget_callback, app); + widget_add_button_element(widget, GuiButtonTypeRight, "Stay", widget_callback, app); + widget_add_string_element( + widget, 64, 19, AlignCenter, AlignBottom, FontPrimary, "Return to reading?"); + widget_add_string_element( + widget, 64, 29, AlignCenter, AlignBottom, FontSecondary, "All unsaved data will be lost"); + + view_manager->switch_to(iButtonAppViewManager::Type::iButtonAppViewWidget); +} + +bool iButtonSceneRetryConfirm::on_event(iButtonApp* app, iButtonEvent* event) { + bool consumed = false; + + if(event->type == iButtonEvent::Type::EventTypeWidgetButtonResult) { + if(event->payload.widget_button_result == GuiButtonTypeLeft) { + app->search_and_switch_to_previous_scene({iButtonApp::Scene::SceneRead}); + } else if(event->payload.widget_button_result == GuiButtonTypeRight) { + app->switch_to_previous_scene(); + } + consumed = true; + } else if(event->type == iButtonEvent::Type::EventTypeBack) { + consumed = true; + } + + return consumed; +} + +void iButtonSceneRetryConfirm::on_exit(iButtonApp* app) { + iButtonAppViewManager* view_manager = app->get_view_manager(); + Widget* widget = view_manager->get_widget(); + widget_reset(widget); +} diff --git a/applications/ibutton/scene/ibutton_scene_retry_confirm.h b/applications/ibutton/scene/ibutton_scene_retry_confirm.h new file mode 100644 index 00000000000..2f96e13f1ee --- /dev/null +++ b/applications/ibutton/scene/ibutton_scene_retry_confirm.h @@ -0,0 +1,9 @@ +#pragma once +#include "ibutton_scene_generic.h" + +class iButtonSceneRetryConfirm : public iButtonScene { +public: + void on_enter(iButtonApp* app) final; + bool on_event(iButtonApp* app, iButtonEvent* event) final; + void on_exit(iButtonApp* app) final; +}; \ No newline at end of file diff --git a/applications/ibutton/scene/ibutton_scene_save_name.cpp b/applications/ibutton/scene/ibutton_scene_save_name.cpp index 9a7ab846091..71eee148bdd 100644 --- a/applications/ibutton/scene/ibutton_scene_save_name.cpp +++ b/applications/ibutton/scene/ibutton_scene_save_name.cpp @@ -49,7 +49,7 @@ bool iButtonSceneSaveName::on_event(iButtonApp* app, iButtonEvent* event) { app->switch_to_next_scene(iButtonApp::Scene::SceneSaveSuccess); } else { app->search_and_switch_to_previous_scene( - {iButtonApp::Scene::SceneReadedKeyMenu, + {iButtonApp::Scene::SceneReadKeyMenu, iButtonApp::Scene::SceneSavedKeyMenu, iButtonApp::Scene::SceneAddType}); } diff --git a/applications/ibutton/scene/ibutton_scene_save_success.cpp b/applications/ibutton/scene/ibutton_scene_save_success.cpp index 0a1fc153a2f..13e173d2d9c 100644 --- a/applications/ibutton/scene/ibutton_scene_save_success.cpp +++ b/applications/ibutton/scene/ibutton_scene_save_success.cpp @@ -16,7 +16,7 @@ void iButtonSceneSaveSuccess::on_enter(iButtonApp* app) { DOLPHIN_DEED(DolphinDeedIbuttonSave); popup_set_icon(popup, 32, 5, &I_DolphinNice_96x59); - popup_set_text(popup, "Saved!", 13, 22, AlignLeft, AlignBottom); + popup_set_header(popup, "Saved!", 5, 7, AlignLeft, AlignTop); popup_set_callback(popup, popup_callback); popup_set_context(popup, app); @@ -31,7 +31,7 @@ bool iButtonSceneSaveSuccess::on_event(iButtonApp* app, iButtonEvent* event) { if(event->type == iButtonEvent::Type::EventTypeBack) { app->search_and_switch_to_previous_scene( - {iButtonApp::Scene::SceneReadedKeyMenu, + {iButtonApp::Scene::SceneReadKeyMenu, iButtonApp::Scene::SceneSavedKeyMenu, iButtonApp::Scene::SceneAddType}); consumed = true; diff --git a/applications/ibutton/scene/ibutton_scene_write_success.cpp b/applications/ibutton/scene/ibutton_scene_write_success.cpp index dbeb595d0ca..397347046ec 100644 --- a/applications/ibutton/scene/ibutton_scene_write_success.cpp +++ b/applications/ibutton/scene/ibutton_scene_write_success.cpp @@ -33,7 +33,7 @@ bool iButtonSceneWriteSuccess::on_event(iButtonApp* app, iButtonEvent* event) { if(event->type == iButtonEvent::Type::EventTypeBack) { app->search_and_switch_to_previous_scene( - {iButtonApp::Scene::SceneReadedKeyMenu, iButtonApp::Scene::SceneStart}); + {iButtonApp::Scene::SceneReadKeyMenu, iButtonApp::Scene::SceneStart}); consumed = true; } diff --git a/applications/infrared/scene/infrared_app_scene_edit_rename_done.cpp b/applications/infrared/scene/infrared_app_scene_edit_rename_done.cpp index 47ef343b5ec..2b6afafd675 100644 --- a/applications/infrared/scene/infrared_app_scene_edit_rename_done.cpp +++ b/applications/infrared/scene/infrared_app_scene_edit_rename_done.cpp @@ -5,7 +5,6 @@ void InfraredAppSceneEditRenameDone::on_enter(InfraredApp* app) { Popup* popup = view_manager->get_popup(); popup_set_icon(popup, 32, 5, &I_DolphinNice_96x59); - popup_set_header(popup, "Saved!", 5, 7, AlignLeft, AlignTop); popup_set_callback(popup, InfraredApp::popup_callback); diff --git a/applications/lfrfid/helpers/decoder_emmarin.cpp b/applications/lfrfid/helpers/decoder_emmarin.cpp index d80fc1d590e..daa8e238c23 100644 --- a/applications/lfrfid/helpers/decoder_emmarin.cpp +++ b/applications/lfrfid/helpers/decoder_emmarin.cpp @@ -15,7 +15,7 @@ constexpr uint32_t long_time_high = long_time + jitter_time; void DecoderEMMarin::reset_state() { ready = false; - readed_data = 0; + read_data = 0; manchester_advance( manchester_saved_state, ManchesterEventReset, &manchester_saved_state, nullptr); } @@ -26,7 +26,7 @@ bool DecoderEMMarin::read(uint8_t* data, uint8_t data_size) { if(ready) { result = true; em_marin.decode( - reinterpret_cast(&readed_data), sizeof(uint64_t), data, data_size); + reinterpret_cast(&read_data), sizeof(uint64_t), data, data_size); ready = false; } @@ -59,10 +59,10 @@ void DecoderEMMarin::process_front(bool polarity, uint32_t time) { manchester_advance(manchester_saved_state, event, &manchester_saved_state, &data); if(data_ok) { - readed_data = (readed_data << 1) | data; + read_data = (read_data << 1) | data; ready = em_marin.can_be_decoded( - reinterpret_cast(&readed_data), sizeof(uint64_t)); + reinterpret_cast(&read_data), sizeof(uint64_t)); } } } diff --git a/applications/lfrfid/helpers/decoder_emmarin.h b/applications/lfrfid/helpers/decoder_emmarin.h index c2bd64e3341..a3b48d71ce1 100644 --- a/applications/lfrfid/helpers/decoder_emmarin.h +++ b/applications/lfrfid/helpers/decoder_emmarin.h @@ -13,7 +13,7 @@ class DecoderEMMarin { private: void reset_state(); - uint64_t readed_data = 0; + uint64_t read_data = 0; std::atomic ready; ManchesterState manchester_saved_state; diff --git a/applications/lfrfid/helpers/rfid_reader.cpp b/applications/lfrfid/helpers/rfid_reader.cpp index e9be694eec4..1a6ed5f70a1 100644 --- a/applications/lfrfid/helpers/rfid_reader.cpp +++ b/applications/lfrfid/helpers/rfid_reader.cpp @@ -78,7 +78,7 @@ void RfidReader::start() { start_comparator(); switch_timer_reset(); - last_readed_count = 0; + last_read_count = 0; } void RfidReader::start_forced(RfidReader::Type _type) { @@ -97,45 +97,45 @@ void RfidReader::stop() { bool RfidReader::read(LfrfidKeyType* _type, uint8_t* data, uint8_t data_size, bool switch_enable) { bool result = false; - bool something_readed = false; + bool something_read = false; // reading if(decoder_em.read(data, data_size)) { *_type = LfrfidKeyType::KeyEM4100; - something_readed = true; + something_read = true; } if(decoder_hid26.read(data, data_size)) { *_type = LfrfidKeyType::KeyH10301; - something_readed = true; + something_read = true; } if(decoder_indala.read(data, data_size)) { *_type = LfrfidKeyType::KeyI40134; - something_readed = true; + something_read = true; } // validation - if(something_readed) { + if(something_read) { switch_timer_reset(); - if(last_readed_type == *_type && memcmp(last_readed_data, data, data_size) == 0) { - last_readed_count = last_readed_count + 1; + if(last_read_type == *_type && memcmp(last_read_data, data, data_size) == 0) { + last_read_count = last_read_count + 1; - if(last_readed_count > 2) { + if(last_read_count > 2) { result = true; } } else { - last_readed_type = *_type; - memcpy(last_readed_data, data, data_size); - last_readed_count = 0; + last_read_type = *_type; + memcpy(last_read_data, data, data_size); + last_read_count = 0; } } // mode switching if(switch_enable && switch_timer_elapsed()) { switch_mode(); - last_readed_count = 0; + last_read_count = 0; } return result; @@ -152,7 +152,7 @@ bool RfidReader::detect() { } bool RfidReader::any_read() { - return last_readed_count > 0; + return last_read_count > 0; } void RfidReader::start_comparator(void) { diff --git a/applications/lfrfid/helpers/rfid_reader.h b/applications/lfrfid/helpers/rfid_reader.h index 9ed6e589769..b3a93b89cfe 100644 --- a/applications/lfrfid/helpers/rfid_reader.h +++ b/applications/lfrfid/helpers/rfid_reader.h @@ -49,9 +49,9 @@ class RfidReader { void switch_timer_reset(); void switch_mode(); - LfrfidKeyType last_readed_type; - uint8_t last_readed_data[LFRFID_KEY_SIZE]; - uint8_t last_readed_count; + LfrfidKeyType last_read_type; + uint8_t last_read_data[LFRFID_KEY_SIZE]; + uint8_t last_read_count; Type type = Type::Normal; }; diff --git a/applications/lfrfid/lfrfid_app.cpp b/applications/lfrfid/lfrfid_app.cpp index fecf15a7e1d..4653eb2d5c2 100644 --- a/applications/lfrfid/lfrfid_app.cpp +++ b/applications/lfrfid/lfrfid_app.cpp @@ -2,7 +2,9 @@ #include "scene/lfrfid_app_scene_start.h" #include "scene/lfrfid_app_scene_read.h" #include "scene/lfrfid_app_scene_read_success.h" -#include "scene/lfrfid_app_scene_readed_menu.h" +#include "scene/lfrfid_app_scene_retry_confirm.h" +#include "scene/lfrfid_app_scene_exit_confirm.h" +#include "scene/lfrfid_app_scene_read_menu.h" #include "scene/lfrfid_app_scene_write.h" #include "scene/lfrfid_app_scene_write_success.h" #include "scene/lfrfid_app_scene_emulate.h" @@ -48,8 +50,10 @@ void LfRfidApp::run(void* _args) { } else { scene_controller.add_scene(SceneType::Start, new LfRfidAppSceneStart()); scene_controller.add_scene(SceneType::Read, new LfRfidAppSceneRead()); + scene_controller.add_scene(SceneType::RetryConfirm, new LfRfidAppSceneRetryConfirm()); + scene_controller.add_scene(SceneType::ExitConfirm, new LfRfidAppSceneExitConfirm()); scene_controller.add_scene(SceneType::ReadSuccess, new LfRfidAppSceneReadSuccess()); - scene_controller.add_scene(SceneType::ReadedMenu, new LfRfidAppSceneReadedMenu()); + scene_controller.add_scene(SceneType::ReadKeyMenu, new LfRfidAppSceneReadKeyMenu()); scene_controller.add_scene(SceneType::Write, new LfRfidAppSceneWrite()); scene_controller.add_scene(SceneType::WriteSuccess, new LfRfidAppSceneWriteSuccess()); scene_controller.add_scene(SceneType::Emulate, new LfRfidAppSceneEmulate()); diff --git a/applications/lfrfid/lfrfid_app.h b/applications/lfrfid/lfrfid_app.h index a73fccea13a..dddfb753af7 100644 --- a/applications/lfrfid/lfrfid_app.h +++ b/applications/lfrfid/lfrfid_app.h @@ -27,13 +27,17 @@ class LfRfidApp { GENERIC_EVENT_ENUM_VALUES, Next, MenuSelected, + Stay, + Retry, }; enum class SceneType : uint8_t { GENERIC_SCENE_ENUM_VALUES, Read, ReadSuccess, - ReadedMenu, + RetryConfirm, + ExitConfirm, + ReadKeyMenu, Write, WriteSuccess, Emulate, diff --git a/applications/lfrfid/scene/lfrfid_app_scene_delete_confirm.cpp b/applications/lfrfid/scene/lfrfid_app_scene_delete_confirm.cpp index 8f8fe9af052..5b7ac0f95ea 100644 --- a/applications/lfrfid/scene/lfrfid_app_scene_delete_confirm.cpp +++ b/applications/lfrfid/scene/lfrfid_app_scene_delete_confirm.cpp @@ -73,6 +73,11 @@ bool LfRfidAppSceneDeleteConfirm::on_event(LfRfidApp* app, LfRfidApp::Event* eve app->delete_key(&app->worker.key); app->scene_controller.switch_to_next_scene(LfRfidApp::SceneType::DeleteSuccess); consumed = true; + } else if(event->type == LfRfidApp::EventType::Stay) { + app->scene_controller.switch_to_previous_scene(); + consumed = true; + } else if(event->type == LfRfidApp::EventType::Back) { + consumed = true; } return consumed; @@ -88,7 +93,7 @@ void LfRfidAppSceneDeleteConfirm::on_exit(LfRfidApp* app) { void LfRfidAppSceneDeleteConfirm::back_callback(void* context) { LfRfidApp* app = static_cast(context); LfRfidApp::Event event; - event.type = LfRfidApp::EventType::Back; + event.type = LfRfidApp::EventType::Stay; app->view_controller.send_event(&event); } diff --git a/applications/lfrfid/scene/lfrfid_app_scene_delete_success.cpp b/applications/lfrfid/scene/lfrfid_app_scene_delete_success.cpp index cb0d6eb79f4..a4f2bf38dc2 100644 --- a/applications/lfrfid/scene/lfrfid_app_scene_delete_success.cpp +++ b/applications/lfrfid/scene/lfrfid_app_scene_delete_success.cpp @@ -4,7 +4,7 @@ void LfRfidAppSceneDeleteSuccess::on_enter(LfRfidApp* app, bool need_restore) { auto popup = app->view_controller.get(); popup->set_icon(0, 2, &I_DolphinMafia_115x62); - popup->set_text("Deleted", 83, 19, AlignLeft, AlignBottom); + popup->set_header("Deleted", 83, 19, AlignLeft, AlignBottom); popup->set_context(app); popup->set_callback(LfRfidAppSceneDeleteSuccess::timeout_callback); popup->set_timeout(1500); diff --git a/applications/lfrfid/scene/lfrfid_app_scene_exit_confirm.cpp b/applications/lfrfid/scene/lfrfid_app_scene_exit_confirm.cpp new file mode 100644 index 00000000000..262dfca1cb3 --- /dev/null +++ b/applications/lfrfid/scene/lfrfid_app_scene_exit_confirm.cpp @@ -0,0 +1,59 @@ +#include "lfrfid_app_scene_exit_confirm.h" +#include "../view/elements/button_element.h" +#include "../view/elements/icon_element.h" +#include "../view/elements/string_element.h" + +void LfRfidAppSceneExitConfirm::on_enter(LfRfidApp* app, bool need_restore) { + auto container = app->view_controller.get(); + + auto button = container->add(); + button->set_type(ButtonElement::Type::Left, "Exit"); + button->set_callback(app, LfRfidAppSceneExitConfirm::exit_callback); + + button = container->add(); + button->set_type(ButtonElement::Type::Right, "Stay"); + button->set_callback(app, LfRfidAppSceneExitConfirm::stay_callback); + + auto line_1 = container->add(); + auto line_2 = container->add(); + + line_1->set_text("Exit to RFID menu?", 64, 19, 128 - 2, AlignCenter, AlignBottom, FontPrimary); + line_2->set_text( + "All unsaved data will be lost", 64, 29, 0, AlignCenter, AlignBottom, FontSecondary); + + app->view_controller.switch_to(); +} + +bool LfRfidAppSceneExitConfirm::on_event(LfRfidApp* app, LfRfidApp::Event* event) { + bool consumed = false; + + if(event->type == LfRfidApp::EventType::Next) { + app->scene_controller.search_and_switch_to_previous_scene({LfRfidApp::SceneType::Start}); + consumed = true; + } else if(event->type == LfRfidApp::EventType::Stay) { + app->scene_controller.switch_to_previous_scene(); + consumed = true; + } else if(event->type == LfRfidApp::EventType::Back) { + consumed = true; + } + + return consumed; +} + +void LfRfidAppSceneExitConfirm::on_exit(LfRfidApp* app) { + app->view_controller.get()->clean(); +} + +void LfRfidAppSceneExitConfirm::exit_callback(void* context) { + LfRfidApp* app = static_cast(context); + LfRfidApp::Event event; + event.type = LfRfidApp::EventType::Next; + app->view_controller.send_event(&event); +} + +void LfRfidAppSceneExitConfirm::stay_callback(void* context) { + LfRfidApp* app = static_cast(context); + LfRfidApp::Event event; + event.type = LfRfidApp::EventType::Stay; + app->view_controller.send_event(&event); +} diff --git a/applications/lfrfid/scene/lfrfid_app_scene_exit_confirm.h b/applications/lfrfid/scene/lfrfid_app_scene_exit_confirm.h new file mode 100644 index 00000000000..4f960d22f89 --- /dev/null +++ b/applications/lfrfid/scene/lfrfid_app_scene_exit_confirm.h @@ -0,0 +1,13 @@ +#pragma once +#include "../lfrfid_app.h" + +class LfRfidAppSceneExitConfirm : public GenericScene { +public: + void on_enter(LfRfidApp* app, bool need_restore) final; + bool on_event(LfRfidApp* app, LfRfidApp::Event* event) final; + void on_exit(LfRfidApp* app) final; + +private: + static void exit_callback(void* context); + static void stay_callback(void* context); +}; \ No newline at end of file diff --git a/applications/lfrfid/scene/lfrfid_app_scene_readed_menu.cpp b/applications/lfrfid/scene/lfrfid_app_scene_read_menu.cpp similarity index 77% rename from applications/lfrfid/scene/lfrfid_app_scene_readed_menu.cpp rename to applications/lfrfid/scene/lfrfid_app_scene_read_menu.cpp index 9b0a6d8a16e..ce0461f9220 100644 --- a/applications/lfrfid/scene/lfrfid_app_scene_readed_menu.cpp +++ b/applications/lfrfid/scene/lfrfid_app_scene_read_menu.cpp @@ -1,4 +1,4 @@ -#include "lfrfid_app_scene_readed_menu.h" +#include "lfrfid_app_scene_read_menu.h" typedef enum { SubmenuWrite, @@ -6,7 +6,7 @@ typedef enum { SubmenuEmulate, } SubmenuIndex; -void LfRfidAppSceneReadedMenu::on_enter(LfRfidApp* app, bool need_restore) { +void LfRfidAppSceneReadKeyMenu::on_enter(LfRfidApp* app, bool need_restore) { auto submenu = app->view_controller.get(); submenu->add_item("Write", SubmenuWrite, submenu_callback, app); @@ -20,7 +20,7 @@ void LfRfidAppSceneReadedMenu::on_enter(LfRfidApp* app, bool need_restore) { app->view_controller.switch_to(); } -bool LfRfidAppSceneReadedMenu::on_event(LfRfidApp* app, LfRfidApp::Event* event) { +bool LfRfidAppSceneReadKeyMenu::on_event(LfRfidApp* app, LfRfidApp::Event* event) { bool consumed = false; if(event->type == LfRfidApp::EventType::MenuSelected) { @@ -38,18 +38,18 @@ bool LfRfidAppSceneReadedMenu::on_event(LfRfidApp* app, LfRfidApp::Event* event) } consumed = true; } else if(event->type == LfRfidApp::EventType::Back) { - app->scene_controller.search_and_switch_to_previous_scene({LfRfidApp::SceneType::Start}); + app->scene_controller.switch_to_previous_scene(); consumed = true; } return consumed; } -void LfRfidAppSceneReadedMenu::on_exit(LfRfidApp* app) { +void LfRfidAppSceneReadKeyMenu::on_exit(LfRfidApp* app) { app->view_controller.get()->clean(); } -void LfRfidAppSceneReadedMenu::submenu_callback(void* context, uint32_t index) { +void LfRfidAppSceneReadKeyMenu::submenu_callback(void* context, uint32_t index) { LfRfidApp* app = static_cast(context); LfRfidApp::Event event; diff --git a/applications/lfrfid/scene/lfrfid_app_scene_readed_menu.h b/applications/lfrfid/scene/lfrfid_app_scene_read_menu.h similarity index 83% rename from applications/lfrfid/scene/lfrfid_app_scene_readed_menu.h rename to applications/lfrfid/scene/lfrfid_app_scene_read_menu.h index 7a91aa95200..43d68a81ab7 100644 --- a/applications/lfrfid/scene/lfrfid_app_scene_readed_menu.h +++ b/applications/lfrfid/scene/lfrfid_app_scene_read_menu.h @@ -1,7 +1,7 @@ #pragma once #include "../lfrfid_app.h" -class LfRfidAppSceneReadedMenu : public GenericScene { +class LfRfidAppSceneReadKeyMenu : public GenericScene { public: void on_enter(LfRfidApp* app, bool need_restore) final; bool on_event(LfRfidApp* app, LfRfidApp::Event* event) final; diff --git a/applications/lfrfid/scene/lfrfid_app_scene_read_success.cpp b/applications/lfrfid/scene/lfrfid_app_scene_read_success.cpp index a86f77e61f7..8f6a0b57ee3 100644 --- a/applications/lfrfid/scene/lfrfid_app_scene_read_success.cpp +++ b/applications/lfrfid/scene/lfrfid_app_scene_read_success.cpp @@ -85,7 +85,13 @@ bool LfRfidAppSceneReadSuccess::on_event(LfRfidApp* app, LfRfidApp::Event* event bool consumed = false; if(event->type == LfRfidApp::EventType::Next) { - app->scene_controller.switch_to_next_scene(LfRfidApp::SceneType::ReadedMenu); + app->scene_controller.switch_to_next_scene(LfRfidApp::SceneType::ReadKeyMenu); + consumed = true; + } else if(event->type == LfRfidApp::EventType::Retry) { + app->scene_controller.switch_to_next_scene({LfRfidApp::SceneType::RetryConfirm}); + consumed = true; + } else if(event->type == LfRfidApp::EventType::Back) { + app->scene_controller.switch_to_next_scene({LfRfidApp::SceneType::ExitConfirm}); consumed = true; } @@ -103,7 +109,7 @@ void LfRfidAppSceneReadSuccess::on_exit(LfRfidApp* app) { void LfRfidAppSceneReadSuccess::back_callback(void* context) { LfRfidApp* app = static_cast(context); LfRfidApp::Event event; - event.type = LfRfidApp::EventType::Back; + event.type = LfRfidApp::EventType::Retry; app->view_controller.send_event(&event); } diff --git a/applications/lfrfid/scene/lfrfid_app_scene_retry_confirm.cpp b/applications/lfrfid/scene/lfrfid_app_scene_retry_confirm.cpp new file mode 100644 index 00000000000..092a5f02008 --- /dev/null +++ b/applications/lfrfid/scene/lfrfid_app_scene_retry_confirm.cpp @@ -0,0 +1,59 @@ +#include "lfrfid_app_scene_retry_confirm.h" +#include "../view/elements/button_element.h" +#include "../view/elements/icon_element.h" +#include "../view/elements/string_element.h" + +void LfRfidAppSceneRetryConfirm::on_enter(LfRfidApp* app, bool need_restore) { + auto container = app->view_controller.get(); + + auto button = container->add(); + button->set_type(ButtonElement::Type::Left, "Exit"); + button->set_callback(app, LfRfidAppSceneRetryConfirm::exit_callback); + + button = container->add(); + button->set_type(ButtonElement::Type::Right, "Stay"); + button->set_callback(app, LfRfidAppSceneRetryConfirm::stay_callback); + + auto line_1 = container->add(); + auto line_2 = container->add(); + + line_1->set_text("Return to reading?", 64, 19, 128 - 2, AlignCenter, AlignBottom, FontPrimary); + line_2->set_text( + "All unsaved data will be lost", 64, 29, 0, AlignCenter, AlignBottom, FontSecondary); + + app->view_controller.switch_to(); +} + +bool LfRfidAppSceneRetryConfirm::on_event(LfRfidApp* app, LfRfidApp::Event* event) { + bool consumed = false; + + if(event->type == LfRfidApp::EventType::Next) { + app->scene_controller.search_and_switch_to_previous_scene({LfRfidApp::SceneType::Read}); + consumed = true; + } else if(event->type == LfRfidApp::EventType::Stay) { + app->scene_controller.switch_to_previous_scene(); + consumed = true; + } else if(event->type == LfRfidApp::EventType::Back) { + consumed = true; + } + + return consumed; +} + +void LfRfidAppSceneRetryConfirm::on_exit(LfRfidApp* app) { + app->view_controller.get()->clean(); +} + +void LfRfidAppSceneRetryConfirm::exit_callback(void* context) { + LfRfidApp* app = static_cast(context); + LfRfidApp::Event event; + event.type = LfRfidApp::EventType::Next; + app->view_controller.send_event(&event); +} + +void LfRfidAppSceneRetryConfirm::stay_callback(void* context) { + LfRfidApp* app = static_cast(context); + LfRfidApp::Event event; + event.type = LfRfidApp::EventType::Stay; + app->view_controller.send_event(&event); +} diff --git a/applications/lfrfid/scene/lfrfid_app_scene_retry_confirm.h b/applications/lfrfid/scene/lfrfid_app_scene_retry_confirm.h new file mode 100644 index 00000000000..af2373f0356 --- /dev/null +++ b/applications/lfrfid/scene/lfrfid_app_scene_retry_confirm.h @@ -0,0 +1,13 @@ +#pragma once +#include "../lfrfid_app.h" + +class LfRfidAppSceneRetryConfirm : public GenericScene { +public: + void on_enter(LfRfidApp* app, bool need_restore) final; + bool on_event(LfRfidApp* app, LfRfidApp::Event* event) final; + void on_exit(LfRfidApp* app) final; + +private: + static void exit_callback(void* context); + static void stay_callback(void* context); +}; \ No newline at end of file diff --git a/applications/lfrfid/scene/lfrfid_app_scene_save_name.cpp b/applications/lfrfid/scene/lfrfid_app_scene_save_name.cpp index c2ad5dd19b3..f755f0e3278 100644 --- a/applications/lfrfid/scene/lfrfid_app_scene_save_name.cpp +++ b/applications/lfrfid/scene/lfrfid_app_scene_save_name.cpp @@ -42,7 +42,7 @@ bool LfRfidAppSceneSaveName::on_event(LfRfidApp* app, LfRfidApp::Event* event) { app->scene_controller.switch_to_next_scene(LfRfidApp::SceneType::SaveSuccess); } else { app->scene_controller.search_and_switch_to_previous_scene( - {LfRfidApp::SceneType::ReadedMenu}); + {LfRfidApp::SceneType::ReadKeyMenu}); } } diff --git a/applications/lfrfid/scene/lfrfid_app_scene_save_success.cpp b/applications/lfrfid/scene/lfrfid_app_scene_save_success.cpp index 3a37da86b5b..184a445ad5d 100644 --- a/applications/lfrfid/scene/lfrfid_app_scene_save_success.cpp +++ b/applications/lfrfid/scene/lfrfid_app_scene_save_success.cpp @@ -8,7 +8,7 @@ void LfRfidAppSceneSaveSuccess::on_enter(LfRfidApp* app, bool need_restore) { DOLPHIN_DEED(DolphinDeedRfidSave); popup->set_icon(32, 5, &I_DolphinNice_96x59); - popup->set_text("Saved!", 13, 22, AlignLeft, AlignBottom); + popup->set_header("Saved!", 5, 7, AlignLeft, AlignTop); popup->set_context(app); popup->set_callback(LfRfidAppSceneSaveSuccess::timeout_callback); popup->set_timeout(1500); @@ -22,11 +22,11 @@ bool LfRfidAppSceneSaveSuccess::on_event(LfRfidApp* app, LfRfidApp::Event* event if(event->type == LfRfidApp::EventType::Back) { bool result = app->scene_controller.has_previous_scene( - {LfRfidApp::SceneType::ReadedMenu, LfRfidApp::SceneType::SelectKey}); + {LfRfidApp::SceneType::ReadKeyMenu, LfRfidApp::SceneType::SelectKey}); if(result) { app->scene_controller.search_and_switch_to_previous_scene( - {LfRfidApp::SceneType::ReadedMenu, LfRfidApp::SceneType::SelectKey}); + {LfRfidApp::SceneType::ReadKeyMenu, LfRfidApp::SceneType::SelectKey}); } else { app->scene_controller.search_and_switch_to_another_scene( {LfRfidApp::SceneType::SaveType}, LfRfidApp::SceneType::SelectKey); diff --git a/applications/lfrfid/scene/lfrfid_app_scene_write_success.cpp b/applications/lfrfid/scene/lfrfid_app_scene_write_success.cpp index 87c870e9d8d..0539e623504 100644 --- a/applications/lfrfid/scene/lfrfid_app_scene_write_success.cpp +++ b/applications/lfrfid/scene/lfrfid_app_scene_write_success.cpp @@ -18,7 +18,7 @@ bool LfRfidAppSceneWriteSuccess::on_event(LfRfidApp* app, LfRfidApp::Event* even if(event->type == LfRfidApp::EventType::Back) { app->scene_controller.search_and_switch_to_previous_scene( - {LfRfidApp::SceneType::ReadedMenu, LfRfidApp::SceneType::SelectKey}); + {LfRfidApp::SceneType::ReadKeyMenu, LfRfidApp::SceneType::SelectKey}); consumed = true; } diff --git a/applications/rpc/rpc_storage.c b/applications/rpc/rpc_storage.c index e9c13ca304b..97d9ab62f95 100644 --- a/applications/rpc/rpc_storage.c +++ b/applications/rpc/rpc_storage.c @@ -473,17 +473,17 @@ static void rpc_system_storage_md5sum_process(const PB_Main* request, void* cont File* file = storage_file_alloc(fs_api); if(storage_file_open(file, filename, FSAM_READ, FSOM_OPEN_EXISTING)) { - const uint16_t read_size = 512; + const uint16_t size_to_read = 512; const uint8_t hash_size = 16; - uint8_t* data = malloc(read_size); + uint8_t* data = malloc(size_to_read); uint8_t* hash = malloc(sizeof(uint8_t) * hash_size); md5_context* md5_ctx = malloc(sizeof(md5_context)); md5_starts(md5_ctx); while(true) { - uint16_t readed_size = storage_file_read(file, data, read_size); - if(readed_size == 0) break; - md5_update(md5_ctx, data, readed_size); + uint16_t read_size = storage_file_read(file, data, size_to_read); + if(read_size == 0) break; + md5_update(md5_ctx, data, read_size); } md5_finish(md5_ctx, hash); free(md5_ctx); diff --git a/applications/storage/filesystem_api_internal.h b/applications/storage/filesystem_api_internal.h index 29098e591b2..f0a3bb3fe61 100644 --- a/applications/storage/filesystem_api_internal.h +++ b/applications/storage/filesystem_api_internal.h @@ -33,14 +33,14 @@ struct File { * @param file pointer to file object * @param buff pointer to buffer for reading * @param bytes_to_read how many bytes to read, must be smaller or equal to buffer size - * @return how many bytes actually has been readed + * @return how many bytes actually has been read * * @var FS_File_Api::write * @brief Write bytes from buffer to file * @param file pointer to file object * @param buff pointer to buffer for writing * @param bytes_to_read how many bytes to write, must be smaller or equal to buffer size - * @return how many bytes actually has been writed + * @return how many bytes actually has been written * * @var FS_File_Api::seek * @brief Move r/w pointer @@ -107,7 +107,7 @@ typedef struct { * @var FS_Dir_Api::read * @brief Read next object info in directory * @param file pointer to file object - * @param fileinfo pointer to readed FileInfo, can be NULL + * @param fileinfo pointer to read FileInfo, can be NULL * @param name pointer to name buffer, can be NULL * @param name_length name buffer length * @return success flag (if next object not exist also returns false and set error_id to FSE_NOT_EXIST) @@ -133,7 +133,7 @@ typedef struct { * @var FS_Common_Api::stat * @brief Open directory to get objects from * @param path path to file/directory - * @param fileinfo pointer to readed FileInfo, can be NULL + * @param fileinfo pointer to read FileInfo, can be NULL * @param name pointer to name buffer, can be NULL * @param name_length name buffer length * @return FS_Error error info diff --git a/applications/storage/storage.h b/applications/storage/storage.h index bb71447b2d5..eb51adefa38 100644 --- a/applications/storage/storage.h +++ b/applications/storage/storage.h @@ -76,7 +76,7 @@ bool storage_file_is_dir(File* file); * @param file pointer to file object. * @param buff pointer to a buffer, for reading * @param bytes_to_read how many bytes to read. Must be less than or equal to the size of the buffer. - * @return uint16_t how many bytes were actually readed + * @return uint16_t how many bytes were actually read */ uint16_t storage_file_read(File* file, void* buff, uint16_t bytes_to_read); @@ -144,7 +144,7 @@ bool storage_dir_close(File* file); /** Reads the next object in the directory * @param file pointer to file object. - * @param fileinfo pointer to the readed FileInfo, may be NULL + * @param fileinfo pointer to the read FileInfo, may be NULL * @param name pointer to name buffer, may be NULL * @param name_length name buffer length * @return success flag (if the next object does not exist, it also returns false and sets the file error id to FSE_NOT_EXIST) @@ -162,7 +162,7 @@ bool storage_dir_rewind(File* file); /** Retrieves information about a file/directory * @param app pointer to the api * @param path path to file/directory - * @param fileinfo pointer to the readed FileInfo, may be NULL + * @param fileinfo pointer to the read FileInfo, may be NULL * @return FS_Error operation result */ FS_Error storage_common_stat(Storage* storage, const char* path, FileInfo* fileinfo); diff --git a/applications/storage/storage_cli.c b/applications/storage/storage_cli.c index 17bffa97a9c..3cb345bdf69 100644 --- a/applications/storage/storage_cli.c +++ b/applications/storage/storage_cli.c @@ -112,10 +112,10 @@ static void storage_cli_list(Cli* cli, string_t path) { if(storage_dir_open(file, string_get_cstr(path))) { FileInfo fileinfo; char name[MAX_NAME_LENGTH]; - bool readed = false; + bool read_done = false; while(storage_dir_read(file, &fileinfo, name, MAX_NAME_LENGTH)) { - readed = true; + read_done = true; if(fileinfo.flags & FSF_DIRECTORY) { printf("\t[D] %s\r\n", name); } else { @@ -123,7 +123,7 @@ static void storage_cli_list(Cli* cli, string_t path) { } } - if(!readed) { + if(!read_done) { printf("\tEmpty\r\n"); } } else { @@ -141,18 +141,18 @@ static void storage_cli_read(Cli* cli, string_t path) { File* file = storage_file_alloc(api); if(storage_file_open(file, string_get_cstr(path), FSAM_READ, FSOM_OPEN_EXISTING)) { - const uint16_t read_size = 128; - uint16_t readed_size = 0; + const uint16_t size_to_read = 128; + uint16_t read_size = 0; uint8_t* data = malloc(read_size); printf("Size: %lu\r\n", (uint32_t)storage_file_size(file)); do { - readed_size = storage_file_read(file, data, read_size); - for(uint16_t i = 0; i < readed_size; i++) { + read_size = storage_file_read(file, data, size_to_read); + for(uint16_t i = 0; i < read_size; i++) { printf("%c", data[i]); } - } while(readed_size > 0); + } while(read_size > 0); printf("\r\n"); free(data); @@ -176,33 +176,33 @@ static void storage_cli_write(Cli* cli, string_t path) { if(storage_file_open(file, string_get_cstr(path), FSAM_WRITE, FSOM_OPEN_APPEND)) { printf("Just write your text data. New line by Ctrl+Enter, exit by Ctrl+C.\r\n"); - uint32_t readed_index = 0; + uint32_t read_index = 0; while(true) { uint8_t symbol = cli_getc(cli); if(symbol == CliSymbolAsciiETX) { - uint16_t write_size = readed_index % buffer_size; + uint16_t write_size = read_index % buffer_size; if(write_size > 0) { - uint16_t writed_size = storage_file_write(file, buffer, write_size); + uint16_t written_size = storage_file_write(file, buffer, write_size); - if(writed_size != write_size) { + if(written_size != write_size) { storage_cli_print_error(storage_file_get_error(file)); } break; } } - buffer[readed_index % buffer_size] = symbol; - printf("%c", buffer[readed_index % buffer_size]); + buffer[read_index % buffer_size] = symbol; + printf("%c", buffer[read_index % buffer_size]); fflush(stdout); - readed_index++; + read_index++; - if(((readed_index % buffer_size) == 0)) { - uint16_t writed_size = storage_file_write(file, buffer, buffer_size); + if(((read_index % buffer_size) == 0)) { + uint16_t written_size = storage_file_write(file, buffer, buffer_size); - if(writed_size != buffer_size) { + if(written_size != buffer_size) { storage_cli_print_error(storage_file_get_error(file)); break; } @@ -239,11 +239,11 @@ static void storage_cli_read_chunks(Cli* cli, string_t path, string_t args) { printf("\r\nReady?\r\n"); cli_getc(cli); - uint16_t readed_size = storage_file_read(file, data, buffer_size); - for(uint16_t i = 0; i < readed_size; i++) { + uint16_t read_size = storage_file_read(file, data, buffer_size); + for(uint16_t i = 0; i < read_size; i++) { putchar(data[i]); } - file_size -= readed_size; + file_size -= read_size; } printf("\r\n"); @@ -277,9 +277,9 @@ static void storage_cli_write_chunk(Cli* cli, string_t path, string_t args) { buffer[i] = cli_getc(cli); } - uint16_t writed_size = storage_file_write(file, buffer, buffer_size); + uint16_t written_size = storage_file_write(file, buffer, buffer_size); - if(writed_size != buffer_size) { + if(written_size != buffer_size) { storage_cli_print_error(storage_file_get_error(file)); } @@ -400,17 +400,17 @@ static void storage_cli_md5(Cli* cli, string_t path) { File* file = storage_file_alloc(api); if(storage_file_open(file, string_get_cstr(path), FSAM_READ, FSOM_OPEN_EXISTING)) { - const uint16_t read_size = 512; + const uint16_t size_to_read = 512; const uint8_t hash_size = 16; - uint8_t* data = malloc(read_size); + uint8_t* data = malloc(size_to_read); uint8_t* hash = malloc(sizeof(uint8_t) * hash_size); md5_context* md5_ctx = malloc(sizeof(md5_context)); md5_starts(md5_ctx); while(true) { - uint16_t readed_size = storage_file_read(file, data, read_size); - if(readed_size == 0) break; - md5_update(md5_ctx, data, readed_size); + uint16_t read_size = storage_file_read(file, data, size_to_read); + if(read_size == 0) break; + md5_update(md5_ctx, data, read_size); } md5_finish(md5_ctx, hash); free(md5_ctx); diff --git a/applications/storage/storages/storage_ext.c b/applications/storage/storages/storage_ext.c index 4ef9a8eae97..bf201d5657c 100644 --- a/applications/storage/storages/storage_ext.c +++ b/applications/storage/storages/storage_ext.c @@ -340,10 +340,10 @@ static uint16_t storage_ext_file_read(void* ctx, File* file, void* buff, uint16_t const bytes_to_read) { StorageData* storage = ctx; SDFile* file_data = storage_get_storage_file_data(file, storage); - uint16_t bytes_readed = 0; - file->internal_error_id = f_read(file_data, buff, bytes_to_read, &bytes_readed); + uint16_t bytes_read = 0; + file->internal_error_id = f_read(file_data, buff, bytes_to_read, &bytes_read); file->error_id = storage_ext_parse_error(file->internal_error_id); - return bytes_readed; + return bytes_read; } static uint16_t diff --git a/applications/storage/storages/storage_int.c b/applications/storage/storages/storage_int.c index 2f610929355..7f7dd7705d1 100644 --- a/applications/storage/storages/storage_int.c +++ b/applications/storage/storages/storage_int.c @@ -349,7 +349,7 @@ static uint16_t lfs_t* lfs = lfs_get_from_storage(storage); LFSHandle* handle = storage_get_storage_file_data(file, storage); - uint16_t bytes_readed = 0; + uint16_t bytes_read = 0; if(lfs_handle_is_open(handle)) { file->internal_error_id = @@ -361,10 +361,10 @@ static uint16_t file->error_id = storage_int_parse_error(file->internal_error_id); if(file->error_id == FSE_OK) { - bytes_readed = file->internal_error_id; + bytes_read = file->internal_error_id; file->internal_error_id = 0; } - return bytes_readed; + return bytes_read; } static uint16_t diff --git a/lib/nfc_protocols/mifare_ultralight.c b/lib/nfc_protocols/mifare_ultralight.c index a2e64017c88..c9311124e6d 100644 --- a/lib/nfc_protocols/mifare_ultralight.c +++ b/lib/nfc_protocols/mifare_ultralight.c @@ -56,12 +56,12 @@ uint16_t mf_ul_prepare_read(uint8_t* dest, uint8_t start_page) { void mf_ul_parse_read_response(uint8_t* buff, uint16_t page_addr, MifareUlDevice* mf_ul_read) { uint8_t pages_read = 4; - uint8_t page_read_count = mf_ul_read->pages_readed + pages_read; + uint8_t page_read_count = mf_ul_read->pages_read + pages_read; if(page_read_count > mf_ul_read->pages_to_read) { pages_read -= page_read_count - mf_ul_read->pages_to_read; } - mf_ul_read->pages_readed += pages_read; - mf_ul_read->data.data_size = mf_ul_read->pages_readed * 4; + mf_ul_read->pages_read += pages_read; + mf_ul_read->data.data_size = mf_ul_read->pages_read * 4; memcpy(&mf_ul_read->data.data[page_addr * 4], buff, pages_read * 4); } @@ -77,8 +77,8 @@ void mf_ul_parse_fast_read_response( uint8_t start_page, uint8_t end_page, MifareUlDevice* mf_ul_read) { - mf_ul_read->pages_readed = end_page - start_page + 1; - mf_ul_read->data.data_size = mf_ul_read->pages_readed * 4; + mf_ul_read->pages_read = end_page - start_page + 1; + mf_ul_read->data.data_size = mf_ul_read->pages_read * 4; memcpy(mf_ul_read->data.data, buff, mf_ul_read->data.data_size); } diff --git a/lib/nfc_protocols/mifare_ultralight.h b/lib/nfc_protocols/mifare_ultralight.h index 06bab2223d1..84447c5decd 100644 --- a/lib/nfc_protocols/mifare_ultralight.h +++ b/lib/nfc_protocols/mifare_ultralight.h @@ -74,7 +74,7 @@ typedef struct { typedef struct { uint8_t pages_to_read; - uint8_t pages_readed; + uint8_t pages_read; bool support_fast_read; bool data_changed; MifareUlData data; diff --git a/lib/one_wire/ibutton/ibutton_writer.c b/lib/one_wire/ibutton/ibutton_writer.c index fc63e9516f5..fe19db71128 100644 --- a/lib/one_wire/ibutton/ibutton_writer.c +++ b/lib/one_wire/ibutton/ibutton_writer.c @@ -71,10 +71,10 @@ static bool writer_write_TM2004(iButtonWriter* writer, iButtonKey* key) { furi_hal_delay_us(600); writer_write_one_bit(writer, 1, 50000); - // read writed key byte + // read written key byte answer = onewire_host_read(writer->host); - // check that writed and readed are same + // check that written and read are same if(ibutton_key_get_data_p(key)[i] != answer) { result = false; break; diff --git a/scripts/flipper/storage.py b/scripts/flipper/storage.py index 53c01d8c8b2..0768ca9e112 100644 --- a/scripts/flipper/storage.py +++ b/scripts/flipper/storage.py @@ -232,18 +232,18 @@ def read_file(self, filename): self.read.until(self.CLI_PROMPT) return filedata size = int(answer.split(b": ")[1]) - readed_size = 0 + read_size = 0 - while readed_size < size: + while read_size < size: self.read.until("Ready?" + self.CLI_EOL) self.send("y") - read_size = min(size - readed_size, buffer_size) + read_size = min(size - read_size, buffer_size) filedata.extend(self.port.read(read_size)) - readed_size = readed_size + read_size + read_size = read_size + read_size - percent = str(math.ceil(readed_size / size * 100)) + percent = str(math.ceil(read_size / size * 100)) total_chunks = str(math.ceil(size / buffer_size)) - current_chunk = str(math.ceil(readed_size / buffer_size)) + current_chunk = str(math.ceil(read_size / buffer_size)) sys.stdout.write(f"\r{percent}%, chunk {current_chunk} of {total_chunks}") sys.stdout.flush() print() From 917be9c6d3c9b85c40eb9b40f1060d1b3c43e45a Mon Sep 17 00:00:00 2001 From: Georgii Surkov <37121527+gsurkov@users.noreply.github.com> Date: Thu, 14 Apr 2022 15:20:41 +0300 Subject: [PATCH 08/20] [FL-2430] Automatic Desktop Locking (#1101) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add Auto Lock Time setting * Update .gitignore * Add value_index toolbox module * Auto locking basic implementation * Better AutoLock implementation, edge cases and cleanup * Fix NULL pointer crash * Turn off backlight shortly in locked mode * Re-enable auto lock after pin lock * Correctly handle start when pin locked * Use timer to hide locked hint * Use a single state variable instead of multiple bools * Do not call update callback recursively * Allow input when the Unlocked hint is shown * Add a delay to backlight switch off while locking * Better user input handling * Switch backlight off after pin timeout * Correct grammar in notification settings Co-authored-by: あく --- .gitignore | 3 + applications/desktop/desktop.c | 109 +++++++++++++- applications/desktop/desktop_i.h | 9 ++ .../desktop_settings/desktop_settings.h | 3 +- .../desktop_settings/desktop_settings_app.c | 7 + .../desktop_settings/desktop_settings_app.h | 3 + .../scenes/desktop_settings_scene_start.c | 64 ++++++-- .../desktop/scenes/desktop_scene_lock_menu.c | 8 +- .../desktop/scenes/desktop_scene_locked.c | 8 +- .../desktop/scenes/desktop_scene_pin_input.c | 7 +- applications/desktop/views/desktop_events.h | 1 + .../desktop/views/desktop_view_locked.c | 140 +++++++++--------- .../desktop/views/desktop_view_locked.h | 1 + applications/notification/notification_app.c | 8 +- .../notification/notification_messages.c | 10 +- .../notification/notification_messages.h | 2 + .../notification/notification_settings_app.c | 49 +----- applications/system/system_settings.c | 17 +-- firmware/targets/f7/furi_hal/furi_hal_delay.c | 4 + .../targets/furi_hal_include/furi_hal_delay.h | 7 + lib/toolbox/value_index.c | 39 +++++ lib/toolbox/value_index.h | 51 +++++++ 22 files changed, 385 insertions(+), 165 deletions(-) create mode 100644 lib/toolbox/value_index.c create mode 100644 lib/toolbox/value_index.h diff --git a/.gitignore b/.gitignore index 319cf90c093..6577101d6ba 100644 --- a/.gitignore +++ b/.gitignore @@ -36,3 +36,6 @@ CMakeLists.txt # bundle output dist + +# kde +.directory diff --git a/applications/desktop/desktop.c b/applications/desktop/desktop.c index 0f969ce2e44..d6c220831a4 100644 --- a/applications/desktop/desktop.c +++ b/applications/desktop/desktop.c @@ -1,6 +1,9 @@ #include #include +#include #include +#include +#include #include #include @@ -13,6 +16,10 @@ #include "desktop_i.h" #include "desktop_helpers.h" +static void desktop_auto_lock_arm(Desktop*); +static void desktop_auto_lock_inhibit(Desktop*); +static void desktop_start_auto_lock_timer(Desktop*); + static void desktop_loader_callback(const void* message, void* context) { furi_assert(context); Desktop* desktop = context; @@ -37,9 +44,19 @@ static bool desktop_custom_event_callback(void* context, uint32_t event) { switch(event) { case DesktopGlobalBeforeAppStarted: animation_manager_unload_and_stall_animation(desktop->animation_manager); + desktop_auto_lock_inhibit(desktop); return true; case DesktopGlobalAfterAppFinished: animation_manager_load_and_continue_animation(desktop->animation_manager); + // TODO: Implement a message mechanism for loading settings and (optionally) + // locking and unlocking + LOAD_DESKTOP_SETTINGS(&desktop->settings); + desktop_auto_lock_arm(desktop); + return true; + case DesktopGlobalAutoLock: + if(!loader_is_locked(desktop->loader)) { + desktop_lock(desktop); + } return true; } @@ -58,6 +75,63 @@ static void desktop_tick_event_callback(void* context) { scene_manager_handle_tick_event(app->scene_manager); } +static void desktop_input_event_callback(const void* value, void* context) { + furi_assert(value); + furi_assert(context); + const InputEvent* event = value; + Desktop* desktop = context; + if(event->type == InputTypePress) { + desktop_start_auto_lock_timer(desktop); + } +} + +static void desktop_auto_lock_timer_callback(void* context) { + furi_assert(context); + Desktop* desktop = context; + view_dispatcher_send_custom_event(desktop->view_dispatcher, DesktopGlobalAutoLock); +} + +static void desktop_start_auto_lock_timer(Desktop* desktop) { + osTimerStart( + desktop->auto_lock_timer, furi_hal_ms_to_ticks(desktop->settings.auto_lock_delay_ms)); +} + +static void desktop_stop_auto_lock_timer(Desktop* desktop) { + osTimerStop(desktop->auto_lock_timer); +} + +static void desktop_auto_lock_arm(Desktop* desktop) { + if(desktop->settings.auto_lock_delay_ms) { + desktop->input_events_subscription = furi_pubsub_subscribe( + desktop->input_events_pubsub, desktop_input_event_callback, desktop); + desktop_start_auto_lock_timer(desktop); + } +} + +static void desktop_auto_lock_inhibit(Desktop* desktop) { + desktop_stop_auto_lock_timer(desktop); + if(desktop->input_events_subscription) { + furi_pubsub_unsubscribe(desktop->input_events_pubsub, desktop->input_events_subscription); + desktop->input_events_subscription = NULL; + } +} + +void desktop_lock(Desktop* desktop) { + desktop_auto_lock_inhibit(desktop); + scene_manager_set_scene_state( + desktop->scene_manager, DesktopSceneLocked, SCENE_LOCKED_FIRST_ENTER); + scene_manager_next_scene(desktop->scene_manager, DesktopSceneLocked); + notification_message(desktop->notification, &sequence_display_off_delay_1000); +} + +void desktop_unlock(Desktop* desktop) { + furi_hal_rtc_set_pin_fails(0); + desktop_helpers_unlock_system(desktop); + desktop_view_locked_unlock(desktop->locked_view); + scene_manager_search_and_switch_to_previous_scene(desktop->scene_manager, DesktopSceneMain); + desktop_auto_lock_arm(desktop); +} + Desktop* desktop_alloc() { Desktop* desktop = malloc(sizeof(Desktop)); @@ -146,9 +220,17 @@ Desktop* desktop_alloc() { animation_manager_is_animation_loaded(desktop->animation_manager)) { animation_manager_unload_and_stall_animation(desktop->animation_manager); } + + desktop->notification = furi_record_open("notification"); desktop->app_start_stop_subscription = furi_pubsub_subscribe( loader_get_pubsub(desktop->loader), desktop_loader_callback, desktop); + desktop->input_events_pubsub = furi_record_open("input_events"); + desktop->input_events_subscription = NULL; + + desktop->auto_lock_timer = + osTimerNew(desktop_auto_lock_timer_callback, osTimerOnce, desktop, NULL); + return desktop; } @@ -157,8 +239,17 @@ void desktop_free(Desktop* desktop) { furi_pubsub_unsubscribe( loader_get_pubsub(desktop->loader), desktop->app_start_stop_subscription); + + if(desktop->input_events_subscription) { + furi_pubsub_unsubscribe(desktop->input_events_pubsub, desktop->input_events_subscription); + desktop->input_events_subscription = NULL; + } + desktop->loader = NULL; + desktop->input_events_pubsub = NULL; furi_record_close("loader"); + furi_record_close("notification"); + furi_record_close("input_events"); view_dispatcher_remove_view(desktop->view_dispatcher, DesktopViewIdMain); view_dispatcher_remove_view(desktop->view_dispatcher, DesktopViewIdLockMenu); @@ -191,6 +282,8 @@ void desktop_free(Desktop* desktop) { furi_record_close("menu"); + osTimerDelete(desktop->auto_lock_timer); + free(desktop); } @@ -214,14 +307,16 @@ int32_t desktop_srv(void* p) { scene_manager_next_scene(desktop->scene_manager, DesktopSceneMain); - if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagLock)) { - if(desktop->settings.pin_code.length > 0) { - scene_manager_set_scene_state( - desktop->scene_manager, DesktopSceneLocked, SCENE_LOCKED_FIRST_ENTER); - scene_manager_next_scene(desktop->scene_manager, DesktopSceneLocked); - } else { - furi_hal_rtc_reset_flag(FuriHalRtcFlagLock); + if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagLock) && !desktop->settings.pin_code.length) { + furi_hal_rtc_reset_flag(FuriHalRtcFlagLock); + } + + if(!furi_hal_rtc_is_flag_set(FuriHalRtcFlagLock)) { + if(!loader_is_locked(desktop->loader)) { + desktop_auto_lock_arm(desktop); } + } else { + desktop_lock(desktop); } if(desktop_is_first_start()) { diff --git a/applications/desktop/desktop_i.h b/applications/desktop/desktop_i.h index 8eb7be21104..2888f0998e8 100644 --- a/applications/desktop/desktop_i.h +++ b/applications/desktop/desktop_i.h @@ -19,6 +19,7 @@ #include #include +#include #define STATUS_BAR_Y_SHIFT 13 @@ -59,10 +60,18 @@ struct Desktop { ViewPort* lock_viewport; AnimationManager* animation_manager; + Loader* loader; + NotificationApp* notification; + FuriPubSubSubscription* app_start_stop_subscription; + FuriPubSub* input_events_pubsub; + FuriPubSubSubscription* input_events_subscription; + osTimerId_t auto_lock_timer; }; Desktop* desktop_alloc(); void desktop_free(Desktop* desktop); +void desktop_lock(Desktop* desktop); +void desktop_unlock(Desktop* desktop); diff --git a/applications/desktop/desktop_settings/desktop_settings.h b/applications/desktop/desktop_settings/desktop_settings.h index 24165fe26be..b56d63a7a61 100644 --- a/applications/desktop/desktop_settings/desktop_settings.h +++ b/applications/desktop/desktop_settings/desktop_settings.h @@ -5,7 +5,7 @@ #include #include -#define DESKTOP_SETTINGS_VER (1) +#define DESKTOP_SETTINGS_VER (2) #define DESKTOP_SETTINGS_PATH "/int/desktop.settings" #define DESKTOP_SETTINGS_MAGIC (0x17) #define PIN_MAX_LENGTH 12 @@ -39,6 +39,7 @@ typedef struct { typedef struct { uint16_t favorite; PinCode pin_code; + uint32_t auto_lock_delay_ms; } DesktopSettings; static inline bool pins_are_equal(const PinCode* pin_code1, const PinCode* pin_code2) { diff --git a/applications/desktop/desktop_settings/desktop_settings_app.c b/applications/desktop/desktop_settings/desktop_settings_app.c index 46e0bdc539e..c52f1947cd1 100644 --- a/applications/desktop/desktop_settings/desktop_settings_app.c +++ b/applications/desktop/desktop_settings/desktop_settings_app.c @@ -36,12 +36,17 @@ DesktopSettingsApp* desktop_settings_app_alloc() { app->popup = popup_alloc(); app->submenu = submenu_alloc(); + app->variable_item_list = variable_item_list_alloc(); app->pin_input_view = desktop_view_pin_input_alloc(); app->pin_setup_howto_view = desktop_settings_view_pin_setup_howto_alloc(); app->pin_setup_howto2_view = desktop_settings_view_pin_setup_howto2_alloc(); view_dispatcher_add_view( app->view_dispatcher, DesktopSettingsAppViewMenu, submenu_get_view(app->submenu)); + view_dispatcher_add_view( + app->view_dispatcher, + DesktopSettingsAppViewVarItemList, + variable_item_list_get_view(app->variable_item_list)); view_dispatcher_add_view( app->view_dispatcher, DesktopSettingsAppViewIdPopup, popup_get_view(app->popup)); view_dispatcher_add_view( @@ -63,10 +68,12 @@ void desktop_settings_app_free(DesktopSettingsApp* app) { furi_assert(app); // Variable item list view_dispatcher_remove_view(app->view_dispatcher, DesktopSettingsAppViewMenu); + view_dispatcher_remove_view(app->view_dispatcher, DesktopSettingsAppViewVarItemList); view_dispatcher_remove_view(app->view_dispatcher, DesktopSettingsAppViewIdPopup); view_dispatcher_remove_view(app->view_dispatcher, DesktopSettingsAppViewIdPinInput); view_dispatcher_remove_view(app->view_dispatcher, DesktopSettingsAppViewIdPinSetupHowto); view_dispatcher_remove_view(app->view_dispatcher, DesktopSettingsAppViewIdPinSetupHowto2); + variable_item_list_free(app->variable_item_list); submenu_free(app->submenu); popup_free(app->popup); desktop_view_pin_input_free(app->pin_input_view); diff --git a/applications/desktop/desktop_settings/desktop_settings_app.h b/applications/desktop/desktop_settings/desktop_settings_app.h index 6297e42db5f..a1ca9f6f595 100644 --- a/applications/desktop/desktop_settings/desktop_settings_app.h +++ b/applications/desktop/desktop_settings/desktop_settings_app.h @@ -5,6 +5,7 @@ #include #include #include +#include #include "desktop_settings.h" #include "desktop/views/desktop_view_pin_input.h" @@ -13,6 +14,7 @@ typedef enum { DesktopSettingsAppViewMenu, + DesktopSettingsAppViewVarItemList, DesktopSettingsAppViewIdPopup, DesktopSettingsAppViewIdPinInput, DesktopSettingsAppViewIdPinSetupHowto, @@ -25,6 +27,7 @@ typedef struct { Gui* gui; SceneManager* scene_manager; ViewDispatcher* view_dispatcher; + VariableItemList* variable_item_list; Submenu* submenu; Popup* popup; DesktopViewPinInput* pin_input_view; diff --git a/applications/desktop/desktop_settings/scenes/desktop_settings_scene_start.c b/applications/desktop/desktop_settings/scenes/desktop_settings_scene_start.c index 8f856b6aef2..63363497f1f 100644 --- a/applications/desktop/desktop_settings/scenes/desktop_settings_scene_start.c +++ b/applications/desktop/desktop_settings/scenes/desktop_settings_scene_start.c @@ -1,35 +1,65 @@ #include +#include #include "../desktop_settings_app.h" #include "desktop_settings_scene.h" #define SCENE_EVENT_SELECT_FAVORITE 0 #define SCENE_EVENT_SELECT_PIN_SETUP 1 +#define SCENE_EVENT_SELECT_AUTO_LOCK_DELAY 2 -static void desktop_settings_scene_start_submenu_callback(void* context, uint32_t index) { +#define AUTO_LOCK_DELAY_COUNT 6 +const char* const auto_lock_delay_text[AUTO_LOCK_DELAY_COUNT] = { + "OFF", + "30s", + "60s", + "2min", + "5min", + "10min", +}; + +const uint32_t auto_lock_delay_value[AUTO_LOCK_DELAY_COUNT] = + {0, 30000, 60000, 120000, 300000, 600000}; + +static void desktop_settings_scene_start_var_list_enter_callback(void* context, uint32_t index) { DesktopSettingsApp* app = context; view_dispatcher_send_custom_event(app->view_dispatcher, index); } +static void desktop_settings_scene_start_auto_lock_delay_changed(VariableItem* item) { + DesktopSettingsApp* app = variable_item_get_context(item); + uint8_t index = variable_item_get_current_value_index(item); + + variable_item_set_current_value_text(item, auto_lock_delay_text[index]); + app->settings.auto_lock_delay_ms = auto_lock_delay_value[index]; +} + void desktop_settings_scene_start_on_enter(void* context) { DesktopSettingsApp* app = context; - Submenu* submenu = app->submenu; + VariableItemList* variable_item_list = app->variable_item_list; - submenu_add_item( - submenu, - "Favorite App", - SCENE_EVENT_SELECT_FAVORITE, - desktop_settings_scene_start_submenu_callback, - app); + VariableItem* item; + uint8_t value_index; - submenu_add_item( - submenu, - "PIN Setup", - SCENE_EVENT_SELECT_PIN_SETUP, - desktop_settings_scene_start_submenu_callback, + variable_item_list_add(variable_item_list, "Favorite App", 1, NULL, NULL); + + variable_item_list_add(variable_item_list, "PIN Setup", 1, NULL, NULL); + + item = variable_item_list_add( + variable_item_list, + "Auto Lock Time", + AUTO_LOCK_DELAY_COUNT, + desktop_settings_scene_start_auto_lock_delay_changed, app); - view_dispatcher_switch_to_view(app->view_dispatcher, DesktopSettingsAppViewMenu); + variable_item_list_set_enter_callback( + variable_item_list, desktop_settings_scene_start_var_list_enter_callback, app); + value_index = value_index_uint32( + app->settings.auto_lock_delay_ms, auto_lock_delay_value, AUTO_LOCK_DELAY_COUNT); + variable_item_set_current_value_index(item, value_index); + variable_item_set_current_value_text(item, auto_lock_delay_text[value_index]); + + view_dispatcher_switch_to_view(app->view_dispatcher, DesktopSettingsAppViewVarItemList); } bool desktop_settings_scene_start_on_event(void* context, SceneManagerEvent event) { @@ -46,6 +76,9 @@ bool desktop_settings_scene_start_on_event(void* context, SceneManagerEvent even scene_manager_next_scene(app->scene_manager, DesktopSettingsAppScenePinMenu); consumed = true; break; + case SCENE_EVENT_SELECT_AUTO_LOCK_DELAY: + consumed = true; + break; } } return consumed; @@ -53,5 +86,6 @@ bool desktop_settings_scene_start_on_event(void* context, SceneManagerEvent even void desktop_settings_scene_start_on_exit(void* context) { DesktopSettingsApp* app = context; - submenu_reset(app->submenu); + variable_item_list_reset(app->variable_item_list); + SAVE_DESKTOP_SETTINGS(&app->settings); } diff --git a/applications/desktop/scenes/desktop_scene_lock_menu.c b/applications/desktop/scenes/desktop_scene_lock_menu.c index 058081eb949..7b7606b1d49 100644 --- a/applications/desktop/scenes/desktop_scene_lock_menu.c +++ b/applications/desktop/scenes/desktop_scene_lock_menu.c @@ -48,17 +48,13 @@ bool desktop_scene_lock_menu_on_event(void* context, SceneManagerEvent event) { switch(event.event) { case DesktopLockMenuEventLock: scene_manager_set_scene_state(desktop->scene_manager, DesktopSceneLockMenu, 0); - scene_manager_set_scene_state( - desktop->scene_manager, DesktopSceneLocked, SCENE_LOCKED_FIRST_ENTER); - scene_manager_next_scene(desktop->scene_manager, DesktopSceneLocked); + desktop_lock(desktop); consumed = true; break; case DesktopLockMenuEventPinLock: if(desktop->settings.pin_code.length > 0) { furi_hal_rtc_set_flag(FuriHalRtcFlagLock); - scene_manager_set_scene_state( - desktop->scene_manager, DesktopSceneLocked, SCENE_LOCKED_FIRST_ENTER); - scene_manager_next_scene(desktop->scene_manager, DesktopSceneLocked); + desktop_lock(desktop); } else { LoaderStatus status = loader_start(desktop->loader, "Desktop", DESKTOP_SETTINGS_RUN_PIN_SETUP_ARG); diff --git a/applications/desktop/scenes/desktop_scene_locked.c b/applications/desktop/scenes/desktop_scene_locked.c index 98d5fa0a36d..65d064d8253 100644 --- a/applications/desktop/scenes/desktop_scene_locked.c +++ b/applications/desktop/scenes/desktop_scene_locked.c @@ -81,13 +81,13 @@ bool desktop_scene_locked_on_event(void* context, SceneManagerEvent event) { if(event.type == SceneManagerEventTypeCustom) { switch(event.event) { case DesktopLockedEventUnlocked: - furi_hal_rtc_set_pin_fails(0); - desktop_helpers_unlock_system(desktop); - scene_manager_search_and_switch_to_previous_scene( - desktop->scene_manager, DesktopSceneMain); + desktop_unlock(desktop); consumed = true; break; case DesktopLockedEventUpdate: + if(desktop_view_locked_is_locked_hint_visible(desktop->locked_view)) { + notification_message(desktop->notification, &sequence_display_off); + } desktop_view_locked_update(desktop->locked_view); consumed = true; break; diff --git a/applications/desktop/scenes/desktop_scene_pin_input.c b/applications/desktop/scenes/desktop_scene_pin_input.c index 60935f07bb2..827b74a6799 100644 --- a/applications/desktop/scenes/desktop_scene_pin_input.c +++ b/applications/desktop/scenes/desktop_scene_pin_input.c @@ -129,16 +129,13 @@ bool desktop_scene_pin_input_on_event(void* context, SceneManagerEvent event) { consumed = true; break; case DesktopPinInputEventUnlocked: - desktop_view_locked_unlock(desktop->locked_view); - furi_hal_rtc_set_pin_fails(0); - desktop_helpers_unlock_system(desktop); - scene_manager_search_and_switch_to_previous_scene( - desktop->scene_manager, DesktopSceneMain); + desktop_unlock(desktop); consumed = true; break; case DesktopPinInputEventBack: scene_manager_search_and_switch_to_previous_scene( desktop->scene_manager, DesktopSceneLocked); + notification_message(desktop->notification, &sequence_display_off); consumed = true; break; } diff --git a/applications/desktop/views/desktop_events.h b/applications/desktop/views/desktop_events.h index 6e5eb2f64ab..f38a5417066 100644 --- a/applications/desktop/views/desktop_events.h +++ b/applications/desktop/views/desktop_events.h @@ -38,4 +38,5 @@ typedef enum { // Global events DesktopGlobalBeforeAppStarted, DesktopGlobalAfterAppFinished, + DesktopGlobalAutoLock, } DesktopEvent; diff --git a/applications/desktop/views/desktop_view_locked.c b/applications/desktop/views/desktop_view_locked.c index 766f2b20afa..9f39c2ce6d8 100644 --- a/applications/desktop/views/desktop_view_locked.c +++ b/applications/desktop/views/desktop_view_locked.c @@ -11,6 +11,7 @@ #include "desktop_view_locked.h" #define DOOR_MOVING_INTERVAL_MS (1000 / 16) +#define LOCKED_HINT_TIMEOUT_MS (1000) #define UNLOCKED_HINT_TIMEOUT_MS (2000) #define DOOR_OFFSET_START -55 @@ -32,14 +33,18 @@ struct DesktopViewLocked { uint32_t lock_lastpress; }; +typedef enum { + DesktopViewLockedStateUnlocked, + DesktopViewLockedStateLocked, + DesktopViewLockedStateDoorsClosing, + DesktopViewLockedStateLockedHintShown, + DesktopViewLockedStateUnlockedHintShown +} DesktopViewLockedState; + typedef struct { - uint32_t hint_icon_expire_at; - bool unlocked_hint; - bool locked; bool pin_locked; - int8_t door_offset; - bool doors_closing; + DesktopViewLockedState view_state; } DesktopViewLockedModel; void desktop_view_locked_set_callback( @@ -78,51 +83,54 @@ static bool desktop_view_locked_doors_move(DesktopViewLockedModel* model) { static void desktop_view_locked_update_hint_icon_timeout(DesktopViewLocked* locked_view) { DesktopViewLockedModel* model = view_get_model(locked_view->view); - model->hint_icon_expire_at = osKernelGetTickCount() + osKernelGetTickFreq(); - view_commit_model(locked_view->view, true); + const bool change_state = (model->view_state == DesktopViewLockedStateLocked) && + !model->pin_locked; + if(change_state) { + model->view_state = DesktopViewLockedStateLockedHintShown; + } + view_commit_model(locked_view->view, change_state); + xTimerChangePeriod(locked_view->timer, pdMS_TO_TICKS(LOCKED_HINT_TIMEOUT_MS), portMAX_DELAY); } void desktop_view_locked_update(DesktopViewLocked* locked_view) { - bool stop_timer = false; - DesktopViewLockedModel* model = view_get_model(locked_view->view); - if(model->locked) { - model->doors_closing = desktop_view_locked_doors_move(model); - stop_timer = !model->doors_closing; - } else { - model->unlocked_hint = false; - stop_timer = true; + DesktopViewLockedState view_state = model->view_state; + + if(view_state == DesktopViewLockedStateDoorsClosing && + !desktop_view_locked_doors_move(model)) { + model->view_state = DesktopViewLockedStateLocked; + } else if(view_state == DesktopViewLockedStateLockedHintShown) { + model->view_state = DesktopViewLockedStateLocked; + } else if(view_state == DesktopViewLockedStateUnlockedHintShown) { + model->view_state = DesktopViewLockedStateUnlocked; } + view_commit_model(locked_view->view, true); - if(stop_timer) { + if(view_state != DesktopViewLockedStateDoorsClosing) { xTimerStop(locked_view->timer, portMAX_DELAY); } } static void desktop_view_locked_draw(Canvas* canvas, void* model) { DesktopViewLockedModel* m = model; - uint32_t now = osKernelGetTickCount(); + DesktopViewLockedState view_state = m->view_state; canvas_set_color(canvas, ColorBlack); - if(m->locked) { - if(m->doors_closing) { - desktop_view_locked_doors_draw(canvas, m); - canvas_set_font(canvas, FontPrimary); - elements_multiline_text_framed(canvas, 42, 30 + STATUS_BAR_Y_SHIFT, "Locked"); - } else if((now < m->hint_icon_expire_at) && !m->pin_locked) { - canvas_set_font(canvas, FontSecondary); - elements_bold_rounded_frame(canvas, 14, 2 + STATUS_BAR_Y_SHIFT, 99, 48); - elements_multiline_text(canvas, 65, 20 + STATUS_BAR_Y_SHIFT, "To unlock\npress:"); - canvas_draw_icon(canvas, 65, 36 + STATUS_BAR_Y_SHIFT, &I_Back3_45x8); - canvas_draw_icon(canvas, 16, 7 + STATUS_BAR_Y_SHIFT, &I_WarningDolphin_45x42); - canvas_draw_dot(canvas, 17, 61); - } - } else { - if(m->unlocked_hint) { - canvas_set_font(canvas, FontPrimary); - elements_multiline_text_framed(canvas, 42, 30 + STATUS_BAR_Y_SHIFT, "Unlocked"); - } + if(view_state == DesktopViewLockedStateDoorsClosing) { + desktop_view_locked_doors_draw(canvas, m); + canvas_set_font(canvas, FontPrimary); + elements_multiline_text_framed(canvas, 42, 30 + STATUS_BAR_Y_SHIFT, "Locked"); + } else if(view_state == DesktopViewLockedStateLockedHintShown) { + canvas_set_font(canvas, FontSecondary); + elements_bold_rounded_frame(canvas, 14, 2 + STATUS_BAR_Y_SHIFT, 99, 48); + elements_multiline_text(canvas, 65, 20 + STATUS_BAR_Y_SHIFT, "To unlock\npress:"); + canvas_draw_icon(canvas, 65, 36 + STATUS_BAR_Y_SHIFT, &I_Back3_45x8); + canvas_draw_icon(canvas, 16, 7 + STATUS_BAR_Y_SHIFT, &I_WarningDolphin_45x42); + canvas_draw_dot(canvas, 17, 61); + } else if(view_state == DesktopViewLockedStateUnlockedHintShown) { + canvas_set_font(canvas, FontPrimary); + elements_multiline_text_framed(canvas, 42, 30 + STATUS_BAR_Y_SHIFT, "Unlocked"); } } @@ -134,43 +142,38 @@ View* desktop_view_locked_get_view(DesktopViewLocked* locked_view) { static bool desktop_view_locked_input(InputEvent* event, void* context) { furi_assert(event); furi_assert(context); - DesktopViewLocked* locked_view = context; - bool locked = false; - bool locked_with_pin = false; - bool doors_closing = false; - uint32_t press_time = xTaskGetTickCount(); - - { - DesktopViewLockedModel* model = view_get_model(locked_view->view); - bool changed = false; - locked = model->locked; - locked_with_pin = model->pin_locked; - doors_closing = model->doors_closing; - if(!locked && model->unlocked_hint && event->type == InputTypePress) { - model->unlocked_hint = false; - changed = true; - } - view_commit_model(locked_view->view, changed); - } - if(!locked || doors_closing || (event->type != InputTypeShort)) { - return locked; + bool is_changed = false; + const uint32_t press_time = xTaskGetTickCount(); + DesktopViewLocked* locked_view = context; + DesktopViewLockedModel* model = view_get_model(locked_view->view); + if(model->view_state == DesktopViewLockedStateUnlockedHintShown && + event->type == InputTypePress) { + model->view_state = DesktopViewLockedStateUnlocked; + is_changed = true; } + const DesktopViewLockedState view_state = model->view_state; + const bool pin_locked = model->pin_locked; + view_commit_model(locked_view->view, is_changed); - if(locked_with_pin) { + if(view_state == DesktopViewLockedStateUnlocked || event->type != InputTypeShort) { + return view_state != DesktopViewLockedStateUnlocked; + } else if(view_state == DesktopViewLockedStateLocked && pin_locked) { locked_view->callback(DesktopLockedEventShowPinInput, locked_view->context); - } else { + } else if( + view_state == DesktopViewLockedStateLocked || + view_state == DesktopViewLockedStateLockedHintShown) { if(press_time - locked_view->lock_lastpress > UNLOCK_RST_TIMEOUT) { locked_view->lock_lastpress = press_time; locked_view->lock_count = 0; } desktop_view_locked_update_hint_icon_timeout(locked_view); + if(event->key == InputKeyBack) { locked_view->lock_lastpress = press_time; locked_view->lock_count++; if(locked_view->lock_count == UNLOCK_CNT) { - desktop_view_locked_unlock(locked_view); locked_view->callback(DesktopLockedEventUnlocked, locked_view->context); } } else { @@ -180,7 +183,7 @@ static bool desktop_view_locked_input(InputEvent* event, void* context) { locked_view->lock_lastpress = press_time; } - return locked; + return true; } DesktopViewLocked* desktop_view_locked_alloc() { @@ -189,7 +192,6 @@ DesktopViewLocked* desktop_view_locked_alloc() { locked_view->timer = xTimerCreate(NULL, 1000 / 16, pdTRUE, locked_view, locked_view_timer_callback); - locked_view->view = view_alloc(); view_allocate_model(locked_view->view, ViewModelTypeLocking, sizeof(DesktopViewLockedModel)); view_set_context(locked_view->view, locked_view); view_set_draw_callback(locked_view->view, desktop_view_locked_draw); @@ -207,7 +209,8 @@ void desktop_view_locked_free(DesktopViewLocked* locked_view) { void desktop_view_locked_close_doors(DesktopViewLocked* locked_view) { DesktopViewLockedModel* model = view_get_model(locked_view->view); - model->doors_closing = true; + furi_assert(model->view_state == DesktopViewLockedStateLocked); + model->view_state = DesktopViewLockedStateDoorsClosing; model->door_offset = DOOR_OFFSET_START; view_commit_model(locked_view->view, true); xTimerChangePeriod(locked_view->timer, pdMS_TO_TICKS(DOOR_MOVING_INTERVAL_MS), portMAX_DELAY); @@ -215,19 +218,24 @@ void desktop_view_locked_close_doors(DesktopViewLocked* locked_view) { void desktop_view_locked_lock(DesktopViewLocked* locked_view, bool pin_locked) { DesktopViewLockedModel* model = view_get_model(locked_view->view); - model->locked = true; + furi_assert(model->view_state == DesktopViewLockedStateUnlocked); + model->view_state = DesktopViewLockedStateLocked; model->pin_locked = pin_locked; view_commit_model(locked_view->view, true); } void desktop_view_locked_unlock(DesktopViewLocked* locked_view) { - furi_assert(locked_view); - locked_view->lock_count = 0; DesktopViewLockedModel* model = view_get_model(locked_view->view); - model->locked = false; + model->view_state = DesktopViewLockedStateUnlockedHintShown; model->pin_locked = false; - model->unlocked_hint = true; view_commit_model(locked_view->view, true); xTimerChangePeriod(locked_view->timer, pdMS_TO_TICKS(UNLOCKED_HINT_TIMEOUT_MS), portMAX_DELAY); } + +bool desktop_view_locked_is_locked_hint_visible(DesktopViewLocked* locked_view) { + DesktopViewLockedModel* model = view_get_model(locked_view->view); + const DesktopViewLockedState view_state = model->view_state; + view_commit_model(locked_view->view, false); + return view_state == DesktopViewLockedStateLockedHintShown; +} diff --git a/applications/desktop/views/desktop_view_locked.h b/applications/desktop/views/desktop_view_locked.h index 60fe791bcba..b0a0aa30301 100644 --- a/applications/desktop/views/desktop_view_locked.h +++ b/applications/desktop/views/desktop_view_locked.h @@ -19,3 +19,4 @@ void desktop_view_locked_free(DesktopViewLocked* locked_view); void desktop_view_locked_lock(DesktopViewLocked* locked_view, bool pin_locked); void desktop_view_locked_unlock(DesktopViewLocked* locked_view); void desktop_view_locked_close_doors(DesktopViewLocked* locked_view); +bool desktop_view_locked_is_locked_hint_visible(DesktopViewLocked* locked_view); diff --git a/applications/notification/notification_app.c b/applications/notification/notification_app.c index d05944906a4..00136ec5788 100644 --- a/applications/notification/notification_app.c +++ b/applications/notification/notification_app.c @@ -1,6 +1,7 @@ #include #include #include +#include #include "notification.h" #include "notification_messages.h" #include "notification_app.h" @@ -416,8 +417,13 @@ static bool notification_save_settings(NotificationApp* app) { }; static void input_event_callback(const void* value, void* context) { + furi_assert(value); + furi_assert(context); + const InputEvent* event = value; NotificationApp* app = context; - notification_message(app, &sequence_display_on); + if(event->type == InputTypePress) { + notification_message(app, &sequence_display_on); + } } // App alloc diff --git a/applications/notification/notification_messages.c b/applications/notification/notification_messages.c index 3934f5d0b09..733b7f9c95f 100644 --- a/applications/notification/notification_messages.c +++ b/applications/notification/notification_messages.c @@ -21,7 +21,7 @@ const NotificationMessage message_display_lock = { }; const NotificationMessage message_display_unlock = { - .type = NotificationMessageTypeLedDisplayLock, + .type = NotificationMessageTypeLedDisplayUnlock, .data.led.value = 0x00, }; @@ -208,6 +208,12 @@ const NotificationSequence sequence_display_unlock = { NULL, }; +const NotificationSequence sequence_display_off_delay_1000 = { + &message_delay_1000, + &message_display_off, + NULL, +}; + // Charging const NotificationSequence sequence_charging = { &message_red_255, @@ -436,4 +442,4 @@ const NotificationSequence sequence_audiovisual_alert = { &message_sound_off, &message_vibro_off, NULL, -}; \ No newline at end of file +}; diff --git a/applications/notification/notification_messages.h b/applications/notification/notification_messages.h index 54215e47a72..b9b0d72d6f6 100644 --- a/applications/notification/notification_messages.h +++ b/applications/notification/notification_messages.h @@ -78,6 +78,8 @@ extern const NotificationSequence sequence_display_off; extern const NotificationSequence sequence_display_lock; /** Display: backlight always on unlock */ extern const NotificationSequence sequence_display_unlock; +/** Display: backlight force off after a delay of 1000ms */ +extern const NotificationSequence sequence_display_off_delay_1000; // Charging extern const NotificationSequence sequence_charging; diff --git a/applications/notification/notification_settings_app.c b/applications/notification/notification_settings_app.c index fc2c16276df..1522628d1ff 100644 --- a/applications/notification/notification_settings_app.c +++ b/applications/notification/notification_settings_app.c @@ -2,6 +2,7 @@ #include "notification_app.h" #include #include +#include #define MAX_NOTIFICATION_SETTINGS 4 @@ -63,44 +64,6 @@ const char* const vibro_text[VIBRO_COUNT] = { }; const bool vibro_value[VIBRO_COUNT] = {false, true}; -uint8_t float_value_index(const float value, const float values[], uint8_t values_count) { - const float epsilon = 0.01f; - float last_value = values[0]; - uint8_t index = 0; - for(uint8_t i = 0; i < values_count; i++) { - if((value >= last_value - epsilon) && (value <= values[i] + epsilon)) { - index = i; - break; - } - last_value = values[i]; - } - return index; -} - -uint8_t uint32_value_index(const uint32_t value, const uint32_t values[], uint8_t values_count) { - int64_t last_value = INT64_MIN; - uint8_t index = 0; - for(uint8_t i = 0; i < values_count; i++) { - if((value >= last_value) && (value <= values[i])) { - index = i; - break; - } - last_value = values[i]; - } - return index; -} - -uint8_t bool_value_index(const bool value, const bool values[], uint8_t values_count) { - uint8_t index = 0; - for(uint8_t i = 0; i < values_count; i++) { - if(value == values[i]) { - index = i; - break; - } - } - return index; -} - static void backlight_changed(VariableItem* item) { NotificationAppSettings* app = variable_item_get_context(item); uint8_t index = variable_item_get_current_value_index(item); @@ -164,21 +127,21 @@ static NotificationAppSettings* alloc_settings() { item = variable_item_list_add( app->variable_item_list, "LCD Backlight", BACKLIGHT_COUNT, backlight_changed, app); - value_index = float_value_index( + value_index = value_index_float( app->notification->settings.display_brightness, backlight_value, BACKLIGHT_COUNT); variable_item_set_current_value_index(item, value_index); variable_item_set_current_value_text(item, backlight_text[value_index]); item = variable_item_list_add( app->variable_item_list, "Backlight Time", DELAY_COUNT, screen_changed, app); - value_index = uint32_value_index( + value_index = value_index_uint32( app->notification->settings.display_off_delay_ms, delay_value, DELAY_COUNT); variable_item_set_current_value_index(item, value_index); variable_item_set_current_value_text(item, delay_text[value_index]); item = variable_item_list_add( app->variable_item_list, "LED Brightness", BACKLIGHT_COUNT, led_changed, app); - value_index = float_value_index( + value_index = value_index_float( app->notification->settings.led_brightness, backlight_value, BACKLIGHT_COUNT); variable_item_set_current_value_index(item, value_index); variable_item_set_current_value_text(item, backlight_text[value_index]); @@ -186,13 +149,13 @@ static NotificationAppSettings* alloc_settings() { item = variable_item_list_add( app->variable_item_list, "Volume", VOLUME_COUNT, volume_changed, app); value_index = - float_value_index(app->notification->settings.speaker_volume, volume_value, VOLUME_COUNT); + value_index_float(app->notification->settings.speaker_volume, volume_value, VOLUME_COUNT); variable_item_set_current_value_index(item, value_index); variable_item_set_current_value_text(item, volume_text[value_index]); item = variable_item_list_add(app->variable_item_list, "Vibro", VIBRO_COUNT, vibro_changed, app); - value_index = bool_value_index(app->notification->settings.vibro_on, vibro_value, VIBRO_COUNT); + value_index = value_index_bool(app->notification->settings.vibro_on, vibro_value, VIBRO_COUNT); variable_item_set_current_value_index(item, value_index); variable_item_set_current_value_text(item, vibro_text[value_index]); diff --git a/applications/system/system_settings.c b/applications/system/system_settings.c index fde07745bd1..f06292ec309 100644 --- a/applications/system/system_settings.c +++ b/applications/system/system_settings.c @@ -1,19 +1,6 @@ #include "system_settings.h" #include - -static uint8_t - uint32_value_index(const uint32_t value, const uint32_t values[], uint8_t values_count) { - int64_t last_value = INT64_MIN; - uint8_t index = 0; - for(uint8_t i = 0; i < values_count; i++) { - if((value >= last_value) && (value <= values[i])) { - index = i; - break; - } - last_value = values[i]; - } - return index; -} +#include const char* const log_level_text[] = { "Default", @@ -80,7 +67,7 @@ SystemSettings* system_settings_alloc() { item = variable_item_list_add( app->var_item_list, "Log Level", COUNT_OF(log_level_text), log_level_changed, app); - value_index = uint32_value_index( + value_index = value_index_uint32( furi_hal_rtc_get_log_level(), log_level_value, COUNT_OF(log_level_text)); variable_item_set_current_value_index(item, value_index); variable_item_set_current_value_text(item, log_level_text[value_index]); diff --git a/firmware/targets/f7/furi_hal/furi_hal_delay.c b/firmware/targets/f7/furi_hal/furi_hal_delay.c index 8a26d8dc946..94ef7865619 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_delay.c +++ b/firmware/targets/f7/furi_hal/furi_hal_delay.c @@ -26,6 +26,10 @@ uint32_t furi_hal_get_tick(void) { return tick_cnt; } +uint32_t furi_hal_ms_to_ticks(float milliseconds) { + return milliseconds / (1000.0f / osKernelGetTickFreq()); +} + void furi_hal_delay_us(float microseconds) { uint32_t start = DWT->CYCCNT; uint32_t time_ticks = microseconds * furi_hal_delay_instructions_per_microsecond(); diff --git a/firmware/targets/furi_hal_include/furi_hal_delay.h b/firmware/targets/furi_hal_include/furi_hal_delay.h index 58b4ed9b332..f34a7053073 100644 --- a/firmware/targets/furi_hal_include/furi_hal_delay.h +++ b/firmware/targets/furi_hal_include/furi_hal_delay.h @@ -31,6 +31,13 @@ void furi_hal_tick(void); */ uint32_t furi_hal_get_tick(void); +/** Convert milliseconds to ticks + * + * @param[in] milliseconds time in milliseconds + * @return time in ticks + */ +uint32_t furi_hal_ms_to_ticks(float milliseconds); + /** Delay in milliseconds * @warning Cannot be used from ISR * diff --git a/lib/toolbox/value_index.c b/lib/toolbox/value_index.c new file mode 100644 index 00000000000..e0745e43410 --- /dev/null +++ b/lib/toolbox/value_index.c @@ -0,0 +1,39 @@ +#include "value_index.h" + +uint8_t value_index_uint32(const uint32_t value, const uint32_t values[], uint8_t values_count) { + int64_t last_value = INT64_MIN; + uint8_t index = 0; + for(uint8_t i = 0; i < values_count; i++) { + if((value >= last_value) && (value <= values[i])) { + index = i; + break; + } + last_value = values[i]; + } + return index; +} + +uint8_t value_index_float(const float value, const float values[], uint8_t values_count) { + const float epsilon = 0.01f; + float last_value = values[0]; + uint8_t index = 0; + for(uint8_t i = 0; i < values_count; i++) { + if((value >= last_value - epsilon) && (value <= values[i] + epsilon)) { + index = i; + break; + } + last_value = values[i]; + } + return index; +} + +uint8_t value_index_bool(const bool value, const bool values[], uint8_t values_count) { + uint8_t index = 0; + for(uint8_t i = 0; i < values_count; i++) { + if(value == values[i]) { + index = i; + break; + } + } + return index; +} diff --git a/lib/toolbox/value_index.h b/lib/toolbox/value_index.h new file mode 100644 index 00000000000..9459292a75b --- /dev/null +++ b/lib/toolbox/value_index.h @@ -0,0 +1,51 @@ +#pragma once + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** Get the index of a uint32_t array element which is closest to the given value. + * + * Returned index corresponds to the first element found. + * If no suitable elements were found, the function returns 0. + * + * @param value value to be searched. + * @param values pointer to the array to perform the search in. + * @param values_count array size. + * + * @return value's index. + */ +uint8_t value_index_uint32(const uint32_t value, const uint32_t values[], uint8_t values_count); + +/** Get the index of a float array element which is closest to the given value. + * + * Returned index corresponds to the first element found. + * If no suitable elements were found, the function returns 0. + * + * @param value value to be searched. + * @param values pointer to the array to perform the search in. + * @param values_count array size. + * + * @return value's index. + */ +uint8_t value_index_float(const float value, const float values[], uint8_t values_count); + +/** Get the index of a bool array element which is equal to the given value. + * + * Returned index corresponds to the first element found. + * If no suitable elements were found, the function returns 0. + * + * @param value value to be searched. + * @param values pointer to the array to perform the search in. + * @param values_count array size. + * + * @return value's index. + */ +uint8_t value_index_bool(const bool value, const bool values[], uint8_t values_count); + +#ifdef __cplusplus +} +#endif From 8cc3fd579caaafca9ea6dba1e7c6275ebd0c28f2 Mon Sep 17 00:00:00 2001 From: Skorpionm <85568270+Skorpionm@users.noreply.github.com> Date: Thu, 14 Apr 2022 16:49:29 +0400 Subject: [PATCH 09/20] SubGhz: Unit_test and bugfixes (#1104) * SubGhz: CLI add "subghz decode_raw" * SubGhz: unit_test * SubGhz: add Hormann_hsm_raw unit_test * SubGhz: fix duration raw * Unit_test: fix total test timer * SubGHz: fix name display scher_khan * SubGhz: fix deviation protocol kia * SubGhz: return max name length to previous value * FuriHal: correctly handle mute in speaker * UnitTests: fix grammar in subghz Co-authored-by: Aleksandr Kutuzov --- applications/subghz/subghz_cli.c | 112 +++++ applications/subghz/subghz_i.h | 2 +- .../flipper_format_string_test.c | 0 .../flipper_format/flipper_format_test.c | 0 .../{tests => unit_tests}/furi_memmgr_test.c | 0 .../{tests => unit_tests}/furi_pubsub_test.c | 0 .../{tests => unit_tests}/furi_record_test.c | 0 .../furi_valuemutex_test.c | 0 .../infrared_decoder_encoder_test.c | 0 .../test_data/infrared_nec_test_data.srcdata | 0 .../infrared_necext_test_data.srcdata | 0 .../test_data/infrared_rc5_test_data.srcdata | 0 .../test_data/infrared_rc6_test_data.srcdata | 0 .../infrared_samsung_test_data.srcdata | 0 .../test_data/infrared_sirc_test_data.srcdata | 0 applications/{tests => unit_tests}/minunit.h | 0 .../{tests => unit_tests}/minunit_test.c | 0 .../{tests => unit_tests}/minunit_vars.h | 0 .../{tests => unit_tests}/minunit_vars_ex.h | 0 .../{tests => unit_tests}/rpc/rpc_test.c | 0 .../storage/storage_test.c | 0 .../stream/stream_test.c | 0 applications/unit_tests/subghz/subghz_test.c | 404 ++++++++++++++++++ .../{tests => unit_tests}/test_index.c | 9 +- assets/unit_tests/subghz/came.sub | 7 + assets/unit_tests/subghz/came_atomo_raw.sub | 8 + assets/unit_tests/subghz/came_raw.sub | 9 + assets/unit_tests/subghz/came_twee.sub | 7 + assets/unit_tests/subghz/came_twee_raw.sub | 10 + assets/unit_tests/subghz/cenmax_raw.sub | 15 + assets/unit_tests/subghz/doorhan.sub | 7 + assets/unit_tests/subghz/doorhan_raw.sub | 10 + assets/unit_tests/subghz/faac_slh_raw.sub | 11 + assets/unit_tests/subghz/gate_tx.sub | 7 + assets/unit_tests/subghz/gate_tx_raw.sub | 11 + assets/unit_tests/subghz/hormann_hsm_raw.sub | 10 + assets/unit_tests/subghz/ido_117_111_raw.sub | 10 + assets/unit_tests/subghz/kia_seed_raw.sub | 25 ++ assets/unit_tests/subghz/nero_radio_raw.sub | 13 + assets/unit_tests/subghz/nero_sketch_raw.sub | 17 + assets/unit_tests/subghz/nice_flo.sub | 7 + assets/unit_tests/subghz/nice_flo_raw.sub | 7 + assets/unit_tests/subghz/nice_flor_s_raw.sub | 9 + assets/unit_tests/subghz/princeton.sub | 8 + assets/unit_tests/subghz/princeton_raw.sub | 8 + .../subghz/scher_khan_magic_code.sub | 22 + assets/unit_tests/subghz/somfy_keytis_raw.sub | 7 + assets/unit_tests/subghz/somfy_telis_raw.sub | 9 + assets/unit_tests/subghz/test_random_raw.sub | 65 +++ .../targets/f7/furi_hal/furi_hal_speaker.c | 4 + .../targets/f7/furi_hal/furi_hal_subghz.c | 6 +- .../furi_hal_include/furi_hal_subghz.h | 2 +- lib/subghz/protocols/kia.c | 10 +- lib/subghz/protocols/raw.c | 4 +- lib/subghz/protocols/registry.c | 20 - lib/subghz/protocols/registry.h | 20 + lib/subghz/protocols/scher_khan.c | 6 +- 57 files changed, 879 insertions(+), 39 deletions(-) rename applications/{tests => unit_tests}/flipper_format/flipper_format_string_test.c (100%) rename applications/{tests => unit_tests}/flipper_format/flipper_format_test.c (100%) rename applications/{tests => unit_tests}/furi_memmgr_test.c (100%) rename applications/{tests => unit_tests}/furi_pubsub_test.c (100%) rename applications/{tests => unit_tests}/furi_record_test.c (100%) rename applications/{tests => unit_tests}/furi_valuemutex_test.c (100%) rename applications/{tests => unit_tests}/infrared_decoder_encoder/infrared_decoder_encoder_test.c (100%) rename applications/{tests => unit_tests}/infrared_decoder_encoder/test_data/infrared_nec_test_data.srcdata (100%) rename applications/{tests => unit_tests}/infrared_decoder_encoder/test_data/infrared_necext_test_data.srcdata (100%) rename applications/{tests => unit_tests}/infrared_decoder_encoder/test_data/infrared_rc5_test_data.srcdata (100%) rename applications/{tests => unit_tests}/infrared_decoder_encoder/test_data/infrared_rc6_test_data.srcdata (100%) rename applications/{tests => unit_tests}/infrared_decoder_encoder/test_data/infrared_samsung_test_data.srcdata (100%) rename applications/{tests => unit_tests}/infrared_decoder_encoder/test_data/infrared_sirc_test_data.srcdata (100%) rename applications/{tests => unit_tests}/minunit.h (100%) rename applications/{tests => unit_tests}/minunit_test.c (100%) rename applications/{tests => unit_tests}/minunit_vars.h (100%) rename applications/{tests => unit_tests}/minunit_vars_ex.h (100%) rename applications/{tests => unit_tests}/rpc/rpc_test.c (100%) rename applications/{tests => unit_tests}/storage/storage_test.c (100%) rename applications/{tests => unit_tests}/stream/stream_test.c (100%) create mode 100644 applications/unit_tests/subghz/subghz_test.c rename applications/{tests => unit_tests}/test_index.c (93%) create mode 100644 assets/unit_tests/subghz/came.sub create mode 100644 assets/unit_tests/subghz/came_atomo_raw.sub create mode 100644 assets/unit_tests/subghz/came_raw.sub create mode 100644 assets/unit_tests/subghz/came_twee.sub create mode 100644 assets/unit_tests/subghz/came_twee_raw.sub create mode 100644 assets/unit_tests/subghz/cenmax_raw.sub create mode 100644 assets/unit_tests/subghz/doorhan.sub create mode 100644 assets/unit_tests/subghz/doorhan_raw.sub create mode 100644 assets/unit_tests/subghz/faac_slh_raw.sub create mode 100644 assets/unit_tests/subghz/gate_tx.sub create mode 100644 assets/unit_tests/subghz/gate_tx_raw.sub create mode 100644 assets/unit_tests/subghz/hormann_hsm_raw.sub create mode 100644 assets/unit_tests/subghz/ido_117_111_raw.sub create mode 100644 assets/unit_tests/subghz/kia_seed_raw.sub create mode 100644 assets/unit_tests/subghz/nero_radio_raw.sub create mode 100644 assets/unit_tests/subghz/nero_sketch_raw.sub create mode 100644 assets/unit_tests/subghz/nice_flo.sub create mode 100644 assets/unit_tests/subghz/nice_flo_raw.sub create mode 100644 assets/unit_tests/subghz/nice_flor_s_raw.sub create mode 100644 assets/unit_tests/subghz/princeton.sub create mode 100644 assets/unit_tests/subghz/princeton_raw.sub create mode 100644 assets/unit_tests/subghz/scher_khan_magic_code.sub create mode 100644 assets/unit_tests/subghz/somfy_keytis_raw.sub create mode 100644 assets/unit_tests/subghz/somfy_telis_raw.sub create mode 100644 assets/unit_tests/subghz/test_random_raw.sub diff --git a/applications/subghz/subghz_cli.c b/applications/subghz/subghz_cli.c index 143016a1955..6928c4bac25 100644 --- a/applications/subghz/subghz_cli.c +++ b/applications/subghz/subghz_cli.c @@ -9,6 +9,7 @@ #include #include +#include #include "helpers/subghz_chat.h" @@ -294,6 +295,110 @@ void subghz_cli_command_rx(Cli* cli, string_t args, void* context) { free(instance); } +void subghz_cli_command_decode_raw(Cli* cli, string_t args, void* context) { + string_t file_name; + string_init(file_name); + string_set(file_name, "/any/subghz/test.sub"); + + Storage* storage = furi_record_open("storage"); + FlipperFormat* fff_data_file = flipper_format_file_alloc(storage); + string_t temp_str; + string_init(temp_str); + uint32_t temp_data32; + bool check_file = false; + + do { + if(string_size(args)) { + if(!args_read_string_and_trim(args, file_name)) { + cli_print_usage( + "subghz decode_raw", "", string_get_cstr(args)); + break; + } + } + + if(!flipper_format_file_open_existing(fff_data_file, string_get_cstr(file_name))) { + printf( + "subghz decode_raw \033[0;31mError open file\033[0m %s\r\n", + string_get_cstr(file_name)); + break; + } + + if(!flipper_format_read_header(fff_data_file, temp_str, &temp_data32)) { + printf("subghz decode_raw \033[0;31mMissing or incorrect header\033[0m\r\n"); + break; + } + + if(!strcmp(string_get_cstr(temp_str), SUBGHZ_RAW_FILE_TYPE) && + temp_data32 == SUBGHZ_KEY_FILE_VERSION) { + } else { + printf("subghz decode_raw \033[0;31mType or version mismatch\033[0m\r\n"); + break; + } + + check_file = true; + } while(false); + + string_clear(temp_str); + flipper_format_free(fff_data_file); + furi_record_close("storage"); + + if(check_file) { + // Allocate context + SubGhzCliCommandRx* instance = malloc(sizeof(SubGhzCliCommandRx)); + + SubGhzEnvironment* environment = subghz_environment_alloc(); + if(subghz_environment_load_keystore(environment, "/ext/subghz/assets/keeloq_mfcodes")) { + printf("SubGhz test: Load_keystore \033[0;32mOK\033[0m\r\n"); + } else { + printf("SubGhz test: Load_keystore \033[0;31mERROR\033[0m\r\n"); + } + subghz_environment_set_came_atomo_rainbow_table_file_name( + environment, "/ext/subghz/assets/came_atomo"); + subghz_environment_set_nice_flor_s_rainbow_table_file_name( + environment, "/ext/subghz/assets/nice_flor_s"); + + SubGhzReceiver* receiver = subghz_receiver_alloc_init(environment); + subghz_receiver_set_filter(receiver, SubGhzProtocolFlag_Decodable); + subghz_receiver_set_rx_callback(receiver, subghz_cli_command_rx_callback, instance); + + SubGhzFileEncoderWorker* file_worker_encoder = subghz_file_encoder_worker_alloc(); + if(subghz_file_encoder_worker_start(file_worker_encoder, string_get_cstr(file_name))) { + //the worker needs a file in order to open and read part of the file + osDelay(100); + } + + printf( + "Listening at \033[0;33m%s\033[0m.\r\n\r\nPress CTRL+C to stop\r\n\r\n", + string_get_cstr(file_name)); + + LevelDuration level_duration; + while(!cli_cmd_interrupt_received(cli)) { + furi_hal_delay_us(500); //you need to have time to read from the file from the SD card + level_duration = subghz_file_encoder_worker_get_level_duration(file_worker_encoder); + if(!level_duration_is_reset(level_duration)) { + bool level = level_duration_get_level(level_duration); + uint32_t duration = level_duration_get_duration(level_duration); + subghz_receiver_decode(receiver, level, duration); + } else { + break; + } + } + + printf("\r\nPackets recieved \033[0;32m%u\033[0m\r\n", instance->packet_count); + + // Cleanup + subghz_receiver_free(receiver); + subghz_environment_free(environment); + + if(subghz_file_encoder_worker_is_running(file_worker_encoder)) { + subghz_file_encoder_worker_stop(file_worker_encoder); + } + subghz_file_encoder_worker_free(file_worker_encoder); + free(instance); + } + string_clear(file_name); +} + static void subghz_cli_command_print_usage() { printf("Usage:\r\n"); printf("subghz \r\n"); @@ -303,6 +408,7 @@ static void subghz_cli_command_print_usage() { printf( "\ttx <3 byte Key: in hex> \t - Transmitting key\r\n"); printf("\trx \t - Reception key\r\n"); + printf("\tdecode_raw \t - Testing\r\n"); if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)) { printf("\r\n"); @@ -595,6 +701,12 @@ static void subghz_cli_command(Cli* cli, string_t args, void* context) { subghz_cli_command_rx(cli, args, context); break; } + + if(string_cmp_str(cmd, "decode_raw") == 0) { + subghz_cli_command_decode_raw(cli, args, context); + break; + } + if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)) { if(string_cmp_str(cmd, "encrypt_keeloq") == 0) { subghz_cli_command_encrypt_keeloq(cli, args); diff --git a/applications/subghz/subghz_i.h b/applications/subghz/subghz_i.h index b2d7df71a36..9ef1ee54009 100644 --- a/applications/subghz/subghz_i.h +++ b/applications/subghz/subghz_i.h @@ -33,7 +33,7 @@ #include -#define SUBGHZ_MAX_LEN_NAME 21 +#define SUBGHZ_MAX_LEN_NAME 40 extern const char* const subghz_frequencies_text[]; extern const uint32_t subghz_frequencies[]; diff --git a/applications/tests/flipper_format/flipper_format_string_test.c b/applications/unit_tests/flipper_format/flipper_format_string_test.c similarity index 100% rename from applications/tests/flipper_format/flipper_format_string_test.c rename to applications/unit_tests/flipper_format/flipper_format_string_test.c diff --git a/applications/tests/flipper_format/flipper_format_test.c b/applications/unit_tests/flipper_format/flipper_format_test.c similarity index 100% rename from applications/tests/flipper_format/flipper_format_test.c rename to applications/unit_tests/flipper_format/flipper_format_test.c diff --git a/applications/tests/furi_memmgr_test.c b/applications/unit_tests/furi_memmgr_test.c similarity index 100% rename from applications/tests/furi_memmgr_test.c rename to applications/unit_tests/furi_memmgr_test.c diff --git a/applications/tests/furi_pubsub_test.c b/applications/unit_tests/furi_pubsub_test.c similarity index 100% rename from applications/tests/furi_pubsub_test.c rename to applications/unit_tests/furi_pubsub_test.c diff --git a/applications/tests/furi_record_test.c b/applications/unit_tests/furi_record_test.c similarity index 100% rename from applications/tests/furi_record_test.c rename to applications/unit_tests/furi_record_test.c diff --git a/applications/tests/furi_valuemutex_test.c b/applications/unit_tests/furi_valuemutex_test.c similarity index 100% rename from applications/tests/furi_valuemutex_test.c rename to applications/unit_tests/furi_valuemutex_test.c diff --git a/applications/tests/infrared_decoder_encoder/infrared_decoder_encoder_test.c b/applications/unit_tests/infrared_decoder_encoder/infrared_decoder_encoder_test.c similarity index 100% rename from applications/tests/infrared_decoder_encoder/infrared_decoder_encoder_test.c rename to applications/unit_tests/infrared_decoder_encoder/infrared_decoder_encoder_test.c diff --git a/applications/tests/infrared_decoder_encoder/test_data/infrared_nec_test_data.srcdata b/applications/unit_tests/infrared_decoder_encoder/test_data/infrared_nec_test_data.srcdata similarity index 100% rename from applications/tests/infrared_decoder_encoder/test_data/infrared_nec_test_data.srcdata rename to applications/unit_tests/infrared_decoder_encoder/test_data/infrared_nec_test_data.srcdata diff --git a/applications/tests/infrared_decoder_encoder/test_data/infrared_necext_test_data.srcdata b/applications/unit_tests/infrared_decoder_encoder/test_data/infrared_necext_test_data.srcdata similarity index 100% rename from applications/tests/infrared_decoder_encoder/test_data/infrared_necext_test_data.srcdata rename to applications/unit_tests/infrared_decoder_encoder/test_data/infrared_necext_test_data.srcdata diff --git a/applications/tests/infrared_decoder_encoder/test_data/infrared_rc5_test_data.srcdata b/applications/unit_tests/infrared_decoder_encoder/test_data/infrared_rc5_test_data.srcdata similarity index 100% rename from applications/tests/infrared_decoder_encoder/test_data/infrared_rc5_test_data.srcdata rename to applications/unit_tests/infrared_decoder_encoder/test_data/infrared_rc5_test_data.srcdata diff --git a/applications/tests/infrared_decoder_encoder/test_data/infrared_rc6_test_data.srcdata b/applications/unit_tests/infrared_decoder_encoder/test_data/infrared_rc6_test_data.srcdata similarity index 100% rename from applications/tests/infrared_decoder_encoder/test_data/infrared_rc6_test_data.srcdata rename to applications/unit_tests/infrared_decoder_encoder/test_data/infrared_rc6_test_data.srcdata diff --git a/applications/tests/infrared_decoder_encoder/test_data/infrared_samsung_test_data.srcdata b/applications/unit_tests/infrared_decoder_encoder/test_data/infrared_samsung_test_data.srcdata similarity index 100% rename from applications/tests/infrared_decoder_encoder/test_data/infrared_samsung_test_data.srcdata rename to applications/unit_tests/infrared_decoder_encoder/test_data/infrared_samsung_test_data.srcdata diff --git a/applications/tests/infrared_decoder_encoder/test_data/infrared_sirc_test_data.srcdata b/applications/unit_tests/infrared_decoder_encoder/test_data/infrared_sirc_test_data.srcdata similarity index 100% rename from applications/tests/infrared_decoder_encoder/test_data/infrared_sirc_test_data.srcdata rename to applications/unit_tests/infrared_decoder_encoder/test_data/infrared_sirc_test_data.srcdata diff --git a/applications/tests/minunit.h b/applications/unit_tests/minunit.h similarity index 100% rename from applications/tests/minunit.h rename to applications/unit_tests/minunit.h diff --git a/applications/tests/minunit_test.c b/applications/unit_tests/minunit_test.c similarity index 100% rename from applications/tests/minunit_test.c rename to applications/unit_tests/minunit_test.c diff --git a/applications/tests/minunit_vars.h b/applications/unit_tests/minunit_vars.h similarity index 100% rename from applications/tests/minunit_vars.h rename to applications/unit_tests/minunit_vars.h diff --git a/applications/tests/minunit_vars_ex.h b/applications/unit_tests/minunit_vars_ex.h similarity index 100% rename from applications/tests/minunit_vars_ex.h rename to applications/unit_tests/minunit_vars_ex.h diff --git a/applications/tests/rpc/rpc_test.c b/applications/unit_tests/rpc/rpc_test.c similarity index 100% rename from applications/tests/rpc/rpc_test.c rename to applications/unit_tests/rpc/rpc_test.c diff --git a/applications/tests/storage/storage_test.c b/applications/unit_tests/storage/storage_test.c similarity index 100% rename from applications/tests/storage/storage_test.c rename to applications/unit_tests/storage/storage_test.c diff --git a/applications/tests/stream/stream_test.c b/applications/unit_tests/stream/stream_test.c similarity index 100% rename from applications/tests/stream/stream_test.c rename to applications/unit_tests/stream/stream_test.c diff --git a/applications/unit_tests/subghz/subghz_test.c b/applications/unit_tests/subghz/subghz_test.c new file mode 100644 index 00000000000..48613868d30 --- /dev/null +++ b/applications/unit_tests/subghz/subghz_test.c @@ -0,0 +1,404 @@ +#include +#include +#include "../minunit.h" +#include +#include +#include +#include +#include +#include + +#define TAG "SubGhz TEST" +#define KEYSTORE_DIR_NAME "/ext/subghz/assets/keeloq_mfcodes" +#define CAME_ATOMO_DIR_NAME "/ext/subghz/assets/came_atomo" +#define NICE_FLOR_S_DIR_NAME "/ext/subghz/assets/nice_flor_s" +#define TEST_RANDOM_DIR_NAME "/ext/unit_tests/subghz/test_random_raw.sub" +#define TEST_RANDOM_COUNT_PARSE 101 +#define TEST_TIMEOUT 10000 + +static SubGhzEnvironment* environment_handler; +static SubGhzReceiver* receiver_handler; +//static SubGhzTransmitter* transmitter_handler; +static SubGhzFileEncoderWorker* file_worker_encoder_handler; +static uint16_t subghz_test_decoder_count = 0; + +static void subghz_test_rx_callback( + SubGhzReceiver* receiver, + SubGhzProtocolDecoderBase* decoder_base, + void* context) { + string_t text; + string_init(text); + subghz_protocol_decoder_base_get_string(decoder_base, text); + FURI_LOG_I(TAG, "\r\n%s", string_get_cstr(text)); + string_clear(text); + subghz_test_decoder_count++; +} + +static void subghz_test_init(void) { + environment_handler = subghz_environment_alloc(); + subghz_environment_set_came_atomo_rainbow_table_file_name( + environment_handler, CAME_ATOMO_DIR_NAME); + subghz_environment_set_nice_flor_s_rainbow_table_file_name( + environment_handler, NICE_FLOR_S_DIR_NAME); + + receiver_handler = subghz_receiver_alloc_init(environment_handler); + subghz_receiver_set_filter(receiver_handler, SubGhzProtocolFlag_Decodable); + subghz_receiver_set_rx_callback(receiver_handler, subghz_test_rx_callback, NULL); +} + +static void subghz_test_deinit(void) { + subghz_receiver_free(receiver_handler); + subghz_environment_free(environment_handler); +} + +static bool subghz_decode_test(const char* path, const char* name_decoder) { + subghz_test_decoder_count = 0; + uint32_t test_start = furi_hal_get_tick(); + + SubGhzProtocolDecoderBase* decoder = + subghz_receiver_search_decoder_base_by_name(receiver_handler, name_decoder); + + if(decoder) { + file_worker_encoder_handler = subghz_file_encoder_worker_alloc(); + if(subghz_file_encoder_worker_start(file_worker_encoder_handler, path)) { + //the worker needs a file in order to open and read part of the file + osDelay(100); + + LevelDuration level_duration; + while(furi_hal_get_tick() - test_start < TEST_TIMEOUT) { + furi_hal_delay_us( + 500); //you need to have time to read from the file from the SD card + level_duration = + subghz_file_encoder_worker_get_level_duration(file_worker_encoder_handler); + if(!level_duration_is_reset(level_duration)) { + bool level = level_duration_get_level(level_duration); + uint32_t duration = level_duration_get_duration(level_duration); + decoder->protocol->decoder->feed(decoder, level, duration); + } else { + break; + } + } + furi_hal_delay_ms(10); + } + if(subghz_file_encoder_worker_is_running(file_worker_encoder_handler)) { + subghz_file_encoder_worker_stop(file_worker_encoder_handler); + } + subghz_file_encoder_worker_free(file_worker_encoder_handler); + } + FURI_LOG_I(TAG, "\r\n Decoder count parse \033[0;33m%d\033[0m ", subghz_test_decoder_count); + if(furi_hal_get_tick() - test_start > TEST_TIMEOUT) { + printf("\033[0;31mTest decoder %s ERROR TimeOut\033[0m\r\n", name_decoder); + return false; + } else { + return subghz_test_decoder_count ? true : false; + } +} + +static bool subghz_decode_ramdom_test(const char* path) { + subghz_test_decoder_count = 0; + subghz_receiver_reset(receiver_handler); + uint32_t test_start = furi_hal_get_tick(); + + file_worker_encoder_handler = subghz_file_encoder_worker_alloc(); + if(subghz_file_encoder_worker_start(file_worker_encoder_handler, path)) { + //the worker needs a file in order to open and read part of the file + osDelay(100); + + LevelDuration level_duration; + while(furi_hal_get_tick() - test_start < TEST_TIMEOUT * 10) { + furi_hal_delay_us(500); //you need to have time to read from the file from the SD card + level_duration = + subghz_file_encoder_worker_get_level_duration(file_worker_encoder_handler); + if(!level_duration_is_reset(level_duration)) { + bool level = level_duration_get_level(level_duration); + uint32_t duration = level_duration_get_duration(level_duration); + subghz_receiver_decode(receiver_handler, level, duration); + } else { + break; + } + } + furi_hal_delay_ms(10); + if(subghz_file_encoder_worker_is_running(file_worker_encoder_handler)) { + subghz_file_encoder_worker_stop(file_worker_encoder_handler); + } + subghz_file_encoder_worker_free(file_worker_encoder_handler); + } + FURI_LOG_I(TAG, "\r\n Decoder count parse \033[0;33m%d\033[0m ", subghz_test_decoder_count); + if(furi_hal_get_tick() - test_start > TEST_TIMEOUT * 10) { + printf("\033[0;31mRandom test ERROR TimeOut\033[0m\r\n"); + return false; + } else if(subghz_test_decoder_count == TEST_RANDOM_COUNT_PARSE) { + return true; + } else { + return false; + } +} + +static bool subghz_ecode_test(const char* path) { + subghz_test_decoder_count = 0; + uint32_t test_start = furi_hal_get_tick(); + string_t temp_str; + string_init(temp_str); + bool file_load = false; + + Storage* storage = furi_record_open("storage"); + FlipperFormat* fff_data_file = flipper_format_file_alloc(storage); + + do { + if(!flipper_format_file_open_existing(fff_data_file, path)) { + FURI_LOG_E(TAG, "Error open file %s", path); + break; + } + + if(!flipper_format_read_string(fff_data_file, "Preset", temp_str)) { + FURI_LOG_E(TAG, "Missing Preset"); + break; + } + + if(!flipper_format_read_string(fff_data_file, "Protocol", temp_str)) { + FURI_LOG_E(TAG, "Missing Protocol"); + break; + } + file_load = true; + } while(false); + if(file_load) { + SubGhzTransmitter* transmitter = + subghz_transmitter_alloc_init(environment_handler, string_get_cstr(temp_str)); + subghz_transmitter_deserialize(transmitter, fff_data_file); + + SubGhzProtocolDecoderBase* decoder = subghz_receiver_search_decoder_base_by_name( + receiver_handler, string_get_cstr(temp_str)); + + if(decoder) { + LevelDuration level_duration; + while(furi_hal_get_tick() - test_start < TEST_TIMEOUT) { + level_duration = subghz_transmitter_yield(transmitter); + if(!level_duration_is_reset(level_duration)) { + bool level = level_duration_get_level(level_duration); + uint32_t duration = level_duration_get_duration(level_duration); + decoder->protocol->decoder->feed(decoder, level, duration); + } else { + break; + } + } + furi_hal_delay_ms(10); + } + subghz_transmitter_free(transmitter); + } + flipper_format_free(fff_data_file); + FURI_LOG_I(TAG, "\r\n Decoder count parse \033[0;33m%d\033[0m ", subghz_test_decoder_count); + if(furi_hal_get_tick() - test_start > TEST_TIMEOUT) { + printf("\033[0;31mTest encoder %s ERROR TimeOut\033[0m\r\n", string_get_cstr(temp_str)); + subghz_test_decoder_count = 0; + } + string_clear(temp_str); + + return subghz_test_decoder_count ? true : false; +} + +MU_TEST(subghz_keystore_test) { + mu_assert( + subghz_environment_load_keystore(environment_handler, KEYSTORE_DIR_NAME), + "Test keystore error"); +} + +MU_TEST(subghz_decoder_came_atomo_test) { + mu_assert( + subghz_decode_test( + "/ext/unit_tests/subghz/came_atomo_raw.sub", SUBGHZ_PROTOCOL_CAME_ATOMO_NAME), + "Test decoder " SUBGHZ_PROTOCOL_CAME_ATOMO_NAME " error\r\n"); +} + +MU_TEST(subghz_decoder_came_test) { + mu_assert( + subghz_decode_test("/ext/unit_tests/subghz/came_raw.sub", SUBGHZ_PROTOCOL_CAME_NAME), + "Test decoder " SUBGHZ_PROTOCOL_CAME_NAME " error\r\n"); +} + +MU_TEST(subghz_decoder_came_twee_test) { + mu_assert( + subghz_decode_test( + "/ext/unit_tests/subghz/came_twee_raw.sub", SUBGHZ_PROTOCOL_CAME_TWEE_NAME), + "Test decoder " SUBGHZ_PROTOCOL_CAME_TWEE_NAME " error\r\n"); +} + +MU_TEST(subghz_decoder_faac_slh_test) { + mu_assert( + subghz_decode_test( + "/ext/unit_tests/subghz/faac_slh_raw.sub", SUBGHZ_PROTOCOL_FAAC_SLH_NAME), + "Test decoder " SUBGHZ_PROTOCOL_FAAC_SLH_NAME " error\r\n"); +} + +MU_TEST(subghz_decoder_gate_tx_test) { + mu_assert( + subghz_decode_test("/ext/unit_tests/subghz/gate_tx_raw.sub", SUBGHZ_PROTOCOL_GATE_TX_NAME), + "Test decoder " SUBGHZ_PROTOCOL_GATE_TX_NAME " error\r\n"); +} + +MU_TEST(subghz_decoder_hormann_hsm_test) { + mu_assert( + subghz_decode_test( + "/ext/unit_tests/subghz/hormann_hsm_raw.sub", SUBGHZ_PROTOCOL_HORMANN_HSM_NAME), + "Test decoder " SUBGHZ_PROTOCOL_HORMANN_HSM_NAME " error\r\n"); +} + +MU_TEST(subghz_decoder_ido_test) { + mu_assert( + subghz_decode_test("/ext/unit_tests/subghz/ido_117_111_raw.sub", SUBGHZ_PROTOCOL_IDO_NAME), + "Test decoder " SUBGHZ_PROTOCOL_IDO_NAME " error\r\n"); +} + +MU_TEST(subghz_decoder_keelog_test) { + mu_assert( + subghz_decode_test("/ext/unit_tests/subghz/doorhan_raw.sub", SUBGHZ_PROTOCOL_KEELOQ_NAME), + "Test decoder " SUBGHZ_PROTOCOL_KEELOQ_NAME " error\r\n"); +} + +MU_TEST(subghz_decoder_kia_seed_test) { + mu_assert( + subghz_decode_test("/ext/unit_tests/subghz/kia_seed_raw.sub", SUBGHZ_PROTOCOL_KIA_NAME), + "Test decoder " SUBGHZ_PROTOCOL_KIA_NAME " error\r\n"); +} + +MU_TEST(subghz_decoder_nero_radio_test) { + mu_assert( + subghz_decode_test( + "/ext/unit_tests/subghz/nero_radio_raw.sub", SUBGHZ_PROTOCOL_NERO_RADIO_NAME), + "Test decoder " SUBGHZ_PROTOCOL_NERO_RADIO_NAME " error\r\n"); +} + +MU_TEST(subghz_decoder_nero_sketch_test) { + mu_assert( + subghz_decode_test( + "/ext/unit_tests/subghz/nero_sketch_raw.sub", SUBGHZ_PROTOCOL_NERO_SKETCH_NAME), + "Test decoder " SUBGHZ_PROTOCOL_NERO_SKETCH_NAME " error\r\n"); +} + +MU_TEST(subghz_decoder_nice_flo_test) { + mu_assert( + subghz_decode_test( + "/ext/unit_tests/subghz/nice_flo_raw.sub", SUBGHZ_PROTOCOL_NICE_FLO_NAME), + "Test decoder " SUBGHZ_PROTOCOL_NICE_FLO_NAME " error\r\n"); +} + +MU_TEST(subghz_decoder_nice_flor_s_test) { + mu_assert( + subghz_decode_test( + "/ext/unit_tests/subghz/nice_flor_s_raw.sub", SUBGHZ_PROTOCOL_NICE_FLOR_S_NAME), + "Test decoder " SUBGHZ_PROTOCOL_NICE_FLOR_S_NAME " error\r\n"); +} + +MU_TEST(subghz_decoder_princeton_test) { + mu_assert( + subghz_decode_test( + "/ext/unit_tests/subghz/Princeton_raw.sub", SUBGHZ_PROTOCOL_PRINCETON_NAME), + "Test decoder " SUBGHZ_PROTOCOL_PRINCETON_NAME " error\r\n"); +} + +MU_TEST(subghz_decoder_scher_khan_magic_code_test) { + mu_assert( + subghz_decode_test( + "/ext/unit_tests/subghz/scher_khan_magic_code.sub", SUBGHZ_PROTOCOL_SCHER_KHAN_NAME), + "Test decoder " SUBGHZ_PROTOCOL_SCHER_KHAN_NAME " error\r\n"); +} + +MU_TEST(subghz_decoder_somfy_keytis_test) { + mu_assert( + subghz_decode_test( + "/ext/unit_tests/subghz/Somfy_keytis_raw.sub", SUBGHZ_PROTOCOL_SOMFY_KEYTIS_NAME), + "Test decoder " SUBGHZ_PROTOCOL_SOMFY_KEYTIS_NAME " error\r\n"); +} + +MU_TEST(subghz_decoder_somfy_telis_test) { + mu_assert( + subghz_decode_test( + "/ext/unit_tests/subghz/somfy_telis_raw.sub", SUBGHZ_PROTOCOL_SOMFY_TELIS_NAME), + "Test decoder " SUBGHZ_PROTOCOL_SOMFY_TELIS_NAME " error\r\n"); +} + +MU_TEST(subghz_decoder_star_line_test) { + mu_assert( + subghz_decode_test("/ext/unit_tests/subghz/cenmax_raw.sub", SUBGHZ_PROTOCOL_STAR_LINE_NAME), + "Test decoder " SUBGHZ_PROTOCOL_STAR_LINE_NAME " error\r\n"); +} + +MU_TEST(subghz_ecoder_princeton_test) { + mu_assert( + subghz_ecode_test("/ext/unit_tests/subghz/princeton.sub"), + "Test encoder " SUBGHZ_PROTOCOL_PRINCETON_NAME " error\r\n"); +} + +MU_TEST(subghz_ecoder_came_test) { + mu_assert( + subghz_ecode_test("/ext/unit_tests/subghz/came.sub"), + "Test encoder " SUBGHZ_PROTOCOL_CAME_NAME " error\r\n"); +} + +MU_TEST(subghz_ecoder_came_twee_test) { + mu_assert( + subghz_ecode_test("/ext/unit_tests/subghz/came_twee.sub"), + "Test encoder " SUBGHZ_PROTOCOL_CAME_TWEE_NAME " error\r\n"); +} + +MU_TEST(subghz_ecoder_gate_tx_test) { + mu_assert( + subghz_ecode_test("/ext/unit_tests/subghz/gate_tx.sub"), + "Test encoder " SUBGHZ_PROTOCOL_GATE_TX_NAME " error\r\n"); +} + +MU_TEST(subghz_ecoder_nice_flo_test) { + mu_assert( + subghz_ecode_test("/ext/unit_tests/subghz/nice_flo.sub"), + "Test encoder " SUBGHZ_PROTOCOL_NICE_FLO_NAME " error\r\n"); +} + +MU_TEST(subghz_ecoder_keelog_test) { + mu_assert( + subghz_ecode_test("/ext/unit_tests/subghz/doorhan.sub"), + "Test encoder " SUBGHZ_PROTOCOL_KEELOQ_NAME " error\r\n"); +} + +MU_TEST(subghz_random_test) { + mu_assert(subghz_decode_ramdom_test(TEST_RANDOM_DIR_NAME), "Random test error\r\n"); +} + +MU_TEST_SUITE(subghz) { + //MU_SUITE_CONFIGURE(&subghz_test_init, &subghz_test_deinit); + + subghz_test_init(); + MU_RUN_TEST(subghz_keystore_test); + + MU_RUN_TEST(subghz_decoder_came_atomo_test); + MU_RUN_TEST(subghz_decoder_came_test); + MU_RUN_TEST(subghz_decoder_came_twee_test); + MU_RUN_TEST(subghz_decoder_faac_slh_test); + MU_RUN_TEST(subghz_decoder_gate_tx_test); + MU_RUN_TEST(subghz_decoder_hormann_hsm_test); + MU_RUN_TEST(subghz_decoder_ido_test); + MU_RUN_TEST(subghz_decoder_keelog_test); + MU_RUN_TEST(subghz_decoder_kia_seed_test); + MU_RUN_TEST(subghz_decoder_nero_radio_test); + MU_RUN_TEST(subghz_decoder_nero_sketch_test); + MU_RUN_TEST(subghz_decoder_nice_flo_test); + MU_RUN_TEST(subghz_decoder_nice_flor_s_test); + MU_RUN_TEST(subghz_decoder_princeton_test); + MU_RUN_TEST(subghz_decoder_scher_khan_magic_code_test); + MU_RUN_TEST(subghz_decoder_somfy_keytis_test); + MU_RUN_TEST(subghz_decoder_somfy_telis_test); + MU_RUN_TEST(subghz_decoder_star_line_test); + + MU_RUN_TEST(subghz_ecoder_princeton_test); + MU_RUN_TEST(subghz_ecoder_came_test); + MU_RUN_TEST(subghz_ecoder_came_twee_test); + MU_RUN_TEST(subghz_ecoder_gate_tx_test); + MU_RUN_TEST(subghz_ecoder_nice_flo_test); + MU_RUN_TEST(subghz_ecoder_keelog_test); + + MU_RUN_TEST(subghz_random_test); + subghz_test_deinit(); +} + +int run_minunit_test_subghz() { + MU_RUN_SUITE(subghz); + return MU_EXIT_CODE; +} diff --git a/applications/tests/test_index.c b/applications/unit_tests/test_index.c similarity index 93% rename from applications/tests/test_index.c rename to applications/unit_tests/test_index.c index 16e75414745..ef12224c013 100644 --- a/applications/tests/test_index.c +++ b/applications/unit_tests/test_index.c @@ -17,6 +17,7 @@ int run_minunit_test_flipper_format(); int run_minunit_test_flipper_format_string(); int run_minunit_test_stream(); int run_minunit_test_storage(); +int run_minunit_test_subghz(); void minunit_print_progress(void) { static char progress[] = {'\\', '|', '/', '-'}; @@ -51,7 +52,7 @@ void unit_tests_cli(Cli* cli, string_t args, void* context) { notification_message_block(notification, &sequence_set_only_blue_255); uint32_t heap_before = memmgr_get_free_heap(); - uint32_t cycle_counter = DWT->CYCCNT; + uint32_t cycle_counter = furi_hal_get_tick(); test_result |= run_minunit(); test_result |= run_minunit_test_storage(); @@ -60,9 +61,11 @@ void unit_tests_cli(Cli* cli, string_t args, void* context) { test_result |= run_minunit_test_flipper_format_string(); test_result |= run_minunit_test_infrared_decoder_encoder(); test_result |= run_minunit_test_rpc(); - cycle_counter = (DWT->CYCCNT - cycle_counter); + test_result |= run_minunit_test_subghz(); - FURI_LOG_I(TAG, "Consumed: %0.2fs", (float)cycle_counter / (SystemCoreClock)); + cycle_counter = (furi_hal_get_tick() - cycle_counter); + + FURI_LOG_I(TAG, "Consumed: %0.2fs", (float)cycle_counter / 1000); if(test_result == 0) { furi_hal_delay_ms(200); /* wait for tested services and apps to deallocate */ diff --git a/assets/unit_tests/subghz/came.sub b/assets/unit_tests/subghz/came.sub new file mode 100644 index 00000000000..04f4365a366 --- /dev/null +++ b/assets/unit_tests/subghz/came.sub @@ -0,0 +1,7 @@ +Filetype: Flipper SubGhz Key File +Version: 1 +Frequency: 433920000 +Preset: FuriHalSubGhzPresetOok650Async +Protocol: CAME +Bit: 24 +Key: 00 00 00 00 00 6A B2 34 diff --git a/assets/unit_tests/subghz/came_atomo_raw.sub b/assets/unit_tests/subghz/came_atomo_raw.sub new file mode 100644 index 00000000000..9706425c1e0 --- /dev/null +++ b/assets/unit_tests/subghz/came_atomo_raw.sub @@ -0,0 +1,8 @@ +Filetype: Flipper SubGhz RAW File +Version: 1 +Frequency: 433920000 +Preset: FuriHalSubGhzPresetOok650Async +Protocol: RAW +RAW_Data: 65 -4082 1356 -4436 197 -1394 65 -2280 67 -3048 165 -232 99 -7272 99 -958 65 -430 63 -2178 65 -2420 65 -6736 131 -4170 67 -4244 99 -1392 97 -5958 65 -1050 97 -5974 65 -2456 165 -1664 99 -13162 65 -3350 67 -1066 67 -98 65 -2668 63 -294 199 -1648 99 -2418 99 -916 99 -934 131 -102 97 -828 67 -964 65 -1644 263 -398 131 -1486 99 -7252 65 -432 65 -1752 99 -5028 331 -698 65 -266 199 -898 163 -916 65 -958 163 -268 97 -5754 131 -928 65 -2524 131 -1100 99 -1848 65 -3168 131 -6354 67 -1198 65 -1452 67 -6396 167 -3714 65 -4624 67 -464 99 -2326 63 -6984 97 -4866 67 -5602 99 -362 65 -1646 131 -6196 199 -5974 131 -798 199 -6046 97 -666 165 -630 99 -4796 99 -3394 129 -1282 221 -10562 1227 -558 609 -606 609 -586 581 -628 579 -600 575 -1224 1155 -1224 1155 -628 579 -622 583 -584 577 -620 589 -614 571 -1214 577 -602 1173 -1206 1173 -612 599 -584 599 -614 561 -616 587 -1216 1169 -620 581 -612 575 -1184 1197 -588 583 -1202 1199 -1204 575 -624 579 -588 1177 -1204 1177 -1206 1179 -608 585 -1212 1181 -620 581 -1184 1195 -588 609 -1182 581 -608 1205 -580 601 -1180 613 -598 1175 -612 595 -580 605 -580 603 -610 573 -616 575 -608 589 -77180 471 -4430 389 -796 387 -818 623 -198 131 -1440 991 -726 485 -668 539 -660 517 -668 539 -660 517 -666 539 -628 583 -1198 1181 -1198 587 -616 573 -618 1183 -598 579 -1214 585 -610 577 -588 1205 -1182 1207 -1166 615 -578 1215 -580 603 -1182 611 -598 581 -602 579 -592 613 -590 1179 -1206 587 -614 577 -610 591 -580 1201 -1180 607 -586 595 -612 1195 -590 579 -608 613 -1180 587 -612 1167 -1206 1197 -598 579 -622 581 -1178 1193 -592 613 -590 587 -77184 1223 -582 613 -1184 579 -608 611 -588 581 -592 1213 -1176 613 -590 1183 -602 579 -622 581 -588 613 -590 587 -1208 569 -614 597 -586 1195 -588 611 -1186 1175 -612 589 -1208 1169 -614 575 -612 591 -1176 611 -590 1209 -1176 579 -610 611 -594 1171 -1204 579 -606 1207 -580 601 -1182 1207 -580 601 -1178 1207 -1174 613 -590 1179 -608 579 -622 579 -1186 1191 -592 613 -1202 583 -612 579 -586 613 -578 1213 -578 601 -1182 1209 -582 601 -578 627 -586 589 -77176 991 -818 365 -1432 355 -834 367 -826 355 -764 1067 -684 531 -674 509 -652 561 -646 545 -618 553 -642 571 -622 553 -1240 1177 -1206 1177 -608 575 -614 561 -1204 1205 -1178 611 -596 1175 -1208 581 -602 1173 -1212 1175 -614 603 -578 601 -580 597 -1208 587 -588 1211 -1170 605 -590 1209 -582 589 -614 575 -1214 575 -622 593 -578 601 -586 1183 -1212 589 -588 613 -578 623 -588 1173 -614 +RAW_Data: 575 -618 583 -1174 1211 -578 609 -1186 601 -586 1193 -590 613 -590 587 -78186 1227 -586 613 -1184 579 -606 609 -574 613 -576 1203 -614 573 -1206 1171 -612 589 -612 575 -608 573 -1210 1197 -1178 603 -580 605 -586 1189 -626 581 -590 617 -1176 1201 -1194 593 -578 603 -610 571 -614 577 -610 1183 -1204 1183 -1200 1185 -1198 1185 -1198 1183 -1200 589 -612 1171 -618 581 -612 577 -588 613 -578 611 -1188 601 -584 601 -582 593 -616 1199 -582 577 -1216 1171 -1216 577 -604 1175 -1208 1207 -578 601 -580 597 -1206 1205 -142854 65 -8644 65 -198 65 -5350 65 -4006 65 -3572 67 -1684 65 -1488 67 -3324 131 -5538 133 -1516 63 -2528 65 -264 65 -3142 65 -884 97 -4344 199 -996 97 -1218 97 -5302 65 -4404 67 -2780 97 -1020 97 -2982 65 -864 65 -1580 65 -98 65 -298 67 -1066 131 -166 65 -4844 65 -2714 63 -6224 65 -98 65 -562 133 -398 133 -66 65 -3956 99 -3784 63 -1056 133 -3548 63 -952 163 -1912 65 -994 165 -2604 97 -4038 133 -6020 65 -632 99 -130 65 -64 65 -98 99 -132 129 -1218 97 -886 97 -164 65 -1680 131 -932 65 -234 97 -564 163 -1856 131 -166 101 -66 99 -6952 131 -3866 63 -66 97 -4254 99 -4154 99 -718 129 -228 197 -4720 99 -496 65 -3784 65 -2768 99 -460 65 -596 65 -234 65 -166 67 -1758 65 -298 97 -3296 163 -328 65 -1150 65 -1246 65 -5224 163 -790 99 -1860 133 -2214 67 -2056 65 -5288 65 -3048 131 -196 197 -10564 1229 -580 603 -586 611 -570 607 -602 579 -598 609 -1192 1201 -1170 1197 -612 573 -606 585 -614 569 -612 599 -578 605 -1206 589 -590 1173 -1220 1171 -622 561 -612 601 -586 599 -1208 1175 -580 627 -582 605 -580 589 -1212 1171 -616 573 -1212 1171 -1214 575 -622 561 -612 1197 -1184 1195 -1184 1199 -590 611 -1172 1211 -578 611 -1180 1183 -624 581 -1184 601 -582 1217 -588 579 -1184 597 -610 1195 -588 611 -578 611 -588 579 -594 611 -608 579 -590 611 -77158 627 -1612 63 -162 63 -786 467 -738 457 -718 1093 -1274 1101 -688 521 -640 535 -688 521 -640 537 -656 551 -638 571 -622 551 -1232 1173 -1208 583 -592 575 -620 1183 -602 575 -640 547 -640 575 -1184 1195 -1182 1199 -1214 575 -612 1185 -598 579 -1194 589 -614 575 -616 583 -614 575 -588 1207 -1184 613 -578 611 -592 577 -606 1207 -1174 587 -622 581 -586 1211 -582 589 -614 575 -1214 575 -622 1157 -1218 1165 -608 613 -586 581 -1186 1191 -594 613 -606 581 -77200 1215 -596 579 -1184 599 -612 595 -586 601 -580 1185 -1198 603 -612 1165 -606 613 -594 577 -602 579 -622 581 -1184 599 -614 595 -584 1197 -586 613 -1182 1173 -610 605 -1182 +RAW_Data: 587 -618 583 -578 1205 -1210 577 -588 1209 -1182 581 -608 611 -588 1175 -1210 581 -592 1207 -582 591 -1212 1175 -612 587 -1184 1201 -1186 601 -586 1195 -588 613 -588 587 -1208 1165 -630 579 -1184 613 -578 611 -592 577 -608 1203 -578 601 -1208 1169 -614 591 -578 605 -586 599 -77194 601 -4244 469 -724 455 -738 1097 -686 501 -678 491 -684 533 -678 525 -650 535 -644 529 -650 563 -1238 1141 -1234 1173 -606 577 -616 571 -1210 1173 -1212 1173 -1210 579 -604 583 -620 1173 -1212 1175 -610 571 -612 599 -580 605 -1206 575 -588 1209 -1184 581 -610 1207 -580 601 -578 597 -1208 577 -622 581 -588 613 -588 1181 -1204 589 -616 575 -588 595 -612 1199 -592 577 -604 579 -1222 1187 -574 615 -1170 607 -588 1207 -582 591 -616 589 -78180 1243 -580 585 -1206 573 -626 583 -590 587 -614 1171 -618 583 -1208 1177 -612 577 -588 613 -578 585 -1216 1179 -1216 583 -578 619 -588 1173 -616 587 -590 613 -1174 1181 -608 611 -586 581 -1216 573 -614 575 -622 1185 -1192 1187 -1196 1189 -1196 1187 -1192 1169 -1202 605 -586 1211 -584 587 -612 573 -618 583 -612 573 -1216 573 -622 561 -612 599 -584 1183 -618 575 -1216 1169 -1206 579 -606 1207 -1172 1203 -580 603 -620 585 -1176 1177 -78216 503 -12116 421 -790 435 -712 483 -1292 1119 -662 541 -1240 525 -642 1161 -1214 575 -614 599 -618 1153 -1224 1151 -630 579 -1214 1175 -1196 1179 -1214 1175 -588 615 -1180 1193 -1180 605 -612 575 -588 597 -610 1195 -1184 603 -588 1195 -586 613 -590 587 -1210 1169 -1206 603 -578 603 -580 1221 -1190 1197 -1174 1183 -1204 1183 -1196 1203 -1170 1199 -133240 99 -1258 131 -3150 229 -100 97 -3048 67 -400 199 -562 99 -2092 231 -300 199 -4556 99 -1878 65 -3834 457 -4170 163 -3484 131 -1380 97 -634 167 -3880 97 -1778 99 -3416 99 -2390 65 -2948 101 -4186 133 -2054 65 -98 65 -164 165 -1154 65 -3114 163 -3102 131 -626 197 -1662 67 -1494 65 -2650 97 -3266 99 -2436 263 -3076 65 -2718 65 -430 165 -68 99 -832 131 -2976 99 -464 97 -134 165 -66 133 -1660 65 -368 131 diff --git a/assets/unit_tests/subghz/came_raw.sub b/assets/unit_tests/subghz/came_raw.sub new file mode 100644 index 00000000000..6c9b565cd3f --- /dev/null +++ b/assets/unit_tests/subghz/came_raw.sub @@ -0,0 +1,9 @@ +Filetype: Flipper SubGhz RAW File +Version: 1 +Frequency: 433920000 +Preset: FuriHalSubGhzPresetOok650Async +Protocol: RAW +RAW_Data: 1601 -32700 381 -296 671 -350 655 -644 343 -332 659 -330 703 -304 697 -314 697 -646 325 -348 647 -646 347 -656 321 -366 621 -23000 351 -324 677 -322 655 -654 335 -352 661 -336 679 -322 689 -296 703 -654 333 -318 665 -634 345 -672 343 -314 661 -22996 359 -306 673 -326 675 -626 359 -352 631 -330 681 -324 681 -344 689 -654 319 -326 645 -678 351 -622 353 -342 621 -23024 345 -304 669 -342 657 -652 325 -352 645 -354 653 -330 703 -346 653 -652 325 -350 649 -646 347 -652 321 -368 607 -23024 351 -322 653 -324 679 -622 363 -354 657 -324 677 -324 677 -346 655 -646 351 -328 679 -644 353 -624 351 -342 639 -22986 349 -328 659 -324 683 -658 329 -350 653 -324 673 -324 681 -342 657 -652 353 -326 653 -646 347 -654 321 -370 607 -23020 351 -324 679 -288 683 -654 367 -322 661 -336 681 -290 717 -310 695 -622 351 -326 679 -642 355 -624 351 -342 625 -23022 315 -366 637 -326 677 -648 345 -312 667 -348 667 -348 669 -334 679 -648 349 -312 667 -654 319 -664 345 -330 623 -23030 355 -312 657 -346 641 -648 351 -348 655 -352 629 -364 645 -354 655 -682 309 -346 637 -678 317 -650 347 -332 645 -23028 359 -324 629 -336 645 -678 349 -346 621 -350 667 -328 677 -324 681 -684 305 -354 629 -660 345 -640 349 -348 623 -23020 379 -354 545 -430 573 -716 273 -420 611 -382 609 -376 643 -372 611 -730 277 -364 611 -714 289 -702 297 -382 605 -23000 371 -304 657 -330 667 -666 321 -346 669 -336 679 -320 691 -296 701 -654 333 -318 667 -654 343 -638 353 -348 623 -22990 371 -324 665 -320 657 -654 333 -350 667 -346 637 -362 645 -354 655 -682 307 -348 635 -678 317 -686 311 -332 647 -23022 359 -324 627 -342 679 -644 351 -314 669 -342 665 -350 667 -312 703 -628 345 -312 665 -650 337 -672 321 -348 635 -23024 339 -326 671 -290 705 -614 375 -320 659 -340 679 -320 691 -296 701 -654 337 -320 667 -654 353 -620 373 -322 625 -23026 335 -322 663 -338 649 -644 387 -316 657 -348 675 -290 703 -324 675 -650 339 -356 629 -654 343 -638 387 -316 623 -22998 347 -342 637 -376 639 -654 343 -316 683 -346 655 -352 661 -334 677 -646 351 -314 655 -646 343 -658 351 -346 621 -22990 365 -360 567 -424 567 -720 269 -446 589 -374 611 -390 631 -392 617 -690 299 -378 609 -692 287 -708 311 -350 613 -23022 355 -314 637 -376 637 -676 317 -354 643 -356 655 -342 655 -350 659 -676 345 -298 685 -626 359 -652 325 -352 611 -23032 345 -304 685 -312 687 -650 325 -316 683 -324 681 -344 655 -354 659 -676 +RAW_Data: 311 -332 679 -618 353 -642 347 -352 619 -23042 307 -336 663 -344 657 -652 325 -352 645 -354 653 -344 657 -352 659 -674 345 -298 683 -626 359 -650 325 -354 615 -23032 349 -304 643 -378 623 -678 325 -352 647 -354 653 -344 655 -352 691 -644 345 -300 681 -624 361 -652 325 -352 617 -23032 387 -328 551 -474 521 -32700 375 -312 657 -344 655 -652 325 -354 677 -320 657 -344 689 -314 667 -688 319 -326 653 -644 349 -654 353 -340 619 -23020 351 -324 645 -354 657 -654 331 -350 667 -312 671 -330 681 -322 717 -616 343 -344 669 -650 325 -642 349 -332 643 -22998 391 -362 563 -402 577 -714 311 -376 621 -378 611 -394 637 -358 655 -688 303 -348 627 -696 311 -686 309 -346 621 -23010 367 -326 663 -320 657 -652 335 -350 667 -346 667 -332 647 -322 717 -648 345 -320 661 -628 347 -654 345 -352 621 -23012 361 -324 659 -322 653 -656 333 -350 667 -312 671 -328 679 -324 717 -648 345 -310 669 -650 325 -644 349 -332 641 -23026 353 -308 665 -310 665 -646 349 -350 647 -322 683 -344 693 -320 693 -644 347 -298 679 -626 361 -648 325 -352 619 -23030 347 -322 645 -322 685 -654 333 -352 665 -310 673 -330 679 -324 715 -648 345 -320 629 -658 345 -638 353 -350 623 -22998 389 -336 577 -408 577 -728 271 -414 625 -354 643 -370 639 -374 641 -674 289 -382 609 -714 311 -680 289 -370 603 -23028 351 -326 681 -288 683 -656 335 -354 659 -334 681 -320 689 -296 703 -654 331 -320 657 -648 353 -660 329 -350 635 -23008 341 -388 547 -428 539 -784 239 -420 579 -414 611 -406 581 -404 611 -724 275 -366 613 -714 289 -702 297 -382 603 -23032 347 -302 679 -310 653 -652 361 -314 681 -324 681 -346 655 -352 661 -674 311 -334 679 -626 359 -646 325 -352 647 -22992 383 -328 557 -440 557 -776 227 -422 575 -422 591 -408 625 -378 621 -706 295 -382 603 -684 305 -714 289 -366 605 -23016 351 -346 637 -326 679 -648 345 -312 697 -316 667 -348 669 -336 679 -644 353 -316 655 -646 345 -658 353 -314 623 -23020 363 -320 669 -322 641 -648 375 -318 659 -340 679 -320 693 -326 673 -656 335 -318 667 -634 345 -672 341 -316 657 -22982 387 -332 581 -408 587 -742 261 -418 609 -356 623 -410 621 -380 623 -706 271 -366 625 -712 293 -678 295 -382 609 -23032 353 -316 655 -324 679 -620 353 -346 669 -326 675 -324 679 -344 655 -678 319 -328 677 -644 353 -624 353 -342 623 -23026 323 -312 681 -324 681 -656 329 -352 629 -364 647 -354 655 -342 691 -656 319 -326 653 -646 349 -654 351 -340 621 -23018 351 -320 +RAW_Data: 647 -324 681 -624 363 -356 661 -298 715 -290 717 -296 701 -622 365 -320 659 -646 353 -626 361 -356 625 -22984 351 -330 657 -324 679 -656 331 -356 661 -332 653 -324 713 -310 691 -624 351 -326 655 -644 351 -658 319 -336 669 -22990 353 -348 617 -354 659 -658 331 -348 635 -376 639 -360 647 -324 683 -684 307 -354 627 -662 347 -654 345 -350 621 -23012 359 -324 629 -362 649 -648 345 -314 667 -350 667 -346 671 -324 673 -646 347 -350 623 -674 345 -622 349 -348 623 -23018 363 -324 659 -320 659 -654 333 -350 667 -346 635 -330 683 -324 715 -614 341 -356 629 -660 349 -654 345 -318 657 -23008 359 -322 627 -354 653 -654 333 -352 661 -334 645 -356 653 -330 703 -656 331 -348 637 -634 345 -672 311 -348 627 -23032 359 -322 659 -308 655 -680 347 -316 667 -314 699 -314 697 -318 671 -670 317 -346 637 -650 375 -636 323 -348 635 -23032 323 -352 641 -322 663 -652 369 -316 665 -348 669 -330 681 -316 689 -648 345 -310 667 -648 325 -646 345 -346 639 -22996 385 -302 675 -310 653 -650 361 -316 677 -324 679 -350 673 -346 651 -654 323 -352 649 -648 345 -654 321 -368 621 -23024 321 -346 653 -324 679 -620 353 -346 655 -324 699 -326 675 -346 653 -656 321 -352 647 -644 351 -664 321 -348 623 -23020 351 -324 647 -324 683 -654 335 -354 661 -334 647 -354 685 -318 675 -638 341 -346 669 -646 317 -648 381 -298 645 -23028 359 -288 663 -342 655 -644 381 -314 669 -312 697 -320 667 -338 679 -646 353 -314 655 -650 329 -670 345 -314 669 -32700 413 -310 647 -330 667 -666 321 -346 669 -336 679 -320 691 -296 701 -638 339 -354 629 -660 343 -640 351 -350 621 -23024 341 -326 671 -322 673 -650 343 -318 661 -340 677 -322 689 -318 679 -652 335 -356 623 -648 351 -656 337 -350 633 -23002 383 -354 543 -430 573 -746 241 -420 611 -378 621 -408 601 -392 605 -716 313 -346 621 -708 271 -692 313 -378 587 -23050 339 -326 669 -322 677 -614 377 -320 659 -340 681 -320 693 -294 703 -654 335 -322 661 -644 351 -632 375 -310 665 -23004 355 -370 543 -438 547 -760 225 -450 565 -420 587 -442 587 -412 593 -736 271 -364 623 -696 295 -710 261 -420 573 -23058 317 -330 677 -318 655 -652 369 -310 665 -352 665 -314 701 -298 715 -642 355 -318 657 -644 347 -620 387 -316 621 -23016 363 -394 533 -424 567 -754 235 -450 547 -446 575 -426 573 -422 591 -720 305 -382 591 -696 307 -688 309 -376 589 -23038 353 -308 665 -320 661 -646 389 -314 657 -322 697 -298 715 -288 719 -646 345 -308 665 -648 +RAW_Data: 347 -622 381 -298 647 -23000 393 -362 535 -468 537 -750 241 -442 555 -444 593 -398 607 -388 629 -718 273 -382 611 -704 257 -718 307 -362 589 -23058 357 -322 657 -310 683 -642 355 -318 689 -322 671 -322 675 -324 713 -614 375 -324 629 -654 343 -634 373 -314 661 -23002 359 -642 225 -568 101 -164 97 -1928 527 -468 537 -456 565 -752 271 -414 557 -736 271 -724 243 -444 555 -23034 381 -274 697 -320 667 -630 343 -346 673 -324 675 -344 653 -356 663 -638 347 -336 675 -622 353 -640 361 -312 645 -23022 345 -3786 131 -436 549 -460 571 -454 527 -788 237 -412 559 -762 239 -758 239 -410 591 -23042 337 -320 667 -322 679 -616 377 -320 659 -340 681 -320 691 -296 701 -638 375 -310 667 -616 349 -646 383 -298 647 -23016 359 -474 393 -570 331 -854 135 -940 555 -474 531 -460 571 -750 241 -412 587 -740 231 -742 255 -416 593 -23036 353 -320 659 -322 661 -644 355 -316 687 -320 669 -328 681 -324 713 -616 377 -288 667 -654 343 -634 389 -318 623 -22988 371 -394 511 -458 531 -790 233 -446 555 -438 569 -424 603 -392 617 -714 267 -414 593 -692 275 -722 273 -412 587 -23014 365 -324 673 -288 703 -616 375 -322 661 -338 683 -288 715 -296 701 -654 337 -322 663 -632 345 -670 341 -314 663 -22998 373 -364 525 -462 549 -766 225 -464 549 -428 573 -422 589 -420 583 -726 263 -410 579 -718 277 -724 267 -410 579 -23040 361 -322 631 -362 649 -648 345 -346 635 -350 659 -340 687 -322 693 -648 345 -312 667 -646 317 -686 345 -300 651 -23014 395 -290 diff --git a/assets/unit_tests/subghz/came_twee.sub b/assets/unit_tests/subghz/came_twee.sub new file mode 100644 index 00000000000..b340a3835fe --- /dev/null +++ b/assets/unit_tests/subghz/came_twee.sub @@ -0,0 +1,7 @@ +Filetype: Flipper SubGhz Key File +Version: 1 +Frequency: 433920000 +Preset: FuriHalSubGhzPresetOok650Async +Protocol: CAME TWEE +Bit: 54 +Key: 00 00 00 00 E7 1E 05 2E diff --git a/assets/unit_tests/subghz/came_twee_raw.sub b/assets/unit_tests/subghz/came_twee_raw.sub new file mode 100644 index 00000000000..31a6d46cd13 --- /dev/null +++ b/assets/unit_tests/subghz/came_twee_raw.sub @@ -0,0 +1,10 @@ +Filetype: Flipper SubGhz RAW File +Version: 1 +Frequency: 433920000 +Preset: FuriHalSubGhzPresetOok650Async +Protocol: RAW +RAW_Data: 65 -918 131 -3388 1159 -100 65 -2632 65 -4574 65 -754 97 -9206 65 -5652 97 -428 99 -8322 99 -98 227 -1348 67 -300 65 -6066 99 -1760 65 -7064 67 -2742 65 -2912 295 -332 99 -3550 165 -266 199 -632 131 -5510 99 -1362 99 -2144 131 -2270 129 -100 331 -962 99 -704 233 -300 65 -66 99 -2010 197 -1162 165 -364 133 -132 97 -164 131 -196 131 -558 67 -98 231 -98 65 -886 65 -1326 165 -100 133 -5110 67 -962 65 -1492 65 -1320 199 -1854 65 -1428 97 -8926 581 -7682 257 -752 257 -740 269 -742 271 -690 361 -652 351 -1152 849 -642 375 -630 399 -1114 385 -626 883 -1106 903 -586 421 -584 447 -1084 917 -1072 939 -554 457 -1074 445 -550 443 -552 485 -514 971 -1044 975 -534 487 -514 473 -1044 979 -522 473 -536 473 -544 479 -1026 983 -1014 981 -1050 477 -518 987 -514 479 -522 475 -1068 431 -51352 467 -606 377 -626 397 -586 421 -582 415 -592 423 -610 375 -608 435 -586 423 -550 449 -554 445 -582 433 -574 443 -556 427 -1074 939 -550 471 -542 477 -1014 483 -544 969 -1032 967 -554 453 -530 495 -1042 975 -1020 969 -550 477 -1014 483 -514 479 -552 449 -556 985 -1026 983 -516 479 -528 487 -1022 977 -548 449 -546 477 -508 475 -1044 967 -1040 979 -1042 479 -512 1003 -524 471 -522 481 -1030 491 -51314 487 -622 325 -654 353 -656 355 -664 367 -606 405 -622 361 -618 387 -618 415 -580 443 -578 409 -590 425 -584 417 -580 417 -1086 939 -576 443 -560 429 -1074 447 -554 969 -1048 947 -550 455 -1036 1005 -528 463 -1044 973 -1042 445 -540 481 -522 999 -522 481 -530 465 -1044 977 -1016 975 -1056 451 -546 481 -516 977 -536 473 -1032 473 -552 449 -526 989 -546 443 -550 475 -522 475 -554 451 -1040 987 -51838 435 -696 259 -740 271 -702 305 -720 327 -650 353 -652 353 -642 373 -610 407 -592 393 -618 385 -620 385 -628 393 -610 411 -1096 919 -586 417 -598 395 -1104 409 -588 923 -1078 945 -550 477 -1030 455 -548 975 -1038 489 -522 975 -1018 481 -546 971 -1034 967 -1050 477 -522 983 -546 443 -1048 459 -552 981 -518 491 -512 481 -514 477 -550 475 -1016 1005 -528 465 -1042 977 -520 471 -1040 469 -548 451 -51346 477 -560 421 -612 409 -574 439 -588 391 -584 449 -556 421 -612 403 -604 407 -590 425 -582 417 -584 411 -576 445 -582 447 -1044 961 -548 449 -554 451 -1050 479 -530 961 -1044 975 -1030 975 -556 461 -514 481 -1040 475 -524 473 -538 471 -554 969 -1026 985 -514 473 -1034 473 -556 451 -544 963 -546 447 -552 481 -1020 967 -550 481 -520 493 -1006 475 -554 449 -554 475 -542 971 -514 +RAW_Data: 481 -1046 945 -554 485 -51810 487 -586 391 -618 417 -586 415 -580 399 -606 409 -594 427 -582 417 -580 415 -590 423 -578 441 -572 437 -552 455 -546 449 -1078 937 -550 479 -530 467 -1048 449 -552 979 -1048 949 -1044 975 -1018 991 -546 477 -516 491 -512 481 -1044 979 -1038 449 -558 959 -514 481 -554 449 -554 449 -546 469 -548 453 -548 447 -552 479 -538 441 -1050 485 -536 959 -1040 477 -524 485 -540 445 -538 965 -1076 939 -1056 473 -51318 493 -562 431 -582 417 -584 449 -556 423 -568 441 -574 443 -550 455 -546 483 -516 473 -540 475 -524 475 -552 453 -540 467 -1044 975 -524 473 -554 455 -1034 489 -512 975 -1044 967 -1050 481 -516 985 -514 475 -554 449 -554 475 -1038 463 -514 977 -554 449 -554 487 -512 469 -548 451 -542 481 -1014 979 -546 479 -1024 489 -514 979 -1052 459 -550 451 -528 493 -512 483 -514 1011 -520 469 -544 475 -1014 481 -514 1009 -51820 431 -650 353 -638 377 -630 397 -620 355 -652 353 -626 407 -612 409 -594 399 -618 387 -614 383 -590 413 -612 411 -576 441 -1084 915 -584 443 -548 441 -1084 451 -550 941 -1046 979 -1052 451 -546 477 -516 969 -556 451 -1044 989 -1014 981 -546 485 -1026 983 -516 479 -1016 983 -558 465 -512 483 -1044 979 -520 487 -1030 985 -516 481 -1022 487 -516 1001 -1010 975 -1052 481 -528 465 -514 481 -98632 67 -300 65 -700 65 -2382 65 -68 195 -798 99 -3430 65 -5332 65 -2574 97 -234 65 -2240 195 -4416 165 -1324 99 -4840 65 -1326 99 -1924 165 -4644 97 -4552 65 -5576 197 -3004 99 -2060 199 -2966 65 -330 197 -3684 65 -3090 67 -1032 99 -2390 97 -1094 65 -200 231 -792 329 -6554 65 -6300 131 -5596 65 -1292 65 -3076 65 -264 97 -3074 67 -3288 97 -3248 131 -228 163 -986 133 -2688 65 -460 99 -98 97 -1062 131 -628 67 -830 65 -1060 65 -332 99 -1290 263 -66 99 -2590 165 -726 131 -292 165 -332 131 -1860 65 -700 65 -666 99 -368 163 -3396 97 -5880 131 -5130 131 -7598 67 -1330 99 -1878 63 -1578 65 -1350 133 -11606 99 -2400 65 -858 67 -3516 133 -1524 65 -1648 99 -3808 99 -1918 65 -396 63 -2308 129 -1514 97 -562 97 -66 99 -3218 165 -592 65 -2110 65 -8596 63 -592 99 -5050 165 -7482 65 -396 199 -100 199 -626 65 -6278 65 -1392 97 -5676 67 -5218 99 -1826 163 -1738 65 -6246 65 -1146 129 -6776 131 -958 97 -1918 99 -1264 67 -98 133 -500 131 -432 131 -166 99 -960 65 -462 97 -2426 131 -1232 65 -5012 197 -2464 575 -510 479 -514 475 -520 507 -522 487 -514 473 -546 451 -546 479 -516 471 -538 471 -538 471 -538 +RAW_Data: 473 -522 487 -516 473 -1044 977 -520 471 -556 453 -1042 487 -512 979 -1048 471 -522 985 -522 493 -512 483 -514 475 -550 473 -1022 485 -518 1003 -1004 479 -552 979 -522 481 -532 465 -1042 477 -516 479 -526 487 -524 985 -1016 981 -1050 987 -1016 965 -544 479 -1010 1003 -1034 975 -520 493 -512 483 -51832 477 -548 483 -518 479 -542 449 -554 449 -544 473 -548 451 -548 481 -518 481 -526 483 -520 487 -536 463 -548 449 -548 445 -1050 985 -518 481 -524 493 -1044 445 -556 945 -1050 975 -548 453 -546 447 -1050 983 -1046 971 -514 483 -1044 449 -552 485 -512 471 -548 985 -1014 979 -544 449 -560 463 -1042 971 -544 451 -552 443 -572 443 -1044 979 -1016 999 -1014 473 -550 989 -514 475 -524 473 -1050 451 -51346 521 -524 463 -514 485 -548 447 -556 447 -554 449 -546 471 -548 453 -546 447 -550 477 -522 475 -538 475 -550 451 -540 467 -1046 979 -518 485 -514 473 -1046 481 -518 977 -1050 975 -520 459 -1072 937 -540 473 -1050 975 -1052 449 -548 443 -542 969 -552 485 -512 473 -1048 977 -1046 949 -1058 453 -544 481 -516 977 -552 451 -1074 427 -546 483 -516 977 -552 451 -544 469 -546 453 -548 447 -1044 999 -51812 519 -530 465 -514 481 -548 479 -516 481 -526 457 -554 487 -496 495 -512 483 -546 479 -514 473 -522 471 -558 487 -512 471 -1042 977 -526 459 -544 487 -1028 487 -512 973 -1048 965 -554 451 -1050 451 -544 975 -1046 473 -510 1009 -1026 451 -544 975 -1046 967 -1018 509 -516 985 -514 477 -1056 459 -518 981 -548 453 -546 479 -516 473 -520 507 -1018 977 -522 495 -1038 973 -524 471 -1018 487 -526 493 -51324 491 -542 455 -548 449 -552 447 -586 433 -546 477 -522 457 -548 483 -548 445 -552 443 -552 483 -548 439 -550 453 -548 449 -1078 935 -554 481 -528 467 -1044 445 -554 975 -1020 977 -1044 973 -520 473 -554 471 -1040 465 -550 453 -546 447 -550 977 -1020 981 -550 487 -1008 477 -524 485 -540 965 -546 445 -550 455 -1038 977 -554 473 -542 443 -1048 481 -514 477 -522 487 -552 949 -558 461 -1042 971 -524 475 -51838 493 -554 409 -592 427 -584 421 -586 413 -576 445 -574 413 -582 447 -576 435 -550 455 -550 447 -546 443 -574 445 -584 449 -1044 959 -548 445 -554 447 -1066 441 -552 983 -1018 977 -1050 987 -1010 1001 -512 481 -514 475 -550 473 -1016 997 -1016 505 -518 983 -514 479 -522 471 -556 487 -514 469 -546 451 -544 481 -516 479 -524 471 -1032 471 -554 983 -1014 483 -546 445 -552 449 -556 961 -1036 987 -1038 475 -51318 513 -562 401 -570 441 -588 425 -582 417 -586 413 -594 423 -572 +RAW_Data: 447 -572 435 -550 419 -584 449 -576 413 -562 459 -550 445 -1056 989 -518 481 -524 475 -1050 449 -560 955 -1044 975 -1018 483 -558 963 -516 479 -524 483 -522 489 -1032 489 -512 977 -522 485 -536 473 -522 487 -540 463 -514 481 -1042 973 -556 453 -1036 489 -512 979 -1016 521 -522 477 -518 485 -512 479 -514 1003 -522 471 -540 487 -1016 467 -548 981 -51816 509 -512 477 -556 453 -536 443 -576 447 -558 463 -512 483 -548 445 -552 447 -554 485 -514 473 -548 455 -546 479 -518 481 -1018 1001 -518 481 -520 493 -1040 443 -552 967 -1034 967 -1046 469 -550 451 -546 973 -522 473 -1052 977 -1020 979 -552 441 -1048 971 -560 463 -1042 979 -518 485 -514 471 -1048 977 -524 455 -1050 977 -548 453 -1044 481 -524 971 -1050 973 -1044 445 -552 447 -554 485 -51302 523 -534 465 -548 451 -550 447 -556 443 -564 449 -550 441 -586 429 -546 481 -516 477 -522 473 -552 485 -512 471 -548 453 -1078 939 -538 473 -540 471 -1034 485 -512 969 -1044 481 -526 987 -512 479 -562 461 -514 483 -516 479 -1054 447 -554 975 -1042 447 -554 977 -520 479 -534 469 -1044 447 -552 449 -564 483 -518 977 -1040 971 -1038 953 -1044 967 -546 483 -1048 947 -1048 973 -546 451 -548 447 -51842 475 -620 353 -644 373 -644 341 -656 395 -616 387 -586 415 -612 385 -598 409 -610 405 -592 427 -584 417 -584 413 -562 459 -1076 941 -550 453 -550 449 -1044 475 -552 953 -1056 451 -546 975 -520 473 -1032 473 -554 485 -498 993 -546 445 -554 447 -1048 487 -536 463 -516 481 -548 479 -516 975 -554 451 -1036 491 -510 975 -554 449 -1052 983 -1016 981 -522 485 -540 475 -1040 463 -548 451 -546 977 -520 471 -1038 467 -51324 485 -3800 195 -672 307 -694 329 -652 355 -650 353 -642 375 -642 375 -624 363 -620 419 -586 419 -1090 925 -572 439 -586 423 -1076 413 -592 939 -1042 477 -524 989 -1046 945 -1034 487 -540 963 -1044 977 -1030 975 -522 495 -1042 445 -554 975 -1018 483 -524 493 -512 481 -546 475 -506 473 -540 973 -1048 487 -498 995 -514 477 -554 447 -556 485 -1010 989 -1044 977 -51826 499 -7642 327 -652 355 -654 355 -674 333 -634 405 -622 361 -1144 879 -612 411 -574 439 -1082 419 -584 911 -1076 447 -566 963 -1042 443 -560 445 -570 441 -546 477 -558 955 -548 445 -1050 983 -1040 463 -514 483 -546 445 -554 975 -1018 483 -558 463 -514 979 -1052 947 -542 473 -548 455 -544 481 -514 477 -522 473 -1050 485 -534 959 -1034 477 -524 485 -93988 65 -6444 63 -964 65 -428 97 -1692 65 -9326 99 -4816 97 -1218 67 -2008 97 -522 97 -1860 99 -1962 +RAW_Data: 65 -504 65 -798 65 -732 67 -560 65 -824 65 -66 195 -1780 65 -656 65 -100 99 -366 133 -902 133 -132 65 -164 97 -2648 165 -1950 199 -2336 99 -468 165 -1296 131 -232 527 -100 259 -66 131 -5558 99 -792 65 -660 99 -2094 163 -1154 165 -9190 199 -166 331 -166 299 -3056 267 -66 65 -298 65 -1422 97 -2908 129 -496 199 -132 131 -2308 165 -364 131 -332 67 -632 101 -1090 231 -1018 197 -66 163 -394 65 -628 65 -460 95 -954 65 -1932 67 -66 65 -1188 97 -1394 131 -98 395 -432 791 -1332 263 -1328 97 -270 67 -962 231 -2222 131 -168 65 -500 65 -630 99 -958 63 -164 65 -980 97 -396 131 -2674 65 -3818 131 -1234 65 -134 65 -200 65 -1394 97 -2108 329 -460 227 -132 195 -426 97 -630 293 -4052 65 -2470 65 -434 133 -400 67 -600 65 -1726 67 -5132 197 -5216 131 -2552 199 -1846 65 -6540 97 -390 97 -132 63 -726 65 -1002 131 -66 133 -4454 131 -1086 65 -3068 65 -66 97 -1022 65 -594 163 -1304 97 -900 99 -364 133 -1004 97 -1760 197 -268 99 -2812 67 -400 97 -432 99 -6002 65 -66 163 -434 131 -432 197 -1460 165 -8400 65 -524 65 -6948 97 -728 65 -166 97 -4386 97 -266 97 -2942 395 -6642 99 -204 65 -1030 67 -468 99 -66 131 -1098 133 -1060 163 -4446 65 -2920 65 -134 99 -4124 67 -6956 67 -1392 99 -6610 133 -1548 65 -1712 99 -2112 99 -3776 165 -896 65 -428 97 -760 197 -1448 97 -936 233 -98 163 -5932 129 diff --git a/assets/unit_tests/subghz/cenmax_raw.sub b/assets/unit_tests/subghz/cenmax_raw.sub new file mode 100644 index 00000000000..2b78115f201 --- /dev/null +++ b/assets/unit_tests/subghz/cenmax_raw.sub @@ -0,0 +1,15 @@ +Filetype: Flipper SubGhz RAW File +Version: 1 +Frequency: 433920000 +Preset: FuriHalSubGhzPresetOok650Async +Protocol: RAW +RAW_Data: 32700 -1024 977 -1010 971 -1046 967 -1012 1007 -1014 1001 -1008 503 -528 523 -518 485 -550 259 -288 491 -556 231 -296 501 -560 265 -268 267 -270 497 -522 489 -550 259 -290 227 -298 267 -306 239 -308 241 -274 507 -524 261 -256 259 -296 265 -268 503 -558 495 -554 229 -296 503 -560 493 -522 259 -256 257 -296 497 -526 525 -520 261 -292 499 -560 497 -524 263 -260 525 -520 261 -290 227 -298 267 -270 505 -558 231 -332 237 -274 507 -524 521 -518 487 -548 259 -286 227 -298 269 -306 239 -308 239 -276 507 -522 261 -258 261 -296 263 -268 269 -268 271 -306 239 -306 241 -274 273 -270 499 -522 489 -550 259 -288 227 -298 503 -558 233 -332 237 -274 999 -1012 977 -1016 1007 -1018 977 -1014 985 -1008 1013 -1014 521 -524 493 -552 477 -546 239 -314 477 -558 231 -298 501 -562 265 -268 267 -270 497 -520 521 -518 259 -290 227 -300 269 -306 239 -306 241 -276 507 -522 261 -258 259 -296 265 -266 501 -558 497 -556 229 -296 503 -558 493 -522 259 -256 257 -294 497 -556 493 -522 263 -292 499 -560 499 -522 263 -260 523 -522 259 -292 227 -298 267 -270 505 -560 229 -300 269 -274 505 -524 489 -550 487 -550 259 -286 227 -298 269 -306 239 -306 241 -276 507 -522 261 -256 259 -296 267 -268 267 -270 271 -304 239 -306 241 -276 273 -270 497 -522 489 -550 259 -290 225 -298 505 -558 231 -300 269 -272 1001 -1008 979 -1014 1009 -1020 977 -1014 997 -1010 983 -1040 507 -508 511 -546 477 -546 257 -280 513 -520 261 -296 499 -558 265 -268 269 -268 497 -522 489 -552 261 -288 227 -296 271 -304 241 -306 241 -276 507 -522 259 -258 259 -296 267 -266 503 -558 495 -556 229 -296 501 -562 495 -518 259 -256 257 -296 497 -524 525 -520 261 -294 499 -558 499 -524 263 -260 523 -522 259 -290 227 -298 267 -270 505 -558 231 -300 271 -272 505 -526 489 -552 485 -550 227 -318 225 -298 269 -306 239 -306 241 -276 507 -522 261 -258 259 -296 265 -266 269 -270 271 -304 239 -308 239 -276 273 -270 497 -522 489 -550 261 -288 227 -296 505 -558 231 -300 271 -272 999 -1012 981 -1024 1007 -992 1007 -1010 1003 -982 1001 -1048 479 -548 477 -548 479 -546 257 -282 511 -554 231 -294 499 -560 265 -268 269 -268 497 -522 521 -520 259 -290 225 -298 269 -306 239 -308 239 -276 507 -522 261 -258 259 -296 265 -266 503 -556 495 -556 229 -296 503 -560 493 -520 261 -256 257 -294 499 -524 525 -520 261 -294 499 -560 497 -524 261 -262 523 -522 259 -292 227 -296 267 -270 505 -558 231 -332 237 -274 +RAW_Data: 505 -526 491 -550 485 -550 227 -318 225 -298 269 -306 239 -306 241 -276 507 -522 261 -258 259 -296 265 -266 269 -270 271 -304 239 -306 241 -276 271 -270 499 -522 489 -550 259 -288 227 -298 505 -560 231 -298 271 -272 999 -1012 977 -1018 1003 -1020 977 -1016 1001 -1008 979 -1040 515 -518 483 -552 485 -552 225 -306 501 -548 227 -318 493 -556 267 -266 267 -270 497 -522 489 -552 259 -288 227 -300 267 -304 239 -308 241 -276 505 -524 261 -258 259 -296 265 -268 501 -558 495 -554 229 -296 503 -528 527 -520 259 -256 257 -296 497 -524 525 -520 261 -294 501 -558 499 -524 261 -260 523 -522 259 -290 227 -298 269 -268 505 -560 231 -300 269 -274 505 -524 489 -552 487 -550 227 -286 257 -296 269 -306 239 -308 239 -276 507 -522 261 -258 259 -296 265 -266 269 -270 269 -306 239 -308 241 -274 273 -270 497 -522 487 -552 261 -288 225 -298 503 -558 233 -332 237 -274 999 -1010 977 -1016 1007 -1020 977 -1014 999 -1014 993 -1012 513 -514 513 -548 479 -548 225 -310 509 -520 261 -294 499 -558 267 -268 269 -268 497 -524 487 -552 259 -288 227 -298 269 -306 239 -308 241 -274 507 -524 259 -258 259 -296 265 -268 501 -558 497 -552 231 -296 501 -560 493 -520 261 -256 257 -294 497 -558 493 -554 129 -32700 261 -332 131 -534 329 -98 32700 -1002 979 -1048 989 -1006 989 -1012 977 -1024 1007 -1034 225 -284 255 -292 263 -264 267 -268 501 -558 231 -298 267 -306 477 -560 231 -296 229 -296 495 -522 523 -520 521 -518 261 -294 265 -304 239 -276 273 -272 497 -522 259 -258 521 -524 261 -296 497 -558 231 -300 505 -528 525 -522 485 -550 483 -550 485 -548 487 -550 261 -294 495 -560 265 -268 267 -270 497 -522 261 -260 259 -296 267 -268 505 -560 231 -298 271 -274 507 -522 521 -520 485 -548 259 -288 227 -296 271 -306 239 -308 239 -276 507 -522 261 -258 259 -296 265 -266 269 -270 271 -272 273 -306 241 -274 273 -270 497 -522 489 -550 259 -288 261 -264 503 -560 231 -300 269 -274 999 -1012 977 -1024 1007 -992 1009 -1000 1005 -982 1033 -1016 257 -248 279 -252 259 -296 265 -268 503 -560 231 -296 267 -304 477 -560 231 -296 229 -296 495 -522 523 -518 523 -520 261 -292 265 -304 239 -276 273 -270 497 -522 259 -290 491 -522 263 -294 497 -558 231 -300 505 -528 527 -522 485 -548 483 -550 485 -550 487 -552 259 -292 495 -560 265 -268 267 -268 497 -522 261 -292 227 -296 267 -270 505 -558 231 -300 269 -274 507 -524 487 -550 487 -550 257 -288 227 -296 271 -304 239 -308 +RAW_Data: 241 -276 505 -524 259 -258 259 -296 265 -268 269 -270 271 -270 273 -308 239 -276 273 -270 497 -522 489 -550 259 -288 227 -298 505 -558 231 -300 269 -274 997 -1008 1009 -988 1009 -996 1013 -1014 991 -1014 991 -1012 271 -288 251 -256 253 -292 251 -288 485 -558 231 -300 269 -306 475 -560 229 -296 229 -298 495 -524 523 -518 521 -518 261 -294 263 -304 241 -274 273 -270 499 -520 261 -290 491 -524 261 -294 499 -558 231 -298 503 -562 493 -520 487 -548 485 -548 487 -550 485 -550 261 -290 497 -558 267 -266 269 -268 497 -522 263 -290 227 -296 267 -268 505 -560 231 -300 271 -272 505 -524 489 -552 487 -550 225 -318 227 -296 271 -304 241 -306 241 -276 505 -522 261 -258 259 -296 265 -266 269 -270 271 -304 239 -308 241 -274 273 -270 497 -522 489 -550 259 -288 227 -298 501 -560 231 -334 237 -274 1001 -1012 979 -1014 1005 -986 1007 -1014 1001 -1006 983 -1040 271 -254 253 -292 253 -292 253 -284 481 -558 231 -296 267 -304 477 -562 231 -294 229 -296 497 -524 489 -550 489 -552 261 -292 265 -302 239 -276 273 -270 499 -522 259 -290 491 -522 263 -294 499 -558 231 -296 503 -560 495 -520 487 -550 485 -548 487 -548 489 -548 261 -290 497 -558 265 -268 269 -268 497 -522 261 -292 227 -296 267 -268 507 -558 231 -298 271 -272 507 -522 489 -552 487 -550 227 -286 257 -298 269 -306 239 -308 241 -274 507 -524 259 -258 257 -296 265 -268 269 -268 271 -306 239 -306 241 -276 273 -270 497 -522 489 -550 259 -288 227 -296 505 -558 231 -300 271 -272 997 -1014 975 -1016 1009 -1020 977 -1016 1001 -1012 989 -1044 237 -288 253 -290 217 -292 253 -290 485 -562 231 -298 269 -306 475 -562 229 -296 229 -296 495 -524 523 -518 523 -518 261 -292 265 -304 239 -274 273 -270 499 -520 261 -292 491 -524 261 -294 495 -558 231 -300 503 -562 493 -522 485 -550 485 -548 485 -550 487 -552 261 -290 497 -560 231 -300 267 -270 497 -522 261 -290 227 -296 267 -268 507 -558 231 -300 269 -274 505 -524 519 -518 487 -550 259 -288 227 -296 271 -304 239 -308 241 -274 507 -524 259 -260 259 -294 233 -300 267 -270 271 -306 239 -308 239 -276 271 -270 497 -522 489 -550 259 -288 227 -298 501 -560 231 -334 237 -274 1001 -1010 979 -1014 1007 -1020 977 -1016 1001 -1008 979 -1044 237 -288 255 -290 255 -290 251 -282 479 -556 231 -296 269 -304 475 -562 231 -296 229 -296 495 -524 521 -518 523 -518 261 -292 265 -304 239 -276 273 -270 497 -522 261 -290 491 -524 263 -292 497 -558 231 -298 +RAW_Data: 505 -560 495 -520 485 -550 485 -548 485 -552 487 -550 261 -290 497 -558 267 -266 267 -268 497 -522 263 -290 227 -296 267 -270 505 -560 231 -298 271 -272 507 -524 487 -552 485 -550 227 -318 227 -298 269 -306 239 -306 241 -276 505 -522 261 -258 259 -296 265 -268 267 -270 271 -306 237 -308 241 -274 273 -270 497 -522 489 -550 259 -288 227 -300 503 -558 231 -300 269 -272 999 -1008 1007 -988 1005 -996 1013 -1012 987 -1004 997 -1044 225 -278 247 -284 255 -296 267 -268 503 -558 231 -296 269 -304 475 -562 229 -296 229 -296 497 -524 521 -518 523 -518 261 -292 265 -302 241 -276 273 -270 497 -522 259 -290 491 -524 263 -292 499 -556 231 -300 505 -558 495 -522 485 -548 485 -550 485 -550 485 -550 261 -292 497 -558 265 -268 267 -270 497 -520 261 -290 229 -296 267 -270 505 -558 231 -300 271 -272 507 -524 489 -550 485 -548 259 -288 225 -298 269 -306 239 -308 241 -274 507 -524 261 -258 259 -294 265 -266 269 -270 269 -306 239 -306 241 -274 273 -270 497 -524 487 -550 259 -290 227 -296 503 -558 231 -334 237 -274 997 -1014 977 -1016 1007 -1018 977 -1016 1001 -1008 981 -1038 257 -274 245 -280 251 -290 263 -266 503 -560 231 -294 267 -306 475 -562 229 -296 229 -296 495 -522 523 -520 521 -518 261 -294 265 -302 239 -276 273 -270 499 -522 259 -290 491 -524 261 -294 497 -556 233 -298 505 -560 493 -520 487 -550 485 -550 485 -550 487 -550 259 -292 495 -558 267 -266 269 -268 497 -522 261 -288 227 -298 269 -270 505 -556 231 -298 271 -274 505 -524 489 -550 485 -548 261 -288 225 -298 269 -306 239 -306 241 -274 507 -524 261 -258 259 -294 265 -268 269 -268 271 -306 237 -308 241 -274 273 -270 497 -522 489 -548 261 -288 227 -296 503 -560 231 -300 271 -272 997 -1010 1003 -1004 999 -1008 991 -1010 1011 -982 1009 -1020 257 -282 251 -286 227 -296 265 -268 503 -558 231 -298 267 -304 477 -560 231 -296 227 -296 495 -524 523 -520 489 -550 261 -292 265 -304 239 -276 273 -270 499 -520 259 -290 491 -522 263 -294 499 -558 231 -296 505 -560 493 -522 485 -550 485 -550 485 -548 489 -548 261 -290 497 -558 267 -266 269 -268 497 -522 261 -290 227 -296 267 -270 505 -560 231 -298 269 -272 507 -524 491 -550 485 -548 259 -288 225 -298 269 -306 239 -308 241 -274 507 -524 259 -258 257 -296 265 -266 269 -270 271 -304 239 -308 241 -274 273 -270 497 -522 489 -550 259 -288 227 -298 505 -558 231 -300 269 -274 997 -1012 979 -1024 1007 -992 1007 -1016 991 -1008 +RAW_Data: 989 -1042 237 -288 253 -290 255 -254 255 -288 487 -560 231 -300 269 -306 475 -562 229 -296 229 -296 495 -524 523 -518 489 -550 261 -292 265 -304 239 -276 273 -270 497 -522 259 -290 493 -524 263 -292 497 -556 231 -300 505 -560 493 -520 485 -550 485 -548 487 -548 487 -550 259 -292 497 -560 265 -268 267 -268 497 -522 259 -292 227 -296 267 -270 505 -558 233 -300 269 -272 507 -524 489 -550 487 -550 227 -286 257 -296 269 -306 239 -308 241 -274 507 -524 259 -258 257 -296 267 -266 269 -270 269 -306 239 -306 241 -274 273 -270 497 -522 489 -550 259 -288 227 -298 503 -560 231 -332 237 -274 999 -1012 981 -1016 1003 -986 1009 -1018 1003 -1006 983 -1044 237 -292 253 -292 217 -292 249 -280 509 -556 229 -296 267 -306 477 -560 229 -298 229 -296 495 -522 523 -518 523 -518 261 -292 265 -304 239 -274 273 -272 497 -522 259 -290 491 -524 261 -294 497 -558 231 -300 503 -560 493 -520 487 -548 487 -548 485 -548 487 -550 261 -292 495 -560 265 -268 267 -268 497 -522 263 -290 227 -296 267 -270 503 -560 231 -300 269 -274 505 -526 489 -552 485 -550 227 -286 257 -296 269 -306 239 -306 241 -276 507 -522 259 -258 259 -296 265 -268 267 -270 271 -306 239 -306 241 -276 273 -270 495 -522 487 -552 261 -288 225 -298 503 -558 231 -332 239 -274 999 -1012 979 -1016 1007 -986 1009 -1016 999 -1012 987 -1012 271 -288 253 -290 219 -290 255 -288 485 -558 231 -300 269 -306 475 -560 231 -296 229 -296 495 -524 523 -518 521 -518 261 -292 265 -302 241 -276 273 -270 497 -522 259 -290 491 -524 261 -294 497 -558 231 -298 507 -560 493 -522 485 -548 485 -548 487 -550 489 -548 261 -290 497 -560 233 -300 267 -266 497 -522 261 -290 227 -298 267 -268 505 -558 231 -300 269 -274 505 -524 491 -550 485 -548 259 -286 227 -298 269 -306 239 -308 241 -274 507 -522 261 -256 259 -296 267 -266 269 -270 271 -304 239 -306 241 -276 271 -270 499 -522 487 -550 261 -288 225 -298 505 -558 231 -300 269 -274 997 -1010 981 -1016 1003 -1020 971 -1006 1025 -1008 987 -1042 225 -276 247 -282 255 -294 265 -268 503 -558 229 -296 267 -304 477 -562 229 -296 229 -296 495 -524 523 -518 523 -518 261 -292 265 -304 239 -274 273 -272 497 -522 259 -292 491 -524 263 -294 497 -558 231 -298 503 -560 493 -520 487 -550 485 -548 485 -548 487 -550 261 -292 497 -560 231 -300 269 -268 497 -522 259 -290 227 -298 267 -268 505 -560 231 -332 237 -274 505 -524 489 -550 485 -548 259 -288 227 -300 +RAW_Data: 267 -304 239 -308 241 -274 509 -524 259 -258 257 -296 265 -268 269 -268 271 -306 239 -306 241 -274 273 -270 497 -522 487 -550 261 -288 227 -298 503 -558 233 -298 271 -274 999 -1012 979 -1016 1007 -1016 975 -1002 999 -1018 995 -1046 237 -288 251 -292 253 -256 253 -290 485 -562 233 -298 269 -306 475 -562 229 -296 229 -298 497 -522 491 -550 491 -548 261 -292 265 -304 239 -274 273 -270 499 -520 261 -290 491 -522 263 -294 497 -558 231 -298 505 -558 495 -520 487 -548 485 -550 485 -548 487 -550 261 -292 495 -558 267 -268 267 -268 499 -522 261 -290 227 -296 267 -270 505 -558 233 -298 269 -272 507 -522 489 -552 487 -550 227 -286 257 -296 271 -304 239 -308 239 -32700 165 -164 97 -1950 465 -232 393 -198 557 -7530 865 -1122 915 -1114 159 -346 187 -348 187 -348 445 -618 419 -584 455 -618 195 -354 429 -596 459 -554 227 -320 225 -294 229 -332 467 -560 229 -330 467 -560 497 -558 229 -296 229 -296 229 -300 497 -558 229 -294 265 -302 237 -308 243 -274 273 -270 233 -298 263 -266 265 -268 501 -558 231 -296 267 -306 241 -276 273 -270 497 -522 261 -258 257 -296 267 -270 507 -556 265 -266 271 -274 507 -524 519 -518 487 -548 259 -256 291 -264 269 -274 273 -310 241 -274 505 -524 259 -258 257 -296 265 -268 269 -270 271 -272 273 -306 241 -276 273 -270 495 -522 521 -516 259 -290 259 -264 505 -558 265 -266 271 -274 1001 -1010 1005 -990 1005 -996 1007 -1014 987 -1016 993 -1010 257 -276 247 -282 255 -294 499 -522 527 -520 523 -520 263 -296 503 -526 527 -520 259 -256 257 -294 265 -268 503 -558 231 -296 501 -560 497 -524 261 -262 259 -296 265 -266 497 -524 261 -296 265 -270 271 -308 241 -274 273 -270 233 -298 231 -298 265 -268 503 -556 231 -296 267 -306 239 -276 273 -270 497 -522 259 -258 291 -266 267 -270 505 -558 265 -266 271 -272 507 -522 521 -516 485 -550 257 -288 261 -266 269 -272 275 -306 241 -276 505 -522 261 -256 259 -296 265 -268 269 -270 271 -270 273 -308 241 -274 273 -270 497 -520 521 -518 261 -256 291 -264 503 -560 265 -266 269 -274 999 -1008 1003 -986 1007 -1004 1013 -980 1023 -1008 991 -1042 225 -276 247 -282 255 -294 501 -524 527 -518 527 -520 261 -296 503 -526 525 -520 259 -256 257 -294 265 -268 503 -526 263 -296 501 -560 497 -524 261 -262 261 -296 263 -266 499 -522 263 -294 265 -270 271 -308 241 -276 273 -270 233 -298 229 -298 265 -268 501 -558 231 -298 267 -304 241 -276 273 -270 495 -522 259 -290 261 -264 +RAW_Data: 269 -270 505 -558 231 -300 271 -272 507 -522 521 -518 485 -550 259 -254 291 -264 271 -272 273 -308 241 -274 507 -524 259 -258 257 -296 265 -268 269 -270 271 -272 271 -308 241 -276 271 -270 497 -520 521 -520 259 -256 291 -266 503 -558 265 -266 271 -274 999 -1014 977 -1016 1007 -984 1007 -1014 999 -1016 991 -1010 271 -290 253 -254 291 -254 495 -542 499 -558 493 -522 263 -296 503 -526 525 -522 259 -256 257 -294 267 -268 503 -554 231 -298 501 -558 499 -524 261 -260 261 -298 231 -298 499 -524 261 -294 265 -268 273 -308 241 -276 271 -270 233 -298 231 -298 265 -266 503 -558 231 -298 267 -304 241 -274 273 -270 499 -520 259 -258 291 -266 267 -270 507 -558 233 -296 269 -274 505 -524 521 -520 485 -548 259 -256 291 -264 269 -272 275 -308 239 -276 507 -522 261 -256 259 -296 265 -268 267 -270 271 -272 273 -306 241 -276 271 -270 497 -520 523 -518 259 -290 259 -264 503 -560 265 -266 269 -274 999 -1008 1005 -986 1017 -994 1007 -1012 991 -1014 991 -1012 259 -276 245 -282 253 -294 499 -522 527 -520 525 -518 263 -296 501 -526 527 -520 259 -256 257 -294 265 -268 503 -558 231 -296 503 -558 501 -522 263 -260 259 -294 263 -266 499 -524 261 -296 265 -270 273 -308 241 -274 273 -270 233 -296 231 -296 267 -268 503 -556 231 -296 267 -304 241 -276 273 -270 499 -522 259 -256 259 -296 267 -272 505 -558 233 -298 271 -272 507 -522 521 -516 485 -550 259 -288 259 -264 271 -272 273 -308 241 -276 507 -522 261 -256 259 -296 265 -266 269 -270 271 -272 273 -308 241 -274 273 -270 497 -520 521 -518 259 -288 261 -266 503 -558 265 -266 271 -274 999 -1010 981 -1026 981 -1026 1007 -978 997 -1012 1019 -1006 255 -276 245 -280 255 -294 497 -524 525 -520 525 -520 261 -296 503 -526 527 -520 259 -256 257 -294 267 -268 503 -558 231 -296 499 -560 497 -524 261 -262 261 -296 263 -266 499 -524 261 -294 267 -268 273 -308 239 -276 273 -270 233 -296 231 -298 265 -268 503 -558 231 -296 267 -304 241 -274 273 -270 499 -520 259 -258 259 -298 267 -270 505 -558 265 -266 271 -274 507 -522 521 -516 485 -548 259 -288 259 -266 269 -272 275 -306 243 -274 507 -524 259 -258 257 -296 265 -268 269 -270 269 -272 273 -308 241 -276 271 -270 497 -520 521 -518 259 -290 259 -264 505 -560 263 -266 271 -274 999 -1008 1003 -986 1009 -1000 1011 -1006 1001 -1000 1003 -1018 259 -280 249 -286 261 -264 501 -522 527 -520 525 -518 263 -296 503 -526 525 -522 259 -256 257 -294 267 -266 +RAW_Data: 505 -556 231 -296 501 -558 499 -522 263 -260 261 -296 265 -264 501 -524 261 -294 265 -270 271 -308 241 -274 273 -270 233 -298 231 -298 265 -266 503 -558 231 -296 267 -306 239 -276 273 -270 499 -522 259 -258 257 -296 269 -270 505 -560 231 -298 269 -272 507 -522 521 -518 487 -548 259 -288 259 -264 271 -272 273 -308 241 -276 507 -522 259 -258 257 -296 267 -268 269 -268 271 -272 273 -306 241 -276 271 -270 497 -522 519 -516 261 -288 261 -266 503 -558 265 -266 271 -274 997 -1014 979 -1014 1007 -984 1009 -1016 987 -1006 1013 -1014 273 -290 255 -254 253 -290 485 -526 527 -522 523 -520 263 -294 505 -526 525 -520 259 -256 257 -294 265 -268 501 -558 231 -298 501 -558 499 -522 263 -260 261 -296 263 -266 499 -522 263 -294 267 -268 273 -308 241 -274 273 -270 233 -298 231 -298 265 -266 503 -556 231 -296 269 -306 241 -274 273 -270 497 -520 261 -288 227 -298 269 -270 505 -556 265 -266 271 -274 507 -522 521 -516 487 -548 259 -288 259 -264 269 -272 275 -308 241 -274 507 -522 261 -256 259 -296 265 -268 267 -270 271 -272 275 -306 241 -276 271 -270 497 -520 521 -518 259 -288 259 -266 503 -558 267 -266 269 -274 999 -1006 1005 -986 1007 -1004 1011 -1014 987 -1014 993 -1012 271 -290 253 -254 255 -290 491 -536 503 -558 495 -554 231 -298 503 -524 527 -520 259 -256 257 -296 265 -268 501 -558 231 -298 501 -558 499 -524 261 -260 261 -296 263 -266 499 -522 263 -294 265 -270 273 -306 243 -274 273 -270 233 -298 231 -296 267 -268 501 -558 231 -296 267 -306 239 -276 271 -270 497 -522 261 -258 259 -296 267 -270 507 -560 231 -298 269 -274 505 -524 521 -518 487 -550 259 -254 257 -298 269 -272 275 -308 241 -274 507 -522 261 -256 257 -296 267 -266 269 -270 271 -272 273 -306 241 -276 273 -270 495 -522 519 -518 259 -290 261 -264 505 -558 231 -300 271 -272 999 -1008 1015 -980 1009 -988 1007 -1016 1001 -1010 983 -1044 237 -292 253 -292 253 -254 491 -560 497 -522 527 -520 263 -294 503 -528 527 -518 259 -256 257 -296 265 -268 503 -526 263 -296 501 -558 497 -524 261 -262 261 -296 231 -298 499 -524 261 -294 267 -268 273 -308 241 -274 273 -270 233 -298 229 -298 265 -268 503 -558 231 -298 267 -304 241 -274 273 -270 497 -522 259 -290 259 -266 267 -270 505 -558 265 -266 271 -272 507 -522 521 -520 487 -550 259 -254 257 -298 269 -272 273 -306 243 -274 507 -524 259 -258 257 -296 265 -268 269 -270 271 -270 273 -308 241 -274 273 -270 497 -522 +RAW_Data: 519 -518 259 -288 261 -266 505 -558 231 -300 271 -272 997 -1012 1009 -982 1009 -986 1009 -1014 999 -1016 989 -1012 271 -288 253 -290 253 -256 495 -540 501 -558 495 -522 263 -296 501 -528 527 -520 259 -256 257 -294 265 -268 503 -556 233 -296 501 -558 499 -522 263 -260 261 -296 263 -266 499 -524 261 -294 267 -268 273 -308 241 -276 271 -270 233 -298 229 -300 265 -268 501 -556 231 -298 267 -306 241 -276 271 -270 499 -520 259 -258 259 -296 267 -272 505 -558 233 -298 271 -272 507 -522 521 -520 485 -552 259 -252 291 -264 271 -272 273 -308 241 -276 505 -522 259 -258 259 -296 265 -268 269 -270 271 -270 273 -308 241 -274 273 -270 497 -520 521 -518 259 -288 261 -266 503 -558 265 -266 269 -274 1001 -1006 1005 -984 1019 -998 1005 -1004 987 -1004 997 -1044 257 -248 279 -252 259 -296 501 -522 525 -520 525 -520 261 -296 503 -528 525 -520 259 -256 257 -294 267 -268 501 -558 231 -296 501 -560 497 -524 261 -262 259 -296 265 -264 501 -522 263 -294 265 -270 271 -308 241 -276 271 -270 233 -298 229 -298 267 -266 503 -558 231 -296 267 -306 239 -276 273 -270 497 -520 259 -290 227 -298 269 -270 505 -558 231 -298 271 -274 507 -522 521 -518 485 -550 257 -256 291 -264 269 -272 273 -308 241 -276 507 -522 259 -258 257 -296 265 -268 269 -270 271 -270 273 -308 241 -274 273 -270 497 -520 521 -518 259 -288 259 -264 503 -560 265 -266 271 -274 997 -1012 1011 -984 1005 -988 1007 -1014 1001 -1010 979 -1040 255 -274 245 -278 253 -292 495 -524 527 -520 525 -520 261 -296 499 -528 527 -520 259 -256 257 -294 265 -268 503 -556 231 -298 501 -560 499 -522 261 -260 261 -296 263 -266 501 -522 263 -294 265 -268 273 -308 241 -276 271 -270 231 -298 231 -298 267 -266 501 -558 231 -298 267 -304 241 -274 273 -270 499 -520 259 -258 259 -296 267 -270 507 -558 231 -300 271 -272 507 -522 521 -516 487 -550 259 -254 291 -266 269 -304 241 -308 241 -274 507 -524 259 -258 257 -296 265 -268 269 -270 271 -270 273 -308 241 -274 273 -270 497 -520 489 -548 261 -288 261 -264 503 -558 265 -266 271 -274 1001 -1010 977 -1028 981 -1024 1011 -978 997 -1014 1017 -1008 273 -252 255 -290 255 -290 491 -534 499 -522 527 -522 263 -294 503 -528 525 -520 259 -256 257 -294 267 -266 505 -558 231 -294 501 -558 499 -522 263 -260 261 -296 231 -298 499 -524 261 -296 265 -268 273 -306 241 -276 273 -270 231 -298 231 -296 267 -266 503 -558 231 -296 269 -304 239 -276 273 -270 497 -522 +RAW_Data: 259 -258 259 -296 269 -270 505 -558 231 -300 271 -272 505 -524 521 -520 485 -552 227 -286 255 -298 269 -272 273 -308 241 -276 505 -524 259 -258 257 -296 265 -268 269 -270 271 -270 273 -308 241 -274 273 -270 497 -520 521 -518 259 -288 259 -266 503 -558 265 -266 271 -276 997 -1014 975 -1018 1009 -986 1009 -1018 985 -1002 1009 -1006 257 -274 275 -276 249 -286 493 -526 525 -520 523 -520 263 -296 501 -526 529 -520 259 -256 255 -296 265 -268 267 -32700 99 -100 529 -100 397 -134 231 diff --git a/assets/unit_tests/subghz/doorhan.sub b/assets/unit_tests/subghz/doorhan.sub new file mode 100644 index 00000000000..1df192ff510 --- /dev/null +++ b/assets/unit_tests/subghz/doorhan.sub @@ -0,0 +1,7 @@ +Filetype: Flipper SubGhz Key File +Version: 1 +Frequency: 433920000 +Preset: FuriHalSubGhzPresetOok650Async +Protocol: KeeLoq +Bit: 64 +Key: 48 50 F0 72 33 78 95 14 diff --git a/assets/unit_tests/subghz/doorhan_raw.sub b/assets/unit_tests/subghz/doorhan_raw.sub new file mode 100644 index 00000000000..bc40a20fc45 --- /dev/null +++ b/assets/unit_tests/subghz/doorhan_raw.sub @@ -0,0 +1,10 @@ +Filetype: Flipper SubGhz RAW File +Version: 1 +Frequency: 433920000 +Preset: FuriHalSubGhzPresetOok650Async +Protocol: RAW +RAW_Data: 1937 -32700 457 -398 425 -356 437 -386 411 -384 447 -384 417 -384 419 -386 417 -386 419 -388 417 -388 419 -388 451 -3998 835 -412 417 -810 821 -420 419 -834 423 -836 819 -450 385 -852 813 -446 419 -822 795 -442 415 -814 419 -850 799 -438 413 -850 415 -860 809 -412 843 -420 397 -826 417 -844 815 -432 387 -842 841 -446 791 -472 377 -850 819 -420 395 -854 787 -454 419 -810 429 -854 807 -416 409 -876 819 -422 395 -854 789 -426 839 -418 813 -422 835 -412 819 -452 809 -474 379 -850 821 -420 395 -852 399 -828 813 -450 809 -422 845 -412 407 -870 421 -812 827 -436 385 -842 415 -840 795 -438 411 -842 407 -848 811 -448 811 -458 387 -838 811 -418 417 -822 417 -830 839 -446 381 -874 785 -452 809 -442 385 -806 417 -15802 423 -388 409 -398 395 -398 423 -408 387 -412 385 -412 417 -416 383 -416 385 -418 387 -416 419 -386 421 -4030 789 -422 415 -844 817 -432 385 -844 419 -850 799 -440 413 -876 791 -426 413 -842 817 -432 387 -838 419 -848 793 -436 411 -842 405 -884 779 -450 807 -426 393 -834 417 -836 825 -434 409 -842 819 -454 797 -434 411 -840 831 -400 433 -806 815 -462 387 -838 419 -848 797 -438 413 -876 785 -438 433 -804 811 -424 815 -446 805 -452 801 -434 803 -448 839 -412 441 -834 811 -416 411 -820 417 -828 835 -444 775 -450 835 -412 409 -868 419 -812 827 -438 385 -838 419 -814 825 -436 415 -850 409 -844 809 -446 809 -424 421 -836 811 -420 415 -822 417 -826 807 -476 377 -876 791 -458 809 -420 385 -820 415 -15780 407 -440 379 -412 379 -444 381 -408 385 -434 391 -394 431 -380 409 -412 413 -380 411 -412 409 -396 411 -4006 819 -414 415 -854 789 -424 447 -808 429 -852 811 -414 409 -868 811 -452 387 -820 819 -450 405 -824 409 -842 801 -426 445 -838 399 -870 781 -460 803 -414 417 -828 407 -850 809 -422 421 -838 819 -450 813 -432 415 -846 787 -452 389 -854 791 -426 413 -842 427 -824 805 -450 423 -838 819 -416 415 -854 791 -428 807 -450 811 -420 817 -448 817 -454 799 -434 415 -848 801 -410 427 -820 413 -842 801 -456 809 -450 811 -432 413 -844 409 -830 813 -448 383 -840 417 -824 801 -442 413 -848 405 -848 809 -448 811 -458 377 -844 817 -420 417 -820 417 -830 805 -476 377 -872 803 -448 799 -442 415 -772 415 -15782 429 -376 437 -376 411 -412 413 -380 413 -414 409 -396 411 -408 379 -444 377 -412 381 -412 413 -408 385 -4064 809 -418 397 -828 813 -450 383 -840 403 -850 813 -450 417 -840 813 -448 407 -828 +RAW_Data: 809 -446 381 -844 417 -822 805 -474 381 -842 417 -864 809 -446 809 -418 395 -830 419 -844 815 -430 385 -874 805 -454 797 -436 413 -850 819 -414 421 -818 819 -418 417 -846 401 -854 807 -422 421 -840 809 -454 393 -854 789 -426 807 -452 811 -422 813 -446 835 -420 805 -454 435 -818 815 -416 417 -850 399 -822 809 -450 821 -420 817 -448 423 -850 387 -842 809 -420 417 -822 417 -830 805 -442 411 -842 403 -850 811 -450 811 -460 387 -838 811 -420 417 -822 403 -852 813 -448 415 -854 789 -456 815 -420 385 -818 417 -15768 453 -370 415 -398 407 -418 377 -438 389 -408 387 -412 385 -446 383 -416 385 -416 385 -418 385 -418 419 -4008 835 -412 409 -830 811 -448 381 -850 417 -826 839 -444 381 -878 787 -424 449 -810 821 -432 387 -838 419 -848 791 -438 413 -844 417 -860 807 -446 807 -416 409 -840 387 -844 823 -432 385 -878 785 -450 819 -434 413 -844 819 -420 395 -854 791 -422 449 -808 431 -818 813 -446 407 -850 811 -452 415 -808 835 -420 813 -420 813 -460 781 -446 835 -420 817 -452 429 -820 819 -418 417 -814 427 -820 817 -418 817 -448 819 -436 415 -848 405 -848 809 -414 415 -848 387 -848 801 -440 413 -842 419 -822 839 -444 811 -418 411 -838 819 -420 415 -822 417 -826 837 -444 379 -850 819 -454 805 -440 387 -806 415 -15792 423 -390 417 -390 409 -384 409 -402 423 -408 387 -410 385 -414 415 -416 383 -418 383 -418 387 -416 419 -4032 787 -438 395 -836 811 -426 421 -836 421 -846 795 -440 413 -878 783 -452 407 -820 805 -414 435 -822 417 -836 819 -434 415 -848 409 -844 811 -450 809 -418 395 -828 419 -844 815 -432 385 -876 801 -428 841 -420 417 -836 813 -416 419 -850 797 -436 415 -814 419 -850 799 -442 413 -850 821 -454 405 -820 805 -414 819 -440 827 -410 837 -418 835 -412 829 -456 415 -840 795 -436 387 -844 417 -840 795 -436 803 -448 837 -410 409 -866 417 -838 799 -440 385 -842 421 -812 827 -434 409 -844 407 -860 811 -450 813 -430 407 -812 807 -450 351 -32700 459 -422 407 -386 411 -416 415 -384 415 -388 415 -388 413 -422 383 -422 409 -396 395 -434 357 -438 389 -4046 783 -448 817 -432 781 -446 415 -824 443 -814 413 -856 819 -450 803 -428 411 -844 779 -460 805 -414 837 -418 817 -452 785 -460 805 -450 425 -838 417 -812 819 -432 387 -842 807 -452 393 -852 391 -868 817 -448 389 -858 409 -810 409 -854 807 -446 379 -840 829 -428 411 -846 821 -468 777 -450 411 -838 779 -452 811 -422 815 -448 803 -458 779 -484 +RAW_Data: 783 -458 411 -846 783 -452 393 -854 415 -832 805 -442 775 -450 835 -444 377 -866 415 -840 799 -438 411 -844 385 -850 795 -440 415 -846 409 -844 809 -448 809 -456 381 -842 809 -452 385 -836 395 -862 815 -418 419 -866 807 -444 805 -418 415 -812 385 -15782 473 -360 429 -358 439 -388 409 -386 447 -382 417 -384 419 -386 417 -388 417 -388 419 -388 419 -388 417 -4030 803 -442 803 -416 819 -438 433 -838 385 -868 385 -872 787 -454 827 -432 385 -842 811 -418 811 -460 813 -412 819 -452 803 -436 807 -450 421 -842 421 -814 821 -430 387 -842 807 -450 421 -824 409 -842 835 -418 413 -840 407 -836 415 -822 819 -444 393 -836 813 -458 385 -874 785 -454 827 -434 385 -844 811 -418 811 -462 813 -412 817 -454 803 -436 809 -450 423 -836 811 -420 417 -822 417 -826 801 -444 809 -452 819 -416 453 -848 413 -816 809 -422 409 -838 421 -810 823 -436 415 -846 419 -818 807 -476 809 -418 409 -838 809 -420 417 -822 415 -866 805 -444 381 -878 785 -470 803 -412 407 -810 417 -15764 455 -368 405 -422 399 -396 391 -436 387 -410 385 -412 415 -418 381 -418 383 -418 387 -416 387 -418 419 -4034 791 -424 809 -450 811 -420 393 -868 419 -810 433 -822 841 -420 813 -446 419 -820 801 -440 809 -448 785 -452 807 -438 809 -450 817 -448 407 -832 419 -812 813 -426 411 -840 819 -454 385 -836 421 -838 821 -450 423 -822 411 -842 407 -824 809 -446 379 -840 819 -442 399 -870 817 -428 809 -450 397 -828 815 -448 811 -418 819 -418 817 -454 789 -462 811 -448 395 -866 779 -452 383 -850 419 -820 803 -440 809 -450 819 -420 417 -850 445 -816 809 -420 409 -840 419 -814 821 -434 415 -848 411 -842 807 -446 809 -422 411 -842 817 -420 415 -844 395 -826 817 -450 415 -854 787 -456 807 -422 417 -788 421 -15780 407 -440 379 -412 381 -442 381 -408 385 -434 393 -394 399 -414 407 -412 411 -382 411 -414 409 -396 379 -4042 807 -446 813 -430 805 -414 409 -866 385 -878 397 -852 781 -480 783 -450 411 -822 811 -450 793 -426 807 -450 813 -454 805 -448 783 -484 383 -850 383 -850 799 -452 407 -822 811 -450 397 -862 383 -878 793 -466 381 -848 417 -820 403 -852 773 -452 395 -864 811 -450 383 -852 817 -450 801 -428 411 -844 817 -430 813 -412 801 -454 805 -452 791 -460 807 -448 411 -838 819 -418 417 -840 395 -860 777 -450 813 -456 781 -446 405 -886 385 -846 787 -466 387 -836 417 -846 789 -436 415 -846 417 -852 773 -476 811 -420 411 -840 783 -450 385 -852 417 -860 +RAW_Data: 773 -474 379 -870 805 -450 815 -412 385 -826 159 -32700 483 -378 411 -414 377 -426 381 -436 379 -410 411 -412 381 -442 381 -408 383 -404 423 -396 397 -414 407 -4014 825 -436 803 -414 435 -822 415 -836 425 -822 839 -416 409 -874 405 -826 419 -812 811 -424 409 -842 421 -846 399 -854 807 -416 441 -848 803 -454 799 -436 385 -842 811 -420 417 -854 803 -416 839 -454 801 -434 411 -844 833 -388 447 -804 823 -434 409 -844 407 -824 419 -868 793 -470 807 -416 409 -840 821 -420 811 -422 813 -446 801 -456 809 -454 815 -428 411 -848 821 -424 389 -856 417 -798 839 -410 841 -418 815 -448 419 -854 415 -814 813 -424 423 -834 389 -844 819 -432 413 -848 405 -826 817 -450 811 -460 385 -838 817 -420 415 -824 417 -826 809 -442 413 -850 823 -454 801 -434 379 -808 419 -15800 421 -408 387 -410 385 -414 415 -386 413 -420 383 -418 385 -420 385 -420 417 -390 417 -390 419 -388 417 -4036 787 -452 799 -432 409 -842 407 -824 413 -838 823 -432 411 -872 377 -864 383 -836 823 -432 379 -872 375 -854 413 -840 821 -430 411 -878 791 -428 807 -448 379 -840 837 -418 417 -846 795 -436 809 -450 815 -448 409 -830 811 -450 383 -848 817 -416 425 -822 411 -848 415 -858 805 -446 809 -420 411 -838 809 -452 779 -460 779 -446 821 -442 797 -474 811 -450 377 -842 821 -418 419 -820 417 -830 807 -440 811 -450 819 -448 411 -842 415 -846 779 -428 411 -838 419 -848 795 -436 413 -846 417 -820 807 -474 811 -420 423 -836 783 -450 383 -850 417 -828 803 -474 379 -874 787 -456 805 -416 413 -830 377 -15802 411 -414 415 -402 393 -396 399 -422 409 -386 411 -416 383 -418 415 -386 415 -386 417 -386 417 -388 417 -4022 809 -442 811 -414 417 -830 445 -814 413 -842 817 -418 419 -850 443 -816 413 -808 823 -420 435 -820 393 -862 423 -810 825 -434 413 -850 821 -420 831 -428 379 -840 809 -450 417 -834 807 -454 813 -412 823 -442 437 -836 781 -428 421 -838 817 -420 415 -824 417 -830 447 -814 813 -458 811 -412 453 -800 805 -440 809 -448 791 -456 811 -420 815 -460 809 -448 395 -864 785 -452 381 -852 419 -818 801 -438 837 -416 817 -446 417 -860 415 -812 813 -422 409 -838 421 -812 827 -436 413 -848 419 -816 807 -474 809 -418 425 -836 785 -448 379 -840 409 -864 811 -418 415 -864 803 -444 801 -416 451 -782 391 -15810 439 -376 407 -378 447 -376 415 -378 419 -420 421 -386 419 -386 421 -388 421 -388 407 -398 393 -400 421 -4010 841 -422 787 -426 411 -842 421 -846 +RAW_Data: 401 -856 807 -418 421 -870 387 -848 403 -818 807 -450 397 -828 421 -846 389 -854 817 -448 419 -852 805 -414 807 -452 417 -800 807 -442 409 -844 801 -454 809 -450 815 -432 413 -850 821 -424 389 -822 827 -428 413 -844 389 -856 393 -866 821 -450 815 -430 409 -810 809 -450 815 -428 803 -448 789 -454 819 -450 815 -430 413 -848 787 -456 387 -836 395 -862 813 -420 809 -458 811 -412 451 -836 417 -812 811 -426 409 -842 421 -814 827 -434 415 -846 421 -816 805 -476 807 -420 421 -838 785 -450 383 -852 419 -824 803 -440 413 -852 819 -444 829 -408 409 -812 415 -15778 423 -406 387 -410 385 -414 415 -384 415 -418 383 -420 383 -420 385 -420 417 -388 417 -388 419 -408 397 -4028 809 -420 801 -444 407 -830 419 -846 385 -854 817 -448 407 -862 387 -846 423 -822 789 -422 449 -810 427 -820 423 -838 811 -454 387 -866 811 -414 827 -428 411 -842 813 -430 385 -840 833 -452 777 -474 807 -452 385 -842 811 -420 419 -824 829 -418 417 -854 379 -850 419 -860 809 -444 809 -420 423 -838 813 -420 811 -420 813 -446 805 -452 803 -470 777 -450 421 -838 diff --git a/assets/unit_tests/subghz/faac_slh_raw.sub b/assets/unit_tests/subghz/faac_slh_raw.sub new file mode 100644 index 00000000000..f29cc8df7a2 --- /dev/null +++ b/assets/unit_tests/subghz/faac_slh_raw.sub @@ -0,0 +1,11 @@ +Filetype: Flipper SubGhz RAW File +Version: 1 +Frequency: 433920000 +Preset: FuriHalSubGhzPresetOok650Async +Protocol: RAW +RAW_Data: -266 12233 -132 4599 -98 2815 -166 10261 -130 1881 -132 11931 -100 2107 -1164 541 -346 243 -630 515 -330 275 -618 281 -572 277 -566 307 -560 257 -626 313 -558 313 -570 547 -324 561 -310 555 -318 285 -544 567 -308 283 -630 297 -572 281 -590 281 -598 275 -568 291 -570 571 -312 283 -556 579 -310 311 -570 303 -578 545 -346 249 -598 553 -302 315 -550 279 -574 311 -592 291 -600 281 -588 553 -316 533 -342 523 -324 559 -312 283 -558 281 -628 559 -294 573 -334 549 -316 541 -314 563 -294 281 -588 543 -312 285 -628 551 -310 283 -594 553 -336 281 -588 283 -560 551 -312 533 -324 281 -626 283 -568 287 -602 543 -348 537 -316 535 -330 273 -580 545 -318 537 -300 1093 -1154 545 -346 279 -598 529 -340 283 -592 281 -560 313 -536 309 -564 257 -640 281 -592 279 -598 557 -294 571 -336 551 -316 285 -560 539 -316 283 -602 259 -606 313 -584 281 -572 307 -564 289 -580 543 -314 285 -560 553 -352 277 -602 257 -608 545 -350 283 -576 559 -296 279 -584 275 -586 281 -592 313 -570 307 -560 559 -340 547 -314 541 -314 563 -296 279 -584 275 -618 539 -348 523 -324 583 -308 549 -314 573 -312 283 -564 543 -292 303 -614 551 -318 279 -602 545 -328 273 -584 281 -594 553 -316 535 -312 283 -596 293 -598 281 -590 555 -314 565 -296 569 -300 277 -588 545 -316 543 -318 1097 -1144 529 -338 283 -604 541 -324 259 -608 281 -572 285 -566 293 -570 277 -622 279 -612 273 -596 549 -302 581 -316 543 -316 283 -572 549 -292 285 -632 283 -578 285 -600 265 -604 281 -590 281 -562 567 -312 283 -564 545 -356 281 -590 281 -572 573 -324 259 -606 551 -316 285 -564 279 -574 275 -630 259 -618 281 -592 539 -348 525 -326 541 -338 551 -280 287 -562 281 -630 557 -326 541 -336 545 -316 537 -348 527 -324 281 -562 581 -280 287 -630 527 -342 269 -608 543 -346 249 -588 279 -596 525 -344 523 -324 261 -640 283 -594 277 -568 579 -292 569 -310 547 -316 281 -578 557 -294 569 -300 1071 -1180 527 -344 269 -608 543 -348 249 -598 279 -598 277 -572 273 -562 291 -616 281 -592 313 -568 541 -324 561 -310 547 -316 283 -580 559 -308 269 -608 277 -622 283 -578 275 -602 257 -602 275 -586 545 -316 283 -582 529 -362 251 -620 281 -592 535 -346 283 -562 547 -328 275 -586 281 -560 315 -580 309 -596 257 -586 581 -316 543 -316 531 -344 523 -322 295 -578 281 -588 553 -350 523 -324 581 -308 547 -316 539 -348 247 -602 543 -294 299 -612 553 -318 281 -602 545 -326 271 -584 281 -584 553 +RAW_Data: -316 533 -308 283 -628 265 -602 279 -594 535 -338 535 -322 563 -310 281 -568 575 -290 559 -310 1077 -1170 541 -322 293 -576 551 -354 245 -580 307 -562 291 -580 275 -586 281 -592 313 -570 307 -560 559 -336 549 -316 539 -316 281 -570 547 -324 293 -608 283 -578 275 -598 289 -580 277 -590 281 -594 539 -310 279 -564 559 -374 283 -582 275 -604 543 -326 271 -584 545 -316 283 -600 279 -564 275 -602 291 -612 281 -582 539 -350 525 -324 541 -338 519 -314 285 -594 283 -596 555 -326 543 -338 551 -318 537 -316 561 -294 279 -586 545 -350 249 -618 541 -324 285 -604 545 -352 245 -602 275 -570 545 -324 559 -310 283 -590 313 -570 307 -558 559 -338 547 -318 539 -314 283 -568 547 -324 557 -310 1079 -1148 557 -326 283 -594 545 -318 281 -602 275 -570 307 -560 259 -590 275 -622 279 -606 273 -592 555 -334 515 -350 541 -318 281 -570 549 -290 287 -638 281 -596 275 -602 257 -602 275 -586 281 -582 539 -312 283 -568 577 -324 309 -588 281 -598 525 -344 269 -600 539 -312 283 -584 283 -560 279 -612 307 -562 295 -602 549 -318 537 -316 561 -294 569 -302 279 -588 281 -626 529 -344 521 -324 567 -348 521 -316 537 -348 283 -564 545 -294 301 -614 539 -348 283 -564 547 -332 275 -588 315 -560 537 -316 529 -344 269 -602 311 -588 283 -596 527 -346 523 -322 561 -310 283 -560 543 -316 537 -314 1093 -1174 541 -346 285 -562 563 -346 267 -568 303 -580 281 -556 281 -584 281 -630 275 -596 257 -618 547 -318 537 -316 561 -294 279 -586 545 -314 285 -618 275 -600 257 -608 313 -584 283 -578 277 -566 541 -322 297 -578 547 -352 279 -572 291 -600 543 -344 249 -596 535 -350 283 -564 257 -570 305 -614 283 -32700 429 -198 97 -726 895 -168 1195 -98 14445 -100 949 -100 4415 -200 1563 -98 10547 -100 7961 -168 267 -166 2059 -132 4651 -98 6711 -100 2341 -1184 511 -382 243 -626 521 -326 283 -600 279 -586 281 -574 275 -566 271 -628 265 -604 279 -590 551 -348 525 -326 543 -306 317 -554 553 -318 245 -632 291 -594 281 -574 285 -600 301 -576 281 -574 539 -320 281 -562 545 -350 279 -598 293 -598 547 -318 279 -600 547 -302 313 -546 317 -536 541 -354 557 -346 537 -302 309 -578 309 -548 577 -282 567 -292 287 -570 547 -350 555 -348 525 -322 317 -576 545 -316 285 -566 313 -536 551 -322 283 -598 317 -596 277 -570 545 -324 563 -312 323 -560 283 -542 315 -568 273 -594 295 -602 551 -318 557 -316 563 -296 311 -556 311 -556 553 -318 545 -284 1103 -1148 553 -336 285 +RAW_Data: -592 541 -314 319 -564 289 -574 275 -586 281 -558 281 -630 271 -596 291 -594 547 -318 567 -286 569 -302 315 -548 545 -318 275 -600 295 -596 281 -584 315 -568 285 -568 303 -546 583 -318 285 -548 555 -352 279 -596 257 -620 547 -318 283 -574 539 -324 283 -568 313 -556 551 -350 539 -326 545 -342 283 -572 285 -600 561 -308 549 -318 245 -566 577 -324 577 -316 533 -350 281 -594 549 -316 277 -566 289 -584 545 -312 285 -594 313 -572 309 -558 557 -340 549 -318 275 -568 291 -582 275 -550 315 -590 315 -572 547 -322 561 -310 547 -354 281 -540 309 -564 545 -296 569 -312 1077 -1172 549 -322 291 -578 545 -318 279 -596 293 -562 313 -550 281 -570 285 -630 273 -582 281 -584 565 -346 519 -322 559 -312 285 -560 545 -316 285 -634 275 -594 257 -620 283 -590 283 -574 283 -566 555 -304 279 -592 551 -348 251 -628 265 -604 545 -318 279 -596 551 -300 277 -586 281 -572 539 -354 557 -346 537 -312 283 -594 291 -562 545 -352 523 -318 285 -566 535 -382 553 -292 565 -312 285 -598 537 -350 281 -566 257 -604 543 -312 285 -592 315 -572 307 -558 559 -336 549 -318 277 -566 289 -580 275 -586 283 -610 261 -598 569 -310 547 -354 533 -312 283 -564 289 -582 545 -314 549 -316 1075 -1150 579 -292 301 -582 545 -354 281 -572 275 -594 257 -584 277 -590 281 -592 313 -572 307 -558 559 -338 547 -318 539 -318 283 -572 547 -290 289 -640 283 -596 277 -568 289 -600 275 -586 281 -596 539 -318 283 -540 583 -322 297 -582 317 -550 567 -310 319 -558 555 -300 315 -552 281 -570 573 -322 557 -346 539 -302 279 -602 275 -588 545 -318 567 -294 277 -582 545 -348 535 -330 569 -336 283 -574 539 -324 283 -598 281 -544 563 -302 277 -634 283 -592 281 -598 545 -326 539 -314 285 -596 281 -566 279 -580 275 -602 289 -586 583 -316 543 -316 563 -310 269 -604 275 -582 547 -320 545 -282 1093 -1152 543 -322 301 -586 545 -352 283 -572 273 -594 257 -586 311 -556 283 -592 315 -570 309 -558 559 -338 547 -320 541 -316 283 -572 547 -290 287 -638 283 -578 275 -598 289 -576 313 -556 283 -598 555 -284 285 -568 565 -346 267 -606 277 -588 545 -352 281 -570 555 -294 279 -584 315 -552 553 -352 529 -346 557 -292 301 -586 281 -596 539 -318 531 -344 271 -564 567 -346 543 -318 561 -294 311 -590 547 -320 283 -564 281 -578 555 -292 309 -592 317 -564 315 -574 547 -290 585 -310 285 -554 317 -566 281 -580 277 -602 289 -32700 525 -130 559 -296 16901 -100 3153 -132 4843 -98 9161 +RAW_Data: -196 817 -234 3911 -166 6897 -98 6789 -166 8923 -100 2785 -100 5393 -1192 541 -344 243 -630 517 -332 309 -578 281 -570 275 -598 259 -572 299 -614 281 -592 275 -600 545 -326 541 -312 557 -316 287 -576 553 -310 285 -596 291 -596 281 -592 283 -574 309 -564 289 -582 543 -312 285 -560 547 -348 315 -564 289 -580 545 -350 283 -572 539 -320 285 -568 311 -550 281 -628 553 -310 559 -322 557 -312 555 -316 321 -538 311 -562 543 -292 567 -346 555 -316 565 -308 559 -326 273 -584 283 -592 555 -280 563 -316 287 -606 543 -328 309 -552 585 -318 561 -278 565 -294 279 -590 547 -312 279 -600 581 -298 315 -574 285 -600 561 -308 549 -316 287 -562 539 -312 535 -308 1119 -1146 551 -318 317 -572 547 -322 259 -610 281 -558 317 -562 281 -566 307 -594 265 -608 317 -568 541 -324 559 -310 541 -314 279 -568 571 -310 281 -602 289 -578 313 -574 283 -598 265 -604 281 -574 539 -326 281 -558 545 -350 279 -598 293 -602 545 -316 277 -598 549 -300 279 -586 281 -570 285 -600 571 -312 577 -318 531 -344 523 -322 297 -580 281 -560 577 -282 575 -346 521 -324 567 -346 513 -352 283 -572 273 -594 551 -300 547 -312 285 -618 527 -344 269 -604 543 -348 545 -318 533 -310 283 -594 547 -300 275 -622 553 -318 281 -602 257 -606 543 -350 511 -354 283 -566 527 -310 559 -292 1107 -1142 567 -312 281 -594 555 -336 283 -556 319 -544 315 -572 273 -562 291 -610 317 -558 279 -600 553 -318 541 -338 549 -318 285 -564 537 -316 283 -604 291 -580 313 -590 283 -562 313 -574 273 -564 547 -330 275 -586 547 -350 281 -570 291 -602 543 -350 285 -562 537 -316 283 -568 291 -568 303 -612 539 -350 521 -320 579 -310 547 -318 283 -576 311 -562 545 -292 565 -346 537 -348 525 -324 545 -342 285 -594 283 -542 563 -312 557 -290 287 -636 543 -314 283 -602 543 -328 543 -314 557 -318 285 -578 527 -342 271 -598 577 -316 283 -600 277 -572 545 -322 561 -312 285 -560 555 -318 541 -318 1101 -1146 529 -340 283 -572 573 -320 293 -576 283 -572 285 -566 293 -568 277 -624 281 -576 309 -594 551 -300 577 -318 543 -318 283 -572 547 -290 285 -632 285 -594 277 -602 273 -566 291 -582 313 -554 547 -316 285 -546 565 -344 269 -608 313 -556 575 -316 279 -566 559 -340 285 -542 281 -598 259 -616 543 -352 529 -344 559 -290 567 -310 287 -596 283 -544 565 -310 557 -322 563 -348 539 -302 565 -326 275 -584 281 -572 571 -292 549 -306 319 -574 573 -322 291 -578 545 -346 535 -294 571 -304 317 +RAW_Data: -544 569 -286 279 -616 543 -350 279 -598 299 -574 547 -316 565 -288 279 -582 579 -280 537 -310 1091 -1176 547 -318 281 -598 551 -338 283 -556 283 -570 287 -596 265 -576 311 -590 279 -610 273 -596 553 -302 549 -350 543 -320 283 -540 585 -290 283 -594 317 -596 277 -568 287 -602 275 -586 281 -594 543 -318 285 -538 553 -354 293 -580 317 -560 569 -310 283 -594 551 -300 277 -586 281 -572 283 -600 569 -310 575 -304 565 -294 569 -314 279 -600 255 -602 543 -312 541 -346 533 -324 569 -348 543 -320 281 -572 309 -558 555 -300 547 -314 287 -592 565 -346 269 -602 543 -310 547 -318 571 -312 283 -564 545 -294 303 -614 541 -350 281 -564 289 -582 577 -318 541 -318 283 -572 549 -290 577 -274 1113 -1146 555 -326 281 -598 545 -318 281 -580 309 -564 287 -574 275 -586 281 -594 313 -572 307 -558 559 -338 547 -318 539 -318 281 -572 547 -292 287 -638 277 -602 257 -618 281 -592 283 -578 251 -596 555 -304 279 -590 547 -346 281 -598 265 -606 545 -318 279 -598 551 -300 279 -586 283 -560 317 -584 555 -324 577 -308 547 -318 557 -316 283 -572 307 -558 553 -300 545 -348 557 -314 561 -324 543 -338 283 -560 317 -548 567 -310 559 -290 283 -630 555 -318 283 -572 545 -324 563 -312 547 -318 283 -566 565 -312 285 -594 555 -338 283 -586 281 -598 527 -344 523 -324 295 -580 547 -318 523 -318 1097 -1142 565 -310 279 -602 545 -326 273 -584 317 -560 281 -562 279 -604 277 -604 257 -606 313 -554 577 -320 531 -342 523 -324 293 -580 547 -318 243 -632 291 -592 281 -572 287 -594 303 -576 281 -572 541 -294 309 -560 545 -350 315 -574 271 -594 559 -336 283 -558 545 -352 283 -540 309 -564 257 -636 551 -316 571 -314 557 -288 585 -310 285 -560 319 -562 539 -316 531 -362 541 -338 549 -318 569 -312 283 -564 291 -588 545 -314 549 -318 285 -598 555 -326 283 -592 547 -318 535 -348 525 -322 283 -564 579 -282 287 -620 557 -326 281 -592 281 -584 539 -350 523 -318 283 -564 549 -316 549 -318 1089 -1134 577 -324 271 -588 545 -352 281 -572 307 -560 291 -558 277 -588 281 -592 313 -572 307 -560 559 -338 549 -318 537 -300 309 -576 541 -312 285 -604 255 -630 273 -584 281 -584 315 -568 285 -570 565 -310 283 -554 547 -352 277 -600 291 -574 545 -352 283 -580 527 -344 267 -570 301 -546 313 -588 569 -312 557 -322 557 -312 539 -342 277 -568 303 -546 579 -282 575 -336 537 -328 545 -352 537 -332 279 -578 313 -548 545 -318 533 -318 279 -612 545 -348 279 +RAW_Data: -596 529 -342 547 -316 567 -310 267 -570 567 -310 285 -592 533 -348 281 -596 293 -562 583 -316 545 -318 283 -540 551 -322 543 -304 1111 -1146 557 -326 281 -596 547 -314 285 -578 311 -562 259 -604 275 -582 281 -592 313 -572 307 -560 559 -338 553 -318 559 -284 283 -580 557 -294 279 -614 281 -598 313 -570 287 -566 305 -584 281 -560 577 -318 285 -542 555 -354 291 -576 317 -566 541 -324 297 -580 545 -316 285 -578 283 -566 259 -624 545 -354 527 -344 557 -294 569 -312 285 -586 283 -562 567 -312 527 -356 555 -312 547 -352 531 -346 267 -566 305 -580 547 -318 537 -300 277 -636 547 -318 279 -598 551 -302 551 -350 537 -304 277 -570 573 -310 279 -604 545 -328 311 -582 247 -598 547 -332 545 -314 279 -568 573 -294 565 -310 1077 -1150 551 -320 285 -606 545 -318 281 -604 207 -32700 231 -134 327 -622 361 -134 8003 -100 4115 -164 1395 -164 3469 -98 5967 -100 4997 -134 6541 -132 4213 -98 1445 -134 697 -238 5817 -134 1455 -132 3877 -130 12819 -100 4195 -134 1829 -100 1755 diff --git a/assets/unit_tests/subghz/gate_tx.sub b/assets/unit_tests/subghz/gate_tx.sub new file mode 100644 index 00000000000..3888ea25d60 --- /dev/null +++ b/assets/unit_tests/subghz/gate_tx.sub @@ -0,0 +1,7 @@ +Filetype: Flipper SubGhz Key File +Version: 1 +Frequency: 433920000 +Preset: FuriHalSubGhzPresetOok650Async +Protocol: GateTX +Bit: 24 +Key: 00 00 00 00 00 02 8F F3 diff --git a/assets/unit_tests/subghz/gate_tx_raw.sub b/assets/unit_tests/subghz/gate_tx_raw.sub new file mode 100644 index 00000000000..31a12f531c3 --- /dev/null +++ b/assets/unit_tests/subghz/gate_tx_raw.sub @@ -0,0 +1,11 @@ +Filetype: Flipper SubGhz RAW File +Version: 1 +Frequency: 433920000 +Preset: FuriHalSubGhzPresetOok650Async +Protocol: RAW +RAW_Data: 711 -646 413 -328 713 -680 381 -648 417 -326 747 -644 1509 -32700 711 -480 597 -454 595 -422 627 -424 659 -388 661 -422 631 -750 319 -394 675 -684 349 -718 339 -690 379 -358 663 -716 345 -716 379 -324 729 -682 379 -654 381 -650 411 -328 709 -322 719 -678 413 -648 381 -358 723 -680 349 -16580 767 -316 699 -350 701 -348 699 -350 701 -348 735 -314 731 -666 425 -304 729 -640 405 -640 403 -638 405 -318 741 -648 413 -648 415 -326 743 -648 417 -618 415 -650 379 -334 703 -344 727 -652 425 -654 385 -348 721 -668 355 -16578 747 -326 717 -324 751 -290 755 -320 723 -320 731 -322 733 -650 453 -292 737 -644 385 -650 417 -650 379 -332 735 -646 415 -648 415 -326 743 -642 387 -648 417 -650 379 -346 725 -314 717 -668 387 -668 423 -312 753 -628 393 -16568 771 -318 703 -322 731 -322 727 -322 727 -322 731 -352 703 -684 379 -352 707 -646 387 -680 385 -648 415 -328 705 -648 415 -648 415 -326 745 -648 383 -650 415 -650 379 -344 725 -348 685 -668 387 -686 383 -350 717 -666 355 -16568 767 -322 735 -322 725 -322 727 -320 723 -322 731 -324 731 -682 409 -320 709 -650 383 -656 405 -638 405 -318 739 -646 413 -640 413 -350 723 -648 409 -648 381 -654 417 -294 753 -322 725 -646 417 -648 419 -324 725 -650 377 -16592 737 -348 691 -350 719 -316 723 -318 725 -346 723 -332 741 -626 441 -304 741 -622 409 -624 431 -622 409 -332 721 -658 409 -644 407 -334 753 -628 405 -644 417 -622 417 -324 727 -318 725 -648 417 -648 419 -324 727 -648 383 -16574 763 -318 699 -350 701 -348 701 -350 701 -350 733 -320 731 -646 411 -348 699 -648 383 -676 387 -636 411 -344 701 -678 379 -672 409 -348 733 -624 385 -678 387 -638 391 -366 699 -346 701 -646 423 -636 421 -342 735 -648 347 -16582 781 -288 753 -320 725 -320 723 -320 729 -322 729 -322 731 -680 409 -320 709 -650 379 -672 383 -672 381 -318 749 -646 419 -650 417 -324 723 -648 419 -650 383 -650 379 -344 727 -346 685 -654 417 -640 417 -348 719 -654 383 -16578 745 -324 709 -324 747 -288 755 -318 725 -322 729 -322 769 -616 455 -292 735 -644 389 -648 419 -616 411 -346 727 -626 429 -622 417 -352 755 -624 381 -654 383 -680 385 -342 705 -336 715 -654 409 -648 419 -332 741 -648 385 -16560 763 -326 699 -336 707 -358 677 -354 705 -356 701 -354 705 -682 409 -320 711 -680 385 -648 383 -648 415 -328 709 -678 381 -648 415 -324 749 -646 385 -682 383 -650 377 -344 727 -346 683 -664 423 -640 403 -342 727 -652 +RAW_Data: 361 -16588 743 -320 735 -320 729 -320 729 -320 729 -320 735 -320 767 -612 439 -332 721 -646 375 -650 407 -662 397 -326 711 -656 407 -648 407 -334 759 -628 407 -652 377 -658 379 -332 725 -328 747 -650 417 -620 421 -326 731 -646 417 -16544 763 -326 731 -306 739 -296 745 -320 739 -322 737 -322 739 -650 419 -294 733 -648 385 -650 417 -652 379 -344 725 -652 389 -670 387 -348 753 -620 387 -678 383 -648 385 -344 719 -336 709 -656 405 -650 435 -326 709 -660 381 -16590 733 -348 701 -348 701 -350 703 -320 731 -352 699 -352 701 -676 413 -310 735 -654 385 -656 381 -650 385 -344 733 -648 415 -646 417 -348 701 -678 351 -674 379 -674 387 -342 701 -350 701 -680 387 -670 379 -346 733 -644 381 -16556 753 -352 691 -354 691 -356 693 -356 725 -354 695 -354 699 -682 377 -354 703 -680 383 -650 381 -650 415 -328 709 -680 381 -646 415 -356 721 -646 383 -684 381 -650 379 -342 723 -318 705 -686 399 -652 391 -346 721 -662 363 -16572 765 -322 733 -322 725 -320 725 -322 727 -322 729 -322 735 -648 419 -328 733 -646 385 -648 417 -650 379 -344 727 -658 397 -658 401 -344 725 -654 403 -620 383 -676 381 -350 725 -320 733 -646 395 -664 395 -368 705 -672 379 -32700 691 -546 435 -522 133 -520 533 -488 595 -454 595 -456 597 -790 305 -422 635 -718 309 -748 307 -712 339 -388 689 -680 375 -678 373 -390 663 -754 275 -752 311 -424 623 -716 343 -392 651 -712 379 -682 379 -356 723 -680 347 -16574 743 -342 709 -326 743 -290 737 -322 733 -320 731 -322 769 -614 453 -292 737 -644 387 -650 419 -614 447 -296 733 -638 419 -646 417 -326 743 -646 421 -612 421 -296 735 -646 417 -326 707 -672 419 -644 419 -292 751 -648 387 -16546 801 -324 691 -326 741 -320 707 -324 735 -322 731 -320 765 -648 409 -330 721 -648 377 -650 405 -644 409 -328 709 -658 409 -666 395 -330 741 -672 367 -646 411 -326 711 -654 409 -328 719 -654 417 -622 417 -326 735 -678 345 -16604 743 -312 721 -346 703 -318 737 -326 745 -322 721 -322 729 -646 441 -330 685 -648 419 -650 385 -650 415 -326 709 -644 419 -646 415 -324 749 -646 417 -614 419 -326 709 -646 415 -328 743 -612 417 -646 417 -324 749 -646 385 -16564 761 -316 729 -346 705 -332 715 -324 741 -324 705 -354 737 -650 411 -318 707 -646 409 -648 383 -652 419 -324 725 -644 417 -650 419 -324 725 -650 417 -616 417 -328 711 -648 415 -328 707 -642 417 -646 417 -324 749 -646 385 -16578 755 -298 741 -290 735 -322 733 -320 733 -322 +RAW_Data: 767 -288 769 -614 451 -294 737 -642 407 -648 385 -654 417 -294 753 -644 421 -616 451 -290 751 -646 419 -616 421 -296 737 -644 421 -296 771 -612 451 -614 449 -292 747 -646 385 -16582 749 -332 711 -322 709 -352 703 -322 729 -322 731 -354 701 -682 417 -326 703 -648 385 -650 413 -642 409 -318 713 -678 383 -682 383 -356 721 -648 383 -652 415 -328 711 -648 413 -328 709 -648 415 -648 413 -326 749 -646 385 -16538 779 -330 709 -326 705 -354 703 -324 733 -322 731 -354 703 -684 379 -350 707 -646 383 -682 381 -652 413 -326 707 -680 381 -648 413 -328 749 -646 383 -648 415 -326 707 -644 415 -326 711 -680 383 -648 415 -326 751 -646 383 -16558 757 -346 703 -346 703 -346 703 -346 703 -348 705 -340 743 -628 437 -326 711 -648 383 -654 417 -614 419 -328 743 -642 417 -646 417 -322 721 -646 417 -648 385 -328 713 -646 417 -328 707 -646 417 -648 415 -324 747 -646 385 -16582 723 -340 705 -338 707 -340 705 -376 703 -346 703 -348 701 -680 389 -344 701 -680 357 -664 379 -668 393 -368 707 -666 367 -654 435 -326 743 -632 405 -644 383 -328 733 -648 417 -324 721 -644 419 -648 417 -322 725 -650 383 -16576 733 -350 721 -332 715 -322 705 -322 735 -322 731 -322 769 -616 445 -318 709 -648 417 -616 417 -650 413 -298 737 -648 413 -646 413 -326 745 -644 419 -614 419 -326 707 -640 415 -326 743 -644 419 -616 451 -290 751 -644 385 -16560 773 -312 709 -330 743 -290 739 -322 731 -322 765 -290 769 -616 449 -294 735 -646 419 -616 417 -614 447 -310 725 -624 433 -656 403 -344 725 -654 391 -654 383 -350 689 -672 395 -326 709 -660 405 -652 415 -334 745 -650 383 -16548 761 -336 719 -322 707 -322 731 -322 731 -322 729 -322 767 -614 445 -318 709 -646 419 -616 417 -650 415 -310 731 -652 389 -666 421 -314 737 -644 419 -616 411 -346 687 -668 403 -346 721 -622 415 -638 431 -346 719 -656 357 -16578 745 -358 687 -354 687 -352 691 -356 723 -322 729 -354 699 -684 383 -358 669 -680 381 -682 347 -684 377 -360 709 -648 413 -648 415 -326 745 -646 383 -650 415 -328 707 -642 415 -328 711 -646 417 -648 415 -326 749 -646 383 -16548 747 -372 681 -362 675 -358 699 -354 701 -354 701 -356 701 -682 379 -362 709 -652 379 -652 415 -656 383 -326 729 -648 415 -650 415 -324 729 -680 377 -648 379 -356 709 -650 377 -350 703 -680 187 -32700 751 -408 653 -378 655 -412 645 -408 667 -370 671 -366 705 -696 369 -358 675 -686 349 -716 337 -716 337 -354 707 -684 379 -690 +RAW_Data: 367 -360 709 -662 373 -678 379 -330 733 -324 725 -648 417 -650 381 -680 417 -324 721 -648 381 -16570 757 -332 711 -324 711 -320 731 -322 731 -322 765 -290 769 -614 451 -324 705 -646 385 -650 417 -650 413 -310 727 -658 399 -660 399 -344 723 -658 403 -630 391 -352 687 -354 725 -618 423 -638 421 -638 423 -340 737 -644 365 -16584 751 -318 721 -318 723 -336 719 -322 741 -322 739 -320 739 -648 411 -320 709 -648 407 -648 415 -618 409 -322 743 -650 409 -646 407 -322 747 -652 383 -652 409 -320 709 -322 735 -648 417 -648 417 -650 419 -290 753 -648 385 -16582 753 -330 711 -322 705 -324 731 -322 729 -322 731 -322 767 -648 411 -320 707 -644 419 -646 385 -648 415 -328 707 -676 387 -646 415 -326 745 -646 419 -614 417 -328 703 -320 719 -676 385 -646 419 -648 417 -324 747 -646 385 -16542 773 -340 701 -370 647 -392 673 -354 705 -354 705 -356 703 -682 383 -358 705 -646 385 -650 415 -652 379 -342 727 -650 389 -668 389 -346 757 -652 353 -684 383 -348 691 -346 703 -670 365 -690 397 -660 397 -328 741 -670 345 -16570 747 -350 721 -318 721 -320 731 -346 707 -336 711 -328 747 -652 409 -332 707 -654 375 -672 377 -654 415 -332 707 -648 419 -650 419 -324 729 -648 419 -648 385 -326 711 -324 715 -676 385 -646 419 -648 415 -326 747 -644 383 -16554 765 -348 671 -380 673 -378 675 -378 673 -380 673 -380 703 -676 381 -346 705 -642 381 -674 387 -672 389 -340 703 -676 387 -672 389 -342 737 -646 385 -670 379 -340 703 -346 705 -642 411 -640 393 -668 423 -340 733 -642 363 -16594 745 -312 723 -352 689 -354 693 -350 733 -308 723 -328 749 -652 419 -328 707 -644 387 -648 417 -650 379 -348 725 -628 429 -624 433 -346 725 -656 401 -620 385 -352 723 -322 725 -628 407 -648 417 -664 419 -294 769 -646 387 -16526 761 -370 649 -392 673 -356 703 -356 697 -354 699 -354 703 -682 383 -360 705 -648 383 -650 415 -652 375 -344 727 -652 389 -668 389 -346 721 -684 355 -672 385 -348 691 -348 719 -666 369 -688 379 -666 407 -320 741 -654 381 -16572 753 -320 723 -320 731 -308 725 -324 747 -322 737 -290 769 -648 415 -318 707 -646 419 -612 421 -648 417 -296 735 -644 419 -646 419 -324 745 -646 387 -650 419 -296 735 -324 711 -642 419 -646 419 -646 415 -326 745 -644 387 -16536 783 -328 681 -358 703 -354 703 -354 697 -354 701 -354 701 -682 383 -360 703 -646 381 -650 417 -650 377 -330 741 -648 411 -648 413 -326 745 -646 381 -650 415 -346 689 -318 739 -650 +RAW_Data: 411 -650 377 -684 411 -344 695 -654 373 -16580 737 -354 703 -322 725 -320 727 -322 727 -322 731 -324 765 -648 407 -330 709 -652 377 -652 407 -646 407 -318 743 -650 407 -628 433 -328 743 -630 417 -622 419 -324 721 -322 721 -646 417 -648 385 -648 419 -324 749 -646 387 -16560 743 -372 671 -360 673 -356 703 -354 703 -356 701 -354 701 -684 379 -360 709 -652 385 -652 381 -684 381 -326 715 -678 383 -682 381 -356 717 -648 381 -682 381 -326 709 -352 689 -680 381 -682 381 -648 415 -324 749 -648 385 -16566 745 -334 721 -322 739 -288 735 -324 729 -322 733 -322 767 -616 453 -294 733 -644 385 -650 417 -650 413 -310 727 -618 421 -656 417 -350 719 -642 393 -654 385 -352 721 -316 721 -632 403 -650 449 -600 445 -318 745 -652 377 -16576 739 -332 701 -332 733 -326 711 -324 749 -320 725 -322 733 -678 407 -330 713 -650 383 -652 387 -648 419 -326 741 -642 419 -646 419 -292 751 -648 419 -616 419 -296 737 -326 711 -676 387 -646 419 -646 417 -326 745 -646 387 -32700 811 -300 743 -300 735 -326 739 -294 765 -294 763 -290 767 -620 441 -324 743 -618 413 -616 447 -616 437 -276 763 -614 455 -602 455 -286 771 -642 413 -310 695 -342 721 -346 719 -316 721 -646 419 -644 419 -346 721 -646 385 -16522 805 -364 649 -374 691 -376 653 -376 687 -378 689 -378 689 -670 387 -378 687 -676 353 -672 359 -702 359 -366 715 -630 403 -688 399 -328 739 -630 399 -320 743 -292 767 -292 733 -324 731 -650 413 -652 413 -324 761 -618 411 -16524 801 -352 647 -374 677 -366 671 -390 675 -358 701 -356 703 -686 373 -386 673 -652 413 -650 379 -652 411 -328 719 -650 411 -652 411 -326 747 -648 413 -294 721 -326 719 -324 749 -290 755 -648 413 -650 415 -324 759 -618 383 -16558 801 -318 703 -332 709 -326 707 -324 735 -322 735 -322 767 -620 443 -320 705 -646 409 -648 413 -618 417 -324 727 -646 417 -648 409 -324 741 -650 403 -318 741 -290 733 -322 729 -322 733 -646 417 -648 415 -326 759 -616 417 -16550 745 -334 713 -322 739 -322 703 -322 733 -324 733 -322 767 -646 407 -322 711 -646 411 -648 411 -624 411 -330 741 -626 411 -660 395 -332 751 -630 399 -322 745 -322 703 -322 733 -322 731 -650 415 -648 413 -328 725 -648 411 -16540 769 -342 689 -348 689 -350 725 -350 691 -346 733 -306 751 -630 433 -328 707 -654 379 -656 415 -652 381 -326 747 -642 417 -648 415 -324 723 -646 411 -320 709 -322 735 -320 727 -322 729 -652 415 -652 419 -322 725 -648 381 -16578 733 -382 +RAW_Data: 663 -374 671 -364 707 -326 741 -322 701 -354 741 -652 411 -320 709 -648 417 -652 381 -650 411 -328 711 -646 415 -648 413 -344 733 -650 377 -344 723 -310 721 -350 685 -350 721 -648 387 -676 389 -380 717 -644 363 -16572 775 -326 707 -320 715 -324 751 -320 725 -320 729 -322 763 -616 443 -330 707 -650 377 -652 411 -624 433 -324 707 -670 397 -658 411 -342 717 -668 365 -354 705 -334 711 -326 741 -320 705 -648 415 -654 415 -326 761 -618 415 -16538 725 -402 637 -394 671 -390 673 -356 703 -356 699 -356 701 -684 379 -360 701 -648 379 -686 379 -652 411 -328 709 -648 411 -648 415 -326 749 -648 383 -328 717 -324 715 -352 721 -320 729 -644 415 -648 415 -324 727 -678 349 -16576 743 -372 673 -360 677 -356 705 -354 705 -324 733 -322 733 -682 409 -320 707 -650 415 -650 381 -650 411 -328 711 -648 413 -648 415 -326 753 -646 379 -328 719 -324 717 -324 717 -352 723 -648 417 -648 417 -324 727 -646 381 -16562 769 -344 683 -362 709 -324 707 -324 733 -352 703 -324 731 -684 409 -330 715 -650 381 -654 415 -618 415 -326 715 -648 413 -650 415 -326 751 -646 383 -328 717 -326 717 -354 723 -320 723 -648 417 -650 415 -324 727 -648 381 -16572 773 -306 741 -296 741 -322 735 -322 707 -324 765 -290 765 -612 449 -326 703 -644 415 -618 417 -650 403 -346 721 -628 427 -628 431 -310 757 -626 433 -312 689 -350 719 -316 731 -342 735 -606 431 -660 395 -330 751 -630 379 -16570 779 -308 729 -344 687 -346 721 -314 721 -350 723 -350 695 -676 411 -350 693 -642 395 -658 395 -658 397 -324 739 -638 395 -664 393 -334 737 -668 365 -356 707 -324 707 -352 705 -322 733 -648 415 -656 415 -326 729 -650 381 -16566 769 -346 687 -350 691 -348 701 -338 717 -326 745 -326 741 -652 415 -328 705 -644 415 -646 379 -650 413 -328 711 -682 381 -650 413 -328 751 -646 379 -328 715 -352 691 -340 705 -362 711 -650 413 -650 411 -328 745 -646 381 -16562 745 -326 711 -322 733 -322 731 -322 731 -322 731 -322 765 -618 443 -318 705 -648 417 -648 381 -652 413 -326 711 -646 415 -648 413 -326 749 -646 415 -294 747 -318 725 -290 753 -320 729 -646 415 -650 419 -324 727 -648 diff --git a/assets/unit_tests/subghz/hormann_hsm_raw.sub b/assets/unit_tests/subghz/hormann_hsm_raw.sub new file mode 100644 index 00000000000..bf82d46cfe1 --- /dev/null +++ b/assets/unit_tests/subghz/hormann_hsm_raw.sub @@ -0,0 +1,10 @@ +Filetype: Flipper SubGhz RAW File +Version: 1 +Frequency: 868350000 +Preset: FuriHalSubGhzPresetOok650Async +Protocol: RAW +RAW_Data: 1718, -32700, 32700, -32700, 11939, -494, 1047, -496, 1015, -516, 1041, -476, 1037, -510, 1035, -512, 1035, -484, 1047, -492, 1031, -504, 513, -1042, 499, -1020, 1041, -512, 511, -1004, 1035, -512, 507, -1042, 481, -1050, 1017, -522, 489, -1040, 1013, -514, 513, -1010, 543, -1008, 513, -1012, 1045, -522, 1003, -512, 1029, -518, 1009, -514, 1039, -476, 541, -1004, 509, -1038, 1035, -482, 539, -1008, 1033, -490, 539, -1018, 1009, -508, 1059, -482, 1041, -512, 1005, -508, 541, -1006, 513, -1008, 535, -1000, 1035, -522, 525, -1016, 515, -1006, 1021, -514, 1045, -478, 12441, -482, 1045, -512, 1005, -512, 1035, -514, 1037, -482, 1035, -520, 1031, -504, 1035, -486, 1041, -510, 501, -1018, 513, -1042, 1007, -512, 509, -1042, 1007, -506, 541, -1010, 507, -1016, 1031, -520, 513, -1010, 1021, -516, 515, -1046, 477, -1042, 513, -1012, 1051, -484, 1043, -512, 1027, -484, 1043, -514, 1007, -512, 509, -1040, 507, -1036, 1011, -526, 493, -1032, 1033, -486, 509, -1056, 1011, -514, 1007, -512, 1037, -514, 1001, -516, 507, -1034, 517, -1036, 493, -1018, 1041, -502, 525, -1016, 513, -1040, 1005, -512, 1033, -506, 12423, -478, 1039, -514, 1009, -516, 1033, -522, 1001, -522, 1039, -510, 1027, -484, 1041, -512, 1007, -510, 509, -1038, 507, -1034, 1037, -482, 507, -1042, 1037, -520, 487, -1014, 527, -1022, 1007, -512, 509, -1038, 1037, -512, 509, -1008, 507, -1044, 507, -1018, 1027, -514, 1005, -528, 1017, -514, 1041, -512, 1003, -512, 509, -1042, 507, -1010, 1035, -520, 507, -1018, 1033, -508, 511, -1038, 991, -516, 1041, -512, 1005, -512, 1035, -514, 507, -1040, 507, -1014, 519, -1014, 1041, -510, 499, -1018, 515, -1046, 1005, -514, 1011, -520, 12425, -480, 1035, -516, 1035, -492, 1031, -522, 1009, -508, 1021, -518, 1041, -512, 1007, -512, 1037, -512, 509, -1008, 519, -1016, 1029, -522, 513, -1008, 1025, -516, 515, -1044, 479, -1038, 1037, -482, 541, -1008, 1035, -520, 507, -1010, 503, -1026, 515, -1042, 1005, -512, 1037, -512, 1005, -520, 1015, -520, 1039, -510, 499, -1018, 515, -1042, 1007, -512, 507, -1040, 1011, -520, 507, -1016, 1031, -520, 1009, -540, 989, -518, 1043, -512, 511, -1006, 507, -1038, 505, -1036, 1001, -516, 509, -1050, 491, -1052, 1009, -500, 1021, -516, 12409, -524, 1015, -516, 1009, -510, 1037, -512, 1033, -506, 1039, -480, 1035, -524, 1019, -522, 1015, -500, 525, -1014, 515, -1040, 1005, -512, 509, -1042, 1011, -524, 493, -1018, 517, -1036, 1017, -514, 515, -1008, 1035, -514, 507, -1040, 505, -1034, 507, -1010, 1035, -492, 1031, -520, 1009, -540, 991, -516, 1043, -514, 511, -1010, 513, -1044, 1015, -492, 531, -1020, 1009, -528, 521, -1012, 1009, -510, 1037, -512, 1037, -482, 1033, -518, 505, -1032, 507, -1016, 537, -1000, 1025, -520, 513, -1034, 519, -1010, 1007, -512, 1039, -514, 12395, -510, 1037, -512, 1037, -482, 1045, -490, 1057, -488, 1045, -496, 1017, -516, 1041, -514, 1005, -512, 507, -1046, 481, -1044, 1035, -494, 505, -1048, 1011, -502, 527, -1018, 513, -1042, 1005, -516, 513, -1010, 1035, -520, 505, -1032, 507, -1022, 503, -1034, 1013, -504, 1023, -516, 1041, -512, 1005, -512, 1037, -514, 507, -1010, 519, -1050 +RAW_Data: 989, -520, 517, -1034, 1015, -516, 513, -1008, 1039, -512, 1035, -484, 1049, -520, 1001, -514, 503, -1018, 515, -1044, 513, -1008, 1041, -482, 541, -1012, 523, -1016, 1011, -540, 991, -516, 12415, -524, 1015, -516, 1039, -508, 1003, -512, 1033, -506, 1037, -514, 1001, -506, 1033, -520, 1033, -520, 475, -1046, 499, -1022, 1041, -512, 511, -1008, 1039, -516, 515, -1014, 489, -1050, 1011, -504, 529, -1020, 1009, -512, 511, -1040, 515, -1010, 519, -1018, 1031, -520, 1009, -538, 995, -516, 1041, -512, 1007, -514, 513, -1042, 509, -1008, 1039, -520, 477, -1042, 1029, -520, 481, -1042, 1007, -512, 1037, -512, 1035, -486, 1045, -522, 475, -1044, 501, -1024, 513, -1042, 1005, -512, 509, -1040, 509, -1008, 1035, -520, 999, -522, 12417, -520, 1007, -524, 1013, -516, 1039, -512, 1007, -516, 1007, -538, 1001, -506, 1033, -518, 1033, -506, 503, -1040, 489, -1052, 1015, -500, 525, -1016, 1007, -512, 541, -1010, 513, -1012, 1049, -520, 477, -1044, 1025, -518, 483, -1044, 513, -1008, 511, -1038, 1033, -508, 1001, -518, 1037, -490, 1031, -522, 1007, -542, 495, -1020, 515, -1012, 1039, -514, 515, -1012, 1015, -520, 513, -1042, 1025, -484, 1043, -512, 1007, -510, 1037, -514, 507, -1012, 519, -1020, 531, -1016, 1007, -530, 521, -1014, 513, -1010, 1045, -482, 1049, -492, 12413, -504, 1033, -504, 1031, -522, 1009, -542, 993, -516, 1041, -512, 1005, -514, 1035, -508, 1037, -482, 541, -1008, 509, -1046, 999, -522, 513, -1008, 1055, -482, 515, -1042, 511, -1008, 1037, -514, 507, -1010, 1035, -520, 507, -1018, 503, -1034, 503, -1050, 1013, -502, 1019, -516, 1043, -510, 1007, -512, 1035, -514, 507, -1008, 505, -1032, 1033, -506, 505, -1046, 1033, -486, 513, -1040, 1025, -518, 1011, -514, 1009, -512, 1037, -512, 509, -1010, 517, -1020, 531, -1018, 1007, -528, 521, -1012, 513, -1040, 1007, -512, 1037, -482, 12425, -512, 1035, -514, 1001, -518, 1031, -506, 1035, -490, 1033, -504, 1033, -502, 1037, -514, 1027, -520, 485, -1044, 511, -1006, 1037, -514, 507, -1042, 1005, -524, 493, -1050, 483, -1034, 1019, -516, 513, -1012, 1037, -514, 505, -1040, 481, -1036, 517, -1036, 1019, -508, 1007, -542, 993, -516, 1043, -512, 1007, -512, 507, -1036, 509, -1044, 1009, -506, 505, -1038, 1017, -520, 513, -1008, 1021, -514, 1041, -514, 1007, -512, 1037, -512, 509, -1012, 521, -1016, 521, -1010, 1033, -520, 519, -1012, 513, -1008, 1033, -508, 1037, -512, 12407, -512, 1005, -512, 1037, -512, 1033, -506, 1033, -506, 1037, -482, 1035, -522, 999, -520, 1041, -512, 497, -1020, 515, -1046, 1005, -516, 513, -1012, 1049, -486, 513, -1044, 497, -1020, 1045, -512, 479, -1038, 1039, -484, 515, -1034, 507, -1048, 507, -1014, 1007, -542, 1025, -484, 1047, -512, 1009, -512, 1035, -514, 509, -1008, 507, -1052, 1019, -522, 483, -1034, 1017, -516, 513, -1012, 1039, -512, 1035, -482, 1033, -506, 1035, -524, 493, -1030, 513, -1010, 527, -1016, 1043, -512, 511, -1010, 515, -1008, 1035, -522, 1019, -506, 12409, -506, 1033, -522, 1033, -486, 1041, -512, 1029, -484, 1043, -514, 1005, -512, 1037, -512, 1035, -484, 519, -1016, 531, -1018, 1009, -528, 521, -1012, 1041, -510, 509, -1006 +RAW_Data: 509, -1044, 1009, -524, 491, -1032, 1017, -516, 505, -1058, 483, -1042, 511, -1008, 1039, -514, 1001, -516, 1033, -508, 1015, -522, 1041, -512, 497, -1020, 515, -1042, 1007, -514, 507, -1046, 1009, -492, 537, -1016, 1009, -542, 995, -516, 1045, -512, 1007, -514, 513, -1012, 517, -1020, 529, -1020, 1009, -528, 519, -1012, 513, -1010, 1043, -516, 1009, -524, 12405, -490, 1057, -512, 1009, -504, 1023, -516, 1043, -512, 1005, -512, 1037, -514, 1001, -520, 1017, -520, 513, -1010, 527, -1018, 1043, -512, 511, -1006, 1033, -508, 507, -1040, 509, -1008, 1033, -504, 507, -1034, 1015, -522, 513, -1008, 525, -1016, 513, -1046, 1007, -514, 1009, -518, 1035, -490, 1031, -520, 1041, -510, 497, -1020, 515, -1044, 1005, -516, 515, -1012, 1013, -522, 513, -1038, 1029, -516, 1011, -512, 1009, -514, 1041, -482, 541, -1012, 523, -1016, 513, -1008, 1021, -516, 517, -1042, 511, -1008, 1043, -482, 1033, -520, 12405, -512, 1037, -514, 1003, -518, 1033, -492, 1031, -506, 1031, -520, 1009, -540, 993, -518, 1043, -512, 513, -1010, 513, -1040, 1005, -524, 493, -1050, 1013, -500, 525, -1014, 513, -1044, 1007, -512, 509, -1040, 1001, -522, 489, -1050, 513, -1008, 527, -1014, 1041, -512, 1003, -512, 1039, -514, 1003, -520, 1017, -504, 537, -1016, 511, -1042, 989, -518, 513, -1042, 1005, -508, 507, -1036, 1037, -516, 1009, -506, 1031, -506, 1035, -490, 539, -1022, 505, -1034, 509, -1008, 1031, -522, 517, -1014, 511, -1006, 1039, -512, 1033, -506, 12415, -514, 1005, -512, 1035, -514, 1035, -482, 1035, -524, 1019, -524, 1015, -498, 1019, -516, 1041, -510, 511, -1006, 507, -1038, 1039, -486, 517, -1036, 1017, -522, 513, -1008, 525, -1016, 1009, -512, 541, -1004, 1033, -508, 507, -1040, 481, -1048, 489, -1050, 1007, -540, 989, -516, 1045, -514, 1005, -512, 1037, -512, 509, -1008, 505, -1034, 1047, -520, 479, -1044, 1027, -516, 483, -1044, 1007, -512, 1037, -514, 1003, -518, 1015, -520, 515, -1044, 497, -1018, 515, -1046, 1005, -514, 515, -1014, 519, -1020, 1029, -520, 1007, -524, 12421, -494, 1017, -516, 1039, -514, 1005, -512, 1035, -514, 1003, -516, 1037, -492, 1031, -522, 1009, -508, 527, -1016, 515, -1040, 1003, -510, 507, -1038, 1037, -482, 539, -1004, 519, -1018, 1029, -520, 513, -1026, 1015, -516, 513, -1010, 511, -1044, 515, -1010, 1035, -492, 1029, -520, 1009, -528, 1015, -514, 1041, -510, 509, -1006, 509, -1044, 1009, -520, 507, -1018, 1031, -522, 515, -1004, 1019, -516, 1045, -512, 1009, -514, 1009, -518, 507, -1044, 509, -1016, 513, -1042, 991, -518, 515, -1044, 511, -1006, 1033, -508, 1035, -482, 12435, -506, 1035, -482, 1031, -508, 1047, -492, 1033, -520, 1007, -540, 989, -516, 1045, -512, 1007, -512, 507, -1036, 509, -1040, 1001, -518, 505, -1038, 1015, -504, 511, -1044, 499, -1018, 1043, -512, 513, -1006, 1039, -512, 507, -1040, 481, -1034, 519, -1020, 1029, -518, 1007, -526, 1015, -514, 1009, -510, 1037, -512, 507, -1040, 505, -1034, 1003, -520, 523, -1018, 1013, -504, 527, -1018, 1041, -512, 1003, -514, 1035, -514, 1001, -518, 505, -1034, 521, -1020, 501, -1048, 1005, -526, 517, -1012, 513, -1010, 1039, -512, 1005, -516, 12427, -512 +RAW_Data: 1033, -506, 1003, -520, 1015, -522, 1039, -512, 1023, -516, 1011, -514, 1007, -510, 1039, -514, 507, -1010, 507, -1044, 1035, -520, 487, -1048, 991, -516, 515, -1046, 511, -1008, 1011, -516, 505, -1032, 1035, -492, 537, -1016, 511, -1040, 497, -1020, 1043, -510, 1007, -512, 1037, -514, 1003, -516, 1033, -504, 505, -1034, 507, -1016, 1033, -520, 521, -1010, 1017, -516, 515, -1040, 1001, -508, 1037, -512, 1035, -482, 1035, -520, 491, -1032, 505, -1048, 513, -1010, 1019, -516, 515, -1042, 509, -1008, 1043, -484, 1049, -522, 12373, -520, 1045, -498, 1021, -514, 1007, -512, 1039, -514, 1035, -482, 1033, -522, 1017, -520, 1017, -504, 525, -1018, 515, -1010, 1039, -514, 507, -1040, 1003, -518, 507, -1016, 505, -1030, 1031, -520, 515, -1006, 1025, -516, 515, -1042, 509, -1008, 507, -1044, 1007, -520, 1031, -506, 1033, -494, 1031, -522, 1011, -504, 527, -1018, 513, -1010, 1041, -514, 507, -1008, 1033, -506, 505, -1032, 1035, -492, 1035, -520, 1009, -542, 991, -518, 515, -1042, 511, -1008, 513, -1046, 1011, -492, 505, -1050, 513, -1006, 1021, -514, 1041, -512, 12415, -484, 1045, -514, 1005, -512, 1033, -508, 1035, -514, 1001, -540, 1009, -522, 999, -520, 1039, -512, 499, -1018, 515, -1044, 1005, -512, 509, -1040, 1003, -520, 523, -1016, 517, -1012, 1019, -514, 517, -1042, 1005, -514, 505, -1042, 513, -1004, 517, -1020, 1025, -514, 1043, -496, 1019, -516, 1011, -512, 1037, -508, 509, -1040, 509, -1008, 1035, -520, 507, -1018, 1031, -522, 481, -1038, 1019, -516, 1011, -512, 1041, -512, 1037, -484, 515, -1034, 507, -1020, 519, -1018, 1035, -520, 485, -1044, 511, -1012, 1043, -484, 1047, -492, 12433, -492, 1033, -520, 1009, -506, 1023, -516, 1041, -514, 1005, -512, 1037, -512, 1003, -516, 1035, -520, 507, -1018, 505, -1050, 1011, -500, 525, -1014, 1041, -512, 509, -1010, 513, -1042, 1001, -522, 489, -1050, 1015, -502, 529, -1016, 513, -1040, 509, -1004, 1037, -514, 999, -538, 1001, -506, 1035, -520, 1017, -522, 513, -1008, 527, -1018, 1011, -514, 511, -1036, 1037, -482, 517, -1046, 1001, -536, 1001, -520, 1043, -510, 1025, -482, 517, -1044, 511, -1010, 513, -1042, 1001, -506, 505, -1036, 519, -1020, 1027, -514, 1009, -528, 12397, -526, 1015, -514, 1043, -510, 1003, -512, 1037, -512, 1001, -520, 1047, -520, 1005, -512, 1031, -516, 483, -1044, 513, -1006, 1035, -514, 507, -1040, 1001, -508, 521, -1016, 505, -1050, 1009, -504, 529, -1016, 1045, -478, 511, -1038, 509, -1042, 505, -1034, 1001, -520, 1033, -494, 1029, -520, 1009, -528, 1015, -514, 513, -1038, 511, -1004, 1041, -482, 541, -1010, 1033, -492, 505, -1052, 1009, -504, 1023, -518, 1041, -512, 1011, -514, 513, -1040, 509, -1010, 507, -1016, 1031, -520, 521, -1010, 523, -1016, 1009, -514, 1041, -512, 12391, -540, 1003, -512, 1037, -512, 1001, -518, 1045, -508, 1019, -522, 1007, -504, 1021, -518, 1045, -510, 511, -1008, 513, -1046, 1009, -490, 539, -1016, 1009, -542, 495, -1018, 515, -1014, 1039, -516, 517, -1008, 1037, -520, 485, -1050, 495, -1020, 515, -1044, 1007, -514, 1035, -484, 1035, -520, 999, -520, 1039, -512, 499, -1018, 515, -1044, 1005, -512, 507, -1038, 1009, -516 +RAW_Data: 507, -1044, 1035, -484, 1041, -510, 1027, -518, 1011, -514, 511, -1010, 511, -1042, 515, -1008, 1035, -492, 533, -1018, 513, -1032, 1013, -514, 1011, -512, 12423, -512, 1005, -512, 1037, -512, 1037, -480, 1035, -522, 1015, -502, 1037, -512, 1033, -520, 1011, -514, 513, -1006, 509, -1038, 1035, -516, 507, -1010, 1035, -490, 539, -1014, 513, -1010, 1021, -518, 513, -1040, 1005, -508, 509, -1040, 513, -1014, 515, -1034, 1035, -520, 1007, -514, 1025, -518, 1011, -514, 1007, -512, 509, -1038, 509, -1040, 1003, -524, 491, -1050, 1009, -504, 527, -1018, 1009, -510, 1039, -512, 1037, -484, 1045, -490, 539, -1022, 505, -1016, 503, -1054, 1011, -514, 513, -1008, 509, -1040, 1005, -538, 1005, -516, 12403, -508, 1037, -512, 1033, -506, 1035, -484, 1045, -504, 1035, -520, 1001, -514, 1029, -522, 1011, -514, 511, -1010, 513, -1044, 1009, -522, 491, -1050, 1009, -504, 527, -1018, 515, -1040, 1005, -514, 507, -1042, 1001, -506, 517, -1046, 507, -1022, 503, -1020, 1043, -498, 1021, -516, 1041, -512, 1007, -514, 1009, -516, 505, -1034, 505, -1034, 1035, -492, 537, -1016, 1009, -538, 495, -1020, 1043, -512, 1003, -512, 1033, -508, 1035, -484, 517, -1046, 507, -1016, 513, -1040, 1025, -482, 517, -1042, 509, -1008, 1039, -514, 1003, -520, 12435, -484, 1047, -522, 1001, -514, 1033, -486, 1045, -514, 1005, -508, 1037, -514, 1009, -518, 1037, -490, 539, -1018, 513, -1008, 1021, -516, 513, -1040, 1007, -514, 515, -1040, 509, -1010, 1035, -494, 503, -1034, 1029, -520, 513, -1028, 487, -1048, 513, -1010, 1043, -484, 1047, -520, 1005, -514, 1031, -518, 1011, -514, 511, -1006, 509, -1038, 1035, -482, 541, -1008, 1035, -520, 507, -1012, 1031, -522, 1011, -514, 1005, -512, 1035, -508, 513, -1040, 505, -1040, 483, -1046, 1001, -520, 513, -1042, 497, -1016, 1043, -512, 1001, -508, 12423, -514, 1039, -510, 1005, -512, 1037, -512, 1001, -508, 1041, -506, 1031, -506, 1035, -492, 1025, -520, 515, -1032, 519, -1010, 1007, -512, 509, -1038, 1037, -514, 505, -1034, 509, -1010, 1033, -520, 475, -1042, 1029, -520, 485, -1042, 513, -1010, 513, -1044, 1011, -522, 999, -536, 999, -522, 1043, -510, 1025, -518, 483, -1042, 509, -1008, 1041, -514, 509, -1012, 1013, -520, 513, -1044, 991, -516, 1043, -514, 1007, -514, 1043, -484, 517, -1048, 507, -1014, 513, -1040, 991, -518, 515, -1040, 511, -1010, 1043, -482, 1047, -522, 12403, -522, 1013, -498, 1019, -516, 1041, -512, 1005, -514, 1033, -508, 1035, -484, 1045, -492, 1031, -520, 515, -1006, 527, -1018, 1013, -512, 511, -1038, 1035, -482, 541, -1008, 507, -1032, 1037, -494, 505, -1032, 1031, -508, 511, -1042, 497, -1020, 515, -1042, 1007, -512, 1035, -482, 1033, -520, 1035, -520, 1001, -514, 501, -1054, 481, -1044, 1005, -508, 511, -1038, 1035, -484, 517, -1046, 1001, -520, 1041, -510, 1025, -518, 1009, -512, 511, -1010, 513, -1044, 481, -1048, 1015, -504, 511, -1044, 499, -1018, 1043, -512, 1005, -512, 12409, -516, 1041, -510, 1005, -512, 1035, -512, 1037, -482, 1033, -520, 1035, -520, 1003, -512, 1029, -520, 483, -1044, 513, -1006, 1035, -508, 513, -1040, 1003, -518, 507, -1016, 505, -1048, 1007, -540, 497, -1016 diff --git a/assets/unit_tests/subghz/ido_117_111_raw.sub b/assets/unit_tests/subghz/ido_117_111_raw.sub new file mode 100644 index 00000000000..d2c59593399 --- /dev/null +++ b/assets/unit_tests/subghz/ido_117_111_raw.sub @@ -0,0 +1,10 @@ +Filetype: Flipper SubGhz RAW File +Version: 1 +Frequency: 433920000 +Preset: FuriHalSubGhzPresetOok650Async +Protocol: RAW +RAW_Data: 32700 -4524 475 -1412 481 -538 465 -1440 481 -500 491 -1408 481 -526 449 -508 475 -552 475 -1450 465 -516 481 -1432 479 -1446 473 -514 473 -1408 481 -502 487 -1438 481 -1430 499 -1444 449 -1448 481 -1408 509 -484 483 -514 449 -1448 481 -1440 477 -1448 473 -518 479 -1446 473 -518 477 -1410 481 -1430 475 -1402 469 -1476 481 -1450 463 -516 481 -516 481 -490 499 -1412 487 -1428 481 -1406 469 -1472 473 -1436 479 -522 473 -520 481 -1426 473 -1442 461 -510 477 -1418 479 -1394 4437 -4508 509 -1410 511 -508 469 -1442 481 -498 491 -1406 483 -492 483 -506 475 -552 475 -1444 467 -516 481 -1438 479 -1414 505 -484 507 -1406 483 -498 487 -1438 483 -1426 503 -1402 509 -1406 507 -1410 487 -504 489 -480 479 -1412 495 -1468 471 -518 481 -1414 511 -510 465 -516 479 -516 481 -1394 493 -480 507 -540 477 -514 473 -1446 467 -516 481 -512 473 -504 473 -522 483 -498 487 -510 481 -1462 487 -498 489 -1406 485 -1450 477 -1406 501 -1410 459 -1438 483 -1382 4443 -4528 481 -1416 497 -514 481 -1440 477 -488 513 -1402 481 -490 481 -510 471 -538 475 -1442 505 -484 515 -1406 481 -1420 479 -506 495 -1406 483 -490 481 -1464 483 -1428 487 -1446 461 -1438 479 -1416 495 -514 477 -482 505 -1414 479 -1438 481 -1452 475 -1434 473 -506 479 -1428 473 -1434 475 -488 497 -514 475 -1444 469 -1442 483 -1450 479 -1406 509 -1406 481 -504 493 -478 509 -482 471 -1482 483 -1404 517 -492 491 -512 479 -1438 477 -484 481 -510 473 -1428 465 -1404 4437 -4530 467 -1442 487 -504 493 -1438 483 -496 489 -1406 481 -490 515 -478 481 -526 485 -1426 517 -510 477 -1404 509 -1408 481 -504 491 -1404 481 -492 481 -1464 481 -1430 501 -1410 485 -1430 483 -1434 479 -488 513 -476 473 -1440 463 -1474 471 -520 481 -1412 513 -1404 499 -486 509 -1408 483 -1426 471 -1408 487 -542 471 -1434 475 -520 471 -1450 479 -514 479 -504 471 -506 483 -1396 487 -544 469 -514 515 -1404 483 -1450 471 -1414 483 -504 481 -1430 475 -1404 501 -1378 4469 -4486 483 -1454 471 -514 481 -1418 511 -510 465 -1438 485 -494 483 -480 479 -524 483 -1448 481 -514 481 -1442 467 -1438 481 -500 489 -1408 479 -492 481 -1470 483 -1422 471 -1440 471 -1452 479 -1408 509 -484 481 -514 483 -1414 479 -1442 481 -522 489 -510 479 -512 475 -520 471 -522 483 -496 485 -1404 479 -1448 471 -514 511 -1410 481 -538 465 -1436 483 -496 487 -478 509 -1406 467 -1474 477 -1438 461 -1448 481 -1418 491 -512 479 -1408 505 -484 481 -1406 505 -1374 4449 -4530 463 -1442 483 -500 495 -1440 483 -496 489 -1406 481 -492 515 -480 481 -522 507 -1414 483 -512 +RAW_Data: 479 -1444 469 -1440 483 -500 489 -1400 481 -492 481 -1462 481 -1430 499 -1412 483 -1450 479 -1404 507 -484 481 -512 473 -1414 491 -1436 481 -1432 497 -520 479 -520 485 -1406 479 -1418 481 -504 491 -478 509 -514 475 -516 505 -492 521 -488 505 -484 481 -514 477 -1430 463 -482 509 -540 475 -514 475 -522 489 -1418 477 -524 459 -522 481 -1412 481 -1426 479 -1404 4437 -4516 477 -1444 471 -514 479 -1412 511 -510 463 -1440 483 -494 485 -480 481 -524 483 -1458 487 -510 475 -1428 479 -1412 503 -486 509 -1408 483 -496 485 -1438 481 -1428 501 -1416 483 -1432 477 -1434 479 -488 515 -480 479 -1414 489 -1434 505 -518 481 -520 485 -1400 483 -526 485 -1398 483 -1416 481 -506 489 -1436 483 -1456 473 -522 483 -1422 473 -1442 459 -520 479 -1416 483 -498 487 -1436 481 -536 463 -514 483 -1438 477 -522 483 -478 477 -506 487 -1428 483 -1398 4431 -4516 467 -1438 489 -506 493 -1434 483 -498 489 -1404 485 -492 513 -474 475 -550 473 -1444 469 -516 481 -1436 479 -1414 503 -486 509 -1406 481 -500 485 -1434 481 -1430 503 -1428 487 -1402 515 -1418 479 -510 463 -514 479 -1406 469 -1476 477 -1432 473 -1426 479 -508 509 -482 507 -494 475 -514 465 -1410 483 -558 465 -514 483 -1436 481 -1416 511 -510 465 -514 479 -1404 503 -1408 485 -532 467 -514 483 -512 511 -484 487 -1426 491 -1400 483 -1418 483 -1430 477 -1402 4433 -4526 483 -1422 471 -514 507 -1412 481 -502 493 -1408 483 -492 517 -480 481 -526 485 -1452 479 -512 473 -1418 495 -1410 483 -526 485 -1400 481 -490 479 -1464 481 -1428 487 -1442 471 -1428 491 -1404 517 -496 483 -478 475 -1440 463 -1444 511 -510 467 -1442 483 -500 493 -1410 483 -526 485 -1400 481 -1416 483 -1462 459 -520 485 -524 489 -512 479 -1408 509 -484 481 -1406 509 -1410 483 -1422 503 -1430 479 -1440 479 -1412 513 -1402 471 -1438 471 -506 471 -1416 485 -1398 4441 -4518 477 -1430 507 -484 515 -1404 483 -526 485 -1400 481 -490 515 -476 473 -538 473 -1440 509 -516 481 -1400 485 -1450 477 -476 497 -1406 483 -492 515 -1432 483 -1424 503 -1432 479 -1402 511 -1408 481 -502 493 -480 509 -1396 505 -1436 473 -1446 481 -1418 495 -1438 481 -496 489 -1400 485 -1416 481 -506 491 -510 517 -1404 483 -1452 471 -520 481 -488 513 -1400 483 -490 515 -476 471 -540 473 -1462 477 -520 485 -510 477 -1404 509 -1408 481 -1426 487 -1408 487 -1372 4471 -4482 507 -1412 481 -538 465 -1442 483 -498 489 -1406 481 -492 517 -478 481 -526 487 -1428 481 -512 505 -1432 475 -1410 481 -504 493 -1406 483 -492 479 -1470 483 -1426 471 -1434 509 -32700 99 -266 99 -732 +RAW_Data: 329 -134 233 -232 32700 -4516 489 -1438 483 -498 493 -1438 481 -498 489 -1402 483 -526 483 -478 481 -524 503 -1428 469 -518 481 -1438 481 -1414 511 -476 495 -1404 481 -494 481 -1462 481 -1430 485 -1446 459 -1432 509 -1406 505 -482 481 -514 473 -1414 487 -1436 479 -540 467 -1442 485 -504 491 -514 479 -1406 505 -1408 481 -1392 479 -1466 487 -1450 445 -1446 505 -484 479 -514 479 -520 459 -520 479 -490 479 -1466 481 -534 463 -516 481 -1440 479 -1414 481 -502 491 -1408 481 -492 481 -1406 4433 -4526 491 -1440 483 -498 491 -1440 483 -496 489 -1404 483 -492 517 -478 481 -522 503 -1434 467 -516 481 -1438 479 -1414 503 -486 509 -1404 483 -500 485 -1436 481 -1428 503 -1420 479 -1446 467 -1438 481 -498 489 -478 477 -1428 505 -1438 471 -1450 481 -1416 481 -1440 479 -522 483 -478 505 -1396 507 -482 481 -544 477 -514 473 -1444 469 -1438 483 -1426 471 -522 479 -486 481 -1402 511 -518 491 -514 479 -512 507 -1406 505 -484 479 -1438 479 -1414 481 -502 489 -1402 4437 -4490 495 -1442 481 -500 495 -1440 483 -498 487 -1406 483 -492 517 -478 477 -538 473 -1444 503 -480 513 -1404 481 -1448 471 -486 511 -1406 481 -500 489 -1436 481 -1424 503 -1434 477 -1438 479 -1406 481 -506 491 -480 511 -1406 469 -1474 469 -520 483 -1444 471 -1414 481 -1428 479 -1430 481 -490 513 -472 475 -1476 477 -520 487 -510 477 -1408 511 -484 483 -510 475 -516 471 -1426 475 -1434 515 -1422 471 -1442 487 -1420 477 -522 461 -520 483 -488 481 -512 473 -1414 4445 -4484 515 -1402 517 -492 491 -1434 483 -496 487 -1404 483 -492 515 -478 473 -554 483 -1414 513 -478 509 -1404 511 -1406 481 -504 489 -1400 485 -492 513 -1434 481 -1430 501 -1412 483 -1430 481 -1438 479 -488 513 -480 479 -1412 489 -1438 481 -540 467 -516 481 -514 479 -518 471 -1428 477 -1432 479 -1408 481 -534 503 -1408 481 -1430 501 -484 511 -1410 481 -504 489 -1406 481 -492 481 -544 479 -512 509 -1406 509 -1406 483 -502 495 -514 475 -474 503 -472 503 -1398 4449 -4516 479 -1442 477 -520 487 -1400 485 -526 485 -1404 481 -490 515 -476 471 -538 507 -1412 507 -480 517 -1402 483 -1418 513 -474 493 -1404 485 -492 513 -1434 481 -1428 487 -1446 469 -1432 481 -1438 477 -484 479 -506 475 -1410 495 -1436 513 -1436 459 -520 483 -1416 511 -510 463 -516 479 -482 485 -1428 477 -1438 483 -1450 471 -520 483 -524 485 -476 509 -482 503 -1394 495 -478 509 -1438 481 -1448 471 -522 481 -522 483 -1402 483 -1414 503 -1414 489 -490 481 -1382 4451 -4498 497 -1440 481 -534 463 -1438 481 -498 489 -1402 481 -526 485 -478 481 -524 +RAW_Data: 485 -1448 481 -514 475 -1446 465 -1438 481 -500 487 -1402 481 -490 481 -1470 481 -1426 471 -1442 485 -1430 481 -1442 475 -486 483 -512 475 -1412 489 -1434 505 -514 479 -522 485 -1402 481 -1454 475 -1404 501 -484 471 -518 477 -540 477 -508 475 -516 507 -1412 483 -1438 479 -488 483 -1438 477 -1408 481 -534 469 -1442 481 -536 463 -1442 483 -1420 473 -512 477 -1416 481 -500 487 -1404 4433 -4518 467 -1438 481 -502 495 -1438 483 -496 491 -1402 483 -492 515 -480 479 -524 483 -1448 481 -514 479 -1446 465 -1440 483 -496 487 -1404 483 -490 481 -1472 481 -1424 471 -1440 487 -1420 479 -1446 465 -514 479 -484 483 -1430 479 -1440 483 -1446 471 -1448 481 -522 477 -508 465 -1406 519 -1388 483 -502 489 -1434 503 -1414 481 -1456 485 -1402 483 -526 487 -476 509 -1406 469 -1406 517 -1420 503 -1418 477 -520 485 -506 481 -1434 501 -484 505 -482 479 -482 483 -1428 4437 -4484 511 -1438 477 -518 485 -1404 483 -524 485 -1406 481 -490 511 -474 475 -552 471 -1432 509 -484 483 -1436 483 -1416 503 -488 507 -1408 483 -496 483 -1434 481 -1428 503 -1434 477 -1410 509 -1404 481 -504 493 -478 505 -1400 505 -1444 475 -512 505 -1410 481 -1426 501 -482 483 -526 485 -478 479 -1414 493 -546 483 -1436 483 -496 491 -514 479 -1402 511 -1408 481 -502 489 -480 479 -552 473 -522 471 -1430 483 -510 509 -480 507 -488 489 -506 487 -478 479 -1416 4439 -4514 485 -1436 485 -496 491 -1406 517 -494 487 -1402 483 -490 515 -478 473 -554 483 -1414 481 -510 509 -1408 509 -1408 483 -500 489 -1400 483 -492 479 -1462 483 -1428 499 -1412 481 -1428 513 -1398 483 -524 485 -476 473 -1428 501 -1442 475 -1434 471 -1428 515 -1402 481 -1416 513 -474 495 -1410 481 -1418 481 -1464 457 -522 487 -1454 477 -510 465 -516 481 -1406 509 -484 481 -478 505 -1448 503 -482 517 -510 479 -482 517 -486 483 -504 489 -1400 483 -494 513 -1402 4431 -4482 497 -1440 483 -502 495 -1438 483 -496 489 -1404 483 -492 515 -478 479 -526 483 -1430 517 -476 507 -1432 479 -1410 481 -506 493 -1402 483 -490 481 -1466 483 -1428 501 -1412 485 -1426 493 -1402 517 -494 485 -476 509 -1406 465 -1472 479 -1438 459 -522 483 -524 485 -478 507 -1396 509 -1408 483 -500 485 -512 481 -1436 485 -1446 471 -1418 481 -1450 479 -1408 505 -484 479 -1402 507 -516 491 -1436 483 -1424 471 -516 507 -484 481 -1438 477 -1408 481 -502 487 -1402 4441 -4480 499 -1438 481 -502 497 -1438 483 -498 491 -1404 483 -492 483 -510 471 -538 479 -1444 503 -482 513 -1398 483 -1418 511 -478 495 -1408 483 -492 483 -1470 483 -1424 471 -1442 485 -1418 +RAW_Data: 479 -1444 469 -516 479 -480 485 -1416 479 -1478 477 -520 487 -512 475 -1430 479 -488 515 -474 509 -482 471 -522 489 -1422 501 -1412 483 -522 481 -1430 501 -484 509 -1406 483 -500 489 -1402 481 -1450 471 -550 477 -516 485 -1402 485 -1420 513 -476 493 -480 511 -482 471 -1420 4437 -4492 481 -1460 489 -510 479 -1436 477 -486 513 -1404 479 -488 481 -512 473 -520 505 -1414 497 -514 481 -1438 481 -1414 481 -504 491 -1402 485 -490 515 -1438 483 -1428 471 -1442 487 -1420 479 -1416 495 -514 479 -478 507 -1418 483 -1434 481 -1424 503 -512 481 -1426 469 -1436 475 -488 501 -1430 477 -1406 505 -514 489 -512 481 -32700 99 -632 167 -604 99 -298 233 -132 733 -166 461 diff --git a/assets/unit_tests/subghz/kia_seed_raw.sub b/assets/unit_tests/subghz/kia_seed_raw.sub new file mode 100644 index 00000000000..b3453536b84 --- /dev/null +++ b/assets/unit_tests/subghz/kia_seed_raw.sub @@ -0,0 +1,25 @@ +Filetype: Flipper SubGhz RAW File +Version: 1 +Frequency: 433920000 +Preset: FuriHalSubGhzPreset2FSKDev476Async +Protocol: RAW +RAW_Data: 51 -5136 1113 -104 127 -606 179 -126 325 -102 147 -200 205 -80 107 -190 81 -54 135 -378 181 -204 199 -104 121 -146 51 -230 75 -76 227 -102 415 -236 159 -54 159 -212 77 -312 73 -74 75 -128 155 -102 125 -358 125 -198 173 -608 75 -248 203 -558 53 -186 367 -180 151 -132 133 -138 135 -424 51 -240 53 -132 703 -80 79 -80 129 -294 77 -102 193 -270 77 -52 131 -180 51 -76 77 -76 51 -666 77 -104 101 -54 77 -164 107 -622 615 -294 133 -138 217 -180 75 -104 185 -80 107 -134 159 -398 181 -74 97 -198 73 -76 99 -102 127 -248 71 -128 211 -106 109 -104 101 -384 311 -398 51 -240 111 -84 81 -110 81 -668 105 -54 77 -158 79 -342 493 -78 153 -152 179 -122 223 -696 139 -590 81 -212 83 -322 129 -132 307 -346 129 -78 77 -232 77 -104 503 -52 187 -290 159 -108 159 -108 51 -136 53 -132 103 -566 177 -326 129 -176 177 -52 355 -308 129 -176 73 -104 151 -262 193 -168 111 -162 247 -52 131 -54 107 -84 83 -218 135 -402 107 -300 105 -220 81 -82 137 -82 163 -238 51 -192 293 -184 319 -454 81 -132 131 -132 79 -866 131 -212 163 -112 133 -106 211 -110 189 -214 51 -410 107 -454 131 -562 157 -52 367 -378 165 -110 81 -134 81 -82 75 -104 217 -638 81 -84 109 -160 81 -160 135 -54 53 -478 239 -78 209 -54 107 -52 155 -238 53 -184 105 -318 105 -370 233 -54 109 -246 217 -110 245 -110 209 -80 129 -514 79 -54 79 -314 155 -156 109 -292 79 -504 51 -644 157 -132 53 -208 53 -76 103 -76 77 -260 105 -82 133 -212 163 -136 53 -380 313 -178 193 -172 207 -82 79 -186 107 -136 53 -136 159 -156 97 -98 99 -254 179 -106 135 -214 307 -310 77 -76 123 -242 129 -52 103 -584 103 -178 203 -324 101 -572 253 -78 125 -126 129 -408 131 -52 129 -76 51 -132 79 -248 79 -414 51 -338 717 -322 79 -180 105 -294 109 -254 241 -76 251 -52 101 -152 125 -260 155 -80 77 -292 51 -226 209 -338 147 -100 51 -366 53 -348 133 -268 79 -366 55 -224 111 -248 81 -218 137 -168 79 -288 291 -132 51 -238 79 -78 103 -102 329 -102 123 -178 53 -202 51 -130 79 -138 51 -126 151 -180 99 -388 75 -126 51 -636 329 -150 99 -152 73 -122 177 -124 151 -386 297 -72 103 -130 51 -256 207 -354 75 -124 71 -148 351 -262 51 -540 77 -200 101 -132 77 -362 77 -254 103 -106 79 -296 51 -130 361 -240 51 -358 51 -284 201 -158 185 -288 183 -424 77 -130 +RAW_Data: 121 -146 99 -124 327 -74 99 -148 99 -252 183 -112 161 -216 263 -232 77 -102 103 -416 77 -382 345 -160 131 -110 167 -138 79 -158 133 -54 163 -84 107 -80 107 -108 107 -136 225 -82 321 -108 79 -106 107 -106 55 -162 103 -160 133 -192 53 -84 269 -106 77 -162 53 -136 161 -82 135 -346 77 -864 107 -140 55 -250 189 -128 201 -502 157 -564 105 -52 107 -1150 53 -218 237 -76 159 -1010 129 -196 139 -244 101 -270 77 -106 133 -110 109 -254 501 -496 237 -692 107 -54 159 -134 347 -210 51 -190 55 -276 103 -184 229 -98 149 -252 123 -156 75 -150 537 -236 103 -204 101 -100 73 -368 283 -102 77 -652 229 -206 99 -150 197 -206 53 -80 131 -274 101 -186 159 -396 51 -188 81 -188 83 -350 105 -428 129 -128 79 -78 53 -104 351 -284 235 -130 79 -242 51 -186 77 -134 135 -434 131 -552 53 -136 107 -140 141 -252 53 -54 53 -82 51 -770 79 -130 103 -432 127 -208 153 -226 131 -248 101 -902 125 -206 129 -102 77 -154 77 -188 105 -322 105 -166 133 -474 77 -728 161 -190 107 -54 133 -80 79 -190 53 -162 53 -404 77 -334 105 -52 153 -728 423 -700 133 -476 53 -162 53 -542 159 -168 189 -134 163 -134 81 -106 133 -54 267 -108 163 -242 165 -56 167 -294 81 -136 185 -660 51 -304 157 -54 109 -378 133 -272 159 -304 135 -110 53 -402 105 -630 185 -78 257 -422 173 -252 247 -100 123 -330 107 -166 109 -502 127 -156 219 -76 101 -348 71 -586 149 -154 73 -74 77 -358 131 -270 81 -108 159 -516 295 -346 53 -240 157 -240 55 -562 133 -110 213 -320 103 -560 79 -286 51 -134 55 -452 79 -136 79 -80 77 -52 185 -504 79 -216 79 -242 135 -262 75 -206 125 -472 111 -564 79 -322 79 -432 217 -456 167 -272 103 -664 53 -302 127 -138 241 -184 53 -80 81 -192 395 -604 133 -136 53 -1044 105 -166 215 -426 133 -1222 101 -348 127 -124 123 -248 153 -492 177 -102 103 -180 77 -204 151 -282 101 -74 103 -76 101 -170 73 -506 101 -368 51 -124 193 -236 53 -310 77 -130 155 -366 229 -526 129 -428 83 -922 51 -106 131 -82 219 -706 79 -80 81 -162 133 -276 195 -220 51 -266 81 -54 51 -238 53 -686 77 -354 229 -164 195 -164 81 -294 81 -132 197 -238 73 -202 181 -180 149 -128 207 -192 111 -56 187 -808 77 -608 79 -898 77 -208 97 -200 73 -184 75 -78 203 -664 105 -384 103 -102 129 -238 131 -1346 137 -526 105 -390 129 -138 81 -484 103 -222 109 -268 51 -240 +RAW_Data: 81 -658 53 -626 79 -562 79 -52 77 -266 107 -54 109 -410 105 -514 107 -110 53 -334 79 -928 121 -498 105 -184 149 -174 73 -908 129 -388 199 -450 153 -862 51 -896 101 -776 51 -990 129 -154 177 -412 169 -254 77 -902 105 -474 77 -2390 103 -1000 107 -2112 151 -402 51 -428 337 -440 129 -590 197 -538 53 -138 81 -584 81 -1958 107 -4714 57 -786 53 -684 137 -442 105 -654 53 -696 51 -2382 105 -376 83 -822 155 -6282 103 -560 77 -252 79 -1518 103 -3648 51 -6150 75 -4986 75 -2042 53 -2798 171 -804 2247 -130 357 -168 309 -168 307 -170 293 -172 305 -192 279 -224 253 -224 279 -196 265 -224 261 -222 253 -224 253 -224 279 -214 245 -232 243 -252 253 -224 251 -226 241 -222 253 -246 251 -224 253 -224 251 -252 213 -248 261 -222 251 -226 251 -254 223 -242 245 -232 245 -250 225 -252 253 -224 241 -222 253 -246 251 -226 251 -224 253 -252 213 -248 233 -248 253 -224 253 -252 223 -242 247 -230 245 -252 223 -252 253 -224 241 -222 255 -244 251 -226 251 -224 253 -252 213 -248 233 -250 251 -226 251 -252 225 -242 245 -230 245 -252 225 -252 251 -226 241 -222 253 -246 251 -224 253 -224 251 -254 213 -246 235 -248 251 -226 251 -254 223 -242 245 -232 245 -252 225 -252 251 -224 253 -214 245 -236 247 -252 253 -224 251 -226 241 -246 231 -246 251 -226 251 -224 253 -252 213 -248 233 -250 251 -226 253 -252 223 -242 245 -232 243 -254 223 -254 251 -224 253 -214 245 -236 247 -254 251 -224 253 -224 241 -246 231 -246 251 -226 251 -252 225 -252 213 -248 261 -224 251 -226 251 -252 225 -252 213 -250 261 -222 253 -224 253 -252 225 -242 245 -230 245 -252 225 -252 251 -226 241 -220 255 -246 249 -226 251 -226 251 -254 213 -248 233 -248 251 -226 251 -254 223 -242 245 -232 245 -252 223 -252 253 -224 241 -222 253 -246 251 -226 251 -224 253 -252 213 -248 233 -248 253 -224 253 -252 223 -242 245 -232 245 -252 223 -252 253 -224 241 -222 255 -244 251 -226 251 -224 253 -252 213 -246 235 -248 251 -254 223 -252 225 -242 245 -232 245 -252 223 -254 251 -226 241 -222 253 -246 251 -224 253 -224 251 -254 213 -248 233 -248 251 -226 251 -254 223 -242 245 -230 245 -252 225 -252 251 -226 241 -222 253 -246 251 -224 253 -224 251 -254 213 -248 233 -248 253 -224 253 -252 225 -252 213 -248 261 -224 251 -226 251 -252 225 -242 245 -230 245 -254 223 -252 253 -224 241 -222 253 -246 251 -226 251 -224 251 -254 213 -248 259 -224 251 -226 +RAW_Data: 251 -254 223 -242 245 -230 245 -252 225 -252 251 -226 251 -214 247 -234 249 -252 251 -226 251 -224 241 -248 229 -248 251 -224 253 -224 251 -254 213 -246 261 -224 251 -226 251 -252 225 -242 245 -230 247 -252 223 -252 253 -224 243 -220 255 -244 251 -226 251 -226 251 -252 213 -248 233 -248 251 -252 225 -252 225 -242 245 -232 245 -252 223 -254 251 -224 253 -214 247 -236 247 -252 251 -226 251 -226 241 -246 231 -246 251 -224 253 -224 251 -254 213 -248 233 -248 253 -252 223 -254 223 -242 245 -232 245 -252 223 -254 251 -226 241 -220 255 -244 251 -226 251 -226 251 -252 213 -248 233 -250 251 -226 251 -252 225 -242 245 -230 245 -254 223 -252 253 -224 241 -222 253 -246 251 -224 253 -224 253 -252 213 -246 235 -248 251 -226 251 -254 223 -242 245 -232 245 -252 223 -254 251 -226 251 -214 247 -234 247 -254 251 -224 253 -224 241 -246 231 -246 251 -226 251 -226 251 -252 213 -248 261 -222 253 -224 253 -252 225 -242 245 -230 245 -254 223 -252 253 -224 253 -214 245 -236 247 -252 253 -224 251 -226 241 -246 231 -246 251 -226 251 -252 225 -252 213 -248 235 -248 251 -254 223 -252 225 -242 245 -230 247 -252 223 -252 253 -224 241 -222 253 -246 251 -226 251 -224 253 -252 215 -246 235 -248 251 -224 479 -484 501 -482 461 -492 483 -466 255 -234 245 -252 223 -254 251 -226 241 -222 487 -480 253 -222 489 -480 251 -246 465 -482 251 -246 231 -246 483 -468 255 -234 481 -488 233 -246 233 -248 483 -466 255 -234 245 -252 225 -252 251 -226 469 -494 483 -488 483 -482 221 -250 473 -488 479 -490 231 -248 231 -246 251 -226 251 -226 251 -252 467 -476 249 -252 223 -252 469 -494 481 -470 485 -484 247 -252 469 -462 481 -498 229 -252 243 -252 225 -252 223 -254 251 -214 477 -484 247 -250 251 -214 247 -234 247 -252 481 -460 261 -244 251 -226 479 -486 1435 -1456 231 -236 247 -252 225 -252 253 -224 241 -222 253 -246 251 -224 253 -224 253 -252 213 -246 261 -222 251 -226 251 -252 225 -242 245 -230 247 -252 481 -462 493 -480 481 -492 481 -462 255 -224 263 -222 253 -252 223 -254 223 -242 475 -484 249 -222 505 -488 245 -222 469 -496 247 -252 223 -254 469 -490 249 -224 477 -482 237 -250 249 -226 479 -484 239 -246 251 -226 251 -226 251 -252 467 -474 481 -490 491 -456 271 -224 469 -494 481 -492 229 -236 245 -252 225 -252 251 -226 241 -222 487 -482 251 -246 231 -246 483 -468 487 -482 473 -486 265 -222 485 -492 461 -484 247 -250 +RAW_Data: 253 -214 245 -234 247 -252 225 -252 473 -486 243 -252 225 -254 223 -254 251 -214 477 -486 245 -252 223 -242 477 -484 1463 -1444 249 -222 253 -224 241 -246 233 -248 251 -226 251 -254 223 -252 213 -248 261 -224 251 -226 251 -254 223 -242 245 -232 245 -252 223 -252 253 -224 469 -496 483 -488 457 -506 479 -462 259 -244 223 -252 253 -224 251 -226 241 -246 467 -478 253 -246 467 -480 251 -248 465 -480 251 -248 229 -248 483 -468 255 -232 483 -474 255 -224 265 -224 483 -492 229 -236 249 -252 223 -252 253 -224 469 -496 479 -482 491 -480 225 -246 485 -482 491 -462 245 -252 253 -224 253 -224 241 -246 231 -246 483 -488 229 -250 241 -252 457 -490 489 -460 497 -484 243 -224 483 -490 489 -458 249 -248 249 -240 249 -226 251 -226 251 -226 493 -472 249 -252 223 -252 223 -242 245 -234 483 -488 233 -246 233 -248 483 -468 1451 -1448 229 -492 247 -248 79 -400 157 -566 133 -108 379 -218 109 -54 163 -164 51 -102 315 -260 263 -80 463 -234 151 -76 149 -154 249 -126 99 -130 125 -270 127 -188 427 -210 131 -222 593 -106 241 -562 239 -84 305 -262 183 -80 53 -524 125 -480 227 -328 51 -350 211 -82 181 -108 215 -106 147 -200 183 -104 397 -52 131 -102 147 -172 335 -618 177 -206 131 -220 129 -158 213 -52 187 -164 135 -334 157 -410 73 -120 225 -234 133 -108 81 -138 599 -238 131 -262 77 -368 209 -130 103 -76 335 -78 101 -232 253 -280 97 -74 73 -74 97 -52 383 -272 125 -104 81 -82 455 -106 159 -78 127 -52 183 -358 55 -170 139 -86 53 -108 299 -52 129 -282 385 -104 101 -514 75 -232 153 -510 75 -174 97 -128 151 -152 101 -206 103 -76 227 -308 77 -302 129 -76 77 -592 175 -202 75 -314 157 -400 343 -52 185 -104 135 -136 129 -108 111 -112 271 -266 161 -108 107 -240 343 -342 213 -128 99 -124 181 -54 103 -200 101 -274 157 -104 131 -154 123 -588 105 -108 107 -54 161 -52 349 -184 83 -84 53 -54 133 -540 105 -52 53 -160 105 -334 481 -180 101 -304 257 -176 77 -286 79 -106 179 -102 73 -554 285 -184 77 -396 103 -264 185 -106 233 -732 235 -108 53 -82 185 -140 137 -188 285 -294 281 -338 127 -378 77 -242 239 -112 327 -106 219 -240 55 -54 109 -584 51 -134 79 -80 215 -80 109 -54 81 -264 157 -310 51 -130 161 -140 375 -290 129 -886 263 -78 51 -342 55 -104 207 -288 271 -108 179 -74 75 -460 257 -280 77 -106 51 -104 53 -150 125 -174 155 -80 221 -108 161 -310 +RAW_Data: 77 -104 51 -208 79 -452 379 -130 51 -318 237 -214 257 -180 77 -298 79 -604 103 -398 187 -346 181 -154 97 -174 285 -156 51 -102 583 -78 75 -74 151 -102 255 -158 339 -80 77 -234 155 -102 101 -250 75 -76 147 -150 123 -100 75 -78 259 -180 251 -80 51 -104 77 -130 77 -52 159 -236 103 -622 173 -1016 131 -184 153 -156 73 -274 331 -292 105 -204 199 -516 103 -210 157 -104 287 -304 153 -78 129 -78 385 -332 179 -286 181 -178 145 -176 121 -76 169 -146 123 -102 181 -180 51 -176 147 -230 103 -172 75 -208 199 -52 153 -52 75 -134 265 -80 51 -182 157 -110 237 -104 183 -198 213 -168 219 -132 75 -78 101 -76 101 -306 231 -130 99 -152 125 -130 105 -132 135 -110 133 -476 213 -54 325 -322 209 -404 303 -106 81 -166 403 -134 105 -242 403 -104 129 -182 55 -174 165 -168 83 -304 185 -130 133 -108 135 -134 103 -52 181 -362 207 -54 179 -228 231 -236 105 -214 53 -158 77 -452 319 -106 79 -348 349 -406 133 -84 195 -104 239 -158 197 -164 79 -80 79 -54 79 -156 201 -374 941 -492 77 -174 73 -230 75 -278 177 -52 477 -306 129 -106 79 -108 113 -196 127 -328 51 -102 125 -76 75 -102 153 -76 99 -146 373 -134 185 -134 105 -352 105 -436 127 -246 51 -106 79 -238 131 -82 165 -270 109 -108 79 -634 157 -242 105 -78 129 -52 131 -266 215 -270 329 -162 51 -478 209 -52 157 -372 79 -82 367 -560 129 -210 53 -54 133 -106 133 -292 77 -106 159 -84 185 -80 509 -54 473 -80 103 -108 105 -158 51 -180 123 -122 71 -208 129 -210 371 -212 75 -110 341 -164 425 -130 181 -54 313 -278 51 -52 129 -386 263 -78 245 -344 287 -134 133 -130 81 -276 105 -114 129 -106 487 -78 127 -182 179 -146 127 -148 125 -186 133 -182 127 -76 195 -96 103 -76 75 -52 101 -204 77 -102 405 -102 75 -224 125 -276 153 -100 147 -350 259 -156 77 -128 463 -76 77 -234 103 -252 51 -286 75 -232 201 -102 75 -176 175 -124 151 -100 51 -254 97 -74 123 -122 123 -174 201 -154 129 -190 53 -136 81 -78 79 -216 133 -106 111 -84 137 -136 163 -324 103 -78 51 -56 109 -106 177 -168 75 -492 131 -52 131 -180 73 -74 359 -104 101 -102 101 -492 159 -290 215 -80 187 -214 103 -160 135 -130 175 -126 107 -54 75 -78 77 -152 199 -604 97 -74 101 -284 127 -52 177 -434 153 -122 781 -208 79 -80 105 -292 135 -84 247 -318 51 -430 79 -162 109 -56 135 -190 185 -78 159 -130 +RAW_Data: 185 -188 137 -108 331 -56 79 -132 167 -188 107 -320 393 -310 99 -154 51 -180 153 -74 101 -76 229 -128 183 -184 249 -108 299 -82 191 -532 295 -400 103 -80 79 -272 53 -276 213 -84 55 -110 291 -106 123 -204 101 -102 77 -104 157 -102 51 -126 51 -126 183 -140 83 -264 53 -134 261 -128 81 -82 81 -298 81 -266 77 -52 51 -474 265 -366 103 -226 239 -166 677 -232 175 -150 205 -76 123 -76 97 -176 127 -284 77 -76 357 -182 73 -326 171 -104 675 -236 301 -216 53 -84 107 -52 157 -78 237 -136 289 -130 215 -350 77 -320 187 -110 347 -240 159 -134 79 -486 207 -272 129 -82 293 -188 105 -212 77 -216 445 -836 151 -150 73 -262 75 -102 253 -52 101 -102 281 -386 149 -230 355 -212 51 -130 329 -224 149 -52 75 -204 77 -108 85 -194 341 -134 269 -132 161 -56 81 -556 187 -448 395 -130 177 -136 107 -184 239 -136 53 -214 135 -266 79 -368 109 -372 315 -78 79 -78 103 -132 53 -82 81 -104 129 -182 125 -74 103 -236 211 -294 205 -216 131 -108 211 -236 79 -54 103 -104 161 -54 265 -54 187 -162 107 -134 183 -190 237 -104 51 -186 107 -164 137 -102 77 -206 197 -238 107 -52 53 -78 155 -126 201 -78 125 -204 103 -102 75 -104 253 -76 105 -238 159 -366 209 -216 165 -56 55 -322 585 -80 183 -108 81 -136 109 -168 211 -236 295 -674 337 -78 211 -312 77 -242 297 -378 215 -190 79 -298 161 -108 183 -122 121 -252 103 -516 105 -54 123 -226 291 -78 77 -104 53 -484 197 -452 51 -306 77 -106 127 -178 51 -256 209 -264 101 -76 101 -126 151 -126 251 -1152 359 -126 325 -254 551 -156 83 -666 161 -236 105 -186 103 -108 161 -80 157 -54 51 -344 159 -82 349 -160 141 -270 131 -578 189 -162 287 -134 161 -712 127 -106 51 -108 345 -704 431 -362 51 -52 415 -208 233 -342 257 -288 131 -80 77 -252 53 -330 105 -160 83 -280 393 -358 103 -480 161 -134 51 -54 259 -104 129 -130 105 -80 217 -350 269 -192 57 -302 79 -264 81 -326 157 -80 79 -214 51 -370 129 -236 53 -136 105 -82 57 -140 137 -52 79 -236 103 -80 55 -192 293 -188 53 -348 185 -236 207 -56 135 -54 215 -216 587 -132 103 -160 133 -158 365 -52 103 -54 107 -80 185 -298 267 -136 159 -110 109 -82 241 -78 77 -78 101 -82 141 -226 55 -462 79 -188 81 -216 511 -210 79 -162 161 -160 101 -388 157 -180 101 -100 197 -336 581 -130 211 -264 155 -52 297 -180 75 -100 73 -100 247 -130 +RAW_Data: 133 -346 505 -108 105 -80 243 -292 79 -104 339 -78 75 -128 287 -398 99 -300 479 -104 257 -130 153 -78 359 -152 79 -300 77 -348 109 -82 217 -108 243 -80 185 -430 133 -460 211 -234 207 -52 291 -80 77 -54 81 -82 265 -78 101 -132 255 -122 73 -512 129 -126 77 -158 213 -168 81 -82 479 -160 159 -108 157 -158 133 -236 129 -128 485 -126 153 -412 99 -250 255 -274 173 -358 231 -76 53 -78 131 -54 135 -290 77 -102 305 -128 77 -310 183 -80 239 -80 135 -166 189 -104 81 -140 111 -164 477 -488 51 -134 53 -80 429 -240 529 -476 287 -80 189 -136 327 -84 79 -160 293 -348 133 -148 179 -52 231 -102 175 -76 125 -100 425 -228 77 -200 183 -154 231 -212 253 -78 299 -132 145 -124 337 -150 101 -132 99 -274 153 -182 53 -158 51 -160 453 -134 427 -182 77 -134 275 -528 77 -108 79 -110 109 -110 245 -136 171 -164 473 -106 265 -80 267 -184 179 -330 287 -212 185 -350 129 -630 467 -350 489 -166 107 -56 79 -270 53 -84 757 -624 207 -102 51 -416 287 -288 103 -406 73 -132 51 -214 135 -644 103 -146 73 -358 629 -736 309 -150 275 -254 51 -106 53 -54 105 -80 53 -180 77 -110 297 -106 79 -418 261 -80 161 -80 77 -480 79 -156 215 -190 601 -130 353 -76 73 -76 127 -198 125 -100 531 -78 77 -438 103 -134 191 -312 291 -108 53 -134 53 -214 317 -80 277 -182 279 -302 329 -104 479 -182 203 -98 273 -222 247 -250 241 -252 219 -248 221 -254 243 -252 225 -254 223 -252 253 -214 245 -236 247 -252 251 -226 251 -224 241 -222 255 -246 251 -226 251 -226 251 -252 213 -248 235 -248 253 -224 253 -252 225 -242 245 -230 245 -252 223 -254 251 -224 253 -214 247 -236 247 -252 251 -226 251 -226 241 -222 255 -246 251 -224 253 -224 251 -254 213 -248 233 -248 253 -224 253 -252 223 -242 247 -230 245 -252 225 -252 253 -224 251 -214 247 -236 247 -254 251 -224 253 -224 241 -246 231 -246 251 -226 251 -224 253 -252 213 -248 235 -248 251 -226 251 -254 223 -242 245 -232 245 -252 223 -254 251 -224 241 -222 253 -246 251 -224 253 -224 253 -252 213 -248 233 -248 251 -226 253 -252 223 -242 245 -232 245 -252 225 -252 253 -224 251 -214 247 -236 247 -252 253 -224 251 -226 241 -246 231 -246 251 -224 253 -252 225 -252 213 -248 233 -248 253 -252 225 -252 223 -244 245 -230 245 -254 223 -252 253 -224 253 -214 245 -236 247 -252 253 -224 251 -226 241 -246 231 -246 251 -224 253 -252 223 -252 +RAW_Data: 213 -248 263 -222 251 -226 251 -254 223 -242 245 -232 245 -252 223 -254 251 -224 253 -214 247 -234 249 -252 251 -226 251 -224 241 -246 231 -246 251 -226 251 -254 223 -252 213 -248 261 -222 253 -252 223 -254 223 -242 245 -232 245 -252 225 -252 251 -226 241 -222 253 -246 251 -224 253 -224 253 -252 213 -246 261 -222 251 -226 251 -254 223 -242 245 -232 245 -252 223 -254 251 -224 241 -222 253 -246 251 -224 253 -224 253 -252 213 -248 235 -248 251 -224 251 -254 223 -242 245 -232 245 -252 225 -252 251 -226 241 -222 253 -246 251 -224 253 -224 253 -252 213 -246 261 -222 251 -226 251 -254 223 -242 245 -232 245 -252 223 -254 251 -224 243 -220 253 -246 251 -226 251 -224 251 -254 213 -248 233 -248 251 -254 223 -254 223 -242 245 -232 245 -252 225 -252 251 -226 241 -222 253 -246 251 -224 253 -224 253 -252 213 -248 233 -248 251 -226 251 -252 225 -242 245 -230 247 -252 223 -254 251 -224 253 -214 245 -236 247 -254 251 -224 253 -224 241 -246 231 -246 251 -224 253 -224 253 -242 219 -256 243 -254 223 -254 251 -224 253 -214 245 -236 247 -252 251 -226 251 -224 243 -246 229 -248 251 -224 253 -252 223 -254 213 -246 261 -224 251 -226 251 -254 223 -242 245 -232 245 -252 223 -252 253 -224 241 -222 253 -246 251 -226 251 -224 253 -252 213 -248 233 -248 253 -224 253 -252 223 -254 213 -248 263 -222 253 -224 253 -252 223 -242 245 -232 245 -252 223 -254 251 -226 241 -220 253 -246 251 -226 251 -224 253 -252 213 -248 261 -222 251 -226 251 -254 223 -242 245 -232 243 -252 225 -252 253 -224 241 -222 253 -246 251 -226 251 -224 251 -254 213 -246 261 -222 253 -224 253 -252 223 -242 247 -230 245 -252 223 -254 251 -224 243 -220 255 -246 249 -226 251 -226 251 -254 213 -246 235 -248 251 -226 251 -252 225 -242 245 -230 245 -252 225 -252 253 -224 251 -214 247 -236 247 -254 251 -224 253 -224 241 -246 231 -246 251 -226 251 -224 253 -252 213 -248 261 -222 251 -226 253 -252 223 -242 245 -232 245 -252 225 -252 253 -224 251 -214 247 -234 249 -252 251 -226 251 -224 241 -246 231 -246 251 -226 251 -226 251 -254 213 -248 261 -220 253 -252 225 -252 223 -242 247 -230 245 -254 479 -462 495 -482 479 -490 481 -470 229 -254 245 -250 225 -252 223 -254 251 -214 503 -458 249 -248 481 -484 243 -224 495 -472 249 -252 223 -252 471 -490 249 -224 479 -486 473 -482 241 -242 477 -482 247 -250 253 -214 245 -234 247 -252 481 -462 495 -482 +RAW_Data: 465 -488 245 -252 479 -480 473 -488 243 -252 213 -246 261 -224 251 -224 253 -252 469 -466 245 -254 251 -224 473 -486 481 -480 485 -482 247 -224 505 -458 499 -484 243 -252 223 -252 225 -252 223 -242 247 -232 483 -490 485 -472 249 -252 473 -484 243 -224 483 -492 231 -234 485 -488 487 -472 1445 -1448 237 -248 251 -226 251 -224 253 -252 213 -246 261 -222 251 -254 223 -252 225 -242 245 -230 247 -252 223 -254 251 -224 243 -220 255 -244 251 -226 477 -482 501 -454 507 -480 479 -462 259 -244 251 -224 253 -224 251 -226 241 -246 493 -464 241 -242 475 -484 249 -222 505 -484 225 -246 251 -242 485 -470 229 -254 477 -480 485 -482 247 -224 495 -464 273 -224 253 -224 251 -226 241 -246 493 -480 479 -470 481 -480 233 -266 459 -488 485 -476 247 -252 223 -254 251 -214 245 -234 247 -252 481 -462 259 -244 251 -226 479 -486 469 -482 481 -492 247 -224 477 -482 503 -464 241 -242 245 -232 245 -254 223 -252 253 -224 469 -496 483 -486 229 -252 477 -476 227 -248 497 -480 227 -254 477 -480 483 -482 1439 -1452 245 -252 223 -254 223 -252 253 -214 245 -234 247 -252 225 -252 251 -226 241 -222 253 -246 251 -226 251 -226 251 -252 213 -248 261 -222 253 -224 479 -484 501 -482 461 -492 483 -466 255 -234 245 -252 225 -252 253 -224 241 -222 487 -480 253 -222 489 -480 251 -248 463 -482 251 -246 231 -246 483 -488 229 -252 477 -478 485 -480 223 -248 479 -484 247 -250 251 -214 247 -234 247 -252 481 -460 493 -482 479 -492 249 -224 477 -480 477 -488 243 -240 245 -234 245 -252 223 -254 251 -226 469 -494 247 -224 253 -252 469 -488 483 -470 485 -482 247 -224 497 -462 483 -490 231 -248 233 -248 251 -226 251 -252 225 -242 475 -484 475 -484 239 -250 483 -468 255 -232 483 -490 231 -246 493 -480 481 -470 1445 -1448 239 -772 105 -194 247 -314 105 -176 125 -126 151 -382 51 -266 51 -104 55 -400 129 -114 243 -210 343 -78 161 -108 107 -110 53 -214 83 -242 209 -80 155 -82 53 -268 391 -80 79 -214 211 -132 131 -320 77 -320 157 -138 191 -136 103 -202 99 -446 213 -406 131 -286 101 -258 51 -188 55 -82 81 -162 237 -130 183 -512 291 -80 193 -342 77 -106 159 -272 77 -52 53 -78 183 -544 79 -106 277 -338 185 -132 153 -108 107 -108 163 -54 107 -134 235 -356 523 -108 137 -134 291 -80 79 -214 213 -266 137 -54 53 -162 165 -84 191 -78 53 -132 213 -318 79 -264 215 -320 159 -82 53 -246 131 -132 175 -102 227 -228 +RAW_Data: 315 -106 53 -872 139 -136 209 -332 177 -272 417 -180 51 -52 181 -338 77 -130 51 -104 151 -52 127 -152 99 -76 155 -126 203 -180 151 -126 101 -200 179 -384 123 -592 153 -80 127 -466 75 -100 121 -98 123 -126 97 -336 359 -104 107 -192 55 -80 103 -190 81 -132 79 -78 207 -128 109 -216 183 -270 105 -80 129 -52 51 -354 85 -194 135 -238 243 -82 81 -370 295 -130 135 -136 137 -190 211 -188 81 -184 53 -80 159 -82 55 -350 319 -160 355 -210 99 -462 53 -130 277 -204 619 -184 471 -78 131 -378 453 -162 171 -86 165 -222 81 -82 315 -210 101 -78 383 -102 101 -180 207 -416 183 -310 259 -200 225 -146 333 -460 185 -78 211 -192 85 -84 353 -82 79 -80 213 -158 75 -156 131 -226 133 -54 107 -134 105 -106 131 -80 267 -132 187 -192 271 -110 105 -82 79 -270 135 -102 185 -134 185 -54 191 -134 249 -368 53 -238 79 -54 185 -526 51 -376 243 -586 109 -346 81 -82 179 -78 267 -206 177 -100 125 -104 173 -74 77 -152 155 -186 83 -190 351 -164 135 -106 109 -142 337 -214 81 -188 79 -78 103 -228 101 -226 175 -214 315 -52 79 -184 77 -240 291 -54 79 -80 51 -624 135 -134 203 -146 223 -74 135 -238 133 -134 129 -380 133 -190 79 -108 241 -186 181 -416 155 -134 157 -128 305 -134 425 -508 283 -128 181 -826 127 -268 77 -368 261 -54 189 -374 415 -156 201 -178 177 -206 127 -234 79 -380 133 -54 161 -236 53 -184 79 -298 53 -294 77 -312 177 -154 77 -208 369 -78 53 -160 215 -106 557 -320 473 -274 343 -78 99 -100 119 -72 155 -98 123 -76 257 -280 51 -260 157 -78 127 -52 99 -74 569 -302 131 -428 77 -336 101 -102 177 -230 97 -124 51 -102 75 -156 251 -126 173 -326 79 -428 123 -380 281 -238 161 -158 157 -230 395 -202 123 -220 255 -104 97 -198 77 -100 551 -76 101 -256 231 -410 77 -102 75 -230 105 -158 51 -132 105 -340 215 -108 241 -134 129 -160 191 -292 51 -852 155 -186 77 -52 103 -578 77 -106 209 -132 107 -130 53 -164 455 -78 155 -244 185 -160 217 -216 381 -130 127 -514 209 -82 55 -136 103 -104 173 -226 231 -176 73 -130 205 -102 319 -244 53 -160 107 -162 57 -350 97 -230 203 -252 127 -360 79 -316 103 -180 101 -178 185 -216 101 -302 257 -182 103 -126 75 -152 103 -102 77 -284 413 -612 177 -432 73 -460 79 -78 53 -556 155 -664 75 -214 327 -134 79 -134 133 -136 51 -82 103 -130 145 -74 199 -128 51 -102 103 -482 +RAW_Data: 179 -100 177 -52 103 -158 191 -110 81 -190 217 -326 51 -280 147 -602 209 -76 99 -124 293 -108 193 -192 241 -184 131 -106 159 -52 77 -132 53 -104 101 -188 79 -538 105 -80 107 -52 213 -428 243 -84 81 -132 265 -140 77 -80 51 -214 189 -140 301 -162 75 -102 231 -178 123 -264 123 -98 125 -76 103 -238 77 -228 183 -140 165 -552 297 -54 291 -186 185 -234 155 -78 79 -180 53 -82 505 -182 103 -128 123 -280 133 -158 103 -644 213 -330 77 -106 79 -424 155 -212 163 -192 189 -508 369 -80 79 -220 111 -166 79 -304 133 -108 139 -140 189 -78 51 -348 289 -104 187 -54 109 -508 131 -108 283 -516 99 -100 299 -380 199 -152 325 -304 229 -476 75 -148 101 -102 75 -208 77 -74 125 -74 73 -76 181 -176 179 -186 235 -130 79 -184 77 -152 121 -304 127 -484 103 -152 173 -100 157 -176 185 -82 177 -156 309 -106 79 -132 51 -236 179 -154 73 -236 77 -74 71 -160 235 -130 105 -108 247 -56 53 -208 75 -74 75 -128 505 -154 179 -76 51 -278 103 -178 99 -126 183 -54 161 -526 133 -80 79 -298 105 -236 77 -264 139 -54 243 -164 459 -208 51 -236 105 -370 79 -374 77 -182 129 -202 77 -158 107 -108 107 -82 245 -244 109 -82 81 -292 179 -52 129 -164 423 -52 153 -102 151 -100 125 -76 259 -78 365 -240 107 -162 105 -244 163 -56 163 -108 159 -52 79 -260 79 -502 133 -82 323 -552 105 -210 699 -78 189 -192 105 -128 165 -188 105 -158 77 -158 79 -54 131 -498 131 -130 101 -176 125 -170 213 -52 77 -106 53 -292 389 -104 133 -402 133 -80 109 -54 53 -104 79 -182 505 -54 161 -264 181 -212 107 -164 83 -244 315 -234 127 -130 147 -150 231 -456 101 -124 73 -104 287 -320 81 -134 107 -244 267 -78 157 -108 137 -84 133 -54 79 -186 107 -262 77 -80 81 -240 53 -82 107 -136 245 -110 185 -294 259 -134 135 -80 159 -566 107 -190 187 -190 79 -54 107 -80 107 -54 135 -164 165 -56 79 -54 349 -78 75 -104 157 -320 53 -82 421 -180 97 -172 105 -106 111 -280 163 -132 193 -250 107 -318 155 -266 109 -162 183 -242 105 -484 79 -106 125 -246 99 -492 75 -180 127 -100 95 -196 75 -152 537 -214 53 -186 103 -134 81 -108 109 -560 51 -382 153 -104 51 -188 373 -240 53 -266 129 -622 51 -132 81 -58 137 -364 263 -78 235 -82 177 -486 105 -276 157 -108 237 -80 105 -132 131 -258 289 -102 51 -104 103 -104 73 -508 283 -102 51 -230 99 -178 105 -106 +RAW_Data: 53 -190 105 -160 157 -158 129 -80 241 -162 277 -260 77 -312 157 -320 193 -108 77 -184 77 -102 125 -286 107 -82 371 -266 447 -218 271 -106 51 -162 107 -194 333 -264 99 -76 75 -150 345 -444 105 -696 75 -154 185 -348 105 -108 159 -296 161 -80 107 -222 81 -106 239 -80 75 -78 105 -52 323 -246 51 -162 79 -130 157 -618 241 -82 107 -106 133 -294 137 -108 53 -104 107 -80 51 -80 267 -106 77 -212 105 -84 81 -56 131 -132 211 -78 187 -138 131 -104 53 -78 311 -210 77 -80 109 -160 239 -208 51 -292 443 -158 167 -138 185 -232 293 -78 181 -136 53 -186 107 -108 53 -80 395 -130 299 -160 53 -162 109 -56 135 -468 75 -102 229 -396 105 -98 277 -386 339 -356 125 -226 291 -270 165 -80 79 -106 77 -244 189 -162 215 -672 343 -184 75 -450 131 -208 57 -114 107 -420 53 -106 81 -188 103 -136 501 -110 211 -76 161 -294 107 -54 55 -206 75 -100 75 -432 77 -248 51 -78 419 -52 535 -106 207 -230 99 -124 179 -100 71 -76 77 -400 53 -340 185 -188 235 -106 105 -220 55 -134 53 -346 53 -192 291 -346 209 -242 185 -158 51 -128 75 -176 153 -282 159 -158 73 -330 105 -634 323 -242 79 -210 181 -52 103 -54 107 -108 105 -330 105 -272 51 -206 227 -154 129 -194 285 -80 79 -266 127 -492 131 -432 181 -108 213 -242 107 -346 207 -78 157 -160 53 -108 53 -322 83 -674 317 -188 243 -186 81 -166 111 -84 535 -78 181 -134 327 -240 103 -206 77 -78 177 -152 121 -70 75 -100 535 -152 75 -78 101 -368 267 -168 217 -688 383 -222 247 -234 275 -224 251 -226 251 -224 241 -222 255 -246 251 -224 253 -224 251 -252 215 -246 261 -222 253 -224 253 -252 223 -242 245 -232 245 -252 225 -252 253 -224 253 -214 245 -236 247 -252 253 -224 251 -226 241 -246 231 -246 251 -224 251 -254 223 -242 221 -254 245 -252 225 -252 251 -226 251 -214 247 -236 247 -252 253 -224 251 -226 241 -246 229 -246 251 -226 251 -254 223 -252 213 -248 261 -224 251 -226 251 -252 225 -242 245 -230 245 -254 223 -252 253 -224 253 -214 245 -236 247 -252 251 -226 251 -224 243 -246 229 -248 251 -224 253 -252 223 -254 213 -248 261 -222 251 -226 251 -254 223 -242 245 -232 245 -252 223 -254 251 -224 243 -220 255 -244 251 -226 251 -226 251 -252 213 -248 261 -220 251 -226 251 -254 223 -242 245 -232 245 -252 223 -254 251 -224 243 -220 255 -246 249 -226 251 -226 251 -252 213 -248 235 -248 251 -226 251 -252 +RAW_Data: 225 -242 245 -230 247 -252 223 -252 253 -224 243 -220 255 -244 251 -226 251 -226 251 -252 213 -248 233 -248 251 -226 251 -254 223 -242 245 -232 245 -252 223 -254 251 -224 253 -214 247 -234 249 -252 251 -226 251 -224 241 -246 231 -246 251 -226 251 -226 251 -252 213 -248 261 -224 251 -226 251 -252 225 -242 245 -230 245 -252 225 -252 253 -224 253 -212 247 -236 247 -252 253 -224 251 -226 241 -246 231 -246 251 -224 253 -252 225 -252 213 -248 261 -222 253 -224 253 -252 223 -242 247 -230 245 -252 225 -252 251 -226 241 -222 253 -246 251 -224 253 -224 251 -252 213 -248 233 -250 251 -224 253 -252 225 -242 245 -230 245 -252 225 -252 251 -226 241 -222 253 -246 251 -224 253 -224 253 -252 213 -248 233 -250 251 -224 253 -252 223 -242 245 -232 245 -252 223 -254 251 -224 253 -214 247 -236 247 -252 253 -224 251 -226 241 -246 231 -246 251 -224 253 -252 223 -252 213 -248 261 -224 251 -252 223 -254 223 -242 245 -232 245 -252 225 -252 251 -226 241 -222 253 -246 251 -224 253 -224 251 -254 213 -246 261 -224 251 -226 251 -252 225 -242 245 -230 245 -252 223 -254 251 -224 243 -220 255 -244 251 -226 251 -226 251 -252 213 -248 261 -222 251 -226 251 -254 223 -242 245 -232 243 -252 225 -252 253 -224 241 -222 253 -246 251 -226 251 -224 253 -252 213 -248 233 -248 251 -254 223 -252 225 -242 245 -232 245 -252 223 -254 251 -224 241 -222 255 -244 251 -226 251 -226 251 -254 213 -246 235 -248 251 -226 251 -254 223 -242 245 -230 245 -252 225 -252 251 -226 241 -222 253 -246 251 -224 253 -224 251 -254 213 -248 233 -248 251 -226 251 -254 223 -242 245 -232 245 -252 223 -254 251 -226 241 -220 255 -246 249 -226 253 -224 251 -254 213 -246 235 -248 251 -226 251 -252 225 -242 245 -230 245 -252 225 -252 253 -224 241 -220 255 -246 249 -226 251 -226 251 -252 213 -248 261 -222 253 -224 253 -252 223 -242 247 -230 245 -252 225 -252 251 -226 251 -214 247 -234 249 -252 251 -226 251 -224 241 -248 229 -248 249 -226 253 -252 223 -252 213 -248 263 -222 251 -226 251 -254 223 -242 245 -230 245 -254 223 -252 253 -224 241 -222 255 -244 251 -226 251 -226 251 -252 213 -248 233 -250 251 -226 251 -252 225 -252 213 -248 263 -222 251 -226 251 -254 223 -242 245 -232 245 -252 225 -252 251 -226 241 -222 253 -246 485 -488 457 -504 481 -462 493 -480 227 -246 251 -244 251 -226 251 -224 253 -224 493 -474 247 -252 475 -486 243 -222 485 -492 +RAW_Data: 231 -234 247 -252 481 -462 493 -480 225 -248 251 -244 251 -224 479 -486 237 -246 251 -226 251 -224 253 -252 467 -474 481 -492 489 -458 245 -250 469 -494 481 -480 231 -238 247 -252 253 -224 253 -224 241 -246 465 -488 243 -240 245 -234 481 -488 487 -472 481 -492 229 -236 485 -474 485 -478 249 -250 251 -226 241 -246 231 -246 251 -224 479 -486 237 -248 485 -470 253 -232 245 -252 223 -254 473 -486 243 -224 251 -254 1439 -1448 249 -224 251 -226 251 -224 241 -246 233 -248 251 -226 251 -254 223 -242 245 -230 245 -252 225 -252 251 -226 241 -222 253 -246 249 -226 253 -224 497 -462 483 -490 485 -472 479 -480 259 -244 223 -254 251 -224 253 -224 241 -246 467 -488 243 -240 477 -484 247 -250 469 -494 247 -224 253 -224 499 -462 481 -488 233 -248 233 -248 251 -224 477 -486 239 -248 253 -224 253 -252 223 -254 467 -476 479 -490 491 -458 271 -224 469 -496 479 -480 233 -238 249 -254 251 -224 253 -224 241 -222 489 -482 269 -212 247 -234 483 -500 483 -480 481 -460 261 -244 485 -460 485 -478 247 -246 223 -248 261 -222 249 -222 247 -252 479 -488 243 -238 479 -482 225 -248 249 -242 251 -226 479 -486 237 -246 251 -226 1443 -1446 243 -252 225 -252 225 -252 253 -212 247 -234 247 -252 253 -224 251 -226 241 -246 231 -246 251 -226 251 -224 253 -252 213 -248 261 -222 251 -226 477 -484 503 -462 489 -490 479 -482 229 -238 247 -252 223 -254 251 -224 243 -220 489 -480 251 -246 467 -480 251 -248 465 -488 243 -240 247 -232 481 -488 487 -472 249 -252 223 -254 223 -242 475 -486 245 -252 223 -242 247 -234 247 -252 481 -460 493 -482 481 -490 249 -224 477 -482 475 -480 243 -240 247 -234 247 -252 251 -226 251 -224 469 -496 247 -254 223 -252 469 -490 483 -462 483 -478 247 -252 473 -486 479 -478 231 -246 261 -224 251 -254 223 -252 225 -242 475 -482 249 -222 505 -486 245 -224 241 -222 255 -246 483 -468 255 -232 245 -252 1445 -1446 243 -460 421 -100 233 -78 103 -126 73 -364 133 -274 163 -238 509 -132 51 -238 211 -812 77 -208 245 -276 261 -184 309 -1392 587 -182 209 -182 101 -122 121 -128 99 -300 175 -154 283 -210 51 -136 163 -506 655 -132 77 -76 157 -242 265 -214 243 -242 163 -574 605 -336 101 -102 331 -78 741 -52 255 -128 51 -178 127 -200 129 -462 179 -132 165 -108 53 -78 159 -728 157 -134 109 -162 129 -108 239 -344 199 -328 99 -102 209 -384 101 -154 229 -78 157 -52 103 -976 259 -102 123 -76 123 -102 +RAW_Data: 73 -200 79 -52 131 -212 55 -402 285 -212 315 -56 573 -110 81 -54 161 -214 53 -390 351 -106 53 -316 129 -230 131 -162 163 -136 55 -140 263 -54 137 -192 313 -184 211 -322 53 -108 139 -56 719 -104 323 -236 263 -138 355 -162 135 -266 155 -156 103 -76 251 -284 335 -102 123 -252 185 -190 237 -394 75 -78 79 -132 81 -328 109 -82 179 -530 163 -160 85 -56 375 -52 351 -416 79 -160 107 -492 53 -108 109 -280 53 -52 235 -216 303 -84 131 -160 79 -80 243 -54 215 -82 165 -82 77 -182 207 -330 107 -264 451 -402 131 -134 53 -464 103 -354 51 -188 163 -154 133 -266 105 -52 209 -430 51 -108 107 -186 131 -426 51 -108 55 -82 179 -164 135 -104 399 -52 105 -214 105 -312 135 -188 51 -242 107 -134 79 -314 77 -54 133 -54 105 -164 135 -318 81 -232 151 -180 127 -102 99 -102 453 -130 299 -126 99 -798 235 -206 149 -100 79 -108 955 -80 79 -210 107 -132 131 -196 291 -134 159 -80 377 -312 159 -242 107 -52 53 -156 51 -132 79 -54 133 -274 157 -54 105 -134 387 -104 129 -234 77 -254 361 -52 77 -104 101 -52 53 -54 561 -80 163 -54 109 -216 51 -498 535 -82 163 -210 51 -182 259 -102 75 -76 305 -102 253 -172 215 -268 77 -52 81 -186 133 -106 333 -162 111 -220 569 -102 215 -54 131 -196 433 -80 51 -158 129 -108 53 -188 261 -52 101 -100 227 -402 201 -182 77 -78 175 -126 75 -306 231 -100 149 -178 489 -228 221 -154 77 -220 81 -52 51 -308 233 -104 77 -156 73 -286 181 -132 133 -144 165 -160 109 -54 105 -236 153 -76 211 -372 133 -140 105 -104 77 -320 653 -54 159 -54 181 -162 133 -406 213 -80 79 -132 211 -154 233 -138 189 -84 165 -200 217 -298 107 -272 161 -110 135 -172 103 -102 291 -56 109 -56 317 -52 105 -54 587 -1018 53 -132 109 -56 187 -80 109 -160 81 -80 107 -188 53 -56 237 -158 79 -154 127 -76 51 -204 103 -106 83 -54 313 -52 187 -186 183 -82 189 -474 133 -82 189 -110 155 -136 55 -192 133 -80 183 -106 233 -52 79 -188 187 -158 77 -106 133 -242 111 -106 81 -108 53 -130 245 -290 131 -54 163 -356 287 -156 51 -80 155 -86 687 -104 53 -290 341 -108 217 -160 51 -188 215 -52 133 -210 161 -186 185 -244 51 -210 51 -184 187 -84 133 -108 101 -126 123 -52 77 -150 255 -132 79 -820 183 -108 263 -340 79 -110 137 -82 243 -80 81 -162 51 -132 131 -136 83 -78 181 -126 299 -80 571 -134 105 -80 +RAW_Data: 187 -216 109 -112 359 -316 79 -108 189 -82 133 -266 319 -544 311 -314 51 -162 165 -136 107 -162 193 -194 427 -104 269 -136 107 -80 343 -106 207 -266 53 -80 75 -178 99 -74 169 -506 51 -150 149 -620 207 -266 325 -106 183 -184 161 -106 141 -86 137 -134 239 -214 289 -104 51 -52 77 -106 129 -344 51 -372 75 -302 361 -214 393 -290 103 -106 135 -82 81 -82 185 -136 55 -194 81 -164 81 -78 101 -168 83 -186 81 -222 105 -52 105 -186 79 -418 129 -324 125 -128 75 -256 407 -414 131 -108 107 -80 135 -54 693 -52 369 -80 159 -162 53 -370 79 -162 55 -164 463 -236 77 -230 99 -178 153 -230 129 -80 161 -82 241 -322 79 -216 105 -216 81 -244 105 -326 289 -210 105 -82 299 -52 473 -496 159 -52 79 -108 249 -80 179 -132 107 -84 303 -370 239 -162 239 -126 149 -430 75 -52 123 -304 637 -238 109 -160 379 -190 647 -370 157 -294 235 -292 133 -108 135 -900 183 -56 241 -414 77 -210 161 -190 53 -184 185 -54 103 -394 131 -196 135 -546 151 -76 73 -100 201 -102 125 -316 259 -208 351 -160 81 -456 107 -232 129 -126 75 -228 101 -78 75 -230 431 -102 101 -172 201 -132 107 -108 303 -166 55 -458 203 -76 51 -232 131 -168 85 -198 137 -80 79 -84 81 -80 131 -194 585 -292 155 -722 221 -588 371 -132 101 -246 107 -270 81 -136 81 -262 289 -108 217 -218 77 -104 219 -342 259 -106 187 -78 133 -594 51 -132 267 -80 107 -54 53 -134 131 -192 243 -52 77 -102 155 -78 79 -104 79 -286 353 -192 53 -84 133 -184 75 -198 127 -132 123 -464 407 -130 103 -102 335 -202 103 -104 129 -176 289 -188 357 -754 255 -386 53 -138 255 -140 135 -426 53 -134 237 -52 187 -196 401 -54 157 -344 159 -192 55 -82 219 -202 215 -164 55 -166 81 -350 105 -158 101 -52 51 -284 129 -366 103 -392 53 -52 367 -312 133 -248 111 -272 211 -242 51 -158 165 -136 163 -54 133 -132 125 -374 229 -230 173 -304 103 -480 75 -78 175 -128 77 -362 127 -246 275 -76 313 -156 105 -158 247 -436 235 -132 71 -222 177 -236 345 -78 343 -78 341 -190 297 -188 77 -78 101 -76 99 -152 333 -154 101 -74 147 -122 75 -152 175 -452 453 -182 261 -284 149 -156 103 -170 109 -236 155 -110 295 -206 77 -132 81 -110 141 -1406 365 -214 79 -110 105 -484 87 -198 53 -106 185 -140 111 -322 77 -444 131 -78 239 -80 103 -182 131 -184 51 -106 107 -270 239 -134 213 -132 53 -316 513 -236 77 -80 +RAW_Data: 163 -664 131 -188 269 -110 135 -200 73 -126 95 -380 53 -128 195 -98 271 -158 147 -224 103 -132 125 -360 231 -336 229 -374 643 -180 247 -104 75 -434 79 -322 107 -138 107 -322 51 -776 157 -78 105 -184 51 -264 433 -82 53 -344 79 -82 161 -110 253 -106 77 -52 101 -78 127 -804 157 -148 73 -74 75 -256 301 -126 99 -76 235 -52 155 -460 77 -130 73 -222 283 -134 53 -110 55 -162 53 -106 263 -78 105 -214 133 -192 107 -208 133 -164 243 -346 105 -276 73 -52 77 -226 131 -408 189 -138 217 -508 77 -214 53 -78 235 -52 213 -372 219 -108 53 -210 207 -52 207 -184 99 -200 103 -54 129 -76 101 -104 101 -74 73 -406 181 -174 509 -300 143 -378 177 -254 101 -216 243 -616 239 -154 99 -312 335 -52 75 -180 127 -202 75 -108 189 -214 101 -384 267 -528 153 -260 367 -214 161 -108 183 -136 107 -130 77 -296 211 -132 189 -134 133 -54 107 -326 51 -266 103 -76 263 -242 313 -284 129 -132 185 -54 275 -138 239 -136 165 -316 129 -212 319 -214 55 -110 237 -312 77 -54 79 -210 227 -76 101 -102 125 -76 251 -104 187 -192 105 -162 79 -404 557 -486 159 -272 157 -84 141 -650 187 -130 205 -596 257 -102 135 -160 101 -270 355 -162 109 -196 187 -104 75 -52 159 -52 107 -266 129 -128 565 -52 133 -54 241 -160 187 -598 51 -184 797 -164 81 -132 161 -160 179 -54 111 -108 159 -164 53 -82 107 -158 161 -162 153 -458 329 -312 79 -218 77 -238 241 -270 307 -110 135 -314 131 -106 53 -354 157 -186 291 -260 563 -80 133 -80 77 -234 219 -84 215 -292 81 -82 135 -54 79 -270 55 -186 77 -78 215 -192 211 -220 109 -158 71 -104 51 -186 263 -230 99 -152 227 -52 75 -102 127 -104 157 -318 107 -112 111 -116 159 -82 105 -218 239 -160 305 -188 99 -52 279 -102 149 -148 259 -180 51 -52 131 -466 135 -460 183 -580 77 -130 51 -106 77 -80 135 -304 107 -160 709 -372 79 -164 53 -158 53 -184 233 -180 107 -466 187 -78 79 -134 291 -78 51 -52 101 -78 75 -78 77 -416 283 -278 131 -106 137 -108 311 -236 247 -252 251 -226 251 -224 243 -220 255 -244 251 -226 251 -226 251 -252 215 -246 235 -248 251 -224 253 -252 223 -244 245 -230 245 -252 225 -252 251 -226 241 -220 255 -246 249 -226 251 -226 251 -252 213 -248 261 -222 251 -254 223 -252 225 -242 245 -230 247 -252 223 -252 253 -224 243 -220 255 -244 251 -226 251 -226 251 -252 213 -248 235 -248 251 -226 251 -252 +RAW_Data: 225 -242 245 -230 245 -252 223 -254 251 -224 243 -220 255 -244 251 -226 251 -226 251 -254 213 -246 235 -248 251 -226 251 -252 225 -242 245 -230 245 -254 223 -252 253 -224 253 -212 247 -236 247 -252 253 -224 251 -226 241 -246 231 -246 251 -224 253 -252 223 -254 213 -246 263 -222 251 -254 223 -254 223 -242 245 -232 245 -252 225 -252 251 -226 241 -222 253 -246 251 -224 253 -224 253 -252 213 -246 235 -248 251 -226 251 -254 223 -242 245 -232 245 -252 223 -254 251 -224 253 -214 247 -236 247 -252 251 -226 251 -224 243 -246 229 -246 251 -226 251 -226 251 -252 213 -248 261 -222 253 -224 253 -252 223 -242 245 -232 245 -252 225 -252 251 -224 241 -222 253 -246 251 -226 251 -224 251 -254 213 -248 233 -250 251 -226 251 -254 223 -242 245 -232 245 -252 223 -254 251 -224 243 -220 255 -244 251 -226 251 -226 251 -252 213 -248 259 -222 253 -224 253 -252 223 -242 247 -230 245 -252 225 -252 251 -226 241 -220 255 -244 251 -226 251 -226 251 -252 215 -246 235 -248 253 -224 253 -252 223 -254 213 -248 261 -224 251 -224 253 -252 225 -242 245 -230 245 -252 225 -252 253 -224 241 -222 253 -246 251 -226 251 -224 251 -254 213 -248 233 -250 251 -226 251 -254 223 -242 245 -230 245 -252 223 -254 251 -226 241 -220 255 -246 251 -224 253 -224 251 -254 213 -248 233 -248 251 -226 251 -254 223 -242 245 -232 245 -252 223 -254 251 -224 243 -220 255 -244 251 -226 251 -226 251 -254 213 -246 235 -248 251 -226 251 -254 223 -252 215 -248 261 -222 253 -224 253 -252 223 -242 247 -230 245 -252 225 -252 253 -224 241 -222 253 -246 251 -226 251 -224 253 -252 213 -248 259 -222 251 -226 251 -254 223 -242 245 -232 245 -252 225 -252 251 -226 251 -214 247 -234 249 -252 251 -226 251 -224 241 -248 229 -248 249 -226 253 -252 223 -254 213 -246 261 -224 251 -254 223 -252 225 -242 245 -230 247 -252 223 -252 253 -224 241 -222 253 -246 251 -226 251 -224 253 -252 213 -248 259 -224 251 -226 251 -252 225 -242 245 -230 245 -252 225 -252 253 -224 251 -214 247 -236 247 -254 251 -224 253 -224 241 -246 231 -246 251 -226 251 -252 225 -252 213 -248 261 -222 251 -226 251 -254 223 -242 245 -230 247 -252 223 -254 251 -224 243 -220 255 -244 251 -226 251 -226 251 -254 213 -248 233 -248 251 -226 251 -252 225 -242 245 -230 245 -254 223 -252 253 -224 241 -222 255 -244 251 -226 251 -226 251 -252 213 -248 233 -248 251 -254 223 -254 223 -242 245 -232 +RAW_Data: 245 -252 223 -254 251 -226 241 -220 255 -244 251 -226 251 -226 251 -252 213 -248 261 -222 251 -254 223 -252 225 -242 245 -230 245 -254 223 -252 253 -224 241 -222 253 -246 251 -224 253 -224 251 -254 213 -248 233 -250 251 -224 253 -252 225 -242 243 -232 245 -252 225 -252 253 -224 241 -222 253 -246 251 -226 251 -224 253 -252 213 -248 233 -248 251 -226 477 -486 501 -456 487 -494 483 -466 255 -232 247 -252 223 -254 251 -226 251 -214 503 -458 243 -252 469 -496 247 -224 477 -486 239 -250 251 -226 477 -486 473 -480 253 -246 467 -488 241 -242 475 -484 247 -224 247 -264 221 -252 251 -226 471 -488 479 -476 485 -502 221 -252 473 -486 479 -490 231 -248 229 -248 249 -226 251 -254 223 -242 477 -482 247 -252 223 -242 475 -482 479 -486 481 -480 253 -232 481 -488 487 -472 247 -252 223 -254 223 -242 245 -232 247 -252 483 -460 493 -488 467 -488 479 -490 231 -248 231 -248 483 -466 487 -484 247 -250 1433 -1456 225 -246 251 -240 251 -224 253 -224 251 -226 241 -246 231 -248 251 -226 251 -254 223 -242 245 -230 245 -252 223 -254 251 -224 253 -214 247 -234 483 -498 483 -482 477 -486 471 -488 243 -250 213 -248 235 -248 251 -254 223 -254 467 -490 249 -224 477 -482 237 -248 485 -468 255 -232 245 -252 481 -462 493 -482 225 -248 483 -480 225 -248 485 -480 251 -222 255 -244 251 -226 251 -252 469 -464 483 -498 483 -482 247 -224 471 -488 481 -480 253 -234 245 -252 223 -252 253 -224 251 -214 505 -460 245 -252 251 -214 503 -458 505 -462 483 -498 229 -250 477 -480 485 -482 247 -224 251 -252 213 -248 233 -250 251 -226 477 -486 475 -488 489 -492 483 -462 231 -248 261 -224 483 -492 463 -484 249 -248 1445 -1430 255 -234 245 -252 223 -254 251 -224 253 -214 245 -236 247 -252 251 -226 251 -226 241 -246 231 -246 251 -224 253 -252 223 -254 213 -248 235 -248 485 -492 459 -484 479 -486 483 -500 227 -250 241 -252 223 -254 223 -252 225 -242 477 -484 247 -250 469 -494 247 -224 479 -488 237 -246 251 -226 479 -486 471 -480 251 -222 489 -480 253 -246 465 -480 243 -240 245 -236 247 -252 253 -224 473 -486 481 -478 485 -482 247 -224 503 -460 497 -484 243 -224 251 -254 225 -252 223 -242 247 -232 481 -474 255 -226 265 -222 485 -490 489 -456 505 -462 247 -252 477 -482 471 -482 243 -240 247 -232 247 -252 225 -252 251 -226 467 -496 481 -468 487 -482 497 -458 267 -224 251 -254 449 -484 503 -464 241 -240 1447 -1454 229 -804 209 -238 diff --git a/assets/unit_tests/subghz/nero_radio_raw.sub b/assets/unit_tests/subghz/nero_radio_raw.sub new file mode 100644 index 00000000000..265ed20ad6f --- /dev/null +++ b/assets/unit_tests/subghz/nero_radio_raw.sub @@ -0,0 +1,13 @@ +Filetype: Flipper SubGhz RAW File +Version: 1 +Frequency: 434420000 +Preset: FuriHalSubGhzPresetOok650Async +Protocol: RAW +RAW_Data: 1487 -32700 235 -202 229 -218 217 -176 197 -220 217 -210 191 -218 217 -210 189 -218 217 -210 187 -212 181 -230 203 -194 211 -212 213 -226 197 -188 211 -212 213 -226 197 -186 211 -212 213 -228 195 -186 211 -212 239 -172 235 -218 181 -212 193 -218 219 -208 191 -212 211 -200 205 -224 181 -212 213 -228 197 -188 211 -212 213 -226 197 -186 211 -212 213 -226 197 -186 211 -212 213 -226 197 -186 211 -212 213 -226 197 -186 211 -212 237 -174 235 -218 789 -244 205 -384 415 -230 185 -418 419 -226 179 -436 419 -190 435 -198 415 -210 215 -406 187 -436 421 -190 213 -438 193 -404 413 -224 185 -430 411 -238 181 -432 201 -428 199 -404 207 -420 205 -426 385 -244 213 -400 411 -192 221 -400 239 -412 205 -426 205 -394 203 -412 243 -390 203 -426 417 -214 215 -402 211 -428 203 -392 205 -406 231 -396 411 -232 203 -408 207 -424 393 -232 203 -408 209 -422 395 -232 397 -244 391 -202 219 -430 389 -238 405 -208 425 -206 217 -394 389 -238 207 -388 243 -382 411 -244 383 -1234 219 -406 225 -198 255 -182 175 -204 211 -212 201 -208 227 -182 211 -214 227 -198 187 -212 211 -214 225 -198 185 -212 211 -240 171 -230 181 -212 213 -226 199 -188 211 -210 213 -228 195 -188 211 -212 213 -226 197 -186 211 -212 213 -228 195 -186 211 -212 213 -228 195 -188 209 -212 239 -172 227 -182 211 -212 227 -198 189 -212 211 -214 225 -198 187 -212 241 -182 227 -198 185 -212 211 -214 227 -196 185 -212 211 -240 173 -234 219 -182 209 -194 833 -210 213 -410 409 -232 199 -406 415 -204 215 -428 387 -244 391 -204 425 -206 215 -428 205 -382 419 -226 181 -434 195 -440 413 -192 219 -400 447 -202 217 -396 203 -418 189 -438 183 -436 195 -408 443 -194 217 -400 445 -204 217 -396 201 -430 199 -404 209 -422 205 -426 205 -412 193 -420 417 -202 223 -402 239 -408 207 -392 237 -382 223 -412 409 -226 191 -430 209 -416 395 -232 197 -404 209 -422 395 -232 397 -242 393 -202 217 -432 389 -238 407 -206 393 -238 217 -396 387 -238 209 -386 243 -388 411 -240 407 -4594 195 -408 245 -214 173 -218 211 -182 231 -204 223 -180 211 -214 227 -198 187 -212 211 -214 225 -198 185 -212 211 -214 227 -196 185 -212 211 -214 227 -196 185 -212 211 -240 173 -234 217 -182 211 -194 219 -218 207 -192 211 -212 199 -206 223 -182 211 -214 227 -198 187 -212 211 -240 171 -236 217 -182 211 -194 217 -220 207 -192 211 -212 201 -206 193 -212 241 -182 227 -200 187 -212 209 -240 173 -228 +RAW_Data: 181 -212 211 -228 197 -188 211 -212 213 -228 815 -200 205 -404 437 -200 217 -432 389 -238 171 -414 445 -192 401 -244 389 -204 215 -426 203 -428 383 -246 177 -430 211 -428 389 -236 171 -412 413 -224 187 -430 239 -406 205 -394 237 -394 203 -410 415 -230 185 -432 411 -200 217 -432 203 -394 203 -436 201 -398 221 -404 227 -412 185 -436 423 -206 217 -416 207 -392 201 -418 223 -410 217 -404 425 -206 215 -418 205 -394 415 -244 211 -396 213 -426 387 -202 437 -208 391 -238 181 -432 387 -240 411 -206 425 -206 217 -396 387 -238 209 -388 243 -382 411 -244 383 -4672 243 -394 239 -182 253 -176 195 -182 211 -230 201 -192 209 -212 213 -192 231 -188 211 -212 211 -194 231 -186 211 -212 211 -194 231 -186 211 -212 211 -194 231 -186 211 -212 211 -228 197 -186 211 -212 211 -194 231 -186 211 -212 213 -192 231 -186 211 -212 211 -194 231 -186 211 -212 211 -194 231 -186 211 -212 211 -194 231 -186 211 -212 211 -194 229 -188 241 -182 211 -226 197 -188 211 -212 211 -194 231 -186 211 -212 211 -194 231 -186 211 -212 861 -188 211 -412 415 -210 211 -390 449 -190 215 -400 449 -166 465 -170 409 -210 251 -362 245 -396 423 -202 203 -408 247 -392 425 -200 201 -406 453 -170 253 -392 205 -380 257 -382 217 -404 227 -410 405 -200 231 -402 419 -204 217 -430 205 -380 221 -414 217 -404 227 -408 215 -404 227 -374 435 -198 233 -398 245 -390 205 -426 205 -378 257 -382 439 -194 225 -396 245 -388 395 -230 199 -404 247 -390 425 -200 431 -174 429 -202 219 -398 419 -204 441 -208 425 -170 253 -396 387 -240 207 -382 247 -390 409 -204 439 -4538 203 -408 229 -196 223 -182 217 -210 191 -220 217 -208 191 -210 211 -204 205 -194 211 -212 213 -192 231 -186 211 -212 213 -192 231 -186 211 -212 213 -192 231 -188 211 -212 211 -192 231 -186 211 -212 213 -192 231 -188 211 -212 211 -194 229 -186 211 -212 213 -192 231 -188 211 -212 211 -194 229 -188 211 -210 213 -194 229 -186 211 -212 213 -192 231 -186 243 -180 211 -228 197 -186 211 -212 213 -192 231 -188 211 -212 211 -194 229 -186 211 -212 833 -210 215 -408 407 -234 199 -404 417 -206 215 -430 415 -216 393 -204 427 -206 217 -394 241 -392 429 -186 213 -412 237 -394 431 -174 251 -376 437 -192 225 -396 245 -390 205 -394 237 -396 235 -378 447 -192 213 -400 447 -166 255 -396 201 -430 199 -400 245 -390 205 -426 205 -380 257 -382 439 -194 223 -398 211 -422 205 -394 237 -396 237 -376 453 -166 +RAW_Data: 215 -432 203 -402 439 -204 203 -404 247 -390 425 -202 429 -176 427 -202 219 -396 421 -204 441 -208 427 -168 253 -396 387 -240 207 -382 245 -392 409 -204 439 -4532 225 -398 247 -178 241 -154 249 -182 217 -216 217 -176 239 -182 217 -212 191 -218 219 -176 221 -212 211 -202 205 -196 211 -212 211 -192 231 -186 211 -212 213 -192 231 -186 211 -212 211 -228 197 -186 211 -212 211 -228 197 -186 211 -212 211 -228 197 -186 211 -212 211 -194 231 -186 211 -212 213 -192 231 -188 211 -212 211 -192 231 -186 211 -212 213 -192 263 -156 211 -212 213 -192 231 -184 211 -212 213 -192 231 -186 211 -212 213 -192 231 -186 857 -202 217 -396 415 -212 213 -394 447 -190 215 -400 449 -166 447 -192 413 -212 215 -408 211 -428 387 -240 207 -382 247 -394 423 -202 203 -408 419 -204 251 -394 205 -380 255 -384 245 -394 203 -418 415 -206 217 -420 399 -194 229 -398 247 -390 205 -426 205 -380 255 -384 245 -394 203 -418 415 -206 217 -420 207 -394 237 -394 203 -406 247 -390 425 -202 201 -406 245 -392 425 -200 201 -406 245 -392 425 -200 431 -174 427 -204 217 -398 421 -202 441 -208 427 -168 255 -394 387 -240 207 -384 245 -392 407 -204 445 -4518 227 -398 241 -172 257 -152 211 -212 225 -200 217 -182 211 -212 227 -198 215 -182 211 -214 225 -198 217 -182 211 -212 225 -198 217 -180 211 -214 225 -198 217 -182 211 -212 227 -196 215 -182 211 -214 225 -198 217 -182 211 -212 227 -198 215 -182 211 -212 227 -196 217 -180 211 -214 225 -198 215 -182 211 -214 225 -198 217 -182 211 -212 225 -198 215 -182 211 -212 225 -198 217 -182 211 -212 227 -198 217 -182 211 -212 227 -196 217 -182 211 -212 855 -176 243 -380 453 -170 253 -392 417 -214 215 -366 445 -192 431 -216 431 -170 251 -392 205 -394 415 -212 249 -362 245 -396 423 -202 203 -408 453 -170 253 -392 205 -412 225 -384 217 -404 227 -410 421 -200 219 -400 445 -168 253 -396 203 -394 233 -398 247 -388 205 -426 205 -380 223 -416 419 -202 223 -400 241 -374 243 -394 237 -394 203 -406 419 -204 251 -394 205 -380 457 -204 217 -398 205 -426 415 -216 395 -204 427 -204 219 -394 417 -212 421 -206 425 -206 217 -396 417 -212 209 -388 247 -394 423 -202 435 -4428 207 -406 243 -180 211 -196 253 -182 209 -192 217 -218 209 -188 217 -220 207 -188 211 -180 231 -206 223 -182 211 -212 227 -198 215 -182 211 -212 227 -198 217 -180 211 -214 225 -198 215 -182 211 -214 225 -198 215 -182 211 -214 225 -198 +RAW_Data: 217 -180 211 -214 225 -198 215 -182 211 -214 225 -198 215 -182 211 -214 225 -198 217 -182 209 -214 225 -198 215 -182 241 -182 227 -200 185 -212 211 -206 241 -164 211 -212 213 -226 197 -188 211 -212 213 -226 819 -200 241 -370 435 -202 217 -398 421 -202 241 -378 453 -166 429 -210 423 -206 215 -422 207 -392 417 -210 213 -394 247 -394 423 -202 203 -408 453 -170 251 -394 205 -410 225 -386 245 -394 203 -418 411 -190 213 -434 417 -190 211 -406 225 -398 245 -392 205 -428 205 -410 227 -386 245 -394 417 -212 207 -386 245 -394 203 -428 205 -410 227 -386 439 -194 223 -398 209 -422 395 -232 199 -406 245 -390 423 -202 399 -210 427 -202 217 -398 421 -204 439 -208 427 -168 253 -396 387 -240 207 -382 245 -392 409 -240 407 -4630 235 -388 213 -192 249 -162 215 -218 217 -210 189 -220 217 -176 221 -218 217 -178 217 -182 241 -202 205 -192 211 -212 211 -194 231 -186 211 -212 213 -192 231 -186 211 -212 211 -194 231 -186 211 -212 211 -194 231 -186 211 -212 213 -192 231 -186 211 -212 213 -192 231 -186 211 -212 213 -192 231 -186 211 -212 213 -192 231 -186 211 -212 213 -192 231 -186 211 -212 213 -192 231 -186 211 -212 213 -192 231 -186 211 -212 213 -192 231 -188 211 -212 829 -210 215 -410 407 -232 201 -404 419 -204 217 -430 385 -210 427 -204 427 -204 219 -394 239 -394 431 -176 251 -374 245 -394 417 -210 209 -388 445 -192 221 -380 223 -416 245 -394 203 -428 199 -400 419 -204 215 -430 383 -246 215 -364 245 -396 239 -392 207 -408 229 -388 217 -404 229 -410 419 -200 219 -400 239 -372 243 -392 239 -394 201 -406 451 -170 251 -392 205 -412 429 -202 217 -398 205 -426 417 -214 429 -168 427 -206 217 -396 417 -210 423 -206 425 -206 217 -396 417 -210 211 -390 245 -394 425 -202 435 -32700 389 -182 211 -212 211 -194 229 -186 211 -212 213 -226 197 -188 211 -212 211 -226 197 -188 211 -212 211 -228 197 -186 211 -212 211 -194 229 -186 211 -212 213 -226 197 -188 211 -212 211 -226 197 -188 211 -212 211 -226 197 -188 209 -212 213 -226 197 -186 211 -212 213 -226 197 -188 211 -212 211 -226 197 -188 211 -210 213 -226 197 -188 211 -212 211 -228 195 -188 211 -212 211 -226 197 -188 211 -210 213 -226 199 -186 211 -212 831 -218 213 -408 417 -210 211 -390 451 -198 183 -430 429 -190 435 -196 411 -212 217 -404 217 -404 425 -206 215 -418 207 -394 415 -210 211 -396 447 -192 221 -396 237 -380 243 -394 203 -428 205 -410 429 -202 +RAW_Data: 219 -398 423 -202 203 -408 245 -388 205 -426 205 -410 227 -388 243 -394 417 -210 209 -386 245 -392 203 -428 205 -410 227 -388 245 -392 417 -210 209 -388 245 -394 421 -202 205 -410 243 -392 423 -202 399 -244 393 -202 217 -432 387 -238 205 -380 245 -392 203 -428 417 -214 215 -400 211 -396 423 -202 441 -1048 211 -396 237 -182 215 -214 217 -182 211 -200 211 -212 237 -174 227 -182 211 -214 225 -198 187 -212 211 -214 225 -198 185 -212 211 -214 225 -198 185 -212 211 -214 225 -198 185 -212 211 -214 225 -198 185 -212 211 -240 173 -230 181 -212 211 -228 197 -188 211 -212 213 -228 195 -186 211 -212 213 -228 195 -186 211 -212 213 -228 195 -186 211 -212 213 -226 229 -158 211 -212 237 -174 227 -180 211 -214 227 -198 187 -212 211 -214 227 -196 187 -210 831 -236 217 -394 395 -232 201 -406 415 -204 213 -430 417 -214 391 -204 425 -206 215 -428 205 -412 391 -238 217 -394 205 -426 385 -244 213 -398 417 -200 189 -432 203 -440 207 -394 201 -416 223 -410 409 -234 197 -402 417 -202 215 -430 205 -412 191 -418 217 -404 227 -410 185 -436 423 -206 215 -416 205 -394 201 -430 201 -408 245 -388 203 -426 417 -214 213 -402 211 -428 389 -238 203 -384 243 -390 423 -202 399 -244 391 -202 217 -432 387 -238 205 -384 243 -390 203 -428 417 -212 215 -402 211 -428 389 -238 405 -4628 201 -420 211 -216 243 -162 217 -218 207 -190 217 -218 209 -188 211 -182 229 -206 221 -182 211 -214 227 -196 187 -212 211 -214 225 -198 185 -212 211 -214 225 -198 185 -212 211 -214 225 -198 185 -212 211 -214 225 -198 185 -212 211 -214 225 -198 185 -212 211 -214 225 -198 185 -212 211 -214 225 -198 185 -212 211 -214 225 -198 185 -212 211 -240 171 -236 217 -182 211 -196 219 -218 207 -190 211 -182 231 -206 223 -182 211 -214 227 -198 185 -212 829 -224 211 -404 425 -206 215 -420 397 -230 197 -402 415 -204 407 -230 397 -244 217 -374 209 -428 417 -210 209 -388 243 -394 423 -202 203 -410 417 -240 213 -394 205 -410 227 -386 245 -394 201 -418 417 -206 215 -422 415 -206 203 -410 193 -418 245 -392 203 -428 199 -406 209 -422 395 -232 201 -406 245 -388 205 -426 205 -410 227 -386 245 -394 417 -208 209 -388 245 -392 423 -202 203 -410 243 -390 425 -202 433 -208 393 -202 217 -432 387 -240 203 -382 243 -394 203 -428 415 -214 215 -400 211 -430 389 -202 439 -4622 235 -388 215 -184 265 -170 201 -212 211 -202 207 -194 211 -212 213 -192 231 -186 211 -212 +RAW_Data: 213 -192 231 -186 211 -212 213 -192 231 -188 211 -212 211 -192 231 -186 211 -212 213 -192 231 -188 211 -210 213 -192 231 -186 211 -212 211 -228 197 -186 211 -212 211 -228 197 -186 211 -212 213 -192 231 -186 211 -212 213 -192 231 -186 211 -212 211 -228 197 -186 241 -182 211 -226 199 -186 211 -212 211 -228 197 -186 211 -212 211 -228 197 -186 211 -212 865 -174 251 -376 439 -192 193 -428 419 -204 217 -396 417 -210 425 -206 425 -206 217 -396 203 -430 393 -210 251 -376 245 -394 417 -210 209 -384 453 -166 213 -430 201 -408 245 -394 203 -428 205 -408 429 -202 219 -398 423 -202 201 -406 247 -390 205 -428 205 -378 257 -384 245 -394 417 -210 211 -386 245 -394 205 -426 205 -410 227 -384 247 -394 415 -212 209 -386 247 -392 407 -204 241 -380 247 -392 407 -204 441 -188 435 -198 193 -428 419 -204 217 -396 239 -380 223 -408 407 -234 201 -400 247 -388 427 -200 429 -4488 243 -394 237 -182 217 -210 191 -212 211 -202 205 -196 211 -210 213 -194 231 -186 211 -212 211 -194 231 -186 211 -212 211 -194 231 -186 211 -212 211 -194 231 -186 211 -212 211 -194 231 -186 211 -212 211 -194 229 -188 211 -210 213 -226 199 -186 211 -212 211 -194 231 -186 211 -212 211 -194 231 -186 211 -212 211 -194 231 -186 211 -212 211 -228 197 -186 241 -182 211 -226 197 -188 211 -212 211 -194 231 -186 211 -212 211 -194 231 -186 211 -212 865 -176 251 -372 439 -202 199 -404 419 -204 217 -430 383 -212 429 -204 427 -204 219 -394 239 -394 431 -176 251 -374 245 -392 417 -212 209 -386 453 -166 213 -430 203 -408 245 -392 205 -426 205 -410 427 -204 217 -398 423 -202 203 -406 245 -392 205 -426 205 -380 257 -382 245 -396 415 -212 209 -386 245 -394 205 -428 205 -410 225 -384 247 -394 417 -210 209 -388 245 -394 423 -202 235 -376 247 -390 425 -202 429 -176 427 -202 219 -398 419 -204 239 -378 245 -394 205 -426 417 -214 217 -368 245 -396 423 -202 437 -4658 199 -416 213 -216 241 -160 219 -218 207 -186 211 -182 231 -204 223 -182 211 -212 227 -198 215 -182 211 -212 227 -198 185 -212 211 -214 225 -198 215 -182 211 -212 227 -198 215 -182 211 -212 227 -198 215 -182 211 -212 227 -196 217 -182 211 -212 227 -196 217 -182 211 -212 227 -198 215 -182 211 -212 227 -198 215 -182 211 -212 227 -196 217 -182 211 -212 261 -166 193 -212 211 -204 205 -194 211 -212 213 -226 197 -188 211 -212 211 -228 195 -188 857 -202 217 -394 417 -210 213 -394 447 -192 +RAW_Data: 217 -400 445 -204 409 -194 413 -218 211 -410 199 -418 419 -204 215 -424 205 -394 415 -210 213 -398 443 -192 219 -400 239 -412 207 -392 239 -394 203 -408 451 -196 183 -432 409 -202 217 -432 203 -394 241 -370 231 -398 219 -404 227 -412 407 -234 197 -402 209 -420 205 -426 205 -412 193 -418 243 -394 417 -208 209 -388 245 -392 423 -202 205 -410 245 -388 425 -202 397 -244 393 -202 217 -432 387 -238 205 -382 243 -390 203 -428 417 -212 215 -404 211 -430 387 -204 439 -4628 237 -396 209 -216 243 -162 217 -218 209 -188 217 -218 209 -188 217 -218 207 -188 211 -182 231 -204 223 -182 211 -212 227 -198 215 -182 211 -212 227 -196 217 -182 211 -212 225 -198 217 -182 211 -212 225 -198 217 -182 211 -212 225 -198 217 -182 211 -212 227 -198 185 -212 211 -214 225 -198 215 -182 211 -212 227 -198 215 -182 211 -214 225 -198 215 -182 211 -212 225 -198 217 -182 211 -212 227 -198 215 -182 211 -212 225 -198 217 -182 211 -212 855 -178 243 -380 417 -204 251 -394 415 -216 215 -366 447 -190 433 -184 433 -196 219 -400 241 -378 433 -196 229 -398 247 -392 425 -200 199 -404 419 -204 217 -428 205 -412 193 -416 209 -430 201 -418 417 -206 215 -422 397 -196 229 -400 245 -388 205 -426 205 -410 227 -384 243 -394 417 -210 211 -386 245 -392 203 -428 205 -410 227 -388 243 -394 417 -210 209 -388 245 -394 425 -202 203 -408 245 -390 425 -202 431 -174 429 -202 217 -432 387 -202 241 -380 247 -392 203 -428 415 -214 215 -400 211 -428 387 -238 405 -4494 237 -392 241 -180 255 -180 215 -182 217 -210 191 -218 217 -208 189 -212 211 -202 203 -194 211 -212 211 -228 197 -188 211 -212 211 -226 197 -188 211 -212 211 -226 197 -188 211 -212 213 -226 197 -186 211 -212 213 -228 195 -186 211 -212 213 -194 229 -188 211 -210 213 -194 229 -186 211 -212 213 -192 231 -186 211 -212 213 -194 229 -186 211 -212 211 -228 197 -188 211 -212 213 -192 229 -186 211 -212 211 -226 197 -188 211 -212 211 -226 197 -188 859 -204 217 -396 415 -210 211 -392 453 -196 187 -418 419 -224 403 -198 423 -210 215 -408 211 -430 387 -240 205 -384 245 -394 423 -202 203 -408 417 -206 215 -428 205 -412 193 -416 245 -394 201 -428 393 -210 215 -410 405 -226 193 -428 209 -420 205 -428 203 -412 191 -418 209 -430 387 -240 207 -386 245 -392 205 -426 205 -410 227 -388 243 -394 417 -210 209 -388 245 -394 423 -202 203 -408 245 -392 423 -202 433 -210 393 -202 217 -432 387 -238 +RAW_Data: 203 -380 245 -392 203 -428 417 -214 215 -400 213 -396 421 -202 441 -32700 249 -214 213 -192 227 -184 211 -212 213 -226 197 -186 211 -212 213 -226 197 -186 211 -212 213 -226 197 -186 211 -212 213 -226 197 -186 211 -212 213 -226 197 -186 211 -212 213 -226 197 -186 211 -212 213 -226 197 -186 211 -212 213 -226 197 -186 211 -212 213 -226 197 -186 211 -212 213 -226 197 -186 211 -212 213 -226 197 -186 211 -212 213 -226 197 -186 211 -212 213 -226 197 -186 211 -212 213 -226 197 -186 211 -212 213 -226 197 -186 857 -196 211 -404 435 -194 211 -404 427 -204 215 -410 411 -208 423 -206 425 -206 217 -396 201 -430 395 -244 215 -376 209 -428 417 -208 209 -388 451 -198 187 -428 201 -410 243 -392 201 -428 203 -412 429 -204 217 -398 425 -200 203 -410 243 -390 203 -428 203 -412 227 -386 209 -428 417 -210 209 -388 245 -390 203 -428 205 -410 227 -392 209 -428 417 -208 209 -390 245 -390 423 -202 203 -412 243 -390 425 -200 399 -244 393 -202 217 -432 387 -238 205 -380 245 -392 203 -426 417 -214 215 -404 211 -430 387 -204 439 -1154 195 -408 243 -196 185 -224 219 -218 209 -200 181 -212 213 -226 197 -186 211 -212 213 -226 197 -186 211 -212 213 -228 195 -186 211 -212 213 -228 195 -186 211 -212 213 -228 195 -186 211 -212 213 -226 197 -186 211 -212 213 -226 197 -186 211 -212 213 -226 195 -188 211 -212 213 -226 197 -186 211 -212 213 -226 197 -186 211 -212 213 -226 195 -188 211 -212 243 -202 203 -186 211 -212 199 -206 225 -182 211 -214 225 -198 187 -212 211 -212 227 -196 833 -196 225 -412 393 -236 217 -396 393 -232 201 -406 417 -204 435 -202 397 -244 215 -376 243 -394 417 -210 209 -388 245 -382 411 -244 193 -412 425 -202 203 -408 243 -390 203 -428 203 -412 227 -386 417 -202 233 -410 427 -202 217 -396 203 -428 205 -410 193 -418 209 -428 203 -428 393 -210 213 -412 209 -428 203 -428 197 -404 209 -422 205 -426 385 -246 213 -398 213 -396 421 -202 237 -380 245 -390 425 -200 399 -244 393 -202 217 -432 387 -240 203 -382 245 -390 205 -426 417 -214 215 -402 211 -430 387 -202 441 -4664 205 -398 211 -216 241 -164 217 -218 209 -188 217 -220 207 -188 211 -182 231 -204 223 -182 209 -214 227 -198 185 -212 211 -214 225 -198 185 -212 211 -214 227 -196 185 -212 211 -214 225 -198 185 -212 211 -214 227 -196 185 -212 211 -214 225 -198 185 -212 211 -214 225 -198 185 -212 211 -214 227 -196 187 -210 211 -214 227 -196 185 -212 diff --git a/assets/unit_tests/subghz/nero_sketch_raw.sub b/assets/unit_tests/subghz/nero_sketch_raw.sub new file mode 100644 index 00000000000..6660b5c4208 --- /dev/null +++ b/assets/unit_tests/subghz/nero_sketch_raw.sub @@ -0,0 +1,17 @@ +Filetype: Flipper SubGhz RAW File +Version: 1 +Frequency: 315000000 +Preset: FuriHalSubGhzPresetOok650Async +Protocol: RAW +RAW_Data: -2704 519 -368 279 -698 297 -712 259 -716 309 -688 647 -356 289 -710 615 -384 275 -692 345 -654 321 -696 619 -376 317 -658 335 -652 325 -684 655 -336 317 -698 295 -682 325 -678 639 -376 319 -662 331 -652 677 -352 631 -326 677 -326 315 -682 323 -680 317 -670 315 -702 637 -362 315 -654 679 -352 315 -658 315 -690 321 -676 647 -346 317 -660 337 -688 289 -686 655 -338 1007 -334 317 -350 301 -344 343 -350 315 -334 325 -352 313 -334 313 -346 349 -316 333 -326 351 -314 333 -348 315 -350 301 -344 343 -352 315 -302 353 -352 313 -334 313 -346 315 -350 301 -358 351 -314 333 -316 345 -350 303 -344 343 -352 313 -334 323 -350 315 -334 313 -344 349 -304 343 -340 317 -350 301 -356 315 -350 301 -346 345 -350 301 -344 343 -352 315 -302 353 -352 313 -334 313 -346 315 -350 333 -326 353 -314 333 -314 347 -350 1315 -320 681 -346 297 -680 317 -672 315 -700 311 -672 649 -354 323 -684 643 -352 313 -658 347 -654 323 -664 651 -376 317 -660 333 -652 323 -684 655 -338 317 -688 321 -676 293 -704 639 -338 353 -662 299 -684 647 -350 667 -326 677 -326 313 -676 323 -680 317 -670 315 -700 639 -362 315 -688 647 -352 313 -658 351 -662 297 -682 647 -350 349 -656 311 -688 321 -660 653 -342 1007 -334 317 -350 303 -344 343 -350 317 -332 325 -352 315 -336 311 -346 349 -316 333 -328 351 -316 303 -344 345 -350 303 -342 343 -316 351 -300 355 -350 315 -334 313 -344 315 -352 331 -328 351 -314 333 -316 345 -350 301 -344 341 -352 315 -332 323 -352 315 -334 313 -344 349 -316 333 -328 351 -316 333 -314 347 -350 301 -344 341 -352 315 -334 323 -352 315 -336 311 -346 313 -352 331 -328 351 -316 303 -344 345 -350 303 -342 343 -352 1281 -352 645 -346 333 -678 315 -672 313 -702 311 -672 643 -354 325 -676 645 -352 313 -690 315 -654 323 -704 649 -344 317 -660 335 -652 323 -684 671 -346 317 -660 335 -684 291 -682 671 -346 317 -660 335 -652 677 -352 627 -364 645 -324 351 -648 323 -682 317 -674 347 -656 643 -360 313 -676 649 -350 315 -692 307 -688 287 -690 653 -338 353 -664 297 -678 319 -684 655 -338 983 -362 315 -350 303 -342 341 -352 315 -334 323 -352 313 -334 313 -346 313 -352 333 -326 351 -316 303 -344 345 -350 303 -342 343 -316 351 -300 355 -352 313 -334 313 -346 313 -352 301 -358 351 -314 305 -344 345 -350 301 -342 343 -352 315 -302 353 -352 315 -334 313 -344 349 -304 341 -342 317 -350 301 -354 317 -350 301 -344 345 -350 315 +RAW_Data: -334 325 -354 313 -334 313 -346 349 -302 341 -344 315 -352 301 -354 317 -348 303 -344 345 -350 1315 -324 677 -316 313 -706 293 -702 315 -670 313 -670 675 -322 329 -688 643 -352 315 -688 315 -654 323 -698 641 -348 315 -692 305 -688 289 -686 651 -342 353 -662 329 -652 323 -684 655 -334 317 -690 321 -676 649 -346 639 -354 637 -360 313 -676 323 -680 309 -688 317 -688 645 -350 315 -658 677 -320 329 -684 319 -660 341 -658 643 -354 327 -684 289 -688 341 -658 677 -320 989 -354 303 -352 315 -334 351 -350 315 -334 313 -342 315 -350 301 -358 351 -316 333 -314 345 -350 303 -342 341 -352 315 -334 323 -352 315 -334 311 -346 313 -352 301 -358 351 -314 305 -344 345 -350 315 -336 325 -352 313 -336 313 -346 349 -316 301 -358 351 -316 303 -344 345 -350 303 -342 341 -316 351 -332 323 -352 315 -334 311 -346 315 -350 303 -356 317 -350 301 -346 343 -350 303 -342 341 -318 349 -302 353 -352 313 -334 311 -346 1325 -350 655 -344 317 -662 333 -652 323 -680 317 -672 671 -334 317 -688 649 -350 301 -672 347 -656 347 -654 643 -352 313 -690 317 -654 323 -702 649 -346 317 -660 335 -652 323 -686 655 -338 351 -654 321 -676 647 -346 639 -356 635 -362 311 -676 323 -680 309 -688 317 -688 647 -352 313 -660 643 -354 325 -684 289 -688 343 -656 645 -354 323 -686 289 -682 317 -672 671 -336 975 -364 317 -350 303 -342 341 -352 317 -332 323 -352 315 -334 313 -344 315 -350 333 -326 351 -316 303 -346 345 -350 301 -344 341 -352 315 -302 353 -352 315 -334 313 -344 315 -350 333 -326 353 -314 303 -344 345 -350 315 -334 327 -352 313 -334 315 -346 349 -304 343 -342 315 -350 301 -356 315 -350 303 -344 345 -350 315 -334 325 -352 315 -334 315 -344 351 -302 343 -340 317 -352 299 -356 315 -350 303 -346 345 -350 313 -334 325 -352 1291 -346 655 -348 349 -658 309 -688 319 -658 343 -656 677 -320 327 -686 645 -350 313 -690 315 -652 323 -704 649 -346 317 -662 335 -652 323 -682 655 -338 319 -688 321 -676 295 -708 627 -364 317 -688 289 -704 651 -346 653 -322 659 -332 343 -670 317 -682 311 -688 317 -688 649 -352 315 -658 643 -356 323 -676 321 -662 343 -656 677 -322 325 -686 319 -658 343 -658 651 -354 987 -322 331 -354 313 -336 317 -382 313 -334 313 -342 315 -352 301 -358 315 -350 303 -344 347 -350 301 -344 341 -316 351 -332 323 -352 315 -336 311 -346 313 -352 301 -356 353 -314 305 -344 345 -350 315 -334 325 -354 313 -336 313 -346 349 +RAW_Data: -316 301 -358 351 -316 333 -314 347 -350 301 -344 341 -316 349 -334 323 -352 315 -334 311 -344 349 -302 343 -342 315 -352 299 -354 315 -350 301 -346 343 -350 315 -334 327 -350 315 -336 313 -344 1311 -352 657 -338 351 -664 295 -684 323 -680 309 -688 645 -324 351 -650 677 -352 315 -658 347 -654 321 -662 651 -376 317 -662 333 -650 325 -678 641 -376 317 -662 331 -650 323 -680 639 -376 319 -660 333 -650 677 -352 629 -328 677 -326 317 -680 323 -680 315 -672 313 -702 639 -362 315 -652 681 -352 313 -660 315 -666 327 -682 647 -348 315 -690 309 -676 321 -664 685 -344 971 -336 317 -350 303 -344 345 -350 315 -334 325 -354 313 -336 313 -346 349 -316 333 -326 351 -316 303 -346 345 -350 301 -344 341 -352 315 -302 353 -352 313 -334 311 -346 315 -350 301 -358 351 -316 333 -314 347 -350 301 -344 339 -354 315 -300 355 -352 313 -334 313 -344 351 -316 301 -356 351 -316 301 -346 345 -350 315 -334 327 -352 313 -334 315 -346 349 -316 333 -326 351 -316 333 -314 347 -350 301 -342 343 -350 315 -334 323 -352 1293 -346 657 -348 317 -660 339 -654 321 -686 343 -654 651 -324 353 -650 677 -352 315 -658 345 -652 321 -664 653 -376 317 -662 331 -652 323 -682 657 -336 317 -666 327 -678 323 -682 655 -336 317 -688 321 -674 647 -348 637 -356 637 -330 343 -676 325 -676 315 -672 313 -702 641 -322 331 -688 643 -352 313 -690 315 -654 321 -702 649 -346 317 -662 333 -652 323 -682 655 -338 973 -364 317 -350 301 -342 343 -352 315 -332 323 -352 315 -336 311 -344 313 -352 333 -326 351 -316 301 -346 345 -350 301 -344 343 -350 315 -302 353 -352 313 -334 313 -346 315 -350 333 -326 351 -316 331 -318 345 -350 315 -334 325 -354 313 -336 313 -344 349 -304 341 -342 315 -350 301 -356 315 -350 303 -344 347 -350 315 -334 325 -352 315 -332 315 -346 349 -304 343 -340 317 -352 299 -356 317 -350 301 -344 345 -350 315 -336 325 -352 1289 -346 655 -348 315 -692 309 -688 319 -658 343 -656 677 -322 325 -686 643 -352 313 -658 347 -654 321 -668 683 -344 317 -660 335 -652 323 -680 671 -344 319 -660 333 -650 325 -680 671 -344 319 -660 333 -650 677 -352 629 -328 677 -324 317 -680 323 -680 317 -672 313 -702 643 -322 331 -686 643 -352 313 -690 315 -654 323 -702 649 -346 317 -660 335 -652 323 -684 657 -336 973 -364 317 -350 301 -346 341 -352 315 -334 323 -352 315 -334 313 -344 313 -352 301 -356 353 -314 301 -346 345 -350 301 -344 341 -318 349 +RAW_Data: -302 353 -352 315 -334 311 -346 315 -350 303 -356 351 -314 333 -316 345 -350 315 -334 325 -354 313 -336 313 -344 315 -350 333 -326 353 -314 305 -344 345 -350 301 -342 343 -352 315 -302 353 -352 313 -334 313 -346 315 -350 301 -358 351 -314 333 -314 347 -350 301 -342 343 -350 315 -332 325 -352 1317 -316 659 -338 353 -662 299 -682 325 -680 311 -690 645 -326 315 -682 677 -318 349 -656 343 -654 321 -660 653 -374 319 -662 329 -652 323 -678 639 -376 319 -662 331 -650 323 -680 639 -376 319 -660 331 -652 679 -318 665 -326 679 -326 313 -674 319 -682 317 -670 347 -670 639 -328 347 -654 679 -350 315 -656 317 -688 321 -676 647 -346 317 -658 337 -652 323 -682 671 -346 969 -338 353 -314 303 -344 345 -350 315 -336 325 -352 313 -336 313 -344 315 -350 333 -326 351 -316 303 -346 343 -350 317 -334 325 -352 315 -334 313 -344 315 -350 333 -326 317 -350 305 -344 343 -350 317 -334 325 -350 315 -336 311 -346 349 -304 341 -342 315 -352 299 -354 317 -350 301 -344 345 -352 315 -334 323 -352 315 -334 311 -346 313 -352 301 -358 315 -352 303 -344 345 -350 315 -334 325 -352 315 -336 313 -344 315 -350 301 -358 1309 -350 665 -326 345 -670 321 -674 295 -702 315 -670 639 -362 315 -654 681 -352 313 -658 317 -688 321 -676 647 -346 315 -662 337 -654 323 -682 653 -338 353 -654 321 -676 295 -704 639 -340 351 -656 321 -676 647 -346 639 -352 639 -330 345 -670 319 -680 315 -670 315 -700 639 -328 347 -652 681 -352 313 -658 315 -666 329 -680 647 -348 315 -690 309 -688 289 -686 653 -374 949 -364 315 -350 303 -344 343 -352 315 -332 323 -352 313 -334 313 -344 315 -350 333 -326 317 -350 301 -346 345 -350 315 -332 327 -352 315 -334 313 -346 349 -316 301 -360 315 -350 303 -344 345 -350 303 -342 341 -318 349 -300 355 -350 313 -334 313 -346 313 -352 301 -356 351 -316 301 -346 345 -350 301 -344 341 -316 351 -300 353 -352 313 -334 313 -346 313 -352 301 -356 315 -350 303 -344 345 -350 315 -332 325 -352 313 -334 313 -346 1311 -346 671 -352 315 -656 345 -654 321 -662 341 -658 651 -354 323 -684 645 -352 313 -658 345 -654 321 -662 653 -376 319 -662 333 -650 325 -680 657 -334 317 -688 291 -704 295 -702 639 -338 351 -654 321 -676 649 -346 637 -356 635 -362 311 -676 325 -676 317 -670 313 -690 641 -344 301 -690 653 -340 351 -654 323 -678 293 -704 639 -338 353 -662 295 -684 323 -680 657 -336 977 -330 349 -354 317 -302 355 -352 315 +RAW_Data: -304 341 -346 349 -318 333 -326 317 -350 303 -344 343 -354 315 -302 355 -352 315 -336 311 -344 317 -352 301 -356 351 -316 303 -344 343 -352 317 -302 353 -352 315 -336 311 -346 315 -352 301 -356 351 -316 303 -344 345 -352 315 -334 325 -352 315 -304 343 -344 317 -350 303 -356 353 -314 303 -344 345 -352 315 -334 325 -354 313 -304 343 -346 349 -316 333 -326 351 -316 303 -344 345 -350 315 -334 1319 -338 679 -322 321 -680 319 -658 345 -656 351 -630 657 -348 333 -674 641 -342 355 -660 331 -652 323 -682 655 -336 317 -658 353 -674 295 -670 665 -362 317 -656 321 -668 343 -658 677 -320 329 -678 319 -664 685 -310 689 -322 657 -332 309 -698 317 -678 311 -688 319 -668 667 -344 297 -682 653 -338 355 -630 329 -684 323 -676 639 -340 355 -662 331 -650 325 -678 671 -310 1007 -334 319 -350 303 -344 343 -352 317 -334 323 -352 315 -304 343 -346 315 -352 333 -326 351 -316 303 -344 343 -352 315 -334 327 -350 317 -334 313 -344 351 -318 333 -326 351 -316 303 -344 345 -350 315 -334 325 -354 315 -334 313 -344 349 -320 301 -356 351 -316 303 -344 343 -350 317 -332 325 -352 315 -336 311 -346 317 -350 333 -326 353 -314 305 -342 345 -352 315 -334 323 -354 313 -336 311 -346 315 -352 301 -358 351 -314 305 -342 1337 -348 655 -322 329 -688 319 -658 343 -656 353 -654 649 -350 301 -670 663 -328 347 -670 321 -678 293 -702 637 -340 353 -662 329 -648 325 -678 671 -344 319 -662 331 -652 323 -682 655 -338 351 -630 327 -682 647 -350 655 -322 663 -344 333 -662 343 -656 317 -690 321 -676 645 -348 317 -662 669 -346 299 -684 343 -654 317 -688 647 -314 343 -662 343 -656 353 -656 649 -346 999 -326 311 -346 349 -304 341 -342 317 -352 299 -354 317 -350 303 -344 343 -352 317 -334 323 -352 317 -304 343 -344 317 -352 301 -354 317 -352 303 -342 345 -350 301 -344 339 -318 351 -300 353 -352 315 -304 341 -346 317 -350 301 -356 317 -350 303 -344 343 -352 317 -332 323 -354 315 -334 313 -344 317 -352 301 -356 317 -352 303 -344 343 -352 315 -334 323 -352 315 -336 311 -346 315 -352 301 -356 351 -316 303 -344 345 -350 319 -302 1343 -338 645 -352 323 -688 287 -688 345 -658 317 -666 655 -348 333 -674 659 -334 317 -656 321 -700 295 -670 665 -328 349 -654 323 -664 329 -670 669 -338 319 -666 327 -682 323 -678 637 -342 353 -662 329 -652 679 -318 667 -324 675 -318 349 -646 323 -682 317 -670 345 -670 635 -364 317 -656 681 -316 351 -656 317 +RAW_Data: -690 319 -676 649 -346 317 -660 337 -646 323 -684 653 -342 1009 -332 317 -346 311 -330 343 -316 351 -352 315 -304 345 -344 317 -350 301 -354 353 -316 303 -344 343 -352 317 -302 355 -352 315 -304 343 -344 317 -352 301 -354 353 -316 303 -344 345 -352 315 -302 355 -352 315 -304 343 -344 317 -350 303 -356 317 -350 303 -344 345 -352 315 -302 353 -354 313 -304 343 -346 315 -352 301 -354 317 -350 305 -342 345 -352 315 -302 355 -352 315 -336 311 -346 349 -316 301 -358 353 -314 303 -344 343 -352 1311 -320 679 -346 297 -680 317 -670 345 -670 309 -670 675 -322 327 -686 643 -352 315 -656 349 -654 321 -666 683 -344 319 -660 331 -654 323 -678 671 -310 353 -662 331 -652 323 -678 671 -310 353 -662 331 -650 681 -318 665 -326 675 -326 313 -680 323 -682 309 -688 317 -656 681 -316 349 -660 645 -354 323 -650 323 -682 317 -672 671 -336 319 -664 327 -680 325 -676 637 -344 1005 -334 319 -350 303 -344 343 -318 351 -302 353 -352 315 -304 343 -344 317 -352 301 -354 317 -352 303 -344 343 -350 317 -334 325 -352 315 -304 343 -346 315 -352 301 -356 351 -316 303 -344 345 -350 315 -334 325 -354 315 -334 313 -344 349 -304 341 -342 317 -352 299 -352 317 -350 303 -344 343 -352 315 -334 323 -352 315 -304 343 -344 317 -350 303 -354 317 -352 303 -344 343 -350 315 -334 325 -354 313 -336 311 -346 349 -316 301 -358 1339 -318 655 -354 305 -690 319 -658 343 -658 351 -656 651 -350 301 -670 669 -338 317 -690 319 -674 295 -672 669 -338 353 -654 321 -678 293 -702 637 -340 355 -654 321 -676 325 -676 651 -324 345 -654 321 -664 685 -344 643 -322 661 -344 331 -662 343 -656 317 -690 321 -674 649 -348 317 -662 665 -346 299 -684 345 -654 315 -656 683 -352 315 -658 317 -664 327 -682 647 -348 987 -336 353 -316 303 -344 343 -350 317 -334 325 -352 313 -336 311 -346 349 -316 333 -326 351 -316 303 -344 345 -350 315 -336 325 -354 313 -336 311 -346 315 -352 301 -356 351 -316 303 -344 345 -350 315 -334 325 -352 315 -336 311 -346 349 -316 333 -326 353 -316 303 -344 343 -352 317 -332 325 -352 313 -336 313 -344 317 -350 303 -358 351 -316 303 -344 343 -352 315 -334 325 -352 315 -334 313 -344 349 -318 333 -326 351 -316 303 -344 1337 -348 639 -354 339 -654 321 -660 317 -704 315 -670 669 -332 317 -654 681 -350 315 -658 351 -656 321 -674 649 -348 317 -662 337 -654 323 -682 655 -338 353 -662 297 -680 325 -680 657 -336 317 -690 319 -674 647 +RAW_Data: -346 639 -354 639 -330 341 -676 323 -676 315 -672 313 -700 639 -328 347 -668 651 -348 301 -702 315 -670 313 -668 675 -320 331 -686 321 -658 343 -658 677 -320 985 -322 371 -318 313 -336 349 -318 349 -304 341 -344 317 -352 301 -354 317 -350 303 -344 345 -350 315 -334 327 -352 315 -334 313 -344 317 -352 301 -354 351 -316 303 -346 343 -350 315 -336 325 -352 315 -334 313 -346 349 -316 333 -328 351 -314 305 -342 345 -350 315 -334 327 -352 315 -334 313 -344 349 -304 341 -342 317 -350 301 -354 315 -352 303 -344 343 -352 317 -332 323 -352 315 -334 313 -344 349 -318 331 -326 351 -316 303 -344 1333 -350 653 -322 333 -686 321 -658 343 -658 351 -654 651 -350 301 -670 669 -336 319 -688 321 -674 293 -702 639 -338 353 -656 321 -674 295 -704 637 -340 353 -662 295 -684 323 -678 639 -342 353 -662 331 -652 645 -350 667 -324 675 -326 313 -676 323 -678 317 -670 313 -700 639 -330 347 -654 679 -318 349 -656 317 -690 319 -676 647 -348 317 -660 337 -652 323 -684 653 -338 983 -364 317 -350 301 -344 341 -316 351 -302 353 -352 315 -334 313 -344 317 -350 303 -356 351 -316 303 -344 343 -352 315 -334 325 -354 313 -336 313 -344 349 -318 333 -326 351 -316 303 -344 345 -350 301 -344 341 -318 349 -302 353 -350 315 -304 343 -346 315 -352 301 -356 351 -316 303 -344 343 -350 317 -334 325 -352 315 -336 311 -346 349 -302 341 -344 315 -352 299 -356 315 -350 303 -344 343 -350 317 -334 325 -352 315 -336 311 -346 1329 -350 655 -346 319 -660 333 -650 323 -684 343 -658 647 -324 351 -650 677 -352 315 -656 345 -654 321 -664 653 -342 355 -662 333 -650 325 -680 657 -336 317 -692 319 -676 293 -702 639 -338 353 -662 329 -652 645 -352 667 -326 675 -324 315 -678 325 -678 315 -670 313 -702 639 -328 347 -654 679 -352 315 -660 315 -690 323 -676 647 -346 317 -660 337 -678 317 -658 651 -344 1001 -348 309 -346 325 -348 311 -344 341 -310 313 -356 349 -312 313 -370 317 -352 299 -352 315 -350 303 -344 343 -352 315 -334 323 -352 315 -334 313 -344 349 -304 341 -342 315 -352 301 -354 317 -350 303 -344 343 -352 317 -334 323 -352 313 -336 311 -346 313 -352 333 -326 351 -316 303 -346 343 -350 303 -342 343 -318 349 -302 353 -350 315 -336 311 -346 315 -352 301 -356 351 -314 335 -314 347 -350 315 -334 97 -16804 99 -30844 99 -5628 511 -370 283 -718 287 -712 275 -722 275 -716 615 -382 277 -690 645 -358 289 -714 289 -688 341 -656 649 -354 323 +RAW_Data: -682 289 -682 317 -672 671 -336 317 -688 321 -674 295 -704 639 -338 353 -660 297 -684 647 -350 667 -326 677 -326 313 -676 323 -680 317 -672 313 -704 641 -322 333 -686 645 -350 313 -690 315 -654 323 -704 649 -344 317 -660 335 -654 323 -682 671 -344 971 -338 317 -350 301 -346 345 -350 301 -344 339 -350 315 -334 323 -352 313 -334 313 -346 349 -302 343 -342 315 -352 301 -354 317 -350 301 -346 343 -350 315 -334 327 -352 315 -334 313 -344 351 -302 343 -340 317 -350 301 -354 317 -350 301 -346 343 -350 315 -334 325 -352 315 -334 313 -346 313 -352 333 -326 351 -316 303 -344 345 -350 303 -344 341 -318 349 -302 353 -352 313 -334 313 -346 313 -352 301 -358 351 -314 301 -346 345 -350 1315 -324 679 -346 299 -678 317 -670 313 -702 311 -672 645 -354 325 -684 643 -352 313 -658 347 -672 321 -674 647 -346 317 -660 337 -652 323 -686 655 -340 317 -698 295 -682 325 -680 657 -334 317 -690 321 -674 647 -348 637 -356 637 -328 345 -674 325 -680 309 -688 317 -666 651 -348 303 -704 639 -340 351 -664 295 -682 323 -680 639 -378 319 -662 331 -650 323 -682 655 -336 975 -364 317 -350 301 -344 343 -352 315 -334 323 -352 313 -334 313 -344 315 -350 303 -356 351 -316 303 -346 343 -350 303 -344 341 -316 351 -302 351 -352 313 -334 315 -344 315 -350 303 -356 351 -314 333 -316 345 -350 301 -344 341 -352 315 -334 321 -352 315 -334 313 -342 315 -350 303 -356 317 -350 301 -346 345 -350 315 -334 325 -350 313 -334 315 -346 315 -350 301 -358 351 -314 333 -316 343 -352 301 -344 339 -350 315 -334 323 -352 1289 -346 655 -348 315 -692 307 -656 323 -682 317 -672 671 -338 317 -658 681 -352 315 -660 317 -690 321 -674 649 -348 319 -660 335 -654 323 -682 653 -338 353 -632 327 -684 323 -682 657 -332 319 -688 319 -676 647 -348 653 -320 663 -342 301 -688 343 -656 317 -690 321 -674 647 -346 317 -660 669 -344 301 -680 317 -670 347 -668 637 -364 317 -654 321 -666 351 -674 637 -340 985 -364 317 -352 315 -334 325 -354 313 -336 313 -344 349 -318 333 -326 351 -316 303 -344 345 -350 315 -334 325 -354 313 -336 311 -346 349 -318 333 -326 351 -316 303 -344 345 -350 317 -334 325 -354 313 -336 311 -346 351 -316 333 -326 351 -316 303 -344 343 -350 317 -334 325 -354 315 -304 343 -344 351 -318 301 -358 317 -350 303 -344 345 -352 315 -302 355 -352 315 -304 343 -346 315 -352 301 -356 351 -316 303 -344 343 -350 317 -334 1319 -336 645 -354 325 +RAW_Data: -676 319 -656 319 -672 347 -654 679 -326 315 -680 647 -350 317 -692 307 -690 289 -686 655 -340 353 -656 321 -676 295 -702 637 -340 353 -662 297 -684 323 -678 637 -342 353 -660 331 -652 647 -350 669 -324 675 -326 313 -678 325 -678 315 -670 313 -702 641 -322 333 -688 645 -352 313 -688 317 -656 321 -668 685 -346 319 -660 333 -652 323 -684 655 -336 977 -364 317 -350 303 -342 341 -318 349 -302 351 -352 315 -304 343 -346 351 -316 301 -356 351 -316 303 -344 343 -350 303 -342 341 -318 349 -302 353 -354 313 -306 341 -346 315 -352 301 -356 351 -316 303 -344 345 -350 315 -334 325 -352 315 -336 311 -344 317 -352 301 -356 353 -314 335 -314 345 -350 315 -334 327 -352 315 -334 313 -344 349 -304 341 -342 317 -350 301 -354 315 -352 303 -342 345 -352 315 -334 323 -352 315 -334 313 -344 1313 -350 659 -336 319 -690 321 -674 295 -672 347 -654 679 -324 315 -676 673 -352 313 -658 345 -640 321 -702 649 -346 317 -660 335 -646 321 -686 653 -340 353 -656 321 -676 295 -702 637 -340 353 -662 297 -684 645 -350 665 -324 675 -326 313 -680 323 -676 317 -670 313 -700 639 -328 349 -656 679 -316 351 -656 315 -690 319 -674 647 -346 317 -660 337 -654 323 -686 653 -338 975 -364 317 -350 303 -342 341 -318 349 -302 353 -352 315 -304 343 -342 317 -352 301 -356 349 -316 303 -344 345 -352 315 -334 323 -352 315 -334 313 -344 315 -352 301 -356 317 -350 303 -344 345 -350 315 -334 323 -352 315 -336 313 -344 317 -350 303 -354 317 -352 303 -344 343 -350 315 -334 325 -352 313 -336 311 -346 315 -350 303 -356 353 -314 335 -314 345 -352 315 -302 355 -352 315 -304 343 -344 317 -350 303 -356 317 -352 303 -344 1337 -346 653 -322 327 -688 289 -688 333 -668 315 -692 639 -344 301 -688 655 -340 349 -636 339 -654 323 -682 671 -346 317 -662 333 -654 323 -678 671 -346 317 -660 333 -654 323 -680 639 -376 319 -660 333 -650 679 -318 665 -326 677 -326 315 -680 323 -678 315 -672 343 -672 635 -362 317 -654 679 -352 315 -658 317 -688 321 -676 647 -346 317 -658 337 -654 323 -682 671 -346 969 -338 353 -316 303 -344 345 -350 315 -334 325 -352 315 -334 313 -344 349 -304 341 -342 317 -350 301 -356 315 -350 303 -344 343 -350 317 -334 323 -352 315 -336 311 -344 351 -316 301 -358 351 -316 303 -344 345 -350 315 -334 325 -352 315 -336 313 -344 349 -318 333 -326 351 -316 303 -344 345 -350 315 -334 327 -350 315 -336 311 -346 349 -302 343 -342 317 +RAW_Data: -350 301 -354 351 -314 305 -342 345 -352 315 -334 323 -352 315 -336 311 -344 1325 -350 655 -346 317 -660 335 -654 323 -680 315 -672 669 -336 317 -690 649 -350 301 -668 347 -670 311 -670 677 -320 327 -686 289 -688 343 -656 643 -354 327 -686 287 -690 343 -656 649 -324 353 -650 321 -682 671 -346 641 -322 663 -330 343 -676 325 -674 315 -670 313 -670 685 -320 327 -686 643 -352 315 -656 347 -672 319 -676 647 -346 317 -658 337 -654 323 -682 671 -346 971 -338 351 -316 303 -344 345 -352 315 -334 325 -352 315 -334 313 -344 349 -304 341 -342 317 -350 301 -352 317 -352 303 -344 343 -350 315 -334 323 -352 315 -336 311 -346 317 -350 303 -356 351 -316 303 -344 345 -350 301 -342 343 -316 351 -300 353 -352 315 -304 343 -344 315 -352 333 -326 351 -316 303 -344 343 -350 315 -336 325 -352 313 -336 313 -344 349 -304 341 -342 317 -350 301 -354 315 -350 303 -344 343 -350 315 -334 327 -352 1289 -346 655 -348 317 -692 309 -688 289 -686 343 -656 643 -356 323 -686 645 -352 313 -658 347 -638 321 -706 647 -346 319 -660 333 -652 323 -682 671 -344 319 -660 331 -652 323 -678 639 -378 317 -662 331 -652 647 -350 665 -326 677 -326 315 -678 323 -678 315 -672 313 -702 641 -324 331 -688 645 -352 315 -656 347 -670 321 -676 647 -348 317 -660 337 -652 323 -682 671 -346 971 -338 353 -316 303 -344 343 -350 317 -334 325 -352 315 -334 313 -344 349 -316 333 -326 353 -314 335 -314 345 -350 315 -334 327 -352 315 -334 313 -344 349 -318 301 -358 315 -352 303 -344 343 -350 315 -334 325 -354 313 -336 313 -344 349 -304 341 -342 315 -352 299 -354 315 -352 303 -344 343 -350 317 -334 325 -352 315 -304 343 -344 317 -350 303 -356 315 -350 305 -344 345 -350 315 -334 323 -352 315 -336 311 -346 349 -316 333 -326 1335 -352 629 -328 345 -654 323 -666 343 -656 351 -662 661 -346 297 -678 671 -310 353 -662 331 -650 323 -678 639 -342 353 -662 329 -650 325 -678 639 -376 319 -662 329 -650 323 -680 639 -378 319 -660 331 -652 645 -350 667 -326 679 -326 313 -674 325 -678 315 -670 313 -702 653 -320 329 -686 643 -352 315 -660 347 -672 287 -706 647 -346 317 -662 333 -654 323 -684 655 -336 977 -362 317 -350 301 -344 341 -316 351 -300 353 -352 313 -306 341 -344 315 -352 301 -356 317 -350 303 -344 343 -352 315 -334 325 -352 315 -336 313 -344 317 -350 303 -354 317 -350 303 -344 345 -350 315 -334 323 -352 315 -336 311 -344 351 -316 301 -358 315 +RAW_Data: -352 303 -346 343 -352 317 -334 323 -352 313 -336 311 -346 317 -350 301 -356 351 -316 303 -344 345 -350 315 -334 325 -352 315 -334 313 -344 317 -352 301 -358 315 -352 303 -344 1339 -346 639 -322 333 -690 319 -660 341 -658 351 -662 627 -346 333 -674 673 -310 353 -662 297 -684 323 -682 657 -336 317 -688 319 -674 295 -672 685 -324 343 -652 321 -664 343 -656 677 -322 325 -686 287 -690 653 -340 675 -320 655 -350 313 -676 325 -680 311 -656 349 -654 679 -316 349 -658 643 -356 321 -652 323 -684 345 -656 643 -356 321 -652 323 -682 317 -672 671 -336 975 -362 317 -350 315 -334 325 -352 315 -336 311 -346 313 -352 301 -356 317 -350 303 -344 345 -350 315 -334 323 -352 315 -334 311 -346 313 -352 301 -356 351 -316 303 -346 345 -352 315 -302 353 -352 315 -336 311 -346 315 -352 301 -356 315 -352 303 -344 343 -352 317 -332 323 -352 315 -306 343 -342 317 -350 301 -356 315 -352 303 -344 343 -350 317 -334 325 -352 313 -304 341 -346 313 -352 301 -356 351 -316 303 -344 343 -352 315 -334 1315 -336 645 -354 325 -684 289 -686 345 -656 315 -690 645 -350 301 -668 671 -336 353 -630 327 -682 323 -676 639 -340 353 -662 331 -650 323 -680 639 -342 353 -664 297 -684 323 -682 657 -332 317 -688 291 -704 649 -346 655 -320 659 -346 301 -688 343 -656 315 -656 323 -704 649 -348 317 -660 667 -344 297 -682 315 -674 349 -656 641 -332 343 -676 325 -674 315 -672 669 -332 973 -362 315 -350 317 -334 325 -352 313 -336 313 -344 349 -304 341 -342 315 -352 299 -354 317 -350 303 -344 343 -352 317 -334 323 -352 315 -304 343 -344 317 -352 301 -356 315 -350 303 -346 343 -350 317 -332 323 -352 315 -336 311 -346 349 -316 333 -326 351 -316 303 -344 345 -350 315 -334 325 -352 315 -334 313 -346 313 -352 301 -358 351 -316 303 -344 345 -350 315 -334 325 -352 315 -336 311 -346 315 -352 301 -356 317 -350 303 -344 1333 -348 639 -354 339 -640 323 -664 343 -660 351 -662 661 -310 333 -676 673 -310 353 -662 331 -650 325 -682 657 -334 317 -666 327 -676 317 -678 671 -346 319 -660 331 -652 325 -678 671 -310 355 -660 331 -652 679 -318 667 -326 673 -326 313 -676 319 -680 317 -672 343 -670 637 -362 317 -658 679 -318 349 -658 317 -658 351 -642 685 -346 319 -660 333 -654 323 -680 655 -338 977 -362 319 -352 315 -334 325 -352 315 -304 341 -346 351 -318 303 -356 351 -316 303 -344 345 -352 317 -302 353 -354 315 -304 341 -346 315 -354 301 -354 351 +RAW_Data: -316 303 -344 343 -350 319 -302 355 -352 315 -304 341 -346 351 -318 303 -354 353 -316 303 -342 345 -352 315 -302 355 -354 313 -304 343 -344 351 -318 333 -326 353 -318 303 -342 343 -352 317 -302 355 -352 315 -304 341 -346 351 -318 301 -356 351 -316 303 -344 345 -352 317 -302 1343 -338 645 -354 323 -686 319 -656 343 -656 353 -654 649 -352 317 -658 679 -320 325 -678 319 -660 343 -658 679 -322 323 -654 351 -656 343 -658 647 -324 351 -652 323 -680 317 -670 667 -336 355 -632 327 -682 645 -350 669 -322 677 -296 341 -680 323 -674 315 -670 343 -636 669 -328 351 -668 649 -350 301 -668 345 -668 311 -668 679 -320 327 -656 353 -656 343 -658 679 -290 1015 -322 367 -322 317 -336 311 -350 351 -304 341 -342 319 -354 299 -348 319 -352 303 -342 343 -318 353 -304 349 -318 351 -32700 99 -8980 101 -14522 97 -32700 99 -22564 diff --git a/assets/unit_tests/subghz/nice_flo.sub b/assets/unit_tests/subghz/nice_flo.sub new file mode 100644 index 00000000000..994c4259cff --- /dev/null +++ b/assets/unit_tests/subghz/nice_flo.sub @@ -0,0 +1,7 @@ +Filetype: Flipper SubGhz Key File +Version: 1 +Frequency: 433920000 +Preset: FuriHalSubGhzPresetOok650Async +Protocol: Nice FLO +Bit: 24 +Key: 00 00 00 00 00 02 FE C4 diff --git a/assets/unit_tests/subghz/nice_flo_raw.sub b/assets/unit_tests/subghz/nice_flo_raw.sub new file mode 100644 index 00000000000..f91bbd8162b --- /dev/null +++ b/assets/unit_tests/subghz/nice_flo_raw.sub @@ -0,0 +1,7 @@ +Filetype: Flipper SubGhz RAW File +Version: 1 +Frequency: 433920000 +Preset: FuriHalSubGhzPresetOok650Async +Protocol: RAW +RAW_Data: 32700 -4166 259 -25228 693 -724 1407 -1390 679 -714 1395 -1418 679 -1408 709 -1404 709 -678 1413 -680 1401 -718 1403 -688 1401 -720 1389 -1412 691 -710 1401 -1400 673 -730 1373 -724 1397 -1394 711 -1378 711 -1408 707 -678 1395 -710 1391 -1406 703 -710 1395 -712 1401 -25172 443 -12300 491 -932 1179 -834 1279 -800 1343 -766 1343 -762 1339 -1426 675 -750 1369 -1418 679 -716 1381 -714 1399 -1412 681 -1404 713 -1404 709 -676 1393 -712 1397 -1416 681 -714 1415 -680 1395 -25196 691 -746 1357 -1440 671 -714 1391 -1406 701 -1408 697 -1408 697 -678 1415 -686 1407 -698 1427 -676 1413 -678 1409 -1410 701 -700 1403 -1392 711 -686 1427 -696 1403 -1390 687 -1408 709 -1406 707 -676 1415 -680 1405 -1414 681 -704 1403 -718 1409 -25142 727 -706 1403 -1398 709 -690 1413 -1414 677 -1406 711 -1406 673 -706 1395 -714 1395 -720 1397 -696 1405 -696 1403 -1394 709 -684 1413 -1382 711 -714 1387 -714 1383 -1406 707 -1406 675 -1406 703 -710 1397 -712 1397 -1404 675 -710 1395 -712 1395 -25186 655 -846 1233 -1548 593 -788 1299 -1520 587 -1490 615 -1474 645 -744 1357 -746 1381 -714 1373 -736 1367 -706 1399 -1432 673 -728 1377 -1418 679 -714 1415 -682 1413 -1376 713 -1408 709 -1372 705 -710 1397 -712 1381 -1410 721 -680 1409 -690 1405 -25168 701 -760 1341 -1456 639 -756 1345 -1452 677 -1410 673 -1442 671 -712 1399 -712 1371 -718 1411 -688 1409 -690 1407 -1416 679 -712 1395 -1414 685 -716 1383 -714 1383 -1410 711 -1400 709 -1370 705 -710 1397 -710 1397 -1410 679 -712 1395 -686 1427 -25156 563 -7950 557 -1546 555 -1508 621 -790 1329 -758 1331 -778 1355 -714 1377 -714 1407 -1404 669 -730 1407 -1390 709 -686 1411 -684 1397 -1416 685 -1406 711 -1404 707 -676 1427 -682 1395 -1420 679 -712 1395 -688 1429 -25160 745 -712 1359 -1438 671 -712 1399 -1408 697 -1406 695 -1404 697 -682 1403 -714 1413 -686 1393 -710 1411 -686 1407 -1402 701 -676 1431 -1368 735 -674 1399 -704 1397 -1400 711 -1414 683 -1408 709 -678 1421 -678 1427 -1374 711 -710 1395 -686 1431 -25158 713 -708 1391 -1406 703 -712 1397 -1408 707 -1372 707 -1406 699 -712 1379 -716 1405 -688 1403 -720 1387 -684 1409 -1402 705 -712 1399 -1408 673 -722 1403 -694 1397 -1390 709 -1414 681 -1404 709 -680 1421 -680 1415 -1406 697 -714 1369 -718 1413 -25180 709 -688 1403 -1424 673 -696 1429 -1398 679 -1404 717 -1376 719 -700 1411 -696 1377 -724 1397 -700 1405 -698 1407 -1390 685 -716 1383 -1412 709 -714 1385 -712 1387 -1406 709 -1402 673 -1406 703 -710 1403 -680 1403 -1412 685 -718 1407 -692 1399 -25178 727 -686 1401 -1400 709 -686 1429 -1388 709 -1408 679 -1406 711 -678 1421 -680 1423 -680 1423 -676 1423 -678 1395 -1406 +RAW_Data: 711 -716 1387 -1408 675 -710 1397 -710 1395 -1404 703 -1404 699 -1408 697 -712 1371 -716 1405 -1386 715 -684 1399 -718 1381 -25206 689 -716 1411 -1414 681 -716 1389 -1406 709 -1372 703 -1408 699 -712 1383 -718 1407 -686 1391 -688 1409 -716 1401 -1406 689 -688 1411 -1384 715 -716 1381 -712 1395 -1414 685 -1408 711 -1372 707 -708 1395 -710 1397 -1402 699 -710 1395 -708 1393 -25166 715 -712 1399 -1420 681 -714 1381 -1404 711 -1404 707 -1404 675 -712 1397 -710 1395 -710 1395 -684 1397 -724 1401 -1392 709 -686 1407 -1414 683 -710 1397 -690 1413 -1382 711 -1410 709 -1372 703 -712 1413 -680 1403 -1412 687 -718 1375 -728 1399 -32700 97 -132 327 -924 291 -98 625 diff --git a/assets/unit_tests/subghz/nice_flor_s_raw.sub b/assets/unit_tests/subghz/nice_flor_s_raw.sub new file mode 100644 index 00000000000..cc9c249aa69 --- /dev/null +++ b/assets/unit_tests/subghz/nice_flor_s_raw.sub @@ -0,0 +1,9 @@ +Filetype: Flipper SubGhz RAW File +Version: 1 +Frequency: 433920000 +Preset: FuriHalSubGhzPresetOok650Async +Protocol: RAW +RAW_Data: 1938 -32700 1599 -1476 515 -1044 507 -1050 487 -1052 1007 -572 1009 -556 999 -548 1025 -546 1019 -510 517 -1044 513 -1042 1007 -514 507 -1074 1013 -546 515 -1046 515 -1044 513 -1040 513 -1040 1005 -514 1035 -516 509 -1072 513 -1040 513 -1042 1007 -576 1009 -512 1011 -546 1009 -548 1005 -516 1005 -586 1009 -546 1009 -544 515 -1042 513 -1042 511 -1044 513 -1010 511 -1042 515 -1076 475 -1074 511 -1040 1009 -548 1007 -546 513 -1040 511 -1038 475 -1040 507 -1074 513 -1042 1011 -578 981 -546 1009 -544 515 -1042 1007 -546 475 -1038 509 -1040 1497 -19024 1543 -1508 503 -1034 509 -1038 509 -1038 1003 -584 1005 -574 979 -576 483 -1074 483 -1042 513 -1044 513 -1038 1005 -514 509 -1072 1009 -548 513 -1042 515 -1042 513 -1042 513 -1044 1007 -514 1037 -516 511 -1068 513 -1040 513 -1042 1009 -546 1009 -546 1007 -546 1007 -548 1005 -514 1005 -584 1007 -548 1009 -546 515 -1042 513 -1044 513 -1040 511 -1038 477 -1038 507 -1076 513 -1044 515 -1040 1009 -546 1009 -546 515 -1042 513 -1010 511 -1042 513 -1078 479 -1072 1007 -546 1007 -548 1007 -546 513 -1040 1005 -514 509 -1038 509 -1008 1529 -19028 1545 -1508 513 -1046 483 -1052 489 -1050 1009 -568 1007 -558 995 -548 527 -1052 1015 -512 515 -1044 513 -1040 1003 -506 541 -1074 983 -578 483 -1044 515 -1042 513 -1042 515 -1040 1007 -546 1005 -516 507 -1072 513 -1040 517 -1042 1009 -544 1009 -544 1011 -544 1007 -540 1009 -546 1005 -548 1011 -578 981 -576 485 -1044 515 -1042 513 -1044 513 -1010 509 -1040 507 -1074 511 -1042 513 -1042 1013 -546 1007 -542 513 -1042 515 -1038 511 -1006 507 -1076 515 -1042 1011 -578 977 -574 1013 -544 481 -1044 1007 -546 511 -1008 511 -1042 1505 -19032 1541 -1488 507 -1074 479 -1044 513 -1046 975 -590 1011 -574 483 -1052 1007 -556 499 -1050 489 -1042 517 -1044 1005 -516 509 -1074 1011 -546 517 -1042 515 -1044 513 -1042 513 -1042 1009 -516 1009 -550 477 -1108 477 -1074 513 -1040 1009 -548 1009 -546 1009 -550 975 -548 1003 -554 999 -574 1009 -548 1009 -548 513 -1040 513 -1044 513 -1042 479 -1040 509 -1040 509 -1078 479 -1078 513 -1042 1011 -550 1007 -548 477 -1072 477 -1040 509 -1040 509 -1076 511 -1038 1011 -548 1009 -548 1009 -546 513 -1040 1009 -518 513 -1040 509 -1010 1527 -19010 1541 -1512 511 -1042 511 -1046 483 -1046 1001 -570 1013 -570 493 -1066 1001 -550 979 -564 503 -1052 485 -1048 1009 -516 509 -1076 1011 -546 517 -1044 517 -1044 515 -1044 479 -1076 971 -574 971 -550 509 -1076 481 -1076 513 -1040 1007 -544 1011 -546 1007 -548 1007 -514 1005 -550 1009 -556 1003 -584 1007 -550 479 -1076 479 -1076 479 -1042 513 -1044 483 -1044 507 -1082 507 -1068 477 -1074 +RAW_Data: 1011 -550 973 -550 509 -1044 513 -1044 483 -1048 491 -1082 519 -1048 1005 -556 993 -548 1021 -546 487 -1046 1011 -548 479 -1044 513 -1012 1513 -19026 1535 -1534 507 -1046 483 -1056 491 -1034 1007 -572 1009 -558 501 -1052 525 -1044 487 -1042 515 -1040 513 -1040 1007 -514 507 -1072 1009 -546 515 -1074 483 -1042 515 -1044 515 -1044 1011 -516 1009 -522 519 -1082 507 -1042 509 -1042 1007 -550 1011 -552 1009 -522 1037 -522 1017 -512 1003 -584 999 -582 993 -546 523 -1046 483 -1042 515 -1042 513 -1040 511 -1006 511 -1074 513 -1042 513 -1042 1013 -546 1009 -540 515 -1042 513 -1040 511 -1004 509 -1074 515 -1044 1011 -544 1009 -578 977 -544 515 -1042 1007 -546 511 -1004 509 -1038 1529 -18994 1549 -1510 513 -1044 515 -1010 505 -1044 1001 -590 1017 -556 487 -1048 505 -1054 1019 -544 485 -1046 515 -1042 1007 -516 513 -1074 1007 -548 513 -1040 515 -1042 513 -1044 513 -1042 287 -32700 1577 -1544 481 -1034 507 -1046 509 -1048 1001 -588 989 -552 1013 -566 971 -584 989 -546 487 -1044 515 -1046 479 -1040 509 -1074 513 -1044 515 -1044 517 -1042 513 -1044 513 -1040 1011 -516 509 -1048 483 -1080 1007 -556 513 -1042 1003 -552 1001 -554 1011 -524 1015 -554 985 -538 503 -1086 499 -1050 1017 -546 521 -1048 483 -1044 515 -1040 513 -1040 1005 -518 513 -1076 1007 -548 511 -1042 1005 -542 1009 -548 515 -1040 513 -1038 1005 -516 509 -1072 1009 -546 1009 -578 977 -580 977 -544 515 -1042 1005 -542 1011 -514 509 -1012 1541 -18996 1571 -1504 515 -1014 519 -1020 537 -1018 1011 -568 1011 -556 997 -546 525 -1050 519 -1008 513 -1040 513 -1038 511 -1004 539 -1040 515 -1076 517 -1008 549 -1010 515 -1040 513 -1040 1011 -514 543 -1002 539 -1040 1011 -546 547 -1008 1043 -512 1045 -510 1043 -508 1041 -510 1005 -546 507 -1072 519 -1042 1013 -542 519 -1010 517 -1040 513 -1040 511 -1040 1003 -514 539 -1038 1043 -542 519 -1044 1011 -544 1011 -510 547 -1008 513 -1040 1009 -514 509 -1072 1041 -544 1011 -542 1013 -544 1017 -510 515 -1040 1009 -544 1007 -512 541 -1004 1527 -19000 513 -4202 99 -1444 853 -672 901 -676 867 -666 407 -1158 923 -618 423 -1114 451 -1082 451 -1082 455 -1110 493 -1080 483 -1076 471 -1056 491 -1082 483 -1042 1007 -546 511 -1006 509 -1072 1009 -576 483 -1076 979 -578 977 -544 1007 -542 1007 -546 1007 -546 477 -1072 517 -1076 977 -578 483 -1042 517 -1042 513 -1044 513 -1042 975 -550 481 -1078 1039 -550 477 -1072 1005 -540 1007 -546 513 -1044 513 -1006 1005 -550 507 -1080 1007 -548 1007 -546 1007 -548 1007 -546 511 -1038 1007 -546 1005 -514 509 -1006 1531 -18994 1447 -1714 323 -1204 399 -1134 407 -1132 925 -652 925 -618 425 -1150 917 -618 +RAW_Data: 451 -1112 449 -1074 483 -1046 483 -1070 477 -1082 509 -1042 509 -1074 479 -1074 477 -1078 477 -1042 1007 -554 483 -1046 507 -1086 983 -548 517 -1064 995 -548 1019 -546 981 -544 1009 -544 1009 -514 511 -1074 513 -1076 979 -578 483 -1042 515 -1042 513 -1042 511 -1040 1005 -516 509 -1076 1009 -548 513 -1040 1007 -574 979 -546 513 -1042 515 -1038 1009 -514 507 -1074 1009 -548 1007 -546 1011 -548 1011 -546 513 -1046 1009 -516 1007 -520 507 -1042 1529 -18994 1457 -1686 321 -1212 385 -1150 389 -1142 937 -638 937 -630 437 -1088 961 -616 951 -584 451 -1112 451 -1078 449 -1078 477 -1120 449 -1110 447 -1080 481 -1072 515 -1046 483 -1046 999 -556 519 -1016 503 -1084 995 -550 527 -1048 981 -580 983 -546 1007 -546 1009 -548 1007 -516 515 -1076 477 -1072 1007 -548 513 -1042 513 -1038 515 -1040 513 -1040 975 -552 481 -32700 1607 -1490 513 -1044 513 -1046 483 -1050 1015 -554 1027 -550 1011 -532 1001 -584 989 -548 487 -1044 515 -1042 1007 -540 1005 -550 513 -1076 975 -580 483 -1044 515 -1044 1013 -548 1009 -518 513 -1048 979 -590 985 -586 475 -1076 1009 -550 991 -548 1015 -546 485 -1042 1013 -516 1009 -586 1007 -548 513 -1042 1011 -548 513 -1042 479 -1072 479 -1038 509 -1040 1005 -586 479 -1072 1009 -546 515 -1040 1009 -548 513 -1040 479 -1072 475 -1036 1009 -586 479 -1078 513 -1042 513 -1044 1011 -550 479 -1076 973 -550 511 -1042 1005 -494 1513 -19020 1555 -1504 509 -1048 507 -1052 473 -1058 1001 -578 1001 -546 1003 -574 511 -1024 527 -1048 487 -1044 513 -1044 1009 -518 1009 -590 479 -1076 1007 -550 477 -1070 513 -1040 1007 -548 1005 -514 511 -1040 1005 -588 975 -586 479 -1072 1007 -548 1007 -548 973 -550 511 -1042 1011 -526 1017 -572 1001 -538 517 -1050 1007 -558 501 -1052 487 -1048 513 -1044 479 -1044 1007 -590 475 -1074 1007 -548 513 -1040 1009 -546 513 -1040 481 -1038 511 -1042 1009 -560 511 -1074 477 -1074 477 -1074 1007 -550 477 -1070 973 -542 509 -1040 1005 -526 1511 -19024 1533 -1542 453 -1086 473 -1050 511 -1042 995 -582 993 -582 991 -548 491 -1080 983 -546 515 -1040 513 -1042 975 -554 1011 -586 487 -1048 1015 -544 513 -1030 525 -1046 981 -546 1009 -546 511 -1042 971 -584 1007 -574 485 -1076 977 -578 979 -546 1009 -548 511 -1042 1007 -516 1005 -588 1009 -550 479 -1074 1011 -548 481 -1072 479 -1072 475 -1040 509 -1044 1011 -558 509 -1074 971 -584 477 -1070 1007 -550 477 -1076 477 -1044 515 -1046 979 -590 491 -1050 519 -1044 501 -1054 1021 -548 483 -1044 1011 -548 475 -1040 1003 -520 1543 -18994 1573 -1468 515 -1052 521 -1018 523 -1008 1025 -580 997 -546 527 -1046 1015 -542 519 -1010 513 -1042 513 -1040 +RAW_Data: 1007 -514 1039 -550 511 -1040 1009 -544 513 -1046 515 -1040 1009 -546 1005 -540 511 -1006 1041 -550 1013 -546 513 -1040 1011 -546 1009 -544 1007 -544 513 -1038 1009 -512 1037 -548 1009 -546 515 -1040 1041 -512 513 -1046 515 -1040 511 -1038 511 -1006 1037 -550 511 -1040 1041 -542 485 -1042 1039 -508 515 -1042 515 -1038 511 -1004 1037 -550 515 -1040 517 -1040 517 -1040 1011 -544 515 -1040 1007 -546 509 -1008 1009 -518 1543 -18992 1535 -1542 483 -1052 487 -1050 521 -1046 991 -578 995 -546 527 -1046 1015 -546 1015 -544 483 -1042 513 -1040 1009 -514 1007 -586 511 -1040 1007 -548 513 -1042 513 -1044 1011 -546 1009 -514 511 -1038 1009 -558 1007 -552 513 -1072 1005 -548 1005 -548 1005 -514 507 -1038 1035 -506 1003 -584 1005 -574 481 -1076 1009 -544 485 -1042 513 -1040 513 -1040 511 -1004 1039 -550 513 -1040 1011 -544 515 -1042 1009 -544 515 -1042 513 -1042 479 -1042 1011 -558 511 -1076 477 -1074 513 -1038 1007 -546 511 -1040 1005 -514 507 -1040 1001 -506 diff --git a/assets/unit_tests/subghz/princeton.sub b/assets/unit_tests/subghz/princeton.sub new file mode 100644 index 00000000000..a2f80c1fe3e --- /dev/null +++ b/assets/unit_tests/subghz/princeton.sub @@ -0,0 +1,8 @@ +Filetype: Flipper SubGhz Key File +Version: 1 +Frequency: 433920000 +Preset: FuriHalSubGhzPresetOok650Async +Protocol: Princeton +Bit: 24 +Key: 00 00 00 00 00 95 D5 D4 +TE: 400 diff --git a/assets/unit_tests/subghz/princeton_raw.sub b/assets/unit_tests/subghz/princeton_raw.sub new file mode 100644 index 00000000000..8aa68fdddca --- /dev/null +++ b/assets/unit_tests/subghz/princeton_raw.sub @@ -0,0 +1,8 @@ +Filetype: Flipper SubGhz RAW File +Version: 1 +Frequency: 433920000 +Preset: FuriHalSubGhzPresetOok650Async +Protocol: RAW +RAW_Data: 1711 -32700 621 -1600 1623 -564 1639 -552 1637 -520 1701 -514 1665 -516 579 -1556 607 -1562 571 -1570 1697 -484 605 -1544 1701 -500 611 -1544 1697 -528 1675 -518 1705 -492 589 -1580 593 -1536 609 -1562 583 -1574 595 -1542 603 -1568 1699 -490 1693 -496 613 -16342 623 -1538 1693 -520 1675 -486 1721 -492 1709 -520 1701 -486 579 -1588 573 -1578 589 -1568 1695 -482 605 -1582 1703 -492 589 -1578 1675 -518 1707 -484 1703 -500 609 -1576 571 -1574 611 -1532 627 -1538 603 -1546 607 -1548 1729 -474 1719 -490 613 -16368 591 -1570 1689 -504 1699 -484 1711 -506 1715 -486 1707 -488 619 -1576 583 -1540 611 -1562 1711 -486 615 -1546 1705 -490 621 -1542 1705 -506 1713 -486 1713 -486 629 -1540 609 -1564 589 -1574 599 -1540 607 -1568 611 -1546 1707 -492 1711 -480 609 -16394 597 -1566 1701 -494 1693 -492 1705 -520 1705 -474 1727 -502 585 -1574 599 -1570 575 -1566 1699 -520 593 -1570 1703 -480 605 -1572 1705 -490 1717 -482 1735 -486 603 -1566 611 -1532 615 -1562 587 -1578 585 -1574 579 -1586 1677 -512 1705 -490 621 -16376 603 -1556 1677 -540 1667 -516 1699 -506 1717 -486 1701 -510 591 -1576 579 -1562 625 -1538 1727 -492 605 -1566 1703 -484 605 -1570 1703 -492 1713 -482 1733 -482 603 -1570 611 -1548 611 -1564 581 -1558 613 -1548 603 -1574 1701 -484 1701 -520 581 -16396 603 -1568 1693 -514 1687 -486 1711 -486 1721 -492 1707 -520 577 -1568 611 -1564 581 -1580 1679 -516 603 -1544 1707 -512 609 -1564 1707 -482 1725 -476 1717 -520 587 -1548 613 -1552 613 -1564 581 -1580 581 -1578 581 -1554 1725 -488 1703 -520 581 -16392 615 -1588 1663 -514 1705 -514 1689 -518 1713 -484 1709 -492 613 -1576 593 -1540 607 -1578 1703 -492 621 -1542 1715 -502 587 -1572 1693 -520 1713 -482 1709 -510 591 -1570 605 -1568 611 -1562 581 -1580 581 -1580 585 -1546 1741 -484 1715 -500 585 -16404 605 -1566 1765 -516 349 -32700 633 -1566 1667 -512 1659 -550 1677 -490 1695 -492 1705 -510 575 -1576 577 -1566 611 -1536 1709 -492 603 -1534 1695 -516 599 -1546 1697 -502 1679 -520 1677 -492 613 -1570 595 -1544 603 -1538 609 -1568 1701 -462 1721 -488 613 -1538 625 -1548 599 -16338 625 -1544 1697 -506 1669 -522 1681 -488 1707 -484 1701 -504 577 -1586 571 -1570 605 -1554 1677 -512 575 -1578 1671 -520 587 -1578 1675 -506 1695 -500 1679 -518 577 -1570 577 -1568 615 -1548 577 -1564 1709 -490 1679 -512 605 -1554 589 -1574 597 -16376 605 -1532 1695 -508 1691 -486 1703 -480 1693 -500 1711 -484 585 -1572 609 -1556 587 -1568 1693 -486 583 -1598 1669 -488 603 -1572 1699 -482 1689 -520 1677 -522 585 -1576 585 -1542 609 -1560 587 -1570 1691 -518 1675 -490 605 -1568 577 -1562 591 -16398 615 -1568 1663 -518 +RAW_Data: 1673 -492 1709 -480 1693 -512 1689 -504 579 -1592 589 -1542 587 -1578 1699 -484 605 -1544 1701 -518 577 -1568 1699 -484 1677 -520 1675 -518 579 -1598 563 -1576 603 -1568 575 -1566 1703 -492 1707 -480 611 -1556 587 -1572 601 -16374 619 -1566 1667 -516 1675 -524 1675 -516 1667 -514 1691 -506 581 -1580 583 -1560 579 -1588 1679 -512 573 -1580 1677 -520 579 -1572 1705 -494 1681 -514 1703 -478 593 -1576 603 -1574 575 -1576 577 -1568 1703 -492 1691 -492 613 -1570 597 -1542 607 -16402 563 -1620 1597 -592 1605 -586 1609 -606 1619 -544 1631 -588 515 -1620 559 -1600 569 -1564 1671 -526 585 -1580 1675 -518 579 -1564 1711 -486 1709 -494 1695 -514 575 -1562 589 -1576 603 -1544 607 -1566 1703 -494 1691 -490 611 -1572 595 -1544 603 -16400 615 -1536 1707 -494 1679 -514 1673 -510 1715 -486 1707 -494 587 -1582 587 -1574 579 -1546 1705 -522 577 -1580 1699 -494 603 -1534 1729 -482 1693 -502 1699 -510 577 -1586 587 -1570 601 -1544 609 -1578 1703 -492 1711 -480 609 -1560 591 -1576 603 -16408 581 -1588 1701 -516 1703 -514 1689 -32700 641 -1534 1703 -492 1693 -486 1673 -516 1689 -504 1669 -520 587 -1572 573 -1548 611 -1538 1715 -486 581 -1576 1663 -520 587 -1560 1699 -484 1703 -488 1699 -518 575 -1576 575 -1570 1663 -520 1677 -522 587 -1576 585 -1540 609 -1556 587 -1574 563 -16370 595 -1568 1689 -506 1669 -490 1677 -512 1699 -510 1681 -508 581 -1560 585 -1580 583 -1560 1665 -516 607 -1538 1703 -486 607 -1576 1663 -504 1703 -482 1695 -500 587 -1574 599 -1544 1697 -518 1671 -490 587 -1578 589 -1572 577 -1564 589 -1574 599 -16376 571 -1566 1693 -518 1673 -518 1649 -520 1679 -516 1665 -514 567 -1574 605 -1544 609 -1570 1669 -518 581 -1562 1669 -518 587 -1574 1667 -516 1691 -518 1671 -490 601 -1568 573 -1584 1673 -518 1673 -518 579 -1558 611 -1550 587 -1580 585 -1572 579 -16380 617 -1566 1649 -542 1669 -490 1679 -512 1703 -510 1655 -518 579 -1564 615 -1562 587 -1562 1677 -520 587 -1574 1667 -506 589 -1568 1691 -520 1679 -492 1675 -514 611 -1554 589 -1572 1687 -506 1675 -520 585 -1574 579 -1578 585 -1568 601 -1540 605 -16408 585 -1564 1663 -530 1663 -518 1667 -514 1689 -504 1699 -482 605 -1582 581 -1570 563 -1574 1693 -504 577 -1588 1659 -518 579 -1598 1655 -518 1707 -482 1701 -480 605 -1582 583 -1572 1687 -518 1671 -490 587 -1574 605 -1582 581 -1570 561 -1576 601 -16376 615 -1560 1673 -518 1663 -530 1671 -518 1671 -500 1697 -514 573 -1584 587 -1570 597 -1540 1699 -504 577 -1586 1693 -486 579 -1600 1681 -486 1711 -518 1677 -486 587 -1572 577 -1590 1677 -518 1673 -498 605 -1566 607 -1554 589 -1572 601 -1544 605 -16396 615 -1544 1673 -518 1667 -530 1673 -518 +RAW_Data: 1669 -520 1677 -488 621 -1576 581 -1542 615 -1568 1689 -486 583 -1596 1669 -520 571 -1572 1703 -512 1697 -494 1691 -528 583 -1570 599 -1574 1703 -484 1703 -512 573 -1588 585 -1572 601 -1574 577 -1568 613 -16404 595 -1574 1697 -504 1711 -506 1733 -510 1717 -504 1371 -32700 613 -1572 1653 -536 1673 -488 1679 -514 1669 -508 1681 -518 579 -1580 575 -1570 577 -1572 1667 -518 581 -1564 1671 -490 587 -1580 1677 -516 1663 -514 1657 -508 1673 -516 1695 -500 587 -1572 565 -1574 603 -1574 575 -1570 575 -1570 579 -1580 575 -16372 585 -1566 1673 -520 1671 -508 1677 -514 1665 -512 1655 -512 577 -1568 585 -1572 581 -1582 1667 -522 587 -1548 1669 -500 613 -1544 1683 -520 1679 -478 1703 -480 1685 -520 1673 -508 579 -1562 577 -1588 571 -1566 605 -1558 589 -1576 563 -1576 601 -16382 581 -1566 1671 -520 1681 -492 1679 -512 1663 -506 1679 -518 575 -1570 577 -1568 581 -1576 1667 -518 587 -1578 1643 -530 571 -1566 1667 -510 1687 -518 1665 -520 1669 -492 1691 -486 581 -1600 561 -1570 605 -1574 575 -1568 575 -1570 579 -1580 577 -16412 581 -1588 1665 -516 1665 -510 1653 -518 1669 -504 1667 -518 573 -1572 579 -1594 561 -1572 1693 -486 583 -1578 1667 -502 577 -1584 1691 -484 1699 -486 1693 -486 1673 -500 1691 -514 577 -1562 591 -1576 567 -1576 605 -1544 609 -1570 577 -1578 577 -16392 617 -1564 1673 -486 1681 -490 1681 -514 1671 -504 1683 -520 575 -1572 577 -1568 579 -1576 1671 -520 583 -1546 1669 -530 573 -1572 1673 -504 1679 -518 1671 -508 1667 -508 1673 -516 575 -1562 591 -1568 603 -1542 607 -1546 609 -1574 577 -1568 577 -16416 583 -1582 1667 -516 1637 -542 1651 -510 1665 -518 1671 -524 585 -1544 585 -1572 577 -1588 1675 -484 611 -1574 1667 -506 581 -1562 1691 -486 1671 -516 1691 -488 1673 -522 1679 -494 571 -1566 607 -1556 591 -1568 603 -1572 577 -1576 577 -1572 577 -16396 617 -1564 1681 -492 1681 -514 1673 -500 1675 -514 1667 -504 577 -1588 589 -1546 603 -1572 1665 -514 567 -1576 1697 -476 613 -1564 1669 -520 1679 -482 1695 -512 1655 -520 1673 -520 581 -1562 579 -1590 571 -1568 607 -1554 587 -1570 567 -1574 607 -16402 593 -1572 1665 -504 diff --git a/assets/unit_tests/subghz/scher_khan_magic_code.sub b/assets/unit_tests/subghz/scher_khan_magic_code.sub new file mode 100644 index 00000000000..81467b0a74f --- /dev/null +++ b/assets/unit_tests/subghz/scher_khan_magic_code.sub @@ -0,0 +1,22 @@ +Filetype: Flipper SubGhz RAW File +Version: 1 +Frequency: 433920000 +Preset: FuriHalSubGhzPreset2FSKDev238Async +Protocol: RAW +RAW_Data: 95 -240 191 -412 187 -152 95 -120 263 -220 373 -116 199 -88 239 -334 503 -142 167 -174 85 -172 143 -86 85 -96 119 -196 259 -96 167 -148 201 -96 481 -120 237 -264 143 -144 105 -790 257 -88 243 -144 143 -86 553 -216 103 -174 143 -142 119 -144 119 -224 307 -144 239 -120 127 -390 189 -168 119 -312 191 -142 215 -96 103 -86 307 -274 191 -104 143 -96 167 -120 357 -390 651 -218 197 -170 143 -164 85 -210 143 -116 143 -86 255 -160 95 -114 199 -88 545 -288 173 -114 115 -202 85 -316 145 -144 113 -562 105 -254 85 -144 287 -116 115 -202 87 -346 287 -244 103 -370 143 -230 143 -144 85 -88 113 -230 231 -984 119 -144 171 -144 201 -174 115 -288 113 -192 277 -114 345 -202 249 -316 83 -228 119 -146 151 -116 85 -202 85 -144 437 -272 115 -144 85 -86 173 -142 163 -260 205 -280 339 -88 229 -194 363 -144 585 -394 599 -144 85 -100 151 -574 171 -174 85 -114 239 -288 211 -410 115 -144 489 -116 115 -116 201 -336 95 -96 93 -120 95 -128 115 -116 257 -174 141 -292 113 -162 165 -192 287 -192 161 -192 1125 -202 85 -222 461 -144 113 -116 115 -114 201 -288 259 -288 401 -174 85 -106 119 -96 431 -130 85 -114 375 -494 95 -96 167 -288 281 -104 411 -214 335 -144 119 -534 85 -144 143 -144 229 -246 97 -82 85 -260 201 -304 403 -116 391 -172 229 -448 81 -82 95 -116 201 -86 521 -144 119 -336 119 -142 95 -144 119 -96 267 -170 283 -288 95 -190 167 -288 199 -116 247 -144 87 -144 85 -114 215 -260 115 -116 113 -338 103 -240 167 -96 119 -120 95 -96 405 -188 85 -116 191 -334 143 -164 85 -230 115 -154 119 -166 143 -288 195 -144 87 -86 343 -232 113 -202 115 -86 201 -278 201 -86 85 -86 303 -286 95 -120 95 -168 167 -118 129 -94 95 -432 151 -218 119 -186 235 -230 167 -632 143 -144 231 -156 153 -282 147 -96 143 -592 261 -120 191 -96 167 -576 333 -342 171 -462 173 -514 157 -432 87 -312 397 -378 287 -374 403 -230 117 -264 257 -170 189 -346 137 -528 117 -240 805 -454 539 -288 171 -86 173 -286 153 -288 115 -172 173 -158 399 -114 85 -116 201 -116 85 -216 215 -432 113 -100 113 -338 123 -146 289 -86 143 -114 343 -94 95 -96 311 -110 171 -86 143 -88 969 -312 119 -316 401 -134 255 -202 323 -86 87 -114 253 -228 95 -172 85 -170 165 -86 343 -192 119 -144 213 -112 191 -334 287 -96 359 -500 137 -120 261 -242 119 -118 283 -210 167 -178 287 -174 343 -268 +RAW_Data: 185 -96 119 -978 215 -120 213 -96 265 -172 261 -168 225 -462 307 -312 87 -172 115 -288 423 -84 87 -230 143 -404 109 -114 233 -216 165 -240 95 -288 95 -192 215 -238 335 -116 199 -170 135 -144 109 -408 285 -130 97 -98 115 -86 85 -86 87 -120 167 -144 119 -264 171 -316 231 -202 257 -274 115 -114 421 -86 85 -202 143 -144 201 -86 229 -86 143 -116 115 -86 115 -114 85 -202 143 -288 163 -186 483 -202 167 -212 373 -288 115 -86 171 -116 113 -230 231 -230 201 -172 171 -318 113 -390 101 -200 317 -404 287 -220 171 -232 199 -490 171 -144 173 -168 223 -202 173 -200 115 -172 119 -288 209 -220 85 -86 85 -480 423 -450 201 -364 411 -216 143 -120 219 -538 513 -330 199 -120 119 -96 127 -138 141 -140 117 -312 429 -182 259 -422 1027 -280 303 -210 131 -168 85 -86 201 -230 547 -174 113 -88 259 -202 109 -96 215 -144 291 -168 151 -316 85 -258 287 -260 279 -302 171 -284 189 -168 95 -96 309 -240 167 -384 165 -96 169 -226 95 -216 271 -122 195 -102 113 -116 339 -168 85 -192 583 -114 297 -406 167 -326 209 -212 119 -262 143 -86 87 -114 125 -172 115 -172 173 -576 219 -192 335 -120 85 -116 171 -202 711 -116 85 -172 373 -232 381 -144 95 -244 173 -210 119 -198 85 -86 143 -312 211 -96 115 -86 113 -528 103 -150 191 -144 119 -98 333 -172 215 -114 87 -86 529 -490 85 -356 239 -374 143 -260 457 -312 157 -394 131 -116 353 -172 229 -490 171 -144 189 -166 305 -144 85 -288 201 -356 147 -106 167 -740 143 -312 95 -242 137 -88 465 -126 239 -358 167 -120 1385 -130 385 -192 95 -120 817 -218 805 -140 171 -394 143 -86 371 -430 143 -216 187 -84 143 -316 173 -86 115 -202 85 -114 215 -96 167 -316 107 -368 313 -120 95 -382 197 -216 289 -388 119 -264 109 -86 113 -202 963 -172 111 -104 113 -346 115 -266 255 -88 229 -202 109 -288 357 -348 365 -226 381 -144 455 -144 901 -532 531 -108 103 -142 225 -144 143 -230 85 -144 141 -142 645 -82 167 -116 143 -172 403 -230 85 -144 87 -288 229 -144 115 -144 371 -82 107 -306 333 -116 113 -88 143 -86 229 -174 617 -96 677 -286 95 -240 95 -168 141 -216 95 -212 209 -120 95 -144 95 -240 165 -116 765 -230 229 -88 141 -192 97 -86 111 -114 231 -172 143 -144 365 -96 291 -144 129 -144 87 -168 141 -120 215 -144 143 -238 215 -192 95 -96 95 -144 403 -216 163 -102 155 -120 95 -120 263 -120 403 -374 431 -230 303 -134 791 -288 +RAW_Data: 201 -138 251 -262 95 -376 287 -230 143 -114 143 -144 259 -214 231 -238 167 -288 95 -166 119 -120 411 -144 143 -546 243 -260 143 -404 113 -450 137 -184 143 -230 375 -144 85 -230 129 -104 133 -112 171 -258 115 -316 259 -86 163 -96 95 -88 113 -350 167 -780 847 -174 143 -404 85 -314 109 -278 287 -86 101 -172 201 -258 115 -86 143 -144 115 -114 547 -86 423 -116 85 -144 507 -144 133 -518 85 -424 167 -246 143 -96 261 -192 109 -240 167 -240 117 -168 239 -192 85 -116 137 -264 143 -304 119 -96 191 -144 141 -264 95 -96 119 -144 95 -96 121 -478 229 -88 575 -230 85 -312 81 -102 103 -390 93 -96 119 -144 143 -238 215 -288 277 -96 115 -114 87 -288 113 -120 143 -114 261 -146 153 -116 335 -144 259 -136 85 -258 87 -144 85 -86 661 -86 161 -120 95 -110 191 -86 135 -408 103 -144 125 -192 119 -336 113 -86 173 -114 173 -216 335 -116 321 -186 559 -116 229 -316 115 -512 141 -168 191 -130 113 -120 143 -288 127 -174 215 -96 85 -318 1169 -174 85 -86 563 -146 315 -162 163 -96 339 -222 215 -230 229 -88 109 -218 493 -120 189 -264 253 -466 239 -240 157 -288 219 -268 309 -192 121 -156 241 -192 215 -144 95 -168 261 -86 397 -428 569 -88 411 -268 251 -168 167 -268 143 -288 453 -144 163 -86 115 -144 113 -296 81 -224 163 -458 171 -310 161 -88 85 -316 461 -508 201 -162 229 -114 145 -144 143 -86 143 -114 259 -144 345 -346 85 -124 143 -302 83 -116 113 -96 261 -84 297 -116 201 -240 143 -120 861 -144 117 -158 167 -96 215 -454 273 -304 239 -96 95 -204 189 -346 345 -286 545 -88 339 -104 171 -284 95 -360 239 -144 289 -96 95 -120 225 -106 197 -144 219 -208 145 -144 187 -282 95 -408 95 -338 187 -250 229 -86 115 -402 87 -86 143 -202 283 -98 329 -134 167 -88 229 -172 221 -138 169 -202 171 -196 111 -108 85 -144 479 -100 623 -212 133 -116 113 -144 403 -88 257 -462 287 -144 373 -210 239 -144 115 -172 289 -168 143 -98 119 -96 95 -96 357 -96 119 -216 143 -144 311 -192 95 -166 175 -416 351 -100 145 -94 119 -360 427 -94 95 -144 263 -144 115 -366 97 -98 95 -190 95 -264 541 -288 131 -140 85 -202 409 -226 229 -518 143 -202 363 -260 85 -86 269 -142 95 -120 215 -168 189 -208 239 -96 285 -456 129 -144 517 -114 589 -344 115 -288 235 -98 105 -282 109 -278 85 -312 171 -116 287 -316 87 -172 335 -430 119 -274 143 -164 229 -216 167 -232 343 -260 +RAW_Data: 143 -86 565 -144 87 -460 115 -508 363 -86 143 -276 671 -144 115 -86 515 -116 199 -236 185 -140 143 -82 113 -116 85 -116 85 -408 95 -284 199 -88 315 -116 143 -114 717 -202 85 -86 173 -86 201 -144 333 -200 115 -86 85 -174 401 -174 263 -244 229 -86 143 -434 229 -202 231 -164 143 -86 165 -182 167 -172 85 -346 771 -252 81 -106 217 -96 119 -96 287 -140 85 -86 143 -374 143 -116 85 -114 83 -118 119 -164 201 -86 153 -166 359 -116 283 -86 187 -120 459 -280 201 -144 229 -258 143 -408 427 -144 373 -294 197 -120 287 -96 119 -264 143 -120 119 -528 95 -168 119 -192 117 -558 97 -148 143 -120 185 -188 167 -264 95 -176 215 -254 201 -258 263 -158 215 -168 119 -312 873 -388 95 -192 359 -278 341 -96 171 -116 143 -432 173 -316 403 -84 85 -144 113 -174 287 -346 243 -216 95 -394 161 -144 317 -200 199 -140 95 -86 143 -278 139 -86 143 -144 201 -114 191 -264 119 -238 163 -114 143 -766 143 -144 167 -604 349 -390 459 -86 201 -172 633 -114 549 -432 339 -114 201 -174 325 -220 287 -116 123 -264 137 -86 173 -336 171 -422 133 -144 661 -86 163 -96 93 -96 215 -168 105 -114 259 -238 115 -86 315 -86 229 -298 167 -168 319 -432 189 -336 167 -120 123 -250 95 -144 167 -346 97 -96 429 -86 517 -120 95 -480 85 -86 307 -84 109 -112 121 -136 227 -112 115 -114 85 -202 201 -230 201 -88 143 -144 229 -96 347 -172 143 -656 201 -508 199 -174 139 -192 171 -172 257 -86 223 -216 143 -144 215 -120 85 -264 185 -212 271 -112 85 -374 85 -116 113 -88 113 -174 431 -202 315 -264 87 -116 373 -336 201 -172 173 -374 201 -172 115 -114 115 -86 115 -86 489 -280 119 -86 115 -144 137 -144 253 -480 1225 -1598 631 -828 709 -782 689 -792 1063 -1152 1105 -1066 1141 -1076 761 -734 1125 -1090 761 -696 765 -698 817 -672 1183 -1012 1197 -1022 819 -686 775 -710 775 -680 835 -646 839 -646 1181 -1018 801 -710 1139 -1078 1151 -1066 813 -646 843 -644 843 -622 841 -650 1187 -1014 1205 -1018 825 -656 829 -652 1197 -1024 1197 -1016 1209 -990 1167 -1074 789 -676 1179 -1032 831 -644 839 -644 843 -650 813 -678 795 -684 769 -712 775 -708 777 -728 783 -676 817 -646 1205 -1006 1219 -998 845 -632 1189 -1044 1177 -980 1527 -1456 1483 -1440 1537 -1388 839 -672 817 -648 843 -676 1127 -1088 1177 -1022 1199 -1020 817 -648 1213 -1010 831 -624 833 -648 839 -646 1213 -1018 1191 -1022 815 -678 783 -710 779 -710 769 -684 773 -734 1115 -1078 785 -710 1147 -1068 +RAW_Data: 1183 -992 855 -630 827 -664 839 -646 815 -644 1209 -1014 1191 -1050 765 -708 771 -738 1113 -1080 1181 -1006 1199 -1020 1185 -1042 815 -646 1181 -1032 827 -668 811 -670 815 -648 839 -676 769 -714 779 -710 773 -712 775 -708 777 -676 835 -644 1213 -1018 1143 -1078 763 -702 1177 -1008 1199 -994 1575 -1376 1525 -1428 1503 -1438 779 -718 817 -646 843 -650 1209 -1012 1179 -1024 1201 -1016 843 -644 1181 -1032 831 -622 831 -668 839 -644 1181 -1034 1197 -1024 811 -684 781 -712 771 -712 775 -680 775 -706 1177 -1024 807 -710 1137 -1076 1159 -1014 831 -652 835 -646 841 -646 839 -644 1183 -1040 1193 -996 837 -656 833 -686 1143 -1074 1161 -1016 1195 -1026 1185 -1012 831 -648 1207 -996 831 -684 771 -710 775 -702 809 -676 817 -646 817 -672 817 -672 817 -674 767 -734 771 -710 1137 -1076 1131 -1066 803 -642 1209 -1020 1197 -1018 1521 -1392 1549 -1416 1519 -1392 815 -670 841 -678 761 -736 1119 -1092 1155 -1018 1217 -1022 789 -702 1183 -1016 815 -648 815 -674 819 -648 1211 -1012 1199 -1022 833 -684 749 -712 769 -736 751 -678 829 -668 1179 -1016 797 -710 1139 -1078 1133 -1090 817 -644 819 -674 815 -676 789 -676 1153 -1064 1179 -1020 801 -712 773 -708 1141 -1076 1133 -1068 1187 -992 1197 -1046 793 -648 1209 -1012 829 -668 815 -674 819 -648 841 -674 761 -706 761 -732 767 -712 769 -712 777 -678 833 -648 1205 -1016 1161 -1074 817 -624 1207 -1006 1197 -996 1575 -1358 1573 -1386 1547 -1380 835 -686 775 -710 773 -704 1203 -996 1195 -1042 1187 -1018 831 -656 1195 -1026 811 -654 765 -736 771 -712 1139 -1078 1153 -1034 835 -646 817 -670 817 -650 841 -676 761 -704 1149 -1062 809 -646 1211 -1016 1191 -1024 839 -678 771 -710 775 -686 779 -712 1137 -1080 1129 -1040 835 -646 841 -646 1211 -1016 1193 -1022 1179 -1014 1197 -1022 835 -658 1143 -1068 817 -648 843 -674 765 -712 777 -712 769 -710 773 -704 781 -674 839 -648 845 -646 815 -674 1179 -1034 1201 -994 793 -714 1141 -1074 1159 -988 1557 -1404 1559 -1386 1509 -1438 809 -668 843 -674 813 -676 1135 -1070 1159 -1020 1169 -1072 817 -648 1207 -1012 839 -622 841 -646 843 -646 1179 -1034 1197 -1024 821 -686 749 -714 775 -710 775 -702 779 -694 1181 -1018 801 -708 1139 -1076 1127 -1088 811 -646 845 -646 841 -624 843 -650 1181 -1036 1203 -994 835 -658 829 -656 1191 -1050 1177 -1012 1179 -1000 1203 -1016 841 -646 1211 -1018 775 -710 777 -730 759 -702 815 -644 843 -646 817 -674 815 -678 785 -712 753 -734 773 -712 1115 -1076 1155 -1038 833 -648 1203 -994 1211 -1018 1519 -1388 1573 -1362 2045 -2332 103 -86 691 -116 229 -144 239 -120 135 -216 93 -202 315 -202 +RAW_Data: 231 -432 229 -114 403 -116 569 -86 575 -404 133 -120 239 -96 95 -96 93 -240 95 -144 95 -96 95 -168 141 -250 431 -174 113 -116 401 -116 173 -144 143 -172 85 -230 115 -260 137 -96 129 -86 605 -172 257 -168 229 -314 113 -88 257 -466 197 -96 81 -330 139 -86 85 -260 277 -200 87 -202 229 -88 219 -168 109 -86 119 -96 143 -216 143 -364 523 -118 95 -120 225 -330 83 -170 115 -86 81 -302 125 -256 95 -144 117 -96 95 -96 119 -168 167 -386 173 -132 515 -232 277 -144 229 -376 229 -202 455 -262 175 -88 171 -174 85 -86 85 -508 143 -174 315 -130 105 -202 115 -114 173 -432 111 -144 221 -162 273 -118 143 -380 257 -356 315 -236 119 -124 325 -214 115 -530 193 -168 105 -86 109 -144 119 -352 93 -96 119 -216 387 -224 197 -120 463 -144 93 -1134 85 -86 259 -86 201 -192 173 -198 185 -144 307 -200 85 -116 115 -192 95 -104 143 -202 229 -120 285 -120 239 -144 143 -392 519 -296 95 -144 229 -202 85 -202 85 -116 95 -120 101 -200 119 -96 95 -96 95 -172 119 -142 143 -216 81 -316 119 -144 269 -286 167 -130 231 -324 221 -96 167 -240 119 -102 113 -116 143 -192 191 -288 143 -144 309 -114 187 -378 231 -172 171 -458 413 -430 201 -120 469 -94 143 -504 261 -96 95 -144 237 -120 455 -334 163 -116 191 -280 169 -288 99 -492 85 -458 141 -260 171 -244 713 -168 359 -96 195 -154 733 -168 119 -364 143 -88 171 -86 85 -116 339 -86 173 -334 359 -144 95 -540 95 -120 185 -144 317 -114 87 -86 113 -254 373 -86 345 -288 85 -96 151 -122 429 -202 113 -342 247 -202 139 -86 229 -172 143 -88 87 -296 755 -220 447 -330 259 -330 241 -118 95 -340 245 -194 239 -112 201 -200 367 -1020 431 -408 279 -120 95 -96 95 -166 95 -216 281 -116 549 -140 257 -166 157 -192 263 -186 95 -286 119 -170 287 -230 173 -258 343 -366 171 -144 143 -116 85 -86 115 -86 243 -422 319 -120 243 -86 115 -172 143 -116 259 -86 201 -202 257 -664 763 -356 289 -114 85 -86 113 -486 271 -144 229 -116 115 -122 423 -314 969 -144 171 -116 201 -230 101 -202 143 -200 317 -86 85 -116 85 -462 181 -172 115 -202 309 -114 287 -316 139 -430 157 -192 191 -84 137 -168 113 -116 259 -114 373 -86 201 -116 199 -88 85 -172 173 -86 169 -240 119 -174 85 -286 137 -200 143 -172 259 -244 147 -144 115 -116 201 -140 423 -172 85 -144 87 -200 87 -202 85 -86 345 -174 143 -202 315 -404 229 -144 141 -212 +RAW_Data: 119 -114 231 -114 201 -318 431 -404 201 -82 167 -88 85 -114 81 -144 85 -202 85 -134 109 -144 461 -114 189 -354 171 -226 311 -152 115 -178 117 -360 239 -240 143 -286 143 -288 119 -268 315 -82 163 -196 173 -288 173 -192 215 -118 489 -88 143 -230 477 -110 459 -172 115 -172 403 -282 113 -116 143 -288 143 -172 139 -144 95 -214 167 -484 191 -444 95 -96 95 -202 117 -168 167 -120 325 -172 239 -202 229 -144 85 -404 115 -86 85 -528 143 -166 83 -172 403 -144 115 -144 507 -258 403 -156 171 -192 95 -120 293 -166 115 -86 547 -230 143 -192 315 -340 129 -84 229 -86 221 -202 143 -86 215 -178 85 -288 143 -164 141 -96 95 -144 287 -120 189 -216 143 -144 533 -192 85 -260 85 -86 115 -244 129 -134 229 -86 287 -174 171 -346 373 -86 229 -260 469 -100 83 -84 143 -118 95 -100 143 -116 431 -124 115 -114 345 -114 81 -314 199 -144 173 -192 95 -114 85 -88 171 -278 239 -288 171 -86 287 -202 201 -114 219 -336 199 -382 145 -144 121 -288 167 -240 299 -188 161 -96 117 -96 239 -120 213 -96 119 -336 127 -88 171 -390 163 -202 201 -216 119 -144 95 -144 157 -86 655 -206 699 -410 111 -126 135 -88 85 -172 115 -576 85 -116 85 -518 143 -86 87 -266 149 -120 129 -168 215 -110 167 -96 119 -168 95 -118 269 -306 201 -202 513 -96 99 -346 229 -288 115 -216 147 -172 173 -230 211 -124 87 -364 85 -172 259 -230 87 -114 143 -140 237 -88 85 -120 215 -238 95 -718 129 -214 167 -168 95 -262 665 -204 215 -418 97 -142 143 -288 95 -144 191 -168 301 -86 115 -202 113 -144 257 -116 173 -288 285 -198 85 -374 539 -244 119 -432 259 -400 175 -302 87 -402 259 -134 171 -88 113 -144 479 -202 85 -260 335 -266 131 -144 147 -144 143 -230 287 -144 231 -518 113 -144 143 -174 167 -172 201 -86 201 -230 171 -194 135 -86 345 -220 259 -144 85 -316 135 -406 191 -262 119 -96 113 -116 143 -144 143 -86 229 -260 115 -142 223 -318 85 -172 201 -86 373 -88 287 -490 105 -144 573 -116 695 -86 113 -82 209 -190 231 -172 605 -86 85 -646 143 -168 209 -168 153 -86 205 -144 143 -238 701 -262 163 -186 191 -96 197 -432 87 -114 341 -202 227 -120 335 -118 95 -240 191 -118 147 -144 87 -144 143 -172 115 -148 119 -130 345 -172 115 -358 493 -250 85 -172 167 -144 81 -548 143 -96 309 -282 159 -130 119 -96 95 -146 311 -86 191 -144 189 -120 155 -84 103 -96 165 -384 287 -120 527 -454 +RAW_Data: 115 -138 349 -212 143 -116 143 -748 143 -148 95 -168 535 -164 403 -316 201 -144 85 -86 105 -120 95 -144 453 -106 167 -144 213 -192 365 -110 143 -96 119 -120 191 -88 229 -114 173 -144 95 -120 107 -462 173 -200 335 -266 377 -118 167 -568 85 -144 85 -318 247 -174 223 -288 123 -128 143 -336 399 -220 263 -192 161 -144 85 -116 257 -260 229 -174 143 -230 115 -172 115 -258 285 -172 143 -142 153 -432 143 -142 145 -96 267 -202 143 -120 95 -142 167 -116 143 -172 287 -116 171 -116 115 -230 315 -86 423 -360 95 -352 253 -96 407 -96 143 -478 311 -168 167 -164 85 -202 85 -202 85 -114 459 -202 421 -230 85 -174 85 -116 85 -86 85 -374 311 -302 171 -116 201 -172 575 -190 373 -116 403 -432 143 -202 115 -86 113 -290 167 -84 243 -172 345 -88 201 -200 113 -312 99 -112 155 -294 171 -430 239 -220 85 -336 95 -96 117 -144 215 -120 95 -144 287 -310 311 -374 85 -174 171 -86 133 -116 153 -102 143 -144 215 -250 85 -512 201 -116 267 -120 279 -356 213 -120 191 -110 335 -144 95 -216 191 -142 95 -216 119 -190 191 -96 95 -240 191 -164 333 -170 267 -120 95 -192 165 -158 229 -202 85 -144 259 -174 191 -116 113 -86 113 -258 173 -144 113 -174 257 -88 417 -110 169 -144 87 -114 173 -114 221 -94 105 -288 85 -88 85 -144 259 -214 149 -258 115 -86 85 -86 403 -192 95 -306 231 -144 113 -86 115 -200 115 -260 171 -236 95 -240 113 -312 197 -166 191 -168 95 -96 165 -96 167 -120 287 -138 339 -216 117 -98 105 -110 597 -144 359 -186 283 -96 261 -312 127 -140 113 -318 171 -174 143 -318 143 -200 345 -576 143 -116 143 -144 229 -316 143 -346 229 -786 85 -316 229 -244 339 -96 603 -304 173 -432 543 -84 111 -116 113 -466 103 -150 141 -88 381 -104 273 -98 215 -318 143 -100 87 -114 85 -174 201 -86 345 -144 521 -172 113 -86 85 -164 199 -174 85 -202 575 -114 87 -144 257 -146 199 -246 237 -274 329 -184 147 -96 311 -130 195 -312 93 -240 163 -140 141 -168 119 -168 455 -144 259 -202 85 -288 143 -174 113 -260 171 -174 633 -440 243 -250 391 -88 287 -144 143 -144 191 -86 239 -142 263 -246 105 -120 143 -142 263 -96 215 -168 85 -260 87 -480 277 -86 143 -144 403 -114 85 -462 767 -200 85 -174 315 -94 147 -408 85 -260 171 -112 143 -114 903 -116 201 -116 115 -86 173 -344 87 -114 115 -288 143 -288 85 -86 365 -230 143 -316 201 -86 569 -202 171 -202 143 -442 +RAW_Data: 375 -172 211 -96 85 -264 429 -168 119 -116 163 -148 239 -168 95 -192 215 -230 95 -216 119 -144 167 -364 115 -316 115 -346 85 -116 229 -288 103 -480 305 -116 143 -86 85 -304 261 -168 167 -96 141 -144 95 -144 455 -106 113 -144 87 -86 229 -202 143 -316 143 -232 199 -174 233 -216 547 -278 143 -116 345 -288 369 -290 153 -316 305 -230 143 -116 545 -230 287 -168 237 -120 95 -370 201 -288 143 -258 173 -138 361 -82 345 -288 197 -168 165 -240 143 -186 263 -216 195 -202 171 -144 465 -194 501 -192 159 -172 143 -144 85 -192 253 -96 219 -300 205 -86 143 -86 311 -120 269 -634 185 -116 113 -456 97 -96 85 -174 85 -288 115 -144 173 -114 245 -144 119 -120 119 -96 93 -138 199 -144 173 -88 315 -202 157 -120 143 -96 167 -120 271 -268 287 -86 231 -144 143 -144 113 -346 259 -104 441 -204 249 -272 231 -114 345 -116 85 -86 85 -142 127 -100 169 -156 119 -96 167 -238 141 -86 143 -230 115 -114 115 -202 137 -168 143 -312 167 -110 193 -338 281 -230 721 -124 95 -120 309 -110 143 -144 563 -460 171 -88 143 -490 201 -144 85 -232 171 -144 201 -144 171 -144 95 -124 109 -572 633 -316 215 -264 161 -236 215 -202 115 -86 229 -260 257 -144 173 -172 259 -86 171 -264 129 -202 503 -350 161 -112 195 -144 401 -116 201 -230 287 -144 191 -96 167 -284 161 -164 119 -224 143 -376 209 -82 85 -144 201 -116 403 -114 231 -238 107 -174 85 -86 387 -200 173 -86 85 -116 87 -200 201 -174 287 -114 623 -86 143 -260 567 -108 113 -246 99 -396 115 -168 137 -396 85 -116 171 -86 87 -114 231 -144 235 -196 85 -144 305 -126 95 -218 417 -330 133 -116 85 -346 371 -134 345 -114 173 -372 111 -144 345 -402 115 -144 85 -86 87 -144 517 -86 413 -86 403 -120 431 -214 119 -264 191 -374 195 -86 287 -86 143 -608 143 -120 95 -216 263 -96 167 -120 113 -336 157 -192 285 -136 287 -200 87 -292 119 -216 109 -168 253 -118 167 -96 309 -96 191 -264 117 -170 119 -96 95 -406 167 -96 95 -120 167 -188 185 -96 417 -120 759 -144 85 -144 115 -86 173 -202 411 -188 263 -306 259 -288 229 -116 113 -88 171 -116 201 -114 365 -220 119 -398 181 -124 143 -202 85 -288 143 -288 229 -86 87 -114 229 -86 287 -88 143 -114 115 -258 287 -260 143 -86 335 -86 267 -240 119 -144 95 -238 119 -96 119 -246 405 -144 105 -144 147 -222 117 -110 129 -202 171 -86 229 -174 85 -96 109 -108 81 -86 95 -216 +RAW_Data: 247 -86 113 -144 459 -140 115 -86 143 -144 229 -652 273 -96 81 -114 115 -172 87 -594 115 -230 85 -462 85 -86 85 -86 287 -240 263 -96 85 -458 363 -480 95 -192 119 -120 167 -288 105 -288 201 -172 201 -172 345 -144 115 -312 255 -144 167 -112 155 -96 167 -134 173 -114 201 -86 105 -114 347 -86 201 -144 173 -258 143 -260 215 -234 173 -114 229 -174 117 -168 335 -114 231 -114 191 -216 589 -120 141 -96 95 -168 335 -150 201 -230 259 -268 125 -100 287 -114 85 -174 201 -288 161 -166 125 -144 345 -116 575 -336 237 -120 421 -96 95 -96 119 -96 543 -258 115 -86 85 -116 85 -202 257 -202 409 -84 169 -114 115 -374 173 -374 85 -144 215 -168 195 -116 345 -230 173 -114 85 -398 81 -86 143 -144 345 -114 115 -86 173 -222 93 -116 113 -86 375 -114 153 -326 401 -116 87 -288 143 -460 143 -168 95 -168 253 -216 469 -96 167 -96 265 -244 111 -114 1439 -114 115 -140 119 -134 201 -144 199 -346 229 -202 489 -288 459 -222 81 -172 229 -288 335 -198 201 -200 143 -140 119 -134 383 -216 579 -86 85 -288 167 -116 143 -312 287 -192 113 -174 403 -460 287 -308 545 -284 333 -114 119 -190 145 -114 115 -96 153 -220 539 -192 829 -162 201 -216 143 -258 143 -116 171 -86 115 -86 115 -638 213 -120 431 -192 287 -144 239 -94 167 -192 95 -120 417 -162 95 -96 119 -142 167 -120 357 -168 431 -214 81 -516 197 -114 361 -86 257 -136 141 -288 87 -86 143 -288 143 -86 115 -172 143 -174 113 -174 85 -144 171 -144 143 -144 85 -116 257 -116 219 -176 949 -342 107 -140 115 -144 359 -142 95 -120 119 -240 95 -96 167 -96 95 -164 185 -172 197 -112 101 -116 171 -144 229 -202 85 -202 115 -114 263 -168 143 -122 213 -216 95 -96 381 -168 319 -202 171 -230 271 -278 259 -278 95 -220 489 -144 259 -132 315 -202 113 -86 143 -144 287 -174 393 -116 173 -346 143 -262 129 -142 119 -86 115 -138 399 -230 257 -422 315 -306 147 -96 285 -192 455 -130 263 -144 113 -144 461 -278 369 -120 97 -136 81 -144 113 -232 85 -258 317 -144 633 -86 173 -316 119 -192 163 -96 115 -86 173 -518 85 -174 285 -108 107 -488 201 -264 93 -232 85 -240 215 -124 215 -344 169 -94 143 -120 119 -120 179 -140 255 -146 119 -280 141 -316 143 -418 147 -442 127 -174 201 -172 115 -172 85 -346 115 -144 85 -144 259 -172 201 -316 87 -86 127 -96 263 -192 173 -114 367 -120 133 -552 313 -144 143 -96 85 -260 109 -614 +RAW_Data: 333 -140 141 -114 287 -394 257 -88 145 -314 113 -86 113 -178 367 -198 199 -136 229 -662 489 -174 181 -134 171 -82 201 -288 367 -196 85 -88 171 -172 259 -116 85 -144 505 -260 85 -318 489 -114 143 -116 143 -172 115 -116 401 -278 167 -96 335 -120 143 -168 249 -184 95 -86 229 -144 187 -114 87 -86 171 -398 461 -326 95 -96 287 -112 181 -124 115 -178 95 -106 85 -192 109 -120 311 -470 95 -190 825 -114 317 -86 113 -146 113 -174 199 -88 85 -192 261 -332 85 -86 115 -116 661 -86 115 -114 287 -144 259 -202 143 -174 113 -322 297 -202 673 -106 111 -202 171 -232 305 -518 173 -346 113 -404 229 -86 253 -226 113 -144 487 -106 249 -302 195 -120 95 -120 311 -216 209 -192 95 -96 171 -96 95 -168 215 -214 167 -140 311 -140 83 -82 191 -336 95 -216 167 -354 107 -234 315 -88 85 -172 113 -86 315 -236 115 -172 201 -316 115 -374 141 -82 185 -190 325 -274 115 -86 143 -164 191 -86 201 -114 215 -170 95 -264 143 -96 119 -196 229 -82 289 -234 143 -264 201 -86 115 -346 229 -172 143 -202 143 -86 345 -86 173 -138 95 -102 575 -144 143 -230 221 -158 251 -168 103 -96 133 -172 173 -336 143 -188 309 -86 143 -116 85 -144 85 -306 201 -116 215 -286 283 -396 305 -148 317 -216 115 -490 115 -186 111 -144 201 -86 143 -192 285 -128 137 -86 85 -116 173 -216 119 -118 215 -96 95 -216 107 -82 173 -258 115 -168 263 -182 459 -288 143 -86 115 -490 143 -230 115 -144 229 -764 93 -112 81 -118 249 -144 229 -174 201 -374 201 -230 171 -88 223 -304 115 -200 143 -86 87 -174 85 -116 169 -172 429 -168 165 -216 603 -188 119 -120 269 -86 249 -120 141 -216 229 -174 85 -202 251 -186 87 -114 121 -254 649 -144 399 -86 201 -104 169 -162 103 -122 165 -168 119 -120 213 -84 143 -86 143 -168 173 -258 85 -232 315 -86 229 -116 95 -288 217 -124 335 -144 191 -120 333 -120 191 -216 143 -574 375 -86 311 -110 143 -202 287 -86 113 -174 345 -96 511 -88 109 -96 143 -638 133 -120 167 -360 95 -96 95 -144 143 -116 403 -480 341 -88 85 -114 115 -230 111 -226 115 -86 171 -404 259 -144 215 -288 405 -240 105 -402 255 -572 115 -168 113 -216 115 -144 143 -116 143 -374 85 -116 113 -116 287 -162 87 -86 219 -240 113 -116 863 -86 305 -126 113 -202 143 -378 143 -376 391 -88 229 -144 171 -200 259 -86 87 -144 109 -140 85 -116 327 -140 363 -114 143 -244 85 -116 335 -96 309 -352 +RAW_Data: 95 -168 219 -96 95 -168 95 -312 333 -144 117 -290 119 -94 373 -240 215 -96 229 -338 135 -202 257 -490 201 -116 85 -202 257 -144 113 -346 85 -86 289 -230 143 -144 109 -168 167 -96 189 -144 239 -114 143 -144 199 -116 85 -202 85 -174 165 -88 113 -112 315 -116 229 -164 119 -110 113 -116 115 -144 85 -202 113 -116 115 -200 115 -86 231 -114 85 -86 287 -168 93 -168 85 -88 257 -144 201 -230 715 -86 115 -144 373 -202 85 -116 85 -194 217 -144 201 -202 143 -172 143 -86 163 -202 115 -402 187 -244 251 -152 191 -336 117 -216 95 -144 253 -114 201 -456 95 -646 85 -288 85 -84 443 -576 115 -116 143 -432 115 -346 257 -334 621 -96 95 -264 171 -198 147 -452 229 -144 215 -288 93 -96 287 -96 165 -96 287 -138 777 -202 363 -190 191 -240 81 -114 119 -118 283 -138 95 -166 229 -194 119 -198 189 -192 167 -168 215 -94 119 -124 81 -196 351 -286 183 -140 969 -346 171 -586 87 -172 201 -164 267 -130 113 -144 191 -98 191 -96 243 -202 201 -174 199 -202 713 -454 95 -144 107 -144 451 -110 201 -174 143 -116 143 -144 285 -84 83 -328 117 -424 119 -144 95 -214 135 -402 115 -114 115 -174 257 -406 215 -336 193 -288 113 -116 229 -86 345 -260 113 -232 101 -264 167 -94 95 -216 401 -202 373 -114 173 -232 279 -690 259 -172 143 -404 229 -220 115 -114 173 -230 171 -318 309 -156 113 -170 223 -172 287 -174 315 -116 229 -332 111 -116 85 -258 431 -404 201 -86 171 -106 115 -96 369 -124 239 -206 115 -230 389 -200 115 -86 565 -488 83 -82 585 -172 459 -198 87 -86 85 -116 143 -202 371 -96 287 -392 221 -174 85 -230 461 -474 93 -120 95 -274 171 -144 339 -226 143 -184 81 -230 141 -216 143 -216 117 -120 167 -216 167 -96 265 -108 165 -86 315 -260 229 -172 87 -312 587 -150 341 -200 187 -432 171 -84 85 -202 85 -116 85 -116 431 -114 201 -84 169 -86 85 -114 313 -346 85 -86 85 -142 159 -646 143 -88 119 -120 521 -134 173 -128 315 -462 99 -362 227 -144 167 -120 165 -246 215 -86 825 -168 443 -536 835 -316 85 -174 113 -144 85 -144 173 -458 143 -288 81 -170 143 -268 215 -192 285 -360 113 -258 225 -168 163 -334 113 -116 257 -296 287 -312 277 -116 603 -82 255 -96 95 -336 301 -82 95 -552 141 -332 281 -110 201 -172 145 -200 115 -144 95 -344 201 -116 171 -96 119 -120 143 -144 421 -96 199 -394 107 -110 115 -114 145 -316 315 -288 115 -200 87 -114 115 -288 +RAW_Data: 85 -374 259 -260 113 -174 287 -144 507 -202 229 -144 221 -142 115 -124 143 -216 95 -96 117 -216 143 -144 85 -144 143 -144 201 -144 85 -284 469 -190 149 -86 143 -316 283 -290 95 -216 119 -180 167 -200 375 -86 111 -192 143 -144 213 -404 85 -144 719 -202 85 -434 143 -144 143 -172 287 -264 111 -114 315 -96 115 -576 85 -230 85 -144 143 -174 281 -198 201 -86 201 -144 575 -116 85 -174 143 -164 315 -168 171 -268 85 -536 111 -172 153 -462 239 -158 333 -174 361 -258 343 -96 453 -240 119 -256 113 -88 171 -172 259 -230 173 -110 113 -202 113 -88 113 -232 315 -100 165 -422 99 -316 311 -262 191 -120 555 -280 85 -174 431 -86 259 -210 119 -168 885 -462 433 -106 107 -116 113 -644 127 -278 115 -86 87 -226 159 -346 115 -144 85 -144 85 -768 541 -168 113 -86 87 -374 113 -144 747 -230 187 -268 521 -346 311 -1194 383 -478 313 -110 229 -202 171 -144 287 -722 285 -138 225 -188 133 -346 85 -174 199 -374 229 -112 135 -194 95 -216 143 -120 377 -86 245 -120 93 -96 95 -178 217 -86 277 -312 517 -530 505 -192 259 -106 119 -94 143 -336 293 -348 219 -316 87 -258 85 -174 143 -86 85 -116 171 -398 167 -88 85 -116 85 -202 459 -314 143 -202 459 -222 253 -202 171 -462 143 -490 143 -264 249 -340 147 -88 143 -144 113 -144 461 -258 85 -86 115 -202 171 -86 317 -86 115 -114 283 -86 287 -116 373 -86 287 -156 659 -158 87 -114 201 -124 95 -86 287 -172 87 -172 113 -144 663 -230 143 -162 95 -116 143 -116 113 -86 173 -356 99 -198 391 -140 191 -144 219 -172 171 -318 191 -374 201 -328 87 -230 85 -86 143 -116 195 -96 99 -226 383 -382 119 -264 431 -120 167 -120 95 -312 191 -106 85 -172 143 -520 95 -238 299 -288 359 -108 375 -172 185 -150 213 -168 119 -120 127 -146 171 -86 143 -202 115 -144 113 -202 201 -116 113 -144 365 -142 143 -22490 523 -858 969 -1190 1065 -1160 1067 -1146 683 -754 1133 -1100 747 -712 775 -708 779 -702 1125 -1102 1119 -1094 767 -698 763 -728 759 -734 755 -710 757 -738 1117 -1070 815 -648 1207 -1010 1197 -1024 835 -658 779 -710 771 -710 779 -706 1115 -1102 1133 -1066 815 -644 843 -650 1203 -1010 1207 -998 1197 -1042 1153 -1020 803 -710 1141 -1076 791 -678 785 -708 767 -712 773 -710 775 -704 779 -704 815 -646 839 -646 843 -648 813 -656 1205 -1012 1205 -1020 1193 -1020 815 -644 843 -624 1551 -1394 1553 -1364 1575 -1390 819 -672 841 -680 755 -712 1141 -1076 1185 -1016 1191 -1050 763 -704 +RAW_Data: 1183 -1014 813 -646 841 -644 843 -648 1203 -1010 1207 -996 805 -714 775 -710 775 -678 835 -648 813 -672 1181 -1016 799 -710 1139 -1076 1151 -1064 811 -646 845 -646 843 -622 843 -650 1205 -1012 1177 -1022 805 -712 775 -714 1139 -1076 1149 -1034 1205 -998 1177 -1040 811 -670 1183 -1012 855 -626 835 -674 817 -644 843 -648 843 -624 845 -674 761 -732 755 -712 779 -714 773 -710 1139 -1080 1127 -1092 1149 -1024 811 -658 831 -658 1499 -1406 1555 -1404 1557 -1408 805 -668 815 -676 817 -678 1131 -1092 1159 -1018 1213 -1022 815 -676 1131 -1092 789 -642 843 -646 841 -648 1185 -1036 1181 -1018 801 -710 775 -678 829 -668 815 -644 845 -646 1181 -1038 831 -650 1207 -992 1211 -1048 791 -650 843 -676 763 -706 763 -734 1119 -1094 1153 -1018 823 -656 829 -676 1179 -1022 1159 -1070 1179 -1006 1191 -1022 815 -706 1125 -1066 813 -648 845 -646 841 -650 815 -678 783 -710 755 -712 779 -710 769 -710 775 -706 835 -646 1181 -1020 1193 -1022 1185 -1016 833 -654 833 -624 1559 -1410 1515 -1384 1569 -1414 789 -674 843 -674 761 -730 1133 -1068 1177 -1010 1195 -1026 817 -678 1151 -1066 813 -646 817 -672 819 -646 1209 -1012 1197 -1024 835 -658 769 -710 799 -710 749 -690 835 -640 1211 -1018 777 -736 1115 -1078 1151 -1064 809 -644 841 -646 841 -624 841 -650 1201 -1010 1205 -1018 803 -712 773 -704 1145 -1076 1121 -1092 1157 -1016 1185 -1048 791 -674 1179 -1012 835 -648 841 -646 843 -646 843 -674 767 -708 769 -714 777 -714 747 -734 777 -668 843 -644 1205 -1006 1193 -1048 1177 -1012 805 -668 843 -620 1545 -1418 1521 -1388 1575 -1360 841 -672 819 -682 769 -712 1139 -1076 1157 -1040 1197 -1026 835 -658 1143 -1072 817 -620 845 -646 843 -674 1185 -988 1205 -1018 801 -712 777 -706 781 -674 841 -646 817 -648 1207 -1008 831 -652 1199 -1024 1199 -1042 817 -644 817 -648 841 -676 765 -706 1149 -1064 1179 -1020 829 -658 825 -654 1197 -1024 1179 -1012 1205 -992 1183 -1072 789 -674 1183 -1010 837 -650 841 -644 843 -646 843 -678 789 -676 763 -706 793 -710 769 -712 775 -706 781 -674 1205 -1022 1139 -1098 1157 -1014 827 -652 829 -640 1537 -1388 1567 -1388 1541 -1392 813 -698 815 -676 767 -734 1133 -1076 1131 -1040 1195 -1052 811 -678 1133 -1070 819 -620 843 -646 843 -676 1125 -1090 1179 -994 859 -632 797 -710 775 -702 839 -622 841 -644 1211 -992 801 -710 1139 -1078 1151 -1062 813 -646 843 -646 843 -622 841 -650 1205 -1010 1203 -1020 823 -658 825 -654 1195 -1022 1201 -1040 1155 -1016 1185 -1046 815 -650 1177 -1034 833 -644 843 -646 819 -674 815 -676 767 -710 769 -712 775 -710 775 -678 861 -620 841 -646 1205 -1008 +RAW_Data: 1221 -1022 1185 -1016 813 -646 841 -618 1573 -1364 1577 -1362 1811 -2658 227 -138 191 -120 333 -488 345 -86 403 -86 115 -604 283 -82 343 -202 143 -316 87 -128 311 -230 119 -264 165 -168 247 -216 199 -166 283 -230 81 -132 487 -114 115 -142 921 -260 345 -114 373 -116 115 -114 115 -166 191 -192 171 -116 417 -242 167 -240 285 -120 283 -86 257 -230 335 -244 167 -96 167 -188 161 -96 85 -232 173 -114 201 -144 363 -144 87 -86 507 -88 143 -490 103 -124 143 -460 517 -144 219 -202 173 -144 113 -318 229 -174 401 -442 143 -88 603 -144 259 -86 115 -116 113 -144 113 -142 297 -202 171 -86 201 -86 115 -374 163 -364 471 -104 169 -88 201 -144 237 -234 203 -160 113 -86 269 -96 95 -240 431 -94 295 -328 191 -144 239 -240 165 -96 119 -168 421 -238 191 -144 119 -168 143 -120 143 -96 209 -164 239 -240 335 -116 201 -316 115 -172 201 -114 115 -172 173 -86 431 -202 143 -86 229 -116 171 -86 317 -162 143 -174 113 -174 85 -228 85 -142 139 -196 305 -106 85 -232 171 -168 531 -86 85 -86 173 -172 143 -260 137 -342 257 -174 85 -100 115 -170 139 -174 829 -96 191 -192 311 -240 311 -82 211 -144 475 -114 201 -86 85 -286 239 -144 95 -264 227 -120 387 -202 251 -142 143 -316 345 -450 85 -174 315 -372 251 -258 143 -230 221 -156 431 -170 85 -114 431 -364 633 -174 421 -114 259 -86 201 -116 115 -86 229 -174 103 -96 115 -244 307 -86 345 -356 259 -450 693 -98 263 -456 191 -96 357 -116 85 -86 115 -230 201 -88 161 -518 259 -340 173 -116 315 -140 107 -218 517 -96 285 -124 95 -382 119 -144 167 -168 357 -168 119 -144 287 -142 95 -200 143 -260 201 -306 173 -604 479 -224 285 -106 507 -116 165 -408 359 -288 97 -116 225 -430 85 -144 449 -374 113 -120 95 -96 241 -106 101 -86 123 -120 117 -214 107 -144 263 -268 119 -120 141 -96 119 -216 229 -306 287 -150 135 -172 287 -114 215 -168 143 -172 115 -462 113 -144 143 -490 199 -116 403 -116 171 -590 637 -304 113 -86 143 -100 111 -534 149 -312 237 -236 143 -202 85 -202 171 -488 109 -572 201 -238 95 -174 397 -202 283 -164 87 -662 201 -244 315 -562 143 -86 325 -96 575 -190 191 -144 85 -202 189 -358 287 -618 835 -160 163 -142 85 -172 139 -144 215 -82 287 -114 87 -144 541 -438 143 -240 167 -144 359 -190 95 -120 263 -108 109 -184 215 -100 113 -288 119 -144 95 -406 81 -114 87 -256 315 -316 171 -100 105 -144 263 -302 229 -174 +RAW_Data: 113 -232 197 -176 143 -200 187 -240 537 -96 95 -118 263 -432 141 -96 119 -216 761 -282 119 -526 119 -120 185 -116 171 -168 81 -86 143 -172 173 -86 113 -144 489 -202 143 -174 287 -186 373 -168 373 -174 85 -168 119 -330 325 -174 113 -144 373 -202 143 -138 195 -174 185 -192 119 -412 115 -114 283 -120 143 -360 525 -120 119 -120 367 -116 115 -144 345 -114 87 -120 287 -240 239 -96 503 -168 459 -144 317 -242 95 -104 255 -82 227 -172 307 -314 119 -264 901 -282 171 -202 171 -346 201 -576 167 -196 201 -288 315 -116 85 -144 85 -290 143 -264 303 -532 173 -120 215 -272 603 -86 143 -86 85 -190 167 -144 431 -238 119 -96 119 -96 455 -96 285 -144 287 -618 85 -288 253 -592 105 -104 139 -188 335 -120 511 -166 431 -202 373 -86 87 -114 231 -206 83 -190 199 -288 201 -86 171 -88 195 -120 201 -116 257 -202 161 -156 229 -144 143 -298 263 -166 119 -158 115 -326 455 -166 95 -144 119 -168 141 -216 455 -334 95 -144 95 -214 143 -96 143 -196 143 -190 479 -364 287 -114 163 -86 287 -130 297 -96 167 -96 431 -144 95 -190 119 -144 141 -120 335 -144 285 -188 497 -112 429 -258 143 -140 111 -232 87 -116 143 -96 285 -204 273 -632 371 -144 85 -202 115 -172 499 -144 143 -120 119 -120 95 -360 143 -258 173 -930 315 -134 431 -144 115 -114 257 -740 373 -174 95 -144 297 -268 167 -96 143 -834 171 -168 95 -172 119 -96 85 -88 199 -88 315 -172 259 -216 311 -202 85 -260 257 -144 657 -120 119 -116 223 -286 233 -130 115 -202 85 -144 143 -172 115 -88 85 -114 95 -114 345 -288 85 -116 471 -124 173 -114 335 -260 115 -658 339 -260 113 -86 201 -480 217 -470 105 -114 259 -134 137 -86 171 -326 191 -120 263 -144 95 -148 289 -124 121 -384 95 -322 171 -142 193 -288 143 -172 211 -266 109 -144 325 -168 213 -96 685 -310 239 -262 143 -216 143 -316 393 -126 215 -216 387 -202 201 -230 143 -116 85 -144 201 -268 143 -262 311 -86 115 -316 167 -86 229 -116 335 -144 117 -302 113 -116 241 -86 143 -202 201 -116 453 -288 293 -272 367 -120 651 -170 565 -116 143 -882 557 -116 181 -588 119 -168 287 -168 119 -118 191 -168 143 -282 115 -88 171 -404 719 -202 115 -172 253 -144 143 -532 121 -144 239 -96 167 -120 119 -456 199 -114 311 -86 201 -352 111 -144 115 -114 173 -86 85 -538 113 -88 257 -116 143 -96 95 -144 121 -198 127 -172 173 -114 229 -116 143 -144 173 -368 111 -200 163 -116 +RAW_Data: 113 -292 169 -200 145 -86 85 -230 259 -86 85 -86 439 -96 85 -116 115 -86 113 -86 85 -192 191 -214 263 -264 119 -96 345 -116 85 -86 173 -288 85 -104 145 -130 85 -662 243 -390 263 -96 129 -422 223 -288 219 -172 655 -108 361 -96 271 -432 167 -120 421 -278 217 -248 143 -96 165 -240 109 -628 99 -96 95 -168 95 -216 119 -144 171 -172 115 -86 85 -174 387 -190 239 -384 143 -344 115 -114 143 -86 233 -140 85 -724 119 -82 85 -144 115 -144 115 -144 143 -114 201 -174 215 -96 109 -144 85 -144 599 -144 115 -258 249 -206 171 -86 143 -110 255 -86 85 -86 287 -208 225 -100 193 -200 143 -288 139 -460 113 -498 85 -144 143 -88 85 -144 229 -144 85 -144 171 -288 261 -202 113 -88 87 -114 143 -288 373 -366 229 -202 201 -172 173 -172 421 -280 153 -120 81 -160 137 -116 201 -250 141 -230 115 -318 863 -206 119 -462 143 -144 85 -86 201 -230 407 -96 223 -112 143 -94 95 -106 479 -86 113 -174 171 -284 119 -158 239 -190 167 -204 185 -408 215 -168 259 -202 201 -86 85 -202 87 -448 249 -332 363 -490 85 -172 115 -114 145 -114 259 -144 101 -142 119 -240 143 -188 387 -384 425 -144 173 -506 137 -162 139 -174 253 -116 131 -106 115 -130 117 -144 95 -86 239 -192 407 -120 237 -144 143 -82 487 -102 439 -112 199 -88 201 -262 269 -230 229 -192 219 -252 133 -96 191 -346 135 -288 621 -232 661 -202 327 -164 143 -144 139 -536 115 -114 143 -174 85 -100 99 -86 85 -174 85 -144 345 -172 243 -408 115 -86 115 -202 229 -114 87 -114 229 -740 801 -158 143 -168 479 -124 103 -264 119 -240 171 -88 219 -278 431 -402 513 -264 465 -256 141 -168 115 -358 251 -316 387 -172 101 -96 683 -192 95 -120 191 -120 95 -462 261 -96 121 -180 167 -878 287 -86 143 -86 311 -118 287 -168 191 -96 167 -158 85 -86 315 -434 165 -822 171 -316 231 -84 415 -174 87 -296 229 -222 93 -192 167 -190 143 -96 95 -96 237 -168 259 -86 115 -346 171 -116 115 -114 317 -114 95 -140 373 -116 143 -286 207 -260 171 -202 171 -134 119 -320 453 -96 293 -168 143 -144 119 -172 143 -202 237 -360 225 -86 287 -86 201 -202 109 -120 133 -214 215 -116 85 -260 267 -122 335 -316 111 -604 87 -172 259 -258 235 -96 173 -230 339 -140 115 -86 287 -288 143 -186 95 -96 95 -96 339 -256 147 -158 143 -246 223 -264 213 -202 85 -110 95 -168 95 -118 119 -168 95 -264 191 -316 119 -144 119 -382 167 -120 diff --git a/assets/unit_tests/subghz/somfy_keytis_raw.sub b/assets/unit_tests/subghz/somfy_keytis_raw.sub new file mode 100644 index 00000000000..21145c064ab --- /dev/null +++ b/assets/unit_tests/subghz/somfy_keytis_raw.sub @@ -0,0 +1,7 @@ +Filetype: Flipper SubGhz RAW File +Version: 1 +Frequency: 433420000 +Preset: FuriHalSubGhzPresetOok650Async +Protocol: RAW +RAW_Data: 1753 -32700 2581 -2598 2513 -2604 2535 -2568 2529 -2602 2519 -2608 2523 -2574 2529 -2598 2517 -2604 2537 -2596 2521 -2574 2523 -2600 2515 -2530 4829 -1304 1305 -1308 1309 -678 669 -1280 1305 -680 639 -678 653 -1308 1273 -1334 645 -686 645 -684 611 -716 645 -684 1273 -1340 1269 -1338 641 -684 643 -684 643 -684 609 -714 1273 -682 643 -680 643 -1340 643 -684 1271 -1310 645 -684 1303 -682 643 -1308 1301 -1312 645 -682 1275 -1350 649 -644 649 -702 647 -678 679 -654 645 -646 681 -644 683 -642 1309 -672 647 -690 645 -1314 635 -680 1297 -688 651 -1316 647 -682 617 -686 649 -682 1307 -660 639 -704 639 -1304 1293 -688 653 -672 621 -696 653 -664 653 -668 651 -670 647 -704 613 -704 617 -704 613 -708 613 -708 613 -710 613 -1336 665 -652 1285 -680 655 -1340 583 -1734 2523 -2570 2543 -2572 2529 -2564 2533 -2570 2531 -2596 2519 -2478 4805 -1310 1299 -1314 1313 -680 637 -1328 1289 -684 623 -690 653 -1322 1289 -1308 651 -668 651 -688 615 -688 679 -654 1305 -1304 1305 -1304 645 -686 645 -688 643 -652 643 -712 1273 -680 653 -680 651 -1312 647 -682 1273 -1342 639 -680 1271 -718 613 -1348 1281 -1310 639 -680 1295 -1314 653 -678 645 -682 645 -678 675 -648 651 -678 651 -678 647 -678 1281 -698 613 -706 613 -1336 669 -658 1293 -684 639 -1330 629 -686 653 -686 653 -654 1309 -678 621 -1340 1273 -712 603 -712 639 -672 653 -664 651 -666 651 -670 651 -702 617 -672 649 -704 613 -706 615 -706 615 -708 613 -1334 1293 -688 621 -1316 659 -686 1281 -2338 2501 -2600 2511 -2606 2491 -2624 2481 -2610 2521 -2560 2527 -2506 4797 -1308 1299 -1312 1317 -678 635 -1294 1323 -682 619 -692 635 -1334 1291 -1312 653 -658 679 -656 647 -688 643 -654 1303 -1336 1301 -1304 643 -690 641 -654 675 -654 643 -682 1303 -678 655 -680 645 -1308 677 -654 1309 -1310 645 -682 1275 -686 647 -1320 1281 -1318 679 -642 1317 -1300 667 -636 677 -660 673 -656 705 -612 671 -670 643 -670 681 -646 1309 -660 669 -674 637 -1310 673 -658 1293 -690 653 -1290 657 -688 649 -656 679 -658 1303 -676 635 -1314 657 -658 1307 -678 669 -670 621 -690 635 -672 649 -674 647 -674 647 -674 647 -708 613 -710 645 -676 647 -676 613 -1336 631 -688 1285 -680 655 -1306 647 -688 611 -1706 2535 -2592 2529 -2570 2533 -2566 2543 -2570 2529 -2572 2533 -2474 4807 -1294 1325 -1314 1279 -680 665 -1290 1323 -648 659 -688 653 -1290 1317 -1310 657 -656 679 -658 641 -688 643 -656 1303 -1334 1299 -1302 675 -646 675 -644 677 -658 643 -688 1303 -676 641 -676 633 -1314 691 -654 1277 -1336 649 -656 1305 -674 667 -1284 1315 -1308 653 -656 1305 -1306 679 -658 645 -690 +RAW_Data: 641 -656 709 -624 673 -656 679 -652 675 -648 1301 -678 645 -670 643 -1332 645 -656 1305 -678 645 -1336 641 -692 641 -656 673 -654 1307 -1308 1303 -678 679 -642 647 -678 647 -680 655 -648 655 -686 647 -656 675 -656 655 -656 683 -658 643 -688 643 -654 675 -1314 1275 -692 651 -1288 1319 -678 635 -1296 661 -1684 2527 -2602 2515 -2568 2541 -2602 2479 -2612 2523 -2578 2509 -2502 4783 -1344 1273 -1320 1283 -710 637 -1292 1319 -680 637 -668 649 -1332 1291 -1316 653 -656 679 -642 645 -688 679 -670 1289 -1310 1283 -1308 679 -670 629 -688 653 -654 647 -688 1311 -676 621 -708 641 -1306 677 -646 1307 -1306 643 -678 1303 -676 635 -1318 1289 -1340 651 -672 1275 -1338 649 -670 631 -688 655 -686 679 -636 667 -654 653 -656 681 -676 1277 -680 653 -676 655 -1304 645 -688 1271 -710 635 -1308 653 -668 671 -658 1295 -686 637 -1330 1295 -1310 1281 -678 665 -648 667 -664 647 -670 649 -702 613 -708 613 -710 645 -676 645 -676 647 -642 681 -1304 1295 -1314 653 -656 1309 -678 635 -680 633 -32700 2601 -2608 2491 -2602 2525 -2598 2521 -2604 2511 -2604 2531 -2584 2535 -2602 2503 -2620 2493 -2602 2533 -2600 2505 -2610 2533 -2474 4829 -1338 1297 -1316 1283 -716 651 -1280 1303 -676 635 -688 637 -1334 1297 -1310 653 -656 681 -644 645 -680 1307 -676 655 -1308 1305 -1304 645 -688 643 -656 643 -684 1307 -678 655 -682 647 -680 647 -1302 645 -680 1305 -1310 643 -682 1303 -682 621 -1312 1311 -1314 671 -644 1313 -1316 637 -680 669 -658 637 -696 637 -682 677 -648 643 -684 643 -68 \ No newline at end of file diff --git a/assets/unit_tests/subghz/somfy_telis_raw.sub b/assets/unit_tests/subghz/somfy_telis_raw.sub new file mode 100644 index 00000000000..79da813eee9 --- /dev/null +++ b/assets/unit_tests/subghz/somfy_telis_raw.sub @@ -0,0 +1,9 @@ +Filetype: Flipper SubGhz RAW File +Version: 1 +Frequency: 433920000 +Preset: FuriHalSubGhzPresetOok650Async +Protocol: RAW +RAW_Data: 675 -624 645 -648 643 -1278 1319 -1242 675 -626 2435 -727768 3971 -2848 681 -1752 2603 -2562 2599 -2534 4613 -1258 1333 -1252 1305 -644 649 -1270 681 -610 667 -614 679 -608 1311 -638 665 -614 665 -620 695 -608 651 -1278 665 -634 667 -614 1303 -652 653 -632 671 -610 649 -642 649 -620 699 -1250 651 -650 1291 -618 675 -642 649 -1268 1331 -616 671 -1250 685 -616 1293 -622 675 -1272 673 -618 1309 -1286 631 -656 665 -626 1289 -628 673 -618 679 -1242 1341 -612 681 -608 651 -1278 1325 -624 643 -646 667 -1248 1319 -616 679 -608 681 -32648 9731 -7680 2595 -2560 2597 -2534 4615 -1256 1303 -1286 1305 -642 649 -1270 665 -616 691 -624 663 -624 1291 -628 673 -1276 1295 -618 665 -1280 677 -628 643 -646 1295 -622 659 -1288 1307 -630 669 -612 681 -1240 679 -614 1319 -628 673 -1244 697 -592 1337 -608 685 -616 669 -1250 1311 -638 669 -614 681 -1236 1341 -1246 1323 -1272 1305 -632 665 -1256 677 -630 1305 -614 673 -1254 685 -616 1295 -622 675 -1270 669 -626 1307 -624 655 -1294 639 -14120 2597 -2568 2589 -2540 2625 -2542 2589 -2572 2593 -2546 2623 -2536 2589 -2586 4593 -1248 1325 -1278 1303 -606 683 -1270 667 -612 665 -636 669 -614 1305 -650 653 -1258 1305 -644 649 -1270 667 -616 695 -624 1291 -640 641 -1286 1297 -620 675 -640 649 -1274 683 -608 1323 -616 675 -1246 661 -628 1335 -608 651 -652 667 -1252 1313 -630 667 -612 679 -1272 1305 -1244 1321 -1290 1305 -626 671 -1240 673 -618 1339 -618 669 -1250 653 -650 1291 -620 697 -1250 677 -612 1297 -642 683 -1242 667 -14104 2623 -2526 2621 -2532 2619 -2532 2623 -2534 2619 -2530 2623 -2534 2619 -2532 4629 -1244 1323 -1274 1303 -642 649 -1268 669 -614 661 -624 699 -594 1319 -614 693 -1256 1303 -644 649 -1268 667 -614 693 -594 1323 -628 673 -1278 1291 -616 665 -622 667 -1280 675 -628 1303 -612 677 -1254 695 -608 1307 -634 671 -614 647 -1272 1341 -616 669 -596 681 -1256 1333 -1256 1305 -1270 1303 -642 649 -1282 667 -618 1303 -618 691 -1256 679 -612 1301 -644 649 -1278 665 -634 1297 -624 681 -1236 683 -32670 9703 -7674 2591 -2582 2575 -2564 4603 -1260 1309 -1274 1301 -644 683 -1246 665 -618 677 -608 685 -612 1333 -622 665 -624 637 -644 647 -642 649 -654 631 -1268 683 -612 1335 -626 637 -644 645 -638 679 -604 679 -1256 679 -606 685 -614 1301 -652 639 -642 647 -1266 1339 -614 671 -1252 687 -616 1293 -622 691 -1272 643 -616 1319 -1270 683 -616 673 -624 1301 -608 683 -614 679 -1256 1313 -630 667 -630 665 -1256 1305 -644 649 -642 649 -1280 1297 -616 679 -614 659 -14758 2623 -2534 2621 -2520 2619 -2558 2609 -2534 2603 -2560 2595 -2546 2605 -2560 4603 -1258 1307 -1274 1337 -608 +RAW_Data: 651 -1280 665 -616 677 -608 683 -612 1333 -624 665 -626 665 -624 665 -624 665 -626 665 -1254 675 -628 1305 -610 677 -624 653 -628 673 -624 681 -1238 679 -628 675 -620 1315 -624 643 -626 679 -1272 1309 -614 681 -1238 677 -614 1319 -626 675 -1250 695 -594 1335 -1272 641 -618 693 -628 1297 -624 681 -608 663 -1278 1301 -610 683 -610 679 -1256 1339 -608 665 -616 665 -1278 1305 -642 649 -644 649 -14760 2597 -2544 2619 -2534 2589 -2588 2587 -2560 2577 -2576 2597 -2564 2567 -2568 4613 -1274 1305 -1252 1307 -642 681 -1240 679 -614 665 -618 667 -620 1323 -642 641 -650 643 -616 693 -592 699 -622 665 -1250 679 -626 1303 -612 679 -626 675 -628 643 -648 655 -1254 675 -628 641 -654 1281 -658 641 -616 677 -1278 1315 -612 681 -1270 643 -616 1317 -626 675 -1280 667 -626 1305 -1270 641 -652 655 -630 1283 -654 653 -630 669 -1242 1333 -608 681 -604 677 -1284 1297 -618 679 -614 663 -1282 1301 -640 651 -610 679 -32664 9707 -7678 2607 -2556 2577 -2576 4589 -1266 1309 -1266 1339 -612 645 -1300 641 -652 653 -630 671 -612 1305 -1276 655 -628 1301 -644 649 -1278 665 -632 671 -612 1305 -1278 653 -628 1303 -644 649 -620 695 -1258 649 -642 1307 -1258 677 -628 643 -652 1279 -1288 1309 -1258 1309 -1272 1303 -1270 1341 -616 673 -624 641 -1284 1295 -1282 675 -594 677 -616 1317 -1288 647 -622 659 -628 1335 -1270 645 -652 655 -626 1291 -1256 679 -622 661 -14126 2589 -2572 2593 -2542 2615 -2532 2621 -2556 2585 -2560 2579 -2572 2591 -2562 4621 -1242 1305 -1268 1343 -614 669 -1252 685 -616 669 -626 641 -626 1307 -1280 663 -620 1325 -628 641 -1280 661 -626 675 -618 1311 -1282 671 -612 1309 -612 693 -624 641 -1270 673 -624 1309 -1284 659 -608 685 -610 1301 -1282 1303 -1270 1301 -1302 1305 -1244 1321 -626 675 -624 653 -1262 1309 -1274 673 -618 681 -610 1325 -1254 677 -624 675 -616 1305 -1272 651 -634 665 -618 1303 -1280 657 -636 675 -14100 2585 -2572 2593 -2548 2591 -2570 2591 -2552 2621 -2532 2609 -2568 2597 -2528 4615 -1278 1305 -1272 1305 -612 679 -1284 639 -644 647 -644 647 -650 1291 -1280 675 -616 1305 -610 679 -1254 685 -614 673 -626 1305 -1272 677 -618 1315 -624 641 -650 641 -1276 655 -626 1333 -1266 671 -618 655 -632 1295 -1276 1297 -1282 1303 -1274 1333 -1238 1337 -616 673 -624 641 -1276 1301 -1284 677 -612 675 -622 1311 -1254 685 -616 671 -626 1301 -1272 675 -622 655 -628 1297 -1284 667 -596 681 -32664 9707 -7662 2623 -2532 2619 -2556 4595 -1276 1297 -1278 1305 -644 647 -1272 685 -606 665 -616 665 -622 1325 -612 673 -624 679 -612 661 -1276 677 -614 675 -622 651 -636 1297 -624 681 -610 665 -618 665 -1280 1305 -1268 +RAW_Data: 669 -624 1309 -622 659 -660 643 -1282 1293 -620 677 -1270 675 -624 1317 -592 675 -1278 671 -624 1301 -1272 675 -622 655 -632 1297 -624 679 -610 663 -1284 1305 -608 685 -612 675 -1252 1341 -604 665 -618 675 -1268 1297 -642 649 -652 631 -14758 2625 -2528 2625 -2546 2581 -2562 2595 -2576 2579 -2564 2593 -2546 2611 -2562 4605 -1254 1337 -1240 1329 -610 683 -1272 667 -610 667 -614 665 -618 1325 -628 673 -622 649 -636 667 -1274 641 -646 669 -620 653 -634 1291 -650 641 -650 653 -634 669 -1242 1333 -1266 669 -618 1311 -626 643 -648 675 -1248 1317 -612 667 -1274 677 -614 1301 -642 649 -1284 665 -626 1291 -1290 649 -622 657 -628 1333 -608 685 -614 673 -1252 1311 -634 665 -614 679 -1272 1303 -614 677 -624 653 -1286 1307 -626 671 -612 681 -14722 2623 -2550 2591 -2570 2591 -2544 2621 -2530 2615 -2542 2597 -2570 2591 -2544 4609 -1286 1297 -1284 1293 -620 675 -1272 675 -620 653 -632 669 -614 1305 -614 691 -630 639 -644 649 -1272 679 -612 661 -620 693 -608 1309 -634 671 -612 679 -608 651 -1280 1321 -1256 679 -624 1313 -612 679 -608 685 -1242 1325 -624 655 -1286 649 -652 1291 -616 665 -1280 675 -614 1301 -1272 679 -610 665 -618 1325 -630 675 -618 653 -1262 1307 -644 647 -644 647 -1280 1327 -624 641 -618 677 -1274 1315 -614 679 -608 649 -32690 9699 -7666 2621 -2560 2589 -2544 4597 -1290 1307 -1254 1305 -644 647 -1294 669 -620 653 -632 665 -626 1293 -638 675 -616 675 -616 667 -1272 651 -608 1333 -1270 1305 -610 681 -624 657 -626 673 -1282 1289 -618 665 -1280 1303 -644 647 -644 647 -1282 1293 -626 679 -1272 653 -626 1303 -644 649 -1284 667 -612 1305 -1276 659 -628 677 -618 1311 -626 655 -626 675 -1278 1291 -616 677 -608 683 -1272 1293 -652 667 -598 679 -1256 1335 -622 665 -594 697 -14730 2627 -2526 2609 -2538 2629 -2528 2607 -2566 2595 -2556 2579 -2584 2591 -2562 4589 -1272 1313 -1278 1301 -610 683 -1278 653 -632 637 -646 681 -608 1307 -632 671 -612 647 -644 653 -1282 665 -614 1323 -1272 1305 -628 671 -612 679 -608 681 -1262 1293 -652 631 -1288 1309 -632 661 -608 685 -1278 1281 -634 677 -1256 675 -626 1315 -616 647 -1272 679 -612 1321 -1256 679 -622 655 -626 1337 -610 649 -654 633 -1286 1311 -630 667 -614 679 -1270 1305 -616 677 -624 643 -1276 1303 -654 639 -642 649 -14754 2611 -2544 2593 -2572 2587 -2544 2623 -2530 2627 -2544 2615 -2530 2617 -2544 4605 -1284 1299 -1248 1323 -618 679 -1268 669 -622 651 -634 665 -614 1327 -612 673 -618 681 -610 663 -1278 675 -594 1339 -1246 1321 -626 675 -624 651 -634 669 -1242 1335 -608 685 -1244 1319 -642 641 -648 643 -1280 1315 -614 679 -1272 645 -650 1287 -626 +RAW_Data: 675 -1278 669 -624 1301 -1270 643 -652 657 -630 1297 -618 681 -614 665 -1276 1301 -642 649 -610 679 -1254 1333 -624 681 -606 665 -1280 1301 -608 681 -612 677 -32676 9683 -7690 2587 -2562 2609 -2536 4601 -1274 1335 -1252 1309 -640 649 -1270 669 -612 693 -592 699 -590 1325 -1266 683 -614 1297 -1278 677 -616 1301 -1272 1311 -1284 671 -612 1305 -1276 1313 -614 679 -1274 1303 -1274 655 -630 671 -612 1305 -1278 1313 -1274 1305 -1270 1303 -1278 1315 -598 679 -628 641 -1276 1319 -1274 675 -614 667 -624 1309 -1254 685 -614 671 -626 1305 -1272 677 -618 651 -636 1295 -1284 669 -626 641 -14100 2633 -2546 2597 -2562 2597 -2546 2601 -2556 2613 -2544 2591 -2572 2591 -2540 4599 -1264 1339 -1268 1309 -614 681 -1234 701 -616 667 -608 665 -634 1291 -1296 649 -644 1305 -1254 677 -628 1303 -1274 1313 -1254 683 -616 1297 -1282 1307 -608 685 -1274 1313 -1260 645 -638 685 -616 1293 -1280 1309 -1270 1303 -1270 1307 -1282 1295 -624 677 -612 661 -1284 1303 -1270 671 -624 679 -612 1325 -1240 679 -624 655 -628 1335 -1238 677 -614 693 -594 1321 -1276 657 -626 675 -14088 2609 -2544 2627 -2530 2607 -2572 2601 -2528 2605 -2574 2601 -2528 2605 -2574 4575 -1286 1295 -1286 1303 -640 649 -1272 667 -610 693 -592 673 -644 1307 -1274 653 -628 1303 -1274 649 -640 1291 -1286 1301 -1278 677 -612 1329 -1270 1303 -614 677 -1262 1307 -1276 651 -626 675 -622 1311 -1256 1303 -1280 1319 -1276 1301 -1272 1303 -644 647 -624 657 -1296 1307 -1270 649 -628 675 -620 1313 -1256 681 -608 685 -616 1295 -1278 675 -628 643 -650 1279 -1286 651 -650 633 -32690 9691 -7690 2587 -2562 2609 -2562 4603 -1240 1337 -1250 1305 -644 647 -1270 667 -652 657 -626 665 -626 1291 -1286 649 -622 1319 -1278 643 -646 667 -622 653 -634 1325 -1258 647 -644 1305 -1254 1339 -1240 669 -626 1307 -1278 665 -632 671 -614 1309 -1272 1315 -1240 1335 -1270 1301 -1272 1307 -622 657 -636 677 -1274 1305 -1254 677 -628 643 -652 1315 -1250 655 -618 697 -598 1309 -1274 675 -616 681 -610 1325 -1256 675 -626 649 -14098 2623 -2546 2585 -2566 2593 -2574 2579 -2558 diff --git a/assets/unit_tests/subghz/test_random_raw.sub b/assets/unit_tests/subghz/test_random_raw.sub new file mode 100644 index 00000000000..77e81f23a0a --- /dev/null +++ b/assets/unit_tests/subghz/test_random_raw.sub @@ -0,0 +1,65 @@ +Filetype: Flipper SubGhz RAW File +Version: 1 +Frequency: 433920000 +Preset: FuriHalSubGhzPresetOok650Async +Protocol: RAW +RAW_Data: 1160 -296 263 -166 65 -66 133 -98 133 -494 97 -226 361 -100 295 -66 131 -164 397 -66 431 -198 989 -100 431 -66 131 -66 197 -1052 231 -400 165 -102 199 -100 199 -100 299 -68 229 -234 167 -98 201 -136 267 -132 165 -100 131 -66 67 -66 131 -68 231 -100 99 -134 165 -132 665 -66 231 -100 267 -66 197 -100 659 -66 231 -266 197 -98 229 -990 297 -98 67 -796 99 -562 231 -300 65 -100 363 -1094 163 -336 331 -132 327 -98 261 -98 293 -100 265 -100 1265 -66 335 -134 267 -98 333 -134 99 -66 331 -66 195 -66 227 -164 263 -100 65 -692 163 -1978 97 -232 63 -132 131 -66 263 -66 293 -98 727 -132 65 -66 97 -66 295 -132 97 -66 263 -100 365 -100 165 -268 463 -66 65 -66 265 -1326 97 -100 197 -888 297 -130 327 -98 229 -264 65 -496 131 -266 195 -132 259 -132 361 -132 165 -98 927 -332 99 -66 99 -100 197 -658 65 -100 197 -164 133 -766 197 -236 199 -168 65 -98 233 -198 65 -100 129 -166 197 -790 97 -394 393 -130 557 -100 65 -230 333 -132 1389 -134 65 -66 99 -100 265 -134 99 -100 97 -460 327 -166 233 -266 199 -562 67 -898 197 -100 165 -1100 231 -100 263 -100 263 -132 1161 -66 463 -98 133 -98 165 -130 131 -66 65 -264 97 -266 97 -66 163 -166 97 -66 229 -296 99 -132 391 -98 327 -98 163 -200 631 -196 169 -102 131 -166 1327 -134 1361 -132 331 -134 99 -396 195 -364 97 -132 163 -66 99 -264 133 -200 165 -334 99 -134 65 -1332 165 -132 133 -298 367 -1124 295 -66 129 -66 593 -66 329 -264 397 -66 533 -66 461 -66 133 -132 65 -266 65 -132 99 -232 131 -2186 297 -98 165 -100 65 -66 97 -100 63 -566 99 -100 133 -66 333 -332 231 -364 231 -68 165 -300 497 -100 763 -100 365 -98 165 -200 65 -100 65 -696 65 -134 65 -262 65 -430 97 -66 131 -98 131 -330 293 -198 97 -132 163 -628 133 -98 131 -198 559 -98 459 -64 753 -98 361 -100 165 -132 133 -364 99 -66 197 -100 65 -132 197 -896 199 -66 65 -432 231 -168 231 -100 299 -528 131 -232 99 -134 97 -66 299 -66 197 -68 495 -100 65 -98 65 -100 563 -828 197 -732 267 -1260 65 -100 165 -898 65 -430 165 -496 199 -66 231 -66 131 -132 195 -66 193 -294 1259 -134 165 -100 199 -66 199 -166 233 -430 97 -366 97 -166 65 -1196 97 -132 97 -64 131 -196 97 -66 131 -960 229 -98 99 -264 233 -134 297 -98 467 -100 165 -98 365 -98 735 -98 197 -1464 233 -626 301 -432 97 -132 +RAW_Data: 231 -100 163 -362 163 -132 261 -298 65 -232 67 -132 297 -100 229 -228 497 -66 395 -98 593 -132 165 -132 67 -100 397 -132 99 -600 297 -66 231 -132 495 -136 65 -860 197 -98 129 -260 129 -100 131 -134 331 -268 165 -98 167 -66 231 -68 131 -232 65 -396 99 -100 663 -200 231 -66 1067 -66 99 -166 331 -132 65 -196 65 -134 133 -66 795 -66 397 -100 233 -132 199 -66 233 -200 433 -362 67 -298 327 -100 397 -66 165 -66 233 -232 529 -66 165 -100 67 -66 397 -66 689 -100 195 -462 325 -164 227 -132 261 -426 331 -98 133 -66 97 -296 97 -98 197 -66 97 -428 163 -526 359 -132 327 -164 99 -66 231 -396 329 -64 525 -66 593 -856 195 -100 129 -132 227 -166 229 -130 129 -98 293 -132 163 -98 195 -130 195 -98 97 -66 165 -100 99 -66 199 -466 265 -66 131 -132 197 -198 163 -232 1857 -100 265 -264 67 -264 265 -368 297 -102 133 -66 233 -98 167 -66 201 -66 133 -134 167 -166 65 -168 99 -400 165 -498 97 -298 131 -198 227 -132 327 -98 97 -66 297 -230 593 -132 67 -132 1227 -68 199 -134 197 -102 131 -232 365 -962 133 -298 297 -66 265 -266 333 -230 165 -102 165 -234 65 -98 131 -98 133 -66 167 -134 1357 -134 599 -532 265 -268 99 -298 199 -100 165 -166 131 -100 231 -266 65 -68 231 -334 67 -266 97 -134 65 -198 133 -100 163 -336 165 -234 65 -332 163 -690 97 -564 263 -64 165 -66 499 -100 563 -230 229 -132 99 -166 165 -132 199 -66 497 -66 659 -166 233 -68 331 -100 331 -66 165 -202 133 -896 133 -228 163 -196 131 -66 229 -130 263 -164 65 -98 263 -164 889 -66 261 -164 99 -494 97 -132 131 -64 65 -462 65 -262 99 -332 65 -102 65 -496 99 -132 197 -230 299 -134 65 -166 99 -430 99 -100 563 -66 165 -330 199 -264 197 -68 231 -100 367 -134 365 -68 299 -68 495 -68 165 -100 65 -498 397 -66 327 -100 195 -98 163 -132 163 -360 197 -98 65 -462 97 -526 427 -100 1419 -66 265 -66 333 -98 299 -98 99 -132 97 -100 197 -134 97 -100 231 -68 133 -100 165 -100 97 -100 133 -98 133 -66 165 -166 267 -132 229 -68 299 -66 97 -964 131 -66 133 -98 99 -66 297 -132 131 -68 167 -134 201 -68 167 -66 301 -166 133 -68 365 -100 527 -130 165 -130 233 -262 95 -628 97 -66 231 -168 99 -498 99 -100 229 -100 99 -166 299 -232 65 -100 99 -468 131 -68 197 -100 99 -66 297 -330 99 -100 463 -100 231 -68 133 -234 131 -134 231 -98 +RAW_Data: 561 -264 131 -100 65 -98 99 -66 133 -134 165 -132 65 -68 97 -68 131 -896 329 -198 65 -100 295 -230 199 -264 97 -196 327 -132 131 -100 131 -100 1293 -66 131 -202 463 -198 65 -68 99 -298 65 -232 333 -566 199 -168 99 -168 65 -498 295 -134 167 -134 199 -100 431 -100 65 -530 233 -164 65 -98 297 -134 363 -100 557 -100 163 -100 261 -66 619 -132 231 -296 97 -596 97 -228 131 -66 97 -66 197 -66 97 -360 229 -98 129 -330 99 -130 99 -130 65 -100 65 -132 97 -460 63 -100 265 -330 331 -98 197 -66 855 -464 165 -66 99 -198 99 -868 231 -66 167 -636 329 -530 165 -130 131 -132 99 -528 165 -64 65 -164 65 -166 129 -162 425 -66 231 -100 133 -98 231 -68 333 -98 165 -200 361 -98 99 -66 297 -68 163 -168 65 -498 99 -232 295 -696 99 -266 131 -100 65 -100 99 -628 133 -132 65 -366 265 -398 261 -100 529 -100 297 -132 2535 -596 65 -932 199 -66 199 -866 65 -298 165 -66 67 -132 65 -100 165 -200 131 -166 299 -200 167 -166 199 -334 65 -694 365 -132 727 -232 265 -66 133 -102 65 -100 531 -232 65 -132 65 -100 131 -562 197 -66 297 -66 265 -100 433 -432 495 -332 197 -98 167 -332 97 -66 297 -758 65 -228 99 -194 295 -130 99 -98 261 -98 163 -66 231 -134 1029 -68 399 -200 133 -132 99 -266 163 -264 163 -130 229 -66 689 -166 131 -988 65 -592 97 -132 129 -164 197 -432 65 -100 165 -134 65 -166 133 -232 563 -66 231 -66 599 -66 265 -100 199 -498 231 -464 327 -262 131 -100 327 -430 197 -266 99 -132 65 -66 133 -132 101 -200 65 -100 433 -166 99 -266 265 -98 97 -66 229 -100 263 -200 631 -100 199 -66 167 -300 753 -262 457 -132 231 -98 163 -164 227 -164 65 -262 129 -594 229 -790 131 -66 129 -428 197 -164 197 -200 133 -100 131 -564 65 -134 661 -134 2925 -68 231 -134 167 -132 99 -98 133 -98 167 -98 197 -1086 329 -296 65 -130 65 -264 197 -132 163 -98 165 -66 97 -132 129 -100 261 -66 97 -66 197 -326 95 -134 629 -98 65 -262 65 -132 197 -264 129 -98 163 -230 131 -528 261 -298 197 -64 131 -394 131 -764 99 -132 99 -66 99 -464 367 -98 165 -98 1159 -134 963 -66 633 -562 133 -132 99 -66 131 -564 197 -134 263 -132 195 -66 131 -262 459 -332 197 -66 133 -1060 133 -66 331 -662 197 -134 231 -100 299 -232 1087 -232 131 -100 265 -462 131 -200 433 -168 101 -432 97 -196 65 -132 327 -100 129 -226 163 -100 163 -132 +RAW_Data: 227 -330 129 -466 165 -200 163 -66 97 -130 97 -66 197 -164 457 -166 463 -166 361 -66 163 -66 97 -198 65 -64 99 -300 65 -68 263 -98 99 -134 197 -100 165 -134 231 -66 297 -98 67 -132 365 -66 197 -228 99 -428 195 -132 65 -330 265 -628 63 -130 97 -132 195 -232 195 -130 263 -132 167 -100 133 -166 1229 -264 165 -332 233 -1230 199 -102 167 -100 401 -166 229 -852 197 -264 229 -130 163 -198 65 -98 229 -66 199 -100 335 -98 899 -134 393 -528 97 -66 97 -300 99 -300 99 -664 329 -198 99 -400 131 -198 299 -330 99 -66 65 -132 67 -298 527 -66 493 -132 1085 -198 425 -232 197 -66 131 -164 165 -66 197 -1480 197 -330 65 -494 65 -330 197 -296 99 -66 97 -592 99 -164 97 -426 329 -66 131 -98 99 -66 265 -98 433 -66 131 -234 267 -234 65 -266 99 -98 65 -166 97 -164 197 -198 65 -866 67 -66 231 -430 131 -200 65 -100 631 -198 265 -526 99 -230 129 -68 165 -232 229 -98 427 -328 1053 -134 431 -198 365 -430 131 -100 131 -398 231 -134 1195 -132 131 -134 661 -100 333 -398 97 -400 97 -234 165 -468 65 -100 99 -66 299 -266 67 -98 397 -166 987 -132 97 -64 65 -266 97 -852 297 -132 163 -428 65 -298 99 -1124 97 -266 233 -66 165 -332 65 -800 297 -98 131 -164 469 -100 97 -658 165 -66 133 -132 531 -134 131 -98 297 -722 65 -132 821 -100 229 -132 459 -66 197 -98 985 -330 131 -100 133 -100 101 -198 299 -100 65 -134 363 -100 67 -830 131 -132 99 -100 299 -66 297 -366 99 -166 197 -66 131 -364 131 -200 331 -134 265 -530 99 -564 65 -68 231 -132 233 -134 165 -66 165 -66 431 -102 465 -132 99 -132 99 -364 133 -98 67 -198 133 -66 65 -264 99 -298 231 -100 199 -728 297 -132 65 -134 433 -926 263 -66 227 -528 65 -130 263 -100 97 -98 723 -100 131 -134 531 -66 267 -400 199 -66 65 -100 99 -498 99 -332 529 -98 197 -460 131 -296 231 -296 97 -66 65 -426 131 -132 133 -100 99 -66 99 -964 463 -68 631 -68 1325 -232 365 -68 163 -432 131 -432 301 -234 165 -432 99 -398 65 -100 133 -166 433 -230 163 -236 67 -132 97 -300 65 -66 199 -132 2355 -296 327 -98 65 -66 99 -294 197 -232 133 -100 67 -134 97 -66 65 -760 65 -98 131 -166 197 -132 63 -132 163 -98 163 -754 429 -230 163 -66 695 -132 199 -98 433 -100 1197 -394 491 -460 65 -460 65 -166 97 -68 131 -134 233 -66 299 -762 231 -200 265 -198 499 -132 167 -766 +RAW_Data: 265 -66 165 -134 165 -66 365 -132 2091 -134 231 -632 297 -630 195 -264 65 -296 65 -64 131 -298 165 -100 99 -100 99 -562 165 -398 99 -566 99 -166 133 -334 99 -134 357 -68 97 -332 459 -130 161 -230 163 -132 163 -98 195 -164 97 -130 65 -1262 265 -166 563 -964 133 -100 99 -796 199 -868 67 -134 65 -232 67 -66 199 -132 295 -98 821 -332 1097 -296 129 -758 65 -200 67 -98 531 -198 265 -66 863 -66 65 -300 363 -100 99 -132 165 -100 267 -134 165 -234 231 -100 533 -198 1057 -200 497 -68 531 -100 63 -66 133 -100 163 -330 63 -230 161 -100 97 -66 131 -298 165 -68 167 -732 265 -396 265 -100 99 -166 99 -200 65 -596 131 -696 263 -200 135 -100 133 -66 65 -98 131 -66 399 -66 367 -130 765 -298 97 -98 231 -130 197 -130 65 -294 131 -98 195 -66 129 -66 131 -428 131 -66 197 -660 133 -66 131 -332 165 -628 65 -724 99 -164 131 -98 65 -166 395 -68 435 -68 299 -66 1323 -400 231 -298 99 -264 199 -428 131 -230 65 -1188 99 -98 163 -526 327 -66 197 -394 165 -66 65 -596 857 -66 163 -66 591 -166 129 -234 167 -624 265 -294 263 -500 131 -164 65 -98 195 -166 97 -100 195 -198 131 -1214 1017 -166 97 -428 425 -66 1183 -430 261 -230 65 -196 97 -100 195 -364 65 -328 65 -560 97 -1084 197 -694 99 -132 65 -132 97 -66 229 -332 163 -330 197 -66 327 -100 195 -98 327 -98 993 -132 697 -332 665 -166 199 -234 99 -168 199 -266 201 -66 199 -462 231 -298 195 -66 165 -884 165 -196 131 -66 365 -98 231 -98 329 -430 165 -66 1195 -300 133 -100 163 -132 65 -462 131 -196 163 -228 197 -992 163 -162 95 -824 131 -98 263 -98 97 -166 65 -98 131 -100 65 -496 131 -100 265 -134 199 -68 199 -98 329 -132 131 -66 983 -198 99 -132 295 -66 261 -460 329 -164 131 -426 65 -268 65 -466 131 -66 131 -230 263 -230 297 -200 895 -66 231 -460 1055 -134 433 -100 65 -66 231 -398 131 -400 97 -68 165 -330 297 -330 133 -396 99 -66 263 -262 97 -1644 295 -66 297 -100 729 -132 335 -68 491 -66 231 -326 393 -68 329 -166 65 -922 99 -1652 197 -266 265 -132 99 -432 265 -134 293 -134 65 -166 231 -232 199 -64 631 -400 163 -400 99 -66 131 -730 265 -100 195 -66 195 -330 163 -132 131 -166 67 -830 99 -66 297 -664 97 -134 65 -100 295 -66 133 -166 997 -66 299 -66 795 -98 493 -68 131 -166 131 -100 165 -198 67 -98 99 -598 65 -266 97 -268 199 -132 +RAW_Data: 65 -364 97 -298 97 -692 129 -264 261 -66 263 -564 297 -298 97 -232 131 -66 97 -66 361 -100 199 -68 433 -66 331 -68 333 -438 165 -598 99 -134 65 -100 65 -264 399 -266 67 -764 197 -232 297 -498 199 -858 65 -100 97 -130 131 -230 231 -230 97 -362 229 -66 497 -66 329 -132 65 -64 423 -98 393 -132 65 -664 65 -198 99 -68 331 -100 97 -332 133 -166 199 -98 693 -332 429 -100 265 -166 363 -100 167 -66 497 -100 1365 -202 333 -200 65 -132 199 -100 99 -330 131 -300 229 -832 65 -764 65 -132 263 -200 131 -1026 97 -196 97 -132 165 -98 525 -232 431 -66 659 -66 461 -98 97 -132 65 -100 261 -66 129 -66 163 -100 229 -364 131 -1560 165 -364 133 -268 165 -132 99 -200 65 -434 97 -68 263 -298 131 -230 199 -132 199 -100 165 -68 1829 -134 463 -100 265 -890 395 -364 131 -362 97 -260 97 -462 65 -66 457 -296 197 -268 263 -66 363 -132 895 -66 435 -164 403 -464 165 -928 163 -134 167 -400 263 -660 131 -100 63 -428 199 -132 199 -700 397 -232 335 -66 497 -166 1425 -66 231 -102 231 -134 99 -132 133 -134 99 -530 133 -66 131 -66 165 -166 199 -266 65 -100 131 -100 527 -300 925 -266 363 -530 131 -898 165 -66 199 -134 165 -232 525 -100 1509 -100 99 -200 99 -168 67 -300 163 -404 263 -132 67 -66 263 -664 65 -494 199 -100 165 -100 263 -264 131 -264 161 -66 65 -428 131 -296 163 -264 559 -166 597 -132 199 -498 65 -66 263 -162 163 -66 65 -66 131 -762 197 -162 65 -98 297 -262 163 -66 131 -130 97 -100 131 -564 199 -100 333 -166 165 -66 1653 -100 689 -296 131 -230 229 -526 65 -462 131 -100 197 -398 99 -264 133 -428 233 -134 265 -132 65 -200 97 -100 131 -100 265 -232 99 -232 429 -196 263 -166 669 -230 293 -298 561 -100 65 -100 229 -100 99 -830 99 -132 65 -1058 133 -564 99 -100 131 -826 165 -100 101 -100 65 -100 99 -398 329 -266 65 -66 557 -132 67 -132 627 -464 99 -66 163 -200 99 -66 99 -232 65 -66 165 -132 167 -266 99 -598 65 -432 65 -134 99 -330 197 -202 65 -266 133 -598 99 -68 163 -66 165 -66 1957 -430 393 -134 97 -134 97 -530 65 -428 161 -1150 65 -64 131 -594 229 -326 131 -196 197 -132 65 -566 297 -68 367 -64 1119 -464 163 -334 165 -134 163 -102 99 -66 199 -460 99 -100 99 -132 67 -266 99 -98 99 -532 197 -992 129 -362 231 -166 65 -132 133 -98 599 -98 795 -66 235 -100 333 -232 331 -98 99 -430 +RAW_Data: 131 -266 297 -232 231 -100 267 -266 397 -232 131 -132 133 -668 65 -98 99 -68 131 -398 1325 -66 333 -166 99 -100 199 -960 99 -66 231 -132 167 -134 199 -100 165 -100 495 -132 367 -332 99 -266 495 -66 65 -66 99 -66 65 -134 163 -134 199 -164 199 -98 531 -132 497 -100 65 -100 97 -530 99 -100 131 -68 131 -200 265 -102 97 -332 365 -66 265 -434 163 -68 97 -232 265 -132 65 -264 133 -198 497 -100 197 -68 729 -66 165 -330 165 -762 265 -430 397 -3844 67 -432 1197 -66 631 -66 521 -458 131 -132 197 -264 65 -922 163 -1586 99 -492 229 -530 65 -634 131 -134 65 -398 99 -398 363 -366 295 -1158 99 -134 65 -298 431 -432 97 -634 131 -66 133 -298 97 -466 99 -66 65 -332 65 -498 65 -962 133 -132 99 -464 233 -598 165 -196 199 -68 331 -66 231 -166 65 -200 133 -100 197 -162 393 -264 327 -1052 65 -164 163 -560 99 -98 63 -394 165 -132 99 -166 99 -100 97 -234 131 -1028 131 -66 99 -394 99 -164 97 -298 163 -66 359 -296 197 -66 499 -98 167 -462 695 -132 131 -134 97 -264 65 -100 265 -132 197 -896 195 -166 65 -262 99 -492 97 -196 99 -66 163 -164 97 -1414 133 -364 65 -132 99 -362 131 -164 195 -296 67 -334 197 -98 227 -66 265 -666 165 -430 167 -364 65 -98 97 -230 67 -364 133 -132 165 -134 65 -100 197 -230 97 -462 131 -296 195 -262 99 -98 327 -530 97 -464 99 -198 167 -234 97 -628 99 -266 131 -134 165 -166 65 -630 393 -100 197 -964 99 -400 163 -230 129 -264 97 -100 333 -332 165 -100 67 -66 199 -200 99 -166 133 -992 99 -66 163 -1590 65 -134 65 -366 331 -68 131 -1692 197 -166 99 -132 99 -100 429 -134 65 -100 367 -164 65 -166 329 -166 131 -234 99 -564 99 -100 99 -66 99 -100 263 -164 201 -436 131 -100 133 -268 231 -232 99 -366 65 -498 131 -100 131 -300 265 -432 199 -132 67 -100 163 -300 331 -100 263 -296 129 -68 97 -100 165 -234 99 -234 101 -66 67 -100 97 -1328 97 -264 99 -3316 261 -134 65 -300 65 -102 199 -98 99 -100 231 -1424 165 -164 195 -130 99 -396 129 -598 199 -264 97 -566 65 -762 99 -132 197 -464 131 -66 65 -494 97 -66 229 -66 525 -428 65 -428 229 -920 459 -556 97 -300 199 -100 99 -466 67 -1362 233 -430 131 -132 131 -294 197 -130 163 -98 163 -132 131 -1020 165 -132 165 -98 97 -232 329 -132 165 -130 129 -132 193 -592 197 -130 97 -2076 133 -164 163 -162 97 -98 63 -760 131 -100 +RAW_Data: 659 -560 97 -98 165 -66 65 -396 163 -662 97 -230 133 -598 97 -796 399 -132 165 -132 133 -66 197 -66 131 -398 297 -232 231 -364 199 -430 65 -100 165 -1096 231 -98 165 -98 197 -560 297 -132 65 -1260 429 -824 97 -68 97 -664 199 -296 495 -630 263 -966 99 -234 167 -66 65 -264 231 -68 197 -68 367 -66 163 -132 163 -430 233 -100 399 -134 167 -98 165 -98 99 -132 231 -230 193 -98 161 -396 261 -494 163 -1290 265 -664 65 -66 461 -100 563 -66 431 -100 1087 -198 165 -166 165 -100 899 -102 169 -200 99 -200 265 -66 231 -68 165 -100 133 -396 231 -366 99 -466 65 -234 497 -66 133 -200 133 -100 99 -100 65 -398 199 -264 101 -132 201 -366 195 -228 229 -134 625 -66 163 -66 293 -164 523 -100 97 -196 163 -396 229 -330 99 -98 65 -100 359 -562 195 -98 131 -98 229 -132 63 -822 65 -100 99 -432 229 -100 261 -66 327 -100 325 -198 2007 -132 261 -98 65 -100 397 -164 133 -66 99 -332 65 -98 65 -696 99 -298 231 -260 97 -296 199 -98 229 -396 163 -398 65 -398 197 -100 363 -66 797 -66 199 -100 1259 -132 331 -330 265 -800 197 -200 97 -166 99 -730 133 -432 99 -168 265 -1060 165 -96 129 -164 163 -66 97 -64 295 -68 397 -100 1091 -98 533 -364 261 -64 163 -920 99 -98 65 -164 195 -462 99 -98 97 -198 97 -100 261 -230 131 -594 263 -100 163 -196 129 -328 97 -98 297 -66 129 -66 131 -66 229 -228 461 -100 1127 -64 359 -1052 231 -298 131 -232 163 -428 65 -230 261 -66 97 -366 131 -68 197 -332 231 -460 229 -262 461 -166 629 -200 367 -198 1745 -528 65 -266 67 -166 131 -564 165 -134 135 -1358 197 -198 229 -98 165 -690 131 -196 197 -66 261 -164 263 -98 63 -132 65 -100 229 -100 197 -100 299 -66 465 -66 165 -68 165 -432 131 -530 63 -330 65 -198 97 -326 97 -66 65 -132 195 -498 65 -98 165 -260 95 -264 295 -130 131 -98 197 -526 65 -896 65 -100 429 -98 163 -132 527 -132 1189 -330 299 -166 165 -232 97 -66 99 -198 67 -168 133 -100 167 -200 165 -100 101 -630 199 -596 199 -1354 99 -198 163 -64 227 -132 163 -98 163 -132 425 -100 461 -262 259 -130 195 -98 65 -130 97 -166 129 -66 165 -98 97 -658 99 -1374 163 -132 165 -328 195 -98 99 -496 63 -132 67 -98 197 -130 99 -66 129 -98 1147 -66 1219 -1120 165 -166 263 -66 65 -100 197 -130 99 -164 99 -100 99 -262 199 -332 97 -66 233 -760 65 -464 363 -696 131 -68 97 -68 +RAW_Data: 329 -164 197 -302 429 -296 229 -232 99 -364 97 -98 131 -98 293 -164 133 -200 165 -270 233 -366 131 -400 399 -100 99 -464 133 -66 299 -198 297 -100 199 -66 365 -66 563 -464 425 -166 365 -166 101 -298 165 -166 99 -300 331 -264 329 -298 65 -200 99 -66 165 -1290 129 -594 99 -66 197 -262 197 -164 163 -100 229 -98 163 -96 1709 -100 65 -66 363 -132 99 -824 361 -1388 165 -98 99 -1952 99 -398 263 -200 201 -300 231 -134 265 -166 133 -66 399 -98 233 -232 461 -66 99 -132 165 -100 65 -298 135 -498 99 -394 297 -296 67 -66 165 -432 165 -98 97 -66 265 -66 563 -98 199 -66 265 -232 597 -100 691 -98 631 -132 99 -632 199 -730 97 -132 99 -528 361 -492 131 -296 65 -460 65 -66 97 -164 99 -262 263 -66 97 -98 263 -64 491 -66 851 -100 161 -132 97 -926 99 -100 99 -98 97 -632 163 -326 231 -290 99 -132 199 -66 199 -166 297 -68 167 -564 1059 -1018 1009 -1016 969 -1042 987 -1008 1005 -988 1013 -1032 483 -550 483 -550 225 -282 517 -522 261 -294 499 -560 495 -554 231 -298 269 -266 233 -298 495 -524 521 -520 263 -290 263 -268 271 -308 241 -274 507 -524 259 -260 521 -522 521 -520 523 -518 523 -518 527 -552 231 -298 265 -266 497 -522 263 -258 521 -524 261 -294 499 -558 233 -298 269 -274 271 -270 499 -520 261 -290 229 -296 267 -268 505 -560 233 -298 271 -272 507 -524 487 -550 487 -550 259 -288 225 -298 269 -306 239 -308 241 -276 507 -522 261 -258 259 -294 265 -268 269 -270 271 -304 239 -308 241 -274 273 -270 499 -520 489 -550 259 -288 229 -298 503 -558 231 -334 237 -274 997 -1008 1003 -984 1003 -1034 977 -1006 1013 -986 999 -1046 513 -514 511 -514 257 -280 513 -520 261 -292 497 -556 497 -554 233 -298 267 -268 233 -298 495 -522 527 -518 261 -290 263 -266 273 -306 243 -274 507 -524 261 -258 521 -522 523 -518 523 -516 523 -552 493 -552 231 -298 267 -266 497 -522 263 -256 523 -522 263 -294 497 -558 231 -300 269 -274 271 -272 497 -522 259 -290 227 -298 267 -270 505 -560 231 -300 271 -272 507 -522 521 -518 489 -548 259 -288 225 -298 269 -304 241 -308 241 -276 505 -524 259 -258 259 -294 265 -268 269 -270 271 -306 239 -308 241 -274 271 -270 499 -520 519 -518 261 -288 229 -298 503 -560 231 -300 269 -272 999 -1010 1013 -982 1007 -1018 973 -1016 999 -1010 987 -1044 481 -554 483 -520 273 -292 473 -552 245 -324 487 -532 501 -558 267 -268 269 -268 231 -298 495 -522 523 -520 259 -292 +RAW_Data: 263 -268 271 -308 241 -276 507 -522 261 -256 523 -522 523 -518 521 -518 525 -518 525 -554 229 -298 267 -268 495 -524 261 -258 521 -522 263 -294 499 -556 231 -300 271 -272 271 -270 499 -522 261 -290 227 -296 269 -270 505 -556 233 -298 271 -274 505 -524 521 -516 487 -548 259 -288 227 -298 271 -304 241 -308 241 -274 507 -524 259 -258 259 -294 265 -268 267 -270 271 -272 273 -308 241 -276 271 -270 499 -520 489 -550 259 -288 261 -264 505 -558 233 -300 269 -274 997 -1008 1003 -986 1005 -1002 1011 -1010 987 -1006 997 -1044 479 -546 513 -512 259 -280 511 -518 263 -292 497 -556 497 -556 231 -300 267 -266 233 -298 497 -522 523 -518 263 -290 263 -268 273 -306 241 -276 507 -522 261 -258 521 -522 523 -518 521 -518 525 -518 525 -554 231 -298 265 -266 499 -522 261 -258 521 -522 263 -294 499 -556 231 -300 271 -272 273 -270 499 -520 261 -288 229 -296 267 -270 505 -560 231 -300 271 -274 505 -524 489 -548 487 -548 261 -286 225 -298 271 -306 239 -308 241 -274 507 -524 259 -258 257 -296 267 -266 269 -270 271 -272 273 -308 239 -276 273 -268 497 -520 491 -550 261 -288 227 -296 505 -560 233 -298 269 -274 997 -1012 1009 -988 1007 -996 1009 -1008 1003 -982 999 -1044 513 -512 511 -514 257 -282 511 -520 261 -294 497 -556 497 -556 231 -300 265 -268 233 -298 495 -522 525 -518 263 -290 263 -268 271 -306 243 -274 509 -522 261 -256 523 -522 523 -518 491 -548 523 -552 493 -552 231 -298 265 -268 497 -520 261 -290 493 -522 263 -292 497 -558 231 -300 271 -272 271 -270 501 -520 261 -290 227 -296 267 -270 505 -558 233 -298 271 -274 507 -522 489 -550 487 -550 227 -318 225 -298 269 -304 241 -308 239 -276 507 -522 261 -258 259 -296 265 -266 269 -270 271 -304 239 -308 241 -274 273 -270 497 -520 491 -550 259 -288 227 -298 505 -558 233 -330 237 -274 999 -1012 979 -1016 1005 -1018 977 -1016 983 -1038 977 -1036 475 -550 509 -514 257 -276 503 -548 259 -288 491 -556 497 -556 231 -298 265 -268 233 -298 497 -522 491 -550 261 -292 263 -300 237 -308 241 -276 505 -524 261 -290 491 -522 521 -518 523 -516 525 -550 495 -554 231 -296 231 -300 497 -522 261 -290 491 -522 261 -294 497 -558 231 -334 237 -274 271 -270 499 -520 261 -290 229 -298 267 -268 505 -558 231 -300 269 -274 505 -524 489 -550 487 -548 259 -288 227 -298 269 -306 239 -308 241 -274 509 -524 259 -256 259 -296 265 -268 269 -268 271 -304 239 -308 241 -276 271 -270 497 -522 489 -550 +RAW_Data: 261 -288 227 -296 505 -558 231 -300 271 -272 1001 -1012 977 -1026 1007 -992 1011 -1008 1001 -1002 1001 -1014 513 -512 513 -514 257 -282 513 -520 263 -292 497 -556 497 -556 231 -300 267 -268 231 -298 495 -522 525 -518 261 -292 263 -266 271 -308 241 -276 507 -522 261 -288 491 -522 523 -518 523 -516 523 -520 525 -554 231 -296 265 -268 497 -522 259 -290 491 -522 263 -294 499 -556 265 -266 271 -274 271 -270 499 -520 261 -290 227 -298 267 -270 505 -558 233 -300 269 -274 505 -524 519 -516 487 -550 259 -286 259 -266 269 -306 241 -308 239 -276 507 -522 261 -256 259 -296 267 -266 269 -270 269 -272 273 -308 241 -276 271 -270 497 -520 521 -518 259 -290 259 -264 503 -560 265 -266 271 -274 999 -1014 977 -1016 1007 -984 1009 -1014 999 -1010 985 -1044 483 -520 519 -522 253 -276 529 -512 257 -282 517 -556 497 -554 231 -298 267 -268 233 -298 497 -522 521 -518 261 -290 265 -268 273 -308 241 -276 505 -524 259 -258 521 -520 525 -518 521 -518 525 -518 525 -552 231 -296 267 -268 497 -522 261 -256 523 -522 263 -294 499 -560 231 -298 269 -274 271 -270 497 -522 259 -292 227 -298 267 -268 505 -558 233 -300 271 -272 507 -522 521 -516 487 -550 259 -286 227 -298 271 -304 239 -308 241 -276 507 -520 261 -256 259 -296 265 -268 269 -268 273 -272 273 -306 241 -276 273 -268 497 -520 521 -516 261 -290 227 -298 505 -556 265 -266 271 -274 999 -1008 1005 -986 1005 -1000 1007 -1008 1001 -996 1009 -1016 515 -514 513 -514 259 -282 515 -520 263 -292 497 -556 499 -554 231 -300 265 -268 233 -298 497 -522 523 -518 261 -290 263 -302 239 -308 241 -276 505 -524 259 -258 521 -522 523 -518 523 -518 523 -518 525 -552 231 -298 265 -268 497 -524 259 -258 521 -524 261 -294 499 -556 233 -298 271 -272 273 -270 497 -522 259 -290 229 -296 267 -270 505 -558 231 -124104 99 -334 97 -794 165 -232 99 -136 595 -260 65 -66 163 -100 1353 -100 231 -134 233 -100 231 -962 99 -432 131 -134 231 -234 133 -98 99 -430 65 -100 99 -396 99 -1228 197 -66 97 -200 299 -100 265 -66 99 -262 99 -64 1447 -66 163 -98 65 -562 197 -66 129 -100 197 -164 65 -262 65 -264 65 -164 65 -1490 99 -66 99 -66 65 -166 197 -134 99 -66 131 -100 99 -66 97 -66 231 -266 465 -66 299 -66 461 -98 295 -132 65 -528 229 -164 129 -396 65 -962 133 -566 99 -198 163 -830 197 -100 201 -400 67 -66 99 -132 299 -66 463 -168 231 -66 433 -66 895 -956 65 -828 229 -468 +RAW_Data: 197 -100 131 -130 97 -132 295 -66 97 -430 133 -198 65 -526 727 -66 229 -262 163 -98 525 -66 853 -132 165 -66 399 -166 99 -268 397 -134 233 -66 67 -298 131 -1130 133 -100 65 -134 297 -198 329 -134 197 -66 129 -590 133 -164 131 -132 131 -132 131 -98 2973 -230 65 -664 165 -134 165 -432 99 -166 165 -496 201 -132 99 -100 197 -68 131 -632 67 -98 133 -132 695 -100 293 -100 131 -98 199 -66 297 -100 199 -100 335 -100 265 -430 165 -66 297 -664 99 -264 199 -98 165 -134 167 -200 99 -100 65 -98 99 -296 65 -164 163 -494 99 -100 267 -198 99 -426 199 -134 99 -232 131 -330 65 -134 131 -134 201 -100 463 -232 97 -296 1087 -100 363 -134 97 -132 197 -300 131 -234 233 -990 133 -232 65 -266 65 -264 199 -200 265 -396 65 -134 165 -66 165 -66 65 -330 231 -300 431 -198 331 -266 99 -232 131 -432 65 -266 131 -100 265 -66 599 -498 97 -98 65 -298 197 -98 227 -328 231 -232 163 -660 197 -132 65 -134 363 -66 197 -166 631 -66 361 -132 231 -132 427 -328 99 -898 199 -332 365 -98 199 -162 197 -230 97 -166 561 -198 263 -196 295 -100 65 -428 65 -98 99 -166 199 -132 131 -100 165 -98 131 -66 1161 -66 167 -166 529 -364 163 -460 231 -196 291 -296 65 -66 97 -398 65 -100 133 -658 165 -164 195 -230 99 -132 229 -98 129 -430 691 -68 165 -100 167 -66 435 -100 597 -66 331 -98 99 -298 263 -262 131 -492 129 -788 97 -428 133 -100 65 -100 65 -98 131 -998 199 -98 235 -100 965 -232 793 -98 861 -100 199 -68 529 -398 195 -960 397 -100 131 -266 201 -66 65 -98 99 -132 233 -168 261 -66 131 -428 165 -66 261 -528 65 -66 195 -166 261 -66 361 -164 525 -200 697 -364 97 -66 131 -558 163 -266 65 -298 331 -464 199 -100 165 -100 97 -66 65 -994 331 -166 131 -534 199 -300 67 -98 329 -266 163 -66 227 -66 133 -66 261 -100 559 -466 231 -260 197 -68 227 -98 97 -96 65 -296 163 -296 131 -164 195 -230 263 -66 393 -230 457 -134 131 -534 133 -630 99 -98 399 -100 265 -266 431 -134 67 -100 789 -1584 165 -624 131 -134 263 -396 99 -692 165 -98 165 -398 295 -66 99 -592 163 -132 131 -328 265 -66 231 -100 363 -98 335 -66 167 -98 499 -100 397 -68 131 -100 231 -100 165 -134 165 -1228 99 -66 233 -1386 63 -924 99 -130 131 -392 231 -166 133 -166 165 -198 501 -66 265 -66 299 -98 299 -100 299 -134 231 -68 165 -232 99 -66 65 -200 165 -100 +RAW_Data: 67 -132 199 -302 65 -1058 199 -798 133 -334 165 -894 65 -132 233 -164 329 -130 493 -66 893 -200 631 -100 1207 -984 1013 -1010 1017 -988 997 -1010 1013 -986 1007 -1032 257 -254 253 -292 265 -266 501 -524 525 -520 261 -294 265 -306 241 -276 507 -522 261 -256 521 -524 521 -518 261 -290 495 -558 497 -556 265 -264 267 -268 265 -264 497 -522 261 -292 261 -268 269 -274 273 -274 275 -276 273 -270 231 -296 265 -264 497 -522 527 -520 261 -294 267 -304 241 -276 273 -270 495 -520 261 -256 293 -264 269 -270 507 -556 265 -266 271 -274 507 -522 521 -516 517 -516 259 -256 291 -266 271 -272 273 -274 275 -276 507 -522 259 -256 259 -296 265 -268 269 -270 271 -270 273 -274 275 -276 507 -522 521 -514 519 -516 259 -254 291 -266 269 -274 511 -558 267 -266 991 -1010 1009 -1000 999 -974 1023 -1012 1009 -990 1007 -1032 225 -284 253 -292 263 -264 501 -524 525 -518 263 -296 265 -306 241 -276 507 -522 261 -256 521 -520 523 -518 261 -290 497 -556 499 -554 265 -266 1535 -556 1321 -340 201 -168 1009 -246 209 -304 1249 -320 489 -196 1129 -338 209 -316 1011 -562 197 -260 539 -66 219 -194 815 -260 515 -132 247 -144 825 -260 815 -272 1301 -262 519 -66 215 -230 533 -132 217 -178 1049 -134 213 -178 347 -208 507 -134 247 -142 511 -192 213 -94 519 -274 521 -278 793 -278 815 -278 521 -132 229 -154 503 -198 839 -228 1597 -262 259 -292 1553 -526 1593 -458 1103 -528 1345 -268 235 -298 1293 -260 523 -194 189 -122 525 -196 221 -94 805 -306 1041 -166 233 -144 493 -228 221 -72 1041 -238 253 -342 791 -314 375 -162 823 -256 1019 -166 213 -154 507 -194 213 -124 815 -266 505 -196 221 -122 407 -166 391 -134 983 -262 219 -312 1213 -360 479 -166 1191 -322 223 -262 1043 -560 229 -166 1035 -206 455 -330 1007 -332 469 -198 837 -196 251 -92 471 -264 519 -330 439 -100 419 -132 421 -132 439 -100 453 -230 549 -330 739 -332 769 -302 347 -210 1025 -98 285 -180 603 -416 619 -404 757 -340 305 -226 463 -134 267 -196 313 -192 1175 -512 1563 -522 1279 -288 253 -290 1553 -524 1579 -492 1075 -528 655 -306 343 -188 373 -164 647 -410 457 -170 615 -344 767 -308 469 -100 275 -178 361 -174 621 -416 625 -418 355 -204 593 -446 583 -466 289 -224 355 -202 327 -206 463 -168 287 -106 399 -134 753 -338 757 -326 283 -230 331 -204 1027 -66 277 -210 487 -100 1219 -324 249 -220 1093 -558 229 -132 995 -282 449 -264 1089 -304 475 -132 1017 -446 483 -68 1235 -338 211 -252 515 -102 243 -176 +RAW_Data: 759 -296 497 -132 213 -214 333 -202 329 -204 331 -240 301 -206 369 -170 595 -442 609 -406 605 -440 347 -194 515 -164 211 -154 1041 -198 193 -180 1503 -516 1361 -258 291 -232 1083 -540 1557 -488 1303 -294 253 -288 1549 -524 393 -172 343 -174 533 -132 617 -264 629 -444 479 -200 217 -144 421 -106 1049 -174 243 -140 1025 -172 855 -166 229 -122 801 -314 1045 -134 239 -178 493 -164 217 -124 1047 -164 221 -122 525 -228 225 -100 457 -66 1041 -226 833 -196 1891 -298 523 -302 411 -100 1011 -290 477 -238 1123 -298 491 -66 1033 -478 1797 -320 225 -162 1001 -242 455 -300 1035 -296 231 -332 767 -302 345 -188 369 -194 567 -452 473 -172 233 -160 471 -208 279 -70 483 -342 605 -432 1511 -172 501 -352 1255 -526 1545 -514 1329 -298 263 -266 1063 -538 1553 -488 615 -310 385 -170 391 -136 621 -404 647 -410 389 -160 405 -132 997 -134 279 -178 987 -134 893 -166 241 -154 409 -130 667 -384 477 -200 613 -308 747 -306 483 -134 283 -146 377 -156 779 -298 795 -304 311 -188 797 -302 505 -502 815 -268 301 -240 305 -240 305 -242 271 -236 561 -470 777 -292 283 -260 1285 -298 267 -274 1573 -520 1483 -70 237 -322 219 -126 991 -314 449 -264 1045 -330 235 -304 1307 -340 209 -244 985 -100 475 -430 603 -426 347 -188 375 -176 513 -168 605 -288 367 -170 1365 -268 1527 -516 1471 -138 497 -386 1233 -486 1571 -514 1339 -262 291 -264 303 -244 821 -208 555 -496 543 -464 545 -98 249 -142 417 -140 1043 -140 241 -166 597 -424 813 -280 519 -100 675 -268 601 -442 515 -132 251 -144 367 -168 1053 -132 215 -178 387 -140 513 -206 211 -108 513 -238 1305 -188 867 -190 213 -94 1043 -280 1013 -276 2453 -282 1009 -262 787 -260 515 -260 1055 -232 225 -62 471 -100 489 -292 491 -196 1095 -298 233 -302 1329 -340 245 -176 1017 -136 459 -356 1043 -198 235 -320 1559 -550 1509 -206 253 -284 1277 -296 231 -298 1365 -276 1527 -528 1473 -100 505 -416 1195 -524 553 -302 739 -334 469 -196 251 -92 499 -234 263 -310 677 -324 1031 -264 165 -132 471 -568 201 -338 473 -558 499 -554 231 -300 233 -302 231 -300 497 -522 261 -292 229 -298 271 -306 239 -306 241 -274 273 -270 233 -298 231 -298 497 -556 493 -518 263 -294 265 -304 241 -276 273 -270 497 -520 261 -290 225 -298 267 -270 505 -558 233 -298 271 -274 505 -522 491 -550 487 -546 227 -286 259 -296 301 -114218 231 -100 97 -402 397 -298 99 -100 363 -164 201 -132 699 -100 1193 -100 199 -100 167 -66 429 -200 99 -1060 99 -400 99 -332 65 -168 +RAW_Data: 199 -232 199 -100 99 -630 67 -962 231 -198 65 -366 427 -100 231 -102 299 -100 299 -66 593 -132 63 -98 457 -426 165 -724 261 -98 163 -164 263 -98 99 -230 195 -862 65 -132 133 -498 131 -266 65 -66 197 -298 663 -298 829 -132 299 -460 197 -930 99 -66 399 -132 99 -960 165 -134 231 -132 99 -66 395 -726 67 -132 99 -132 231 -132 597 -98 593 -66 133 -198 1131 -98 267 -298 97 -724 525 -196 623 -132 199 -98 295 -98 65 -98 97 -66 197 -264 497 -98 163 -134 233 -100 297 -198 131 -568 297 -100 99 -66 99 -98 465 -100 97 -100 199 -398 1051 -1046 951 -1046 967 -1018 1009 -1004 1003 -1012 993 -1046 237 -288 465 -554 245 -290 253 -286 247 -276 509 -558 497 -554 497 -522 523 -518 259 -254 519 -520 263 -292 263 -266 269 -306 239 -308 241 -274 273 -270 499 -520 487 -550 261 -288 493 -554 231 -296 267 -306 241 -276 271 -270 233 -298 495 -522 261 -294 493 -556 497 -554 495 -554 231 -296 265 -266 497 -524 261 -290 227 -298 267 -268 505 -558 231 -332 239 -272 507 -522 521 -518 487 -550 259 -286 227 -296 271 -304 241 -308 241 -274 507 -522 261 -258 259 -296 265 -266 269 -270 271 -272 271 -308 241 -274 507 -522 489 -548 259 -256 259 -296 499 -558 229 -298 269 -306 241 -274 999 -1012 981 -1026 975 -1024 1011 -980 995 -1012 1019 -1012 261 -274 501 -514 259 -282 253 -292 265 -268 507 -556 497 -556 497 -522 523 -520 227 -286 519 -520 261 -292 261 -266 271 -308 239 -306 241 -274 273 -270 497 -520 489 -550 261 -288 493 -556 231 -294 267 -304 241 -274 273 -272 233 -298 495 -520 261 -292 495 -558 493 -556 493 -552 231 -298 265 -268 499 -522 261 -290 227 -296 267 -270 505 -560 231 -298 269 -274 505 -524 489 -552 487 -550 227 -318 225 -298 269 -304 241 -306 241 -276 507 -522 261 -256 259 -296 265 -268 269 -270 271 -304 239 -308 241 -274 507 -524 487 -550 259 -254 259 -296 499 -558 231 -298 267 -304 241 -276 999 -1014 979 -1016 1005 -988 1007 -1014 1001 -1014 993 -1012 273 -288 465 -552 247 -290 251 -286 247 -278 507 -556 495 -556 497 -522 527 -518 227 -286 517 -522 261 -292 229 -300 269 -304 241 -306 241 -276 273 -270 497 -520 487 -550 261 -290 491 -556 231 -296 267 -304 241 -274 273 -270 233 -298 495 -522 261 -292 495 -556 497 -552 495 -554 231 -296 265 -268 499 -522 259 -292 227 -296 267 -268 505 -560 231 -300 271 -274 505 -524 489 -550 485 -550 227 -318 225 -298 269 -304 241 -308 241 -274 +RAW_Data: 507 -522 261 -258 259 -296 231 -302 267 -270 271 -304 239 -308 241 -276 505 -524 487 -550 227 -288 257 -296 499 -558 229 -298 269 -304 241 -276 997 -1012 981 -1026 977 -1026 977 -1014 1001 -1014 993 -1046 235 -288 495 -528 239 -326 219 -290 253 -288 485 -564 501 -556 497 -522 493 -552 227 -286 515 -522 261 -292 231 -300 269 -304 239 -308 241 -274 273 -270 499 -520 489 -550 259 -290 489 -556 231 -296 267 -306 239 -276 273 -270 233 -298 497 -520 261 -292 493 -558 495 -554 495 -552 231 -298 233 -300 497 -522 261 -290 227 -296 267 -270 505 -558 231 -334 237 -272 507 -522 491 -552 485 -552 227 -318 225 -296 269 -304 239 -308 241 -276 505 -524 261 -290 227 -294 231 -302 269 -268 271 -304 239 -308 241 -276 507 -524 487 -552 227 -286 259 -294 501 -556 229 -298 269 -306 241 -276 997 -1010 1003 -986 1007 -998 1009 -1008 1001 -986 1001 -1048 227 -276 503 -550 259 -254 257 -298 267 -270 505 -558 497 -554 497 -524 521 -518 229 -286 517 -522 263 -290 263 -266 269 -306 241 -306 241 -274 273 -270 497 -520 521 -516 259 -290 493 -556 231 -296 269 -304 241 -274 273 -270 233 -298 495 -524 261 -290 493 -558 495 -552 497 -552 231 -298 265 -266 497 -522 259 -292 227 -298 267 -270 505 -558 231 -300 269 -274 505 -524 489 -550 487 -550 229 -286 257 -296 269 -304 241 -308 241 -276 507 -520 261 -258 259 -294 267 -266 269 -270 269 -306 239 -306 241 -276 507 -524 489 -548 259 -256 257 -294 501 -558 231 -296 269 -306 239 -276 999 -1012 979 -1028 975 -1024 1007 -1000 1001 -1000 1007 -1012 259 -280 507 -518 259 -290 225 -298 267 -270 503 -558 497 -554 497 -524 525 -518 227 -286 517 -522 261 -292 263 -266 269 -306 239 -308 241 -276 271 -270 499 -520 487 -550 259 -288 493 -556 229 -298 267 -304 241 -274 273 -270 235 -298 495 -520 261 -292 495 -556 495 -556 493 -554 231 -298 233 -300 497 -520 261 -290 227 -296 267 -270 505 -558 233 -298 271 -272 507 -522 491 -550 485 -550 227 -318 227 -296 271 -304 239 -308 241 -276 507 -522 261 -258 259 -294 265 -268 267 -270 271 -304 239 -308 241 -274 507 -524 489 -550 227 -286 257 -296 499 -558 231 -298 267 -304 241 -274 999 -1010 1001 -1004 983 -1004 1011 -1008 1003 -998 1003 -1018 257 -282 509 -518 259 -290 225 -298 267 -270 503 -560 497 -558 497 -520 521 -520 227 -286 517 -522 259 -292 263 -266 271 -304 239 -308 241 -276 273 -268 499 -522 487 -550 259 -288 491 -556 229 -298 267 -304 241 -274 +RAW_Data: 273 -272 233 -296 495 -522 261 -294 493 -556 493 -554 495 -556 229 -298 265 -266 499 -520 261 -290 227 -296 267 -270 505 -558 233 -298 271 -272 507 -524 489 -548 489 -550 227 -316 227 -296 269 -306 239 -308 241 -274 507 -524 259 -258 259 -294 265 -266 269 -270 271 -304 239 -308 239 -276 507 -524 489 -550 227 -286 257 -294 501 -556 231 -296 269 -306 239 -276 999 -1012 981 -1018 1005 -980 1009 -1018 1003 -1008 977 -1038 255 -276 499 -516 259 -282 253 -290 265 -268 505 -556 499 -554 497 -520 525 -518 227 -288 517 -522 261 -292 229 -300 269 -304 239 -308 241 -276 273 -268 497 -522 489 -550 261 -288 489 -556 229 -296 267 -304 241 -276 271 -270 233 -300 495 -522 261 -292 495 -556 495 -552 495 -554 229 -298 231 -300 499 -522 261 -290 227 -296 267 -268 507 -558 231 -298 271 -272 505 -524 489 -552 487 -550 227 -318 225 -296 267 -304 239 -308 241 -274 507 -524 261 -290 227 -296 231 -300 269 -270 269 -306 239 -306 241 -274 505 -524 489 -550 227 -320 225 -296 499 -556 231 -298 267 -306 241 -274 999 -1012 979 -1016 1005 -982 1009 -1014 1003 -1010 979 -1044 237 -292 473 -552 247 -284 245 -276 277 -276 501 -546 515 -548 485 -550 487 -548 225 -286 515 -520 263 -290 263 -266 269 -306 239 -306 243 -274 273 -270 495 -520 491 -548 261 -288 491 -554 231 -296 267 -304 241 -276 273 -270 233 -298 495 -522 261 -290 495 -556 495 -520 527 -554 229 -298 267 -268 497 -522 259 -258 259 -296 269 -270 505 -558 231 -300 269 -274 507 -522 521 -514 489 -548 259 -256 289 -264 271 -272 273 -308 241 -276 505 -522 259 -258 257 -296 267 -266 271 -270 269 -272 273 -306 241 -274 507 -522 521 -516 259 -254 259 -296 501 -556 231 -296 269 -306 241 -276 1001 -1010 979 -1016 1003 -986 1009 -1014 1001 -1006 1011 -1006 253 -276 497 -516 259 -282 255 -292 267 -270 507 -556 497 -554 499 -522 523 -518 259 -254 517 -522 261 -292 265 -266 269 -272 273 -308 243 -274 273 -268 497 -522 521 -516 259 -288 491 -554 231 -298 267 -306 241 -276 273 -270 231 -298 493 -522 261 -292 495 -556 495 -520 527 -554 231 -296 267 -268 497 -520 261 -290 229 -296 267 -270 505 -558 233 -298 271 -272 507 -524 489 -550 487 -548 259 -252 291 -264 271 -272 273 -308 241 -274 507 -520 261 -258 259 -296 265 -266 269 -270 271 -270 273 -308 241 -276 505 -524 487 -548 259 -256 255 -298 501 -556 231 -298 267 -306 241 -276 999 -1004 1007 -988 1009 -998 1011 -1012 991 -982 1025 -1010 +RAW_Data: 269 -290 465 -554 247 -290 251 -286 247 -278 505 -556 497 -554 497 -522 525 -516 227 -286 519 -522 261 -292 261 -266 271 -304 239 -308 241 -276 273 -270 497 -520 489 -550 259 -256 521 -556 231 -296 269 -306 241 -274 273 -270 233 -296 495 -522 261 -292 495 -556 495 -520 527 -554 231 -296 267 -266 499 -518 261 -290 229 -298 267 -268 507 -556 233 -298 271 -272 507 -526 487 -550 485 -548 259 -254 291 -264 271 -272 275 -308 241 -274 505 -522 259 -258 259 -296 265 -268 267 -270 271 -272 273 -274 273 -276 507 -520 521 -516 259 -254 291 -262 501 -556 231 -298 269 -306 241 -276 1001 -1010 979 -1018 1007 -982 1009 -1016 999 -984 1019 -1008 257 -274 499 -548 257 -254 257 -296 267 -270 505 -558 497 -554 499 -520 523 -516 259 -256 517 -524 261 -290 263 -266 271 -270 275 -274 275 -274 273 -268 499 -518 519 -516 261 -288 493 -524 263 -296 269 -270 275 -276 271 -270 233 -298 495 -518 263 -292 493 -524 529 -522 527 -522 265 -294 265 -266 497 -520 261 -258 293 -264 267 -270 507 -556 267 -264 271 -274 507 -522 523 -516 485 -548 259 -254 291 -264 271 -272 275 -274 275 -276 507 -520 259 -256 257 -296 265 -268 271 -270 271 -272 273 -272 275 -276 505 -520 523 -514 257 -256 289 -264 503 -524 263 -296 269 -272 275 -276 999 -1004 1001 -998 1019 -972 1007 -1006 1001 -996 1009 -1020 257 -280 511 -520 259 -256 293 -262 269 -272 505 -556 497 -554 497 -522 523 -518 259 -252 517 -522 261 -292 263 -266 273 -272 275 -272 277 -274 271 -236 529 -522 521 -514 261 -256 523 -522 297 -264 269 -270 275 -276 273 -236 265 -264 529 -520 261 -290 497 -522 527 -520 529 -552 265 -264 267 -234 531 -520 259 -258 291 -264 269 -272 507 -554 265 -266 271 -274 507 -522 519 -514 521 -514 259 -256 291 -266 271 -272 275 -274 275 -274 507 -522 259 -256 289 -264 265 -270 269 -270 269 -272 273 -274 275 -276 505 -522 519 -514 259 -254 291 -264 501 -522 299 -264 269 -272 277 -276 999 -978 1045 -958 1011 -1024 1007 -978 1019 -978 1013 -1008 271 -292 503 -490 283 -288 249 -278 273 -268 501 -522 529 -520 531 -520 525 -516 257 -254 519 -520 263 -292 265 -266 271 -274 273 -274 275 -276 269 -236 529 -520 521 -516 259 -256 523 -522 297 -264 269 -272 277 -274 273 -236 265 -262 527 -522 259 -292 495 -524 529 -520 529 -518 297 -264 267 -234 531 -520 259 -256 293 -264 269 -270 505 -556 267 -264 271 -274 507 -520 521 -518 517 -514 259 -256 293 -266 271 -270 +RAW_Data: 275 -306 241 -276 507 -520 259 -258 257 -296 267 -266 269 -268 273 -272 273 -274 275 -274 505 -524 521 -514 259 -254 289 -264 501 -556 231 -298 269 -270 277 -276 997 -980 1011 -996 1009 -990 1045 -980 999 -1010 1015 -1008 271 -256 501 -536 251 -272 245 -276 277 -286 499 -558 499 -554 497 -522 523 -516 259 -254 517 -522 261 -292 265 -266 271 -272 273 -274 275 -274 271 -236 531 -520 521 -516 259 -256 523 -524 263 -296 269 -270 277 -276 273 -236 265 -262 527 -520 263 -292 495 -556 497 -518 527 -552 263 -266 267 -268 497 -520 261 -258 291 -264 269 -268 507 -554 267 -264 271 -276 507 -522 521 -514 519 -516 259 -254 293 -264 271 -272 273 -274 275 -274 507 -522 259 -256 291 -262 265 -268 271 -270 271 -272 273 -272 275 -276 505 -520 521 -516 259 -254 289 -264 501 -526 263 -298 267 -272 275 -276 999 -1004 1003 -986 1007 -1000 1013 -1010 985 -1014 1015 -1006 275 -254 501 -524 283 -256 251 -284 275 -272 501 -554 499 -554 497 -520 525 -516 259 -254 517 -520 261 -292 263 -268 271 -274 273 -274 275 -276 271 -236 529 -520 521 -516 259 -256 523 -524 295 -264 269 -272 277 -274 273 -270 231 -264 527 -522 263 -258 527 -522 527 -520 529 -552 265 -266 265 -268 497 -520 259 -258 293 -262 269 -272 507 -556 265 -264 271 -276 507 -520 521 -516 519 -514 259 -254 293 -264 271 -272 277 -274 275 -274 507 -522 259 -256 257 -294 267 -268 269 -270 271 -272 273 -274 275 -274 507 -522 519 -516 259 -254 289 -264 503 -522 263 -298 267 -272 277 -276 999 -1008 1009 -984 1009 -984 1005 -1012 999 -1012 1013 -1004 255 -274 499 -544 257 -252 289 -262 269 -270 507 -556 497 -552 497 -520 525 -518 259 -254 519 -520 261 -294 263 -266 271 -272 275 -274 275 -274 273 -234 531 -520 519 -516 261 -256 523 -522 263 -298 269 -272 275 -276 273 -270 231 -264 527 -522 261 -292 493 -524 359 -91592 331 -232 65 -2392 131 -496 329 -2040 231 -66 201 -200 133 -920 65 -232 97 -100 491 -100 195 -198 131 -196 295 -98 197 -66 655 -166 131 -428 99 -296 65 -330 163 -66 163 -98 97 -66 99 -1778 165 -66 195 -854 129 -494 297 -98 97 -66 197 -260 261 -262 165 -132 293 -66 423 -166 9931 -462 67 -762 99 -268 199 -862 65 -760 165 -232 131 -434 133 -1126 363 -132 165 -134 67 -332 97 -466 97 -66 265 -100 133 -100 231 -1590 65 -334 199 -98 67 -1592 201 -100 131 -66 165 -164 97 -1714 327 -66 329 -98 595 -100 993 -132 65 -100 165 -232 65 -100 +RAW_Data: 97 -100 293 -330 99 -98 163 -458 99 -196 131 -66 163 -426 167 -298 99 -462 99 -66 67 -462 229 -66 195 -100 757 -66 425 -66 427 -100 529 -134 265 -1430 131 -302 97 -66 97 -132 65 -66 229 -100 97 -1530 133 -264 563 -66 1165 -200 1025 -198 167 -1294 265 -132 197 -962 131 -300 131 -66 99 -366 165 -198 167 -830 197 -230 195 -434 299 -98 965 -132 265 -894 99 -98 65 -860 461 -66 97 -398 67 -928 165 -200 199 -66 199 -1456 197 -334 133 -132 501 -198 1579 -66 1151 -132 463 -98 10275 -528 97 -966 263 -760 65 -264 197 -134 65 -512 479 -526 455 -572 443 -572 437 -550 451 -548 447 -552 481 -526 457 -542 483 -538 469 -548 449 -548 447 -554 449 -1048 975 -558 463 -548 451 -1046 449 -554 953 -1054 981 -540 443 -550 475 -1014 985 -1052 981 -516 475 -1048 473 -520 487 -534 463 -548 943 -1044 969 -554 449 -558 465 -1042 979 -520 485 -514 473 -548 453 -1042 973 -1048 981 -1014 483 -546 971 -522 473 -556 445 -1032 493 -51306 533 -514 457 -546 451 -550 477 -522 475 -542 471 -554 453 -538 467 -548 451 -546 447 -550 477 -524 473 -554 451 -540 469 -1044 977 -554 451 -546 441 -1042 483 -514 975 -1048 977 -522 493 -516 481 -1046 977 -1018 979 -552 453 -1042 481 -520 485 -516 471 -550 983 -1014 981 -546 477 -518 489 -1012 975 -554 451 -544 467 -550 451 -1042 975 -1050 949 -1046 483 -548 941 -554 483 -514 469 -1046 447 -51364 513 -518 451 -554 451 -544 469 -548 451 -546 481 -514 475 -522 475 -554 443 -572 443 -548 453 -546 479 -514 477 -554 447 -1050 975 -522 493 -512 483 -1040 471 -538 969 -1032 985 -534 467 -1046 977 -528 485 -1016 965 -1042 481 -524 489 -522 973 -524 493 -514 481 -1040 969 -1050 979 -1016 481 -514 475 -552 977 -522 479 -1028 493 -512 481 -546 975 -520 485 -514 473 -548 453 -544 481 -1016 981 -51834 519 -526 465 -514 481 -546 479 -514 473 -522 471 -558 487 -514 469 -548 451 -546 479 -514 475 -522 471 -538 471 -536 485 -1048 961 -546 445 -552 483 -1016 479 -536 965 -1042 977 -534 475 -1042 465 -548 979 -1014 485 -516 977 -1042 479 -514 1005 -1018 975 -1018 483 -544 975 -520 473 -1058 471 -516 975 -548 453 -546 479 -516 479 -522 471 -1052 985 -520 489 -1006 1005 -528 459 -1050 479 -518 489 -51332 483 -542 453 -546 445 -550 477 -522 483 -554 449 -554 461 -514 483 -548 445 -552 441 -588 447 -548 441 -550 455 -548 481 -1042 967 -540 441 -552 481 -1024 489 -514 975 -1034 971 -1050 973 -548 451 -548 447 -1048 485 -540 +RAW_Data: 453 -542 467 -548 945 -1048 981 -544 449 -1056 453 -546 481 -516 973 -554 449 -544 469 -1046 975 -526 487 -508 485 -1038 489 -512 483 -516 479 -522 1001 -508 483 -1036 983 -514 475 -51832 491 -574 411 -604 399 -618 389 -618 385 -622 383 -610 415 -578 411 -602 437 -552 455 -550 449 -554 445 -584 445 -546 441 -1046 981 -522 485 -546 447 -1054 451 -546 973 -1052 953 -1046 965 -1042 977 -556 451 -542 467 -514 483 -1040 969 -1050 479 -532 961 -546 445 -552 481 -520 485 -516 473 -548 453 -546 481 -516 481 -522 475 -1046 481 -532 961 -1044 481 -530 461 -554 449 -524 987 -1040 969 -1052 449 -51326 525 -532 465 -548 451 -548 445 -552 443 -586 431 -546 477 -524 491 -514 481 -546 445 -552 441 -554 485 -516 473 -548 487 -1010 977 -554 451 -540 469 -1042 475 -508 1007 -1034 967 -1042 477 -518 983 -516 479 -524 487 -536 473 -1018 481 -526 987 -540 479 -516 475 -524 485 -540 453 -544 469 -1044 975 -526 483 -1014 505 -518 981 -1010 473 -556 485 -514 469 -548 451 -546 971 -542 483 -520 485 -1010 493 -512 975 -51842 491 -606 339 -662 333 -652 357 -654 385 -628 357 -642 377 -604 403 -622 391 -584 417 -590 421 -614 409 -574 439 -554 421 -1114 909 -578 415 -578 449 -1094 423 -550 975 -1034 969 -1038 477 -522 493 -514 975 -554 483 -1012 967 -1048 977 -518 481 -1028 987 -510 479 -1034 1005 -520 485 -534 465 -1014 1007 -492 517 -1012 999 -514 483 -1016 487 -520 975 -1060 949 -1050 457 -550 479 -530 467 -51296 517 -552 451 -578 421 -570 447 -572 407 -592 427 -584 417 -586 417 -578 415 -576 445 -576 447 -546 447 -568 465 -550 453 -1046 977 -510 467 -542 479 -1050 449 -542 973 -1052 483 -518 973 -514 483 -546 447 -552 483 -520 471 -1036 471 -516 1011 -1012 487 -506 1017 -510 471 -548 451 -1042 475 -510 483 -542 487 -506 983 -1036 987 -1046 975 -1020 979 -516 483 -1042 973 -1028 997 -512 471 -550 487 -51298 65 -1910 229 -230 99 -66 165 -922 97 -164 197 -66 131 -426 65 -68 231 -264 95 -66 361 -196 1023 -66 227 -98 195 -66 229 -98 4711 -100 233 -98 99 -66 1025 -66 10443 -130 233 -168 465 -66 2057 -100 6537 -66 821 -132 1841 -98 165 -98 7675 -66 1343 -232 67 -132 131 -134 329 -100 365 -132 3561 -66 297 -134 1691 -100 861 -66 497 -66 1359 -66 197 -198 429 -66 929 -66 2675 -100 261 -98 99 -98 459 -166 197 -66 195 -130 625 -98 295 -132 455 -66 391 -130 197 -132 5171 -66 1597 -66 1085 -68 1025 -66 565 -100 131 -132 4741 -66 559 -66 2343 -98 +RAW_Data: 4573 -66 2455 -98 2333 -130 5301 -66 531 -66 1895 -66 163 -68 5167 -98 591 -100 1521 -166 7219 -100 2149 -100 1443 -98 1149 -66 9647 -66 5157 -100 1321 -164 917 -100 2083 -132 7551 -134 165 -68 1169 -100 1263 -68 3619 -166 963 -100 1229 -198 2393 -68 1661 -98 2109 -66 131 -68 299 -100 5029 -66 957 -100 1185 -66 1653 -98 4925 -66 1201 -66 1827 -96 163 -132 501 -66 165 -66 763 -100 163 -98 821 -66 4555 -264 1353 -132 499 -100 163 -66 1749 -100 1063 -132 1577 -100 763 -68 331 -102 299 -100 429 -66 265 -234 331 -66 1963 -68 627 -132 231 -102 763 -66 497 -66 265 -68 2061 -68 463 -66 297 -100 1393 -430 295 -100 823 -98 97 -100 631 -102 529 -66 1251 -68 1195 -66 361 -66 195 -100 4929 -134 231 -100 561 -66 829 -68 893 -66 6729 -66 901 -68 1259 -66 65 -166 131 -232 65 -100 131 -132 131 -100 131 -564 661 -98 329 -66 199 -66 263 -66 165 -68 97 -68 363 -566 197 -1064 395 -862 133 -200 99 -198 199 -596 229 -994 295 -928 163 -130 395 -98 229 -66 99 -98 997 -66 133 -566 165 -232 99 -100 99 -100 99 -530 99 -66 133 -66 165 -764 99 -398 199 -296 165 -96 129 -328 131 -560 227 -298 99 -100 465 -100 397 -66 67 -98 331 -132 199 -232 201 -438 263 -166 329 -166 463 -632 131 -398 99 -134 131 -1590 263 -66 67 -196 163 -298 195 -1220 227 -292 297 -132 591 -298 295 -100 493 -66 163 -162 325 -134 197 -64 197 -164 97 -460 65 -166 195 -266 97 -164 327 -264 229 -234 165 -66 163 -630 299 -532 197 -796 131 -100 65 -466 65 -98 99 -328 361 -66 197 -130 295 -66 197 -692 99 -166 99 -166 99 -66 131 -100 99 -66 165 -134 233 -130 267 -498 265 -66 167 -1192 67 -364 463 -132 133 -300 197 -100 99 -298 629 -66 331 -132 629 -134 65 -132 231 -100 65 -1392 65 -166 131 -230 199 -466 97 -100 233 -730 263 -296 99 -98 133 -100 163 -134 67 -100 131 -98 229 -100 231 -132 497 -264 989 -164 233 -98 65 -102 495 -264 197 -826 99 -496 133 -132 365 -64 131 -66 99 -98 65 -132 65 -100 329 -66 165 -100 131 -700 165 -492 231 -130 195 -130 131 -230 197 -200 691 -132 99 -66 331 -264 165 -100 131 -730 131 -200 131 -498 99 -100 197 -100 131 -66 165 -68 165 -534 65 -498 401 -166 65 -592 65 -98 65 -100 131 -66 231 -132 133 -100 299 -198 133 -164 265 -100 433 -66 429 -330 631 -98 163 -66 265 -232 65 -66 199 -100 165 -198 233 -66 131 -234 67 -564 +RAW_Data: 163 -400 165 -464 131 -362 561 -332 263 -98 133 -132 165 -100 661 -232 591 -328 65 -98 133 -368 131 -560 97 -100 165 -464 131 -296 129 -558 131 -98 99 -196 65 -98 163 -100 97 -394 261 -558 259 -98 97 -426 299 -364 365 -66 599 -166 363 -428 231 -134 625 -98 359 -394 195 -164 197 -66 97 -98 263 -490 195 -98 261 -460 163 -100 199 -330 131 -198 163 -66 293 -66 885 -100 1315 -234 333 -234 365 -200 133 -596 197 -166 295 -100 197 -232 165 -66 131 -336 197 -268 231 -100 99 -696 163 -262 331 -132 197 -132 131 -132 361 -100 525 -66 195 -132 227 -232 163 -262 1233 -68 797 -98 427 -98 231 -200 331 -132 129 -98 163 -66 129 -100 97 -100 5243 -198 1295 -66 197 -66 165 -66 499 -23298 65 -68 131 -564 329 -100 133 -298 101 -166 199 -300 65 -764 133 -266 297 -130 165 -132 265 -66 2793 -198 4161 -66 1747 -100 1729 -98 603 -132 363 -530 99 -266 129 -100 231 -396 129 -198 133 -98 991 -132 397 -462 131 -330 295 -132 197 -134 99 -262 99 -232 229 -268 263 -1448 229 -68 65 -198 99 -134 165 -996 429 -396 631 -632 727 -98 297 -100 199 -134 65 -332 65 -234 165 -362 99 -428 263 -232 67 -1158 165 -196 129 -228 131 -132 195 -98 163 -698 65 -234 531 -728 295 -130 97 -98 229 -366 499 -66 99 -66 131 -66 297 -232 165 -100 65 -400 233 -66 265 -134 131 -134 165 -132 233 -134 97 -300 397 -102 65 -98 99 -98 6595 -132 65 -164 131 -100 529 -66 2157 -66 163 -100 99 -466 99 -530 163 -166 195 -264 197 -66 199 -66 199 -100 11433 -164 1055 -562 497 -134 233 -100 399 -100 131 -66 163 -234 733 -264 163 -236 65 -430 67 -332 133 -132 133 -66 465 -66 603 -98 265 -98 199 -66 3567 -100 391 -166 525 -132 1055 -98 627 -264 333 -100 795 -66 165 -66 297 -66 393 -134 263 -100 1317 -98 131 -98 529 -98 293 -66 99 -66 163 -100 493 -64 265 -164 231 -100 199 -132 265 -66 265 -100 99 -134 199 -132 431 -100 365 -132 231 -68 201 -132 891 -100 831 -98 167 -100 1191 -64 329 -66 393 -98 131 -64 131 -98 229 -132 2693 -132 10455 -66 297 -98 631 -100 431 -100 433 -98 165 -134 65 -100 65 -68 863 -132 499 -100 267 -134 99 -66 989 -66 657 -100 757 -594 395 -66 199 -66 463 -330 663 -264 4219 -66 851 -98 129 -132 915 -66 129 -66 363 -98 99 -100 699 -66 4847 -66 2153 -134 1993 -66 5935 -66 1435 -100 2119 -66 9535 -296 197 -624 131 -1446 129 -362 65 -198 +RAW_Data: 67 -298 197 -226 131 -164 595 -66 463 -98 131 -198 395 -262 131 -66 1773 -516 455 -548 481 -516 479 -556 451 -554 451 -542 469 -548 451 -546 447 -552 449 -554 471 -542 477 -518 489 -512 481 -1044 977 -506 485 -540 469 -1044 481 -518 975 -1050 947 -548 489 -512 481 -1042 967 -1020 979 -550 455 -1038 477 -520 471 -556 483 -514 969 -1044 977 -536 473 -544 449 -1054 955 -552 447 -554 485 -514 471 -1046 975 -1020 485 -518 1003 -512 483 -548 447 -554 447 -556 485 -1010 491 -51312 527 -512 453 -544 477 -540 477 -514 473 -538 473 -524 471 -558 453 -542 467 -514 485 -546 479 -514 473 -522 471 -534 501 -1014 1001 -512 481 -514 479 -1052 459 -544 979 -1016 1009 -516 473 -522 469 -1044 995 -1010 1007 -524 475 -1004 495 -512 483 -544 479 -514 1003 -1018 977 -522 489 -512 479 -1034 1003 -522 487 -512 467 -514 483 -1044 975 -1020 485 -524 991 -514 477 -550 473 -524 473 -536 471 -1030 489 -51306 517 -520 493 -512 483 -546 445 -550 477 -520 469 -544 479 -518 495 -512 481 -514 475 -550 477 -526 471 -538 473 -538 471 -1018 979 -548 451 -546 479 -1010 473 -554 965 -1034 989 -516 479 -1048 967 -554 451 -1022 977 -1034 475 -554 473 -510 1003 -512 481 -546 443 -1064 969 -1034 977 -1020 483 -546 477 -516 967 -538 473 -1052 449 -562 461 -514 481 -546 477 -514 477 -522 999 -510 485 -1038 985 -51816 479 -3892 63 -722 289 -742 265 -734 271 -762 231 -722 291 -720 321 -644 373 -642 339 -626 395 -1114 911 -610 415 -580 413 -1098 425 -548 979 -1054 955 -544 443 -1080 449 -548 939 -1054 473 -550 949 -1048 481 -514 973 -1050 975 -1050 453 -544 971 -538 473 -1032 471 -538 967 -554 449 -524 495 -512 481 -546 479 -1008 473 -556 487 -512 965 -546 481 -516 473 -1036 487 -522 483 -97226 691 -134 1391 -396 231 -166 1025 -98 199 -132 99 -266 395 -100 165 -132 231 -98 689 -66 493 -98 65 -98 557 -134 365 -68 131 -164 425 -132 259 -98 1255 -232 195 -66 495 -64 1651 -100 199 -100 1099 -100 331 -132 265 -168 6433 -66 28525 -100 395 -66 395 -100 259 -164 559 -100 463 -66 327 -66 131 -100 685 -66 395 -98 199 -100 431 -66 101 -100 231 -66 333 -66 399 -266 165 -68 99 -100 165 -398 299 -98 197 -824 97 -132 229 -66 295 -264 97 -230 131 -394 469 -266 397 -198 165 -270 133 -562 165 -66 229 -266 99 -232 363 -530 427 -730 99 -166 97 -534 297 -100 297 -134 133 -132 67 -100 67 -66 361 -430 397 -330 65 -198 165 -200 167 -68 131 -132 199 -68 233 -100 +RAW_Data: 99 -234 65 -300 263 -562 163 -66 199 -166 165 -132 99 -264 131 -262 261 -64 459 -66 427 -132 65 -132 131 -100 97 -228 163 -164 523 -328 297 -66 131 -332 199 -266 65 -134 165 -66 197 -68 697 -98 165 -134 233 -496 231 -164 63 -66 197 -264 297 -166 99 -198 131 -100 365 -266 299 -232 99 -66 627 -132 1415 -100 195 -198 165 -98 327 -98 523 -98 131 -228 229 -230 295 -694 499 -100 531 -66 131 -134 165 -300 165 -132 265 -300 997 -102 1921 -134 723 -98 195 -132 99 -164 163 -68 397 -100 331 -132 165 -266 467 -232 131 -66 465 -198 463 -132 165 -66 329 -100 2691 -100 431 -166 397 -100 199 -134 529 -100 1053 -66 18073 -98 1251 -130 1425 -66 497 -98 6625 -10518 1205 -578 607 -588 599 -612 597 -586 605 -582 587 -1214 1171 -1180 1207 -582 609 -588 613 -578 613 -592 611 -576 613 -1184 583 -580 1205 -1206 1169 -614 577 -590 629 -576 601 -1182 609 -598 1177 -578 627 -588 603 -1178 1207 -582 589 -1178 1209 -1178 613 -588 613 -576 1215 -1174 1181 -1204 1183 -604 579 -1218 1175 -604 579 -1186 1225 -562 615 -1184 611 -578 1207 -578 605 -1184 609 -568 1209 -580 629 -582 603 -574 605 -580 603 -612 577 -610 603 -77146 1139 -774 423 -1374 419 -716 495 -708 493 -682 1089 -1308 1095 -688 519 -638 539 -656 551 -638 539 -656 549 -638 575 -622 551 -1206 1179 -1204 585 -616 577 -620 1189 -594 581 -602 581 -1186 603 -614 1169 -1200 1207 -1176 613 -592 1181 -600 581 -1214 583 -580 611 -588 615 -576 615 -588 1173 -1212 579 -590 613 -590 587 -614 1169 -1212 579 -612 591 -580 1201 -588 615 -578 613 -1180 587 -616 1169 -1210 1201 -580 579 -622 591 -1170 1203 -612 575 -614 593 -77174 1201 -608 589 -1210 583 -622 549 -606 585 -626 1169 -1204 579 -608 1205 -578 601 -586 621 -582 589 -614 575 -1214 575 -620 563 -612 1193 -592 579 -1204 1183 -606 577 -1224 559 -614 1195 -588 611 -1182 581 -606 1205 -1176 611 -586 579 -628 1173 -1208 581 -604 1167 -616 571 -1216 1171 -618 585 -1210 1177 -1208 581 -586 1205 -580 589 -616 571 -1212 1171 -616 587 -1206 573 -594 615 -588 589 -614 1169 -618 583 -1212 1177 -578 609 -590 613 -578 611 -77168 1211 -612 565 -1242 549 -628 577 -620 583 -586 1173 -616 587 -612 587 -588 615 -578 611 -586 579 -628 579 -620 585 -1180 1197 -1194 1183 -600 583 -622 583 -1184 1193 -1180 1197 -604 577 -1214 585 -614 1169 -1210 1165 -614 577 -622 591 -580 603 -1182 609 -602 1173 -1204 577 -598 1203 -610 571 -616 575 -1202 581 -608 611 -592 577 -602 1203 -1172 611 -588 611 -578 611 -592 +RAW_Data: 1171 -622 591 -580 603 -1180 1207 -580 599 -1208 579 -622 1173 -612 575 -590 613 -123688 65 -3788 133 -896 65 -168 65 -926 297 -168 65 -100 365 -66 297 -98 201 -1162 131 -428 195 -66 297 -166 99 -760 99 -196 131 -132 65 -98 197 -66 493 -264 99 -264 821 -66 793 -100 3007 -98 2067 -66 2411 -430 97 -98 197 -130 297 -230 465 -98 4123 -100 391 -132 163 -66 751 -164 161 -990 759 -64 1055 -264 129 -166 429 -66 3943 -66 399 -100 665 -432 431 -132 99 -132 97 -68 97 -330 295 -164 131 -66 291 -66 589 -264 563 -100 1227 -166 233 -298 699 -100 863 -534 131 -332 1619 -100 1595 -132 2191 -164 465 -66 233 -68 299 -66 561 -134 369 -68 233 -134 297 -168 463 -166 795 -100 265 -68 131 -100 3629 -66 227 -66 853 -66 529 -100 1191 -98 501 -132 1417 -64 229 -132 1115 -66 463 -66 231 -64 361 -66 231 -98 989 -98 265 -300 1125 -66 897 -68 197 -100 529 -66 787 -164 163 -66 2705 -66 1899 -132 929 -64 1197 -132 4387 -98 263 -96 261 -100 751 -66 229 -10520 1245 -566 609 -564 615 -572 613 -590 615 -594 589 -1174 1203 -1204 1195 -564 615 -592 617 -580 611 -560 627 -576 603 -1186 609 -564 1213 -1176 1211 -578 623 -588 611 -1176 1205 -582 583 -582 613 -588 611 -578 625 -1152 1205 -592 615 -1176 1217 -1172 601 -576 605 -590 1193 -1186 1191 -1184 1227 -576 615 -1150 1209 -604 613 -1152 1227 -576 591 -1188 613 -578 1207 -576 607 -1184 607 -600 1179 -578 629 -588 607 -582 587 -1182 613 -586 1209 -77154 1187 -666 541 -1242 523 -676 535 -618 553 -644 1163 -1212 1169 -628 577 -620 551 -616 609 -588 589 -614 573 -586 597 -610 599 -1182 1209 -1182 581 -592 613 -604 1169 -1216 577 -604 1175 -1206 1175 -1208 1173 -1206 579 -596 1201 -610 571 -1212 605 -584 587 -610 575 -618 583 -612 1171 -1210 577 -588 613 -580 611 -590 1205 -1170 611 -578 611 -592 1171 -622 591 -578 603 -1182 611 -600 1177 -1206 1177 -610 597 -586 601 -1178 615 -590 589 -578 1205 -77194 1193 -618 583 -1208 575 -624 577 -606 583 -588 1205 -1178 611 -572 1201 -612 575 -588 615 -576 611 -590 579 -1206 585 -616 575 -622 1183 -600 577 -1216 1177 -604 581 -592 611 -608 583 -1178 1197 -1196 573 -616 1199 -1174 611 -586 589 -614 1167 -1214 575 -620 1185 -600 577 -1216 1177 -604 575 -1220 1159 -1222 585 -582 1181 -622 579 -592 611 -1200 1175 -588 585 -1208 605 -576 605 -620 561 -612 1189 -606 581 -1212 1177 -1208 581 -586 1207 -77162 599 -4312 397 -788 425 -772 1027 -722 471 -708 487 -686 503 -678 521 -686 503 -680 523 -652 +RAW_Data: 535 -1274 1109 -1240 1175 -614 559 -650 533 -1240 1177 -616 559 -1208 575 -628 577 -604 577 -620 1175 -1208 1171 -614 605 -578 601 -588 599 -1178 615 -588 1185 -1202 589 -614 1167 -618 583 -612 591 -1186 599 -584 601 -582 591 -618 1199 -1176 603 -580 591 -616 573 -616 1179 -624 581 -584 613 -1184 1173 -622 591 -1172 611 -592 579 -610 613 -588 1173 -122626 229 -330 197 -98 65 -98 97 -100 229 -166 129 -232 65 -66 131 -394 97 -66 97 -66 395 -66 557 -66 657 -64 489 -66 327 -100 65 -98 461 -64 5371 -64 691 -98 859 -66 631 -166 797 -66 299 -132 65 -66 4463 -134 331 -134 233 -132 1495 -264 699 -98 263 -134 1031 -692514 65 -100 97 -1392 131 -398 65 -134 201 -832 4061 -132 523 -66 431 -66 99 -132 99 -100 831 -66 165 -66 1969 -164 8553 -100 297 -68 523 -100 197 -130 957 -98 361 -98 2015 -98 263 -130 195 -130 4497 -66 999 -66 1357 -66 1189 -132 929 -66 4649 -66 263 -66 131 -64 657 -100 195 -68 231 -100 1025 -100 565 -68 931 -98 985 -98 661 -164 363 -100 501 -66 3719 -66 2015 -66 663 -132 299 -330 823 -66 1661 -66 4179 -66 433 -66 1523 -68 697 -68 197 -100 199 -66 1265 -98 629 -68 299 -168 629 -100 3539 -166 331 -66 495 -98 327 -132 589 -166 499 -66 463 -100 331 -66 627 -98 489 -64 129 -130 361 -98 195 -130 65 -100 793 -98 391 -66 1515 -66 129 -66 757 -132 561 -98 653 -64 197 -98 1577 -296 163 -100 789 -66 689 -66 3829 -100 533 -398 467 -166 531 -66 331 -198 753 -64 557 -98 693 -66 165 -100 4907 -134 199 -100 131 -66 333 -198 1345 -66 3781 -98 267 -100 597 -232 1449 -66 723 -330 197 -164 1021 -132 561 -98 591 -100 755 -66 559 -100 229 -228 131 -66 163 -198 689 -100 3365 -100 99 -68 431 -100 797 -66 431 -100 401 -68 397 -134 295 -66 297 -64 65 -100 1085 -132 3135 -66 497 -66 201 -98 99 -168 299 -66 165 -68 267 -366 231 -66 463 -266 733 -132 397 -66 297 -100 4563 -66 163 -66 293 -100 755 -100 697 -100 563 -100 4661 -132 65 -100 97 -494 691 -98 63 -66 459 -232 295 -230 229 -198 495 -66 457 -266 425 -685602 231 -202 133 -66 331 -66 167 -132 699 -98 231 -66 301 -66 299 -596 399 -66 557 -230 7389 -66 733 -98 657 -66 723 -100 789 -68 1661 -132 627 -66 1087 -134 97 -66 5173 -134 693 -134 1261 -132 4435 -66 131 -134 199 -66 891 -66 493 -100 397 -66 365 -100 297 -134 4287 -66 501 -166 1281 -100 195 -100 1151 -100 467 -266 265 -98 +RAW_Data: 2027 -68 131 -66 5771 -98 2171 -130 163 -66 7573 -66 661 -66 653 -66 357 -130 7217 -98 229 -132 393 -66 997 -66 4689 -100 97 -134 9081 -66 163 -132 493 -100 1217 -132 529 -230 131 -66 235 -100 133 -134 1359 -66 5243 -98 329 -66 167 -100 299 -100 431 -66 7349 -132 1059 -66 1393 -100 1317 -66 629 -98 429 -100 495 -100 365 -66 397 -234 1489 -100 4599 -100 399 -100 1855 -68 433 -98 1393 -132 7409 -100 5607 -66 463 -66 665 -68 2553 -134 167 -102 2263 -686936 99 -800 67 -98 99 -66 133 -230 265 -66 3631 -100 229 -130 99 -66 825 -100 99 -232 231 -66 521 -66 593 -98 1413 -130 359 -66 4639 -66 131 -68 97 -202 799 -166 99 -68 365 -66 1595 -66 2987 -66 423 -100 131 -98 791 -132 433 -100 893 -66 4831 -100 101 -98 629 -66 1221 -98 197 -66 625 -98 261 -66 559 -66 665 -66 4409 -66 331 -268 2017 -166 199 -68 333 -98 1553 -68 401 -166 563 -66 393 -100 195 -66 1485 -230 265 -100 4353 -68 431 -100 2383 -66 6737 -98 493 -66 1017 -68 5915 -66 1085 -198 527 -66 4223 -100 163 -64 131 -66 1187 -98 393 -66 1747 -130 263 -66 597 -100 501 -100 431 -132 1491 -100 131 -66 599 -68 2595 -100 497 -68 265 -100 763 -100 265 -100 165 -66 595 -68 331 -100 1587 -66 163 -66 99 -164 559 -130 457 -66 1611 -100 991 -66 4403 -100 1427 -164 565 -132 499 -66 827 -298 299 -100 4637 -166 263 -100 995 -66 1083 -428 365 -424 369 -454 377 -420 377 -418 409 -418 377 -424 381 -436 357 -438 387 -444 383 -414 385 -4058 783 -452 797 -434 811 -412 417 -862 773 -474 779 -484 387 -874 383 -850 403 -822 809 -450 415 -834 807 -444 773 -482 381 -870 787 -478 791 -436 805 -448 803 -420 411 -842 403 -836 415 -838 391 -864 807 -480 395 -850 387 -840 385 -844 391 -858 381 -878 783 -452 795 -464 807 -450 817 -448 377 -858 807 -446 777 -450 789 -454 813 -448 819 -430 809 -448 411 -838 807 -446 385 -862 379 -870 769 -468 801 -446 809 -456 379 -872 409 -858 781 -448 383 -846 409 -846 775 -478 381 -848 415 -858 809 -444 813 -422 393 -868 781 -448 385 -850 409 -860 777 -480 385 -866 805 -444 805 -418 411 -808 391 -15820 421 -372 417 -388 419 -386 437 -394 395 -400 421 -408 385 -412 415 -384 415 -418 383 -420 383 -420 385 -4030 825 -410 845 -420 811 -418 423 -838 821 -420 815 -456 385 -878 419 -816 407 -816 835 -416 409 -842 821 -422 811 -456 387 -876 789 -454 825 -428 801 -414 821 -442 399 -850 381 -852 +RAW_Data: 417 -824 447 -812 809 -462 413 -848 421 -816 399 -822 413 -850 419 -816 803 -440 809 -450 815 -446 821 -456 403 -820 821 -420 819 -418 807 -456 811 -412 821 -454 807 -470 379 -850 823 -416 423 -824 409 -844 789 -450 815 -432 807 -446 409 -838 439 -822 811 -414 409 -844 419 -822 803 -442 413 -848 409 -844 815 -448 811 -424 421 -838 787 -450 411 -810 407 -864 811 -418 415 -866 803 -448 817 -418 419 -776 417 -15782 437 -396 427 -378 407 -410 415 -376 415 -410 419 -388 419 -390 419 -388 411 -382 417 -400 409 -398 423 -4008 821 -420 815 -422 815 -446 405 -830 813 -450 811 -452 379 -876 407 -828 419 -810 813 -458 377 -842 823 -454 783 -458 385 -876 789 -456 827 -432 811 -412 821 -420 435 -820 393 -862 421 -810 429 -852 809 -444 409 -836 421 -812 425 -820 393 -828 421 -846 821 -432 809 -446 821 -448 821 -422 393 -854 787 -454 801 -432 803 -446 803 -446 821 -446 793 -472 381 -840 835 -418 415 -838 399 -820 837 -414 835 -410 835 -418 437 -858 389 -846 817 -432 385 -840 421 -812 827 -432 415 -848 421 -816 809 -472 811 -418 393 -866 785 -450 381 -852 419 -820 807 -440 411 -874 801 -448 803 -426 407 -804 413 -15800 397 -394 435 -388 409 -388 411 -386 447 -382 417 -384 417 -386 419 -388 415 -390 417 -420 385 -420 385 -4032 805 -440 803 -446 801 -416 437 -826 811 -448 809 -454 409 -844 407 -828 419 -834 817 -432 385 -842 819 -418 845 -428 415 -846 787 -456 831 -430 805 -414 821 -454 401 -834 381 -840 409 -866 415 -834 801 -472 379 -842 407 -832 419 -842 387 -832 409 -842 823 -454 785 -462 809 -448 817 -418 419 -846 795 -436 809 -414 829 -428 811 -450 811 -456 809 -444 409 -840 819 -420 383 -852 419 -822 799 -442 807 -452 815 -448 419 -854 413 -814 809 -422 409 -838 421 -844 795 -434 415 -848 419 -818 807 -476 809 -420 393 -834 813 -450 383 -852 417 -824 805 -474 381 -850 821 -454 805 -432 379 -808 417 -119860 67 -134 67 -98 133 -764 65 -398 133 -132 665 -200 597 -64 461 -66 4203 -96 227 -98 655 -98 327 -66 819 -66 589 -132 5777 -66 1495 -328 231 -130 131 -66 463 -66 265 -68 131 -68 429 -66 195 -98 5117 -100 797 -100 299 -166 459 -100 1731 -66 1759 -66 563 -66 825 -98 1081 -68 5321 -232 1291 -134 1955 -100 523 -68 795 -66 767 -66 3589 -66 827 -66 267 -100 2395 -100 4745 -66 2343 -66 1057 -100 1363 -100 6775 -166 329 -66 593 -66 1719 -98 6079 -100 427 -66 523 -66 525 -98 +RAW_Data: 1195 -66 1157 -68 333 -100 533 -66 4957 -134 731 -66 297 -66 97 -98 2989 -66 6633 -66 981 -98 983 -66 993 -98 2015 -132 65 -68 857 -232 723 -66 165 -66 1283 -100 853 -66 5575 -102 627 -98 367 -100 265 -66 853 -66 261 -66 195 -66 751 -66 195 -98 657 -132 953 -66 163 -296 429 -264 263 -66 1511 -98 263 -262 297 -68 263 -66 2523 -66 163 -132 295 -96 1447 -66 199 -66 463 -68 795 -66 1795 -100 701 -66 1333 -66 99 -66 131 -264 1293 -100 99 -66 299 -68 397 -66 399 -66 329 -100 595 -100 795 -66 131 -66 2015 -100 295 -98 2673 -130 1571 -66 753 -66 887 -98 723 -98 821 -100 131 -66 889 -66 793 -66 1057 -132 399 -100 397 -298 165 -66 299 -100 465 -100 233 -132 763 -66 1391 -130 2395 -66 895 -132 99 -134 2029 -166 799 -100 593 -98 195 -64 131 -66 1545 -66 785 -100 97 -98 131 -98 1753 -130 295 -66 619 -198 853 -166 233 -66 1393 -98 1783 -66 291 -132 691 -100 997 -66 133 -332 231 -66 131 -66 525 -66 263 -64 2435 -68 2967 -68 1101 -100 165 -68 599 -66 167 -134 235 -134 297 -68 497 -384 377 -448 377 -418 375 -454 377 -432 369 -424 377 -438 377 -436 377 -430 381 -434 359 -436 387 -4046 383 -852 797 -436 387 -870 385 -848 403 -850 809 -454 379 -876 415 -822 405 -852 381 -846 417 -822 801 -440 415 -846 415 -856 805 -446 383 -874 379 -834 405 -838 813 -460 783 -446 817 -444 793 -472 383 -880 381 -862 773 -442 411 -842 377 -858 413 -846 387 -870 775 -484 771 -480 805 -420 415 -848 795 -438 811 -414 817 -452 803 -470 777 -450 819 -450 417 -822 801 -442 385 -876 385 -848 795 -438 809 -452 819 -450 385 -882 375 -848 811 -422 413 -840 383 -846 823 -434 385 -874 381 -886 771 -476 811 -420 411 -840 809 -450 385 -850 413 -832 809 -444 383 -880 771 -486 803 -430 403 -806 383 -15810 425 -384 401 -420 393 -420 391 -386 421 -422 389 -386 423 -386 423 -388 419 -388 421 -388 421 -388 421 -4026 407 -840 813 -418 411 -842 397 -113844 97 -66 97 -164 99 -328 99 -232 299 -366 99 -1066 165 -66 623 -134 1197 -68 931 -66 599 -66 99 -234 2323 -132 1281 -66 495 -198 555 -414 383 -418 383 -418 417 -386 417 -418 383 -422 375 -422 379 -436 385 -444 351 -446 383 -416 385 -4076 379 -844 421 -812 395 -854 377 -862 813 -452 385 -840 815 -450 799 -488 383 -822 807 -446 803 -420 419 -842 403 -852 779 -450 407 -856 387 -880 805 -430 385 -840 809 -454 385 -856 377 -856 +RAW_Data: 777 -484 783 -454 807 -476 807 -410 797 -454 773 -462 383 -872 789 -454 787 -454 383 -870 797 -474 407 -822 813 -446 775 -448 785 -456 785 -484 783 -452 385 -872 385 -882 777 -442 809 -444 375 -864 777 -450 385 -886 789 -452 783 -470 383 -884 391 -858 779 -448 383 -848 385 -852 411 -856 379 -848 419 -852 777 -504 783 -418 801 -448 375 -852 811 -446 777 -450 813 -448 801 -458 419 -810 783 -424 379 -16422 413 -400 399 -396 405 -426 375 -424 411 -390 411 -390 413 -420 383 -420 383 -418 383 -418 415 -418 385 -4062 419 -816 383 -850 383 -852 409 -856 781 -448 385 -852 805 -468 779 -480 383 -844 819 -420 815 -418 391 -860 387 -880 763 -462 383 -876 417 -852 813 -446 381 -848 769 -456 397 -858 363 -882 779 -450 811 -454 807 -480 777 -446 803 -452 779 -432 383 -874 771 -488 765 -456 383 -878 795 -488 385 -854 773 -448 785 -456 777 -484 783 -450 771 -478 377 -860 407 -880 809 -418 813 -416 391 -862 779 -450 385 -888 791 -452 781 -468 381 -876 409 -834 777 -452 383 -872 377 -856 385 -866 405 -854 355 -898 787 -488 765 -460 777 -446 383 -852 807 -432 809 -446 783 -458 817 -454 391 -822 799 -418 399 -16448 421 -388 381 -424 417 -390 377 -456 379 -406 385 -442 383 -416 385 -418 387 -418 387 -452 355 -450 357 -4096 383 -840 387 -846 389 -858 365 -882 785 -444 385 -886 793 -452 781 -470 415 -844 791 -452 779 -432 379 -872 377 -884 779 -448 383 -872 379 -896 799 -430 411 -834 789 -456 383 -838 421 -846 799 -428 807 -444 803 -480 803 -446 767 -472 777 -448 383 -852 791 -488 775 -466 381 -848 793 -486 389 -852 775 -448 803 -446 801 -454 779 -468 775 -448 389 -896 387 -878 775 -438 807 -448 367 -848 813 -444 385 -848 789 -490 767 -458 383 -912 363 -850 813 -444 381 -848 385 -850 409 -854 385 -870 387 -846 803 -464 811 -418 801 -446 375 -884 779 -444 779 -484 779 -446 797 -472 381 -850 773 -416 407 -16410 409 -422 369 -410 403 -410 409 -410 379 -412 411 -408 377 -442 377 -428 379 -440 347 -444 381 -416 381 -4076 411 -844 375 -848 383 -850 385 -884 757 -488 385 -856 775 -480 769 -478 409 -840 787 -448 777 -450 391 -860 387 -848 793 -458 383 -878 417 -852 813 -412 383 -874 787 -454 389 -844 393 -854 785 -482 781 -454 807 -480 777 -446 801 -452 779 -434 381 -876 801 -454 765 -460 381 -878 787 -488 411 -826 775 -446 801 -458 779 -450 809 -450 803 -444 379 -862 419 -878 777 -438 807 -446 367 -878 +RAW_Data: 777 -446 383 -850 791 -486 783 -468 381 -882 393 -856 777 -446 383 -848 383 -854 411 -858 379 -848 419 -850 775 -506 783 -450 769 -446 377 -852 813 -446 777 -484 779 -448 795 -454 417 -824 777 -414 405 -122598 99 -134 65 -100 199 -832 99 -200 829 -98 163 -100 165 -66 197 -100 361 -98 723 -66 2987 -100 561 -460 1415 -100 527 -164 621 -98 459 -100 797 -66 497 -66 365 -132 401 -134 131 -66 699 -100 231 -66 327 -164 197 -66 299 -66 359 -66 395 -66 1773 -98 591 -66 295 -64 261 -98 833 -132 4215 -66 735 -98 331 -100 431 -66 761 -266 331 -102 497 -200 5637 -66 97 -198 921 -100 531 -66 299 -100 1559 -98 99 -100 233 -100 4173 -68 431 -66 599 -100 231 -66 429 -166 331 -132 431 -100 489 -66 359 -98 131 -66 261 -134 5083 -134 299 -100 1921 -68 197 -136 5299 -100 263 -64 721 -100 399 -130 429 -100 99 -98 1351 -100 295 -66 1315 -164 129 -98 393 -164 925 -66 663 -68 131 -66 229 -100 231 -100 99 -98 427 -66 325 -130 165 -98 197 -130 197 -128 327 -100 429 -66 1227 -100 893 -98 3491 -68 699 -66 365 -100 529 -98 229 -396 261 -66 561 -98 227 -98 329 -426 393 -130 363 -66 133 -166 1353 -100 393 -200 197 -100 199 -100 333 -66 961 -66 199 -66 197 -64 593 -66 627 -66 1317 -66 165 -198 199 -98 99 -66 3621 -98 597 -98 165 -66 4527 -200 263 -66 2751 -100 2131 -66 229 -64 721 -132 1261 -266 629 -98 201 -68 1323 -100 1689 -66 233 -326 1283 -66 261 -66 1381 -66 201 -100 4351 -66 331 -100 565 -134 2025 -66 563 -198 1657 -98 3057 -68 397 -98 297 -66 231 -100 931 -98 365 -66 1127 -66 165 -132 201 -100 99 -66 961 -100 99 -66 425 -66 1087 -166 463 -64 6307 -530 329 -66 297 -100 329 -66 201 -100 1123 -66 723 -98 523 -64 985 -66 131 -134 99 -66 4897 -66 1451 -132 199 -66 659 -66 195 -66 557 -66 263 -68 569 -100 661 -164 1975 -100 1361 -66 3647 -66 335 -100 363 -100 919 -66 887 -166 1775 -166 501 -66 495 -66 2753 -98 887 -66 3259 -66 821 -464 797 -134 567 -66 2401 -98 5415 -100 435 -100 99 -100 427 -66 599 -68 465 -132 435 -100 1495 -66 301 -68 233 -200 431 -66 397 -100 265 -68 231 -100 461 -234 199 -98 893 -132 265 -298 131 -166 2055 -68 199 -66 497 -66 1697 -66 1857 -66 5599 -66 2351 -66 131 -100 4929 -66 265 -134 561 -66 765 -132 861 -66 5351 -134 265 -102 99 -66 563 -66 267 -136 333 -98 233 -100 601 -66 365 -98 +RAW_Data: 1023 -66 5413 -232 631 -134 8367 -66 1583 -196 1901 -98 129 -66 1381 -98 3681 -98 1583 -98 133 -100 263 -134 1731 -100 465 -66 629 -66 4609 -166 201 -132 1995 -66 333 -66 499 -100 723 -134 561 -66 5317 -66 333 -66 1135 -66 1193 -66 1227 -100 885 -132 163 -230 719 -100 2305 -66 1025 -166 397 -68 793 -100 1381 -132 5385 -66 623 -164 763 -98 357 -396 3739 -134 4665 -66 393 -130 1153 -98 687 -66 229 -100 961 -66 467 -66 1301 -66 3647 -98 363 -66 329 -68 1589 -100 261 -66 5647 -66 2039 -66 297 -164 523 -66 197 -100 933 -66 99 -164 67 -66 97 -64 197 -64 559 -132 1151 -64 229 -98 2249 -64 1151 -66 533 -134 299 -134 665 -98 559 -98 1253 -66 2687 -134 995 -132 233 -68 131 -68 467 -132 297 -66 233 -66 167 -66 165 -134 201 -98 165 -166 1421 -428 333 -480 327 -448 361 -462 367 -424 371 -452 377 -420 379 -420 411 -418 381 -422 379 -424 381 -4072 773 -450 393 -852 397 -858 777 -448 811 -458 779 -480 793 -458 809 -448 385 -854 789 -426 411 -844 391 -852 815 -450 801 -444 415 -848 407 -848 383 -850 799 -450 409 -854 773 -450 395 -862 419 -844 401 -852 809 -456 379 -838 417 -848 397 -822 805 -446 411 -840 419 -848 799 -470 811 -418 411 -840 385 -844 423 -838 381 -882 369 -882 777 -480 383 -856 395 -862 385 -842 819 -432 387 -840 419 -850 399 -854 381 -850 403 -884 811 -418 415 -822 417 -826 405 -850 811 -420 817 -446 801 -452 811 -472 381 -840 833 -410 807 -454 785 -458 803 -444 805 -448 801 -458 417 -844 795 -440 809 -382 417 -16778 459 -354 455 -386 385 -422 419 -388 411 -382 405 -420 397 -398 421 -408 387 -410 385 -414 415 -418 383 -4046 787 -424 413 -844 427 -818 817 -416 835 -428 811 -450 811 -458 803 -448 409 -838 785 -450 383 -840 417 -862 809 -442 811 -416 421 -872 385 -850 403 -820 809 -452 397 -828 815 -446 413 -840 409 -838 413 -872 807 -412 411 -848 407 -824 415 -844 783 -460 379 -876 385 -850 807 -474 809 -418 411 -838 419 -810 429 -818 423 -838 419 -846 797 -436 413 -878 381 -828 411 -848 811 -418 411 -840 419 -846 397 -852 387 -870 387 -850 803 -442 413 -844 407 -824 415 -848 781 -462 809 -412 837 -448 803 -458 419 -810 827 -434 811 -414 801 -454 815 -450 779 -458 803 -450 395 -860 809 -416 809 -424 379 -16828 405 -414 379 -412 413 -410 383 -406 423 -396 399 -392 433 -382 407 -412 413 -380 411 -414 409 -394 413 -4044 805 -422 393 -854 395 -826 813 -448 +RAW_Data: 811 -456 811 -412 821 -486 775 -438 411 -844 801 -442 395 -838 413 -838 803 -448 801 -456 413 -840 407 -836 417 -834 805 -446 387 -848 801 -438 415 -844 407 -848 417 -848 819 -432 385 -844 419 -816 429 -826 809 -446 411 -838 419 -848 797 -468 805 -418 393 -866 385 -846 389 -854 409 -838 415 -838 799 -472 379 -886 367 -850 417 -846 781 -458 379 -842 419 -848 401 -854 381 -884 369 -884 783 -450 415 -820 407 -848 413 -814 809 -460 809 -444 805 -448 801 -460 417 -844 795 -434 811 -412 801 -450 809 -436 805 -448 805 -446 417 -864 809 -412 803 -416 409 -16802 423 -386 411 -382 405 -420 377 -122006 97 -98 165 -66 97 -132 65 -428 427 -132 3981 -66 265 -66 161 -66 327 -66 1625 -66 727 -100 4773 -134 863 -66 665 -66 2605 -98 4311 -98 99 -66 1249 -98 263 -100 5105 -68 461 -100 5065 -66 965 -68 799 -164 5737 -19106 327 -196 131 -362 131 -332 229 -134 363 -1162 297 -132 1197 -100 99 -132 231 -66 425 -200 267 -100 395 -134 331 -134 267 -100 563 -100 231 -66 655 -66 427 -66 299 -98 197 -132 3997 -66 463 -134 133 -134 1827 -132 1847 -66 131 -66 933 -100 3749 -132 131 -328 887 -98 457 -66 457 -100 593 -98 1813 -66 3895 -98 1117 -66 199 -66 881 -98 987 -66 397 -98 749 -66 195 -100 953 -100 819 -100 1017 -98 1915 -100 1707 -130 3865 -98 567 -132 265 -132 333 -66 1033 -132 791 -100 165 -100 1261 -66 531 -68 4337 -68 1191 -100 933 -100 767 -66 499 -164 363 -132 65 -100 5559 -66 233 -66 167 -68 265 -232 195 -100 329 -98 1795 -132 5043 -132 197 -66 223 -132 265 -200 525 -66 1147 -132 793 -100 4221 -132 703 -66 197 -132 595 -100 3891 -100 333 -100 1451 -164 261 -328 199 -166 1277 -1574 1699 -490 1705 -516 1663 -516 1695 -518 1699 -484 617 -1538 609 -1562 585 -1576 1693 -518 587 -1576 1701 -514 581 -1554 1737 -484 1737 -484 1711 -528 583 -1572 599 -1576 609 -1530 615 -1560 1719 -494 1739 -520 581 -1560 631 -1534 609 -16396 609 -1576 1707 -490 1713 -516 1697 -520 1699 -508 1711 -530 579 -1572 599 -1576 609 -1544 1707 -518 587 -1570 1731 -484 605 -1578 1699 -516 1729 -476 1753 -494 605 -1568 609 -1566 593 -1540 607 -1566 1733 -510 1705 -512 599 -1578 611 -1544 615 -16410 631 -1536 1711 -530 1703 -500 1731 -516 1737 -518 1741 -480 639 -1566 599 -1568 615 -1580 1743 -482 641 -1534 1751 -486 655 -1542 1735 -520 1735 -514 1745 -512 595 -1570 613 -1546 651 -1548 603 -1574 1767 -484 1745 -516 609 -1570 595 -1580 611 -16402 631 -1542 1733 -486 1747 -480 1773 -484 +RAW_Data: 1729 -486 1783 -462 643 -1542 637 -1548 613 -1562 1743 -480 611 -1566 1747 -490 623 -1540 1747 -502 1739 -492 1759 -500 615 -1544 639 -1532 617 -1556 623 -1542 1777 -462 1771 -490 623 -1540 619 -1570 609 -16422 629 -1546 1747 -486 1739 -474 1737 -516 1713 -506 1751 -488 621 -1574 611 -1558 617 -1542 1729 -520 619 -1534 1735 -512 611 -1546 1743 -508 1727 -514 1729 -482 647 -1554 615 -1546 605 -1568 613 -1560 1713 -512 1737 -486 607 -1568 613 -1562 621 -16400 643 -1538 1715 -518 1709 -482 1725 -514 1723 -520 1711 -530 581 -1570 603 -1596 575 -1592 1693 -516 601 -1580 1703 -520 591 -1574 1737 -484 1741 -482 1761 -482 605 -1576 611 -1560 613 -1548 623 -1538 1739 -478 1715 -520 587 -1556 603 -1568 607 -16414 661 -1524 1743 -478 1727 -486 1727 -486 1747 -490 1731 -522 587 -1558 623 -1546 623 -1574 1737 -484 597 -1566 1739 -480 635 -1560 1745 -464 1745 -516 1729 -504 619 -1546 623 -1546 623 -1574 609 -1560 1743 -486 1747 -480 639 -1572 337 -80934 65 -702 65 -960 165 -132 333 -100 1031 -134 163 -100 199 -398 2413 -66 853 -96 3999 -66 1027 -68 495 -66 431 -98 197 -134 65 -100 431 -68 663 -596 197 -132 525 -100 425 -100 397 -100 429 -100 263 -166 4697 -132 291 -228 459 -64 957 -66 233 -66 723 -364 5193 -198 759 -66 359 -98 231 -98 425 -66 265 -98 457 -66 3309 -198 863 -66 263 -166 393 -66 1025 -166 331 -134 463 -102 4119 -66 331 -66 465 -66 395 -66 267 -100 365 -136 97 -100 333 -134 363 -100 265 -100 799 -66 463 -132 1917 -100 2273 -132 99 -66 2537 -98 97 -100 195 -66 657 -98 1145 -66 359 -66 423 -98 227 -66 5391 -66 4069 -100 795 -130 455 -66 3877 -100 165 -98 365 -198 2085 -66 1059 -66 333 -66 7359 -102 431 -66 1349 -100 131 -66 459 -66 327 -66 4189 -98 533 -100 563 -66 365 -66 465 -66 863 -66 493 -66 1317 -66 3459 -98 99 -66 1153 -130 1875 -166 867 -232 5309 -132 363 -66 301 -66 1333 -166 1525 -66 865 -166 5313 -98 295 -98 363 -98 197 -98 229 -64 557 -100 97 -164 199 -66 99 -66 291 -66 393 -98 163 -326 327 -100 529 -134 467 -68 165 -66 201 -66 6277 -66 229 -64 361 -66 227 -66 1215 -66 525 -66 131 -66 1053 -66 1147 -66 1463 -100 565 -402 1127 -66 1329 -98 331 -66 97 -68 461 -66 265 -68 65 -66 1197 -66 831 -66 761 -66 233 -66 4805 -66 395 -68 297 -100 827 -198 625 -100 399 -66 1191 -68 429 -100 629 -66 499 -66 195 -100 2485 -66 655 -100 4745 -68 297 -66 1965 -134 4807 -68 99 -134 627 -66 233 -132 499 -66 +RAW_Data: 5047 -98 165 -102 167 -66 533 -66 133 -100 1359 -166 493 -100 2385 -100 3759 -66 635 -132 331 -100 2115 -100 431 -66 5673 -66 631 -66 231 -100 1589 -100 9979 -100 2797 -394 327 -66 687 -66 899 -100 5425 -134 461 -100 623 -132 5885 -68 399 -100 165 -98 165 -100 1761 -230 697 -66 227 -98 919 -66 1921 -134 1099 -66 331 -66 333 -166 531 -100 793 -66 129 -164 197 -66 131 -98 887 -100 131 -198 295 -66 197 -68 761 -68 827 -100 297 -100 1585 -100 1083 -66 199 -66 1553 -68 433 -100 631 -232 165 -66 297 -234 431 -66 2297 -100 233 -66 565 -230 129 -196 4915 -66 297 -66 529 -134 365 -132 433 -66 297 -166 359 -66 695 -68 1259 -130 689 -66 1645 -98 525 -100 791 -66 295 -66 1413 -64 165 -68 261 -100 1627 -134 1677 -66 357 -66 633 -132 197 -132 1061 -100 5353 -66 233 -100 897 -66 395 -66 459 -66 129 -100 897 -134 4679 -66 857 -130 1841 -66 1023 -134 5191 -98 361 -98 527 -66 1021 -98 591 -66 493 -66 955 -100 231 -98 295 -364 99 -66 4471 -66 99 -132 1193 -66 563 -66 267 -68 661 -66 1261 -134 827 -98 4705 -66 1643 -132 2273 -166 263 -66 459 -100 3483 -66 565 -100 2155 -130 195 -100 1695 -100 529 -100 1053 -202 133 -100 885 -98 297 -98 853 -68 531 -66 263 -100 4855 -66 331 -66 563 -64 391 -164 333 -68 97 -132 1789 -132 165 -132 267 -66 1191 -66 727 -100 197 -66 601 -98 231 -100 331 -200 465 -66 863 -66 97 -98 361 -66 231 -100 959 -66 525 -66 167 -98 531 -100 4877 -100 829 -66 331 -66 363 -66 589 -64 227 -98 393 -132 99 -98 197 -132 197 -100 763 -100 399 -100 627 -98 301 -66 1595 -1492 511 -1044 513 -1040 507 -1042 1005 -558 1007 -554 1005 -574 1007 -548 1005 -546 1003 -542 477 -1072 1007 -516 1013 -556 1009 -552 513 -1076 975 -550 1009 -554 1013 -524 1017 -552 487 -1042 999 -580 993 -584 493 -1050 985 -580 977 -576 483 -1044 515 -1044 1007 -516 1005 -586 1011 -550 481 -1072 1013 -548 1013 -548 975 -552 515 -1042 475 -1050 1017 -574 491 -1084 983 -570 475 -1056 525 -1048 979 -546 515 -1042 479 -1040 1003 -584 515 -1040 515 -1044 513 -1046 515 -1042 1009 -548 1007 -516 509 -1040 1003 -524 1513 -19022 1537 -1536 477 -1048 507 -1032 509 -1046 1001 -570 1013 -572 979 -580 483 -1064 499 -1052 981 -546 513 -1044 1009 -518 1009 -586 1009 -548 513 -1040 1011 -548 1009 -546 1009 -546 1005 -516 511 -1044 977 -620 981 -570 495 -1050 1013 -534 999 -550 525 -1048 485 -1044 1009 -514 1003 -586 1009 -546 515 -1074 979 -546 +RAW_Data: 1009 -542 1009 -546 513 -1040 479 -1040 1003 -586 513 -1040 1007 -576 483 -1074 483 -1044 1011 -548 479 -1044 511 -1042 1003 -588 477 -1076 479 -1074 513 -1040 513 -1040 1009 -548 1007 -516 509 -1040 1003 -522 1527 -18990 1541 -1550 481 -1042 509 -1048 481 -1046 1001 -588 1017 -554 985 -572 477 -1060 1023 -548 981 -544 515 -1040 1011 -514 1003 -586 1007 -548 513 -1042 1007 -576 981 -546 1013 -548 1007 -516 509 -1042 1005 -574 1005 -576 481 -1076 981 -578 977 -546 513 -1044 513 -1040 1005 -518 1007 -590 971 -584 479 -1074 1011 -548 1007 -548 1005 -516 511 -1040 509 -1044 975 -588 519 -1052 1003 -552 501 -1046 513 -1062 993 -548 485 -1042 515 -1040 1003 -574 485 -1076 485 -1076 485 -1076 483 -1042 1009 -548 1009 -516 509 -1040 1003 -520 1527 -19010 1537 -1524 481 -1076 481 -1046 511 -1044 1013 -554 1013 -552 519 -1044 1005 -556 497 -1050 983 -578 483 -1042 1011 -516 1009 -586 1009 -550 513 -115324 65 -2458 65 -66 231 -896 231 -68 131 -434 1191 -66 399 -66 295 -100 627 -132 561 -66 755 -100 593 -100 1155 -98 163 -66 3687 -100 793 -98 229 -98 425 -100 623 -98 393 -132 131 -132 393 -66 395 -66 259 -132 259 -132 99 -100 463 -166 5379 -132 631 -66 1131 -66 819 -164 1115 -66 1525 -66 3617 -98 297 -98 65 -66 497 -68 199 -100 267 -166 593 -66 787 -132 197 -68 5473 -68 527 -164 329 -66 229 -64 195 -230 359 -100 263 -66 391 -98 821 -66 165 -66 2935 -100 65 -68 1057 -66 267 -68 561 -98 559 -98 329 -166 367 -100 1925 -134 999 -66 399 -98 529 -66 299 -134 299 -164 4801 -132 299 -98 595 -66 265 -68 1259 -98 327 -132 755 -198 4311 -130 721 -68 1259 -200 399 -302 495 -100 1259 -66 665 -66 331 -66 531 -66 3979 -134 461 -66 1313 -66 325 -66 753 -68 329 -98 427 -66 5079 -66 299 -134 527 -68 165 -100 333 -100 1091 -66 195 -164 195 -66 4411 -66 199 -100 1695 -66 567 -66 435 -234 1415 -98 325 -98 97 -98 329 -66 165 -268 131 -164 1905 -132 1123 -68 263 -166 199 -234 533 -134 491 -98 293 -66 989 -98 4053 -134 299 -166 499 -98 893 -66 463 -134 5411 -66 4201 -100 4949 -66 533 -166 1327 -66 131 -100 1717 -100 2787 -166 471 -66 1051 -98 1183 -66 2895 -68 2289 -66 797 -66 295 -68 627 -200 697 -100 163 -66 5101 -100 1791 -66 965 -134 7887 -66 265 -100 99 -134 1891 -100 559 -66 661 -98 167 -68 465 -68 1851 -164 4741 -98 397 -66 261 -98 955 -198 567 -98 233 -132 699 -100 465 -66 265 -164 331 -66 131 -98 765 -100 461 -98 1125 -64 +RAW_Data: 3701 -100 1033 -66 197 -68 4443 -68 595 -134 565 -66 499 -66 199 -134 5461 -66 645 -344 635 -326 677 -648 345 -312 697 -310 669 -350 667 -348 667 -634 345 -312 669 -650 373 -636 323 -348 635 -23014 363 -320 669 -322 641 -650 373 -312 667 -350 667 -346 667 -332 681 -642 351 -312 667 -640 319 -666 347 -318 645 -23022 349 -326 641 -352 659 -656 335 -350 661 -334 651 -354 657 -330 703 -658 329 -316 655 -646 349 -668 341 -318 625 -23038 323 -348 653 -322 663 -654 335 -354 661 -336 653 -322 685 -330 701 -652 321 -346 637 -648 351 -658 333 -354 623 -23022 319 -336 677 -320 661 -654 335 -354 661 -336 679 -322 687 -296 703 -656 331 -318 667 -652 353 -620 375 -318 625 -23036 321 -346 655 -322 661 -652 371 -320 659 -338 677 -322 691 -296 705 -654 333 -350 635 -634 345 -672 353 -300 635 -23040 349 -314 667 -314 665 -642 349 -352 645 -354 651 -344 693 -318 693 -644 345 -300 679 -626 361 -648 323 -354 651 -22990 345 -338 661 -346 653 -652 325 -350 647 -322 681 -350 673 -346 653 -654 321 -354 645 -646 349 -656 351 -340 609 -23046 321 -344 637 -328 679 -648 345 -314 697 -316 667 -348 669 -338 677 -646 351 -316 655 -646 343 -658 351 -314 655 -23016 333 -352 627 -328 681 -646 345 -350 655 -346 655 -322 691 -320 675 -652 337 -350 637 -666 315 -672 351 -300 669 -22998 349 -318 655 -340 653 -646 349 -348 667 -314 667 -352 669 -338 679 -646 351 -316 655 -646 345 -658 351 -314 653 -23020 335 -318 659 -322 665 -672 345 -316 659 -342 671 -330 677 -324 683 -650 341 -354 631 -656 349 -654 345 -352 621 -23002 329 -352 667 -322 641 -684 343 -316 659 -340 677 -322 695 -326 675 -654 333 -354 623 -648 353 -658 331 -354 629 -123230 99 -66 197 -568 97 -594 65 -100 229 -130 589 -134 5281 -66 99 -98 2761 -66 1385 -132 299 -66 4967 -230 1991 -200 627 -66 1515 -232 5531 -132 1693 -98 995 -66 465 -100 399 -66 893 -66 4501 -66 363 -66 197 -66 1989 -66 1727 -198 99 -66 499 -100 427 -98 1649 -132 165 -164 97 -98 295 -132 325 -98 131 -66 295 -66 657 -64 625 -66 295 -130 1515 -68 231 -66 455 -64 521 -66 559 -66 1977 -98 167 -166 335 -66 493 -66 233 -68 335 -66 199 -266 165 -134 167 -68 431 -100 425 -98 163 -98 197 -66 359 -98 691 -98 229 -66 689 -66 195 -66 785 -66 163 -230 231 -196 259 -66 425 -98 265 -102 597 -100 199 -100 231 -100 231 -68 565 -66 133 -166 165 -100 229 -66 629 -134 65 -132 +RAW_Data: 231 -68 2745 -66 4279 -132 1093 -200 663 -98 2791 -66 299 -66 4055 -64 691 -66 529 -66 165 -68 865 -66 629 -66 133 -100 597 -266 297 -68 4367 -66 261 -130 519 -68 1265 -66 2189 -66 1423 -66 131 -66 4185 -66 165 -100 333 -132 1125 -66 363 -66 701 -66 1523 -534 3887 -66 1941 -100 293 -66 327 -164 131 -98 589 -98 133 -66 129 -66 429 -98 1415 -132 1021 -130 555 -100 1791 -134 299 -66 165 -66 331 -100 927 -298 231 -66 97 -68 1025 -66 297 -66 199 -68 699 -66 97 -66 97 -66 261 -166 393 -98 129 -98 161 -100 425 -100 1873 -66 759 -66 799 -100 427 -66 299 -66 1031 -134 267 -100 2349 -68 2659 -100 2097 -132 629 -100 1129 -166 231 -66 231 -66 1719 -132 427 -200 5213 -66 1399 -66 3055 -132 7835 -66 1327 -66 4625 -66 359 -66 2607 -420 373 -452 345 -452 347 -454 379 -422 377 -450 349 -466 359 -434 359 -436 389 -442 353 -444 385 -4052 781 -448 797 -436 379 -872 803 -430 807 -448 813 -458 779 -478 803 -450 805 -430 801 -446 381 -848 815 -444 789 -472 381 -846 819 -454 803 -434 413 -840 375 -858 409 -838 387 -852 395 -864 815 -450 385 -854 391 -870 383 -846 389 -852 395 -860 383 -844 393 -886 781 -448 415 -858 411 -816 417 -820 405 -850 411 -848 779 -458 805 -446 805 -450 803 -458 415 -846 793 -434 387 -840 417 -848 791 -436 809 -448 805 -450 409 -860 383 -848 825 -434 387 -840 417 -846 793 -434 385 -874 383 -888 375 -882 779 -458 807 -416 803 -456 381 -842 821 -434 813 -450 413 -836 809 -444 811 -426 395 -828 409 -17022 421 -414 417 -382 417 -384 417 -386 417 -418 385 -420 409 -398 395 -398 391 -440 387 -408 387 -412 415 -4026 819 -420 793 -430 421 -838 811 -454 781 -462 813 -446 787 -488 777 -440 809 -450 793 -426 411 -844 817 -430 809 -448 397 -862 817 -452 783 -462 385 -838 419 -812 427 -820 393 -866 421 -810 823 -436 413 -842 409 -866 385 -844 389 -854 397 -826 419 -846 387 -854 813 -440 409 -848 419 -844 389 -856 399 -822 417 -844 783 -460 803 -446 801 -448 801 -454 417 -846 799 -438 385 -842 421 -846 793 -436 809 -448 821 -418 419 -848 407 -848 811 -420 409 -840 421 -810 823 -436 383 -874 407 -858 387 -844 821 -438 807 -414 835 -418 417 -844 797 -436 809 -450 395 -864 811 -452 785 -428 423 -804 415 -17028 413 -430 363 -450 339 -448 375 -450 343 -450 375 -452 371 -420 381 -432 351 -470 349 -442 381 -410 383 -4072 773 -446 805 -426 411 -844 787 -464 811 -448 +RAW_Data: 793 -456 813 -450 789 -460 805 -416 803 -456 381 -844 825 -434 811 -448 415 -834 811 -446 813 -458 357 -870 383 -846 391 -852 395 -862 383 -872 793 -468 379 -874 397 -860 383 -844 387 -854 365 -856 415 -848 387 -854 819 -450 383 -886 375 -850 383 -850 417 -826 403 -852 777 -450 805 -446 805 -454 817 -450 395 -850 819 -418 415 -848 397 -850 779 -448 805 -458 777 -482 387 -850 393 -864 809 -450 385 -854 379 -862 773 -474 383 -846 415 -858 377 -882 785 -458 805 -414 803 -456 381 -844 821 -434 809 -448 379 -868 815 -452 789 -432 391 -832 413 -17034 411 -398 427 -380 407 -412 413 -378 413 -412 411 -382 417 -396 417 -396 409 -414 379 -436 387 -410 385 -4044 819 -420 789 -426 411 -840 809 -456 821 -430 809 -448 821 -418 831 -430 805 -450 811 -414 409 -838 811 -454 783 -456 409 -848 819 -448 791 -440 415 -814 421 -814 431 -824 413 -850 385 -850 805 -474 379 -850 419 -828 411 -848 381 -850 417 -822 405 -852 381 -850 823 -452 409 -856 381 -840 417 -830 407 -852 379 -850 821 -422 827 -432 807 -448 821 -418 419 -850 803 -438 409 -810 407 -854 811 -448 809 -418 815 -446 419 -858 417 -814 811 -422 409 -838 421 -812 827 -434 415 -848 419 -816 411 -848 813 -456 805 -412 833 -418 413 -822 807 -452 817 -418 419 -850 803 -472 809 -420 397 -794 411 -17034 429 -394 435 -388 409 -386 411 -416 415 -384 415 -386 417 -386 417 -420 385 -420 383 -422 385 -422 417 -4022 805 -414 807 -448 407 -838 785 -454 809 -456 811 -412 833 -448 801 -454 809 -420 815 -420 409 -838 821 -420 813 -458 387 -876 787 -454 827 -432 385 -840 421 -814 429 -820 421 -836 421 -844 795 -436 409 -874 377 -866 383 -836 425 -824 409 -844 407 -822 415 -836 821 -434 409 -874 377 -866 387 -844 389 -854 397 -824 813 -450 813 -452 811 -412 831 -442 407 -864 783 -450 381 -840 419 -822 805 -442 809 -450 817 -448 419 -850 413 -814 813 -422 409 -840 419 -812 823 -434 415 -846 419 -818 409 -848 811 -458 805 -414 831 -416 415 -820 807 -450 801 -446 409 -864 819 -452 783 -428 393 -834 413 -17032 409 -432 363 -424 369 -448 375 -448 343 -450 375 -450 339 -454 375 -434 377 -432 351 -464 357 -436 389 -4050 773 -444 785 -466 385 -874 771 -452 793 -464 811 -446 803 -448 803 -454 809 -418 813 -422 411 -838 817 -448 781 -462 411 -846 797 -486 777 -438 415 -842 383 -850 403 -852 379 -848 405 -848 811 -448 415 -856 395 -856 387 -846 385 -834 391 -868 +RAW_Data: 387 -844 429 -852 781 -446 409 -862 419 -844 399 -824 385 -838 409 -854 811 -444 779 -452 815 -448 801 -472 385 -842 825 -434 387 -838 421 -812 827 -432 805 -450 819 -420 415 -850 411 -850 811 -422 393 -864 387 -846 787 -462 385 -876 385 -848 407 -848 811 -458 803 -414 831 -416 413 -852 773 -448 803 -446 405 -882 387 -113196 99 -362 163 -66 65 -1810 97 -66 165 -196 129 -98 523 -98 1525 -100 1095 -100 725 -66 6021 -66 261 -64 195 -98 293 -130 1745 -98 99 -132 397 -98 363 -98 199 -98 5181 -166 299 -66 429 -66 367 -66 431 -100 629 -134 1297 -98 229 -66 163 -100 4973 -132 995 -66 165 -98 395 -66 297 -66 1711 -200 5349 -100 1493 -232 663 -198 1721 -66 301 -100 5563 -66 1151 -66 331 -66 227 -66 97 -98 163 -100 65 -98 1975 -66 361 -66 97 -230 525 -66 657 -66 863 -66 4121 -230 231 -66 401 -132 129 -98 259 -98 263 -66 955 -100 327 -132 5011 -170 299 -64 763 -66 435 -100 297 -66 401 -132 827 -200 2287 -64 8629 -100 897 -66 1689 -100 2345 -132 97 -100 1155 -68 1915 -396 787 -66 1021 -130 1057 -100 267 -132 829 -100 4749 -68 599 -66 397 -100 329 -64 163 -296 99 -132 329 -66 4881 -66 2091 -66 165 -66 231 -98 359 -100 663 -98 297 -66 5775 -100 233 -98 699 -98 131 -66 361 -100 297 -66 331 -66 1017 -98 233 -66 231 -132 197 -98 1721 -130 523 -66 197 -98 953 -164 231 -164 231 -98 795 -100 1155 -66 753 -166 825 -66 4525 -98 955 -298 625 -66 885 -66 4759 -100 367 -66 495 -66 597 -100 465 -66 265 -100 601 -98 467 -230 463 -66 4177 -66 495 -66 693 -100 831 -66 431 -68 363 -132 295 -98 131 -166 265 -66 331 -100 3189 -66 395 -298 625 -64 327 -362 631 -66 333 -100 3927 -98 1743 -66 295 -100 197 -68 793 -66 891 -132 65 -100 5247 -132 427 -66 199 -66 263 -68 629 -68 297 -100 1345 -98 263 -66 693 -130 591 -68 263 -100 299 -66 399 -68 565 -200 231 -102 231 -100 497 -68 2259 -236 297 -66 663 -100 493 -98 133 -66 597 -132 265 -166 2459 -66 1857 -134 627 -100 827 -320 705 -354 695 -354 693 -354 721 -320 727 -322 733 -678 377 -358 677 -356 705 -644 381 -672 381 -348 691 -676 383 -672 415 -640 419 -324 697 -680 383 -650 381 -654 407 -658 365 -664 395 -382 685 -350 719 -350 653 -16570 709 -380 651 -384 687 -352 691 -346 701 -336 709 -362 715 -654 409 -352 681 -354 669 -678 383 -648 417 -326 711 -646 417 -648 413 -648 415 -326 711 -642 +RAW_Data: 383 -684 377 -656 367 -684 387 -672 385 -350 685 -384 685 -386 651 -16538 737 -332 705 -334 705 -332 705 -362 707 -320 719 -354 723 -646 417 -324 697 -354 693 -678 385 -652 379 -344 691 -698 361 -686 385 -654 417 -350 685 -652 385 -674 355 -700 357 -664 391 -664 393 -364 685 -364 709 -360 677 -16510 773 -310 695 -354 709 -320 733 -320 727 -322 729 -322 733 -680 387 -326 699 -352 693 -678 385 -648 381 -330 739 -648 415 -648 413 -650 413 -328 675 -682 379 -656 371 -688 353 -686 381 -652 413 -352 689 -386 693 -348 669 -16546 733 -348 697 -344 701 -346 699 -352 685 -354 721 -354 695 -644 423 -340 699 -332 711 -650 383 -652 419 -324 721 -642 419 -646 385 -680 387 -356 687 -646 387 -682 379 -656 401 -654 385 -654 383 -352 717 -352 723 -352 659 -16524 759 -324 697 -374 675 -358 679 -356 709 -352 703 -354 703 -680 375 -358 677 -354 709 -644 385 -680 385 -326 713 -680 385 -650 415 -648 415 -326 713 -648 383 -656 405 -654 385 -654 383 -652 413 -350 689 -386 693 -348 687 -16514 759 -322 699 -348 699 -336 721 -322 709 -354 707 -354 707 -680 385 -326 703 -354 691 -680 383 -638 417 -328 709 -646 419 -650 415 -648 413 -328 675 -682 381 -654 369 -688 385 -656 381 -684 381 -350 721 -354 695 -348 689 -16510 763 -322 697 -350 703 -350 701 -348 703 -350 701 -350 701 -678 379 -350 685 -350 697 -666 379 -662 395 -326 719 -654 417 -656 385 -650 409 -358 677 -680 377 -646 379 -686 367 -680 379 -662 395 -362 687 -364 709 -358 649 -16538 763 -324 699 -348 701 -346 687 -362 711 -322 707 -356 705 -682 377 -358 685 -354 707 -644 385 -682 385 -328 711 -648 417 -648 415 -648 415 -328 679 -684 379 -656 371 -686 353 -684 383 -684 381 -350 689 -386 687 -372 653 -16534 757 -328 689 -320 737 -320 729 -320 731 -320 729 -320 731 -644 407 -360 711 -320 707 -644 387 -650 419 -326 709 -644 423 -646 417 -648 415 -326 711 -646 383 -652 407 -656 387 -656 381 -654 413 -352 689 -352 723 -338 689 -16532 729 -328 711 -354 703 -320 695 -352 727 -322 727 -322 733 -678 375 -358 685 -354 671 -678 385 -648 417 -328 709 -646 417 -648 415 -650 413 -328 679 -684 379 -656 371 -664 393 -652 387 -684 383 -350 723 -350 695 -348 665 -16554 763 -308 713 -322 713 -322 731 -320 729 -322 727 -320 735 -678 387 -326 701 -356 689 -678 385 -650 381 -346 725 -652 387 -654 415 -644 415 -354 685 -654 383 -674 355 -662 391 -662 391 -664 395 -364 687 -362 +RAW_Data: 713 -326 679 -123960 161 -132 263 -624 263 -66 327 -162 131 -1094 131 -98 723 -66 621 -66 459 -66 229 -66 329 -66 591 -66 881 -66 3747 -66 1783 -66 3219 -68 263 -100 695 -66 165 -66 99 -66 1193 -98 531 -234 263 -68 7149 -66 461 -100 3253 -66 595 -134 561 -66 325 -66 685 -66 199 -98 359 -130 99 -98 787 -100 925 -100 5157 -66 591 -98 233 -100 827 -66 1345 -66 10323 -200 3355 -100 367 -100 965 -98 495 -98 233 -102 1923 -66 6641 -68 263 -68 299 -100 705 -198 827 -100 529 -68 625 -66 493 -66 3641 -98 897 -68 333 -100 6513 -68 825 -66 597 -132 231 -100 659 -100 1099 -102 963 -98 831 -68 261 -68 299 -134 4477 -66 561 -66 927 -98 393 -66 1871 -166 327 -132 229 -100 63 -66 561 -1216 479 -414 205 -636 517 -358 235 -642 243 -612 237 -628 227 -614 237 -682 241 -604 269 -628 525 -336 513 -348 537 -346 245 -600 513 -326 265 -644 279 -606 273 -596 257 -620 281 -556 281 -594 553 -314 283 -572 549 -324 299 -586 317 -550 567 -310 319 -558 555 -300 315 -554 281 -572 571 -324 557 -312 279 -598 289 -578 313 -552 577 -320 533 -312 559 -290 573 -342 285 -580 525 -350 279 -594 547 -318 283 -578 559 -310 269 -568 567 -346 281 -578 311 -564 545 -328 545 -350 513 -318 561 -316 283 -572 253 -628 579 -316 541 -318 279 -602 289 -574 313 -552 283 -560 555 -320 531 -288 1123 -1164 537 -332 279 -576 581 -320 283 -578 277 -568 287 -568 305 -550 315 -590 315 -564 275 -600 545 -328 543 -314 559 -320 285 -546 561 -310 285 -628 263 -608 283 -584 281 -600 269 -596 291 -558 549 -314 287 -554 577 -350 281 -598 257 -582 581 -320 283 -582 527 -344 269 -566 303 -548 579 -318 593 -314 283 -564 291 -578 313 -558 545 -318 571 -314 525 -292 569 -336 319 -562 569 -312 283 -596 549 -300 317 -556 553 -320 275 -566 543 -362 281 -594 281 -580 555 -324 541 -340 549 -318 543 -320 283 -540 309 -596 555 -338 549 -318 281 -580 311 -562 291 -578 275 -586 547 -320 511 -318 1099 -1150 557 -336 283 -594 539 -318 317 -534 291 -606 273 -552 317 -556 283 -604 287 -600 277 -586 547 -348 533 -320 541 -340 285 -542 565 -302 277 -632 283 -572 287 -594 303 -576 283 -594 283 -544 565 -310 285 -562 547 -362 283 -594 279 -580 551 -322 285 -604 553 -318 285 -548 281 -602 527 -346 557 -326 277 -588 283 -596 281 -578 553 -294 571 -302 551 -314 549 -352 279 -602 545 -324 275 -590 545 -318 319 -540 555 -324 279 -560 +RAW_Data: 545 -350 317 -574 273 -594 557 -302 549 -352 521 -318 567 -294 277 -582 275 -624 537 -340 565 -290 301 -582 319 -566 285 -568 299 -544 547 -316 549 -318 1103 -1150 543 -326 275 -586 547 -352 281 -574 309 -562 257 -588 275 -590 283 -592 317 -574 271 -594 557 -336 549 -318 543 -318 283 -574 547 -290 283 -634 283 -584 277 -600 257 -604 311 -556 317 -560 541 -320 283 -538 583 -320 297 -582 317 -564 567 -314 283 -562 581 -298 313 -548 283 -572 539 -354 555 -346 245 -598 289 -580 313 -552 575 -316 535 -292 569 -304 547 -348 279 -602 555 -326 279 -594 551 -320 283 -546 565 -310 285 -562 547 -364 283 -594 281 -600 525 -344 557 -290 565 -314 555 -320 287 -562 283 -580 585 -322 555 -310 283 -588 317 -538 309 -564 289 -576 543 -312 549 -320 1071 -1150 579 -290 301 -584 545 -352 283 -574 273 -566 291 -582 277 -588 283 -592 279 -610 273 -596 557 -300 549 -352 533 -316 279 -580 543 -312 285 -596 315 -568 307 -564 291 -580 313 -556 283 -584 537 -316 283 -570 545 -356 307 -590 283 -562 565 -346 247 -594 553 -302 279 -590 283 -570 541 -356 557 -310 279 -600 289 -576 313 -554 545 -316 565 -288 569 -302 547 -348 279 -598 557 -334 283 -572 541 -322 283 -600 547 -320 245 -598 543 -328 313 -574 285 -596 533 -342 549 -316 535 -332 531 -330 273 -586 281 -606 541 -322 565 -312 279 -600 289 -576 275 -588 281 -572 571 -290 543 -304 1117 -1144 557 -326 281 -592 547 -320 281 -580 311 -564 257 -602 275 -586 283 -590 315 -572 273 -594 555 -336 549 -318 523 -320 283 -578 557 -294 277 -618 317 -560 315 -568 273 -602 257 -604 277 -590 547 -318 285 -564 537 -350 317 -560 293 -598 551 -320 283 -564 565 -312 283 -562 291 -580 543 -348 555 -318 283 -602 257 -604 275 -590 545 -318 537 -348 527 -292 569 -336 319 -560 535 -348 283 -596 551 -298 313 -556 545 -318 277 -564 579 -330 283 -594 279 -600 523 -344 561 -290 567 -312 549 -318 283 -566 279 -600 549 -324 585 -308 285 -588 281 -600 277 -572 273 -594 551 -298 543 -312 1077 -1150 585 -290 289 -606 547 -316 319 -540 309 -566 289 -576 275 -586 281 -622 277 -570 291 -602 543 -314 547 -318 569 -312 283 -564 545 -328 273 -618 283 -578 309 -562 291 -580 313 -556 283 -586 537 -314 283 -570 577 -320 311 -588 283 -598 527 -346 269 -564 573 -312 285 -554 317 -564 539 -352 553 -322 291 -578 283 -594 281 -566 563 -302 563 -292 569 -312 549 -348 281 -598 529 -340 283 -570 +RAW_Data: 573 -290 285 -604 549 -318 245 -598 545 -358 281 -572 287 -596 567 -310 547 -320 535 -316 561 -294 277 -586 277 -624 557 -316 561 -326 281 -558 171 -112742 297 -66 231 -100 133 -98 131 -66 231 -66 65 -330 231 -790 165 -400 99 -434 459 -66 233 -132 1581 -98 163 -66 1049 -132 1849 -100 1855 -98 5435 -100 301 -68 761 -66 3115 -100 231 -68 2421 -68 765 -66 167 -68 233 -134 997 -66 233 -66 1061 -66 833 -98 565 -66 369 -102 131 -100 5197 -132 853 -232 825 -100 265 -100 765 -100 631 -66 827 -66 1749 -66 265 -136 165 -66 399 -100 3821 -98 793 -66 599 -100 231 -68 635 -68 197 -134 5091 -132 299 -68 1327 -100 757 -98 629 -66 601 -66 2887 -100 1167 -98 1879 -66 131 -98 295 -162 7033 -66 655 -68 1025 -100 261 -66 295 -66 195 -132 65 -66 9407 -100 4337 -68 795 -100 361 -132 99 -66 4915 -198 819 -100 327 -64 1611 -132 429 -100 331 -66 4037 -68 729 -66 827 -398 2751 -66 295 -66 4365 -98 1187 -66 389 -100 231 -166 1945 -66 431 -450 587 -458 587 -458 587 -458 587 -458 625 -424 623 -748 309 -424 627 -392 657 -716 343 -720 307 -408 657 -694 365 -692 365 -694 363 -410 653 -382 651 -382 651 -716 321 -704 355 -702 357 -370 717 -368 673 -364 675 -16544 735 -352 673 -362 677 -356 709 -320 733 -320 733 -352 703 -680 385 -358 669 -354 693 -678 381 -638 417 -328 709 -646 417 -646 417 -648 413 -326 713 -326 713 -326 713 -648 415 -650 379 -652 409 -346 723 -346 721 -346 653 -16532 777 -296 703 -360 709 -326 709 -348 689 -352 727 -320 731 -678 385 -326 701 -354 691 -678 385 -650 381 -346 725 -652 385 -656 415 -656 381 -386 685 -352 689 -330 711 -650 385 -652 419 -648 385 -328 751 -320 727 -352 671 -16536 757 -318 709 -320 731 -322 695 -352 725 -322 727 -322 731 -678 381 -348 705 -320 697 -676 383 -670 381 -346 687 -678 385 -680 383 -682 385 -326 717 -324 717 -326 711 -672 385 -650 415 -650 379 -330 737 -324 749 -320 699 -16538 747 -328 681 -354 705 -320 733 -320 729 -320 729 -354 703 -678 377 -358 677 -356 703 -642 385 -680 385 -328 711 -680 385 -650 417 -646 417 -326 713 -326 711 -326 713 -646 417 -650 379 -652 411 -344 725 -346 723 -346 653 -16538 707 -404 657 -376 653 -380 687 -382 655 -382 691 -380 679 -668 395 -366 671 -360 675 -682 381 -650 383 -358 687 -680 383 -682 383 -682 385 -326 715 -326 713 -326 715 -682 385 -650 379 -654 409 -346 723 -346 723 -348 651 -16540 743 -324 +RAW_Data: 713 -324 717 -356 687 -354 687 -354 727 -320 729 -682 379 -350 671 -354 693 -678 381 -672 379 -350 687 -678 381 -672 381 -674 413 -348 667 -356 691 -354 689 -678 381 -672 379 -672 381 -350 721 -320 727 -354 671 -16544 747 -328 689 -354 703 -320 731 -320 729 -320 729 -322 733 -680 385 -326 701 -354 693 -678 385 -650 381 -344 693 -686 387 -670 387 -670 385 -350 685 -352 689 -350 695 -672 363 -688 393 -660 395 -328 741 -332 711 -360 685 -16498 781 -328 679 -354 707 -320 731 -318 729 -320 731 -320 733 -680 373 -360 687 -352 705 -642 389 -648 419 -326 707 -646 419 -648 417 -648 415 -326 711 -326 711 -324 713 -646 419 -648 381 -652 409 -346 725 -348 719 -348 651 -16530 775 -298 703 -360 709 -326 711 -326 713 -354 723 -320 725 -646 409 -358 677 -354 707 -644 385 -650 417 -328 709 -646 419 -648 417 -650 415 -326 711 -326 711 -326 711 -648 381 -684 379 -652 407 -346 723 -346 689 -382 651 -16542 739 -316 715 -324 715 -350 689 -354 723 -322 725 -322 729 -680 375 -358 677 -354 705 -644 385 -680 385 -328 713 -678 387 -650 415 -650 413 -328 711 -326 711 -326 713 -648 381 -684 379 -652 407 -346 723 -346 717 -316 705 -16506 781 -288 717 -354 689 -356 687 -354 723 -320 725 -320 731 -680 381 -348 705 -320 695 -676 381 -672 381 -346 687 -678 381 -674 381 -672 419 -324 695 -356 687 -354 687 -678 385 -650 381 -682 379 -346 727 -346 721 -346 653 -16534 739 -346 693 -342 699 -344 699 -342 731 -346 687 -382 685 -686 383 -352 683 -352 689 -680 357 -664 391 -362 687 -654 409 -662 395 -662 393 -366 671 -360 679 -354 703 -646 419 -646 385 -648 417 -328 711 -354 725 -354 671 -16506 783 -316 705 -322 729 -320 727 -320 727 -320 727 -352 703 -678 377 -358 677 -354 707 -644 381 -672 383 -346 691 -678 381 -672 415 -638 419 -326 699 -354 689 -350 689 -678 381 -672 381 -672 383 -348 721 -322 727 -354 669 -16544 747 -328 689 -352 703 -320 727 -320 727 -322 731 -322 733 -680 385 -326 701 -356 691 -678 385 -650 379 -346 689 -686 387 -670 387 -654 417 -352 683 -354 689 -346 687 -656 377 -686 379 -666 393 -362 687 -364 715 -358 649 -129582 163 -694 263 -100 197 -68 199 -166 199 -100 131 -200 65 -662 629 -66 625 -164 65 -100 987 -66 587 -66 163 -66 95 -66 4701 -300 1593 -66 587 -98 587 -98 1907 -100 4575 -264 195 -296 1449 -132 161 -132 195 -66 359 -132 129 -66 5365 -66 65 -132 595 -100 731 -134 299 -68 1361 -100 +RAW_Data: 3975 -100 1023 -98 197 -132 887 -98 195 -100 261 -100 229 -132 1677 -98 5099 -132 1973 -98 2701 -130 4541 -102 165 -66 163 -66 163 -132 591 -66 791 -66 199 -102 4581 -68 1487 -100 161 -98 2113 -66 469 -66 3741 -100 4299 -66 163 -64 391 -166 65 -66 2619 -100 399 -66 4573 -66 2117 -132 6427 -66 1019 -132 529 -66 165 -66 797 -200 165 -102 199 -66 4713 -68 3163 -232 993 -100 363 -98 267 -66 5573 -98 263 -98 261 -66 197 -66 131 -100 2179 -264 4751 -166 467 -100 1727 -100 233 -100 2019 -100 4073 -66 861 -132 1359 -134 201 -66 235 -430 297 -66 599 -68 727 -100 263 -68 265 -68 4727 -100 499 -64 199 -134 65 -66 329 -100 97 -164 525 -64 485 -64 5219 -66 1149 -66 229 -230 1713 -66 131 -98 97 -66 1053 -66 5951 -66 2599 -100 131 -132 955 -132 259 -132 97 -66 99 -98 691 -66 889 -66 4877 -132 1543 -66 1147 -132 65 -298 793 -100 1329 -66 563 -66 595 -232 231 -66 165 -134 4975 -100 791 -100 231 -66 793 -68 1393 -100 463 -132 597 -132 165 -100 4941 -98 425 -132 165 -132 65 -68 231 -66 1033 -66 1003 -132 5379 -166 1745 -66 5759 -66 719 -200 2589 -66 5447 -66 2057 -234 1721 -100 467 -66 5485 -100 65 -66 1187 -134 599 -68 1131 -64 5741 -230 131 -66 819 -100 297 -68 133 -68 231 -132 5413 -100 131 -166 1157 -264 331 -66 727 -66 1283 -66 1513 -98 593 -66 265 -102 233 -66 797 -100 165 -134 665 -100 791 -132 99 -168 5317 -100 299 -100 929 -66 429 -66 835 -100 763 -100 165 -100 3941 -68 231 -68 699 -68 231 -68 1091 -66 299 -100 265 -100 365 -200 531 -66 761 -100 365 -68 5283 -100 299 -100 563 -166 999 -66 657 -132 5585 -64 131 -98 97 -132 361 -66 555 -98 293 -66 1247 -66 521 -196 263 -66 497 -132 6527 -66 399 -66 729 -100 197 -68 6605 -66 1115 -132 919 -98 7149 -66 1297 -66 197 -100 1151 -98 463 -266 197 -98 427 -68 891 -68 3379 -66 397 -68 67 -100 297 -98 983 -232 165 -132 883 -68 3773 -66 263 -64 653 -166 795 -100 397 -98 5091 -68 429 -66 297 -164 227 -98 621 -164 691 -130 2735 -64 1513 -98 299 -66 963 -166 333 -66 993 -100 4049 -66 555 -100 293 -98 815 -64 133 -66 729 -66 165 -66 1493 -66 1183 -234 165 -66 267 -202 1031 -100 693 -64 261 -66 261 -66 4057 -98 327 -98 425 -98 291 -100 65 -100 931 -68 297 -68 527 -68 463 -66 5135 -66 163 -98 5887 -4482 477 -1448 469 -1438 479 -1430 485 -518 467 -1440 451 -532 451 -1440 477 -1444 +RAW_Data: 471 -1474 451 -1446 481 -518 449 -1446 483 -514 475 -520 445 -502 491 -546 453 -1470 449 -1450 473 -1432 473 -1444 479 -482 473 -1460 461 -1404 481 -1484 461 -1444 449 -1446 483 -1440 477 -522 453 -1436 479 -1414 479 -1428 473 -1444 481 -1444 471 -1440 481 -1426 473 -1446 483 -520 451 -508 491 -1402 481 -1448 469 -1474 447 -556 443 -538 467 -514 481 -518 449 -1432 483 -482 485 -1418 4439 -4500 485 -1452 479 -1408 507 -1412 479 -504 495 -1406 483 -526 449 -1432 479 -1444 471 -1450 477 -1448 469 -516 479 -1430 481 -522 449 -510 475 -488 503 -522 481 -1466 461 -1446 447 -1448 481 -1442 477 -484 481 -1440 477 -1410 481 -1456 459 -1438 479 -520 483 -506 481 -538 463 -514 479 -1408 469 -516 481 -514 509 -1440 477 -518 451 -1436 483 -524 485 -478 475 -1444 469 -514 477 -540 477 -1438 475 -520 485 -1402 485 -1420 487 -1436 473 -512 463 -514 479 -1404 4423 -4516 489 -1442 483 -1420 473 -1440 471 -506 481 -1426 471 -512 471 -1408 483 -1484 463 -1442 475 -1448 465 -514 481 -1438 477 -484 481 -512 473 -490 499 -548 481 -1420 469 -1442 487 -1418 481 -1446 463 -516 479 -1408 471 -1442 449 -1486 461 -514 481 -524 491 -510 479 -1404 509 -1410 481 -500 491 -478 475 -1476 479 -520 489 -1434 451 -526 489 -1402 483 -524 487 -1404 479 -490 481 -1468 485 -1426 473 -1440 487 -524 451 -1454 477 -508 463 -1406 483 -492 483 -1406 4439 -4518 491 -1438 481 -1420 471 -1442 487 -522 451 -1418 479 -506 495 -1404 481 -1444 503 -1418 479 -1446 469 -516 481 -1438 479 -486 483 -506 475 -520 473 -522 479 -1464 459 -1436 475 -1444 467 -1442 481 -496 491 -1404 481 -1412 481 -1462 457 -1468 481 -514 475 -1412 483 -512 475 -1444 465 -1408 483 -1414 481 -538 507 -516 485 -512 477 -514 475 -492 503 -490 483 -1414 481 -1426 487 -514 509 -516 451 -542 475 -1430 479 -1414 479 -504 493 -514 475 -482 473 -1428 4417 -4510 483 -1440 481 -1452 475 -1438 461 -512 479 -1416 487 -506 489 -1406 479 -1448 487 -1444 459 -1434 479 -520 487 -1414 477 -518 473 -502 479 -504 491 -546 449 -1466 485 -1416 471 -1438 481 -1414 493 -514 477 -1406 471 -1442 483 -1456 461 -518 483 -1446 471 -514 479 -520 485 -476 477 -516 473 -1428 481 -1440 481 -1448 473 -512 473 -1436 481 -1426 473 -512 481 -1416 481 -1426 473 -1444 475 -518 507 -1422 491 -1436 481 -496 489 -1404 481 -1418 481 -502 491 -1400 4449 -4492 493 -1438 481 -1422 469 -1444 487 -522 449 -1450 471 -486 475 -1440 483 -1454 459 -1440 479 -1446 469 -516 481 -1436 477 -486 483 -510 475 -488 501 -518 421 -129440 263 -162 65 -362 +RAW_Data: 129 -264 65 -266 199 -132 67 -332 99 -98 3287 -100 4663 -132 4127 -98 331 -68 99 -66 5149 -200 1759 -66 65 -100 1051 -132 619 -66 5371 -132 1873 -232 195 -130 657 -132 357 -66 229 -66 4517 -100 365 -64 2447 -132 261 -66 633 -100 1153 -100 593 -132 259 -66 1589 -134 229 -66 65 -66 99 -66 491 -66 3789 -100 2059 -102 301 -66 663 -98 327 -98 5013 -98 4239 -164 987 -98 197 -66 163 -66 1479 -100 897 -66 99 -166 827 -66 465 -100 67 -100 563 -100 5179 -66 2043 -100 985 -66 1355 -66 431 -66 729 -232 165 -352 689 -346 685 -364 709 -322 709 -354 705 -354 701 -680 377 -360 675 -356 709 -644 385 -682 383 -328 711 -680 383 -648 415 -648 415 -328 711 -318 717 -326 713 -680 383 -650 379 -684 377 -330 741 -324 717 -354 691 -16506 751 -352 703 -322 693 -354 693 -354 725 -320 729 -322 731 -680 383 -356 669 -354 695 -678 385 -650 379 -344 691 -696 363 -686 387 -686 383 -352 685 -350 691 -346 699 -668 365 -684 367 -682 379 -366 685 -362 709 -360 677 -16540 731 -354 667 -352 699 -350 689 -362 711 -322 713 -354 707 -680 387 -326 737 -320 691 -676 383 -638 417 -316 715 -676 387 -648 421 -644 419 -326 711 -326 709 -326 713 -642 421 -648 415 -618 413 -346 725 -348 721 -314 685 -16528 775 -298 733 -326 709 -326 711 -324 715 -350 725 -320 731 -646 421 -326 699 -354 689 -678 383 -638 415 -318 711 -678 387 -648 417 -648 417 -326 715 -324 707 -318 717 -678 387 -648 381 -684 379 -346 725 -346 719 -348 651 -16544 741 -352 691 -354 687 -356 691 -348 691 -326 747 -320 743 -646 407 -330 725 -320 707 -644 389 -648 423 -296 735 -646 421 -648 417 -646 417 -326 707 -326 709 -324 711 -646 421 -648 381 -652 411 -346 725 -314 753 -316 683 -16546 649 -538 489 -574 455 -574 487 -542 557 -442 593 -474 575 -802 263 -464 599 -428 605 -752 319 -716 321 -422 639 -720 351 -720 319 -730 361 -366 669 -362 673 -356 705 -684 345 -686 381 -682 383 -326 715 -356 723 -354 669 -16540 747 -330 715 -320 707 -320 731 -320 729 -322 729 -354 701 -680 377 -358 675 -356 707 -646 381 -672 383 -328 717 -678 385 -680 383 -648 415 -326 717 -326 713 -326 713 -646 417 -652 379 -686 375 -346 723 -346 721 -346 653 -16542 775 -316 693 -354 687 -348 699 -354 691 -348 719 -332 711 -658 403 -354 677 -356 707 -644 385 -682 385 -328 713 -646 419 -650 415 -648 415 -326 713 -326 713 -326 711 -646 417 -648 379 -652 411 -344 725 -346 721 -346 +RAW_Data: 653 -16540 741 -348 691 -348 685 -354 687 -350 697 -378 705 -332 719 -652 405 -352 677 -354 705 -644 385 -682 387 -326 713 -646 419 -648 415 -650 415 -326 713 -326 713 -326 713 -646 381 -684 379 -652 407 -346 723 -346 719 -314 705 -16508 781 -290 715 -354 687 -354 689 -354 723 -320 729 -320 731 -646 419 -324 701 -354 689 -680 385 -650 379 -350 711 -648 417 -648 413 -638 415 -326 715 -324 713 -324 713 -648 417 -650 379 -652 411 -344 725 -346 723 -348 651 -16538 745 -324 711 -324 717 -324 717 -354 687 -352 725 -322 727 -678 375 -360 685 -354 705 -644 385 -648 419 -326 709 -648 419 -648 413 -650 415 -326 707 -318 715 -326 713 -646 419 -648 379 -684 379 -344 725 -346 719 -348 653 -16544 741 -336 697 -334 703 -332 737 -328 707 -326 717 -352 725 -646 415 -348 671 -352 693 -678 381 -638 415 -318 715 -678 383 -672 383 -674 383 -348 693 -354 687 -356 689 -678 387 -648 381 -684 379 -332 737 -326 745 -320 695 -16504 781 -286 737 -322 693 -354 691 -354 727 -318 729 -322 731 -680 381 -348 705 -320 697 -678 383 -650 381 -360 707 -648 415 -650 413 -650 413 -326 677 -362 675 -360 711 -648 381 -684 379 -654 405 -344 723 -346 685 -382 651 -16544 743 -350 689 -352 685 -352 691 -346 685 -364 709 -358 711 -650 407 -352 679 -354 671 -678 385 -648 417 -328 709 -648 415 -648 415 -648 413 -328 677 -360 711 -328 713 -648 381 -684 377 -656 405 -346 689 -380 687 -382 653 -16540 741 -352 689 -320 719 -354 689 -336 719 -322 711 -352 707 -680 407 -328 709 -322 711 -644 387 -680 385 -328 711 -678 385 -648 417 -648 415 -326 715 -326 713 -326 711 -648 419 -648 381 -652 409 -346 723 -348 719 -348 651 -130012 261 -132 261 -198 199 -130 791 -66 531 -66 231 -100 463 -66 299 -66 299 -100 785 -332 131 -66 267 -66 4069 -66 657 -100 589 -100 129 -100 523 -166 1325 -66 99 -132 4995 -98 429 -132 1151 -100 231 -130 361 -98 261 -66 1709 -98 165 -98 4413 -100 723 -132 63 -66 259 -98 359 -66 427 -68 665 -266 297 -330 961 -166 2625 -66 763 -98 65 -98 327 -166 463 -198 269 -100 529 -132 97 -98 227 -66 259 -162 327 -198 429 -66 295 -66 133 -162 3959 -234 789 -266 97 -230 827 -98 129 -100 97 -66 97 -66 361 -98 65 -66 525 -100 165 -64 757 -266 163 -166 3769 -166 563 -132 399 -68 563 -68 363 -66 133 -100 263 -66 529 -100 1065 -102 989 -132 1091 -100 729 -66 497 -98 133 -66 67 -98 565 -66 265 -234 +RAW_Data: 467 -166 499 -100 97 -66 4339 -100 165 -134 2121 -66 697 -134 531 -100 3557 -100 829 -130 461 -98 263 -300 199 -68 199 -66 733 -66 431 -132 365 -66 435 -66 637 -68 2411 -66 821 -66 65 -100 331 -100 693 -66 527 -200 131 -268 1959 -66 363 -464 5279 -132 199 -66 165 -200 329 -64 197 -98 1511 -132 525 -66 4411 -66 99 -100 131 -66 1161 -100 431 -66 165 -66 4607 -66 337 -68 267 -134 1623 -66 497 -66 295 -100 401 -100 65 -100 4201 -66 165 -68 233 -168 825 -100 599 -100 1857 -68 2819 -66 325 -164 359 -98 131 -298 99 -66 197 -66 4209 -100 1031 -66 131 -100 263 -66 267 -66 363 -100 1163 -132 633 -102 3097 -100 799 -66 265 -66 331 -100 763 -134 897 -100 333 -66 599 -66 467 -132 99 -66 3491 -66 821 -66 327 -66 557 -164 661 -68 165 -362 197 -98 757 -98 99 -98 525 -98 557 -134 1027 -132 197 -66 663 -100 991 -66 493 -68 131 -132 863 -132 529 -132 165 -102 397 -66 4095 -200 2929 -66 689 -66 397 -66 229 -98 163 -96 163 -98 227 -66 1063 -330 165 -66 495 -100 1021 -66 2569 -132 667 -134 331 -66 329 -64 555 -100 329 -66 227 -230 2225 -66 5081 -98 265 -66 669 -132 363 -100 265 -66 263 -132 731 -100 497 -98 199 -100 431 -166 233 -100 3069 -66 721 -132 329 -64 795 -66 535 -66 265 -100 531 -66 233 -3824 129 -706 305 -696 295 -688 323 -686 351 -644 353 -646 373 -644 375 -592 427 -584 421 -1078 909 -610 413 -602 399 -1080 451 -554 951 -1078 937 -552 455 -548 451 -1084 949 -1046 971 -516 481 -1046 449 -554 473 -542 475 -516 983 -1046 947 -552 451 -530 493 -1042 973 -522 473 -538 473 -540 471 -1040 975 -1006 477 -550 473 -508 1001 -522 487 -534 465 -548 451 -1044 447 -51358 455 -608 373 -628 365 -654 355 -652 353 -658 373 -640 373 -600 401 -618 389 -614 383 -622 415 -566 443 -580 407 -590 425 -1080 943 -564 413 -578 445 -1062 455 -548 943 -1078 947 -562 463 -548 451 -1044 967 -1050 983 -518 487 -1008 477 -524 485 -538 477 -510 1007 -1010 973 -556 453 -546 467 -1042 973 -542 447 -556 473 -510 475 -1044 979 -1016 499 -514 481 -526 991 -514 479 -522 483 -536 487 -1012 493 -51302 493 -3786 199 -670 339 -656 329 -684 321 -646 385 -628 373 -646 375 -626 365 -618 419 -586 417 -1088 909 -610 407 -590 427 -1082 415 -576 939 -1080 941 -584 425 -1074 941 -542 443 -1078 973 -1046 451 -548 445 -550 967 -554 475 -508 473 -1044 977 -1054 957 -1044 465 -516 483 -546 975 -520 485 -1048 461 -514 +RAW_Data: 483 -546 445 -552 975 -1018 979 -552 455 -1044 977 -51850 457 -4674 299 -704 305 -694 297 -720 323 -654 355 -626 385 -642 341 -632 401 -620 389 -1116 883 -610 413 -602 401 -1112 419 -552 943 -1066 937 -590 427 -1078 449 -556 951 -1044 475 -556 921 -1076 445 -550 981 -1030 985 -1012 485 -522 977 -528 495 -1010 479 -554 975 -506 479 -538 473 -548 453 -544 481 -1010 473 -554 985 -530 465 -514 481 -546 479 -1010 473 -556 475 -51320 459 -688 263 -754 225 -750 289 -742 297 -640 339 -658 365 -652 355 -648 353 -644 363 -640 375 -626 397 -586 419 -584 417 -1104 911 -578 445 -560 429 -1080 449 -554 937 -1082 941 -1082 947 -558 421 -584 449 -1034 455 -548 483 -516 479 -540 967 -1050 977 -520 489 -1038 443 -552 471 -538 967 -554 453 -540 467 -1042 977 -522 469 -544 477 -1016 481 -514 1009 -1014 481 -534 963 -1044 977 -554 443 -111144 233 -134 197 -196 131 -132 2559 -98 699 -98 233 -100 895 -100 897 -98 297 -230 295 -64 527 -66 895 -132 65 -98 4231 -134 667 -100 65 -66 297 -100 231 -102 563 -100 2053 -300 3873 -100 957 -66 291 -66 1225 -66 1095 -100 1029 -98 235 -100 4947 -66 131 -132 1159 -232 4881 -130 1649 -130 429 -66 463 -66 327 -266 133 -66 5073 -66 229 -100 697 -134 1353 -66 133 -130 4655 -264 299 -132 1065 -100 65 -100 199 -66 631 -66 1531 -98 233 -100 4353 -66 661 -100 233 -66 167 -68 1657 -66 267 -100 397 -98 761 -66 493 -68 761 -64 823 -98 525 -98 163 -66 197 -98 231 -66 167 -66 133 -98 953 -66 689 -66 735 -66 163 -98 229 -100 595 -168 195 -130 263 -132 957 -66 493 -98 65 -132 723 -98 431 -166 4275 -132 333 -100 97 -68 827 -66 491 -198 327 -264 4271 -134 1087 -100 797 -134 131 -302 695 -66 261 -236 465 -66 4191 -66 663 -100 433 -66 1325 -100 229 -132 295 -100 261 -100 431 -66 531 -130 195 -98 4647 -66 229 -66 359 -264 525 -98 365 -232 165 -264 457 -100 231 -66 629 -366 229 -66 3411 -68 1163 -132 763 -66 165 -66 1657 -66 393 -132 521 -262 5821 -132 1221 -98 129 -100 1345 -66 425 -198 165 -66 525 -66 299 -100 465 -66 497 -100 599 -298 4711 -100 397 -66 99 -132 627 -66 793 -98 327 -98 97 -68 265 -66 99 -98 265 -1152602 163 -1918 65 -330 197 -98 97 -198 721 -66 897 -232 4175 -166 299 -134 299 -132 331 -100 363 -66 499 -166 527 -98 1327 -68 931 -66 701 -198 265 -298 131 -100 301 -132 1029 -132 295 -134 3515 -66 197 -100 427 -100 99 -100 165 -98 231 -100 +RAW_Data: 4709 -232 163 -66 129 -96 1557 -100 229 -64 621 -100 4377 -100 1895 -66 2321 -66 4485 -66 167 -66 67 -66 1395 -68 65 -132 429 -134 1855 -68 231 -100 5991 -366 629 -100 2525 -68 233 -264 295 -98 853 -132 4433 -66 163 -66 457 -98 657 -66 331 -66 825 -66 785 -166 293 -66 559 -100 4747 -228 887 -66 895 -130 1457 -100 6935 -100 229 -66 329 -162 1051 -66 461 -100 97 -100 4427 -66 859 -68 299 -100 165 -100 1249 -132 197 -198 4129 -66 299 -268 927 -164 557 -98 261 -66 2419 -66 4739 -100 97 -66 2309 -66 97 -66 987 -198 325 -64 5109 -66 199 -100 1059 -66 723 -100 763 -100 5355 -98 201 -134 265 -100 165 -100 827 -66 595 -100 297 -100 231 -132 4787 -100 361 -100 429 -200 733 -66 633 -66 531 -330 4215 -68 1361 -200 5943 -66 1117 -132 953 -66 261 -132 199 -134 235 -200 261 -66 165 -132 65 -98 395 -266 197 -98 791 -134 229 -100 1195 -68 363 -100 99 -66 525 -98 759 -66 663 -98 163 -98 3411 -100 1033 -132 133 -134 133 -100 363 -100 663 -66 131 -66 331 -100 299 -134 65 -66 1025 -100 397 -66 2051 -66 697 -66 605 -390 415 -398 409 -400 393 -438 387 -410 387 -410 385 -448 383 -414 385 -416 387 -416 387 -448 387 -4030 787 -422 449 -810 425 -816 423 -838 417 -844 399 -852 805 -456 811 -412 837 -418 415 -814 823 -434 385 -878 385 -848 799 -474 383 -850 819 -452 405 -820 385 -844 415 -842 403 -848 809 -456 779 -446 417 -862 413 -814 417 -852 785 -452 799 -436 811 -450 415 -832 807 -444 411 -838 803 -446 407 -850 807 -410 807 -452 819 -418 817 -448 815 -434 809 -450 409 -840 817 -418 417 -818 417 -862 773 -476 773 -450 803 -446 409 -866 419 -848 793 -436 387 -838 419 -846 793 -438 415 -846 409 -846 811 -446 813 -422 423 -838 783 -448 413 -838 379 -866 807 -450 383 -862 807 -450 813 -412 415 -816 387 -15812 443 -358 433 -386 409 -386 447 -350 451 -382 419 -384 421 -384 419 -386 421 -386 421 -388 419 -388 419 -4024 837 -410 415 -814 421 -848 399 -822 413 -850 419 -824 841 -444 809 -422 815 -416 413 -842 801 -438 411 -844 409 -846 811 -446 413 -832 841 -414 409 -840 419 -812 425 -820 393 -866 811 -418 841 -430 415 -846 419 -820 405 -850 807 -418 819 -416 809 -454 395 -854 817 -450 419 -848 807 -412 413 -850 785 -450 811 -432 809 -412 837 -416 831 -458 811 -452 389 -854 787 -454 407 -824 413 -814 821 -448 815 -432 809 -450 395 -864 421 -814 827 -434 387 -840 421 -814 +RAW_Data: 825 -434 415 -846 421 -816 837 -444 809 -420 423 -806 813 -450 383 -840 417 -864 807 -444 381 -848 821 -454 805 -434 379 -806 417 -15798 421 -428 321 -504 321 -474 323 -508 293 -508 325 -468 323 -476 365 -444 365 -444 333 -466 359 -464 331 -4092 749 -490 351 -870 381 -882 361 -888 381 -838 411 -860 807 -450 815 -434 809 -414 417 -824 803 -442 413 -846 417 -854 773 -476 381 -882 793 -426 413 -844 387 -854 397 -826 417 -848 787 -462 813 -448 395 -864 419 -812 429 -818 821 -418 809 -448 783 -460 411 -846 785 -486 399 -850 811 -414 415 -828 801 -442 809 -450 789 -456 807 -452 785 -458 805 -450 411 -836 819 -418 419 -820 415 -830 805 -474 777 -450 815 -450 417 -852 413 -812 811 -424 411 -838 419 -844 795 -436 385 -878 409 -844 809 -444 813 -424 423 -838 777 -450 413 -842 399 -860 777 -448 413 -868 803 -448 791 -424 411 -812 413 -15768 435 -396 429 -358 435 -378 411 -410 413 -380 439 -394 409 -406 379 -412 407 -414 409 -382 413 -410 417 -3998 837 -414 409 -840 421 -810 427 -820 421 -838 421 -844 797 -472 805 -418 815 -408 419 -850 799 -438 415 -816 421 -852 799 -438 411 -874 803 -416 413 -842 403 -836 413 -842 395 -826 813 -452 807 -458 407 -846 419 -822 409 -816 839 -118766 99 -132 819 -98 917 -132 233 -100 167 -66 533 -66 525 -64 163 -98 947 -66 327 -66 425 -132 229 -66 331 -68 1949 -98 261 -132 261 -66 1187 -66 295 -100 5279 -68 595 -98 527 -66 1293 -68 97 -134 527 -68 4543 -66 229 -64 927 -332 199 -132 363 -264 825 -100 829 -68 565 -200 3743 -66 2027 -66 1425 -100 1301 -66 229 -196 99 -98 4645 -422 353 -446 385 -418 385 -416 387 -450 357 -450 355 -450 357 -450 359 -450 357 -450 359 -450 359 -4096 779 -448 771 -474 777 -444 779 -480 775 -482 367 -880 779 -446 387 -918 781 -418 819 -416 813 -454 779 -448 385 -882 379 -854 779 -484 385 -872 787 -454 793 -456 781 -448 385 -850 405 -854 779 -448 803 -458 785 -484 395 -854 787 -430 809 -446 383 -842 793 -486 383 -856 777 -478 379 -906 381 -824 803 -432 807 -446 785 -442 783 -482 785 -454 381 -872 375 -918 787 -418 815 -418 391 -860 785 -448 385 -876 787 -460 775 -484 387 -890 385 -834 777 -450 385 -852 417 -854 379 -856 381 -882 369 -876 777 -482 791 -454 771 -446 377 -886 779 -446 383 -874 769 -458 819 -450 785 -456 779 -420 383 -16402 383 -444 385 -416 385 -448 355 -452 355 -450 359 -450 355 -450 357 -452 359 -450 +RAW_Data: 357 -450 359 -450 357 -4096 777 -448 799 -446 761 -464 775 -478 769 -454 419 -846 799 -466 381 -876 799 -440 801 -440 775 -448 811 -448 379 -872 385 -848 803 -464 381 -876 781 -454 783 -448 783 -448 411 -836 421 -848 763 -494 775 -482 779 -480 379 -858 779 -448 777 -448 379 -866 787 -484 353 -886 785 -462 383 -878 411 -854 775 -444 769 -454 807 -454 789 -452 803 -446 377 -864 419 -878 779 -436 809 -414 415 -860 775 -434 383 -876 787 -486 765 -490 349 -906 379 -858 777 -446 383 -842 409 -856 387 -850 393 -856 391 -856 785 -518 763 -460 779 -446 385 -852 803 -430 381 -872 801 -452 783 -472 777 -450 785 -428 377 -16446 411 -422 355 -478 353 -448 353 -448 359 -448 361 -450 357 -450 357 -450 357 -450 359 -446 353 -450 361 -4086 807 -442 769 -454 809 -452 783 -448 773 -480 381 -860 777 -472 383 -908 769 -448 801 -452 779 -432 809 -448 365 -882 387 -846 795 -456 381 -910 787 -426 809 -446 779 -446 379 -862 407 -846 783 -472 779 -482 777 -482 391 -860 783 -446 779 -448 395 -852 777 -482 385 -872 773 -448 417 -888 385 -834 785 -456 777 -448 801 -456 769 -458 809 -444 391 -858 421 -878 777 -434 807 -444 377 -856 777 -448 387 -872 803 -450 801 -452 389 -886 391 -858 757 -454 381 -854 391 -856 387 -848 397 -866 377 -872 797 -488 781 -470 773 -446 369 -878 751 -476 383 -848 787 -482 763 -494 777 -448 789 -400 401 -16398 419 -418 355 -434 385 -442 351 -446 383 -450 353 -450 357 -450 355 -450 357 -448 359 -450 357 -450 357 -4088 805 -414 803 -458 781 -446 781 -482 783 -450 383 -882 771 -468 383 -884 783 -456 783 -446 779 -450 783 -456 417 -844 371 -888 777 -482 367 -910 769 -452 771 -460 777 -446 379 -886 385 -848 787 -456 807 -446 815 -482 379 -858 783 -446 779 -448 395 -852 775 -480 357 -872 803 -448 409 -890 383 -850 763 -460 779 -446 803 -460 777 -480 781 -448 381 -870 379 -914 769 -440 799 -434 383 -872 767 -486 383 -856 777 -478 771 -480 379 -890 383 -850 767 -462 385 -872 351 -882 367 -866 383 -878 365 -878 775 -516 767 -460 779 -448 383 -848 803 -464 349 -876 785 -486 763 -492 777 -412 787 -454 359 -16460 421 -392 415 -392 405 -412 379 -432 385 -440 351 -448 385 -416 385 -418 387 -450 355 -450 357 -450 357 -4092 775 -446 799 -454 769 -458 805 -444 769 -452 405 -882 785 -446 383 -884 813 -418 809 -454 785 -452 779 -448 375 -886 387 -848 787 -456 379 -908 801 -418 785 -452 813 -448 +RAW_Data: 379 -838 421 -846 767 -494 777 -480 777 -480 379 -858 779 -446 779 -448 379 -898 755 -482 385 -842 803 -446 409 -890 383 -850 765 -462 775 -446 801 -458 775 -484 783 -450 379 -876 383 -886 783 -474 775 -446 365 -880 779 -448 385 -850 793 -486 779 -468 381 -884 391 -856 779 -446 383 -850 383 -854 409 -854 355 -900 385 -848 805 -464 813 -452 779 -420 419 -844 763 -460 383 -876 799 -454 769 -494 775 -444 771 -426 411 -16408 355 -436 383 -444 383 -416 385 -418 385 -452 353 -450 357 -450 357 -452 357 -446 355 -446 387 -410 391 -4094 775 -448 789 -430 807 -446 777 -450 813 -450 385 -848 807 -468 381 -884 783 -456 777 -123134 99 -266 65 -594 99 -232 301 -134 2911 -134 861 -66 529 -98 569 -66 1593 -68 429 -66 5405 -132 263 -98 821 -66 397 -66 361 -66 491 -100 165 -66 495 -66 3677 -132 825 -68 529 -134 299 -66 165 -68 661 -68 203 -134 135 -100 429 -100 397 -98 859 -66 365 -166 399 -98 2811 -68 229 -66 567 -164 1153 -168 167 -134 265 -100 631 -66 1493 -132 65 -98 199 -68 4269 -132 365 -202 1493 -132 299 -66 131 -66 465 -66 231 -98 229 -96 165 -130 3593 -100 927 -100 231 -200 1825 -68 265 -66 1557 -100 65 -100 463 -68 495 -100 2591 -232 1027 -100 229 -98 461 -66 1847 -100 265 -66 4369 -270 131 -100 131 -66 1725 -66 397 -98 1659 -66 329 -132 6605 -234 397 -134 1427 -100 231 -166 5117 -66 663 -98 499 -66 1331 -66 931 -66 563 -166 4219 -66 265 -164 491 -166 263 -164 557 -100 1483 -100 361 -98 461 -66 497 -102 4575 -100 1327 -98 265 -234 131 -100 399 -100 565 -100 637 -100 463 -64 3975 -166 197 -202 333 -132 199 -132 693 -68 631 -66 165 -100 265 -66 297 -200 165 -166 199 -364 3717 -198 761 -66 197 -134 395 -66 99 -66 695 -198 797 -132 397 -200 431 -102 6087 -198 199 -100 399 -100 361 -100 333 -100 827 -166 1135 -132 333 -100 497 -68 3915 -130 363 -98 897 -66 99 -66 297 -230 395 -66 195 -66 5099 -100 687 -66 915 -66 165 -66 95 -230 1181 -98 593 -98 301 -198 4807 -132 431 -232 367 -198 629 -164 199 -68 65 -100 331 -100 431 -132 1397 -66 165 -332 297 -66 1131 -466 533 -132 463 -198 861 -98 293 -66 4561 -100 459 -66 691 -130 557 -292 393 -66 161 -66 425 -66 163 -130 1147 -96 4103 -100 399 -132 395 -66 429 -66 131 -68 197 -98 199 -98 167 -100 65 -232 67 -132 165 -68 235 -66 467 -68 1027 -66 4281 -198 261 -66 861 -166 231 -198 333 -66 +RAW_Data: 231 -196 1265 -100 133 -68 933 -100 7293 -66 331 -132 295 -68 1157 -98 261 -132 1223 -200 929 -98 1291 -68 3909 -132 199 -100 2729 -66 195 -134 829 -132 263 -262 329 -68 1559 -100 497 -66 5119 -64 949 -66 533 -166 397 -68 559 -98 263 -98 951 -66 3273 -134 665 -100 65 -100 231 -66 267 -132 267 -100 1131 -132 133 -66 129 -130 885 -66 193 -164 229 -264 65 -66 889 -130 259 -164 689 -66 4127 -130 229 -66 1545 -98 199 -100 131 -100 2059 -66 329 -98 197 -66 4261 -166 791 -98 199 -68 465 -66 233 -66 265 -66 2983 -64 327 -98 229 -66 2403 -132 259 -98 953 -100 1657 -100 761 -498 799 -66 433 -200 495 -98 229 -66 1179 -68 5479 -232 627 -66 693 -66 265 -66 265 -66 463 -100 231 -68 499 -66 133 -100 299 -66 4899 -66 195 -164 621 -130 229 -130 231 -98 261 -66 97 -334 397 -100 425 -98 729 -134 65 -134 367 -102 463 -66 3197 -132 893 -66 495 -164 461 -66 197 -164 1715 -100 663 -66 99 -166 265 -100 201 -98 233 -66 133 -100 829 -132 361 -68 561 -98 199 -66 431 -134 263 -100 2071 -100 661 -66 461 -98 227 -66 1149 -66 297 -98 631 -98 329 -66 463 -66 263 -66 951 -64 3587 -66 1413 -66 919 -66 689 -132 847 -132 459 -100 161 -196 4049 -66 301 -68 397 -134 427 -98 229 -100 263 -134 335 -68 397 -98 259 -100 823 -100 399 -66 165 -66 3571 -132 563 -166 231 -100 197 -132 867 -66 433 -68 761 -98 335 -100 99 -98 99 -66 1751 -230 1019 -100 765 -100 231 -68 365 -134 4643 -66 367 -68 297 -66 531 -166 1333 -66 531 -66 67 -98 959 -66 791 -66 3787 -66 261 -132 721 -362 133 -66 897 -134 629 -100 1395 -368 1127 -132 895 -100 463 -66 1793 -66 5239 -66 331 -66 1095 -68 433 -68 6899 -98 1527 -132 267 -66 67 -66 131 -100 495 -66 4027 -68 999 -132 959 -134 265 -66 199 -68 299 -132 999 -134 65 -66 497 -98 67 -66 265 -132 4751 -66 231 -98 263 -98 463 -66 99 -66 859 -66 327 -66 435 -66 2987 -100 993 -68 1025 -66 1491 -68 1095 -100 297 -66 4409 -98 787 -132 2569 -66 957 -68 795 -64 593 -100 335 -66 1675 -100 7041 -134 1727 -134 65 -100 1029 -132 1027 -66 4653 -66 65 -66 995 -100 1129 -66 267 -66 231 -68 469 -66 465 -134 4047 -68 165 -100 597 -166 729 -100 665 -66 1115 -68 293 -130 297 -66 1607 -398 393 -410 409 -410 415 -378 413 -412 413 -382 417 -396 419 -396 409 -382 409 -404 423 -408 385 -4052 417 -820 401 -820 809 -450 +RAW_Data: 823 -420 417 -848 797 -472 381 -876 791 -428 413 -844 817 -426 379 -878 385 -848 403 -852 807 -452 379 -878 801 -452 801 -438 385 -838 419 -846 399 -852 379 -850 315 -110416 645 -1548 1691 -486 1667 -518 1695 -488 1671 -498 1697 -508 571 -1588 583 -1570 561 -1574 1689 -504 583 -1560 1679 -520 587 -1574 1677 -488 1701 -484 1697 -520 1677 -492 1693 -488 581 -1566 591 -1574 601 -1546 607 -1568 577 -1566 581 -1576 579 -16394 591 -1548 1679 -518 1671 -520 1679 -516 1663 -514 1689 -486 583 -1580 579 -1578 579 -1566 1701 -494 571 -1568 1697 -514 563 -1570 1693 -506 1669 -516 1695 -496 1681 -518 1667 -506 573 -1576 603 -1544 613 -1568 597 -1538 607 -1566 581 -1580 577 -16400 619 -1534 1703 -494 1677 -480 1697 -506 1675 -518 1669 -518 587 -1580 581 -1562 579 -1576 1683 -488 589 -1582 1677 -524 583 -1570 1653 -510 1703 -518 1641 -518 1693 -502 1677 -516 579 -1570 579 -1578 581 -1566 615 -1566 585 -1564 585 -1580 585 -16408 595 -1546 1685 -518 1673 -490 1669 -548 1665 -518 1675 -494 587 -1552 595 -1570 605 -1556 1673 -520 581 -1578 1665 -520 581 -1558 1701 -484 1681 -516 1667 -516 1697 -508 1675 -490 603 -1570 577 -1566 593 -1572 603 -1576 575 -1568 579 -1578 579 -16400 625 -1554 1667 -500 1699 -482 1691 -506 1679 -518 1673 -520 585 -1566 579 -1560 611 -1548 1697 -488 577 -1602 1651 -518 583 -1578 1667 -508 1691 -522 1675 -512 1665 -502 1699 -482 605 -1574 585 -1566 601 -1570 577 -1576 581 -1576 579 -1566 579 -16452 591 -1534 1693 -508 1683 -518 1673 -520 1673 -488 1711 -514 575 -1562 589 -1570 603 -1568 1667 -518 589 -1578 1677 -486 605 -1570 1701 -484 1701 -504 1697 -514 1667 -510 1717 -518 581 -1578 615 -91426 233 -298 197 -332 593 -162 261 -98 131 -68 163 -692 821 -132 227 -64 131 -66 197 -132 163 -66 263 -68 363 -134 461 -98 65 -66 229 -298 295 -66 3173 -64 987 -164 425 -98 193 -98 693 -66 723 -196 391 -496 431 -100 229 -68 499 -100 63 -66 165 -66 397 -98 133 -100 533 -166 1179 -166 361 -100 3973 -98 825 -100 131 -98 723 -66 1053 -66 131 -68 197 -100 199 -100 331 -66 165 -100 429 -68 231 -66 567 -66 533 -100 593 -68 1463 -66 2093 -100 599 -66 361 -66 361 -132 261 -462 263 -66 621 -98 555 -100 131 -68 4609 -200 199 -164 1033 -66 863 -132 131 -68 331 -100 4565 -98 229 -66 1313 -130 589 -166 3959 -100 531 -100 263 -132 361 -166 229 -64 165 -66 231 -328 261 -66 229 -66 165 -100 235 -100 299 -132 265 -266 165 -66 4417 -100 261 -68 1625 -64 165 -98 229 -160 259 -98 99 -332 593 -166 167 -102 +RAW_Data: 199 -66 1063 -98 267 -100 263 -332 5513 -64 229 -232 685 -232 661 -98 431 -66 1021 -66 4085 -64 655 -66 2313 -66 531 -66 263 -100 197 -134 67 -132 901 -66 1591 -66 4217 -100 827 -100 165 -66 299 -166 1987 -166 4097 -66 365 -66 131 -332 131 -100 625 -66 361 -98 131 -196 1679 -66 163 -98 293 -100 2275 -98 1689 -66 825 -98 627 -164 297 -398 461 -66 4707 -66 795 -134 329 -132 597 -66 777 -6038 371 -1818 167 -668 693 -622 1573 -638 465 -1666 503 -1626 541 -1622 1635 -518 577 -1578 1669 -512 567 -1606 1667 -502 1677 -516 1693 -500 1673 -518 1675 -522 587 -1562 581 -1558 625 -1546 587 -1558 611 -1560 571 -1568 609 -16352 633 -1548 1689 -476 1707 -490 1687 -482 1709 -502 1675 -520 579 -1578 577 -1568 577 -1568 1705 -486 581 -1586 1695 -486 579 -1568 1679 -520 1673 -520 1669 -508 1707 -498 1677 -514 577 -1566 615 -1550 581 -1568 615 -1532 617 -1546 617 -1532 615 -16406 599 -1530 1691 -514 1695 -484 1679 -530 1659 -518 1669 -514 601 -1568 577 -1578 577 -1568 1699 -492 573 -1576 1707 -486 577 -1600 1655 -518 1669 -530 1691 -486 1673 -514 1691 -502 585 -1576 585 -1580 577 -1592 573 -1576 571 -1570 613 -1570 559 -16430 619 -1538 1703 -462 1723 -484 1697 -488 1691 -488 1715 -462 635 -1534 607 -1556 589 -1580 1685 -488 621 -1538 1711 -492 589 -1548 1717 -478 1693 -514 1687 -504 1693 -484 1705 -482 605 -1570 579 -1566 619 -1550 581 -1580 579 -1568 615 -1536 619 -16382 625 -1534 1709 -490 1683 -514 1673 -504 1677 -518 1671 -518 587 -1560 577 -1588 587 -1580 1681 -482 609 -1558 1677 -520 581 -1576 1663 -530 1659 -518 1673 -514 1691 -504 1697 -510 587 -1572 575 -1564 591 -1570 603 -1574 577 -1568 579 -1578 579 -16430 599 -1564 1693 -484 1695 -486 1675 -500 1713 -484 1709 -488 579 -1568 593 -1576 603 -1570 1665 -520 581 -1560 1699 -482 603 -1580 1677 -518 1667 -520 1671 -488 1711 -482 1699 -516 599 -1570 577 -1578 577 -1568 579 -1570 617 -1566 581 -1560 587 -16424 629 -1542 1677 -482 1695 -514 1687 -484 1711 -494 1675 -514 571 -1584 587 -1572 599 -1542 1695 -520 585 -1544 1701 -510 593 -1568 1665 -514 1689 -506 1669 -508 1679 -528 1669 -520 579 -1576 579 -1568 581 -1582 581 -1578 579 -1568 615 -1564 585 -16412 631 -1540 1683 -516 1671 -510 1653 -506 1691 -518 1671 -514 601 -1570 577 -1578 577 -1578 1665 -498 603 -1566 1693 -514 563 -1576 1699 -506 1663 -514 1701 -478 1687 -520 1669 -500 603 -1568 605 -1558 589 -1574 601 -1542 607 -1576 577 -1576 577 -16434 597 -1534 1695 -516 1687 -488 1707 -486 1683 -518 1693 -496 583 -1574 599 -1542 605 -1578 1665 -500 611 -1550 1711 -478 605 -1558 +RAW_Data: 1679 -518 1675 -502 1699 -482 1693 -506 1679 -510 613 -1562 581 -1590 569 -1570 605 -1560 587 -1572 599 -1542 607 -16400 625 -1560 1669 -508 1677 -518 1667 -518 1695 -486 1709 -464 601 -1566 607 -1560 589 -1576 1691 -476 615 -1562 1677 -486 625 -1542 1709 -486 1703 -484 1697 -520 1673 -506 1695 -498 585 -1570 603 -1544 609 -1572 579 -1570 583 -1580 581 -1582 579 -16410 629 -1524 1715 -484 1679 -518 1673 -516 1663 -518 1697 -504 583 -1576 577 -1592 587 -1552 1681 -514 579 -1580 1681 -516 577 -1566 1705 -494 1689 -488 1705 -486 1695 -520 1675 -522 587 -1574 579 -1584 581 -1576 599 -1570 575 -1578 579 -1564 613 -89724 99 -1166 129 -1158 167 -532 163 -98 361 -198 299 -298 197 -66 2489 -66 3797 -66 1937 -66 1479 -98 557 -66 361 -66 1709 -66 6741 -98 1889 -132 5693 -68 7367 -100 8643 -100 2655 -100 3727 -66 1023 -66 865 -66 1161 -100 6287 -66 3987 -66 1961 -132 3307 -68 2183 -66 2429 -132 4179 -66 753 -66 461 -66 621 -64 5761 -100 331 -66 1683 -198 465 -66 629 -68 7341 -66 357 -198 261 -66 593 -234 331 -100 593 -64 293 -64 1611 -100 459 -100 297 -100 561 -134 1725 -66 6901 -100 1407 -68 8017 -200 1989 -66 5721 -100 199 -166 1251 -66 359 -130 9965 -66 4361 -100 819 -100 1051 -66 2187 -64 555 -66 861 -66 5889 -66 diff --git a/firmware/targets/f7/furi_hal/furi_hal_speaker.c b/firmware/targets/f7/furi_hal/furi_hal_speaker.c index 298574d83fb..001861986e6 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_speaker.c +++ b/firmware/targets/f7/furi_hal/furi_hal_speaker.c @@ -21,6 +21,10 @@ void furi_hal_speaker_init() { } void furi_hal_speaker_start(float frequency, float volume) { + if(volume == 0) { + return; + } + if(volume < 0) volume = 0; if(volume > 1) volume = 1; volume = volume * volume * volume; diff --git a/firmware/targets/f7/furi_hal/furi_hal_subghz.c b/firmware/targets/f7/furi_hal/furi_hal_subghz.c index fc7c01ff187..956342ffdbe 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_subghz.c +++ b/firmware/targets/f7/furi_hal/furi_hal_subghz.c @@ -160,7 +160,7 @@ static const uint8_t furi_hal_subghz_preset_2fsk_dev2_38khz_async_regs[][2] = { /* End */ {0, 0}, }; -static const uint8_t furi_hal_subghz_preset_2fsk_dev4_76khz_async_regs[][2] = { +static const uint8_t furi_hal_subghz_preset_2fsk_dev47_6khz_async_regs[][2] = { /* GPIO GD0 */ {CC1101_IOCFG0, 0x0D}, // GD0 as async serial data output/input @@ -178,7 +178,7 @@ static const uint8_t furi_hal_subghz_preset_2fsk_dev4_76khz_async_regs[][2] = { {CC1101_MDMCFG2, 0x04}, // Format 2-FSK/FM, No preamble/sync, Disable (current optimized) {CC1101_MDMCFG3, 0x83}, // Data rate is 4.79794 kBaud {CC1101_MDMCFG4, 0x67}, //Rx BW filter is 270.833333 kHz - {CC1101_DEVIATN, 0x14}, //Deviation 4.760742 kHz + {CC1101_DEVIATN, 0x47}, //Deviation 47.60742 kHz /* Main Radio Control State Machine */ {CC1101_MCSM0, 0x18}, // Autocalibrate on idle-to-rx/tx, PO_TIMEOUT is 64 cycles(149-155us) @@ -403,7 +403,7 @@ void furi_hal_subghz_load_preset(FuriHalSubGhzPreset preset) { furi_hal_subghz_load_registers(furi_hal_subghz_preset_2fsk_dev2_38khz_async_regs); furi_hal_subghz_load_patable(furi_hal_subghz_preset_2fsk_async_patable); } else if(preset == FuriHalSubGhzPreset2FSKDev476Async) { - furi_hal_subghz_load_registers(furi_hal_subghz_preset_2fsk_dev4_76khz_async_regs); + furi_hal_subghz_load_registers(furi_hal_subghz_preset_2fsk_dev47_6khz_async_regs); furi_hal_subghz_load_patable(furi_hal_subghz_preset_2fsk_async_patable); } else if(preset == FuriHalSubGhzPresetMSK99_97KbAsync) { furi_hal_subghz_load_registers(furi_hal_subghz_preset_msk_99_97kb_async_regs); diff --git a/firmware/targets/furi_hal_include/furi_hal_subghz.h b/firmware/targets/furi_hal_include/furi_hal_subghz.h index 59741e3ff4f..4c5ad07f07b 100644 --- a/firmware/targets/furi_hal_include/furi_hal_subghz.h +++ b/firmware/targets/furi_hal_include/furi_hal_subghz.h @@ -20,7 +20,7 @@ typedef enum { FuriHalSubGhzPresetOok270Async, /**< OOK, bandwidth 270kHz, asynchronous */ FuriHalSubGhzPresetOok650Async, /**< OOK, bandwidth 650kHz, asynchronous */ FuriHalSubGhzPreset2FSKDev238Async, /**< FM, deviation 2.380371 kHz, asynchronous */ - FuriHalSubGhzPreset2FSKDev476Async, /**< FM, deviation 4.760742 kHz, asynchronous */ + FuriHalSubGhzPreset2FSKDev476Async, /**< FM, deviation 47.60742 kHz, asynchronous */ FuriHalSubGhzPresetMSK99_97KbAsync, /**< MSK, deviation 47.60742 kHz, 99.97Kb/s, asynchronous */ FuriHalSubGhzPresetGFSK9_99KbAsync /**< GFSK, deviation 19.042969 kHz, 9.996Kb/s, asynchronous */ } FuriHalSubGhzPreset; diff --git a/lib/subghz/protocols/kia.c b/lib/subghz/protocols/kia.c index 79e36ea7165..f623a61d3e8 100644 --- a/lib/subghz/protocols/kia.c +++ b/lib/subghz/protocols/kia.c @@ -95,15 +95,15 @@ void subghz_protocol_decoder_kia_feed(void* context, bool level, uint32_t durati switch(instance->decoder.parser_step) { case KIADecoderStepReset: - if((!level) && (DURATION_DIFF(duration, subghz_protocol_kia_const.te_short) < - subghz_protocol_kia_const.te_delta)) { + if((level) && (DURATION_DIFF(duration, subghz_protocol_kia_const.te_short) < + subghz_protocol_kia_const.te_delta)) { instance->decoder.parser_step = KIADecoderStepCheckPreambula; instance->decoder.te_last = duration; instance->header_count = 0; } break; case KIADecoderStepCheckPreambula: - if(!level) { + if(level) { if((DURATION_DIFF(duration, subghz_protocol_kia_const.te_short) < subghz_protocol_kia_const.te_delta) || (DURATION_DIFF(duration, subghz_protocol_kia_const.te_long) < @@ -139,7 +139,7 @@ void subghz_protocol_decoder_kia_feed(void* context, bool level, uint32_t durati } break; case KIADecoderStepSaveDuration: - if(!level) { + if(level) { if(duration >= (subghz_protocol_kia_const.te_long + subghz_protocol_kia_const.te_delta * 2)) { //Found stop bit @@ -164,7 +164,7 @@ void subghz_protocol_decoder_kia_feed(void* context, bool level, uint32_t durati } break; case KIADecoderStepCheckDuration: - if(level) { + if(!level) { if((DURATION_DIFF(instance->decoder.te_last, subghz_protocol_kia_const.te_short) < subghz_protocol_kia_const.te_delta) && (DURATION_DIFF(duration, subghz_protocol_kia_const.te_short) < diff --git a/lib/subghz/protocols/raw.c b/lib/subghz/protocols/raw.c index 6c6675fe62b..0e68a937eaf 100644 --- a/lib/subghz/protocols/raw.c +++ b/lib/subghz/protocols/raw.c @@ -15,7 +15,7 @@ #define SUBGHZ_DOWNLOAD_MAX_SIZE 512 static const SubGhzBlockConst subghz_protocol_raw_const = { - .te_short = 80, + .te_short = 50, .te_long = 32700, .te_delta = 0, .min_count_bit_for_found = 0, @@ -223,8 +223,6 @@ void subghz_protocol_decoder_raw_feed(void* context, bool level, uint32_t durati if(instance->upload_raw != NULL) { if(duration > subghz_protocol_raw_const.te_short) { - if(duration > subghz_protocol_raw_const.te_long) - duration = subghz_protocol_raw_const.te_long; if(instance->last_level != level) { instance->last_level = (level ? true : false); instance->upload_raw[instance->ind_write++] = (level ? duration : -duration); diff --git a/lib/subghz/protocols/registry.c b/lib/subghz/protocols/registry.c index a1482210f7c..6d15af560d4 100644 --- a/lib/subghz/protocols/registry.c +++ b/lib/subghz/protocols/registry.c @@ -1,25 +1,5 @@ #include "registry.h" -#include "princeton.h" -#include "keeloq.h" -#include "star_line.h" -#include "nice_flo.h" -#include "came.h" -#include "faac_slh.h" -#include "nice_flor_s.h" -#include "came_twee.h" -#include "came_atomo.h" -#include "nero_sketch.h" -#include "ido.h" -#include "kia.h" -#include "hormann.h" -#include "nero_radio.h" -#include "somfy_telis.h" -#include "somfy_keytis.h" -#include "scher_khan.h" -#include "gate_tx.h" -#include "raw.h" - const SubGhzProtocol* subghz_protocol_registry[] = { &subghz_protocol_princeton, &subghz_protocol_keeloq, &subghz_protocol_star_line, &subghz_protocol_nice_flo, &subghz_protocol_came, &subghz_protocol_faac_slh, diff --git a/lib/subghz/protocols/registry.h b/lib/subghz/protocols/registry.h index e6e7f234c14..cce48e02438 100644 --- a/lib/subghz/protocols/registry.h +++ b/lib/subghz/protocols/registry.h @@ -2,6 +2,26 @@ #include "../types.h" +#include "princeton.h" +#include "keeloq.h" +#include "star_line.h" +#include "nice_flo.h" +#include "came.h" +#include "faac_slh.h" +#include "nice_flor_s.h" +#include "came_twee.h" +#include "came_atomo.h" +#include "nero_sketch.h" +#include "ido.h" +#include "kia.h" +#include "hormann.h" +#include "nero_radio.h" +#include "somfy_telis.h" +#include "somfy_keytis.h" +#include "scher_khan.h" +#include "gate_tx.h" +#include "raw.h" + /** * Registration by name SubGhzProtocol. * @param name Protocol name diff --git a/lib/subghz/protocols/scher_khan.c b/lib/subghz/protocols/scher_khan.c index 68fc672b6e5..c352b4ae686 100644 --- a/lib/subghz/protocols/scher_khan.c +++ b/lib/subghz/protocols/scher_khan.c @@ -207,7 +207,7 @@ void subghz_protocol_decoder_scher_khan_feed(void* context, bool level, uint32_t */ static void subghz_protocol_scher_khan_check_remote_controller( SubGhzBlockGeneric* instance, - const char* protocol_name) { + const char** protocol_name) { /* * MAGICAR 51 bit 00000001A99121DE83C3 MAGIC CODE, Dinamic * 0E8C1619E830C -> 000011101000110000010110 0001 1001 1110 1000001100001100 @@ -222,7 +222,7 @@ static void subghz_protocol_scher_khan_check_remote_controller( // instance->protocol_name = "MAGIC CODE, Static"; // break; case 51: //MAGIC CODE, Dinamic - protocol_name = "MAGIC CODE, Dinamic"; + *protocol_name = "MAGIC CODE, Dinamic"; instance->serial = ((instance->data >> 24) & 0xFFFFFF0) | ((instance->data >> 20) & 0x0F); instance->btn = (instance->data >> 24) & 0x0F; instance->cnt = instance->data & 0xFFFF; @@ -268,7 +268,7 @@ void subghz_protocol_decoder_scher_khan_get_string(void* context, string_t outpu SubGhzProtocolDecoderScherKhan* instance = context; subghz_protocol_scher_khan_check_remote_controller( - &instance->generic, instance->protocol_name); + &instance->generic, &instance->protocol_name); string_cat_printf( output, From a5cc3453c815ca01fa46ae9d3873a72d0ef52d65 Mon Sep 17 00:00:00 2001 From: Skorpionm <85568270+Skorpionm@users.noreply.github.com> Date: Thu, 14 Apr 2022 18:05:40 +0400 Subject: [PATCH 10/20] SubGhz: support for custom frequencies for SubGhz (#1108) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * SubGhz: add load setting * SubGhz: add support file upload with custom frequencies * SubGhz: add load region setting * SubGhz: fix syntax * SubGhz: fix furi_halt error * Desktop: hide dolphin controls in production build * Notification: fix crash on NotificationMessageTypeLedDisplayUnlock message Co-authored-by: あく --- .../desktop/views/desktop_view_debug.c | 10 +- applications/notification/notification_app.c | 13 +- applications/notification/notification_app.h | 1 + .../subghz_frequency_analyzer_worker.c | 13 +- .../subghz/scenes/subghz_scene_read_raw.c | 3 +- .../subghz/scenes/subghz_scene_receiver.c | 3 +- .../scenes/subghz_scene_receiver_config.c | 61 ++- .../subghz/scenes/subghz_scene_set_type.c | 6 +- applications/subghz/subghz.c | 72 +--- applications/subghz/subghz_i.c | 7 +- applications/subghz/subghz_i.h | 10 +- applications/subghz/subghz_setting.c | 361 ++++++++++++++++++ applications/subghz/subghz_setting.h | 17 + .../assets/setting_frequency_analyzer_user | 19 + assets/resources/subghz/assets/setting_user | 24 ++ 15 files changed, 511 insertions(+), 109 deletions(-) create mode 100644 applications/subghz/subghz_setting.c create mode 100644 applications/subghz/subghz_setting.h create mode 100644 assets/resources/subghz/assets/setting_frequency_analyzer_user create mode 100644 assets/resources/subghz/assets/setting_user diff --git a/applications/desktop/views/desktop_view_debug.c b/applications/desktop/views/desktop_view_debug.c index 0aed2adfc27..98cf57ce8cb 100644 --- a/applications/desktop/views/desktop_view_debug.c +++ b/applications/desktop/views/desktop_view_debug.c @@ -114,14 +114,8 @@ bool desktop_debug_input(InputEvent* event, void* context) { DesktopViewStatsScreens current = 0; with_view_model( debug_view->view, (DesktopDebugViewModel * model) { -#if SRV_DOLPHIN_STATE_DEBUG == 1 - if(event->key == InputKeyDown) { - model->screen = (model->screen + 1) % DesktopViewStatsTotalCount; - } else if(event->key == InputKeyUp) { - model->screen = ((model->screen - 1) + DesktopViewStatsTotalCount) % - DesktopViewStatsTotalCount; - } -#else + +#ifdef SRV_DOLPHIN_STATE_DEBUG if((event->key == InputKeyDown) || (event->key == InputKeyUp)) { model->screen = !model->screen; } diff --git a/applications/notification/notification_app.c b/applications/notification/notification_app.c index 00136ec5788..447bf9034fa 100644 --- a/applications/notification/notification_app.c +++ b/applications/notification/notification_app.c @@ -164,7 +164,6 @@ void notification_process_notification_message( notification_message = (*message->sequence)[notification_message_index]; bool led_active = false; - uint8_t display_led_lock = 0; uint8_t led_values[NOTIFICATION_LED_COUNT] = {0x00, 0x00, 0x00}; bool reset_notifications = true; float speaker_volume_setting = app->settings.speaker_volume; @@ -192,18 +191,18 @@ void notification_process_notification_message( reset_mask |= reset_display_mask; break; case NotificationMessageTypeLedDisplayLock: - furi_assert(display_led_lock < UINT8_MAX); - display_led_lock++; - if(display_led_lock == 1) { + furi_assert(app->display_led_lock < UINT8_MAX); + app->display_led_lock++; + if(app->display_led_lock == 1) { notification_apply_internal_led_layer( &app->display, notification_message->data.led.value * display_brightness_setting); } break; case NotificationMessageTypeLedDisplayUnlock: - furi_assert(display_led_lock > 0); - display_led_lock--; - if(display_led_lock == 0) { + furi_assert(app->display_led_lock > 0); + app->display_led_lock--; + if(app->display_led_lock == 0) { notification_apply_internal_led_layer( &app->display, notification_message->data.led.value * display_brightness_setting); diff --git a/applications/notification/notification_app.h b/applications/notification/notification_app.h index 5b7546aa62b..2c41bc823a5 100644 --- a/applications/notification/notification_app.h +++ b/applications/notification/notification_app.h @@ -49,6 +49,7 @@ struct NotificationApp { NotificationLedLayer display; NotificationLedLayer led[NOTIFICATION_LED_COUNT]; + uint8_t display_led_lock; NotificationSettings settings; }; diff --git a/applications/subghz/helpers/subghz_frequency_analyzer_worker.c b/applications/subghz/helpers/subghz_frequency_analyzer_worker.c index 54b3191d334..b6b3a1edc20 100644 --- a/applications/subghz/helpers/subghz_frequency_analyzer_worker.c +++ b/applications/subghz/helpers/subghz_frequency_analyzer_worker.c @@ -29,6 +29,7 @@ struct SubGhzFrequencyAnalyzerWorker { volatile bool worker_running; uint8_t count_repet; FrequencyRSSI frequency_rssi_buf; + SubGhzSetting* setting; float filVal; @@ -77,10 +78,12 @@ static int32_t subghz_frequency_analyzer_worker_thread(void* context) { frequency_rssi.rssi = -127.0f; furi_hal_subghz_idle(); furi_hal_subghz_load_registers(subghz_preset_ook_650khz); - for(size_t i = 0; i < subghz_frequencies_count; i++) { - if(furi_hal_subghz_is_frequency_valid(subghz_frequencies[i])) { + for(size_t i = 0; i < subghz_setting_get_frequency_count(instance->setting); i++) { + if(furi_hal_subghz_is_frequency_valid( + subghz_setting_get_frequency(instance->setting, i))) { furi_hal_subghz_idle(); - frequency = furi_hal_subghz_set_frequency(subghz_frequencies[i]); + frequency = furi_hal_subghz_set_frequency( + subghz_setting_get_frequency(instance->setting, i)); furi_hal_subghz_rx(); osDelay(3); rssi = furi_hal_subghz_get_rssi(); @@ -150,6 +153,8 @@ SubGhzFrequencyAnalyzerWorker* subghz_frequency_analyzer_worker_alloc() { furi_thread_set_context(instance->thread, instance); furi_thread_set_callback(instance->thread, subghz_frequency_analyzer_worker_thread); + instance->setting = subghz_setting_alloc(); + subghz_setting_load(instance->setting, "/ext/subghz/assets/setting_frequency_analyzer_user"); return instance; } @@ -157,7 +162,7 @@ void subghz_frequency_analyzer_worker_free(SubGhzFrequencyAnalyzerWorker* instan furi_assert(instance); furi_thread_free(instance->thread); - + subghz_setting_free(instance->setting); free(instance); } diff --git a/applications/subghz/scenes/subghz_scene_read_raw.c b/applications/subghz/scenes/subghz_scene_read_raw.c index e63014f7136..cbd64f8f7f8 100644 --- a/applications/subghz/scenes/subghz_scene_read_raw.c +++ b/applications/subghz/scenes/subghz_scene_read_raw.c @@ -127,7 +127,8 @@ bool subghz_scene_read_raw_on_event(void* context, SceneManagerEvent event) { scene_manager_next_scene(subghz->scene_manager, SubGhzSceneNeedSaving); } else { //Restore default setting - subghz->txrx->frequency = subghz_frequencies[subghz_frequencies_433_92]; + subghz->txrx->frequency = subghz_setting_get_frequency( + subghz->setting, subghz_setting_get_frequency_default_index(subghz->setting)); subghz->txrx->preset = FuriHalSubGhzPresetOok650Async; if(!scene_manager_search_and_switch_to_previous_scene( subghz->scene_manager, SubGhzSceneSaved)) { diff --git a/applications/subghz/scenes/subghz_scene_receiver.c b/applications/subghz/scenes/subghz_scene_receiver.c index dc6b9968903..8a5ee9218d3 100644 --- a/applications/subghz/scenes/subghz_scene_receiver.c +++ b/applications/subghz/scenes/subghz_scene_receiver.c @@ -120,7 +120,8 @@ bool subghz_scene_receiver_on_event(void* context, SceneManagerEvent event) { subghz_sleep(subghz); }; subghz->txrx->hopper_state = SubGhzHopperStateOFF; - subghz->txrx->frequency = subghz_frequencies[subghz_frequencies_433_92]; + subghz->txrx->frequency = subghz_setting_get_frequency( + subghz->setting, subghz_setting_get_frequency_default_index(subghz->setting)); subghz->txrx->preset = FuriHalSubGhzPresetOok650Async; subghz->txrx->idx_menu_chosen = 0; subghz_receiver_set_rx_callback(subghz->txrx->receiver, NULL, subghz); diff --git a/applications/subghz/scenes/subghz_scene_receiver_config.c b/applications/subghz/scenes/subghz_scene_receiver_config.c index 98fce89ad13..f2ae749f029 100644 --- a/applications/subghz/scenes/subghz_scene_receiver_config.c +++ b/applications/subghz/scenes/subghz_scene_receiver_config.c @@ -40,6 +40,21 @@ uint8_t subghz_scene_receiver_config_uint32_value_index( return index; } +uint8_t subghz_scene_receiver_config_next_frequency(const uint32_t value, void* context) { + furi_assert(context); + SubGhz* subghz = context; + int64_t last_value = INT64_MIN; + uint8_t index = 0; + for(uint8_t i = 0; i < subghz_setting_get_frequency_count(subghz->setting); i++) { + if((value >= last_value) && (value <= subghz_setting_get_frequency(subghz->setting, i))) { + index = i; + break; + } + last_value = subghz_setting_get_frequency(subghz->setting, i); + } + return index; +} + uint8_t subghz_scene_receiver_config_hopper_value_index( const uint32_t value, const uint32_t values[], @@ -64,10 +79,17 @@ static void subghz_scene_receiver_config_set_frequency(VariableItem* item) { uint8_t index = variable_item_get_current_value_index(item); if(subghz->txrx->hopper_state == SubGhzHopperStateOFF) { - variable_item_set_current_value_text(item, subghz_frequencies_text[index]); - subghz->txrx->frequency = subghz_frequencies[index]; + char text_buf[10] = {0}; + sprintf( + text_buf, + "%lu.%02lu", + subghz_setting_get_frequency(subghz->setting, index) / 1000000, + (subghz_setting_get_frequency(subghz->setting, index) % 1000000) / 10000); + variable_item_set_current_value_text(item, text_buf); + subghz->txrx->frequency = subghz_setting_get_frequency(subghz->setting, index); } else { - variable_item_set_current_value_index(item, subghz_frequencies_433_92); + variable_item_set_current_value_index( + item, subghz_setting_get_frequency_default_index(subghz->setting)); } } @@ -85,15 +107,27 @@ static void subghz_scene_receiver_config_set_hopping_runing(VariableItem* item) variable_item_set_current_value_text(item, hopping_text[index]); if(hopping_value[index] == SubGhzHopperStateOFF) { + char text_buf[10] = {0}; + sprintf( + text_buf, + "%lu.%02lu", + subghz_setting_get_frequency( + subghz->setting, subghz_setting_get_frequency_default_index(subghz->setting)) / + 1000000, + (subghz_setting_get_frequency( + subghz->setting, subghz_setting_get_frequency_default_index(subghz->setting)) % + 1000000) / + 10000); variable_item_set_current_value_text( (VariableItem*)scene_manager_get_scene_state( subghz->scene_manager, SubGhzSceneReceiverConfig), - subghz_frequencies_text[subghz_frequencies_433_92]); - subghz->txrx->frequency = subghz_frequencies[subghz_frequencies_433_92]; + text_buf); + subghz->txrx->frequency = subghz_setting_get_frequency( + subghz->setting, subghz_setting_get_frequency_default_index(subghz->setting)); variable_item_set_current_value_index( (VariableItem*)scene_manager_get_scene_state( subghz->scene_manager, SubGhzSceneReceiverConfig), - subghz_frequencies_433_92); + subghz_setting_get_frequency_default_index(subghz->setting)); } else { variable_item_set_current_value_text( (VariableItem*)scene_manager_get_scene_state( @@ -102,7 +136,7 @@ static void subghz_scene_receiver_config_set_hopping_runing(VariableItem* item) variable_item_set_current_value_index( (VariableItem*)scene_manager_get_scene_state( subghz->scene_manager, SubGhzSceneReceiverConfig), - subghz_frequencies_433_92); + subghz_setting_get_frequency_default_index(subghz->setting)); } subghz->txrx->hopper_state = hopping_value[index]; @@ -116,15 +150,20 @@ void subghz_scene_receiver_config_on_enter(void* context) { item = variable_item_list_add( subghz->variable_item_list, "Frequency:", - subghz_frequencies_count, + subghz_setting_get_frequency_count(subghz->setting), subghz_scene_receiver_config_set_frequency, subghz); - value_index = subghz_scene_receiver_config_uint32_value_index( - subghz->txrx->frequency, subghz_frequencies, subghz_frequencies_count); + value_index = subghz_scene_receiver_config_next_frequency(subghz->txrx->frequency, subghz); scene_manager_set_scene_state( subghz->scene_manager, SubGhzSceneReceiverConfig, (uint32_t)item); variable_item_set_current_value_index(item, value_index); - variable_item_set_current_value_text(item, subghz_frequencies_text[value_index]); + char text_buf[10] = {0}; + sprintf( + text_buf, + "%lu.%02lu", + subghz_setting_get_frequency(subghz->setting, value_index) / 1000000, + (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) { diff --git a/applications/subghz/scenes/subghz_scene_set_type.c b/applications/subghz/scenes/subghz_scene_set_type.c index 32aecc146e7..4fb36467f98 100644 --- a/applications/subghz/scenes/subghz_scene_set_type.c +++ b/applications/subghz/scenes/subghz_scene_set_type.c @@ -46,7 +46,7 @@ bool subghz_scene_set_type_submenu_gen_data_protocol( if(!subghz_protocol_decoder_base_serialize( subghz->txrx->decoder_result, subghz->txrx->fff_data, - subghz_frequencies[subghz_frequencies_433_92], + subghz_setting_get_frequency_default_index(subghz->setting), FuriHalSubGhzPresetOok650Async)) { FURI_LOG_E(TAG, "Unable to serialize"); break; @@ -213,7 +213,7 @@ bool subghz_scene_set_type_on_event(void* context, SceneManagerEvent event) { 0x2, 0x0003, "DoorHan", - subghz_frequencies[subghz_frequencies_433_92], + subghz_setting_get_frequency_default_index(subghz->setting), FuriHalSubGhzPresetOok650Async); generated_protocol = true; } else { @@ -237,7 +237,7 @@ bool subghz_scene_set_type_on_event(void* context, SceneManagerEvent event) { 0x2, 0x0003, "DoorHan", - subghz_frequencies[subghz_frequencies_315_00], + 315000000, FuriHalSubGhzPresetOok650Async); generated_protocol = true; } else { diff --git a/applications/subghz/subghz.c b/applications/subghz/subghz.c index 3320db480cf..80c69734386 100644 --- a/applications/subghz/subghz.c +++ b/applications/subghz/subghz.c @@ -3,68 +3,6 @@ #include "subghz_i.h" #include -const char* const subghz_frequencies_text[] = { - - "300.00", - "303.88", - "304.25", - "315.00", - "318.00", - - "390.00", - "418.00", - "433.08", - "433.42", - "433.92", - "434.42", - "434.78", - "438.90", - - "868.35", - "915.00", - "925.00", -}; - -const uint32_t subghz_frequencies[] = { - - /* 300 - 348 */ - 300000000, - 303875000, - 304250000, - 315000000, - 318000000, - - /* 387 - 464 */ - 390000000, - 418000000, - 433075000, /* LPD433 first */ - 433420000, - 433920000, /* LPD433 mid */ - 434420000, - 434775000, /* LPD433 last channels */ - 438900000, - - /* 779 - 928 */ - 868350000, - 915000000, - 925000000, - -}; - -const uint32_t subghz_hopper_frequencies[] = { - 315000000, - 318000000, - 390000000, - 433920000, - 868350000, -}; - -const uint32_t subghz_frequencies_count = sizeof(subghz_frequencies) / sizeof(uint32_t); -const uint32_t subghz_hopper_frequencies_count = - sizeof(subghz_hopper_frequencies) / sizeof(uint32_t); -const uint32_t subghz_frequencies_433_92 = 9; -const uint32_t subghz_frequencies_315_00 = 3; - bool subghz_custom_event_callback(void* context, uint32_t event) { furi_assert(context); SubGhz* subghz = context; @@ -186,9 +124,14 @@ SubGhz* subghz_alloc() { SubGhzViewIdStatic, subghz_test_static_get_view(subghz->subghz_test_static)); + //init setting + subghz->setting = subghz_setting_alloc(); + subghz_setting_load(subghz->setting, "/ext/subghz/assets/setting_user"); + //init Worker & Protocol & History subghz->txrx = malloc(sizeof(SubGhzTxRx)); - subghz->txrx->frequency = subghz_frequencies[subghz_frequencies_433_92]; + subghz->txrx->frequency = subghz_setting_get_frequency( + subghz->setting, subghz_setting_get_frequency_default_index(subghz->setting)); subghz->txrx->preset = FuriHalSubGhzPresetOok650Async; subghz->txrx->txrx_state = SubGhzTxRxStateSleep; subghz->txrx->hopper_state = SubGhzHopperStateOFF; @@ -281,6 +224,9 @@ void subghz_free(SubGhz* subghz) { furi_record_close("gui"); subghz->gui = NULL; + //setting + subghz_setting_free(subghz->setting); + //Worker & Protocol & History subghz_receiver_free(subghz->txrx->receiver); subghz_environment_free(subghz->txrx->environment); diff --git a/applications/subghz/subghz_i.c b/applications/subghz/subghz_i.c index ea6fa80e4bc..5740ea9d84c 100644 --- a/applications/subghz/subghz_i.c +++ b/applications/subghz/subghz_i.c @@ -514,9 +514,9 @@ void subghz_hopper_update(SubGhz* subghz) { } else { subghz->txrx->hopper_state = SubGhzHopperStateRunnig; } - // Select next frequency - if(subghz->txrx->hopper_idx_frequency < subghz_hopper_frequencies_count - 1) { + if(subghz->txrx->hopper_idx_frequency < + subghz_setting_get_hopper_frequency_count(subghz->setting) - 1) { subghz->txrx->hopper_idx_frequency++; } else { subghz->txrx->hopper_idx_frequency = 0; @@ -527,7 +527,8 @@ void subghz_hopper_update(SubGhz* subghz) { }; if(subghz->txrx->txrx_state == SubGhzTxRxStateIDLE) { subghz_receiver_reset(subghz->txrx->receiver); - subghz->txrx->frequency = subghz_hopper_frequencies[subghz->txrx->hopper_idx_frequency]; + subghz->txrx->frequency = subghz_setting_get_hopper_frequency( + subghz->setting, subghz->txrx->hopper_idx_frequency); subghz_rx(subghz, subghz->txrx->frequency); } } diff --git a/applications/subghz/subghz_i.h b/applications/subghz/subghz_i.h index 9ef1ee54009..b2ce806c350 100644 --- a/applications/subghz/subghz_i.h +++ b/applications/subghz/subghz_i.h @@ -30,19 +30,12 @@ #include #include "subghz_history.h" +#include "subghz_setting.h" #include #define SUBGHZ_MAX_LEN_NAME 40 -extern const char* const subghz_frequencies_text[]; -extern const uint32_t subghz_frequencies[]; -extern const uint32_t subghz_hopper_frequencies[]; -extern const uint32_t subghz_frequencies_count; -extern const uint32_t subghz_hopper_frequencies_count; -extern const uint32_t subghz_frequencies_433_92; -extern const uint32_t subghz_frequencies_315_00; - /** SubGhzNotification state */ typedef enum { SubGhzNotificationStateStarting, @@ -137,6 +130,7 @@ struct SubGhz { SubGhzTestCarrier* subghz_test_carrier; SubGhzTestPacket* subghz_test_packet; string_t error_str; + SubGhzSetting* setting; }; typedef enum { diff --git a/applications/subghz/subghz_setting.c b/applications/subghz/subghz_setting.c new file mode 100644 index 00000000000..98a8a16eb37 --- /dev/null +++ b/applications/subghz/subghz_setting.c @@ -0,0 +1,361 @@ +#include "subghz_setting.h" +#include "subghz_i.h" + +#include +#include +#include + +#define TAG "SubGhzSetting" + +#define SUBGHZ_SETTING_FILE_VERSION 1 +#define SUBGHZ_SETTING_FILE_TYPE "Flipper SubGhz Setting File" + +typedef enum { + SubGhzSettingStateNoLoad = 0, + SubGhzSettingStateLoadFrequencyDefault, + SubGhzSettingStateOkLoad, +} SubGhzSettingState; + +static const uint32_t subghz_frequencies[] = { + /* 300 - 348 */ + 300000000, + 303875000, + 304250000, + 315000000, + 318000000, + + /* 387 - 464 */ + 390000000, + 418000000, + 433075000, /* LPD433 first */ + 433420000, + 433920000, /* LPD433 mid */ + 434420000, + 434775000, /* LPD433 last channels */ + 438900000, + + /* 779 - 928 */ + 868350000, + 915000000, + 925000000, + 0, +}; +static const uint32_t subghz_hopper_frequencies[] = { + 315000000, + 318000000, + 390000000, + 433920000, + 868350000, + 0, +}; +static const uint32_t subghz_frequency_default_index = 9; + +static const uint32_t subghz_frequencies_region_eu_ru[] = { + /* 300 - 348 */ + 300000000, + 303875000, + 304250000, + 315000000, + 318000000, + + /* 387 - 464 */ + 390000000, + 418000000, + 433075000, /* LPD433 first */ + 433420000, + 433920000, /* LPD433 mid */ + 434420000, + 434775000, /* LPD433 last channels */ + 438900000, + + /* 779 - 928 */ + 868350000, + 915000000, + 925000000, + 0, +}; +static const uint32_t subghz_hopper_frequencies_region_eu_ru[] = { + 315000000, + 318000000, + 390000000, + 433920000, + 868350000, + 0, +}; +static const uint32_t subghz_frequency_default_index_region_eu_ru = 9; + +static const uint32_t subghz_frequencies_region_us_ca_au[] = { + /* 300 - 348 */ + 300000000, + 303875000, + 304250000, + 315000000, + 318000000, + + /* 387 - 464 */ + 390000000, + 418000000, + 433075000, /* LPD433 first */ + 433420000, + 433920000, /* LPD433 mid */ + 434420000, + 434775000, /* LPD433 last channels */ + 438900000, + + /* 779 - 928 */ + 868350000, + 915000000, + 925000000, + 0, +}; +static const uint32_t subghz_hopper_frequencies_region_us_ca_au[] = { + 315000000, + 318000000, + 390000000, + 433920000, + 868350000, + 0, +}; +static const uint32_t subghz_frequency_default_index_region_us_ca_au = 9; + +static const uint32_t subghz_frequencies_region_jp[] = { + /* 300 - 348 */ + 300000000, + 303875000, + 304250000, + 315000000, + 318000000, + + /* 387 - 464 */ + 390000000, + 418000000, + 433075000, /* LPD433 first */ + 433420000, + 433920000, /* LPD433 mid */ + 434420000, + 434775000, /* LPD433 last channels */ + 438900000, + + /* 779 - 928 */ + 868350000, + 915000000, + 925000000, + 0, +}; +static const uint32_t subghz_hopper_frequencies_region_jp[] = { + 315000000, + 318000000, + 390000000, + 433920000, + 868350000, + 0, +}; +static const uint32_t subghz_frequency_default_index_region_jp = 9; + +LIST_DEF(frequencies_list, uint32_t) +LIST_DEF(hopper_frequencies_list, uint32_t) + +struct SubGhzSetting { + frequencies_list_t frequencies; + hopper_frequencies_list_t hopper_frequencies; + size_t frequencies_count; + size_t hopper_frequencies_count; + uint32_t frequency_default_index; +}; + +SubGhzSetting* subghz_setting_alloc(void) { + SubGhzSetting* instance = malloc(sizeof(SubGhzSetting)); + frequencies_list_init(instance->frequencies); + hopper_frequencies_list_init(instance->hopper_frequencies); + return instance; +} + +void subghz_setting_free(SubGhzSetting* instance) { + furi_assert(instance); + frequencies_list_clear(instance->frequencies); + hopper_frequencies_list_clear(instance->hopper_frequencies); + free(instance); +} + +void subghz_setting_load_default( + SubGhzSetting* instance, + const uint32_t frequencies[], + const uint32_t hopper_frequencies[], + const uint32_t frequency_default_index) { + furi_assert(instance); + size_t i = 0; + frequencies_list_clear(instance->frequencies); + hopper_frequencies_list_clear(instance->hopper_frequencies); + i = 0; + while(frequencies[i]) { + frequencies_list_push_back(instance->frequencies, frequencies[i]); + i++; + } + instance->frequencies_count = i; + + i = 0; + while(hopper_frequencies[i]) { + hopper_frequencies_list_push_back(instance->hopper_frequencies, hopper_frequencies[i]); + i++; + } + instance->hopper_frequencies_count = i; + + instance->frequency_default_index = frequency_default_index; +} + +void subghz_setting_load(SubGhzSetting* instance, const char* file_path) { + furi_assert(instance); + + frequencies_list_clear(instance->frequencies); + hopper_frequencies_list_clear(instance->hopper_frequencies); + + Storage* storage = furi_record_open("storage"); + FlipperFormat* fff_data_file = flipper_format_file_alloc(storage); + + string_t temp_str; + string_init(temp_str); + uint32_t temp_data32; + SubGhzSettingState loading = SubGhzSettingStateNoLoad; + uint16_t i = 0; + + if(file_path) { + do { + if(!flipper_format_file_open_existing(fff_data_file, file_path)) { + FURI_LOG_E(TAG, "Error open file %s", file_path); + break; + } + + if(!flipper_format_read_header(fff_data_file, temp_str, &temp_data32)) { + FURI_LOG_E(TAG, "Missing or incorrect header"); + break; + } + + if((!strcmp(string_get_cstr(temp_str), SUBGHZ_SETTING_FILE_TYPE)) && + temp_data32 == SUBGHZ_SETTING_FILE_VERSION) { + } else { + FURI_LOG_E(TAG, "Type or version mismatch"); + break; + } + + if(!flipper_format_rewind(fff_data_file)) { + FURI_LOG_E(TAG, "Rewind error"); + break; + } + i = 0; + while(flipper_format_read_uint32( + fff_data_file, "Frequency", (uint32_t*)&temp_data32, 1)) { + if(furi_hal_subghz_is_frequency_valid(temp_data32)) { + FURI_LOG_I(TAG, "Frequency loaded %lu", temp_data32); + frequencies_list_push_back(instance->frequencies, temp_data32); + i++; + } else { + FURI_LOG_E(TAG, "Frequency not supported %lu", temp_data32); + } + } + instance->frequencies_count = i; + + if(!flipper_format_rewind(fff_data_file)) { + FURI_LOG_E(TAG, "Rewind error"); + break; + } + i = 0; + while(flipper_format_read_uint32( + fff_data_file, "Hopper_frequency", (uint32_t*)&temp_data32, 1)) { + if(furi_hal_subghz_is_frequency_valid(temp_data32)) { + FURI_LOG_I(TAG, "Hopper frequency loaded %lu", temp_data32); + hopper_frequencies_list_push_back(instance->hopper_frequencies, temp_data32); + i++; + } else { + FURI_LOG_E(TAG, "Hopper frequency not supported %lu", temp_data32); + } + } + instance->hopper_frequencies_count = i; + + if(!flipper_format_rewind(fff_data_file)) { + FURI_LOG_E(TAG, "Rewind error"); + break; + } + if(!flipper_format_read_uint32( + fff_data_file, "Frequency_default", (uint32_t*)&temp_data32, 1)) { + FURI_LOG_E(TAG, "Frequency default missing"); + break; + } + + for(i = 0; i < instance->frequencies_count; i++) { + if(subghz_setting_get_frequency(instance, i) == temp_data32) { + instance->frequency_default_index = i; + FURI_LOG_I(TAG, "Frequency default index %lu", i); + loading = SubGhzSettingStateLoadFrequencyDefault; + break; + } + } + + if(loading == SubGhzSettingStateLoadFrequencyDefault) { + loading = SubGhzSettingStateOkLoad; + } else { + FURI_LOG_E(TAG, "Frequency default index missing"); + } + } while(false); + } + flipper_format_free(fff_data_file); + furi_record_close("storage"); + + if(loading != SubGhzSettingStateOkLoad) { + switch(furi_hal_version_get_hw_region()) { + case FuriHalVersionRegionEuRu: + subghz_setting_load_default( + instance, + subghz_frequencies_region_eu_ru, + subghz_hopper_frequencies_region_eu_ru, + subghz_frequency_default_index_region_eu_ru); + break; + case FuriHalVersionRegionUsCaAu: + subghz_setting_load_default( + instance, + subghz_frequencies_region_us_ca_au, + subghz_hopper_frequencies_region_us_ca_au, + subghz_frequency_default_index_region_us_ca_au); + break; + case FuriHalVersionRegionJp: + subghz_setting_load_default( + instance, + subghz_frequencies_region_jp, + subghz_hopper_frequencies_region_jp, + subghz_frequency_default_index_region_jp); + break; + + default: + subghz_setting_load_default( + instance, + subghz_frequencies, + subghz_hopper_frequencies, + subghz_frequency_default_index); + break; + } + } +} + +size_t subghz_setting_get_frequency_count(SubGhzSetting* instance) { + furi_assert(instance); + return instance->frequencies_count; +} + +size_t subghz_setting_get_hopper_frequency_count(SubGhzSetting* instance) { + furi_assert(instance); + return instance->hopper_frequencies_count; +} + +uint32_t subghz_setting_get_frequency(SubGhzSetting* instance, size_t idx) { + furi_assert(instance); + return *frequencies_list_get(instance->frequencies, idx); +} + +uint32_t subghz_setting_get_hopper_frequency(SubGhzSetting* instance, size_t idx) { + furi_assert(instance); + return *hopper_frequencies_list_get(instance->hopper_frequencies, idx); +} + +uint32_t subghz_setting_get_frequency_default_index(SubGhzSetting* instance) { + furi_assert(instance); + return instance->frequency_default_index; +} \ No newline at end of file diff --git a/applications/subghz/subghz_setting.h b/applications/subghz/subghz_setting.h new file mode 100644 index 00000000000..cdf607974ea --- /dev/null +++ b/applications/subghz/subghz_setting.h @@ -0,0 +1,17 @@ + +#pragma once + +#include +#include +#include + +typedef struct SubGhzSetting SubGhzSetting; + +SubGhzSetting* subghz_setting_alloc(void); +void subghz_setting_free(SubGhzSetting* instance); +void subghz_setting_load(SubGhzSetting* instance, const char* file_path); +size_t subghz_setting_get_frequency_count(SubGhzSetting* instance); +size_t subghz_setting_get_hopper_frequency_count(SubGhzSetting* instance); +uint32_t subghz_setting_get_frequency(SubGhzSetting* instance, size_t idx); +uint32_t subghz_setting_get_hopper_frequency(SubGhzSetting* instance, size_t idx); +uint32_t subghz_setting_get_frequency_default_index(SubGhzSetting* instance); diff --git a/assets/resources/subghz/assets/setting_frequency_analyzer_user b/assets/resources/subghz/assets/setting_frequency_analyzer_user new file mode 100644 index 00000000000..2c03a402280 --- /dev/null +++ b/assets/resources/subghz/assets/setting_frequency_analyzer_user @@ -0,0 +1,19 @@ +Filetype: Flipper SubGhz Setting File +Version: 1 +Frequency_default: 433920000 +Frequency: 300000000 +Frequency: 303875000 +Frequency: 304250000 +Frequency: 315000000 +Frequency: 318000000 +Frequency: 390000000 +Frequency: 418000000 +Frequency: 433075000 +Frequency: 433420000 +Frequency: 433920000 +Frequency: 434420000 +Frequency: 434775000 +Frequency: 438900000 +Frequency: 868350000 +Frequency: 915000000 +Frequency: 925000000 diff --git a/assets/resources/subghz/assets/setting_user b/assets/resources/subghz/assets/setting_user new file mode 100644 index 00000000000..11bd984dc98 --- /dev/null +++ b/assets/resources/subghz/assets/setting_user @@ -0,0 +1,24 @@ +Filetype: Flipper SubGhz Setting File +Version: 1 +Frequency_default: 433920000 +Frequency: 300000000 +Frequency: 303875000 +Frequency: 304250000 +Frequency: 315000000 +Frequency: 318000000 +Frequency: 390000000 +Frequency: 418000000 +Frequency: 433075000 +Frequency: 433420000 +Frequency: 433920000 +Frequency: 434420000 +Frequency: 434775000 +Frequency: 438900000 +Frequency: 868350000 +Frequency: 915000000 +Frequency: 925000000 +Hopper_frequency: 315000000 +Hopper_frequency: 318000000 +Hopper_frequency: 390000000 +Hopper_frequency: 433920000 +Hopper_frequency: 868350000 From c078bbcb0ea7dc88a2079511450805a72773b68a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=82=E3=81=8F?= Date: Thu, 14 Apr 2022 18:08:29 +0300 Subject: [PATCH 11/20] [FL-2428] region name in about (#1113) --- applications/about/about.c | 3 ++- applications/desktop/views/desktop_view_debug.c | 3 ++- firmware/targets/f7/furi_hal/furi_hal_version.c | 14 ++++++++++++++ .../targets/furi_hal_include/furi_hal_version.h | 6 ++++++ 4 files changed, 24 insertions(+), 2 deletions(-) diff --git a/applications/about/about.c b/applications/about/about.c index bda50a4b0c1..9e3fd34eb2f 100644 --- a/applications/about/about.c +++ b/applications/about/about.c @@ -82,11 +82,12 @@ static DialogMessageButton hw_version_screen(DialogsApp* dialogs, DialogMessage* string_cat_printf( buffer, - "%d.F%dB%dC%d %s\n", + "%d.F%dB%dC%d %s %s\n", furi_hal_version_get_hw_version(), furi_hal_version_get_hw_target(), furi_hal_version_get_hw_body(), furi_hal_version_get_hw_connect(), + furi_hal_version_get_hw_region_name(), my_name ? my_name : "Unknown"); string_cat_printf(buffer, "Serial number:\n"); diff --git a/applications/desktop/views/desktop_view_debug.c b/applications/desktop/views/desktop_view_debug.c index 98cf57ce8cb..75a9bab1ab0 100644 --- a/applications/desktop/views/desktop_view_debug.c +++ b/applications/desktop/views/desktop_view_debug.c @@ -36,11 +36,12 @@ void desktop_debug_render(Canvas* canvas, void* model) { snprintf( buffer, sizeof(buffer), - "HW: %d.F%dB%dC%d %s", + "%d.F%dB%dC%d %s %s", furi_hal_version_get_hw_version(), furi_hal_version_get_hw_target(), furi_hal_version_get_hw_body(), furi_hal_version_get_hw_connect(), + furi_hal_version_get_hw_region_name(), my_name ? my_name : "Unknown"); canvas_draw_str(canvas, 5, 19 + STATUS_BAR_Y_SHIFT, buffer); diff --git a/firmware/targets/f7/furi_hal/furi_hal_version.c b/firmware/targets/f7/furi_hal/furi_hal_version.c index be92b348bd3..fdc4d2030ec 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_version.c +++ b/firmware/targets/f7/furi_hal/furi_hal_version.c @@ -252,6 +252,20 @@ const FuriHalVersionRegion furi_hal_version_get_hw_region() { return furi_hal_version.board_region; } +const char* furi_hal_version_get_hw_region_name() { + switch(furi_hal_version_get_hw_region()) { + case FuriHalVersionRegionUnknown: + return "D"; + case FuriHalVersionRegionJp: + return "Jp"; + case FuriHalVersionRegionEuRu: + return "Eu"; + case FuriHalVersionRegionUsCaAu: + return "Us"; + } + return "U"; +} + const FuriHalVersionDisplay furi_hal_version_get_hw_display() { return furi_hal_version.board_display; } diff --git a/firmware/targets/furi_hal_include/furi_hal_version.h b/firmware/targets/furi_hal_include/furi_hal_version.h index f174ade82e6..500e0d8139b 100644 --- a/firmware/targets/furi_hal_include/furi_hal_version.h +++ b/firmware/targets/furi_hal_include/furi_hal_version.h @@ -108,6 +108,12 @@ uint8_t furi_hal_version_get_hw_connect(); */ FuriHalVersionRegion furi_hal_version_get_hw_region(); +/** Get hardware region name + * + * @return Hardware Region name + */ +const char* furi_hal_version_get_hw_region_name(); + /** Get hardware display id * * @return Display id From 9b9edf2fbffa2fc671a67ec2b629cc322952cd4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=82=E3=81=8F?= Date: Thu, 14 Apr 2022 19:41:15 +0300 Subject: [PATCH 12/20] [FL-2460] Rpc: debug request logging and cli log command (#1114) * Rpc: debug request logging * Furi, Cli: replace global thread callback with local ring buffers, fix log command --- applications/cli/cli_commands.c | 26 +++++++++++--- applications/rpc/rpc_app.c | 6 ++++ applications/rpc/rpc_gui.c | 14 +++++++- applications/rpc/rpc_storage.c | 29 +++++++++++++++- applications/rpc/rpc_system.c | 24 ++++++++++++- core/furi/stdglue.c | 31 ----------------- core/furi/stdglue.h | 9 ----- .../targets/f7/furi_hal/furi_hal_console.c | 34 +++++++++++++++---- .../targets/f7/furi_hal/furi_hal_console.h | 4 +++ 9 files changed, 124 insertions(+), 53 deletions(-) diff --git a/applications/cli/cli_commands.c b/applications/cli/cli_commands.c index 58c131600ba..a58ddd49a74 100644 --- a/applications/cli/cli_commands.c +++ b/applications/cli/cli_commands.c @@ -6,6 +6,7 @@ #include #include #include +#include // Close to ISO, `date +'%Y-%m-%d %H:%M:%S %u'` #define CLI_DATE_FORMAT "%.4d-%.2d-%.2d %.2d:%.2d:%.2d %d" @@ -126,11 +127,28 @@ void cli_command_date(Cli* cli, string_t args, void* context) { } } +#define CLI_COMMAND_LOG_RING_SIZE 2048 +#define CLI_COMMAND_LOG_BUFFER_SIZE 64 + +void cli_command_log_tx_callback(const uint8_t* buffer, size_t size, void* context) { + xStreamBufferSend(context, buffer, size, 0); +} + void cli_command_log(Cli* cli, string_t args, void* context) { - furi_stdglue_set_global_stdout_callback(cli_stdout_callback); - printf("Press any key to stop...\r\n"); - cli_getc(cli); - furi_stdglue_set_global_stdout_callback(NULL); + StreamBufferHandle_t ring = xStreamBufferCreate(CLI_COMMAND_LOG_RING_SIZE, 1); + uint8_t buffer[CLI_COMMAND_LOG_BUFFER_SIZE]; + + furi_hal_console_set_tx_callback(cli_command_log_tx_callback, ring); + + printf("Press CTRL+C to stop...\r\n"); + while(!cli_cmd_interrupt_received(cli)) { + size_t ret = xStreamBufferReceive(ring, buffer, CLI_COMMAND_LOG_BUFFER_SIZE, 50); + cli_write(cli, buffer, ret); + } + + furi_hal_console_set_tx_callback(NULL, NULL); + + vStreamBufferDelete(ring); } void cli_command_vibro(Cli* cli, string_t args, void* context) { diff --git a/applications/rpc/rpc_app.c b/applications/rpc/rpc_app.c index c35decf034c..728c20528d3 100644 --- a/applications/rpc/rpc_app.c +++ b/applications/rpc/rpc_app.c @@ -4,12 +4,16 @@ #include #include +#define TAG "RpcSystemApp" + static void rpc_system_app_start_process(const PB_Main* request, void* context) { furi_assert(request); furi_assert(request->which_content == PB_Main_app_start_request_tag); RpcSession* session = (RpcSession*)context; furi_assert(session); + FURI_LOG_D(TAG, "Start"); + PB_CommandStatus result = PB_CommandStatus_ERROR_APP_CANT_START; Loader* loader = furi_record_open("loader"); @@ -43,6 +47,8 @@ static void rpc_system_app_lock_status_process(const PB_Main* request, void* con RpcSession* session = (RpcSession*)context; furi_assert(session); + FURI_LOG_D(TAG, "LockStatus"); + Loader* loader = furi_record_open("loader"); PB_Main response = { diff --git a/applications/rpc/rpc_gui.c b/applications/rpc/rpc_gui.c index b67035ac2c8..f390d983707 100644 --- a/applications/rpc/rpc_gui.c +++ b/applications/rpc/rpc_gui.c @@ -65,8 +65,10 @@ static int32_t rpc_system_gui_screen_stream_frame_transmit_thread(void* context) static void rpc_system_gui_start_screen_stream_process(const PB_Main* request, void* context) { furi_assert(request); furi_assert(context); - RpcGuiSystem* rpc_gui = context; + FURI_LOG_D(TAG, "StartScreenStream"); + + RpcGuiSystem* rpc_gui = context; RpcSession* session = rpc_gui->session; furi_assert(session); @@ -103,6 +105,8 @@ static void rpc_system_gui_stop_screen_stream_process(const PB_Main* request, vo furi_assert(request); furi_assert(context); + FURI_LOG_D(TAG, "StopScreenStream"); + RpcGuiSystem* rpc_gui = context; RpcSession* session = rpc_gui->session; furi_assert(session); @@ -132,6 +136,8 @@ static void furi_assert(request->which_content == PB_Main_gui_send_input_event_request_tag); furi_assert(context); + FURI_LOG_D(TAG, "SendInputEvent"); + RpcGuiSystem* rpc_gui = context; RpcSession* session = rpc_gui->session; furi_assert(session); @@ -220,6 +226,8 @@ static void rpc_system_gui_start_virtual_display_process(const PB_Main* request, furi_assert(request); furi_assert(context); + FURI_LOG_D(TAG, "StartVirtualDisplay"); + RpcGuiSystem* rpc_gui = context; RpcSession* session = rpc_gui->session; furi_assert(session); @@ -259,6 +267,8 @@ static void rpc_system_gui_stop_virtual_display_process(const PB_Main* request, furi_assert(request); furi_assert(context); + FURI_LOG_D(TAG, "StopVirtualDisplay"); + RpcGuiSystem* rpc_gui = context; RpcSession* session = rpc_gui->session; furi_assert(session); @@ -282,6 +292,8 @@ static void rpc_system_gui_virtual_display_frame_process(const PB_Main* request, furi_assert(request); furi_assert(context); + FURI_LOG_D(TAG, "VirtualDisplayFrame"); + RpcGuiSystem* rpc_gui = context; RpcSession* session = rpc_gui->session; furi_assert(session); diff --git a/applications/rpc/rpc_storage.c b/applications/rpc/rpc_storage.c index 97d9ab62f95..a21fec8ea3d 100644 --- a/applications/rpc/rpc_storage.c +++ b/applications/rpc/rpc_storage.c @@ -12,7 +12,8 @@ #include #include -#define RPC_TAG "RPC_STORAGE" +#define TAG "RpcStorage" + #define MAX_NAME_LENGTH 255 static const size_t MAX_DATA_SIZE = 512; @@ -106,6 +107,8 @@ static void rpc_system_storage_info_process(const PB_Main* request, void* contex furi_assert(context); furi_assert(request->which_content == PB_Main_storage_info_request_tag); + FURI_LOG_D(TAG, "Info"); + RpcStorageSystem* rpc_storage = context; RpcSession* session = rpc_storage->session; furi_assert(session); @@ -140,6 +143,8 @@ static void rpc_system_storage_stat_process(const PB_Main* request, void* contex furi_assert(context); furi_assert(request->which_content == PB_Main_storage_stat_request_tag); + FURI_LOG_D(TAG, "Stat"); + RpcStorageSystem* rpc_storage = context; RpcSession* session = rpc_storage->session; furi_assert(session); @@ -205,6 +210,8 @@ static void rpc_system_storage_list_process(const PB_Main* request, void* contex furi_assert(context); furi_assert(request->which_content == PB_Main_storage_list_request_tag); + FURI_LOG_D(TAG, "List"); + RpcStorageSystem* rpc_storage = context; RpcSession* session = rpc_storage->session; furi_assert(session); @@ -273,6 +280,8 @@ static void rpc_system_storage_read_process(const PB_Main* request, void* contex furi_assert(context); furi_assert(request->which_content == PB_Main_storage_read_request_tag); + FURI_LOG_D(TAG, "Read"); + RpcStorageSystem* rpc_storage = context; RpcSession* session = rpc_storage->session; furi_assert(session); @@ -330,6 +339,8 @@ static void rpc_system_storage_write_process(const PB_Main* request, void* conte furi_assert(context); furi_assert(request->which_content == PB_Main_storage_write_request_tag); + FURI_LOG_D(TAG, "Write"); + RpcStorageSystem* rpc_storage = context; RpcSession* session = rpc_storage->session; furi_assert(session); @@ -395,6 +406,9 @@ static void rpc_system_storage_delete_process(const PB_Main* request, void* cont furi_assert(request); furi_assert(request->which_content == PB_Main_storage_delete_request_tag); furi_assert(context); + + FURI_LOG_D(TAG, "Delete"); + RpcStorageSystem* rpc_storage = context; RpcSession* session = rpc_storage->session; furi_assert(session); @@ -433,6 +447,9 @@ static void rpc_system_storage_mkdir_process(const PB_Main* request, void* conte furi_assert(request); furi_assert(request->which_content == PB_Main_storage_mkdir_request_tag); furi_assert(context); + + FURI_LOG_D(TAG, "Mkdir"); + RpcStorageSystem* rpc_storage = context; RpcSession* session = rpc_storage->session; furi_assert(session); @@ -456,6 +473,9 @@ static void rpc_system_storage_md5sum_process(const PB_Main* request, void* cont furi_assert(request); furi_assert(request->which_content == PB_Main_storage_md5sum_request_tag); furi_assert(context); + + FURI_LOG_D(TAG, "Md5sum"); + RpcStorageSystem* rpc_storage = context; RpcSession* session = rpc_storage->session; furi_assert(session); @@ -521,6 +541,9 @@ static void rpc_system_storage_rename_process(const PB_Main* request, void* cont furi_assert(request); furi_assert(request->which_content == PB_Main_storage_rename_request_tag); furi_assert(context); + + FURI_LOG_D(TAG, "Rename"); + RpcStorageSystem* rpc_storage = context; RpcSession* session = rpc_storage->session; furi_assert(session); @@ -544,6 +567,8 @@ static void rpc_system_storage_backup_create_process(const PB_Main* request, voi furi_assert(request); furi_assert(request->which_content == PB_Main_storage_backup_create_request_tag); + FURI_LOG_D(TAG, "BackupCreate"); + RpcSession* session = (RpcSession*)context; furi_assert(session); @@ -567,6 +592,8 @@ static void rpc_system_storage_backup_restore_process(const PB_Main* request, vo furi_assert(request); furi_assert(request->which_content == PB_Main_storage_backup_restore_request_tag); + FURI_LOG_D(TAG, "BackupRestore"); + RpcSession* session = (RpcSession*)context; furi_assert(session); diff --git a/applications/rpc/rpc_system.c b/applications/rpc/rpc_system.c index 6ea3b02e4b3..f54bb19791f 100644 --- a/applications/rpc/rpc_system.c +++ b/applications/rpc/rpc_system.c @@ -7,6 +7,8 @@ #include "rpc_i.h" +#define TAG "RpcSystem" + typedef struct { RpcSession* session; PB_Main* response; @@ -16,6 +18,8 @@ static void rpc_system_system_ping_process(const PB_Main* request, void* context furi_assert(request); furi_assert(request->which_content == PB_Main_system_ping_request_tag); + FURI_LOG_D(TAG, "Ping"); + RpcSession* session = (RpcSession*)context; furi_assert(session); @@ -46,6 +50,8 @@ static void rpc_system_system_reboot_process(const PB_Main* request, void* conte furi_assert(request); furi_assert(request->which_content == PB_Main_system_reboot_request_tag); + FURI_LOG_D(TAG, "Reboot"); + RpcSession* session = (RpcSession*)context; furi_assert(session); @@ -84,6 +90,8 @@ static void rpc_system_system_device_info_process(const PB_Main* request, void* furi_assert(request); furi_assert(request->which_content == PB_Main_system_device_info_request_tag); + FURI_LOG_D(TAG, "DeviceInfo"); + RpcSession* session = (RpcSession*)context; furi_assert(session); @@ -105,6 +113,8 @@ static void rpc_system_system_get_datetime_process(const PB_Main* request, void* furi_assert(request); furi_assert(request->which_content == PB_Main_system_get_datetime_request_tag); + FURI_LOG_D(TAG, "GetDatetime"); + RpcSession* session = (RpcSession*)context; furi_assert(session); @@ -132,6 +142,8 @@ static void rpc_system_system_set_datetime_process(const PB_Main* request, void* furi_assert(request); furi_assert(request->which_content == PB_Main_system_set_datetime_request_tag); + FURI_LOG_D(TAG, "SetDatetime"); + RpcSession* session = (RpcSession*)context; furi_assert(session); @@ -158,6 +170,8 @@ static void rpc_system_system_factory_reset_process(const PB_Main* request, void furi_assert(request); furi_assert(request->which_content == PB_Main_system_factory_reset_request_tag); + FURI_LOG_D(TAG, "Reset"); + RpcSession* session = (RpcSession*)context; furi_assert(session); @@ -172,6 +186,8 @@ static void furi_assert(request); furi_assert(request->which_content == PB_Main_system_play_audiovisual_alert_request_tag); + FURI_LOG_D(TAG, "Alert"); + RpcSession* session = (RpcSession*)context; furi_assert(session); @@ -186,6 +202,8 @@ static void rpc_system_system_protobuf_version_process(const PB_Main* request, v furi_assert(request); furi_assert(request->which_content == PB_Main_system_protobuf_version_request_tag); + FURI_LOG_D(TAG, "ProtobufVersion"); + RpcSession* session = (RpcSession*)context; furi_assert(session); @@ -226,6 +244,8 @@ static void rpc_system_system_get_power_info_process(const PB_Main* request, voi furi_assert(request); furi_assert(request->which_content == PB_Main_system_power_info_request_tag); + FURI_LOG_D(TAG, "GetPowerInfo"); + RpcSession* session = (RpcSession*)context; furi_assert(session); @@ -248,6 +268,8 @@ static void rpc_system_system_update_request_process(const PB_Main* request, voi furi_assert(request); furi_assert(request->which_content == PB_Main_system_update_request_tag); + FURI_LOG_D(TAG, "SystemUpdate"); + RpcSession* session = (RpcSession*)context; furi_assert(session); @@ -305,4 +327,4 @@ void* rpc_system_system_alloc(RpcSession* session) { #endif return NULL; -} \ No newline at end of file +} diff --git a/core/furi/stdglue.c b/core/furi/stdglue.c index 52fb3fd9ae3..4e727202344 100644 --- a/core/furi/stdglue.c +++ b/core/furi/stdglue.c @@ -17,7 +17,6 @@ DICT_DEF2( typedef struct { osMutexId_t mutex; - FuriStdglueCallbackDict_t global_outputs; FuriStdglueCallbackDict_t thread_outputs; } FuriStdglue; @@ -31,17 +30,6 @@ static ssize_t stdout_write(void* _cookie, const char* data, size_t size) { if(state == osKernelRunning && thread_id && osMutexAcquire(furi_stdglue->mutex, osWaitForever) == osOK) { // We are in the thread context - // Handle global callbacks - FuriStdglueCallbackDict_it_t it; - for(FuriStdglueCallbackDict_it(it, furi_stdglue->global_outputs); - !FuriStdglueCallbackDict_end_p(it); - FuriStdglueCallbackDict_next(it)) { - osThreadId_t it_thread = (osThreadId_t)FuriStdglueCallbackDict_ref(it)->key; - FuriStdglueWriteCallback it_callback = FuriStdglueCallbackDict_ref(it)->value; - if(thread_id != it_thread) { - it_callback(_cookie, data, size); - } - } // Handle thread callbacks FuriStdglueWriteCallback* callback_ptr = FuriStdglueCallbackDict_get(furi_stdglue->thread_outputs, (uint32_t)thread_id); @@ -71,7 +59,6 @@ void furi_stdglue_init() { // Init outputs structures furi_stdglue->mutex = osMutexNew(NULL); furi_check(furi_stdglue->mutex); - FuriStdglueCallbackDict_init(furi_stdglue->global_outputs); FuriStdglueCallbackDict_init(furi_stdglue->thread_outputs); // Prepare and set stdout descriptor FILE* fp = fopencookie( @@ -87,24 +74,6 @@ void furi_stdglue_init() { stdout = fp; } -bool furi_stdglue_set_global_stdout_callback(FuriStdglueWriteCallback callback) { - furi_assert(furi_stdglue); - osThreadId_t thread_id = osThreadGetId(); - if(thread_id) { - furi_check(osMutexAcquire(furi_stdglue->mutex, osWaitForever) == osOK); - if(callback) { - FuriStdglueCallbackDict_set_at( - furi_stdglue->global_outputs, (uint32_t)thread_id, callback); - } else { - FuriStdglueCallbackDict_erase(furi_stdglue->global_outputs, (uint32_t)thread_id); - } - furi_check(osMutexRelease(furi_stdglue->mutex) == osOK); - return true; - } else { - return false; - } -} - bool furi_stdglue_set_thread_stdout_callback(FuriStdglueWriteCallback callback) { furi_assert(furi_stdglue); osThreadId_t thread_id = osThreadGetId(); diff --git a/core/furi/stdglue.h b/core/furi/stdglue.h index c83a443ee42..800fcf92817 100644 --- a/core/furi/stdglue.h +++ b/core/furi/stdglue.h @@ -22,15 +22,6 @@ typedef void (*FuriStdglueWriteCallback)(void* _cookie, const char* data, size_t /** Initialized std library glue code */ void furi_stdglue_init(); -/** Set global STDOUT callback - * - * @param callback callback or NULL to clear - * - * @return true on success, otherwise fail - * @warning function is thread aware, use this API from the same thread - */ -bool furi_stdglue_set_global_stdout_callback(FuriStdglueWriteCallback callback); - /** Set STDOUT callback for your thread * * @param callback callback or NULL to clear diff --git a/firmware/targets/f7/furi_hal/furi_hal_console.c b/firmware/targets/f7/furi_hal/furi_hal_console.c index f3cf06da531..e5db927bfe1 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_console.c +++ b/firmware/targets/f7/furi_hal/furi_hal_console.c @@ -18,11 +18,21 @@ #define CONSOLE_BAUDRATE 230400 #endif -volatile bool furi_hal_console_alive = false; +typedef struct { + bool alive; + FuriHalConsoleTxCallback tx_callback; + void* tx_callback_context; +} FuriHalConsole; + +FuriHalConsole furi_hal_console = { + .alive = false, + .tx_callback = NULL, + .tx_callback_context = NULL, +}; void furi_hal_console_init() { furi_hal_uart_init(FuriHalUartIdUSART1, CONSOLE_BAUDRATE); - furi_hal_console_alive = true; + furi_hal_console.alive = true; } void furi_hal_console_enable() { @@ -30,20 +40,32 @@ void furi_hal_console_enable() { while(!LL_USART_IsActiveFlag_TC(USART1)) ; furi_hal_uart_set_br(FuriHalUartIdUSART1, CONSOLE_BAUDRATE); - furi_hal_console_alive = true; + furi_hal_console.alive = true; } void furi_hal_console_disable() { while(!LL_USART_IsActiveFlag_TC(USART1)) ; - furi_hal_console_alive = false; + furi_hal_console.alive = false; +} + +void furi_hal_console_set_tx_callback(FuriHalConsoleTxCallback callback, void* context) { + FURI_CRITICAL_ENTER(); + furi_hal_console.tx_callback = callback; + furi_hal_console.tx_callback_context = context; + FURI_CRITICAL_EXIT(); } void furi_hal_console_tx(const uint8_t* buffer, size_t buffer_size) { - if(!furi_hal_console_alive) return; + if(!furi_hal_console.alive) return; FURI_CRITICAL_ENTER(); // Transmit data + + if(furi_hal_console.tx_callback) { + furi_hal_console.tx_callback(buffer, buffer_size, furi_hal_console.tx_callback_context); + } + furi_hal_uart_tx(FuriHalUartIdUSART1, (uint8_t*)buffer, buffer_size); // Wait for TC flag to be raised for last char while(!LL_USART_IsActiveFlag_TC(USART1)) @@ -52,7 +74,7 @@ void furi_hal_console_tx(const uint8_t* buffer, size_t buffer_size) { } void furi_hal_console_tx_with_new_line(const uint8_t* buffer, size_t buffer_size) { - if(!furi_hal_console_alive) return; + if(!furi_hal_console.alive) return; FURI_CRITICAL_ENTER(); // Transmit data diff --git a/firmware/targets/f7/furi_hal/furi_hal_console.h b/firmware/targets/f7/furi_hal/furi_hal_console.h index 637c17f6a03..104515ce9ce 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_console.h +++ b/firmware/targets/f7/furi_hal/furi_hal_console.h @@ -7,12 +7,16 @@ extern "C" { #endif +typedef void (*FuriHalConsoleTxCallback)(const uint8_t* buffer, size_t size, void* context); + void furi_hal_console_init(); void furi_hal_console_enable(); void furi_hal_console_disable(); +void furi_hal_console_set_tx_callback(FuriHalConsoleTxCallback callback, void* context); + void furi_hal_console_tx(const uint8_t* buffer, size_t buffer_size); void furi_hal_console_tx_with_new_line(const uint8_t* buffer, size_t buffer_size); From c97d9a633ebf94af2365c6e17760b44cd8c88c60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=82=E3=81=8F?= Date: Thu, 14 Apr 2022 19:53:46 +0300 Subject: [PATCH 13/20] Assets: update dolphin animation (#1117) --- .../external/L1_Laptop_128x51/frame_0.png | Bin 1669 -> 4914 bytes .../external/L1_Laptop_128x51/frame_1.png | Bin 1655 -> 4917 bytes .../external/L1_Laptop_128x51/frame_2.png | Bin 1648 -> 4914 bytes .../external/L1_Laptop_128x51/frame_3.png | Bin 1649 -> 4914 bytes .../external/L1_Laptop_128x51/frame_4.png | Bin 1646 -> 4909 bytes .../external/L1_Laptop_128x51/frame_5.png | Bin 1646 -> 4908 bytes .../external/L1_Laptop_128x51/frame_6.png | Bin 1627 -> 4900 bytes .../external/L1_Laptop_128x51/frame_7.png | Bin 1641 -> 4907 bytes .../L1_Leaving_sad_128x64/frame_0.png | Bin 0 -> 1575 bytes .../L1_Leaving_sad_128x64/frame_1.png | Bin 0 -> 1589 bytes .../L1_Leaving_sad_128x64/frame_10.png | Bin 0 -> 1386 bytes .../L1_Leaving_sad_128x64/frame_11.png | Bin 0 -> 1358 bytes .../L1_Leaving_sad_128x64/frame_12.png | Bin 0 -> 1365 bytes .../L1_Leaving_sad_128x64/frame_2.png | Bin 0 -> 1597 bytes .../L1_Leaving_sad_128x64/frame_3.png | Bin 0 -> 1617 bytes .../L1_Leaving_sad_128x64/frame_4.png | Bin 0 -> 1544 bytes .../L1_Leaving_sad_128x64/frame_5.png | Bin 0 -> 1523 bytes .../L1_Leaving_sad_128x64/frame_6.png | Bin 0 -> 1555 bytes .../L1_Leaving_sad_128x64/frame_7.png | Bin 0 -> 1574 bytes .../L1_Leaving_sad_128x64/frame_8.png | Bin 0 -> 1479 bytes .../L1_Leaving_sad_128x64/frame_9.png | Bin 0 -> 1382 bytes .../external/L1_Leaving_sad_128x64/meta.txt | 32 ++++++++++ .../external/L1_Mad_fist_128x64/frame_0.png | Bin 0 -> 1556 bytes .../external/L1_Mad_fist_128x64/frame_1.png | Bin 0 -> 1580 bytes .../external/L1_Mad_fist_128x64/frame_10.png | Bin 0 -> 1606 bytes .../external/L1_Mad_fist_128x64/frame_11.png | Bin 0 -> 1556 bytes .../external/L1_Mad_fist_128x64/frame_12.png | Bin 0 -> 1541 bytes .../external/L1_Mad_fist_128x64/frame_13.png | Bin 0 -> 1545 bytes .../external/L1_Mad_fist_128x64/frame_2.png | Bin 0 -> 1558 bytes .../external/L1_Mad_fist_128x64/frame_3.png | Bin 0 -> 1583 bytes .../external/L1_Mad_fist_128x64/frame_4.png | Bin 0 -> 1560 bytes .../external/L1_Mad_fist_128x64/frame_5.png | Bin 0 -> 1557 bytes .../external/L1_Mad_fist_128x64/frame_6.png | Bin 0 -> 1581 bytes .../external/L1_Mad_fist_128x64/frame_7.png | Bin 0 -> 1575 bytes .../external/L1_Mad_fist_128x64/frame_8.png | Bin 0 -> 1581 bytes .../external/L1_Mad_fist_128x64/frame_9.png | Bin 0 -> 1584 bytes .../external/L1_Mad_fist_128x64/meta.txt | 23 +++++++ .../external/L2_Soldering_128x64/frame_0.png | Bin 0 -> 1778 bytes .../external/L2_Soldering_128x64/frame_1.png | Bin 0 -> 1768 bytes .../external/L2_Soldering_128x64/frame_10.png | Bin 0 -> 1781 bytes .../external/L2_Soldering_128x64/frame_2.png | Bin 0 -> 1779 bytes .../external/L2_Soldering_128x64/frame_3.png | Bin 0 -> 1778 bytes .../external/L2_Soldering_128x64/frame_4.png | Bin 0 -> 1784 bytes .../external/L2_Soldering_128x64/frame_5.png | Bin 0 -> 1782 bytes .../external/L2_Soldering_128x64/frame_6.png | Bin 0 -> 1799 bytes .../external/L2_Soldering_128x64/frame_7.png | Bin 0 -> 1797 bytes .../external/L2_Soldering_128x64/frame_8.png | Bin 0 -> 1798 bytes .../external/L2_Soldering_128x64/frame_9.png | Bin 0 -> 1778 bytes .../external/L2_Soldering_128x64/meta.txt | 23 +++++++ .../L3_Hijack_radio_128x64/frame_0.png | Bin 0 -> 1611 bytes .../L3_Hijack_radio_128x64/frame_1.png | Bin 0 -> 1619 bytes .../L3_Hijack_radio_128x64/frame_10.png | Bin 0 -> 1642 bytes .../L3_Hijack_radio_128x64/frame_11.png | Bin 0 -> 1660 bytes .../L3_Hijack_radio_128x64/frame_12.png | Bin 0 -> 1627 bytes .../L3_Hijack_radio_128x64/frame_13.png | Bin 0 -> 1674 bytes .../L3_Hijack_radio_128x64/frame_2.png | Bin 0 -> 1615 bytes .../L3_Hijack_radio_128x64/frame_3.png | Bin 0 -> 1622 bytes .../L3_Hijack_radio_128x64/frame_4.png | Bin 0 -> 1667 bytes .../L3_Hijack_radio_128x64/frame_5.png | Bin 0 -> 1672 bytes .../L3_Hijack_radio_128x64/frame_6.png | Bin 0 -> 1609 bytes .../L3_Hijack_radio_128x64/frame_7.png | Bin 0 -> 1755 bytes .../L3_Hijack_radio_128x64/frame_8.png | Bin 0 -> 1754 bytes .../L3_Hijack_radio_128x64/frame_9.png | Bin 0 -> 1706 bytes .../external/L3_Hijack_radio_128x64/meta.txt | 14 +++++ .../L3_Lab_research_128x54/frame_0.png | Bin 0 -> 1687 bytes .../L3_Lab_research_128x54/frame_1.png | Bin 0 -> 1700 bytes .../L3_Lab_research_128x54/frame_10.png | Bin 0 -> 1640 bytes .../L3_Lab_research_128x54/frame_11.png | Bin 0 -> 1656 bytes .../L3_Lab_research_128x54/frame_12.png | Bin 0 -> 1639 bytes .../L3_Lab_research_128x54/frame_13.png | Bin 0 -> 1689 bytes .../L3_Lab_research_128x54/frame_2.png | Bin 0 -> 1707 bytes .../L3_Lab_research_128x54/frame_3.png | Bin 0 -> 1680 bytes .../L3_Lab_research_128x54/frame_4.png | Bin 0 -> 1691 bytes .../L3_Lab_research_128x54/frame_5.png | Bin 0 -> 1708 bytes .../L3_Lab_research_128x54/frame_6.png | Bin 0 -> 1689 bytes .../L3_Lab_research_128x54/frame_7.png | Bin 0 -> 1655 bytes .../L3_Lab_research_128x54/frame_8.png | Bin 0 -> 1645 bytes .../L3_Lab_research_128x54/frame_9.png | Bin 0 -> 1655 bytes .../external/L3_Lab_research_128x54/meta.txt | 59 ++++++++++++++++++ assets/dolphin/external/manifest.txt | 39 +++++++++++- .../dolphin/L1_Laptop_128x51/frame_0.bm | Bin 576 -> 555 bytes .../dolphin/L1_Laptop_128x51/frame_1.bm | Bin 578 -> 557 bytes .../dolphin/L1_Laptop_128x51/frame_2.bm | Bin 580 -> 560 bytes .../dolphin/L1_Laptop_128x51/frame_3.bm | Bin 578 -> 556 bytes .../dolphin/L1_Laptop_128x51/frame_4.bm | Bin 582 -> 560 bytes .../dolphin/L1_Laptop_128x51/frame_5.bm | Bin 575 -> 554 bytes .../dolphin/L1_Laptop_128x51/frame_6.bm | Bin 575 -> 553 bytes .../dolphin/L1_Laptop_128x51/frame_7.bm | Bin 581 -> 560 bytes .../dolphin/L1_Leaving_sad_128x64/frame_0.bm | Bin 0 -> 514 bytes .../dolphin/L1_Leaving_sad_128x64/frame_1.bm | Bin 0 -> 526 bytes .../dolphin/L1_Leaving_sad_128x64/frame_10.bm | Bin 0 -> 316 bytes .../dolphin/L1_Leaving_sad_128x64/frame_11.bm | Bin 0 -> 294 bytes .../dolphin/L1_Leaving_sad_128x64/frame_12.bm | Bin 0 -> 322 bytes .../dolphin/L1_Leaving_sad_128x64/frame_2.bm | Bin 0 -> 542 bytes .../dolphin/L1_Leaving_sad_128x64/frame_3.bm | Bin 0 -> 557 bytes .../dolphin/L1_Leaving_sad_128x64/frame_4.bm | Bin 0 -> 488 bytes .../dolphin/L1_Leaving_sad_128x64/frame_5.bm | Bin 0 -> 469 bytes .../dolphin/L1_Leaving_sad_128x64/frame_6.bm | Bin 0 -> 499 bytes .../dolphin/L1_Leaving_sad_128x64/frame_7.bm | Bin 0 -> 486 bytes .../dolphin/L1_Leaving_sad_128x64/frame_8.bm | Bin 0 -> 403 bytes .../dolphin/L1_Leaving_sad_128x64/frame_9.bm | Bin 0 -> 317 bytes .../dolphin/L1_Leaving_sad_128x64/meta.txt | 32 ++++++++++ .../dolphin/L1_Mad_fist_128x64/frame_0.bm | Bin 0 -> 520 bytes .../dolphin/L1_Mad_fist_128x64/frame_1.bm | Bin 0 -> 540 bytes .../dolphin/L1_Mad_fist_128x64/frame_10.bm | Bin 0 -> 542 bytes .../dolphin/L1_Mad_fist_128x64/frame_11.bm | Bin 0 -> 505 bytes .../dolphin/L1_Mad_fist_128x64/frame_12.bm | Bin 0 -> 501 bytes .../dolphin/L1_Mad_fist_128x64/frame_13.bm | Bin 0 -> 500 bytes .../dolphin/L1_Mad_fist_128x64/frame_2.bm | Bin 0 -> 515 bytes .../dolphin/L1_Mad_fist_128x64/frame_3.bm | Bin 0 -> 538 bytes .../dolphin/L1_Mad_fist_128x64/frame_4.bm | Bin 0 -> 512 bytes .../dolphin/L1_Mad_fist_128x64/frame_5.bm | Bin 0 -> 519 bytes .../dolphin/L1_Mad_fist_128x64/frame_6.bm | Bin 0 -> 524 bytes .../dolphin/L1_Mad_fist_128x64/frame_7.bm | Bin 0 -> 515 bytes .../dolphin/L1_Mad_fist_128x64/frame_8.bm | Bin 0 -> 517 bytes .../dolphin/L1_Mad_fist_128x64/frame_9.bm | Bin 0 -> 526 bytes .../dolphin/L1_Mad_fist_128x64/meta.txt | 23 +++++++ .../dolphin/L2_Soldering_128x64/frame_0.bm | Bin 0 -> 699 bytes .../dolphin/L2_Soldering_128x64/frame_1.bm | Bin 0 -> 688 bytes .../dolphin/L2_Soldering_128x64/frame_10.bm | Bin 0 -> 699 bytes .../dolphin/L2_Soldering_128x64/frame_2.bm | Bin 0 -> 689 bytes .../dolphin/L2_Soldering_128x64/frame_3.bm | Bin 0 -> 689 bytes .../dolphin/L2_Soldering_128x64/frame_4.bm | Bin 0 -> 693 bytes .../dolphin/L2_Soldering_128x64/frame_5.bm | Bin 0 -> 696 bytes .../dolphin/L2_Soldering_128x64/frame_6.bm | Bin 0 -> 712 bytes .../dolphin/L2_Soldering_128x64/frame_7.bm | Bin 0 -> 732 bytes .../dolphin/L2_Soldering_128x64/frame_8.bm | Bin 0 -> 705 bytes .../dolphin/L2_Soldering_128x64/frame_9.bm | Bin 0 -> 698 bytes .../dolphin/L2_Soldering_128x64/meta.txt | 23 +++++++ .../dolphin/L3_Hijack_radio_128x64/frame_0.bm | Bin 0 -> 524 bytes .../dolphin/L3_Hijack_radio_128x64/frame_1.bm | Bin 0 -> 527 bytes .../L3_Hijack_radio_128x64/frame_10.bm | Bin 0 -> 550 bytes .../L3_Hijack_radio_128x64/frame_11.bm | Bin 0 -> 572 bytes .../L3_Hijack_radio_128x64/frame_12.bm | Bin 0 -> 539 bytes .../L3_Hijack_radio_128x64/frame_13.bm | Bin 0 -> 579 bytes .../dolphin/L3_Hijack_radio_128x64/frame_2.bm | Bin 0 -> 526 bytes .../dolphin/L3_Hijack_radio_128x64/frame_3.bm | Bin 0 -> 529 bytes .../dolphin/L3_Hijack_radio_128x64/frame_4.bm | Bin 0 -> 571 bytes .../dolphin/L3_Hijack_radio_128x64/frame_5.bm | Bin 0 -> 574 bytes .../dolphin/L3_Hijack_radio_128x64/frame_6.bm | Bin 0 -> 524 bytes .../dolphin/L3_Hijack_radio_128x64/frame_7.bm | Bin 0 -> 655 bytes .../dolphin/L3_Hijack_radio_128x64/frame_8.bm | Bin 0 -> 645 bytes .../dolphin/L3_Hijack_radio_128x64/frame_9.bm | Bin 0 -> 611 bytes .../dolphin/L3_Hijack_radio_128x64/meta.txt | 14 +++++ .../dolphin/L3_Lab_research_128x54/frame_0.bm | Bin 0 -> 611 bytes .../dolphin/L3_Lab_research_128x54/frame_1.bm | Bin 0 -> 614 bytes .../L3_Lab_research_128x54/frame_10.bm | Bin 0 -> 576 bytes .../L3_Lab_research_128x54/frame_11.bm | Bin 0 -> 585 bytes .../L3_Lab_research_128x54/frame_12.bm | Bin 0 -> 571 bytes .../L3_Lab_research_128x54/frame_13.bm | Bin 0 -> 615 bytes .../dolphin/L3_Lab_research_128x54/frame_2.bm | Bin 0 -> 618 bytes .../dolphin/L3_Lab_research_128x54/frame_3.bm | Bin 0 -> 608 bytes .../dolphin/L3_Lab_research_128x54/frame_4.bm | Bin 0 -> 615 bytes .../dolphin/L3_Lab_research_128x54/frame_5.bm | Bin 0 -> 618 bytes .../dolphin/L3_Lab_research_128x54/frame_6.bm | Bin 0 -> 615 bytes .../dolphin/L3_Lab_research_128x54/frame_7.bm | Bin 0 -> 585 bytes .../dolphin/L3_Lab_research_128x54/frame_8.bm | Bin 0 -> 578 bytes .../dolphin/L3_Lab_research_128x54/frame_9.bm | Bin 0 -> 581 bytes .../dolphin/L3_Lab_research_128x54/meta.txt | 59 ++++++++++++++++++ assets/resources/dolphin/manifest.txt | 39 +++++++++++- 160 files changed, 376 insertions(+), 4 deletions(-) create mode 100644 assets/dolphin/external/L1_Leaving_sad_128x64/frame_0.png create mode 100644 assets/dolphin/external/L1_Leaving_sad_128x64/frame_1.png create mode 100644 assets/dolphin/external/L1_Leaving_sad_128x64/frame_10.png create mode 100644 assets/dolphin/external/L1_Leaving_sad_128x64/frame_11.png create mode 100644 assets/dolphin/external/L1_Leaving_sad_128x64/frame_12.png create mode 100644 assets/dolphin/external/L1_Leaving_sad_128x64/frame_2.png create mode 100644 assets/dolphin/external/L1_Leaving_sad_128x64/frame_3.png create mode 100644 assets/dolphin/external/L1_Leaving_sad_128x64/frame_4.png create mode 100644 assets/dolphin/external/L1_Leaving_sad_128x64/frame_5.png create mode 100644 assets/dolphin/external/L1_Leaving_sad_128x64/frame_6.png create mode 100644 assets/dolphin/external/L1_Leaving_sad_128x64/frame_7.png create mode 100644 assets/dolphin/external/L1_Leaving_sad_128x64/frame_8.png create mode 100644 assets/dolphin/external/L1_Leaving_sad_128x64/frame_9.png create mode 100644 assets/dolphin/external/L1_Leaving_sad_128x64/meta.txt create mode 100644 assets/dolphin/external/L1_Mad_fist_128x64/frame_0.png create mode 100644 assets/dolphin/external/L1_Mad_fist_128x64/frame_1.png create mode 100644 assets/dolphin/external/L1_Mad_fist_128x64/frame_10.png create mode 100644 assets/dolphin/external/L1_Mad_fist_128x64/frame_11.png create mode 100644 assets/dolphin/external/L1_Mad_fist_128x64/frame_12.png create mode 100644 assets/dolphin/external/L1_Mad_fist_128x64/frame_13.png create mode 100644 assets/dolphin/external/L1_Mad_fist_128x64/frame_2.png create mode 100644 assets/dolphin/external/L1_Mad_fist_128x64/frame_3.png create mode 100644 assets/dolphin/external/L1_Mad_fist_128x64/frame_4.png create mode 100644 assets/dolphin/external/L1_Mad_fist_128x64/frame_5.png create mode 100644 assets/dolphin/external/L1_Mad_fist_128x64/frame_6.png create mode 100644 assets/dolphin/external/L1_Mad_fist_128x64/frame_7.png create mode 100644 assets/dolphin/external/L1_Mad_fist_128x64/frame_8.png create mode 100644 assets/dolphin/external/L1_Mad_fist_128x64/frame_9.png create mode 100644 assets/dolphin/external/L1_Mad_fist_128x64/meta.txt create mode 100644 assets/dolphin/external/L2_Soldering_128x64/frame_0.png create mode 100644 assets/dolphin/external/L2_Soldering_128x64/frame_1.png create mode 100644 assets/dolphin/external/L2_Soldering_128x64/frame_10.png create mode 100644 assets/dolphin/external/L2_Soldering_128x64/frame_2.png create mode 100644 assets/dolphin/external/L2_Soldering_128x64/frame_3.png create mode 100644 assets/dolphin/external/L2_Soldering_128x64/frame_4.png create mode 100644 assets/dolphin/external/L2_Soldering_128x64/frame_5.png create mode 100644 assets/dolphin/external/L2_Soldering_128x64/frame_6.png create mode 100644 assets/dolphin/external/L2_Soldering_128x64/frame_7.png create mode 100644 assets/dolphin/external/L2_Soldering_128x64/frame_8.png create mode 100644 assets/dolphin/external/L2_Soldering_128x64/frame_9.png create mode 100644 assets/dolphin/external/L2_Soldering_128x64/meta.txt create mode 100644 assets/dolphin/external/L3_Hijack_radio_128x64/frame_0.png create mode 100644 assets/dolphin/external/L3_Hijack_radio_128x64/frame_1.png create mode 100644 assets/dolphin/external/L3_Hijack_radio_128x64/frame_10.png create mode 100644 assets/dolphin/external/L3_Hijack_radio_128x64/frame_11.png create mode 100644 assets/dolphin/external/L3_Hijack_radio_128x64/frame_12.png create mode 100644 assets/dolphin/external/L3_Hijack_radio_128x64/frame_13.png create mode 100644 assets/dolphin/external/L3_Hijack_radio_128x64/frame_2.png create mode 100644 assets/dolphin/external/L3_Hijack_radio_128x64/frame_3.png create mode 100644 assets/dolphin/external/L3_Hijack_radio_128x64/frame_4.png create mode 100644 assets/dolphin/external/L3_Hijack_radio_128x64/frame_5.png create mode 100644 assets/dolphin/external/L3_Hijack_radio_128x64/frame_6.png create mode 100644 assets/dolphin/external/L3_Hijack_radio_128x64/frame_7.png create mode 100644 assets/dolphin/external/L3_Hijack_radio_128x64/frame_8.png create mode 100644 assets/dolphin/external/L3_Hijack_radio_128x64/frame_9.png create mode 100644 assets/dolphin/external/L3_Hijack_radio_128x64/meta.txt create mode 100644 assets/dolphin/external/L3_Lab_research_128x54/frame_0.png create mode 100644 assets/dolphin/external/L3_Lab_research_128x54/frame_1.png create mode 100644 assets/dolphin/external/L3_Lab_research_128x54/frame_10.png create mode 100644 assets/dolphin/external/L3_Lab_research_128x54/frame_11.png create mode 100644 assets/dolphin/external/L3_Lab_research_128x54/frame_12.png create mode 100644 assets/dolphin/external/L3_Lab_research_128x54/frame_13.png create mode 100644 assets/dolphin/external/L3_Lab_research_128x54/frame_2.png create mode 100644 assets/dolphin/external/L3_Lab_research_128x54/frame_3.png create mode 100644 assets/dolphin/external/L3_Lab_research_128x54/frame_4.png create mode 100644 assets/dolphin/external/L3_Lab_research_128x54/frame_5.png create mode 100644 assets/dolphin/external/L3_Lab_research_128x54/frame_6.png create mode 100644 assets/dolphin/external/L3_Lab_research_128x54/frame_7.png create mode 100644 assets/dolphin/external/L3_Lab_research_128x54/frame_8.png create mode 100644 assets/dolphin/external/L3_Lab_research_128x54/frame_9.png create mode 100644 assets/dolphin/external/L3_Lab_research_128x54/meta.txt create mode 100644 assets/resources/dolphin/L1_Leaving_sad_128x64/frame_0.bm create mode 100644 assets/resources/dolphin/L1_Leaving_sad_128x64/frame_1.bm create mode 100644 assets/resources/dolphin/L1_Leaving_sad_128x64/frame_10.bm create mode 100644 assets/resources/dolphin/L1_Leaving_sad_128x64/frame_11.bm create mode 100644 assets/resources/dolphin/L1_Leaving_sad_128x64/frame_12.bm create mode 100644 assets/resources/dolphin/L1_Leaving_sad_128x64/frame_2.bm create mode 100644 assets/resources/dolphin/L1_Leaving_sad_128x64/frame_3.bm create mode 100644 assets/resources/dolphin/L1_Leaving_sad_128x64/frame_4.bm create mode 100644 assets/resources/dolphin/L1_Leaving_sad_128x64/frame_5.bm create mode 100644 assets/resources/dolphin/L1_Leaving_sad_128x64/frame_6.bm create mode 100644 assets/resources/dolphin/L1_Leaving_sad_128x64/frame_7.bm create mode 100644 assets/resources/dolphin/L1_Leaving_sad_128x64/frame_8.bm create mode 100644 assets/resources/dolphin/L1_Leaving_sad_128x64/frame_9.bm create mode 100644 assets/resources/dolphin/L1_Leaving_sad_128x64/meta.txt create mode 100644 assets/resources/dolphin/L1_Mad_fist_128x64/frame_0.bm create mode 100644 assets/resources/dolphin/L1_Mad_fist_128x64/frame_1.bm create mode 100644 assets/resources/dolphin/L1_Mad_fist_128x64/frame_10.bm create mode 100644 assets/resources/dolphin/L1_Mad_fist_128x64/frame_11.bm create mode 100644 assets/resources/dolphin/L1_Mad_fist_128x64/frame_12.bm create mode 100644 assets/resources/dolphin/L1_Mad_fist_128x64/frame_13.bm create mode 100644 assets/resources/dolphin/L1_Mad_fist_128x64/frame_2.bm create mode 100644 assets/resources/dolphin/L1_Mad_fist_128x64/frame_3.bm create mode 100644 assets/resources/dolphin/L1_Mad_fist_128x64/frame_4.bm create mode 100644 assets/resources/dolphin/L1_Mad_fist_128x64/frame_5.bm create mode 100644 assets/resources/dolphin/L1_Mad_fist_128x64/frame_6.bm create mode 100644 assets/resources/dolphin/L1_Mad_fist_128x64/frame_7.bm create mode 100644 assets/resources/dolphin/L1_Mad_fist_128x64/frame_8.bm create mode 100644 assets/resources/dolphin/L1_Mad_fist_128x64/frame_9.bm create mode 100644 assets/resources/dolphin/L1_Mad_fist_128x64/meta.txt create mode 100644 assets/resources/dolphin/L2_Soldering_128x64/frame_0.bm create mode 100644 assets/resources/dolphin/L2_Soldering_128x64/frame_1.bm create mode 100644 assets/resources/dolphin/L2_Soldering_128x64/frame_10.bm create mode 100644 assets/resources/dolphin/L2_Soldering_128x64/frame_2.bm create mode 100644 assets/resources/dolphin/L2_Soldering_128x64/frame_3.bm create mode 100644 assets/resources/dolphin/L2_Soldering_128x64/frame_4.bm create mode 100644 assets/resources/dolphin/L2_Soldering_128x64/frame_5.bm create mode 100644 assets/resources/dolphin/L2_Soldering_128x64/frame_6.bm create mode 100644 assets/resources/dolphin/L2_Soldering_128x64/frame_7.bm create mode 100644 assets/resources/dolphin/L2_Soldering_128x64/frame_8.bm create mode 100644 assets/resources/dolphin/L2_Soldering_128x64/frame_9.bm create mode 100644 assets/resources/dolphin/L2_Soldering_128x64/meta.txt create mode 100644 assets/resources/dolphin/L3_Hijack_radio_128x64/frame_0.bm create mode 100644 assets/resources/dolphin/L3_Hijack_radio_128x64/frame_1.bm create mode 100644 assets/resources/dolphin/L3_Hijack_radio_128x64/frame_10.bm create mode 100644 assets/resources/dolphin/L3_Hijack_radio_128x64/frame_11.bm create mode 100644 assets/resources/dolphin/L3_Hijack_radio_128x64/frame_12.bm create mode 100644 assets/resources/dolphin/L3_Hijack_radio_128x64/frame_13.bm create mode 100644 assets/resources/dolphin/L3_Hijack_radio_128x64/frame_2.bm create mode 100644 assets/resources/dolphin/L3_Hijack_radio_128x64/frame_3.bm create mode 100644 assets/resources/dolphin/L3_Hijack_radio_128x64/frame_4.bm create mode 100644 assets/resources/dolphin/L3_Hijack_radio_128x64/frame_5.bm create mode 100644 assets/resources/dolphin/L3_Hijack_radio_128x64/frame_6.bm create mode 100644 assets/resources/dolphin/L3_Hijack_radio_128x64/frame_7.bm create mode 100644 assets/resources/dolphin/L3_Hijack_radio_128x64/frame_8.bm create mode 100644 assets/resources/dolphin/L3_Hijack_radio_128x64/frame_9.bm create mode 100644 assets/resources/dolphin/L3_Hijack_radio_128x64/meta.txt create mode 100644 assets/resources/dolphin/L3_Lab_research_128x54/frame_0.bm create mode 100644 assets/resources/dolphin/L3_Lab_research_128x54/frame_1.bm create mode 100644 assets/resources/dolphin/L3_Lab_research_128x54/frame_10.bm create mode 100644 assets/resources/dolphin/L3_Lab_research_128x54/frame_11.bm create mode 100644 assets/resources/dolphin/L3_Lab_research_128x54/frame_12.bm create mode 100644 assets/resources/dolphin/L3_Lab_research_128x54/frame_13.bm create mode 100644 assets/resources/dolphin/L3_Lab_research_128x54/frame_2.bm create mode 100644 assets/resources/dolphin/L3_Lab_research_128x54/frame_3.bm create mode 100644 assets/resources/dolphin/L3_Lab_research_128x54/frame_4.bm create mode 100644 assets/resources/dolphin/L3_Lab_research_128x54/frame_5.bm create mode 100644 assets/resources/dolphin/L3_Lab_research_128x54/frame_6.bm create mode 100644 assets/resources/dolphin/L3_Lab_research_128x54/frame_7.bm create mode 100644 assets/resources/dolphin/L3_Lab_research_128x54/frame_8.bm create mode 100644 assets/resources/dolphin/L3_Lab_research_128x54/frame_9.bm create mode 100644 assets/resources/dolphin/L3_Lab_research_128x54/meta.txt diff --git a/assets/dolphin/external/L1_Laptop_128x51/frame_0.png b/assets/dolphin/external/L1_Laptop_128x51/frame_0.png index 94b9e7c58350a3eec1ee0748022c457029f234d7..a42e97fc44a4d901dc76d92743252777571f34e6 100644 GIT binary patch delta 4112 zcma)9cU05Mw*C>C6d{1p`vH^^5)udyL201~(m_CqAqgRhB$5!SB#KB;l%n)<0Fho5 z6eOSmBI2Qo1?lJk>E%!a;l+E;eed1%-g@i(F>7Y;{mtI{+p}lZnwX>YDoILo4ubJH zV*seT$G4B+1OQ$gqN%Ap#nHk<-U@As)Y3;HA#hDC0I=-JO$%{${vaCL#|#NC_yY!V zyfyy(1uz(q>W#)^NL)P0E`ZRkQz!%pq0O=sE$urP1NKU;W_93W&b8c1M^0*qqn$NK z<|DVOD_geL*Y{>BNlTBn=}mi!%svk>Af*JFp3Y^>mh@I+HQFF&UMSgtx(G1XWG^yQ z0UKBIW}n)KBjE0yKVtF}f|~lE+S;e3y@}HQFdx zbi~!f@gbUWG=wIE>&z2i57ei1r$0IiAlQLpRsmvUw|GUQkXF2$@T}tWS76eT$LH#o z^BR*lzK--DE9<@~iij{LRVGbyZ1{7Q@%AjPn9Koc2UOHEy9q;HgN{R)Ez*GK%Dy{% z`tu+f-KgEr_=K*lje!3ww?7QtAf5d(iVm09X(E8D4sS2j><>x;7vIHSdc1KPQq9Zg zg#d5H_I!u*0LH^olFWy;X2Ej?(0Gt>b7I|9SJyP5^me$g*rwo5yV$mZnpT3+>E(Ot z{a*TOHkbs4X0?<$METsC62e1-yL9tZe(a7M_d&2M7u`4~R3N`y1bs99(VZS^a6@+2 zH{NGN162BUe%6j)`@zG`Ceir89U*({9ma65no-me_eowM`GLJoufrlz>kdplDr`zE z^)}^jMfWG+W%0CfboQ!#uky*8y~67VvF(mN;osTVEJ12X+;5F!<^a=+T$Kz6nIrIp z)J`-QOy_ZB7q#RlV+ht8$$sSEHP-sbv&Fb%&n;<;@aOC@KB33i8*M!)`HU?vdhg;f z8wTN`XbTq~m;<8#H@iNoaNJU4F!r517f!IrxYZtfjHlCt2P`OT64vimDy|k?UJza? z@k18HlN(!Y6y5LT&!2TGDt7$k5t|!jwZfI0QuKCyR>13~lP+XX3s-Lp-=qv#`3oQy zb82#9Rc8ljz4Bw3gsuE^iPxn@zA6ngVsrA0y#??W~sx;gputO`8gojl1w z{1_+NLZUFhA+OZ_7+(WdgRIMqa&sB;;NQa?bRDpz?!y+^5>;^{7Nfs2`-SE>sG`ka zy4UqUlcz<{LQ>I*{u(WD{-Z^Sb+1Bw6}7A~8Zw06owkwsChZ4C+|6wFty_1yRw*+g z*VDmU8}m_Z(P7bj5ljQ^aanYfO}-;9KRYQcn0~L~h0M#`mq({muJVPdwy2DAt=uEb zP*#g~%p-LVP*I>Zqa+o7k;NklH2Xul`n-5_%^z zQ_nooIz?eV+0$}BNrA{c51yBv*PK_*v>8!6l~VKuv@Q^Y*ahth?Iv=dUs=Agz5%H- zE;KJR^|hRCQu20m8ng;(z*Xa7W_h|7QV@=zst{E%)knkOWs+s7j=wol29FV)h;;hA z^Sto8FT?|S;*65Wyteh>lU+r8>H71&8K3XizdFWXkX&&YgQ|Mds%0>0Oe#QEIP3w@t zl797h=BB#~+QrVL;1csYkI0hmn&RLM(#J}G^W$4X}7o7W$N!n_e$n+;(8(~F;D8U zxP`
L`z?~6(C9rO>HaHhW=9@UYJYLa&2gCi1loyUrk%` zp>^Hxog&n|FYKC*E`FdqQU5;Z^VxQ_k@AsCH;wTeu(RUnRRbfvBT|)i?rjZqPlP^7 zKi&Ofq#yZdD{g5xXz6Rt*TkN#rQyX4+F!JyE$W`z9{X02K)HZTELSYO>+biv0bMFx zRwuklluC+h`*P3a?Dj78ZfGJk7d(5L6su*c(bepM@W6t=_ks7my#FHd<-!+&p@zXo zc+Q4d#E;PBb?G(7b>A?Zh(E$Fgw<>;|D~|YvFE&Ju=Rf9>mF_IWz=}o^PjSn{hlu` z49pAeGxtOG&hYmOxQVP{<>@Lg`C64#t0bbmx4jQcSx;rha&-axXVPHOUID7$Rev6= zyLPVjTkS6S!)pENz>%4_V4)9+#}%8By&OK4)|NghZF&%>zFnCU*BGaHN7lQTsTT46 z!F%2cC)fPD$#*cXbK=llx4LBGuk~#bkgz|eTc$6~__=FVGAjuI7BsqkL>9J7b;joP zXlHt-o$^QJMcWKps%52R&QvqGq6wN}korC4Tk6kLL1p?`9y_9SXYuPtd9&TCDPc_F zTjD2T^!$(cnE9g10V9j5@1DA=qOP%E)<{J{ zpP#XS5+ZtW)e*~2FVh_^yI+o2ciupLO{}7LoNtr$kbBxni2iZw#!(R|L!|7u*~j}W z^Cgj~`}O0i_6i7Q*9V-B`Zs2aWD zgkRr-1pM*f2%dd(uy%W1C68r#ZNuNluF*9y1iOj?v*8o*Uzfpv%#Ig zD*|M}FJ;@MEB^hLO7-IOGs0G_ux{9ir*}x%*~hXHvQJA-%SakZQ=dKkRNk~3H=R5v z`V9RMeogzwT;hr+y=~!=PCyl@sNuLAd)LjbyePT7pQ~5%XADn>pYWjf?-w-Y4tfu> z1-M!XMU8TLQhFGpDyE$#bi@$#cmArxs5+g*Yv@ zK1&ZHO&z@Ep5sOf7R$OCI7SYyK3?v-Qj}Iy(&gFpLyr4Q>zQ6j`j+);=*kJ+yrg_* zn{peZUFNymEE+w(b&dLUD4sCiC+f#be{j&S)zrHo7e(2xq9c82)0~H$B@@=(Z`%wu zFMX=WYhpB6)HwM---$7k>69JF%$14ft0Ad;?kjaG>SyMn<__jI)?Stj+vOi{vS)1U z`(|02001D5wRAiO0O2YCz_hK)9hftvT)hkIHOtf z;o)KNr~EP2iid3JP5}Tukza!i$jT810M3Qvvl$ZlSS(f>hu4sY!{Bfz3<1^BhG=P_ z;K<~k6Py$(nnq2XV3QT0IERt(P)9t46dZ)bqiOg+YU&W1rd~iG1%<;JD*98YWE2!i z4h{;?Bn1(mI4l$&fWN|mQJ`9yT2Mv#&?~>NWPcKsMDZu3jR=&AZ8#31r>%{LV30@z zL|0oMq3?@B==x&)Qky{9bXGVr$}|X%q2kS0!%*=TJqS!20@HQY(r3{_X=$m$5GWYz zS7v0?ITDWO7xwQ^Ep2BlJrrCIrLFgGP&^fb!%#8*7ue$;j&WF&A1UYxhH9utyn-R% zq2xey^A_$h62~tcoVHZwy0jbiV zr{xV;6waMPSrRE!QcxI64#N4NobXrwUIh^4|8bHi43n84}^Lq%g8$rmqg z|93x-<>3fTg#5|##6TP=grfSd+FTg0SZ zl=qb05j0JsZZ)7?`xdLqUZCN0C$c5%@?5x;T;vEt&E&Ib$9qTTZ#M$+&Nv$70e5IA zSfGYspdv3k>C85(z=+J_*5|PIvbP&gkT0Kn1e#WZWxbjeiBfB_digoS_-L(EHqQ$J z6@I)HEMgS+iVMKJi8M>Rj*6{d2XE)f8!ku=sK5kIY&itjv?rf6aJ8a`V~=`qTSI+C zrRxx(B}TJcj&w#DWKAatG|L;xSj&1MHXZh#TVoZnrrQZ%oIFO(&8wHjpVOA`jzxhU<4>V@fb*YrsBAu(CW?6QZ)#m<|{zj zTdK&R%ubKUDv-U%DLSaM5$LaTt3>ox?tbfGTU-J|Na2^4xRU+F!g(jpmq8eEof)=5 z4Wj-dWODJ*4<{9 delta 940 zcmV;d15^C6CWQ@M=DH6kE$ zbW&wzI%IESb!}yCbV)=#B4K22Vr4pHZ)0g>I&f%jbZ>KLZ*V#=HfCltHa2E0W-?`A zEjBeYV=ZA}HDoPfH8L_}Gd5&4HaIsTFFqhVFLGpNIz(l2lYz>(bxA})RCwCtnOkzhFbG8t``>hD z>PP_r0y%E`QTHcyV(Ey-1*ym{UljN5_wele>v+7sAO`+vfa?hZMt#q`o^=4h69xd+ z9fm|6L%_Qoz19n0f1Un01cJc(p4R~oIq$&)u-0Wn#)~0yI{VlniD&BTS~Q|ua7Zv? z==w-M(dW`t5YiSA7fW%N7i)JGkUIb)og@O-ycAhLZW9m~U;+>(q_+Ta6X5$@BC$uO zk-8c2kFfyq2|*CSOz+sgDS8+H;?ybth6&$eIScTbPnnu1e+JmeW&-e%PNoG6gbnU# zVkS`nKsaSCQ8T56xGpYW&52=wH8GbO(I%MYpH>KCQvoOo1mlk?NekdjVCwtM0wf}3 zM|5$R_6KOyx79{R6KL5kEZ_kkH-oCGc2vD)yhGL%t^oQGxg%6fUo+8#ople^sw`f$ zF_X8pGyMXuf7w+Tv7D+90EixI^*c#J5cQDv0k%{52U!P;krZ366aXY$6KU%qK3=9j zjaONEh7draQXcm&o$iWQ`wD<+3jmF#V1fuoE|9R8BRvuDVjzSufS9JI1bENttJD_2 zNpTZ^q~YeEIrlGo25`JPSaZ>NgG2{<0L}TsG%SROf6nfUrU!tiEsttJ_|gaSJ2^)3 zK67346CUt;!(wBS8GwVP*cPu~l{?|o8XM*RO@N+mXmvHQk>q`~Gc$(`w72I<2#Zd< zp91}(CH$^Db$m6y+yw|vg^Ht{@c50Ond$@7$wxK65&dHq>_mq~2Y$-}gtXl$ zhdEfMI({cqIldN-gCjlqlHWKy;`~SvdBOy3R~??Y{Kfwd{vW`X00RJmj1#F0`IChJ O0000L!>I6V9MA# zdZxav^ZU}$`b-_;%k}Tvw)MHLfdCaCy9%D0E8!xN`9x_k#i~#M$?{^)0Xz|{P@WOs z>bJK&q%lzn-23#|$zt7TP>7hwV#0w=5Oa7C&2yLBEUEAp96dgp2S6@ew^TEQsH9ow zyJW&z2Ttdy=bDD8>WAGnw1qrPwX$8~&*2 z*F$)GE2gFO1{Z@tqkh(SZpJJ#_PrU$C#bEq(ZJU>&wOdv7*Yp9`_d0xUp`}2FT?9M z10GMTlZGt-UPU!S^JRCtf}0gQ9c0^{(R9SmF9(u)AEl`BP2s0UYIkYFZJM6V{Q0H9 zAj_|=#M3-j{WcRbeYeL|vZ-QnuNW-}u5DqQe93(!{E74{XP>%&TQ2o{ zl(|K>!sUK1DOgpw|EuC*n{xWlD#Vj~mNyb(yeH|4q@fH%=lS}>pv`i|?Nx+MQv8%L z{|sw$!TcxfZsoLo%B4lietp9e{fbLymG2J*6fcX2IDw2aC7EsIrsTRh~lg9<4Dk8C&F-^a}5gr=+?qI$XTRc87&{e~QaH^;;rQDeIwI zTzRxm7vy7Jt>1h;c^A1l2YH^m2yqK+NfA3zKwfdPU!Hs{X1VKs8gcQ~m_=z!3Ga)2dLp2jX8H%QE9moUd~{ohefxLdUmf*}OMEo$k|N zc&Tm?$2+Q(MS2xidv1|!k!aEKO|IFixi{u=f|t1$x!Qlk5u=OQp3!tKjs!(I=e6W1_Sv{@`=}8HMxV>SPik5^aI8*q zRQu@znZ}c2#&ceC{&QdsXkEhb!PR$t%=ue}8Vb4RYwu{@ExP;1l)(|%IHOL3w-O8I zX)~X%+*W-am-vz_#6AlK55JHU=?Z_184 z8<%gf_oz#@t{^MW>A9XRT~YuRXb4~e{e0I^=&tPY$Dk$oX!IIr4YHOYhQH@@&n4Nc z$+m27nLWvAx=k1-AS5#3NQ30qZRAfFVKLw>id1NGoFPgR^dSQLkg(sB=a=w>7;oZuVeY(r# zJ!w=bCAarfZ`jk($Hh6CmAV+S0u{59e*1R0Z@bcUuzES7%l>hD?>+>+}BPJziN?iFY{<@2ZkA z`D7$vRPSq5J=S1RRZ;i8^g=zMl5I=hn}21ly09X!{^;KLfRkmUhI_t7`z>piF2G!3 z%c=%V1YO_!eeu2?zNLq{KJh*!7qkXc2iy+0^x8fq8E0=D+!fg6c+Afpf8T?<-J={o zQ*02-FU_xR+kf4I73^}*Bru}ZuWIx{Yhi0Hr=D|WMO3r-TuQ%skwnqKcGaL$QO)x< z6WbCRi%$lZ1!ugCId)*uyQH?;gF6Tu4n2Ga9ga{%>Z#$>!qi(;A>do*Jy1D8>} zEke~%Z2>ip{uNFlW|M}(qbCX6MOB0rTbgb_ z#x!oOJsTawzFJB9G7|meL*a*vr#)Xr=JGgyamrWN>j&0FSIXsU~DkCYt`fHMWawrrBN@U&cAu_M(NGLH#BQg ztI>qQWrxHcaq~+WU%i(|@jDZrB^-=zSf2k&cTH@aux_>TV)?^5XZ>!{+oX=4T6Keg zcMm=nC~S0X#IEm_87K!!Aqag7gH@-+&)`2Zhceeoai#YL zixItzvyC4c*O)ICn-`x;&7{RZUP8A*+p>bZ#;O~uuT-~Pj57INSD4nC20N=2T-jxu z_~POVnOYyel5<&SiH{1?@I9w`w9=0ae4}9ze@=H!ADRjCht+k}(IOo=T+74)a*xrB z>!b09xeq<`$Momi^W51^bxws-?abOXc(xV)Q}##xPriaacb~Ke-Q{8BqbtSldl$3g zyXa5oujna)AA*yD@`%XMIe+xi?^EW~J!-Y6b}_>90YbN@<1M^J4!y*mzh+=!`q`nC zjfHpYc7)Rs`ziH_^EV^7UJ?EgiA#iK?1zkNtbqO9S^?TOZ_`qKoJ#&fX`3}x>#f7s zg-$`$QT|5r#{Nt9&0|#zw?>+(PEI#fR(h6YhFCPe;6zMdN3ip)$G?0WuWjX;l2n4s zutxQUNg?-)+kRvS%r8zJeGTa*Umj^@Z@TxnzwMt2lJAhubuPYXyB#zWIP6z@prebEq@6f9nAG$0TFkzf zhcOHCOocaBzgI7W4<4$vNVCj~UvwrPAWz;r%eZuDOTp<&HX75K>ed?UTQ^_Tw5_F0 zXALRe!jGYjVSdbJECh19KOfo|d5uxtvQ=BO=R{9&lJ@$~#Umv%);m;p1aJp8N?VJD zf=5JR-n08S2Ap#oJm-(%Z#J)n506j$Dt~@H)%|L5jip&)`!~5M*Sq;1G}b_Wk;`s# zmd(^goQLbcPg#gc)L#-S@`2yl;?}a)D`k(lAEUv?gKT0Retgnf%RO6L^wP8;=G(z< zH#aF?eb#v&_VmQmehxCPW3Uxq+E(cI2==clpP#wh?2HQP=$c-6$DCa(%9_o3zH4rm zPpr@U?OVC=jHzFbBxfb@3YA)ZR^CTP7O&3_94^l(uj&cx`JpYj`}XdBb?%DGBlyA& znc~b6f@_T{)+67osDQ&Qx&4*>VK|*87*GzA;a>dJveMSStewQ#xW>hjIMd>r5343! zf}eC-eLM83wz!Sg=Gfp90`F7l%HpzC&1Mcyb}Yv7W&IbL7EE@}Ce8kuUH*EvYQ&@D zm$+!&@&>8E#SQ=f9kP?R8vrC2008d<0Q?Y&c(VWyg8*>Ar%(XESv#{OEN~n?W zbS2=0^XBGe<*Skj;Yyn6CS*71Y1Slv}1px8SS^M(TEXiathC(&fK_O5mI06kv zV$6_8915HDb5fke#&g*GNf9k279pNVg?m$3jF@OL70;nYvH8OyFpJ127LG!;hK94* zOdK4}jERnfF`{X33K>p~q#hQ+Sa2i^35V*$9sZ4FhBMd!7T3Oy|T-=Rnh0cn9lS>Sg5JCw>MQiyEg{{;^ChhYjC7siM_Ok`U_>4%9l zDx4WbgX;W?wJ<(LBqLhr`FD8#UG6OWKtwab=#fIj|M*Do=RgR4J_yRU6IJBkK@9%X;4>m66bVcA?kvVF3e{Y#f0@6Zwi@DL0N%PB*sP_AzZdp)tx3ciMD zoa|#V2r60_0K`k_l>F351&n1sJvj(*fV{cEyCrqD1`&UxlE=N_o%HCr$?qGb;?Vg1Fhi{`Nh0v(Mz6 z+TJR$U<$r^oS+>_aycqj0knx*-HCH6kg5}5Zi^OC{TLK`3p9K1{kc7VsyhOsHKxJ% z^hZTEiUcaF)nbG3XCh`wFX%zUN>3e?YYcia>9n;@#BnY&g#=g*ifYPgTx&=mxj+P_;f3`sz<&7%x3S%+!{|Fh z_MchDDZc01rB@rOke&y1`V;#{b4_Jil@Cw}&5_!dwM7-RoDI2>vQ5ShQjZ3;`|6s8 z(Vsyt=m(Kfeh^?8esps#VtiWbtj4*U$zQh}&-*00g&xwfuNFw4KI;>E(gywzXBXe4 zj=}73I#vQB?wH*0J=f5pzFRw(Q8%Hgb;QQo;Vt4Wr}}GW_h#>=M=DH6kE$ zbW&wzI%IESb!}yCbV)=#B4K22Vr4pHZ)0g>I&f%jbZ>KLZ*V#=HfCltHa2E0W-?`A zEjBeYV=ZA}HDoPfH8L_}Gd5&4HaIsTFFqhVFLGpNIz(l2lYbBoTnkOA!O|7y$tR698dCdIpe(0Dj&j5_@zSshbi17zU7U5Cjp-^p5?T zqK5%MoLU8dLE*iYV}Q?oifW=5U?-aifRA)C889Gha8HVve~1zQgj?nkHB)Mc>*4~| zoEQwOiMiB>HiAk2WFd@A1wb(ntUszGEdVzHQ{Q(CkcgCB(ZylfAD~s=RvR5npk=#Y zzypAs231wfMgw*lr68Q4vsvKXd8b2Ri zZ`f`OERQ%JDI#xBupMeVukZil{|EmcfIk8Z0C8XwqMbN5c>n+a07*qoM6N<$f@3pr A5&!@I diff --git a/assets/dolphin/external/L1_Laptop_128x51/frame_2.png b/assets/dolphin/external/L1_Laptop_128x51/frame_2.png index 2912da593ede6d5bb1953804853ed418ab7fa643..93df45f84df55d52a5b31beee7b14cd3b744e8e7 100644 GIT binary patch delta 4112 zcma)9cU05aw*C=%k*ZRpgbbjRkdQ=51f+!`NEZR6CLu&Ii6r!rC?Z8sAVY6bB1i`Z zq==}1$iM(1A}UCCKq(Oz1VMQ5-ns9+yWU%Gy+6)6XYc*(^6hihS!=UJ8r4!&=sX0| zv!(#ha94QGj~4)hP7=+{9jVS%W?&nPxvq|Zt}Yaztpfnoy#<+JuC8y7CJc3iMHc@7 z2RYyT*!~n4iDG(V{IX?zPjHJOQ4Pu^API~`F2vfgoAJs~#m%BY{IF|1zly*K9T|+P z7TI#_R&Dj;Z|m#3bJgUPhu`R}yUQIzp3*>iIV>xS&z39ocPVz9Vg8atniFjqU~nn= zGSmS(H_JAk`X~YMzWzVr3zdUGK0I9PNcYDe%Ijey!=C@3sLW$2`r2YPAd&abKvqja zI#FNMHdVWMC^=g$ODjM|HQ>n!Q;Gg01HZIG#=BaLrP=Qu7&a&N7|_cfy1esWJ@U2L zPT8tEu`W><*_y8h6%G)}lXE7-<%Xoe~!$xBnn)SeuDpKJPU9>=2afVu!R&73~MYp)UK*Ex^nfun1C z9*EiZBN$9Gs;T)mItqnE{HSz12-zT?nfQQ-l-+J6h}Rt4TB+L`kpp}Ok}f^mxCN~h zVhloomy^5xuk`^&Sp`|)ZD*U|Q;o#Va z84czw>cN`c55hCntZG~y+h9=j#En78b)@vS?jgy0TwK;5ja2^MO%xUZb6>t{29&}> zdU|X-PF$QW=*E52n&$yStkFbqoJYu1XIyZLamkTi&J-EQ+iQAUpLa0Mc3Q55ixju( zd)SUa@ICsNPgtDCPZ?oxZC?3^wbV$$0GJOa)@u61QT(uAkC~vjn50?6a6pBOMqFia zWQFW^MYLc+Laj;Muvef+?#fSO>eMIZtEHfosRocoFOhDSCT9P5$WdrYE_aNe&cSnRdT9O85a@LmS#M!hDaU& zlbvJ^^J1)IOM;vVD;y6CH}N$op1WRYsbCp$FVacR30vVYYK4-mNgT8KaIa%nVv&b- zv`w7ub&X{9s1#O0E% zyM#F^o3(8jt+$Vk1$COFss&0d3n<@Ed9G$gS1rzJ z)0bSAB$s{}IbT+et4DYuNQj^uP)-~|8uvn708=n)=I5mABFFKRauqq3_Zf4x{@or~M*&n;#aiQe5ZlWNeZ%eht_GaclKQx2- z>)gvDeNBCnnNi0bvci}SnNzA$>IZa3F4nzr@rqPdz0XX^^8x42&L3FSER5}4SVy^l z=4W+2_1bfW72|dKzn5pj z)p+t)WPM@0cZqk($B-EJDd(c9P6zrhaK-n^Q)D1qMn^>!EgK-$EOSTp)$Qn%^%QhU z;jzmyRwRgPV{VT$L0pOML`c{MgTcC6aLqqC{u zH;HliM>~Iv4eP$!N?aKYURlUrNa^og8C}i}{VTL|i?-{&%e_@9S}AImz?VSpz4Q4_ zP_J6A&2g`CmGV;ip@OsdJA*5O8``?sUoH-|LTVLjF}2(z1gV(xhIDu0&4kp%g$aU@ zmf=`r{)R==_wdzq`LE9F{t+jm{)oH~QMa-Bm+}tJuIsMh)|-um-O$}($scsYFL_M<2MVzS_1m`-}LWsUxYo#pvSa z!-ep^`o;QB^*fZe>_+x0fw{yGiMNm=kk&LWr}2vViu)C<86?eb)%l6diQ2any;&U^ zQExKd2vxbb72Qd@?e`)-5z~9KS1~DOXp^7||8w^7?4`K?5AEuXYC@1zDBU0`7u%~o zXZPYmPgakE>bUB%eYQQ#y4pH_rj1h73QIR+eop_y{J|7crJoUWAlmk@UfeI7?_;M& zbP#_hz9YsheP4=SD!m*uw(NoI|2CtCH<7JEwDGvU8glJ)v}(cVXA+A%m^*5kT3;-h zX}YlX(^fD-)F7@lYW2}&y3=Kk%TepD8@dZAHB`^@or<1HkDd_XzTdolNa~o8uHr|F z@n0V=l}9u88u!lUb?JpkpEwevB{MbKz+yR;r26PLz6rfNsXMB>+I(&0(}${Nx|YAR z7gSfh_C&1DbB)&TDNA}8Q_=4wICo$O&S z4SLh@fT4_J{E?6-!KnBsE6o_q_DWP`s9Q&!ef1Nsxr?ves@&T73_oNT+6*m`* zc#m?0%+m%!)k5!tVnPoUZW_OPedWXCe(9^b3HA>PD-EDgZJQ!9cF%Gg2-Km$0^8Gi zRO6Ywa0k1gAHovSq`&yKL@#c(hVP{BvV>#oV+gPhUdACkpMLMFqTjA6c&k+xvUy?i z(E;wO%PwQVq&KAMiQJ=L z%bmTk=bvk91^@sUYwdg%03y`@fN=u=zH?NJMF0qa18Cs0F94vk0YI9P-{xegh$F*h@?K$u#fOwCbd=5UNTh8Y8rSAk>USUo+I0Tg#qUmuFaqwr8a zJ%20|jy#FQ8zAvIC$R?1RuGELNk>7O2jl%{cni)lg8ZZhg`=QwJy#tA4n4GvjwT$5 zhQohWMnRt?Jcj|MsV&!vgV~nEz_<|I)R8Ca01EXkmWAcvAxBRTx1`ab$ly z*zxc8Kmj9=+DPz;^F$Jk97a|DS8>=tKN10tGlIY%KY7Cbix}*0&V2tQ%}nJsq0{c~ za0V@qw~d9Vt9#c%&O6c^Tm&O_a8S;l-HkY(hA>>|;t5P^!9;Zbm5hnq#%vhu89%-} zbzrorl*)Z@nK2}#E%O(3?8_vOYB&R$-Vij0)G3R1-7)^c|1^&-c1`8${`*4!?pag= zP#xBanCo}sEr=mGEg;+9u0Ktn?Ib2;Lnc)A_Txw8{h<>Qt12O2ML_4;U?pT$UqxBB*CX};>J_yfOPKV_W@k& zD+O9&?uoo$y%~TpikmE{z1fy~8AxRps2Ijt-WD8~=~nD{kCJEIs-vs-Ro4`6JbeQR zm`+@Ic1jF)>E0-R_C$I%x2nm?H33RTxfV|}XyOhH$cp+QXvB!MP!OQiT;=iYNWP_U z2DMtYqS2{h31!q?crN3>Qi%s!pPa`sY94IgbFJqyDHs5m6z85`C3HtiBsQMmUc472 z25%`Jw>~e~zvRh#4^0o{8}{Pzg*32@1_z=yjsRQ1iD|kWF$!{Nfkz^R#LGvIf}8#A zSc$p3a*VNP*q}KS^_l|Iub2v&j3w(u`p#ZM?rImE!jx6{QrbyeW_6!W&g?1fckj=8 z!@aTwRudfOP1d-Ue(ROuA26K8k4}c_^9q#b0Na{^WtQ!Eu{pAj9uBfJTq*;o6E`YL zG^54I3nIFjIWaTU_iwMicN?dO2qtCca?6t*A$GI#zRTZp7v8oDdMl;zd9uW>#WeUr zf1k{v5E<)l|3+=EFET5lUrFn(zK=SD+~V6l8gA?ryKumNp!8Jf7DH05VFE15`C9=S MjJ-vzneX-g0FebhdjJ3c delta 919 zcmV;I18DrRCh!c9BqkYjMObuGZ)S9NVRB^vL1b@YWgtmyVP|DhWnpA_ami&o000Am zlgSF08)al+GGa4kVPh;HGB7eRFEKGMF*hwSH##yilX?r^lb8%8lO7FRlT!~Nlba12 zlNS#nliUq5ljsgFe=sm+WHmHpW-T)}H)1U}Wi(_hIb$_qEihzcHe)$7V>M=DH6kE$ zbW&wzI%IESb!}yCbV)=#B4K22Vr4pHZ)0g>I&f%jbZ>KLZ*V#=HfCltHa2E0W-?`A zEjBeYV=ZA}HDoPfH8L_}Gd5&4HaIsTFFqhVFLGpNIz(l2lYjj`U{~QDa z@m_Wl095cEOn~TJe{N>HF^q!FoLda|%=)@EjkyqPB4`}CK2lHgwsl8B$|91uq-nm` zd-8yt0Jzi16oAP~$^&+c0O5cJ0GW{41K1&e*SjdO$ET6Ix%p4<0QMaOg2A-t#J?tb z1OVvNS^&6R_*pA?fVVy8Y7_^U$>spSTRLeT2p}T4n~Q0Pe+B@MCdU%hQtB4hE(G*B zaeJUo%&tb15j6KVFGy}W0L}wq{kuw10`Nf)>if(C3`8ofn0Pqs5AdoVtBq$9c-dZf zAOnE08(dY5tNJ~Y1JduX2jCwu4uq@eeI_Q_#qbclN*C40nQ?2|(oaM!?kb37Qw0IQ z{91k788if{e}_B=Fg2AQj5=6?q{MpV0KlMYV%U0E=1Yrbh$>yrAOV;v<+^{VbXREY zTL4%c0ie(nG$6)S2uv1ptR@0k3=GKuEHph!03WNlN=*SIDJ}wF&~UTSoaYz52Vnbj zFqC579GwHG*pGZJ3lWvm7i$2$R`q=7Yk@4r5897@f6e^ZI7L;@hm5M>L^fm*5k5I^ z!18G3HC771E&$nG7Sy#1l{C6KnT25k<>R>%!bK}y6rrur65>=&VX~s^+bIA!6%q(m zRlpFdWEz@OmQoh2atV tBSq{9B^OMG8t2vJPyT=K{{VamFaX$-6SGz|X~F;i002ovPDHLkV1jKqf@lB$ diff --git a/assets/dolphin/external/L1_Laptop_128x51/frame_3.png b/assets/dolphin/external/L1_Laptop_128x51/frame_3.png index 3445c5b95e28f2d8e93d6ab7a65a034c2e76ffd9..a86b5e744bd7adb1cba70fcdc13e5ef53209267c 100644 GIT binary patch delta 4112 zcma)9cU05Mw*DnF0i`Ov3n(=WDG`tsigXAly(NSoCXp0CkOUC{6)91QQjQ?fs|OSi zP*Ed-G!e1U@eoCbz@Z4ri}#-M?!D{1_161i*391fo4xn9XRlc^-}W|ZW~tM8ahA@O z0ML{vyc5C)076Ib*4A!h4?8Or2b8rT%*4=853Uab0DD$ZZVVdzMk;l%Gv@5Amr$_B z#fgrGz(_nZ5EYUy8+@2Y1YyvmS_&3N+1yaGcYDGZc2oDZX%gFyZWK`8a~LLrLhBN3 z$1c~`KG;}U*`BQ>e!aUvZ`)q%9Q2h2aw;HsdHjx`tQV4;WYa>nc(yxb5nzCnf*D$X zlecYqP-FZavEIIyDaESM;2>TQ=j_P`VA8801j9vOx8$}DJ0WQy9}vHJ*F;uVTsqBI z!!b+0b?{QYT%K;Yj7E6ZVN3D8bd!+medgP`&1Ly-t4v$do|@1r?s~orT{`fs)k)Rv zNm@giFruwcSA0^U$@UWTy3UNz%s5&E!2|4fh>|9qOjk1$hovh^%&E=H15@^bL1#Xk z(4E2vKgo-Ba2%W_OG@xj6m#`Ij=sBLxiN<+C-H)N08O2OUfipI5sy~|4-^2Y?~~0RsM`+HIG*N<9AIJ?gCNW*bhdZuj!nhMf^PAhPvCiJxv+7%NiJBZ<0@e&Xh@MA>VEW6yq_6t6>5)>1au!qzF$bk~BU5 z$|*;uRyjvD4NZlPCI2DD5EGXxy(FWy_X*!OyV9)K3z@Zcm$HOzgYc;KZ1Xuy_@#ao zqPxs~K9rqoX_R|$rQ3et7XB6`uk+Qmini3>&bk}9hgJHF+8M~!rH$FW|E+UKe1VrD z)hD}$60%MJ}Sz-0FBE6Zql92=?zbI5PWm*_WllK-R-E{3>T&=cCUa`IfQ z;+S&Z6QRbGaqUI-MW0168hD%E?n%{DKWXXyVFl5=%$kRakBT1co7Oxd9IN#}bAo?4 z6E{odlyBN582v;hg1arUG$SMz_o!Y_f2?Um*SK|^l+9sqa_rTs#p}|OZ1m3@Y|4qf z5?f$wo8XwE%Fgz;A68ez3$Vr53T%D0MuF3q+R>b{=in8QXv7wHOMEMX7xmcwvEzBY zCd*RWQtMFrnKt!656=;Y=oU;pCS^{r_e&1KBUVdKOIqvB=-Dc{DyGLl5Aw)DR+&}a7&Kk_xZmTm$NTcya+G5xq_bj= z&Sx!tt$Huh%JBx{irckwx31Nr%PE$4+k!ibm4&zc>l19_d{at88ypY6hSCa?iiujBC+GPSR5}KFH zKgyqNEKUh54a}IJo;x||QBu?GN*@AF2cLe3h=9t#)Mb&f;c~4qS7nEaR-ot>vA` z{Tf7Loe!PHHN7rn%_Ns!*O+X69sTZjkM>ygSmXsuEHCu9OkUma*ua>4t*cLWOVjV- z;|lk-UXBeJzFklIIvV|TzHmOHkM(tQF`xD)t!$mLeR7*;y-cK9#3_|OmCm~Q`DzqP zljU$IphCT(%w@31xo~UX>%gkMq5c>Dfi|^zrFv974*^cNMR-lf{P6mN4<9EU8tTcBGIRKr+v)1LE1?2oLGtnFLKTaSl| zp}ma@jh`B~NN+gJoZ&sQX;kqyY6sNXvIE@5D;q2CRJL6w=xo#$rnRQ&Ur`Dy@6?We zef_miji-0X)$A)F&kEB}tcxtA^mBu2I78?kGY@7WXTyE;YddRkQFb)CN&Jm4me#D( zv-eN)p1Nv`Yb?6tyHM1!oKMUjOi>N`aY0wS2Gun0&IXs-u7FwpSKc)zJ348J%JGv!iL4)W)Z^5r z)MXKp=!dF}%H@cm$V%fhll(Z2L)gi%$$M9bH*fC0ap|VH!i=JvnF8hhy|>kETWK@d zBU1NKeEjzdTZ!cYKq?IHc;36*6!_M zzIkpl<}Fy%nlAxHwM2@jzOpG|4odlX=gUjSdk+W!9i21lQ=|n>QT9Ui@X^Jio-v+F zUH9|ih|@ox2`mVpM9Y=DO+6AuId_)^PnYGERj~Y7-<1W9bsZa!qpv$YgDf8sD$XiF zJ5@Uwx)wMW-JsD+y1r57U!~*NgHqu_^y@!c*4qYFl@rN3b#%i}+6>?B(~3#Qz!%-7 zYmskjirW}%b`73EkbddTY&v;UZ}#+L2PcLp?6cgotaEH3apC8}>bFM~qpl@C`FQeI zcS3JCS^)r{5@zq=3;<^}0f2D<0KRioj0FIoLIEW3IT!$t`2ZkIDr|Q*JcO^)&_aOs-u;i}+0&Wz_007^Y?Bn^eCShS=1{kca3LFZDL!bx<%s>wY zL&6QSe@ya`DJU9+ISEpdB%|X(R(l?GGkdc@$Gqnf`g@lAa zNYv;kePT2Yf(e6Qqp+vBFfs(D4}++w#Gd|zB}EV^L~;a?IRTR1^WVY-C|t$T+7f}V zwmf2GXlx6Ep{$J!ZQ-aR*4CCb#whL!&x&~tte|d)K_IY3aEzWocxb2|9BvS*XJQf> zriXwVhaL$xKp0@*P-Yw0fX)p^LRv>-Lnv4q?l4pPMNbcEpa(TV!%VpJkT94I6oG_7 ze`Q8OIukMY@VNhk!VJ(bV}PEF-+*4+GvQN(C&ibsO!1=gZN z%vDUe6r7!r_INUd7#+uzqcPz~Pwbh$R#AABf1D&TB#eS561Yx7XjqKeUrIcIObH=` zVI6GD)VO~1@pugK|5N9`_S2Cu5m>IzzYF}oRPCR^$;5C30uGBYQ-i4e;tBZ|G00z>`Tt3pnZ;v4-$8%R z0swHJgN-HnWY2uTTSAYD7;125*Y!j-Pw@f%zSGK)TJAG8()DJAoa}vTBz4#KwIPLpK&8#qi3@ zmQ}u}y--WOtX<+0;F)w8bCEuk75r)F&m8m3e$e#`zu&ZfUatF+&!_*Gr$sSvB|0aJ zQOPjXRFRxQgXUBj37?V`z?ItLF%ycGxsROr)G@(hDOE>z(9z=HpnM0B#>ks|4=bqf z1C3&m7KF$A06U9%S#BTI@C~3cU7&87m=PhF-x0gTK{mvQe zY220u>>YTaT|;-a>iTUcZ&hl--bMxOiNlJuAUDKa!0o=~@h_^dAl}lt5dgUm2$I|0 zFVB7vY7$ffpjiU|jqV35oYYOoM4al1<7Kocmd-m9>#Pq-e6?}~&1kpqrq#)KYL$+G z_dTR-UNqTgY4q7A5A-QrlfJF6nRFE_Fnci4Im$#WfG^`CH7tHkZe&7oePeo!mvm|& zF=)t4pKYVk%H-j@q@|dlOs_5ndWZSk*Uc@C38+uz-0oSTC58*rJ0d?;i%WUVCjkz_ z2jnmv(d)RQ1&3y8?_61ZX8=OhFtYNi%pbD1eBtKd6%zu7Gx_|FzWr8JDLi62jfp9u zSgxnslbN~@$>bbjb*%X%&T`UL52EJw3FfBC4W7t5wzWI83rYY5#z;sOQ)R@scPrq4 LaM=DH6kE$ zbW&wzI%IESb!}yCbV)=#B4K22Vr4pHZ)0g>I&f%jbZ>KLZ*V#=HfCltHa2E0W-?`A zEjBeYV=ZA}HDoPfH8L_}Gd5&4HaIsTFFqhVFLGpNIz(l2lY1E!W&i*H22e~? zMF0Q*|NsA`*`M7200MJKL_t(|+T@u*cEd0TL_hbxblgKMmk|!VN}!&$ym-0KpS(09Ae6fq#j2nYxm00mDqtOkTAylee}b{Q|GqT^X?)st^DW zz1Hk^l7=Aae<9BSEKT_bSqF=e6kD$p07$wf($+(KybOODuQK%vApnU=dECErx+`Ms zD*#kS0BAG?1BkHY0tt&b(h~tM20|DEh-rFC0B@_lN-Y66DQ*HFX}H;G&fN>20XR4v zWJ;)-qjLbIeMHs7Eg_WNMPgj1pT z_`e>%5j0bM0K4V2{Z6Q|ea&KcKD=IRwlO?n uf24>!CPBe+sBvCh{^b7${|~^I00RK4iW97JxgC=L0000<0*E#onf6jg1pZnbBT-RAUQ6rxsOJl+tSQ!97 zLo(-q7c&5Gs1uBgY{~YfhSKI3BNSWm+ESmyc7~`lyG#UTB zw))ZT=H~ulHSz0%U0Un@YR9095Rg_5&B|i2U`Tl>uo11DzrvSlM_C2v43eI7MZnU@ zr0rsT1RHPPtJg7wGC`n=Obi?07aoB~Z-$U`Yu2NpyUr_DuPnyH&jF;72OWquE z*ZOAZb(5}IE2a#QvwBgEzl(GhZ<{ZQ`!2qf+AI?=b1euz98Q z-^oYo8b9$*$`<6J^ER{w

fU@NXi8cApLM-(g@d11Y7jzSNgk28=ves_76CQ(%|a z_h?>T8oLvtpc&JBI!~j%xU15doNzNvgCdqSAl_nAK4wB`)o#^!m6r;*70yt_NAfc)>&f^< z@sw;9imgC^x(n?=|Ho1e4d!RkOy(A{gQ?sWQQIH0M z5|a`mZ?lC~Sr2=M5%ZuXY%MlsiM{Vj8qz*g5uzxhcyBcPzUcjQ`_uO1k&^@m0*$uf zxWd13dgT1wa%?@q1rdnw&jIB`BZRQe71=Na3x-~HC{nk_@wopRoal(PDZ^CeIF?LXU3l~tEvERvxeI!I<}q9Vb0l{E56k6nf^H{x7nq_<*`fNJEPzzw2_WShg*l~H76rXw+-#IO(|xv zP~IcGIH#iZ`~w@ZhlQ)M+vO^!^6}fv`OR6>TI%mRj1rBvq6b6^SPER*gxzBU8`pH- zi-p%0#(0!?B+Ue0yD)2CRMlxi8v+761G9szc=u8U`rLH`o(Ra6i>YM{L|3&e+z6ed_*`$eGCYpOV!>Zcki? zS9lIO4np?zP7HBh5ZLgMrpd#k>*Y7hQwX*mwijV?n)2VxHoowFN*PJnFGd$X9V&$N z)i2k7tluNO-DunxW?PI8=6ef11#V4sx0|S_ueevynh~hHTb&=@9Iu)v=~3396fu@D z#!=lMT2uiV5 zA@br=rPd!wD;gQISKsk<`rH|9q#RlITh9#4yK}d5XPIYx$fPB$?@Yb7vxY*IXiaB) z2QzNsP6bD>N5n*!DqmA>uT-m~I(5`pS3h=NbbI4eb)mh38YvYqI~3XbvnKd#a8K|$ zH;HHZ{%*y(-_WHB&3LWsunlvc3qG?C6N!0wCv$J+>54B%i0X(_S{_bTw(i9*q>c!- zU?vdP)P5`{t-H}Wzg$xHuOXH;oswegz0q43DYgG|<4Vz@&Kcn|F0`S8;^u-8k5Pu; zB}zY4o_dRlp>h>&>rTE2n0kL$I-DG5eZR0$3lh<`ePZ77NsbMkJUCEbp{GICoj(Y* zu^jx#$tM)}C(91E+jeW{UfO;c=QZnVc<7Y7Zg9`Xmwi>V#Hxa~Ds{ozuG>M?97ptHwsdhQ-^gdLUwZVYW%+m5+x85I8ta^|221IE)7SEyUXE+K|iX1H~ zEm1Z(Rt33KTG8Wgln-wb@GFCYz8tiS!=|0qfi0;>@<9y^@k`Ek`aNE^mE%Qa)-^bjZw@y>;N7 zYhefgfV7X9y%hk2%L4%Y1_1mxR?(LMAQ%RqfzO@*fX)U0AyR&uo%XSX#n#dhb37j% z9hFTMy+2;DlgymS0Kh5mYcK%0`N9Ce{3Z2lwuqLGkB=G_ry`AjArMd)5(-y?z~N{F zD)r|qGns;+QqpG`Bn8NhVI&;X9!Dky2l?PIR9qk>{SAYvrhgzAjrGw1`%x$)G!#k- z4)Rwe2H~MtA1KZr7jO(CL*c4$C|Ei);1`zUN2CzRe#G<{1|hcp7IqnYr42QWQ5srC z8ipuM6F3}Wq=hm@7{k;w)L>eM>Ih9t`ZbWaECQjX<%RHuL)5SuS`ZCyH5^1s3x|bh z;MA~MI8B7QCJdI|3R0sTha;hlf^c3GobmC{0so>0fvG`Y8jf(SV|r*fTp5N$!(hKM zBcZK`Sb}fZe?sAEj&MyhLKCfy`VT0M;)V61c>P~smw!0M`k;M@K>=PA9WWul3y*`6 z0`Xw!zgZvWNAxEK9Y_9^-oNY3k3SGWL|=mcvEhGwB+^$wu=E@dINgwuKm8m?kp|V3 z);^|SWra2)kSWBVuwyw0>x*{4UHNO}Pmun{Nus@cCd^e@gV|0JEB!l+M!oF*S% z4v@3Cv4P`-?hiSxfnQ)JnB(?mx0x@w%Jjr3j0Nb`UKdPoF!s^qPIg?%f(ov`pY3k{ zGC14&iP3wmh^1w1qpM<2EGj@XPr*dmnolMyc_c8b6=CV^8%HYUAX!N&t0P!0$O2 zzXox21?`n-?FKYv$8yo_qZeXtbLkBwbUpv!E8i@hx)$|(Eu0I+Ir2^*c7MZm+ zPop#A>t#vPPjPQ!mNdANC-m%%XV?tFDz50x9xWZQ9!YiSnJe=%PrKQOA3v*rImX(! J*3dKRzW~guG)n*g delta 917 zcmV;G18V%OChiQ7BqkYjMObuGZ)S9NVRB^vL1b@YWgtmyVP|DhWnpA_ami&o000Am zlgSF08)al+GGa4kVPh;HGB7eRFEKGMF*hwSH##yilX?r^lb8%8lO7FRlT!~Nlba12 zlNS#nliUq5ljsgFe=sm+WHmHpW-T)}H)1U}Wi(_hIb$_qEihzcHe)$7V>M=DH6kE$ zbW&wzI%IESb!}yCbV)=#B4K22Vr4pHZ)0g>I&f%jbZ>KLZ*V#=HfCltHa2E0W-?`A zEjBeYV=ZA}HDoPfH8L_}Gd5&4HaIsTFFqhVFLGpNIz(l2lYk22e~? zMF0Q*|NsA`*`M7200MAHL_t(|+T@u*cEd0TL_hbxbljhw*{y7LF z!uy^#03ZwAg9+f-e`P4+g`o;MYi&{Jnf-Mw8ZjZbi9j`Uy``V%x^yE#+9ndTl*@dx z_P~Ig02t{c8Gyx)G6v)r0SN&LfHWZ^1IQtO@86P{JvNQZ&CoxN0pt?|iGtDS_?Ma< z4gh&-Z2$}k-(v*^c+F?1Cer{b+bjUQtP^Fxf$-v1icv%be*n@cYm3s98s<8MfH@}y z19M`oY;%P`=~os~Z5jZEfn_7Qa;OiiCNG04t`2hS>V4RM;OTU$-P7$f|uoLQ2)9BYX)#B7CJ@a)NHu`Cre_P_J!@7a765`3Hvv#I-1M9CkS3o3IM^Lj zPH38=a{$}cn&szI-?;x39SzogZE=EWdGh#Qh^h r diff --git a/assets/dolphin/external/L1_Laptop_128x51/frame_5.png b/assets/dolphin/external/L1_Laptop_128x51/frame_5.png index c997a0d838442988e66c501cfca939a40005263e..ef1a75b90e1508fb8835ca398a0d1ebb9a77c00a 100644 GIT binary patch delta 4106 zcma)9c{tSF+y5F{mWM(1ZOEEsHd!WQ8%y>zge)`0L}oH$kC{kR6sGJ;NcOddvOhu+ zF-cNHwjyiDlFB>%e$VfH-{1AV*L%Hxoa>zXzCY)_@6Ubi>s;rob5|>*%28NwhSr7v z&~S(AhYu?NaGt^&8{3f_%#0uwXk$&dj;5v>LLCkO=Kc8@;Z9C(g%U?P!lQ~_!axq! zr`!GlMx$w7XrC-mZzX0Pq(*~GF^CUsk|S$w*Gqk6C+A|)06y+i&n|aN2`++mQYDy< z->R){-`mG|FpAMz$k>fkxb-}OARx)P2 zNp(qF$d)`+z8U@o)0?n+Dsx(M6HYuxX5hF*kTB8phO8zZ{Dw6Dg6!NP@X?&(!sV%R zsvj|2y_q2vmLszy0e)7pWQO{OvG+NKdkdISA`7SoP*BMpz`gbyb$FfKE&&K_{BT3e zy&pxRn>Cu6|DJAb)|7_JE-o2-nLP-8;T_(ewuxOub)7gl{q;Lr zbWfeHRz5eW>b2r3YVy|4%Ww~nZW67tg^Byp?7u>#*eHg15j=%G0_bZu9wrZ3f}3*t zKXE?6>!LFE3Ul^(dwxCWYZ1CJy3c3lmrNZCJ!ufT#;(N42YGea=Xq2@=-h`vVk2iy z(r%HCHne`?x=ZKe<8wE4hUJy64fAgyh4*?#`0q0@nS)NIvcE8pTmp=}*{Z2(M3&&c z#P{RDU(MQ-E~B z>5to+r}i~aq z9A`zFi53Uh7nIu_=W1eWl5&o#G?g?By&q+-W$#z+HfE+FT9Y(xHhI5;&bP!u7HS1k zJg){DJuZP36G{~6b#M{xKT1*>o<{h}!Y#6zviOJet;9b`_=AzRvwM6Swp?SXCC8-) zdpYY9CQh!}uez;*!$5~@X1x_3hluM>lq7gF?^OLI*`440$E?C-t_bCJg=w~pJGgn$ zX6e4^6|G;WSWuTiszQLk>M@yXa!(bEDDp-3h-sVD&2)3QO1_#KS54F}pJ+&rNRG(X zHoan*F0-8GVg5=^2G70>UY1x^UzX3d8kaqtUh*8Y#S?-&03Glhq_Ci$nm@ISQ)@6R zHZ3;xHJ@vd^Kx(;wFqg#)M64AI0jbIkq!~cYRbaO567Y^#42bGCmcwl$MKGM3T4@8 znSc4j=(z`Fn0kaeA{Y^r4a$y32xFcpA4BKQ8Tr_2I*KuN3OI2)=YBz37YjLdmGIc% zuvkpy!1V$D!SUw>8Iq+k8frPhY6&i9Puqw;>^NWiXD^-uH?S*TV|hJeXi)7Q>F)e< z!GWfM4;j&lwwd8H+l(3c8Ra929aHK3GH`inY5j%S;-^CnUmPY&t4qy}T{X_q~yUMRX->r_fM#G7V6TrJOg;8AC?z!)cL*r1!dR`qK9cD2u#^@ef$_d*N^n8JW z7p*9}yye^@TauUMc@>YqDwneHyUlscnPIhIw|1E&8*j%Ci{-QBpKlfMydK=RuKz(i zs=gq>tJo`LIyA<0#-XsP%a%e1E_q-23mE_tfy;@aME%8@MQ)3}O1_e^m4Zqs5DyeF z6Wu_pBYy?>`lS1g287HwQJ#%WYRvpOxf71mLuR<8yi+4JwzM6vZL4n!5AI}M&RDw; z)*t6Pi)(mO+&>pzdQX0)@lDA4vppxrE5|QhGsLpM&WdE#yc!=K7q7N;>uPHFlW#)e z@xjY+y5_sxq_we-wZ*)}l)?VBvDK`wZ($|7uJce6jYo%(@wameY;G*C+!FQ(KObJY#pTg;>>W)X{ zZJR`Yk67Q5`0B9b8+j`FWz_k|y6yFEG6yV&PKUa?Z?+c?!w$P+r(@fGN>$T6y3fB_ z=Kay}BmD3TH=V~-VABsmQGh|}6*etW@pfKz7hv+*3j5}pE8x$mqp62QsG_Iz0@y(P zQvIj;1LE7w#?4p9=95DC-pUHfwxoI5Pn6e}KP+##7p$^ZotM;{q@FD0RoZbf`pvyJ zoK=o4g}2j^eV*kdq5H4*OWlYW*}-YTKF_t!U7YuKQ?Kr*#s!&$QFNkn{Q8yWt)5Nx zW%k+1Psp#@WZ96-tIhLfTZvUI&~#nem-J7xpEO>1%2^Iuyk%eMvxfx>1DolQ9rzdc zclh|_@5>3xC4oWXt8U1_y;&`+foK(?mBs1Rh*OuH*%P#O2ENdZcA%i5x?<8y)`Yg5 zF@xfwhcUI$>yHB|_JMAJ(OXX2nu{qlB=>V&Qtr}^J8|*fugCo%Ag-q=HEl9+w|%+n z3hhVZk8`;_TH(SMQK2rm0-3 z6no+6$(HXa%UbtluDs{#^1DCQNItR|vY8&9_2g;e$+XB^%%G%f>`s2Lw}C=WQkoR~ zNABIk3Wi2=L?=X>sl=$XRccg*xpdUoRCjvLd%Sk3a&7Afi^_zK|OvueWo^vx-Ut&&DOizOR0Zv{9ia z=m|uO#`mR^4G&7!%EePbHH4BTL22gxYyAbW(uY4cFBi`1DT*k%Q|Ld6n)64!#+X7E z$U|WYVYkE3VSg0t=)Ze?Y4XFbl2>;UZ7K>Xb=0C;cerP*y0dL@q>dxh;GmP9`k{TFUJO)GlB@FHs@8?>oZoqTg!$@t zNL@7O53O49)T$LuZJryEg!cBd$x7V?S3RKZRV#frM)`6dfGAEalP|N zW+Y+u*E9Adb~JCPl#8yzm9fo7>m!#+GD^z&J^H^(v!CfaGb~2gwR{HMP~TAw$9H9qZD?2B`?0dfm-7`_;7DGQ2GvOZrhm(ew?QV?F9Co3ZqI(WSd{ z@m*Cx3$?|p&hY|tNVp@7LfTiGzckaf8BXJJ+i2KOIkObI^lNGRYj@e0ZQ(Cg=B(`> zzB!gg002Pz%pI%&AW8uMsMi4CJ3~cX0)S8$fC9dF0{|)u0ECHot@gSM3!9yl6Phs} z9UYavEBwG%aS+YjNC3bk@Ov-;Ie8)gz`BxlHcM2;&(BW-gH?qfUhhJ?a3)ZlOw zLNo2>3@eF@4kOcMn4|OUA z#zsb(+NN+g+St$tZlrCb$xxg!)`26Cv>1?t91N?0(Kw~)qvo&UqoanvYG|wZV&F(M zEhHR+^*e?2^MxU3Eg%gFBODQB9D?;BV@()CPxd!GHJFAPOv?$b!=Q(P!&P8N6b$w| zGa|~GfWiAm{yP+|;RM%4A+%Aabp8#BCHr7}$UgrU*!>@lF@7k2LdYc_vYssdk`E3G zB?jYUA^&2{$d3?22w_D2o!)=fTQEKlAq0PX5X104J`%K55R8@$lBF3j^V6I`$`q(R zM3+Iq+8Sk!Cy@yukqkKmACl#-u-W#K4eRu=U_?bR_t87#eOh*>r=;}etRJ0 zNUu{G%zP9`UE$G6{+<`wAr8cyo&r2JU~*exApO;)CNH4vU=MtZf1}Qm-Qak;FxOvE znWvHZ+-~#=(k<1(irU4iw=k51kEz~^^l#}p`!AU8T}#eQ8Z1?M$*Mdq9cfSiOfAaw z1Jle~S=8rDWl{!GpyxQf=Q7mFxX$e`7JD{cJ%~DUiMrMFY^LHZ@M?nS0^mGp1?bn% z7MZvjfCWo!0HTroxV){X_R|-jS5M$tSx~OvRkyr}QrFz;Cqm&NW0Y}vWc?di{~o@{ zcuU@?)Y`f-dwTBsJ>#Q(s~q%{7gNEv zy?`d!bKPGNdYqEzkZuCLCbk7Pz`vL=7p!KoQ+WiW-aS*X11^Muyj<{r|S z0Qc<UCynBYPhZa-Us6O1pXEMZKL#D<@moiW|!@7K>Vr&!0CHcNIU!EkD8J z#pPAZ?T_%7TwbPTv*#tt?i@&X7clcnSU{TJR}serBX zQDMt{%fP1HL@>ix?j89aay8=6MdmZ^3j}9>l)jZhYY~S6w~) zVX^f-?W_8B#u*W*%lZx`)5LCVr$l7t%>GgL5&I^)4}_m*No?{o<5mSM&^9KuM&5D% E0S=KlasU7T delta 917 zcmV;G18V%NChiQ7BqkYjMObuGZ)S9NVRB^vL1b@YWgtmyVP|DhWnpA_ami&o000Am zlgSF08)al+GGa4kVPh;HGB7eRFEKGMF*hwSH##yilX?r^lb8%8lO7FRlT!~Nlba12 zlNS#nliUq5ljsgFe=sm+WHmHpW-T)}H)1U}Wi(_hIb$_qEihzcHe)$7V>M=DH6kE$ zbW&wzI%IESb!}yCbV)=#B4K22Vr4pHZ)0g>I&f%jbZ>KLZ*V#=HfCltHa2E0W-?`A zEjBeYV=ZA}HDoPfH8L_}Gd5&4HaIsTFFqhVFLGpNIz(l2lY<)mdoJ;{&yrdYg+XxT@3;@W2%nV>R0eroSGJAX(xtmM>1O~A0AP@>>WGDU& z(<1;tm(~WrMd4?x!~pMjj%t(!SlMO);BB1@1_FpE?m;mFe^CJd8M3yhQBs$=PAOon ziHm``Fjuy@LNMqbEJ$rS0FD7MJ|=Cg6oJl*C>m}Kn)Cd^_W&I4 z4(3`+*`V-&9)M;@e#S@>FPZv?Gt- z5Y1E{z`pp{#Sf-`oPw3<(2$^S?ARSNbdQjhJ7qCUr}R5g<@lO#931Jq}(`DG_)2-QV~A?(g1n?zw+F=Xsv@`}JO4@8^A-iTWl4G|gZWXKb@Ih*LRga=h`C)CbHq-;*`!WT)Tx$B;eawi0_&tsF`c+k zUG?P0`ufg%6=nIs4@S$**VZ97aUit}mYKQAQ>;F3Si}I z`siG3!~wzH{+BTY@_}sU*gez8`y=WB6kMUrJ?X>jae4vU`cIJVqT}Wj~Pu#8!7*k#lcH zvDiknxU+DnMJLMGV*X@r4to2}VY=(~#>MlAvX9#6>B89~_1%BIJZ!fB8BPtlIB&`p7 z=zg=p#WSJRN7OVFtzVQ8@1R_z9?ceB|0&D07bL^UFw6_(FYFY-UX8nZv)@v%A-Crf zPcummllh}C=chpD-kt6ivAEHnLUukknPWk!C!?0RlzD{YMs~VA_Dd*jKjCswVY8}f zH)#8-+P{e%rE`kWxof(Eipp09h1XHyKe~p5Z-YSQY^upzeJ7#!lpkE6%%m=4EawB^jmND}SY5eSD_q5Kgwe^z3V7Lg<}{V<3Flx8?~F86@f{!= zb9`oFP3tFGkLN`6UxG|Qp~J=T5)i&Fj&Ekg$)Q)1s?6e(dG3Hn*heV_3rfiN0Xd4j zgeV8rOtRSDzM$Mrl(&JiLFV+83R7v*pxfd0+V(!>u487JlJ{dL%%*O)4ht=^)5RVM zGCVGmjhaee#gvj`!!-yAzJnzRb4qdD{j=G!qmknH=PC!V`Ey1%d$i+WmZgXj-|5`XSnFaj$MzC_ zJ0gLA&+NU{>)Su^q98-MR9;gfM_ePu`P6ZnBX?WR7C-DFaT9yD6z^MJ%NXd_NT=PJ ze{ra{q4#}8#4+2fB|N;f2#X5al%T?2@xFw$qkz)V2gW zU!dffR+L@d;_|?j=4p9W&HX~9bJ@hL#=OSN;OgKTTVUz>#OT4p`JDM@A4zyzBiFAO zygw3NTM*+}?3wT(=+c>Khr-HsTgEUD;1%!`=6y`)?^z!Enic##xMYjIb7lv;Rl;AvZ*`sXI-@7?bE1Eb zQjf(kk1~a_5}ToX>%8s3<-rXo8v4b3umw^rQ;n?#lab^i@;Eu^-S|6^cW2)b_0{zz z!t*vvB7TLgtV?}!SoaRoig+1*Hmqi2<-7bg`;OC&-q!fW$DQDvj;Ie&kAKTl4ZC-o z9a$3CZQTvoIl(u~e@0}@M~Ek?=j?RUNDK~M?^J1|**Lq~)E)8uG(eS_Kp3I$}_jQFf(mKxSd z>La}&MKAqYidibT;6L%z71jS^R-15AvJ&}--DzaVsol=38LN{)Ds)ZTR#H>{V$w)Q z!ycb7gApSJ@zoJ4O&1vU7hEqytUGO>KPKF#xw*8zu1{M99<=juvJ?TVAn>C}%0UwDrmL$5SmUj8&y*~n1$7WdFV zt5hpToqML*@+)CUJAFFxtx&tq?Xi0LzRiHmhrwA7{>S{87MUM27zwLeQ}69Jl#Oh{+ty%b-@tJPANy*I>&56%7keZV|tS?1xZhBMEvK>2@ zGAh=LokU*J{I!^{>dt8Ya$d{-KBc7LkSw_8YEMCw?9T7Ci-q(0$0UxqF@|@G8uLdz z$3Q^~^nqZd;KX2T@WFyjgEy}Nrrz(Bj3iyRxmQr3s}b>NlW*3lBioip8yd{FJfTf9 znB5JvwHo@(DNhou3oTC~W&i|M)77xHKf@%fm?DYuIWT+>ni;?cQggy@TgC_PfibEj|0% z^)}DHsVrz=wwTp8o`VgDx27;?KQ-n9rXR0`r1840)~%|YSd3cSTip28Q8s2mTw6##y*M9f712!aC`;IkJ1V6p%}oSOH@UXP{Ww6k); zviAM`{n9su?^!2qs<|r-0C+|IED(^BCjkH)b1A2?q;!3Jd^GU{bvYy)iG;yXFodQC z0)auIF$mq1y>}cmIyRV|_8ugY_7ud=fej{*>1iV%sEa?DhQa&jL;UD;Dh39l1_k;< zDS<>7-UmkTCj_uyG#CPkfI;L!1O8yCeiS-|=0~CamkF5$#o;O51gH-s0QR>!?K{X< z*2GB5#1yGzVuaQ)MIf-ox@aw=3Ca*{qy^W~HNmEZvq>wUv~XHzZ#Y~-2d(9!0oT;T zYk2GGXlfvRbr1+2T{I4-t)14yrpaK%r(%o)2{<~zgthb`e~7XSG~n7!2;F}WMX141 z7&!b-s#J_M1yAw~`*$cp(+Q!2LF)b+jzGuZadh1Ojl?_oV0>q#ffR!n}97xe;E(U=WHx*h8W zi+O`yWKx0Job{*RLJz+2-hoq2Lx>^v*}5%(0|Rqi(C)XIQul5!+CkC{T67uzhS)dM zuC1A8;AwbETY;$|<-8-a4}AP-K+Z$KNs*JsMYhD}D(?1yUVtxGYb63zE-6(!jeYSk z9_6!cfJakvfZnZCg)4Gn$w{D7j(esRUI&?O*&Iw0t&~#&-?kw$gmlhf!)g7eGkM-e z^DU~ZU#kM+bw`

    >lCT=$3hfdYyQ|LqLpn-A|bZ`A=NmBWs}1ItaI?U0WucFglO z$nWKkxp(76503ByeKMlp7nfzSLT4tUnrjr}&0RWX==wK+%W}P1v%6AzU3&}eaOupO zj>)LgQjF!3qM7_zVNZLNjS7cApLFFqQrNw7-}kDIHwAqOb54N&;vA9^6!n+`hp5_u zr{4^@50`4qI+aT~*0Uy_cj3WU<^B~{Ux-A~!wpV`V1czUsW$Su F@*n31Im`e6 delta 875 zcmV-x1C;!vCff{@9LC6gWvT$4=?A(NX8 z8@N>?{||T9&*mff1^d$gKHu<-j{BW9 z?j``W%P#;vp9o0o8Uzv=ygS9l)lI;B z*!wb7UDWMZmJdB}4B)1}6LFER&9aAL7vIRKEjCQ|ER zBVSrRLsscLg9Kozm22lyb68UQ764X904SIOXLYtxV7i%GO$0_U=!j;~u^j*iU1AMj zkm4c$*5}5hIqz%X0)V~KL0^kQHb``!2B5gUEW?EmQ8|54%mAQlx#|V-p^NJqmix@2 z+t|)P#sTerrzW_pbl|002ovPDHLkV1lI= BYVQC5 diff --git a/assets/dolphin/external/L1_Laptop_128x51/frame_7.png b/assets/dolphin/external/L1_Laptop_128x51/frame_7.png index 6f3b22897460742c1333983d0cdb41da592f2d73..ca19b669fdbb968b7ce8032fa3597ab83b76b28d 100644 GIT binary patch delta 4120 zcma)9c{r5)yMIiUP_`EPHX+;W(=ZdVjU}>9LX=^~7%?-MvBykFmMBctEFlrHR1_tJ zlJeS;lq5^N$QE8@KhyhrJLmkabFOopKfc%VeeU~n-}mQpKlk-q*FCkXLL)_u%}+5o zW&!}US4B670stU#h-zl$z;v=SRk6mKVGvjh27-hl0Klp}FC&ydc(*^UyD2oH@DDi1 z>C&f1Pl3Kj?kPMmOV&$shZqW7t6Bt-#GB`UtsL4oy$)(F=Cu-g2{l4$J2eq9c!Dn7 zV&HOB<>McVi|gZ+^x1nq*bVD5P2KL&Kw2p*GgHupFXh#qg&2d}Dalkv)(pVmQ}W_y z0k$p{ji+lOcS>};{v$SDH3)Q?pKl?;^)ZO?rU%8b6WT7g={9xl{A3m&dHo(%R##Fw zUSHiN1zO*om?f8~>no$~`$W@3@^u21n7Z3&UH5Kr*8AHA_3_WK?9zMA@4e^teXqAw zwQP&8ju%BW-!qaue^u`7WVyGR!Uh4p9hHC;CBZ){*mYM*MeE~jO374E?+hu6K|=mVUaWpu@N&5h#63}6W$lg8xQvo0@)Mvd~trk|5h8H%zRcbr1ex!mXs&HWGE$ z+rNrDq#EEde-z~W6mQ+S`MhC&Lf=nG2cINPf3UW3^sJDkh@?vI`g70iV)~PxaFyur zQEl#J=JveaCgoYln0n0h1#FkP=EW|lMU?c9wr;5#e0)|Q?G&L`#)^}GnU`QC2g2Z| zJ(d3%BO$>ScGeXa?U~uBdQq)K!<4OFn9fLD;4GwBsg+CKNjPr~J$s-w zEi5T4Ti@cGO`7Uds)tptnkrRjN@7Z33Oc2pZ94!yoL2l2v?vyYS_Q32t|s&2TdZ1a zE)J{1$_gM$kk*Y|s6T%(e(ojxeS`aO1ty}#Ox8-hgoenrL`}R_u zsciNXVM=Q1K;Ma*rKB39JCcSB$OdJ{Af-t!w07e2#!QKh7-ukBxv!(HV>l!7pnYa2*FIxJeMD=U?Z8)Zqg0|SrKINcXi-b2)3no2No5J%<|?eI zbf?a=mY`PEaf7nKYW>oil@o>6st6@46RJh_t(mgin;uo?EW+Jmi@d8_j%%I3RxDnF z+JqLB_UKGCExR4ZAGbeV=-)KWnZA%y?_TEq#QpjQv)~IjGs9C&9!-`}E@t>vd-ehQ zV*Gf%#wl)Lc3H!Td-lvzHYasF&Q!RR4qU6xt0PI6$lbR=AC9(a50nr1Uo;`}!;i{j-sv6a8j!EFcWbVz zy)QYa@L=_ifga5JmH65IpxH0EUy@(9&-Tw`h5Qv#yuw;{UEi@%ELJXN8z&gYZoe{p zC7@lS-TI(ssak2VU3cEG+|{nxt|cf2`pu)O0bHe2g|FH{L(&RqZ)sOQzWuo8jVnCqSe9~HI+T%|^1!8(QNaLVB{TwPz|r`5tYi9b{NQq~J` zg)Ke#@Q#|vny)phjCTun7kYP&#|KNk1MdSjqHMh7jjxY~CMlgN zY0{2-oBmd$!r7(ZN@^1EMQ%L4{ZhM9LR9xM1q1(c?D3fYxUUU;3M&|gm zYmM8!7N4&fg5*KLr3?U zc|8jQdvwGSMv3eqRYlG{IKy^4<8~%;k+6jMl6;5hexg~)UHQQiO3d1&3%mEo8)B3` znGarjJXLy*yK#5p#PwFaP-)G50lG3HW3?qE4n--a_3yq7IWvsu$IR8ApZz*iQP0-( zmiB~Tw5l|tPq%0{tR+wBrH`EZAldA5qyH{z+pg2@Q`e}c*dwt_>&!11?Bw~Cp*CvzaJ=o3P{0{}(p%>TfQ{K^ju{}Rpd3|%?Y{9tUL79W@?4FIn z`npk%TOGW7 za{0kF>AUkf=ZkTBaK$%Iy-GSu9I9-9nt-#mZhia1=D}l{=cA^vmCuaHg}l_s)ZW80 zhn+*6=bk*w45yE7y%3rd!i$$ExfnQ|>tDDx*Bw}#QC!;Y(Y~fEbmYmAE;;s!%?sH4 zL6Q8F0)lP1Eyh0kSYA#DyWq)p)|WR4l&S9hz9Q`Ot-6(lt|jGY=Efa1#yez8VEcLL zh|Q^2%?8Wk;&-Et;wbD&r194 z3$_GyWG!uY=h&D60HESy<#Y@HA~XPia}fa6cqYyy00hGU95C$#0JtmwkY?mIIvVgi zf)2I>Jny-^yCkW>~o~0YG%mufqrA}CmS@;kZcbHF!`;<>i03Sl8vADf_&=UbPCXVD|2=-&K7&sV= z5gZf%r3X=9Bp(<#fE>t!F<}TO0tQwI3;cy;_|aK(rXQX0pCL3Rlt`j`lc7HJK-h0L z_b)zQ6>|jIL|-3`FvaLwAP{&nECzAN6pe+Oqp?^l>JWk(2~to)>LI+z-dG}pgwRJr zP((BWqVJ6%K~OxSJ{C*T$0B{X4?t)(j{pN_7DOhp$mYCb2>zuM0!KsOdISXaZ>0zw zI0^@c|KiHP9ix+|zTy84MW6`?eH>CBhsOLHl*}TMh%Dm&1$O^CG06w#OAiVpvJAo0 zKq7?eGm>D<4HGwHspP+}0-guT-I zyD9*HPFS0p5L{coWPhWz!gt1s&u{l}GY0vXaEb8Qt8O3qZynpnKD>8vGLk~mx6*6E>geF-J}Ql2wv z*C)6jmGX|?3p9BYSd=oJTQbf8UWqQgyeu^r)#FU?*amzhH0MV=YEz0ybTE; z*iQY-mMa4cEzZixhv+9XWkP~WGX?Nd@jiI*3dBUyB{T@2j5uz-7{3?w@J=F{C4LE-)U-E!q*y8#J-I@9LC6gWvT$57|A(NX8 z8iEif`=HZeG6F)}u0Fd`sx zbW&wzI%IESb!}yCbV)=#B4K22Vr4pHZ)0g>I&f%jbZ>KLZ*V#=HfCltHa2E0W-?`A zEjBeYV=ZA}HDoPfH8L_}Gd5&4HaIsTFFqhVFLGpNIz(l2W0QmsG=Eo<;EDhM00vM@ zR7L;){{R30Rl?JL0007QNklyF(p2!#3G|D~(yOEj70~HI`ox})xB@b|staCLg2Uyc4RS^yZ%pE5t_i*vWdw(^6LCOseTwM&uWPT&x zx z1C#prY`##52m;*h?Ir9{A((X4U-HY<+svrg$=g@Bv};!#D*O_KudPfRalby zHUO3*fEO{lhImPxqY#*G=3+?MILYSM0st(Co-TmElq~>>ikkpfO788PhMMMn4xm3M z%9m0!D0qO*B;2(x%Wy+Pw5G3qohn(bdV&1tMf=gOWq*F`Bqy8!I2cSS2Qbf@2PH6{ zaygor9~4ruxlo<~Sc;eI^hqBU+JoI>CK2qLN0jJR>tGIB)xpIDE5S#%1nemQc`LNL z+EJHnEM&_bKr2($_5dAS$#XJ@r&?%JG_T{Paq%x;Ad6 p=^Iyy&mbJI57qzm53XMV3;^;F1}%MHD@FhS002ovPDHLkV1n3Ve`f#y diff --git a/assets/dolphin/external/L1_Leaving_sad_128x64/frame_0.png b/assets/dolphin/external/L1_Leaving_sad_128x64/frame_0.png new file mode 100644 index 0000000000000000000000000000000000000000..c7751a1d4b721d28573bd3f3614009aec223909f GIT binary patch literal 1575 zcmbVLeM}Q)7=K#^mijRxsAw|1)bEe$eQ<@|LBZM=+Bb5`C0DzI^g+?2cmGGUXh=bo-imetXCP*fSWEb61m<s0S*EVw0L5Io+6W2v zpovthQ@tSNuvig;7!;6nHGy(Cjw9)`+J(EdE`i49A|y@{7(rr$1|{Jf=SQyIt55WwK}MKP_Eg+iR11EJ{F1g~c8xV-qx@p_H6V4%SC_3BeCtp66=yY@rtW4QGPqLfLpZFA%^#^n8(v@qwat7H2H@a&KwusqrMS<8Ec*M1o1Z0gwW4$E7! zoOSjN*|+^Ob{Ocp*JZtZj;5Juhdvww+6~^xH#PU{{$^yvky}@j(PZcCabs^p7F@31 zIHBz+k_hfDn%(x*?#D^<;%9!}YMs%sd2;{N(?u5#TAlYl>dq>#qcU~-c&EJOFL2g( zb|hebtF3xs0M$Fsmr^UH8xx(&kYP8<^$PIl(gAiw|A@+!_c_q|`Th#&Ov74b_ujE) z(~jPo%EfV~SHIQ2bIbXzGnYWsGyU6j8ArJq&x5XlXV)@;qirb^X6wkV(#?95gH(a09+$+Z?)Lv@%$g@53Yd4B_=Cu`W zNT^%czT{!Z13K#)pMM7qr*tXfhmj>c3G(^p60Q_}yfm`~SDeaPPd6rm3wx$zXm`=) zPHghcUBCRaWCDy5UsW_Uqua8y*>>Xj;fmqMT}@k4EUN}ab@kbtX3eBuYu;R!vA2qu zTJ<0=?~PAo2iCPx{GENH-Upw2Fz>;f-sa*)bQAOUJLaBqbz$Vkwv^KN^P-~m!lA9% avIL-5JF)tkYN{Si5-^)`jR)sD*Zc#8Gdbq~ literal 0 HcmV?d00001 diff --git a/assets/dolphin/external/L1_Leaving_sad_128x64/frame_1.png b/assets/dolphin/external/L1_Leaving_sad_128x64/frame_1.png new file mode 100644 index 0000000000000000000000000000000000000000..20b3a71045078ab145fa43dbf97e18dabda89d58 GIT binary patch literal 1589 zcmbVMc~BE)6#qg9a%k~r$(SB&Hx9OzWDk;%U5N+@DX}CXVxi+q&1SPX3dyFMg#;OG z#G@8EsEp2_s6}SlI@TUkj!|?-t#(?p9TgAC;8nF)YOB&i9glQ_#P$!zKe{u!?>pY_ zz2Cd`y<*F&lagi00DwuRLPLolL&7^ZQ7n9~B(5_HVme@{zH$K(JY4!BFp`Eqj+NwXd$71dD&Jw5>qKu&JZN6{4w57`)}+pB}G_w>S$ z+pdGl)MnJ|(=#r2;ZlxSxYSZgFRh>nJDfWQ$_bK!0T07dP|#E9^^-vzJZ6^^*3n}G zhQ?I*3LX5ARJpkr(z6@`Wh*fSjiM-&O(<=sLu+FQG!w#6978Z1!PE*IBXKo}siE-) z7W{E`2U%h;j(Zb!I@rbYJ`zC!fq*iQrDQoLf)NCPpg4l#3PD5RukrF!P~r80x2ZgEC1=8*pbkX(dDCA5H^pdiSY^}#0j&)^vzu)%vnNlQE7o7 zBaz65KYnl)fVg~fsOvT#yL11*g3u*N>${*sk}z9V zYweb-N*$WuyFIgBzb&w4OXs-(@r|418mRC5G7z3V&pErSEkzral&5}8pBzn2OI|Nx zCs!65R&O4NADMa?pk!0p&d;It_*v&L(A;!%aKaBY-G?EMDE-0~2|3^OyI4N_t9oFO zv{f963ytiTLaK{rM0Km~_Jh9XHz1!@gR7zwU_)wn&$hro&kprF($K^e&XlrIRmL}x zgLvrf#iV(EG!}`I!6Es|?Om#FU0Z+K5%ASLvFUUZc2rWAhW~u~oMr1PmNL;izH7)* zRhun8vu+az9bA6ry6JdB!myQ;uD#ncK+m-Y zH;$c<{dsw1dggPW>t^S^`e)KSoM&W>2+lh`CA_zZ5wWd0ccX)?AFOl5S{hdk3it6APUu~^9<(%? zoCt}SeW}SpT$Zu9NutS?m}!={4Z`9Qb7&gN&+oCZp&f#02=pST%c*))K zzRx|s-}5~jZf+{Em)ijVCBf~!2$B|h8;c6iceZF>2#JlRKW4V*aWgF%5NuU+31Y#7 z*a0I@RQh|qg!KRvq}6E5jD>azvYv2?IU8ptkwjKigiQSO2!CczF>^We8WAIC9O z@!-3-5EV*#VW+x1YrvLlb5zcD$-II$Y{BX?0wPF2Q^YcfZY?EbJoqB7fX+EJiDQc< zW|s$F3Mv)~V_w~WSe=t5WQwA&I^HQ!akm6{ss>{yh9+r-q&b421%?x74qJY3s>P81i^E^*d49PGAvLI6Znki-oEmfIk@WGU9s7X`R zH7v&{N_wy9!BMPBNhFe?&CFS?Dpw$Zvtv&(C5L?AE%-!0wd9kEXfR^xS>S2 zcts}MoJ%1T(Z##@S}HD!VxDI;JVntio(;Ho%FocW-|MdP^M0?FcXKSw(3CHa4QeS< z)MS|Vts>vcSoVQf!D~R#)QzaFcjxCI+^L&-s#8y54C`dD>X0a_T2AwHu1iZv`=Fur zK_y`532d>OC&-|~?tC^9!I z|Cyb<3JqlLxUviAva(H3Ln~yUU2*QcQ;7EL;qcC=AIXJWs?A6vB5fUV|So6+xYx7qOH%d{_y_jn@8|JADgN! zdX^jATXpsN)H->p>Dy2_xHtby;~ua9&~W^{hhD}1hz=dSbRpID(T7&a#|BCCNev7wmWopXPlY3 z(?-*gplCu;v>4#YjS*2G=nGg2LL=dUL<5>ssje#?g=UuT2J>e1-D;+#2`DwH(JmUN0CX)2p7MmB>stvLMGjRnzWVnByf9GY6c zA)|__LKB^mC8?xmA$~`g=EF@~Kwub-VZuSaIV^;OL4oHy49n1=5;u}FEh#6% zl5G{)p5yv&%N2tLlq}6iXj-P!2eGtfX=Yl}G1fz}SVL5j)m-uBkz$o*gAPGMeI67SLgSnqUr%kb!39bM~tr(41Aqx)Na|r>Cd)o_p(C0LnH-LjHt({^#A_ z-}NcBcmA_gVnsbze1kG${P-CjeHkLfgAl?- xIm5Nz1U@`pwLLO=scJh!OV^nfpLT|U3rwzA9ysd$U|sPK7YTQV4h1%C`3IS^&G7&L literal 0 HcmV?d00001 diff --git a/assets/dolphin/external/L1_Leaving_sad_128x64/frame_12.png b/assets/dolphin/external/L1_Leaving_sad_128x64/frame_12.png new file mode 100644 index 0000000000000000000000000000000000000000..1edc9348061162f58f2ddf1ed86ffd4c7a1dec93 GIT binary patch literal 1365 zcmbVMeQXnD7=OEVr4$jPk!7Iqa)V_?uJ_U2*1N2u(7Q>Ij;5<|2_xY?-fqX%yW{Rg zyG3Bb&BPC6_%)&?E+jhsK#ajeQFK)j(W%jh#-h<6YEVLefaoBG`F2~Ue=PjrC3nyJ z@%*0W_k7)B$(H*U` zO^x6Wu?Z?+#$czmuFrz4eJyFFuS?-ne03AnnCFp!EOaC+pY7IdJ|DrS?eb_{Iwo;! zTE*##;4`G!5=ks(SP*Ln(1b!!6xP56WGWMuAxEvk7>c1unjvYHU}&CUd78y$9~}9! z)C`{znrFSCT?FrR9Fr%>TrL;L1p|iFLDC$@krYER41qKVyH|IlJfYh)WeWnd6-zT6 z&Cs!uMM*Y#oCuD%&IFM)6Nx#)x;>jJlr%CgnIs*c$ZWP0*|fIpq~O0a=GC^-y(T16 z&^CH31yv+dQwF2#-P}=05wYPnS{f>g)GZiFPZsJek6BQ13@dFI-Q_+=b{dXhcN!+f1Op6Kmyi@qFP+?5s?to*0<^U4 zP;Iu1EH<5HUYmyk&2kJ!NkM|*V1@|M!4MIaCDcEmOal$sAQh}<@mak3f73@IQe>%D z{?j|t*KbSI0L0Gr7 zod;ex75YE~t$X_a-rEF<6OOyMYkbGKiZ9RQy~PW=#u*n@T^L^fGiZt4;Ytz}g6q(I z3@E&_u(toNBVI7*tBX~D2lIOl9<5BCxUFXQN^g3At_8&>xw{J2b-#D`#o`;lS|0iE zad>=r`=erg`_b{sjxf9_dij<&pMTDu{_%J-X#KSP$eAH5F|e`r54Y#D$`#reICS+H zfAVS9V9ih*d|Ux0-gEu3&{@&H)pMh(^8Jw$ge!fPQbSMpstQdPuWsI1d93PpvBy8@ z32$Hfo6B5u+GF~Y&u)rdZ|PWi@J{URS6e|f7#*9qu@T?d#?fR;kxdv)}l+dZvj_cTh{o+$jJH9k1j5@2#42h G+5Hc+R?XA^ literal 0 HcmV?d00001 diff --git a/assets/dolphin/external/L1_Leaving_sad_128x64/frame_2.png b/assets/dolphin/external/L1_Leaving_sad_128x64/frame_2.png new file mode 100644 index 0000000000000000000000000000000000000000..5752d80e6fa14bf9a7466a6cd78ab60e1c1b1a58 GIT binary patch literal 1597 zcmbVMd2kbD6yF>`T8L8UAQWNNFgPG=_DBNR9YWJKO`Ae`M#u=Z-Ryp$X}j6D**0mN z+JICkA|Qw$)BzNS!(zG7f>0<(aj*=aBb0&^VUUTSfMB6W+>{3WgW(T%X7_!^`@Q#j z*VgA|XQ<M>AzWgk4~c$7|C3zVDz0_OK?+ zOoJV>`_e#(C$m}r1=ZOOrn-zFSxxd(cuJ6x3~)fC;UHJ;^;1EUrq?bdt)s`N2JTf6 z%S@Wbq@4C#IE@zoJXwn)42EIwWK!$G+(s85v57E&5jctyC~iOqoFWVqZh-q9jpR>Y z-BiBC+UHH$nKUJ$=%Y|H5C~`kIxR2EL2;5KQH($d0+BQjf0b9HgNWBZCT76`{EXo7 zi5}hyM=jDWzCtu7+A{QvmHehB{o!!;E~Egms@zIf&*UBW-)1`8!hW$DZ+&ljEf-< z)(BjPo@5!sXwb6=OY2D^ISF$!G##_^G`v+$;ut{~NOBU1KT#q~ccGkZK{* ztud_4>lbM+17f~ClJ7pO{+U=RO#rmW3l5$ykM%)r2`}>g65an8$B5x zt4{?wtx19I(zuWoIMT zgdjW1-#?)4+?h3}NfHVsjm)f;zsByw^bJ3>@5HrSpe6)4FxpdtF`{PTgR?huNQ%;_z9Ech|zWw))(pHkr8;=uUS|YkFsZ z%C~x~@^oHzOG3}XHyaBo!|!g}kiXot|MEB0Z(k}MT9~2#YI*#IbK%t|6#luMXRV)C9KIf2b!^3oI~&IK{8I95-O?Q= zcZG(?LObJ9Z`*q8TlTPX>(0m%A_)3NiTIT5Y%hW3`7OqmlKXSu&4=xO- zN%N+_ftnvKw;R7}Xdad$%NX7UvXbxL?a2wrpq#NuWi|?xM}O$H^lZzQsm1gD0pnau AiU0rr literal 0 HcmV?d00001 diff --git a/assets/dolphin/external/L1_Leaving_sad_128x64/frame_3.png b/assets/dolphin/external/L1_Leaving_sad_128x64/frame_3.png new file mode 100644 index 0000000000000000000000000000000000000000..f62078f8426cceae8fdc9a4a5146da8db9ddd122 GIT binary patch literal 1617 zcmbVMdrT8|9RIadEaed@o3DW$=bW;6?cKG7-VMf4T3%~eg)T6L$o1|D7ih0*4_lZD zqHH>+Y%?xSjgN>Z8q`cp=G;cvn9)5lrct{^%wA+$1SPr|$eiqo)a?)BAG_r4`+Iyp z-|y%9x{dadf&|q(6#yWisL)(0$yVv5lnUuPr0lRsVyj-c_DW~~vT}l6nyKeR$jR06o^1H$nO+#; z*=)GnU_))*Jg$x}Z1!IgGdP%J|5C~`jI*s6~)nWueXi;2?OGugD7?C}NRz3XNhmEOEUbgxhPgJuvL?Po+vqnl?y#wU`Fgy4{h;Cbj)yDfcgp zhidyBOdBh@fHZ0v}Se_+u zCx$al21i&U=S1`b%OFOBo<&$%PZ)^|)Wy(r)Xu~3`6iQ*(CPCDB7?v%OI|KUm`oN_ zhiBmVhKx*O6kFu+i?oN~qP}^__Y~IhNGzG><7iRvIRv30+6VSJK@|LTf)~Pd8XQ_; zqZ!^4IZ2OH>3+~=&d0Ch*nFShh9=WY@(-ba83>#}X&r(RoD0!oIz3`^(o+BEU6~kX z(4o2v13ZOi|8M%V5-Dw@SN_vG(IcrLBg+S~AZ;E@6X%ge$S2K8iG0;gY0hHoR)`^*bYpAh|D1p4}xs6g<-g8n<1!85|w}+Xs`EQ>9=-!y^8ydLXXritiSf zHp2ueH(JxHK+@3F$CmF?eAT(b)I-7-Z@oL;yLW$U@kzEa_WF}4Pc%L~E&Ssjp+tDL z{O;8gWbS^|+DoSjE!}dvHT0WHRdasLeEG{?VyS%m=pBD*Vn>_o!Y3Z*J4vHTbaSuz z@m~~uC%bdkQ|9$Hb-4Ow=<>GScD0#mOkVW*czZY|VGl^^pCxEqTe}98-yWW)h7QfU z;e;HwcO9j@&F$2Twq?icX^WDPdpp$Ust%asZwYG@?ZtZ+-wvKB>&i-9qLS)1Tr;Nt zgp^CuKJo`PpSF(k)aB0N@q_i4KJ)Fwb7`sz7j$=Zi#LJ34xj*@-nq-x)}~ZPe)2_@ K67x}0P1`?uJ3A2o literal 0 HcmV?d00001 diff --git a/assets/dolphin/external/L1_Leaving_sad_128x64/frame_4.png b/assets/dolphin/external/L1_Leaving_sad_128x64/frame_4.png new file mode 100644 index 0000000000000000000000000000000000000000..021e0582200da47411a7dfdf078ff4181342c13f GIT binary patch literal 1544 zcmbVMeM}Q)7=MqV0xCooqbTTkIK~3k`)EshClyM|M;D8v)={Gqu6J)sC%voJLkehC z)Xf+XG%oYw4|N|-WRB>fbK;^Ehg0WtVwU+4GtoH%bHRONOEeq10(JYt_{T1}d)|-d z_dLJn>o!$Zlub^VnF0WqY%jMtRT)v=q9l#_y`R+XP(`{@;#L+*UZsJPA+QLN2cq@> z=Yvkj35}~Rzybg?4SttfaXS{WycE!KF&%9<5LD3s6cmPo9KRAOs0aG|q8S@Hc^X6g zf*GqaI7mm(3Tyr4O)^~ERN>;AR`QI16)r#v!mMf_02K}m2kOKS8#ZGjc3E{DJ0>u6 zL`7L?#zslG9hIn6k|Ao;QaDeNBx+=|9@1;_K!(giX_BT0iY6!nPE#yxU?~GS_F$?% zS@5z>Tj`iLb!WzE6(z_LL_3`3AKLDRUZfrlDJg$v_iC@XHk21C5; z4=R31L}L~?k5sRiF_r6R5P_h>@zk&w8cUU$G$PCe2}(;6fj}&>5$%xTg#Xfbrgq5H z7=(lqhNOC#S1aPpii6ecJ>OAGQDws}lKpB~xH_A}*9V}e*llJ^z0nGOfu%hZ&3kwn z7fjHD>luN^O$NPy3!I)YG5MsI=eW3?XW>bTB8?>!$uRjAiYl?1^j4#_gtF$FiY=B> z#umrg#gM{@JdFGHtG-9EWa)FUtW}1bBFQdEs*CqQWv!%0p;{@3(mE}T<~TUsFUC$@ zj#X(iXd9IMtD#UTO96Bw&8+_!6et5jGbE?ONd|gxJ*Cs*CJ(3fkKSvfpg~9K@(tJ+ zUiiQ1BUDmEtXKZiJMkm6A!Ey@v!HICP7@T>5t7we8R|Tdt^6%leDmSXE#g^p(uVdw-x#n560)!RURd~k0A4&=nz`neD>qUv-YjkmuP36@ z?-&#IRi}Xhv4x24O^kHsgGndX*KJSRS5Pyq*7#HP0NA~0R?+RDrrgOz^}kL)9#w-V zICn({)?T0S;70%E&C^!Qc>vlRGeBNWbMLiBvjLWyZ9}HFwkCCD%8Ii)4^Rx5gzS*S6CWtMauTPgIxZ6f%El4zb`{p41b@LGPuaRK37>fKK#+(wu%Ei z7IzDB=nqZV)E%!@w^jEXo>X%ztJuIdM}ACj%{epv4*m18ednC%%fUd_teQ^vmh)a} z)t<{aSkhHl*fFlVytY59=WzDMbj?>GgpE9oMw&}g!Lhl8SaM|T@!2gtV1qYjYEB`m zyCWbxVII|6)i15XLAL?v?YV^<{qk~J%Y}ZWFj6RAO8fd? zE_rPJHgNTRTU7=)bL6$(rnG%(IqlJ&`?%`O_qLN=9pi!z;Qn&&HQ>9jF)3$Y`HH;o z(1gI?Qd+pcByAv>*4^gTPk_peV~^`QoNF>%Y^sqXe2cV+uKm(Zc^lx7I?h+OIH`_}pY+c1Q>;3^BLLK!0 literal 0 HcmV?d00001 diff --git a/assets/dolphin/external/L1_Leaving_sad_128x64/frame_5.png b/assets/dolphin/external/L1_Leaving_sad_128x64/frame_5.png new file mode 100644 index 0000000000000000000000000000000000000000..d7e88112a8ae23ce0c59cf2dad130af731798de6 GIT binary patch literal 1523 zcmbVLYj6`)6uxO_ErALGqE^6V3)BLeeWYo#OG8t#4U}n0ED@qip_|Q38_H(GW+7=9 zAQXn-F$jpG41(n;B3PIa26+gvI*e@@o=OLWfr0UbwA7)1FtqiiH0Te8AMVWVx%ce( z&f`1htaOx2Ow*<7003!4llW33qv*AyYSH(X)U|dbUQ-KQ>QvdQh6DwI0*~y5Sdk=D zz)~o9s^>PqJOH#IpVOtf?8TfYOL`%0qYp~~ga#llKO7LmDyU*^SmE=V@jJ&(;+W54 z#-|(Yls#aDmA*+41x}5WIK@bn$a?Vn@mOA%Lk=XU3Rqa0;}3FSGv4i&L+7}f#IbG@ zwaSb?Ny=q+U{+aySgxKXM2e!YTvqR=D<-Yt8%bX4q%Ky&tPxb1<~h^YqH{9 zdQvnG72ka5u_>~Ib<@oGo{<7=WEqwc3&x%%>bm&RnicA{mUD%tM@Hx)t1}nAc(FA4cz(gKVb_zxn$8T+ zehW+gZ&8Uup>EQmMX!&b!?87pyBr-&ohU-WhFO z;gDwBs2!|dd*$!8KS%6|y*>SC)&XO*>`+ztfa|x%)HSR-wQS=L`P-sOJ$&QZ^6|09 zCxC8i3Ca9r02^kkejRv2i>7D+zSn%9B>Dw#B~wFszkkq@Qr`tw6s z$?dC~_wP9W;pqN{f9?oB(5%Zy>9gpAU3Wj;=Nj0MHd$&*smKQ#MqSwgOveWCE%<^d zt@Xg&Z*N5R;8X9(WXG*dtu?df=4qndY4@^T*>vLI3#qrP7q1Rim(3iob=>_`7r1kE z>v!0fj;Sx6@Lh#=l?ATJ0*fav-yhuhS($C`#+x;_zd3%Gs5*Oo$59|OTaql*M_T$= znl%t3Q$y7!q-hGulWZx{3YA~ literal 0 HcmV?d00001 diff --git a/assets/dolphin/external/L1_Leaving_sad_128x64/frame_6.png b/assets/dolphin/external/L1_Leaving_sad_128x64/frame_6.png new file mode 100644 index 0000000000000000000000000000000000000000..142ebbca028e5278af20d8ad239d516fb172cf02 GIT binary patch literal 1555 zcmbVMeM}Q)7=KH(G$KQsXwXHDBN`oC@1s5G)fOofrIBL!Fk)tu>)l&9q<8gt(CW-A zuxuIP#7s7IQ`rYDSsb!uaS$CctD88?&=5uECev)orbe=C%H{{VB6a)2_{T1}d)|-d z_dLJn>t1sgFH4*TO_k1okUtRahPzy}o;3HfTofF)!@$L(6wb@UiV zk#QAegAIK|s>0<)@+BD}*#;8h2!cSe8H0!Lnmv#qvJi@(NSvf_lEx^~LeUnIMkXFq z^(XUQOQ~b&gg13(L#q_UZ^7|kFlY!G4U)VbCmDvp2@0nuOx3^wn?!{TVPYU7X2Agi zoGkbiK@yRuMb;zLDmGN*`X~sW-{pF2SPV?0N=+IbV*NO2AaI{A8risZKq-a)(s-hF zpnQ`b;-xSk)ykY&5pPBetY+`&j-rYx8_Nn=P|L#BI3%vt2Svr{u%YUWffslSG_tA*)Doxg^!Z`oLW!DN>+H@*|YdKp_iUEGLN3 zlZDYLJqp?ZWuXr8OJ&K2jHlTmJdpxJF$8PG2nKpF6KOPIW)G|OkI9=&LfS|e7t!bh zp8vn;!&Opvv{(MqJFz3RA*0L3v!HGsPZJc?5t7we`EJkPS#{2I?xOMnRgR5~wO=~$ zJpgft(_t?UUB0<{dsBp%+Sqz`>#vO+zK2;a6nD%CW=$KaSlu)9=`|gc+O~`)^?-HZ zl=>(?1&SfA+|s-O0O_ zW%x4&4DR3SYZKo|Ysm?p6X$lFSXg%dnckB3TZdEJt^^xMp9R(~t?fERep`fO<}KEh zT-Z2!OVn<}n%Db~7Ee(Y3i{N3+uE13~wLO_N#KBLd z-ne$Rd)}D=ipm-VmhjQNZA}BW&b8`CKQ5YHS?8HIc^kfVIHBA2wGkXTo7tqBdDWV3 zeOMQ6)$3=@jjK#RtdU9J&f7`7)x}v3^NsYB`kv-#mlntOUg?})(|7svZQ#TA-Yv{q zZsNho`P$o;r>`#Cziv!9aPh)+P@R@I)R7bvwQc(reDRrBIvvavIvk{|5(CH?vEmcFT9#;*Z=@h!d;uk^>6wEgk?#rk3GDNSWg zCwAi8P?hfV6+^^1xv24E{E<7-1-dny8cx&bz|MQK*Q{1_uKCnq5Ma(Y~=Ws63M+yuu)0~rmtRAw0 zu`?tcsOe&|0g(ILjxw>#Hk+V0kD83=sQn&ZLIaRJ!_Sjc6(d4Urozn{;hP-?V8~4y z;dy$S#>VF{mF}5!0yC$s*g@4*Q8*3H$bqu`gk-?Oh$Q6qRI^^fZ-j^J64E+yjKI*4 zidbcYp9WQCD~0knfq@KaR7Ght8pwdFof=n`lfg9^5T?OU1jP_kufk9Q(-Wv38h&8O zpFq0^yQN^*o3t~+m7>TK2;%ek)IP166DklC$8ki1AsD8TG*sRIE0TT{>zy36U}3zJ z;O0d)$3hW{q?4-^jj$B!(m8;_A`S7AJc6nrYzj#km64$s0fH7<%IqjsK$NAnB?nfhD|$1}|+nxB`8Vpy&Y)0)kB z27|f49K~8$uSl{K6ZP$ud=FzK%3pvb@&twyIl;kk)zLmEt>i?`TgmYdrd4B5x{ajV zY~*BGq)JbdwlIQwAww4koCg}BnQ%WZ1U-)78d9s$;EYS9L$x|pmXnnFN9Qu2j9#nJ zX6oT#JpF&^L!_XPNU!{-ccMp9Lq?X*WpMo5rmOss&uv^Uy|W) z__N=(^Z_tJYqgji{xjDb8`wjTGCwXH{&mBirOEB(38~-OY>7Jp>z6Ek0&V+d?cJ-g z9569>Kw;XqUv}|E(ja(T1g`8!C=U^FvNzj)4rj`*Tz=Stfb_(#CNw1tu)$X|(!g8F zlLc3k%coqZ2d8?+g0=!aR65YS0z3|VnLv9FrycAZ@ss?DsXsAwa|trptHXvyE7$b z{kH3(W#xmNogF~XLtWEm1}lI0ef~vz#pMyFM;$uXw|ain#m4&sYiLWm>%Er~w!R)Z zReY2_e(ngX-v*91Po5r{8{9Q!qP%_oE$84Q)8;dZrauw2v}?S8_ETc?`P!aL)Fx#I@=>eHu{WEbAJ)mv{2(zCYrwzMs)u>J@JI~Js#9X)B! z$eIj|F1Vn%r|7S?xH10jnuGk_iLUtNOB%K-``Qc>-iSE{nD0IgnF29edmf+fE=*XI z_%&#}wkv66tL%q&mfV=-v~AfSC{~zv@2-j!$D59R?`hewwB(qHjh(V_^qMA5ZP!#{ zlrVnErvWf`?47&a0eD?)W0(A1OYNmEZXe#Q$iH3HU{vlr;!K{E7~h(lapJ(+vW?Z} eJMI?+WuRw6%9Drt8cs+4+}8YJOKWcV`~LuABSAU< literal 0 HcmV?d00001 diff --git a/assets/dolphin/external/L1_Leaving_sad_128x64/frame_8.png b/assets/dolphin/external/L1_Leaving_sad_128x64/frame_8.png new file mode 100644 index 0000000000000000000000000000000000000000..d307e7a27cff7b80c61e15a3a80e52d80af0052e GIT binary patch literal 1479 zcmbVMeM}Q)7=H_h)QOOpC5~lso}%Dv@1rgBP71WNNH+?#vI+Y@uXk_hS$bEmhrN;! zt5G+TC2Vef#5u)}ZEiUC$KpOP5p;8=i?A)Ah9xqMb4wP{EGEce40{XI?GNK0yX5Y9 zKc3(7{GPAd>8)RtJEvd{03g?0>+~U+KyOt}Ci>pY>GB})wCZY7*T?}i#wifk1=$ZV zcbIF1KFA62jY(JzKxRyAY*L#%bu2H3ja*8{sD&d44M2IN7UB31R53qn6(t*f=X4*A ziGmGZYw?htNHq+KwH*pv(^22ZcZ7IGz$+`Ta*ag>!cgTfE!-wWSbxh#c zl!_X%;nSp=JYK9?Rv=bpqzpVsl2{pI^pgRrA2Q?$j3#M{plE`!7-)*6Ei7fhW*!{* zQ-lEPbJomwLpvKDRMiMe5V2Uy7&94VrInx{+8p-m2kDYa9StJ-cZv)Ubug=Fkja~b1E zW8G3z^0FG{JCl2nzZ zgLXni+ysRhMGj+AX=cSoP@pUf&5)eQKr%33FjFS8!RqHw|Cj@16ttK~Q>g`?!3+O4 zeFP#!qdp8;uCtjGp8YJG(O`HNJGK;&u;4dk^n)`pW%uh5I zUEIdyb%)C5U8{9|px@EFh1u%G3o@!E&lu+{_}%r^=9bx@_b+J()WDqk{aGNmn_CzE zX3KVPVIm%HE6N|g@?>K0+%V|ezUm#ne$Tc=t$UA^cVw14AIW#J_~4ecy73MDo07Wz zU=t|*ySaX;){|+9-Dpex(Az^D+jwqPf!F8g)Y=OVJyUaU)+^tA)w06Io_udXmNk3q zz`VPlcxg_3Va7Esab%=E>1@s0-`z1`0!oH=nM2C*1{{)Z!TAHG{G;H_UE=#6TV8uE zL?1r>Nz02nc1Ea#wtV6|7`?u7T<}-?(Rl~F{Q1GRKg)I(B)W^A?d|+}#Y$JY* zhZZ?U_w^I%rC_Kg)H8Zz+5R)b=Cdbm?p9vEoxlInqRWT%LzgStR)3Unq3)KE8L;-{ zT^?^PNoHi-?LR(NIy`VHzW&KUh;p_puZ&%FW?y$3S-(6U>;lW7$#2!MI Z4IFz58h$>#wJG&$b-U`FCmrjz{sWQH1k(Tj literal 0 HcmV?d00001 diff --git a/assets/dolphin/external/L1_Leaving_sad_128x64/frame_9.png b/assets/dolphin/external/L1_Leaving_sad_128x64/frame_9.png new file mode 100644 index 0000000000000000000000000000000000000000..0d28a861564508c8510dc8d8de27e2beb901ce17 GIT binary patch literal 1382 zcmbVMeM}o=7{4+=Krn>R1h$M_4##lrdLM0R??UCHS6s6dNht!0OSs;>g_E{-yF2L7 zOvmQLX|^FM$@Yf>jZK6^Vl>N)3$u$eW<#@tsL|nKOcb`nxR{Be`@r{rqJNP6;U#y^ z`|abk8w3F_4ji})Y7t~pLJD>09f7^9AjfRHsbe!@3PdAFZJnX;LNCzKFzA-z9_-fn zPcT#xJy^RlKn4^q=#h3ORnVGj4hhL#ff2E~C(v4hg$80k=TRdTjccso!B*_DaBUtF z7`mdO_j<5ZQXPR7)GMn1b=fFfAW0H+F}5%nafbmz?m}sjrU;5AC?`%+EbU||C%X1v z(4Q(s*dW)m<_+#VSdXqNEI}j^30uN$lhtm5Vi<-XX@aJ4sDWz(ah*5txK^35zyVEA zB}JFyIBHtt!*ZYQ!64VwAYw`&ux>c6t)&VkjWBqHpll=&iuPAKp-G0RX`m>dx6#!IfnLh)@{&H6*O$Ti zHsfDar5Lcvr4N$ zb3m2)f!L(VF?1!(th50I%E{0S$=h*~0TJ9m*&Vn$%)|b1L|hbb+DUtj6I;WJ|2KUE zBt@9L@}J(x9KnV(m+P|tH|x^`;&6miI4h4^Un+ugmfNy7K5BShMjrF^gznX?*} ziu`oyz3dw|q>}oIzU02bSD!z0e=+Oe7UVY42xgy|OrjqnClii))I{MzR`uHxd54D% z%yZcbw-(#dKMw8(OWR7zu39S7BV(7223wbqyOC&B@oaZFax_?gb4RuVg z-`LvEjdZ?Z`Kfrk^ZZBlRMzDe@8(-3KYM*@babX5?}e+k`>xFVRd9(E>n0ZZON=)k zc3a*VK*XZ@u^~G$biFR8zHIS++2BxzmH+?% literal 0 HcmV?d00001 diff --git a/assets/dolphin/external/L1_Leaving_sad_128x64/meta.txt b/assets/dolphin/external/L1_Leaving_sad_128x64/meta.txt new file mode 100644 index 00000000000..87600307954 --- /dev/null +++ b/assets/dolphin/external/L1_Leaving_sad_128x64/meta.txt @@ -0,0 +1,32 @@ +Filetype: Flipper Animation +Version: 1 + +Width: 128 +Height: 64 +Passive frames: 4 +Active frames: 42 +Frames order: 0 1 2 1 3 4 5 6 7 8 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 10 11 12 4 3 +Active cycles: 1 +Frame rate: 2 +Duration: 3600 +Active cooldown: 7 + +Bubble slots: 1 + +Slot: 0 +X: 51 +Y: 49 +Text: Adios. +AlignH: Center +AlignV: Top +StartFrame: 6 +EndFrame: 9 + +Slot: 0 +X: 1 +Y: 49 +Text: Forgot something... +AlignH: Center +AlignV: Top +StartFrame: 42 +EndFrame: 45 diff --git a/assets/dolphin/external/L1_Mad_fist_128x64/frame_0.png b/assets/dolphin/external/L1_Mad_fist_128x64/frame_0.png new file mode 100644 index 0000000000000000000000000000000000000000..04aa17ac07fb2fbaebdb7c4ac1c6f8fbe1876b4b GIT binary patch literal 1556 zcmaJ>d2ka|7~domLfUdnOQDowSyU*p*&}I^T^n0+w1jDB3}J}cKf2j{AsM>6VY9WN z1Ji(I#+Htf&M+f7Vv(bc)N(i;C`dR&=~(ap6x4bEe=q`Nn86XLQ(xK!`Ga9+cHev7 z`+nc|`>t*CEw9cu%rqbflJ8mS^20R=-%7m>ey{0Y^TMTAbqCcIa#(HR6o4!dZoML20uH7 zp;5t(tt#`9-k1|aqDz|{HX*VwU9QbDf|b;=4rtwsvxNs>gZj4?!pZ6Uyri&2`SDT1O2stl(omM&wdGIZ?0 zpg%{f7)MRWj8D(WPK`{(NkTgNlIMl%7>m-#+;8J{k)`APf zc_kWCqq2l%EOH^aQMF@`>u3;S%EX#(aOjgDOLSfv@GZvgHGly}8<~ZCGHi0kzq}ggQVFaW|WIE@ePRfd4 zduFx|CIcQG%odQ~Kq+u??9PI>;M9%x)dbvd9UdOubLs705JX$xaV-fXE`Pm!i*ypr zbMGG>?p_srUiWvK*a`f*i}o;eLvt#x+`Zj>Zi0De%AHlyk!!scq;G21O?_wg))xQJ zlZ|hl?i)M_b{UbM|7=Wpw@pS~X&G3yPdkL)>TB_J_2>Exc~V!y;C;h_Nri<6kiB9v z;wkw?Q?;Sy{j&?xzuH>XzM#>UO8@lMYAzi5V(8LfPW#>K#Y1gNBY_#6_(#=_4^AA{ z8J^HwE=*oG&?lt|#ss4){yD!%KrOnrDb%ylG%J15r+W%rlPm0`| zoIP>ddn?MP@5oILes9<~3)ywcBF@uy{g}*0hX37QIN-gmoAeb@S~BJ7oj)y^8ku~j zpp)s&)kbp8v=ygzG#)KFI2SqFP%sOv_#rm)TvAiCV9&(l%AP-ZZ0GY%eR}mq>lwqQ zopV0q>yAyV+#BBB61<_+|K2q&{mfZ=YZEfQ_3+LC-PSku&#q;E8#gCO^`G*W-gBJS z1dr8CKtye8UtbmCSnRrq_{yiv0G(w0ZOtboNoud3eO{J literal 0 HcmV?d00001 diff --git a/assets/dolphin/external/L1_Mad_fist_128x64/frame_1.png b/assets/dolphin/external/L1_Mad_fist_128x64/frame_1.png new file mode 100644 index 0000000000000000000000000000000000000000..d93b1f588d42a88503e2938fe6590228afbf85bc GIT binary patch literal 1580 zcmaJ>eM}Q)7{6;>t$ZkcMR1ZG1(Pzl-em?Bmdx z46_6xE>UMtvoK9`7_-c|sYqOAG$Je`I5jcr+}uK ze$Ur+_^KD4O}t$&tXhebCK%N~1jsCsh-`_*nS{eIWtUO+DKTb1 zrc~r6hhdsjo!5uBLRRfK;MrAgEM&pHP3vLkS zrEp9Ri%}$Hk>$j#vcsTqoem-r^Ln2ej>czFr6vtaurZ7<;aDV+ifl?dF4uzpX*^du z?r)6&tQN$@trD+RBv_aRtJ!<8qm-h`hFLF#)v~Z#+#KXS8VDAf#YO`T&mT^gdl|{)fid)is;0uYe7!QdtgrrO)V)U|nIGU0a zr>Zm^v>Qm_Z9u4y#0WB#W+wa`3OoUL)@r9wPQcah?Y1Cl<8d0rS&Nmlup~(V-Y|m~ zo=M+yqpA`$j98itLr_*b1-Kwe^L7i$n&}{FCs`Jyf)oe>fYVkBWx!O5SgLcL>7=ws zZO_#9>13#fr?Um3>Oe{AN+_&*?Z&QEeO)A@VHm|6E_Fz=S083 zvp#t;IhI|w|N1rb${2|_fBx!laR-y}UEhxmW7Kx^Zi)- zZg*Q1e@A?9YJ&(Ru1&y2^(!Ig;|H4>@{(fn<|kThq{hbu^x8X#i51K8uLlM+c>aji z_a~e`aH;e1XrAuj%fHP&lBaat{hTnxiweU+B`do)(!g4Wev_==x-kMHS7A` zUK$9@8W=vGFy78OuK&>JgYnKPcl!mUEAtwX?7h@|;6$%OmjzXb?ehwcEf|{kVBSOM z(5`|;<#32~j&c_Vz}`o1@=mn!bZ60P)b0k#o|M zk-?hzocpd8Dd;7?9fG0dFy4Op%ytU8`(C2@Ang3ZAK2qL+b|bOvN<{2gMYS_?)fr$ oFPjFi*|_+nxBC0%CMy*fn&Vk~W$!XqU+VwuDX(_-l?Ar{2aXdbAOHXW literal 0 HcmV?d00001 diff --git a/assets/dolphin/external/L1_Mad_fist_128x64/frame_10.png b/assets/dolphin/external/L1_Mad_fist_128x64/frame_10.png new file mode 100644 index 0000000000000000000000000000000000000000..47185499d7ac7d13e9c24210e59b912b8c557cb7 GIT binary patch literal 1606 zcmaJ=c~BE)6#qgv1*VKz1sd%VwAkt*_f;nP;A7} zT92Y_ooQ7DWU6$$>d`48Dxua^s8XiwjP;=7fz`I&w{t`<!MiCS#Cn-6p!YNWusq~}@8+oKCo`-el zt){$@Xy}$9trP^eUM{b$u9j6RWW1+BPU>_zIYG%O3P%>Wx5g#VKHTL^4S6s@FXQ3d z0>`_sphw!yFAy@Mi0g0?PPfJK%(2TmQYut5xsP_sNf{w`I)j-FS$hR5{GY}Pt-Yl+ zZYZ}xFTcRUppH0FLts?Bmj?ba~{gJU8t0(L%Lptns zoM34NR}xTxYqd%WSF=jUsD20r|rdVi(a|JbT z2D>zzvCnx-fPWTYc_ z_PO#64=U22G~6LJdQzd$DWKhfD;b>{r&US^uA^ugS2z^V0U@E(s1;HKlOnJkHlW7l2ywxcQYb^rSSJl-+NKd_qu9~=Gq@aZ>l zo?7&uv=>wiJh{WPE&g0(jSFgu zL>qqWNSh%sRAgNf@0@V!l{weMooY*Z<{#GM+{tN0?c+{e`BS$!wZe4h`mB`7vuiUg zY2d(_ws7LB#g}HMM%a2*1SZX1uP$+wDJKVN_U_nR9yLbX_jp&`qlEb7jgE~+4#pZH zyUFbb8ZZ4*2XeQXnD7{6|Oj0v*9ro$0(-jEIOzPo-L>nOAx%&bthM#hKI>)qR}cJ0;cjdpy* zG6xAPaRdB9Bby)?WX=^q7D#M?2{=gDR3c-7D1vcA7&<|MalYMF}Bi z4oUzoR=@f+$VZUmjc$9HQf4jY1j$SAaUCM$^+Pm*aWRRZ zLn?~LfDMx>v)WLTBm-1S(6~TR6spw|PRgZo0zLIS%1{hV(hN!G;S9|&c^sXGjyxFj zCyOqw#9TPy4W0~Gg`)U5k_-leM35yUxtyf+dOb-oB*WlP0}oXD6h4Ie0@(=*W)Ki$ zw_kBfJ~VETcS==?0fStJgYf#T)(3`tfss_fq>&-sPtpWMdcE<;hO`4p3HYDJBeete zYCj-LKtQUJ1y~VRb^;8u_jpHfMaYI*EW2S@_)4=RRC$34b%xckHTwchNTNlmihENil!|lotb4!7Mh~jLWVZ$ zvwOE74zl^5K;xMXI$ zO2a{$f$Uxl#6nr}qC;us+>f9j&_Lj|dNuA8DHy(9=fZUYrN${~ZWM)2Z8 z=^JiTD1l-46Kpt|)#_Q`bm3}2ufh2|wF}oXJdd+37PtVQ)LIRTk&q%8@0^D^DItRG z8Q(sb40w1jTfhegN`{kD-xEC!r*4d`*lvOA;Nak%?#4?9k~F!rmJX+sLwx9a-r_}IMSpdNc`|q!uV65wHTpqn? zyA7_^4M~Toh1WOKChgqXqkThF zQ{YG*;G)gpmD7Teoi<~4>EYgV%J9DZT+Xg=b>p%tRhO!#Pv)}5_tu@?(b;pwwyOC> zhxV9$YIxRY;)(I9>6sn7V^3P5z2ARVbM@pG!szqSGj)e{^tXO^?dGJbr91kQ8pe&I z)<^6cE*G@TC1$t2^LZr6jx?Pc)t5RjYIS;lM%ucHGfNz~O`c=>s)aj$rJ|pP*WJDJ zo07I|@P2XbXKaB()jI$5fjxHPlJ*S$*(~JaxB8av3E%nZLRWKS_msY6Z7V=Y+6 zpzP3<6m{F3dwZ1^Ht;jvbVbHAwK!cX);?`quPd%kK{5**o8IeMWz2LmBRzkcf^S!b z8zy$12zOV}9SaVcF!>1KXZ4ZR1?ueBcI2fl$%EYfa!hip?Zhk<^FfJFe`r)gU&i)7 z`_r0~3o~O|Tjos5IM}xoIlXDz&zF_`vsInm<+m(%apaqm2i9hqkfzayJx5yH;z2&j zskPY}=WJBcYE?~#ZHcKk4{Fq@jv<68WB>1G!tL?@bdhC|xn;hi=0BN`JI4S3 literal 0 HcmV?d00001 diff --git a/assets/dolphin/external/L1_Mad_fist_128x64/frame_12.png b/assets/dolphin/external/L1_Mad_fist_128x64/frame_12.png new file mode 100644 index 0000000000000000000000000000000000000000..15ded267251deb5676fa24b1633c1e4e280fb0c3 GIT binary patch literal 1541 zcmaJ=eQXnD7{9jb7!}-v6&OT!+(16Y^*;J}#|rJ%b#0`jmIW81!1eAeJGS1P?TwZx zrkEfBiA#)x4^hE@3t^%eDqkUh%M22dA)rGx1+xK)gpB}V95CN*EAj{7lDp@9pL>4K z^LxJ5hk{jO4U-KBf{gY1JYgu)@O9wt!>8N20--6RTBKg(Zk&GHFVhO>%rWK`{(NkTgNlIJCeMt0a|6;ZmX`>%jvOd|Xsi zQI^n*M=l~as7?%W9Zn*q1Oks7ONo(E!J-iQxFL z!XP0x#Ch0}Xh{|ftM~Lk8AHg1T^JW(Tey0U%s0eKTpEjyybK`RcSA$+$2R+RyaInx}uUIDYKWRJPvyn z>z5KLC-EQ~TZFMku(qdS*@`&eR5@NP%k|kg2-V7}oT!x*ls21abY_6#MJc11mFd!O z(jE{OR|3Hsmt*KqnOX4(6nF~ooSm`Y5rKs1Gma?k;7JQkayC0{<7nCpcx(hOJXXHp zL4_KahLUB&Qf51229YRk;TapwSuIhVp*apWN6jD#0BNz?%oqVF5}C<)Y?87nIG&l~ zqs@SqN4o_ixKMGpIsTSi&2Z~-Lkp@ap&T3>-2Ka^zaoe>$M11hr!IDHUGu(fYMy7^ z;NYJ}gs#Kir8gYx+#axrvCY@!Xv40XJ-;W9$swhrx5}9A^%kXj^Fn{;eXwxq;7g4& zl3P!lzS|RP{tcQ|f7J)OaaEtmA?2R<9~_PlZ4yZXEB*M0xcCm3yd zwtk!bU8J>WgVFVsalVwYOzeKf8+y=m^_>G_OAi<}He;ObkM^6#P9iI?o!{o)Y`Rvs zLyNHE=9KoIYW~Y`W^KvN^o#vTcOtj$QmOH*VasbsjuGj4?!w~Zx@DvM6Yx#>cRGuT zx9F7ikYUn>$@&(8J#@MC>^?@HySp`?EZa7E?zUU8%Y{pWuUkf=1-9{J-5uKX$h3mM ztb(fY{mQ`?+?vzhe01oO)j6)~Qp)?925;M&~|hQ#T4+qCCvRvmat~v!N1Xz z(PjMN-uBG{ZIS2GKYiYJ?eMdRPwQ&QZ-4N$4w?OCn>f{j>?-|G@A`iFZl5N6AvpTh zCS*(N?G8kkZX6Sxpt)g7*K2OfSi5fB`0nB0(VT;x-w3Z(o@<7fuG^uMB$j Il`nheKjID@Z2$lO literal 0 HcmV?d00001 diff --git a/assets/dolphin/external/L1_Mad_fist_128x64/frame_13.png b/assets/dolphin/external/L1_Mad_fist_128x64/frame_13.png new file mode 100644 index 0000000000000000000000000000000000000000..13ee0450e23fe651e38cdea5d5bd816c8ed3087b GIT binary patch literal 1545 zcmaJ>YfKbZ6uz!*MS_V{Y>RE`bg&3*XXmlcnXo+e0n)IzUDlQuQ=Of;%dWUP%kBUR zi8=z>n5v}4rqRYoV|}z>jrCCqMnPi5N)&5ieHE#oO+_P`wwRK*y$h`MhjEgbd+)jD zJLfyE+2|}OoS8f?82~V|Xpzl@Rt3FzNmJ4Hc2biAEorj7OfHqYat$AbAYYU`5GxAs z<L;c}8@S(c<2l3@s>K}2eUG9M*^k@SQG8;l5H ze@OOAK`d^O_efQ;8An_vf(V2hj;Dr$k;zn{q>)iRMA90H3&v{5rTNiiE%6dRVlV_)eX{Gw}mn{s6EPR&Wl8A=~2oU05Kq$xv5&STTgF6oJF z?LWJ^cg3B*2Lt>1LED|tDX%Qa0eQ=JZ+EF%KmWaVPHN_-_1jdA*ZR&>6sJ7u+@R7Z zYkFVK`(^s^>;K$sT)NZQc||*a=Mr$FvufAntbxZzOLK>JD|O4=T^Gtv`PSyIKE%yA z;RtO3&F`-}r?P?>8$9Y+jkkWC*>t(Sx;yFH*u|wIhxpqcZhYv@I1cI#jggG9qj>-Q zhOt3by&ov&r=3eaKKy69Dtqq2)V^tJQkR_{xVG4~ZnyG{`oN{nup_6FuO~;r2XCb? z{Mwxl*RkM-W$&s}?3-09`S!p1vPLTVF6j4xn@_5$+0GGP#y#Ip-C*yO*#~+SD0x>l zEvz0>S`YJcE^bp*X6QOfZoZwV{8+6$c(e)hoOr!|Z|0PN$9XAO|HFYs)#_;XgO)as zHNQDcbGN;9H2+lEwZoe_a!i-fU0;!FXDF2orBjE-<~20@@kVFKKApOGW!J|CuVg)< zYj2N4`WC70jSiFDEucNes3%81In9BVpO3lDtH4$;YuH+udmkwM29{_{QsnjDgPyjp zQ?v36$4V{Pvq5R~lQgAuTYXnA4srtlaPQUiUlvAH?fi}4NF~TsrGPy<=C-`K;Fcx+ Ob1t%%*uJx@sQ(Wlel_3# literal 0 HcmV?d00001 diff --git a/assets/dolphin/external/L1_Mad_fist_128x64/frame_2.png b/assets/dolphin/external/L1_Mad_fist_128x64/frame_2.png new file mode 100644 index 0000000000000000000000000000000000000000..32c0a1b9b50237f972e47318b9cf28fe57794711 GIT binary patch literal 1558 zcmaJ>eM}Q)7=NKyuq)yWZeZLz5Bym4dS9jORf@GON+(r@&4l45*Sojv4SH9u$0&*! z7?(j*Fvbnd)ajybiJ!}&b2W{t*U_#R9GY$suUyEs0|&kYgP9#F^(bw zDoTY79VAuaDMFl*3=y+|#5jT=5Hn-&5q^sgGQ?DbA}A6kDV)r~DAG#hSjik@=s{I~ zGViw*yJik~Q%^QDs3>78j@Q)G7;0#PBnNPkVHljCaEiiI4J=YCDr^)JBUy0^E*Rlt zA*=|Jh{PWzUHcq`%KInwX* zVFb@|n2~@qX0aG4%)}cZZ?c#yMre%Nc@~}~au^rsU>xKOf+X{u78gx9^GSlFXHulg zVvb|oVnks@4#s^8s_!AJ<+)g^Q--V}$zDmSjQ2rNP*S8wPzoayZJ?0J9+nftnB=us zl?H=$L0NbY@-t;AgbbwFDm;S%M?#J@Ge*qE6KeR3#gADy!iW*9$xNA8ilQNh4&nKy z(l^+sszePV9A{%CX){AZpC2=Fj0t0NjDC!vSQexGH1tDA7|kXc#Z`)UtaF~~q_{|J z&)D|KWT=NHvjs(Upk#G&Mr3an)Tz@J6?*g4wZFfA>%~vI0Z1I}cFpicyH1r37mpDs z%lh9x@KIl*Mzi*)@V2n^n4HnlkkH!LdH2rQ+nUt6#@{&|=scbQc8%ZkW!B`4jwKTw zt^URn_-*h0o99wNXWcma>T4R%v(QL))bAVh!=q&F@y|9LYagYJE^ci?(u^75Emsbo zPO<-#T-Vf))0 z1$uUV&S;YWGIzK(J8_ckYH4pt_Lai)41Ex@R|V4l`L%h=342QYDQ`CT_U4YZX?Y{* za=)X!-a)q4uWM{t^U{J{N4}dz>3_bL^2g-Dz5W$%(PM|P`N!Aa0K3Bu`a;5#vc6J2 z;|@LkO`mQAw^F#f_>aUx_u;M0y`b;x-IwkEzLOQqy$=-e^%p>P>FI;MqK9I^pFMlzqGjbt zKOQ>Z2IZ|^bxfa1fdXexbLQfNB%-RbJ86#{nLWt_>K{+hA3YiE$<^Gd-uCWp4f;3m zw*8Vk^7`h}hcBmtuEIAm!TQyS*KJ!{z@`1^nGY;1{c6YTvWk^`T-p5Zmv1l5Gd&*L b-U2jWjB|9i{hGEn_NR8|&vET?lrQ}cDb**T literal 0 HcmV?d00001 diff --git a/assets/dolphin/external/L1_Mad_fist_128x64/frame_3.png b/assets/dolphin/external/L1_Mad_fist_128x64/frame_3.png new file mode 100644 index 0000000000000000000000000000000000000000..93593594e9c7fa130a763fc5becb073fe8fe39c9 GIT binary patch literal 1583 zcmaJ=eM}Q)7=KH#L#!W|AjL1vL$m6*-bcS1Dj#jZI*X*@R^uGK-o1qjv{&16RG5>A z-#Sf1U6yRfVq8XWMAR)VqB4PG=o~DXOr1=ey6G@eaU0VuV{d^v|1e&1_q^|O&+mDD z&)2r%qQZ&E(~|)J6P=6fZX|2bo0}v@-`h#MT}Y%$4v(}<^h;H27=k=r^g+xSV9THz zvi#cB-7p&f`6i*nBY9j)ESwn7urV7=G!Q~)0J3wUA(pFv66S+tLePreKY0en1m23j zu6I$ckPVg#i>kwLS#?nfS6#uGc|2z!mL0Vq2LULtSTs->j98*pe8jH>onvYe$3{$~ z3M)QJ%Ht}=Y+@KC|;QN zTio`7v1sUK#mglrWFg6_swz#DRwIVXNZM>RlN3WT41p|&$l9R9Mu}h~Gw#6-BV1Sr zNrD)}VjfwaxJI(#i0fz)fso7f)NwE}Rw`69GRlTXT0@b6KrFKn>xkrr|I>J`b);l% z2$F6X5!Zw{)DeGX9E_^>;y^J&#Ky8TETFcqm3EO^6M#X}JiM0Do9%SIJ)h2_Xxd>j*|m(#K~uE0fT8Us zV;t)YMkF@K!FX%|#U8`jUWm2W!jP53aET~Z#^<28T$IE}xfsG2t%kwWE|wF5G0pr~ zmqwGe!?5rc=qu1|wr&8Ab~^d<@S& zQ@+tbMH-YwD9*-0YmH_t^!W)LXEqS5Ugsyw49gN)zZUu-q;y7u7AFx!GB!ESOj2Bh z#xr(&x*6#5bhls-EmRn7PF>}yNoea7#Y;*YNDdDVAG&g&4}b)X)1Frnz530H@w+-O z<;>yXiz}Om_m}Q;8uu-jx0OoIJ`Kv-W}mLmosMkA*)^Z&LnUB?FpdsfYE&ply=Q}JXyK73F~Ud) zIiOU3p~*Zkb%J#Np!#FOw5+q{doTN<6s`;!urEylOTKT{O8d7qdfBw*)E?0mHY5HHkvflV7qg9qx z``h?&3f1-mMMkwK>$R%WTrsFYovB_8F<(p5{X-fx0WcCvV=P zyfyjOf#U}5((i*g@3js6n9z8u@7+XmVs5K!21xi)NS9ZxOa;yBvyaPKRd-&&8d7c- zbT-WU1izr}T~K4MzE-+!a*KTH$(su7`uCya9#w69k&w{7c>k*I6Q_K09!=cHZ@P4? zNL56=cCZDgziYXkhz-5^pfBZKhUXptTPWF-bA@TOddEJ)dEsQwdPO^67tB8LQtqc` z-bmm7VcK2%vaJ2;2d=(6{9D;!)tzI8LGX6Yt?pyX$5jFBr_zJ2^_|mgb3p&PIsjU4 z?%_e%SyON7M?Hay^<_uyc3d2ka|7=LYOIns_rP$^a1F3{oH?Aau{JxJOV$Vfsd8Hu1{H@h!w+GaOR7MgY_ z23mWmlo5-92SO4TSo8%1`vq|MG%=X)=k?We=zLK?tAZh-|zc= z-?hz!_Swm!#*YF3BwOcLiqtivzNQfx^?PMRt4&=}l>(=-Kz1utydMIyD7zqH_3|aK z2=ZceKrJb2&lw>iDRRF6i~CXaKTj27SCx4i&@&OFU8zdb9H&ig?5v zbYZ5Au=(;~sb@}&A1{UKisIvNysD~7S4Hb&e+f>qEQ=EqPEnYufd#51g%4sB?_e5 z<-!P&7cho^G-fn16s8v$DC&)RBLkV3oyXxB+F&*ltT~S~6C_!XZ?w=&6bJ?*c)fwr^Atrx0Ug4N zkECy~QB{c=hA+m3BWVLmLzf$41XhpnnT#7_DW1n@Hx1no5{yAlqqs^Dk9N)@ofH$P z?HS!ZoDB8waJHbN4wPS=oDnG-wCdC)7S44PsB3?J|HtPy{tQ6;b5@Jl5&YrAD{o1f z^d!2!zq_qx$M8w^t~$xVeL9<6mQgt&;b?a5gByL?@e}GFT#G0CA0>yo(oH{(o-{B0 zU{USUwKn1Eo-ZnT62R$YFPK(e(Sn{)BhrEXQ#+aYOMCL!&NXN3 zK3{uW@wv6Zwm8@IVPC!D3?FH%&MTkce2`a%ytZfI$T#E*=U=+FvU#h0^7@e}eX{HA zv?L$6#4H6Fnwh=KA@J^HM3WW&XF>8UciZ2Eow@PF;p^{D>fhBAe-3#suB)Xx;mo%YUHm%40ZJ1tObxBF zN45}1dVO;j2%V=&K?)k4f2>u5RPWFhTk=*!+S5VVHeM}Q)7(b|hlrnWd)XmJ>!JKYh@1v#d-6&9Ll_F&w*1+ONxVydw9rW(j9=0I3 zj?6@}`2ooiwrND?BJ{lQfLGlX13MbS873D#-PqJbU&R)P! zpVx|2>wxv ze2VImB{XJ{#<=eIFl-vG$PC?1f?elzdsh)ly*=p2mjM}s&>%R zpa7yA1m*gG04pM9$H6dr&vq13glyP113p+5uFftC^?o3!PP-L@H+rwn%aXiTphTX> zNiQehMiLlsi^WLeCa)2AO%{{I2#j$%Ps1AxW}A&<94jarNl}g>i`_sMIVh4ctfVQs z#T>^vrJ%}50*L$eLEkf2`!lg@Q2=nN9Pr3;UAzz6HL@xPYh(qb4SE_~>f!{S6q78A zRcShCI|%qT0q@Fy>_?~4%=(@}L7;%ZnHeL_dr25RV-azSKpJt9Gnr`Bz1U`#ldYZP&Y<~ZCS8h{7@X*8P*7y&5~vCes-lj0)S zp0VxY$$*E)vjrqLPyskOPWHC~ICaVHQjY_!(P;FGp?x(3OKUs3JG!K~ z?VnG3`Xpqg9ZJ+2nc3K-*(sf_jo49ks8-Jg^mDV}oSom*Kj_z)n_~BqHsaKTs z35ERXykimJ&*yr!uOCTS+@DbrwB4Dn>-pv#e@@e{-68yb(hkqZttYd(kDh3u%9f63 z+HVdZ`x8U?8{CBlI-9JLGr={oxyR0>kEJ&xmFnByUOXP<*S$Xv`NeWD;eP$_-H+0B zS#!TG###s5_g)|P`C#jTiV@Sb{@g>zwu{Z9*Vmm=jTxJax25hM3c40@&ljR~-y5hi z=jXRpWNpiS*>wr6pZh^#d#yP*-aM;nYs#6@!M64!rLIa>c=bCNXlDQI4rZA&jJPxk zrrGnbb$oZ{z17!W&F4*rJ6DZXy!6)E#$@Dn@}cA_lex(${Y+$UnNQm>r~R{Ye0eHY zypj2KLC*dSL)m@e*)2&O$5O9uIa!(V$AW>u(o|&g?|TxIAK%L?{OL~Fob1G^l|ZGjfo|yX#L~(jlW{_i-eeRMj@2jT}ALGNiw?2pR7hoz+>QowIA?;pCNYQ_nt4 bIF&?(B3akR1|Keu{ivOeGW+orRW1JkP{l8a literal 0 HcmV?d00001 diff --git a/assets/dolphin/external/L1_Mad_fist_128x64/frame_6.png b/assets/dolphin/external/L1_Mad_fist_128x64/frame_6.png new file mode 100644 index 0000000000000000000000000000000000000000..17930e075838239a97b2055f0449220f528d4dce GIT binary patch literal 1581 zcmaJ>c~BEq7+(^DfI4dNf>zxwvBkm79$9j%1QQaDI0i99i*2oLc3&WcWY=UVfdN?+ z?V*--TBl>H1@uVkz$tYnT9lEFA9!u-(U$ z11Dg(+T~w^90*db@w&>yGRHic<$W3^rlSe@1Q`uMIdeh+!&U+jc7t-S--O)mIF7(x z&V;;_?Z6#^6;ybO>H?s&uGq!aRkB77nUf3WglO4-4~PsL@>ThRbjXAZ+NI@vOpGD$ zpo&;&LWW3{IZ9wF9{{jkL!c~<soWw{Hl{L^{tzTq9s6Utyw_pQ7 zHsBRRFYkwA78y5REt(LS>rfCr!Qpsh*dH8Dm7Fvz#0VIn!7-mN7TKV7P;`R-X*^Lo z=&BU}<^(~$I>5>m@npooa`v9?D5fa0q2~v@a#@%v8_!nzfM2xROo)7=;k+D;yE&Hd zxZNnuF)T{qK#Lj-6p89M3UE4u&OiYwZs$pON~^b6a0{77Sa5>Kw;F6((wa};gtmYr zYzBQCYxf65#?OMdZ?Eio7)v}AOIrhg5&3|N=d0pMC`P$rx5phl8mP_0J`JOJR7UZ+JcnIabJoX0vT zE|S|bwtX}i^5M~J0lz#@0eNx`_ULxXQ@lPd=L?p(f|oT6!Zus{_F6sDQajNkU# zc=gu2hoAg8_l|DM#_o?k+ft{z{@M>CllIm_(!;Jrb0@YfYR!sTR<>sr&5W!`ICkvZ zm+G-qnQ+3%E1MJ44dx~H_Po3A+ho;x)7=Y;RpwDwZ(gHSO-tAPyLh_leE-pu6}hQj z45;pQ{xYvuZ!jE$BK7lg4oE_^Mc6T^_s14w`{7ABH=spLRcQzL)npM6(!ZCXGr_P3+F3SC@iZ{GugRJ9a+#8DP!MSdsNXnY5%3d=;Ep@Tq&Kk zW`x1+#wC3#_b41XyE--fod(s;!gT4-#{TTxlB4;e@l;EauPgn^$9?#+iOKCq@9&)_ z3ao6_>CQxGt89DUgw*1n4d1u+Z2GVj3UxH~M(*G0K^5aJ&+gtjqT9kq$CfvYFz^2~ z@5sZ|ow?Hb9W$Vgo9h)7FRmCFULYifby6C1US&~8)f+0y(;)Bh6nIwn+-;2tDpEtr zh#^v&>$i(U6je|3EIYhrY2xEWGH$*zeHjCt!?Vn1+uezEOf-m+Ey E0hXRQ8vp z@A=wPn4g!doTdZ-B-<8Ri;xVXH+yUx`ra5@Z%1OPoa>Z}MUPy?N)Y7mq8nm1A6o{C zAj_{>aRO!m5Vu}%IAy1O5yOc-H5;{2hkOBq1|VyGD8O>%P{!P_Oz@jj_uAT3n82G< zB|1B44_KgASXeE=;_7?{S6$8-dDZ-Pv8)h-9QdHjVj*9JKgfhksv*A&I!D!n3L7$! z%T20bQcimzW)UTb>D3g@ktB)fjcPaPF}R_ToQKgQO%W7LP&%BZ7+S|rI&9=op?DJS zVT!B^MxvpcN#&L007DQ}RaNRLjarn-2+C+Q5+qH~G>$Cr;3~h&hH!r{E#|=rgPbG; zWI^;}QID)!tdvbE#C13cU%+mE?${q3DHSRj5n=-br6viVFPhnqbxJ>bxz5Bg=B)ucjy)V#nmq?_j`kK2ut zJj>x)5^8XRK}+MAycY7AhD?JNYGZz0hS%v0x*XDKHd8qyMdexyRt;^*rASJ%fTpYl zeGF^!2W8gJ!B}ho#U8=tyb{Y;B*@C5GDqV$ah4{qQ{El#qTdODM(X$|C5BY6IW z@(m9v(x5Z~F*XdP(Hk|;?ZLI2F%xHXS`TidSr*rLG|&Sfsnus{R0N_(L?`EkNs6h^ zct(%UHv?Us?-ulVKY;UY&al7oYTU;WZ}1%OerZPpw|=+eoCt=sCb zadjIXuDRXDKN!svM<$6!yZ9STjoe^%I+M<8opVkpE0+m%v`$pi|ww`iQ$_A1G}5O?UMqEUHy`{?|zEBH!<9=m>KS4 z@3dTezhg(}(z=#e*N%65o^qB31vQlgu8mF2$I_n8wo=RUPu`nw`?Lj5j##{@U{7_| zlOJv!JMOxcvC^Qpg5iJe*Z`EJNAn(Tw$0Hd>{@OpIGVU~-Ewg2NwY0n+gXeM-Pzl& zxVt%++|f3e4DQxw+({jk;q#a?;o{>vuPM$N(-U2b!BXp0ML>F_%wGC-eCpHIpMl&B u$Ac5y4NK>oy0H5}Tlen??c;m$!U|Awa7tXzygCuh4zT6sTMwFDwf_NH0Xzr* literal 0 HcmV?d00001 diff --git a/assets/dolphin/external/L1_Mad_fist_128x64/frame_8.png b/assets/dolphin/external/L1_Mad_fist_128x64/frame_8.png new file mode 100644 index 0000000000000000000000000000000000000000..570c8b0c4c48cced5794a0adac9f8f07f3d3cc36 GIT binary patch literal 1581 zcmaJ>d2ka|7=Ix>0u%}kU|Ru~w2rNIvsZ2#+R&sWnABQQ8t!g(Uz*S)8#Y^##-b@= zxv>sd9mG=35r#6Jj0{=}j8bMmjtT<~RM25ir~)!&KnroxHpm|gJG1-V``-8azTbE4 zs`9eZQ6sWO002f=rkg6nH7dSEGO75zDtp%^E}4SaAnOs$fQSa5pfDVunOZ0yPFUmd8{{_+ekVsftU+F- zvf;KsF?4&TM|e0hQf6l&wTzCH7fwYA!g|qw4+=CA_Idq5eb^u$u&WpMaWN)G22_Mv zgM5&b!&Z(Ib38;e3Ib(t97i-dg%fvaoluA8BP31|7(rr$3MC0WsnQcFWayEL{&?1< zuP~Jic@s|txmyqddJGGNLW&Tj;P@Jh(CKs-PGTg9iW+FJ-Y?K$)E~@FSTMmL!+QdP zhw~$Gi?oxg6AW^Z>tGPRfX(*Eus=AIDlutTm=0is0>^y5cw__GL7@WvPveQ&L3@1w zVihpR)$xp25m$BsEN1WNj^c_U8~tm%M=T5NHE~Rx5Bdd*$siYR6s(8U<4%?#Tuvv7 zvowP$aY&(Bt&&95tP-+nty-&u%7mRK;Z+)~%7~jvrV&P*Ak4*D6GaxA37nuxNW!Gm zB(N5LP@w$`O!)SQzK5{pr(*TRJfsDVw{x5~(Ff&jPT+!WE`X4ff<$s{G~@BdC3*2G z4F+w3yk`kyOL)$Q45V4_c>)E7fDEnCDN!eji{b0EE>z3lN))Hn8d6P@Bn27y5T1Q3 zeS?iEO2jY%2{w9y(&#AYbfHQ{r$%X&(uL|snno!X1ziy0N{yP5V8<6P@FrZyRKqq%f7`ECm%{?4IK@AZ!|VOyY(%rq`8MkDT>JO{YfV(e~)eG z$lL64)<3v^es?-(=)DFef8HPg5B|*Go_6o`{VlQ1PRF<}GaQGbWn89nL+a=ZndH3Z zFQ8nCMA}_1UcH_o^%sP0D5P!4WtTo?kXtv}-u$st($}$f*)J!TUw9~&;w{6wM~xoY zM5h2t!PuOPrcBwq`3J9@ozvE|t$$&A^3CUZywCjBZoSvKV`oue7dXxyPM0h)?k&t( z1gu2S@K3krfjtYF(j5O%;9Oec$XVWufb2+a`Kx2RpUuADCN3{(q|epyIdd&dZJk9) zi0zP4du!9~{A;VzHv)%x7+BJumoo28&4eEIkE<7%PTL2)EtVAv-6xiR%;};R<12QmJM#- zLBaXqYtOc}Z>#lYoy>~1I@Txv$L;w(T1jsLW#f0{rdCSUcJ-x#Z)RP*Uwt|iSR07j zbDLj^u3H|O1OojhR@z(m$sfKq`*|w5I_&uNy0m)Bj3zK{UNwd+OsbA_WrDwVOqi0t zc@mhKw*Te8jj#J7-pVWX7dnS%c0^Ex6-Rr|S*W*8Mi@D6SZ(8-T{{Xy* BGI;<1 literal 0 HcmV?d00001 diff --git a/assets/dolphin/external/L1_Mad_fist_128x64/frame_9.png b/assets/dolphin/external/L1_Mad_fist_128x64/frame_9.png new file mode 100644 index 0000000000000000000000000000000000000000..2b6b6e57cbe2126dad0a5e24236024079c1c6fe7 GIT binary patch literal 1584 zcmaJ>eM}Q)7=PQ&s(dJJh5KEpBWhbBo0M#nqTPan#%V<^zYMF$NHX01e)&N-YqhW@vg%aX}HGIgbx%Gp@=BN3BqYNIVjTZByfT%CJBeh zn6!0;A`%l~VbV7*`_>yx`a;}EzR;Goi;$57(JKf`lYLMg5F{ZI5W)yaX-Q;;n_>A- zLNYT^rQx6*P~?|Gu2>X;$WWST{y7v_0rk9A7)b*|k`!b$ zBlg@g=^JiTSt5rKPO_m1%4nvb&yVU@vjJuFIzMVA83v{N6!b%g>x>3UgUJ-JMCUxy zNlB61o{8<#$&e3EXA6epffD7((MfxaWn;#s={BYyCjIRmaQ+hdT<5YE3{<{bJ7j?w#$6N9MYCH+{O;&CS7K*R_ zC7j20p3?aTmRwzaD;=DDY>OeMMuYBlW5vnXzUyZmD^+m8I$uYs>Oj|-=8dBbS>=k; zryhVe8VmltbA0WIU&pGOt;=rDR&|UD?SJQ3?E1yIPrhkU-fCPpD!+Z~w*yW6zPjmM zW#P%{Se|-HYMQbHpGbk+iGtBmmD<00!luD(o$*@xdF!;J6>awv_y()(IQWJ8vB$PQ ze+wIX8Jund_fb>YqQ7-#z+zKx<;=U2c^uE}-WFe`=G!kc+e+tTXLJIb2ALCXF4&&c z4O(Zms*k}PgG>H=e;S}BS?EcncpET~_dutVY7M(|DHLZ#0YVQP&9xnKN z($8zJ5b1`ToXra^sKur~rZ#PT6ivI-RxW+n!AD!SWc=3SOgp!ds8%A4#(lAuItM%F zDrVTKRT*RM;jv6roWvWZNQ<4d7cLI8Re^$t9KRvwoVU;2 z*mAY#H4s&9d%ak-BSD zATljo0eZDS|LHYFwPXG0m}Ka)?0$3a>g?`OUCr0OP;`_|cY=()TY4U&p!;%@C6>9< zS(@?>39{9J+hFdozO#qlTIK%i(WU5>_*uoHSE|A8tW2zJpy-3dKiuV<=h#(L-Si(i C12D7z literal 0 HcmV?d00001 diff --git a/assets/dolphin/external/L1_Mad_fist_128x64/meta.txt b/assets/dolphin/external/L1_Mad_fist_128x64/meta.txt new file mode 100644 index 00000000000..93e59e49b43 --- /dev/null +++ b/assets/dolphin/external/L1_Mad_fist_128x64/meta.txt @@ -0,0 +1,23 @@ +Filetype: Flipper Animation +Version: 1 + +Width: 128 +Height: 64 +Passive frames: 7 +Active frames: 13 +Frames order: 0 1 0 1 2 3 4 5 6 7 8 9 10 11 12 13 12 13 12 13 +Active cycles: 1 +Frame rate: 2 +Duration: 3600 +Active cooldown: 7 + +Bubble slots: 1 + +Slot: 0 +X: 67 +Y: 24 +Text: Am I a joke\nto you?!?! +AlignH: Left +AlignV: Center +StartFrame: 15 +EndFrame: 19 diff --git a/assets/dolphin/external/L2_Soldering_128x64/frame_0.png b/assets/dolphin/external/L2_Soldering_128x64/frame_0.png new file mode 100644 index 0000000000000000000000000000000000000000..bd20ae84369ed42105e0a1a546d1f1d654f9be80 GIT binary patch literal 1778 zcmbVNdr;GM98Xo0r%*(Xhq_ptfZ8T$N=qU|fl#PNu~$(LJRxmUsL-Ug0otNF9=_P_ zm?Bf>W5Ovob*G#H;)5Fl=3_dcR${b5&8xtHBYOy0JS?9>nVS2&*C@|87a|TQlOM*62E^Wnaa=|;hIJb5lLjv%f z3Y#Mrybmf>r3Pae3kAwVh)@T^Fet-Bl%5o8Q3I))3yNVe0wLTj6CyHPjN%9ej$8uH zp+#@NHH2cs9k-JUvRT%QLr_6Mfv5l#F_tU{!7vPh#gJGm$TGIQ!*F=Cl#n113RH$5aj{r9UTO9Hp4R3Y{m?VQ4s=$ zrWk2GQ(z5q_UL`e1Z6SiQ+kDkF@f)jj2k}^fP~aa3}UTTNMRC0s25A5LQ;$Bgs2vU zWl}=~sv{A>2wwkxiwAK*LC#6}&*Y3AapUM*exL%k`9LO$<``t*sN&Uu)^ju)uTD&k z zmbo)ErEuD_=X2({f`@UA<}=QaXCeF!}`d57tXdH@CDlD@XrBxiKTwiSKNk=i%ND@f$A$W4^ly+x?ys-SQM_RVp^Wgw9=T-rOu4dma9BXzI#owWsQQiM@$TV*RAc zz!!0vsxD;sv}W%qDOp#oytOHGKTWu7VhEHM=F!;`9t8IUA6b{` zeo@W*5i?kkmU^jVP~_iO)L!j5Be(qips4Cn_-A8!nf&0on>`v}pvJp-+5E}8y@2i| zwam44jZ59}*&#q?)44TnZL^zx@VM=8rT5i!KKLg34YqOH)nfrqOOUXB`tnlu)@k>* zx7(k4G|aB=b5ohJv>9J!+1(G#d2Q#H+-8r#*Yz7pn_QQ?iY|u^Ta{;yrtKuA{GGn# zc(TI1e_&dU>0sABL#d_zL9MyDe~^HHg?ICpu57&RogH%WP5O4}3y62U_tx8#p~>Cx aMLb~qz$CN(>RyZUFQkl1A`Zu7mizTS@hn0~;F`R} zokTbQFqddk(y4Ssf>=%JdALJ|XVn{NGysH0SdF+khoC?ek)<_ApvO(8AW*B3KxrWg zSYeDJvbC}KCL%dMF-4u9qZVnPh?!uxRZJVu6BG_w^*V!DY?VMmcE$ACam<@w7{$bh2poPO+M!94 zDOSp3hTYLS36xDyMlqjnu~>K(j7OTX_=rd(;=?E(MY*&F*PLgda4Xkf_8+kzC(LS- z)<|hd1L&}btH@kR0?}mON1-<=6dw#5%)_~&v&OgLMn1xW`Fg!0v>|OXr6m5P@lkDa zN}iG6D+x21Yf{rC$@Cuq)9L%PBZnf*Mm)!)rR#$0st40I_SA?P%H!L$0#Z&?qfeFEgosZ$+5RoiQ5GD(Y!Gs7B9VJ3V@@N@` z$OWQEfiPM&f{innDcqnYMto~&-^19*Ph!PUCIY8OQwmAyMj9b0o1{o{HfaP=jE8_< zq-hNr(qayB)aZT4a>ArtLTF-4q#hhfvRL~O0s>qm$V62tE+G;iTn#D+<>D$#&Bat0 zEDX&I!_+te4dXTcH+g)T6yMP)|LL5OBf1?O%MYVKZ$1nYVW20-M2|}8rqa{&n7Je+ zq(swlaB#5Z#|T;d(5!2 zY$y9IKyBGBpTd1Czlib`Kxe&2OTX9J(Z2DmwQgf8?-Us$!%mZ@uDiPc3FuVC{tLcu zPYiTSP4Vkb3U7JNSZoaS@hi3k1U^g7vQIz828r%5mZ+NfU1)a*>{4;NX$o{ygB&aJ z=P)_T;t$<&u^9r9ny2>iehzQRI8OgoaKriL*#bNENtNrt*fd!x(d@;yMo^88b?jO;`<=> zt=;>^o}}i$N?my62KZ>{$s_f?vWC`Ko+~L^rt9{N1+hInsIGQ?+<3X*8jtXr>s4ccrEq01xRk~5I{ln=W-Pzsuec!&{d%t(h zZcUm$cckw)UjP6`YUgQ^IqBk_SfPM>KN1${IPo!?kjkboM%Ip5Ng$433?!&EW0_Dx0cHRN;(SjCpj#4zqnv*0M9s^$k}3J~^>}_Zt|UY;v%x5biZfs)SqyZTb7-5&5iNRaSH-P8#}X0v zR)x)u7QG{ts!IaZjFklCVg$lr7zX7^F-c%j18T(ZnV=MwA`*nV z=g>+RRmqw;gYLLpw8+G=7L`O|x7)>bRLod2C5Td~l)zGnR0?q#kj+W6m;<71!9x}_ zqz$)H7M5aY&|?uZFe}+;5l8l26lRM~_uepV8_X4#HHibWNDwhBF`GT1z16m{$>cvY zKB#TeJ1wLnnY1x0tvFW_WAG4|OW%Jx@+fj_R12&WR~IZt!{95;B+Y6y(IW1Pn4kz% zgc4E6NI41-uv7uzh>V1kQYi{4jFD2*AcGN@lnvSW5MCyeDP@s}LNN!GBS?ZeUaeHe zY1C)}tUwj8R62y!(l!>OadOBv#rYn@%KsCqQd>!kWvqIJ$r);dBoo6jHWOn3rKlJI zLzhrA!PsqKo*KOiSwmW>Jd&7WWz68)B&(A{ec)pNOe|2`;89;k5*2fF!g%(FKZyvaetujo5G0Gc~8E6 zQ0of}=-AnvD~_eC-r)4sT5gW3j^AjY_zyP?PjnD`aQ(}j0ViE2fD+jS7qGzh881F7 zt}j6gw1~0P#fiO3v#P@iHV4&sbpq|fM#hewIDTQ)w7IM9hipy zQn|w#7UyU5`TJwD%W+?~dIaH0I~wF39ZV0z@$#Ph0KhjIZhz&K?(z=mjA$8GF8KUm zX=SI6`?@!KE_X@JC&RY(ck%5!e|esB((+;gs4p{}0X{R8RV^>BwF0+&v}?PcU8q{t z`gs0yJ+J(vv*c{`GO+P*s8Klf0DntbEYp5Hv@rU~o%5quG4}MgD?GY~=WRKgbF1lU z=!=@+2T!$cDh@96{eu@V%V$PcaY*79&skZ=HQ(LB#)epJZ}p|_(9-m@%H%Ax<8;I7 z-aG5f+u)vwyMR|y_f4H?2`JC@_Hi{I+;RKnk)CT%%BRcZoJDCmw!tIxnwyfb# z{A+SsK=(rT8FvE_caa|bG7T;&2)uG`3^l6V8dX$q5WgY37ar6T(o968%9}1`2f@4y z*`*6-E4=sbxEdatTiOYU11eDQcD{U4L3miJ)meA=&5C{1AtC*yZTtt%%l!{M-@7bp z(evHO$F9uTSQ2sMI8r!y($PP){MHIXS7Eata@V{aF;tymalI`6z~0)XUn`zfc?&LN zw$6O_GURT&?r0hR-tWC{ f_O2WLBG?V=p~fs=-*gmteni@Y`I=Ml83lg>noO5K literal 0 HcmV?d00001 diff --git a/assets/dolphin/external/L2_Soldering_128x64/frame_2.png b/assets/dolphin/external/L2_Soldering_128x64/frame_2.png new file mode 100644 index 0000000000000000000000000000000000000000..514241266b9dedb21dc9a4e5a72b77d7038a77c7 GIT binary patch literal 1779 zcmbVNX;c$e6rK=}rL3Z&JucHh#i&_k60%H5A!LDA!3b0+T4gdBAckbp$v^_0(*~r- zVqNKRN3pG1#iiDzXsuLh6_v#z7OmEZO|94#EiSaxrV|9)A0B^n&dl8R-rVor?`~(R zbg4-pK`#dZ01%>0R;4l0$vg=GZ079_Sf0X&F|<01PA79|J4O+J!a(W?P;18Wh%^E- z6u;d}!~p=i$e58uXQj+Uanj7gygEFG*~*{+ATHiv#c&frgL)#*Xpuv`M~_3G(IAI1 zV^ahvRwa>dOfI2_^peyJyu^gd3{d=QV4MSG444TT10Ci9iw$+ip#i%nv-TeIA#gy2 zHp!uarX;!1LtrL-FLvZrWZ0myC?iuBtUyKLg=WG+YgKZH`NA_84QQ+k zmWl|8kZTYiQZ5dQ2(Ao4gj{K^7!m440$4zZhU`2KFHj(2kwmGKYJ?IPRx1^VCN@zb zln7;FB`lVThp<|Ujm9iEG349G_#VV2z7UHlDFUNODuW~oh8jVaPtv3X&&Ognm)&qjgSJR2s$!b}jwj7rBtV=FUe!*nw< z)Qt3aJRe`)e2tk&mR6<6a9lZ`9Z31W!K*!<+o_!9vxhd~fjYFKDDjo*FfHt-30ve* zn)@dK=F-ggKv#CXd(DZ)2UgNH!MUl+V}DfP8s&UdvF;~#3-HTv*1ld=Qy}oT^*T!s zq-|Dwo_+UT?KofE#w#qxJBvRoRdTY38^hd=2wr&Jq6anE?LgC{Nb&81b&HS3%V(G0 z@2u%&Eq!UCv+qKGmT$w3GqXCII;~@zAst0oAyo%8-|sW&M$fD0EvdY+%IzAzEFm=E zch2g*RN&0b5!*yjdv+{2AgysWUJsr`T$&oI5%{<7zN8Mj(LY-H2CM1r3}47OJ^kbp zTR;xGXDwToupJ1#1?j#sH!Opl`>)|qR{`K2`y3#}*;VZ;f0MPrV`|l@yI1ri%}t8gU8Amy>z~ql!40&8B~JTGcQ*6>5k>VAr=sN!Si419 zK2o#k@XeJz`tq7m;>#6^1t%Mdj`hqxF`-~7@6xpB*bS}z3uDkl+y-$UpSADQ@<;Z+ dN4k=nETDR9WX`;aCSX{2J+gKH!%^94%1<>kZ1sym*lV@IwMAaTCBiemOu}WwnLx+l|Y#Z zYPQ-U!wL-x%Brk%^gtpzNONF-vhVHONCNDYRq)Jz}_hS^3Rw;;!C zI;+7#7;rP_v508#WrPGG$-a)lWKpZ%7&hC+az$p1|Yvh z)wZRVS};}`X2X|Rb!18O^l>nmzIQwFD3WZ%3#|sSE=aK)*DW()WiIBN%VTrc7;oIp+wg29ES1T4a-otd;BXW&sYuC} ziC~3NDiR140{%EwWwsHBS%;1LHjuu@u(Eez#WE{~5V$oR$BV}sK~snmxUCSkfH0TI z0cU3#%qVWR#d~V>I%GL!HI!he(u$kF(IkrvZy~@#v^+hm)iN*pP%lyb~d}l+RF~4y4@}I0ccaObA8mT+_J{!Ij1WZcvW5T z>N}I@*3w>uI+vcvdl~B-SbKD2i4bq=)NP}>!Uo*A%Rz^Cze=;Q^aUFjz6o4;Na^qg zUUjuochIUYfjN^$UTlc+21}xVV>c$D{hEN13`er)zRhx3g!P6x3VFnuer?I2=o-?KCU}Zd+M7|V6`2pqg>+u z(wZj&jJtF}PD-v9drOV8wKpe90;v8vTR8zpK90mB-g^IVaQ{iFO$v5W!R5K;{J_&`eK!LY)YF(xeIt+Fc4`*O9gJn_nTZb9S!YZ)rG`TpBmq77wcxX#NL{oEUo(;*fZ&5Jk>WLg60Ug z_4jf7!-UM?w*2irpQ44;UWV}d8UCA}mvmL0X{@U_g+1u0x6@rsccyR1w;$rguZx57 zBY}}CUG&J0Tg?YhISwb>Qf5>}qrG2zj^BTY-gbGAa~!l!;7vG+#K+I7#V_&?~bz;qDm61D6&fnud4EAQ;utgYG#k`lgI~80_ ziTzw$KIC$Bf62W|KR4}2dCkC-uO-gN9|X}wg|WE@*Dad6eU*Xh4hMQip1j(+!e@xy Y0nq;p%b?ZI6?y(bDn+WiRhnP<56?u6S^xk5 literal 0 HcmV?d00001 diff --git a/assets/dolphin/external/L2_Soldering_128x64/frame_4.png b/assets/dolphin/external/L2_Soldering_128x64/frame_4.png new file mode 100644 index 0000000000000000000000000000000000000000..ca696e4cf425d7108426461b313fc8619bad15d7 GIT binary patch literal 1784 zcmbVNYfuwc6utp@h&+pJ5k;4v^3Wu^n?N2Ac_cxi1SkZFij>V}11TgMl8ppxEzog% z6;W`2Dq5;olqyB5Gq#kfbyN^Us-hw?>WE6UidBj@R_O-8_J`w-?(FWl=ic+3_t{;a zl(5jv#n%M@;3kigCeyTtexjW1>GvJyG6hYhQ8E>kLTage%tU}_4XGv|xgN_Rk_k*x zkk>{;0ARmTr&LiYMZ5?n^=!;0!?x;;G#Y@2NUIUUa|jAj6InWgm^s*dj0x#9VrE*X z0#+C$M7A!j&_tvZCMfa399*bjMlOINtRh;0o}e(us?Rl;MOHC$Os|Mu+qOAOXiS94 z5i?&qrBWn864FFKd^WM;aiTModjwC^3_E_H`6`qeAgUvB5l^D>`c&D`w;%Y?!0h+d>-v5}ahhOj=AhT@r1;1ei|WyA9a{X>UY{CLLWDELTe67Cm90;Rui4{pq1V)i2B}wK^G(u7~Ns;Dk(g>kkHUb5u z=?oe&-yCeK(d&?lQuLdZi{8k85t!qi-x#Z_}* zewbFk#W93Aj@SI({>B8T7QF~59vKrv9f3Qw4bp!bVF|Y2F5_f z@T;n8j~9bZhm4oAi*nXfe!T1H<#zF1A?Q6gdj3&h$wIJmGg{idopE*4@%S%JARIid zIA&kFyY3Q{K4;`bK(BMH;E28P(~^o}g}*BGmiO7=+3B90Py0B-CEg$%#wwOgM@C+B z`^n>G1q81y&MTQ@+*w+NWXfV!hd4Esw1fR_y>|_94c+>ajnSCVYxRBqPZn3U^>swe zg`RJ1D+mPrc`hm2ywmz6%W9C!N8ys-uPjyfy*e1K-&xuuf(5?yA;2dCgX~)M4SkU* zAg2y@k7Dewga5#5JA14B#6^d$Yc zaZ}g%TwdF^+07@Yiv?OYjdXZ;0%Ntz+wHSC$jD4bDY5z4;TNFsW~w%|GRjmQcsUfD z_-m8&qWo&&{TVBKqsm9RZhL?w*Qe`6^M0;NdS1M7?n7R4--Yt2IS1^ViX`bJ2aijD zEU<;WCD{5!MjGaRq-OmhFndG1IArvqA2+u*y~a6g*W|nlYaMoXu2SA^dap#FPYi)OujB+BxvxrJK&s0jBs()wW`W#o2EPUT=F*s z2DxKvKDzhNT36I+M4CE2Ls(0F!BTWl!|0208LE0FTS@I7&)0UY4 literal 0 HcmV?d00001 diff --git a/assets/dolphin/external/L2_Soldering_128x64/frame_5.png b/assets/dolphin/external/L2_Soldering_128x64/frame_5.png new file mode 100644 index 0000000000000000000000000000000000000000..aa7fc8ea0f4d658610ee89aaf2c68514807c758d GIT binary patch literal 1782 zcmbVNc~BE)6kiBOkkgS-Lo$$TNEQfqL8KzI zR7$PZskfHOQAf);qJpBWsMXPmc+sIKtyU{mm_h78HypNqIR4R{-F@Hp?fbp=d)I8G zEPa*toWMB%0C=Y)OXRdHrJr~vgMJS)x2Mr!AthB(Ye^kdgj)zetR>Y1m}10p2swdk zi}QPlSO8!Y8Wc)OnU*TlkVY=<(BayQW*Q9uv2ivtuE`}RP)+0*Od{4uXBP`JXhp2d zs5CguoJi;m$t4zIZArR9Qi6X~}^Qfj|JkD1@RMT7zRPHc_~ZW3q2}+e*oae`&l? z+o~uw6Of#+k_8qGT@qdRESOH;+Z{O+X*R+Pi-E2So+lwS1xCU|rAS09`U_WU&oMvNs>e)CJEysh%`|k#l(q{ zBry-6S5eW(EH=etrErsmnDuR-ea~Rww_=5f76PY8i-IKcW*b4KCn?gZC(R&=aS@Q6 zX)tNYBI`0ojiy7E5Eerrp-r-oMsO<0Lc<#f@NhLxhpN>aLcl{fT9g;f!PS_CgQ+o? zAFYeQG&mi=G+z6ElLyhHAV;VCr*meH=yr50UylO4c|A;oiJl+}Ju1n*I6;q@n=Dl! zrRC)0wWb>8J?z zWB6^TisIm1-oVMd=XZR2PTCPPG?$v|H=14}*Bz5DdF3SbRVlwt@iqOy-qUbxrCPmD z+RfO8O8fT@yE`9PKJErEvRuKfgBO?&3xXOByVSIGj@Z2cc)NXjIwL-(sfL+k9`)Yw zOR>-3uZ*&eb&;V#?&To>vU_oHbE?;kcA9%kl$1l|O zVC&G8lTVkGN<7&>L)boWLl(bJ76c!aj01Movk50xK={2xQf&a|Zpd&+&e4b1d{j#y ztg*%QkbkzaABgE+A^6Ps=+c6!3KS?CO8ndWVa}H5;a0`R75zJJ8s;~CViqrFx^zpq zSCuN?_<|N7e>wUnq^-wm!S&s2SHI*)-ax~$)`Q!W%8B)b;Kvqv9%1TDAYlYUatoZ@97tVeFK!6Q1FW@#Zk7ve9G2UhluD z?RNj1THoD0s)N5pID@?|A!)-{aCO2^@)>Tz@w4ugc7H7RwpgzVl~265=b_!5@X3YA(c$#7$(D cZg%zp_}|T2>vB(g)$u1vk)}(IC8+HG0C{VIwEzGB literal 0 HcmV?d00001 diff --git a/assets/dolphin/external/L2_Soldering_128x64/frame_6.png b/assets/dolphin/external/L2_Soldering_128x64/frame_6.png new file mode 100644 index 0000000000000000000000000000000000000000..85d1e30c9bd90b8aa7ccdc2355c1c33e9d183356 GIT binary patch literal 1799 zcmbVNYfuwc6uu!mQiMVc)Dd-D15&7NlHDXgG6aDnmQaEiP}7c%Y_gk&m~7mv60k~8 z@WDeVSjDO%j!2z?N?}lE&=GvKDhPt_4vL~etsOz7T050)5Nv-q{n4G>J@?){-#OoT z&2COh{mkDt#1{bIuTD~G8R=r4cn+I+KjduHFk&*T($VRpkiIqjj1TnSr$OF}DuiX|*$G0AlAj?U*5ppdmeBve@Ljr_HB$kOi0X z7D+Thja@;QElIf)k)E5HVaUxgNO9hrI4IUBV+>dc8iSnHSO&X*iDFTY-Bd|dz6hhHbK7nJXUSz}!vmsQ7A_9cDqhTakhKgi}6dJpD zj6(`H%CyS4WA2!poM)zKyG$U+&d%m%i})mE5+G8kR3JnJC<-$gup`GtV@}xS2pzYe zBpe3HVy7*n4RTw=^yErf&SS{FjlyczXx;i-@6j-h9&_=Z#w3hgX z#(T9L898=Bpd}pSO3J{L#27jbX43cHj@*h28`(U{!qf#@t|SdBt%QwME9E@q3m>=O zGKmz45fjlO7#E^3umKShuoOi_aEvhu73sx7L`aCo?Ys|<#w4Ihi3Ew6D~d)Cl|m{( zRSAhvhzN~AP*f!y$Es}(8nYRQao-lk_ZU|ApIDiKA~2eyGDvdycq62lNt$$+Njrp! z_y`oS$YR6EY)7QKMsGt_5|m{XfzPE#D>Ry9ndLnM#F$=eMD==@kctr)N5xSvrWYAt zkzOQ>jxxrG3>d;2!{h%qc>;!%z}+eT>YVW-rXAhOccZ{;-VGCBVWA%{CM(%o!rYFD`SRR7x5-1PY_-J=uGbk?l{ti}qi^Y>sKJ*dN}!e9Ug02^N)fy?)pZ9-Ly8b+B5v z;KiOf>?%}!F+msk>iIXZ9OzaPYw$H&!A{yPrCa$E0wQ2A)%%|JiY>LrmL&v$^E=DJ zZ`1^=&AaV`6=j}x<+fM7V%4zE<~Lq9gI;7p(!{SK4F; znOrY>dbuabWLFL~ z4zyaQ7i#^lPgpwj%NF(~qUgr-H8ODU^hs8W>$+FxuHG82XUB)H%x5Qc_n2C}07TyO zu97d@wka_`v*Cpb9ElA)_dF(R%D(R2pm^G-zSG7%x<2?rP;i%bq;xpFgX>$UI~oB7 zdrsgTVR3_J{abfh2ZQ3Z6P&9WL(qeCp+|(P@AY?ahZdkfFq9PBB9T{tk{w~HpxV`e z#@3fQ7rx>01qaCeWN}?rkiE(IX}JcZ4quM%OW+tPQn(5&$iKg&^v9dv@v;bw!}GAu zcJqT|QIjUnyDv(W9mM+SMC#L!8z9Yh23_a%!9s)QH1ig`mQ{3c7%tve{d4ev?P0_I zJC9F7j}f5$T4iPFG1)mBQ)U*T))Z=HIlD8oyh=9vPu;$hB`udSiF|e52F{_cP(Nc) zxJGe$cMi`80+U^;_|qO&b1J<`OswpDj-G3}ze94UVZKjPW99`9z0aLlwrzcX&8|8X zZ1t!iSHYbcDiRFr3pn$#(yPEjcc7zt-ABJobDf+oWdZL=ae^5GC6^lFOE*>}`-=8V zpL~48KS#Y-Gz6kW=T zh6aKaPzpXzK#6IBpd|+Qpg|F$A|j9qqK~FVgo-7)ZoF83`1nWn+}-#0^8I|@Kf7cx zt32KP-2njb6h{f=l(bS`n5z@@zvY@QrNo=0D1nS6)T9|R;6S*FP~f0gi>2Ul98+!D z(1x!70H=+bxCAmmx|*jXv~oOMw*hVqJ^#mS6FzI0WD5qphcUmGx98a+Js#mwYDEKXyAkj znZ~D029+R{fdaySgKRniDPb4}*<3oV!cYZMjVYIcD2yTugnHQ!!sek&9>N8u9vbD) zpi=YX!pJFi)Q(R}B}qMx!7!W6bTgAq7*ZGrm&;|qC<8?yN&_-((vg@2(isD%EeLU= z(xB0k8bSx!En*77MDl4=u#;J6^-}2z!#d+st*ELoESR2w&|!vFYfo)L+epgsf5UjG zwlQv#9%smLBVjTqsg|e%r@>VDUhT-PNJYb2W6)52!P13<(xk<8q*%zOQ8#pzM#Wpk zMK~;+&4g4i%7K&!3x~KU%7i%T5R|E4!3d1ArtQ28kBVTF&E*O?kxVv%hy)xqQzS$X zM8HLvTmc)I#)@@D64NR1Y2O;k_Y_v}N-R%cz%i0A#1TaL^dQJm36e0T5_%A2(h)E? zUZYbHX5-uT9!;h!#0{E_xGK^>Xu*jh^E59BfQ2boYE+?sa4rjhR46M1!W2v;#8fb0 zc8Hq8RAN*DlX%ttEgpjkieaCW|4h#G5jBqX>DFi~%Z<}Gej>oJ)o09>b2&0z9aVgjgSmu@A zcWiLCE(RX58y#d_=lsgu#fQRspeJnx2axShSQP?X4}ej<`wcm~c3?(D(V%Z~G5q2A z=I?Ds0k|!Tb-LbQU3(+3wE0Ln}2z3%u`o?zfxMi<~uzjFXj zd3I-TWx%JB0LLv)!=6g|mxn~;wI*7N+vN@K1$A%P^OsB%^$_~4*JNXj3L_4B`vcEe zNqx0hUJV-r8`Oy#{lF6EhErEPMjQt&WpF&}9Ck=ZFYlnik^mXdsR;8uJ!xw$^k*?KH3efTBNW@K%t54DWbQiJ1_Lki70sjMwzG3AC>O;TvWSdJh z>Dv)Nu3S?wURtyFU~7z9*rJv@Yoo5YAH55Yipa$h;P^txMKU&ay-2=o0dp+kalJ=! za@Qk%jVa+;_TDCcJOggqAN6{9{K95a!lPr6C6(6v<|U5N&v$#j|5P=*-9y@&Bjk=o zwgcngT|Nahfb<&fRKMj(op1otoQG8#uh%#OHx%wj2w{FJlOr<=b_lrh(XB@^oRlhd&Z90%jfop zQq=($N6wl$+KS`T#CwZI-yMOE@`^p)-bfQi2U`Wb= r6Z_659q(V>{>!>yFXv(7GoNJOS+GxZ<r literal 0 HcmV?d00001 diff --git a/assets/dolphin/external/L2_Soldering_128x64/frame_8.png b/assets/dolphin/external/L2_Soldering_128x64/frame_8.png new file mode 100644 index 0000000000000000000000000000000000000000..12bed1b4a04012af0eeefb7566680314c52ba787 GIT binary patch literal 1798 zcmbVNc~BE)6#qg7K~7OYyw`=Qs7ZFSfgBP<2?9b80U;J0-6R_lA=#K+NTePSM+CK1 zE2YR$#fm_+f_6k&5Adpj3KX>t3W&Cdj#zJn z;@27pUMxY8X(km@5{=I=m`UG<9oZBaHj>3A9a9%PRYt1P^n`(qkV#?Y3s&C zNI(cNjvC>MI4V>?aKwB*#t~@(_?S|Fpa>xtw(~wbCJ>-9kys{LhzU_NG(?Pwu~5D+ zKqwL|2*CXPhp`a`ipC8pV%WEi@jZkM`5;yjVj^&wG{uu->Tn~(Xi1u+w4@Q@V_X!P znW!_UNi*eVtI^w#WrRtWPN)}}NIf)|WQp!Q1O&KJpy4Z(96~HWIcmNjfP*VB6$evd zh%i7S!c;g458>7SH+ejU6wlTv|LL6JBc>f~%Xg!|Y~BqMVPGc6#EgpfrSJe|%tpjS z#fLI-U|^uMbzeI(lVc-f^W!adu6?{c`Xb^&y%{LmU6WKONN@RUGU6M|P7u1^y$-&) zdUNUPo*t#MfmL;xwOsgjdy_+5zebuF0%|sHx!eOfPd?3gv2rK5y3PrhGg}^ZT>w3` ztg2eJbq07fW5Crq%lGrmNK)^uZg;y;r`$ltzERrFlCeF%|)5`A3pJGLg%!;_KZHm#Ds7J^tAQ@2p+- zlk!sQ!K^WLvYup*E3ELK(pHjfHH782EU!5@rR6%;&g(1|-f(l)QlCdGm&5*#@zx-x zvPHmq!{|+(!Fd&?*OTlNR9*!O+0OwND39i}Qwd?N!PS4=u@?gCx^n?w-?0U-jZUWd$YBOt8eDM9PrrX-kxrt z>CatO%Bk|6wxha@T~*VuM0?utNknm+!5&(&u3;*-FSWTrmz(>`{S$J@_0=cn$ld;> z{gDKg1<(DtE3$9y@!Yx*XMEBXov>s~DVXH9?a*ES(%rtrr(-A*U+>(O=;rL_vE|c~ zL6_K706a#{yHCH9qXipe50-D8_EVEGSLamYlHlR}d|Y<(fsLl8o}qiHr{U4<*`vWH zG3gE9qXQzM?pDDOXNyxFaPf&O?mz3*W8PG0Eid}D99cH9@MZN=yW|}$ty$8P#_tW$ zrHSx?GF)`edBdU%*ls$AvfuvIocxz=bsgnJc2J@>im^{pk8LkD?ug5|eU5jtyg6ZUKAm^%&~uj=y$Mt5Z--_FzS`fdovjgN zZ;m0R9$dGkpl`1GGEKp*FM?gzQQm2_MN|DQo-7!3-o*rMwzQY8;LZK=+PI01jinpQ xOY-T-lfO=XQe7CZH-$JoJwIB1!wSZ1WyRz~WTZV+t$aQa7gcK3bXx9|7f z?_INXS(&SRy%%`{0DRNa70|t^NAe*7oXpz{Y@T^@4vvwWx zU}#o_E|J2oNU0QAkc={ukPyMR8Wcq#p%@{x1g_@m2+eW`M{$gYF}IM52_-mRf{CHI z3uYXewK_?TJax_;vy;L_G;Nabcvhr1mzhFuFz(+Ep!g~ z4~;i!Ta(Q>v!1C7Q7Wf2Wd_nnr^}@<^99lB zwUSsdCK8ZBK39w4BCZA#kX$j2^SL5j9L`q@Pz)sn^LE~Z=O-n}lH_QTD3ve7uoPJ` zj>pPUFkBcbN|wdOzQ(2-Ei_@&kn_IvjPE(D_&>1{nVBSL%B-ZQ()mWnDxzr0Qbd^` zoR45oRG!|brL2}^t{S}xSx%bu<)k*%Oc|irBun&fARr*r0v)bab4jrP<7#n19G6h@ zHC(=$j|$^-BEE*e;5oeZ|0a*ekm9*I1u*QvrolG?3~oH z*73GDcP*X?1$TX&zZJaII@RAt)%*jWL;X$?| z63oPJ=L|%LH&mk=9!P6Ca4+HxfKHuSX{+P#1{MH7T0v0F*L!&@#!nP7c}5U(;U;# zHMZ!}p>B`hsVx8TcO*H$m zks0s_=;*Yk-JubGedOMSo$_*)C$~drum-|Qh9C0;?O~-}iK>rwZ5v>P6bxP2qwv17 zkoCo7k?+8h#;j??{p}m*$va)wOARrLa$}A!4=fNYktMVg<&|D-GcPH)s0oWZ7qVO! z^+U6>Ap;NY=M3DdjbOD7mUh?qohv}Fx)1W%iKouqtC$|!(Jj;N4>^1$wA0ix)T0Cy zQ4jJv+G{yudEo&A=huVXwN1U(f!|Xfd4FH)#qV3K8w=UKZNZ*khb%lah3qJCe*OZz zk< zt7(=VT6TA$W#`1!WXFi|VIc9bL*d{1d!%ph@akr!C;tfg5^0K*hWN*}HSgK5&6Dpg zzOcD(ygDqdZlbPq<>*PlV2|D7zWp{Q&RAUk?0%!>#c~BEq7=I*kc%XR9pw_l)kf{`t?2&Uz5XdGHOMr%O)Kbf4cSABE*|=FsK&K71 zirNlN84pyH7A+pFXh(}hI~5(vpmheV|J1A2qjYq180!IpB7Fg3{ljr*cHev7`+nc| z`>tJ^pSvi2!t4nEfOtzbWrJ%7z8P^+`29O>y%jFAL{o`az&ph%THrt?%R4y4;-$+u z8%ML%%T9A?07z@y_7btgnnN#S6}|u&G{{Eml5iguD`m)t zis&)OMoE=e^ARI2aEMlc$r%(y5v^X~K%F`Vr$-kcIErIR3|C@mIgXLIn#9z|*dv4f z1lCE~DD#*%crwUbqUa};%Brd=MHQjog>ogP*XxxiuEcRU)Q|_NeIgx{`vOT33ltY% z1h-#w^FAbOk#_KvqCp0^jt1fNTdmIx`vPOBf=N>bX}=Ovph~Yd9NCC=K(ulH(|D=MycIK?ZLWteYjZ8kLSv zYmJ0Pmx*B}VslmfEN?nzWjTjhA6H<}5r5GnuonOf-zuQ3P%@VJJqJag5Sw zBUp^xr)>4AI~FY*Bw??-S#fgg( z)QvVNl)y0j5jLbsrK33~jml9Sfyx_B@3zcaPUb?&Ga=m13 z0`=Xq;oaKv(StFnNvAer&Yf-N$_I-c#yuOTP5di57_~G6mjQj}pGils=@Ub#^-p|X zoRX~CQUzLjj~B~}#HW7g*NwwR<~tJ5(zvMf;^e!U#Bnh_(iK+(trq+XV>+=4Uo-ktCt! zo7VP2{L;ex)c6y3=I%?`Uy!*iAnQI1_ITRC_lHxYu4{IE#>Sb2M-$&Y*c)olyq>d( zdM#>0PD$*ZrJm&56@`!b0iLl9v<=Myw?Mlwl)dt{A)zkRyR#0==(x2!*B;%T-z=H& zgkH3EFjUaH8$8-sKe6I1w&g(2U}(E^vD<8H%A2$!+O@IlL!@ihv+Hc$#F@?a_LigS ztz8p3_OAZj^DQ`4+tk>-qW|zwbi461ajE%i`_P3uvqR^S3hJ7CX!c1<(V51@54tb+ zgRJJy*FD}L4B9p}KHgVZG;d%!uw7l2ab?x&x-*?pN;B^9J0*vD=%h>JCT8w|y-S1# zomtZ+N3Gd2tFrA=BDM=KiyG1se~#6F2JGSeYqzEMOE>J;S2o2m=gS{1Ui2TV4}_#| ztQp_ZG4p1>q#`+XEBVv%mYc|&abeM}Q)7{9i(qbL!TsoSF5PINfE-d8_QD<8cw$}A!jg=LOjdsk?ny>dO)if$`z z1C556ZA2Z8;79z*WK2b)#()kLGo8+lIAD2k1IGk~@dkfV0hw+lT_kExD`906? z`MTwW1@9y$y`BU?P_iwLDFSN*yjh6~@V%D!g&i!fN!C)SSnx<8R^*{o zMLf$bsyWWjf*?h`*HJ2!+UL-2!KYzkI-0OA0MHOLD>EEm-Br8QWo!dH6p>O{V{uE620t8$w-By%=AD@+3eK3-zsu&>%5q{C)p&@K)3F)@a~ zgDO&$85tr~YA=K>g2=-L4S~9G9ES}ijSKe}UAzgO0h2gMU<8Q~I+P@6Qb!Xyc=$np zKaum$MNICnH*hi|m68;oF)S1cX+o4n5GydkWHMnmiIF4cO0 zqBkIU1wS0K$hw4D$&3K5LqYfgcKb8K{@`$`K+>=<8^8z+j`@7C$Og58QW5_@jTdSM z9g6}yR>TK|TG0(E;+Y%=gY3QBQA`oAq34QTP!_hD5!|&t-Y?l0GXicjoR^~wdaaSt z87!3Em`xB?OEzWHGub9xj?SXBSPlBPjTd1Fg4F6vlqHAA*2l0$h9WIi0w<_kl32-;j_c3YLPb)lzQ8U6S3@%_rM?1Knc{+Zc*d4bb2U`LwLkvQ8P=cmeN_*EALGw(>^5)^OH`i z8fo}L}ZaO_Ww9LY`HDAy=`r+z5i&>p%-{w~}4i)sX%vkV!TkbSbTTs>~J^N!3R zWT4JXuUN;|Mb4;iK_$A>v|aMvhaqTZRtxm=(~*z}U7C`Wdgx(NkGXBfl}Qkjz(7~t z?ilg6U!9LNHjQ~4dH2r)Q?{nnrgs$de)j#TC6U(1`h<}?+io?tK-Fmz)IG$uF4M)I z63 zfv!WNGE&Ae*Ig_7Msze!s=V3Xy1Z${eHdCi${m9A`Tcw0gRdSkbsuaz@0-^iy0#HI k&evRxDk;PE%#RW#Kna$yoA%`Q9g6+tZPo&&J;%B9KVz~zy8r+H literal 0 HcmV?d00001 diff --git a/assets/dolphin/external/L3_Hijack_radio_128x64/frame_10.png b/assets/dolphin/external/L3_Hijack_radio_128x64/frame_10.png new file mode 100644 index 0000000000000000000000000000000000000000..1e3890a7bcaa73004aa9f340d1f62736a89900aa GIT binary patch literal 1642 zcmaJ>c~BE)6yGFrNXjutJ*emsY>Sp8yV)F@NGu@w3G8ZcAC+yxx2zylRsd*m-^Lw@&Y<#b~VGIZ(2uy$wT?mOeUgmhx8N{gpA5 zmoGf~_sP^zYm_xlSDc^jp5NR6>%*Bv5%DLg_gK=ynZK&12}ie$^9lX$`eWPXpyI+Y zAaLWubTN=(zP&dBs9ltkaddO{v6y+eJIrg(G?W&hvi3>9(RkOTI5psJe4ZMOW=xHf zR-6|0=QPTC#Cfs)Tg%sXof>#Pw&Jp2WzFeYQP&JE0RP%3=(zi_uw%D%e8wR8_vSBd z)Fd?=LCn7ie(xfnz8vLsk%%eEOlm0Ky`hoy-yYBtO^QxItuX-*AM6oquWJTc!qz_Y zZxh)P4+-Xq`+>{TI+h<5Grdi_QtM+j29Ak4WMMLYq9AqqEhH&25iU1w>C0L@hZ62P z?&zEyU=A0FTiWU}K1mzDXxX_dnVPEwPvfiV3N{{i!W^EvF_7Hlxzzhd(|zh-cw76N z&g50~f5rp?mD49Ixu>6iG1(ZPP=nPG zY7wk;v=(v7SO=A&)wbH!VtgUBv_7bcS_j8bYq7qt;{&Ma28i{CkkumD$D9p57Kn8UL#dar)24H$>v6D0xQVe9G@@)z5G|Me;>I`Ulv4S;Vrx+3{wih|viee=^U{}HJgJKkh z22_|rB|J#Vs5d}r+C@Q90gjk441=U{feEw9Oq3jZ2NGgJ9L0qwE=Gj7LMT??Vrb}r zS${5zRgtMlAM(bYlyCvVI29=B^?C(fLO{FnQCu#UqnHpC3K3QVahEt4vKVo=r-UqM zD7V>Vb22vC0R=6RCfdU&VV3J)5O$|t|H81tJ(MaoX=pL&L~#Lz+U>!}2DIHwCiOp! zS8BVnOPmy%Nx5l{%gk29Iwb^Vv-f&OK}D90Vy?@^mW3?R&}NUFaxglL5@v4%7Mn#O zm55}7SgIx@G8K+%)ha?J(WvC&G_hKw)=DKI8?VBORFqE=Ytp+rpo=b$INh zl`+q1&j~t91t)7_m>p(t(aYUbR^`rI$NA=I%+!kTy}UZGm+$Aa4?oSl!A$~8<$mx< zQ`@0;LGATi?r{fvy3g;Co)uL`^)8=UlZ*34c^ZYZIJ^`pMxT)bQ+yyDCGFzn3RU#z*c;@<;EZF6HIXz43F)!+UA%u-$Ivevh7 z(!qwM4ZcSw>$u~7ujwTEZs zXTWpwE3lE8#EMl27+Y3;i^n9lCIFWdUi>W4_xW1#4`|q;`m4A3BHnC6QTf^v*Q*@` z^ZTatEXHk*ZZ7qhy@F=t?o>1?cTdg}&~&M{r1Grt&uVw`K3()KUGMq3rv4Fmy|Hzk z%^kzCI-tVK^U7*RVmWyc;CO6!@)OY5k0*nLdew9Nm~C6tUn;NMJ2Ga;`WP@Ht}bym zccNAn))sk;)PB0(pD@`<901sb=(cZXj_KqZ+sWSoljE=THQZdZu`BWYc;miSJ!t2= zY4FAFEq~aVaP^t$VMFKSD>~_x3o^d18+-hQzk2k+f@2dZ+ h2=EDM_nzlrrqTS+4*YdC4xoRu@|- z6bdZAeAyXcJ_LooFEXWascjL>NiG!|)KU3e9)O0R`B{Ds%T)<7Y!@m;w*eXM`T>DO z-hh;7Y?#es5}aaQomVKT%V)T{Do)QMS()&BKMf4H1et~Xu4=cB_8X8fyENDb#V7)g zsmN6ZWSmr~tpGMjUIEsra3zOf7_8H)?3jbH3wmrWOkf0#;slColmt!_8XDKY6AuFX zd3gt2XwIGR22KXVDa#%jMQdwoRkfr_@>Zg_Uavq>rsR0FTB*15Y9))?d6wicN>A_z3Mit%u6e49LL$(b z!R?c&0EZ`YCAh&bdBN1|y3+a)n7F8dMT}*1bQElhdoHbnps=M@vyt&%ySM%N;T|}_ zQu}!Hz|OC7hLW69-?{s+*|4>3Xi0zI@uQyjk+9Sy%LS$yT|KNM*f(=ND6>ze*7 zkEJi+fk6qrQ-5{GNj%_~nHH-KEa{5~Bm`2j+eYRFUJOJ8ny7fFWc|rw;n4Z-UxlyR zM(R^Lcb%GIdn2l5-icfLs4%DmnUmNbmA!X~Gb=tk_R#IMLk32{&nB9Thov?OWKZ(isSL!%5BHPmL&{a^h|F)7Knk*g?-ji zt9Wbfn#r#n3~wiIMh-Mhimf;bF)f2f=uP_^9qW8I(px^!DHzqKH5*d;{YNjv69)zi zr7tJ_c&PJ2;=XsYkki)4E!y4rt?^yHmIvql{-&ck^UHR{X?yGaO}W3^)1A*en`XSa z5k4oEcML1ctB_*)r1-&FG0t&q^NKiCZ|VCP&}PH3>~Eu++cN3MnBwGzH~9y9eCfw3 z%MG3DXJ3Tir5hNlBXUZEC#Em@1Z&<~2JgtXlO<5fVBT%+6{ccx^MGl1bSIrO+<3O@ z_3sv5u4!hbB`cgSj0D1PV+T4T*;=!5Q+=KzeY?D;V}B9!aq6idsJb(|Y`P=jXT?zJ uo4&&K1$Xv9KXp)ljW(2N?(WVEOMo7&ed*U;O-k@L0$DBj=JuS5hW`M3kwzi_ literal 0 HcmV?d00001 diff --git a/assets/dolphin/external/L3_Hijack_radio_128x64/frame_13.png b/assets/dolphin/external/L3_Hijack_radio_128x64/frame_13.png new file mode 100644 index 0000000000000000000000000000000000000000..b5e75921a2adc58f63359a7f8ae900a642554c41 GIT binary patch literal 1674 zcmaJ?Yfuwc6yAgh3hHz!2=&on8?4H}W*>Pk1PMuaSVAL)7AsXYn+-%rcG)Zts9;1Y z+R=)Sf>J;nb*MVEbZE<{SVd9PX>BdFSha$tPEmZ&+A3BCx)Edj;kYxq_ug~Qcg}ZS zv+GRh$y0)71OostB{fB#!LJ_vO_&(Ke{W3OXyljaoFR)_MBBI$f~5ehm9|h|s)NX- zGAP1YT6l(v1Au^4c5@b&WlY0K+94r)Iuf^o;n4sPH{Z<=WIn}#7An{7)QImLJ}L(7 zR*m>wxe+lkIx5eeQpQq?%F@kbSw5+@is#3Jac-P9;Gj4HbUO;1F5ImVKe3DRd!HB< zgHKere2sXVRF=^M>S&e%l@b&p5d;C1YKaB0sVtNli2*SLLtzwyQ8|R6I3~wYIr#Ju z^ZrQ2*0- zp|;Ch%203y<)VvNlCOv@(hugd_i{%*MV<}*Hf!h0LKNs}vdBR>xm3MI%-=|?b}Oz_ z$W&6fQYTfYv?yxOX{9QKUaOWT%5^fGL8Sfm6gB~d9vDOCt0qvRMwC{O~D+Yl*#P^c-2 z4}TnQeJ*w5P0CC7Fc?1@TqaWyl#M_jL?uNa(khcdYKv6{5vavVNUexUjakJoPZ9QY z&2wGk7xAs>+di8L{_t$BC?`KmEI%~{W-iT7T%akWlttlhXByXGW{8CCj*Lxk3_G_pBgIIF=67jex_!jtVYqWRc*#yBiQ_r_mX9A7-YozIq zQ|ZD5)5`2E!*_0uTm%%87FGt>gHP3OIlUej=)EFbyX$+Ar@ZIE98P*3s9(7#FzE5j zneg4!?`S*Cx?4y74QkG;+#lWAH(e&%U^2JWP8JT|q@(UP?gX3>doixO;*CsN@=MW-Ov9`ecR@>IaCaOVrc}?xd z8IKa`zZ19be_-4E@~r6A zqfqkuy*F5{wjem>J#T2jk-T44pO}$S+7hw64(P=<9}FA#sVpQ1tyYhftZ0r8hj#26 ziTbto*l*$vVgIatfoOTr{$fH4*(HdZ7t|!|ALzaq3n(*c+Cg39wty86 u$*<)%Dl+4PTQ7zsk1j)8yGCy%dj!BxNXV-0K%n0DcStp)>klO6RQ?BP`e-fy literal 0 HcmV?d00001 diff --git a/assets/dolphin/external/L3_Hijack_radio_128x64/frame_2.png b/assets/dolphin/external/L3_Hijack_radio_128x64/frame_2.png new file mode 100644 index 0000000000000000000000000000000000000000..6a239a1b69fc34ee2487214ce05396be87d8a1a9 GIT binary patch literal 1615 zcmaJ>c~BEq7=I9M>R`cXr82k#q+ZGHW^-;6CFIbcfiy+@lBZDf! zVx4%1RI$~D7&x9qR8m|*V;F|0G*Ty4s&=v(Y$77VWH^e;P+TFA;iODK;tJ%+BZmHX zrj)cB%}>0+lTPdw1V4$QRaI5eDniQfE)>^jG$3t>d`Q?L<>V>^ofvW*3c~BRTAv#B1)ih|CJhZzeiWBtsMi~gY*0HO*xCPSJXbs5 zsP?m{oegjmJPj*SnjHbd?7i4gSP`-zi+B$#3sq+1=n60E6D&rZ7~V)34@0Vyay6k) z83?6XkK-nTo=_`|dW|AqVUQb4DrLmR^RPHBlPffGEFae^!&tSEkQq!kh7)EPZd9ux zSc@+pP(GTC`1L@)Ls-K6LM&5ms-y2q!MiHr-(w7#M)tnV+3s20*mkV$?f=J-@F%)9^X+ zlJV%kz>Xc`)AQU>wIA{2jWOmym4#O-Agx9iMKn&mM{E{dd&m*wIIF%ZD{zt{-2QndkG1@^V8dNToWtBn<)Xxz}Pt9@EXMv4CEf zYTK3g&EK{6zyEdnxSkT!rM~{I4s;Z5oo~>BUhVCkHQ(k%PmFCbr{vZ}g&g9F^tDI! zr-lyW=XMR>*l&2WbJ3WBgjp$XT0N_h?lz_Ax5wqpKN#D*Z8s6>`$`&rd5rmkd#6&{ zHKCqS1xc;via#qYL{w zkoNa{ale^oEX-0}u+{vrIpM+9x)op7@3^r1PR2%UXMaVCNH{D&7?n`R$6sQq*^c>nPVQDe%4C0(tV$bqbV$LAdArm}m; zb#&I=D~EpirFMBvM)dFnMAE&ti1;r6J*7eUYJ0pAG~gY7{%}XsKX2`(w&oN|#>)Ly zuK4$@4unLRy@|)VM&7y~T{b3u1KH?mxrJoJlsv>L<4dw*`VvxS#@q(onX@`u=5?Rl n0?r)x_`yKk997%q{+N+qtUT?VEs4uUhJW!EQ=xHBeo5VbJq$&j literal 0 HcmV?d00001 diff --git a/assets/dolphin/external/L3_Hijack_radio_128x64/frame_3.png b/assets/dolphin/external/L3_Hijack_radio_128x64/frame_3.png new file mode 100644 index 0000000000000000000000000000000000000000..8cec74395ec549931d1436a739d5ed4f7aaebe3f GIT binary patch literal 1622 zcmaJ>c}x^n7=N%(EtaD-Eoj6{M@vARopaB+bzyfAD67kI6wfldGr$&hXPF(!f{H6% zsHsP58m}4}D^+U$IMX6Ganv@u&VoBFFrY-Ttm<0Zt#mpEKH)Zf;QA`VW6 zexxuHX19Sab!60td~VH>JbO)EO&XdUL87aR}1$+F^(eR zDpHvaogh_cwjc&UL0(Uxtk&SD6BrE?vjhAYB z@~YiDZsk2frD%s0DV`Go!|c7W3&N(=(O3A2c zg~~uH)u|+DGNjUKr7=~bNK+UXgGr?f*?1Y2Bq>IrVVE>BRT;#pjWlI2kpxMnQ>0O? z3Sl!{9*K3?`H)`+^gD^AUy0QkM4pudF;5W6Lp@+A6(qq^D!37fmJ>*_nYBAyK}kxm zLK6WSdC~DH&!vlk6B$pj*6|VwHk!55c9O<;m72g9UO{23l4LPOF+szFQp58w{0Thw zLh2@(6iQ$i?hqR-!>C!lm?bbmO%s@%V;D?h;~0!3Z5&H;gjz#!C=My&!LE6si$WsU zn!)Y!sep&)bH%&hFo|$#&h{kif)n?eB|Fa)2n66Zzw>G>0O89rjj4Iwo1^=0iCsvX z;b$f`&wSrb_tG{_) ztDfzT2VEoWRajHT1GlUpJ8&@P5mMB8C4B84Sr>0*#btYE59J zWuWn3FM6giE!MKPImYtcmOJ(qKs`0nFmUUO6IfaA|1^S)*9y}lJ#TK+4FAg*6qIyU(W3sZW~m9J&TJIMYVqMCRu*p z;h#rcCH}s!`n4xg4z%AJ*^!eVuI%hc&K`;d8IQZe4hi!sS6+*XJB>YDf0|j;mVV|3 ztf#K&_=0o!MX8%s0hBs&_nAs@Wy<~d&mS#+`1TF3Z}e+_U}vmv)teX3H@6;nlJNc- z<><;DvSUM3cf`QCgr}Fo%S|#Y@iskBJ3S_xSd-8uYaR%1kL)do=mD2!7wnMzern#X n@ND^x`2jrPT+Y*xrM@tbv~K!w`oXN+;GaIzw8YqyR#f*NKJQSk literal 0 HcmV?d00001 diff --git a/assets/dolphin/external/L3_Hijack_radio_128x64/frame_4.png b/assets/dolphin/external/L3_Hijack_radio_128x64/frame_4.png new file mode 100644 index 0000000000000000000000000000000000000000..d034b0a533f7961426d579bb00213ed0803e56a3 GIT binary patch literal 1667 zcmaJ?eM}Q)7{Ai2Ac&%D*?_s+3aC@B_tmef6e%r?B1J4!*mTPE?g|C2*R_XKK&@tg z1f32+qx+Ef$y87`(M?79n5HIX8i&gim5r%$5e2syoyyo1sPhlAOYYwHectEyJiq5F zSCf_bZg^;PC;$NA#x#RjSiQoV6e1SBw?a0Uge8hk$>p;-8(&Jg7(hpJRt7Y(WIkhN zNP78)=a>Wl5U;jda`{|ShKAx;8R^%Nd03}_27rV)9w$i^F+6Bx^6d_-bl}8kDQKs) z(j0{eF*)^2fjzCv#blRdTBx!jilC))62SzIMlirKJPCT(VuxGf(Mm_`YJ|OC3`@Zg z6~0I-9VL}($^!MAivd+K6rvCW0ab*|irCavhCpV47=ocNiovJ?!cYyS(4Y!%?2!uo zT(nJNHl&Vu6HZ!b0na-%FkD(%Dl5fhoGTwj34(wT48|}>(16^_9X#oQ9PZeF1q0)z zTy`gK=NzElB5CDHc&$|6IvND)G?|_ocDTn3)%aBM}9?tjb@(9E|i5VHgHr4%Q$$WK`Rw*WVD^usFZRw zu2AW5rCNugDS92QRvL7KB3YrA>r+(9fQ^@7F~p!&DpaauRHyV~)dn2Xr=SRmr(&o< ztqNd`4mVFaC???7F8Ce8D*qR&(YqLu=Uf(!D-QHPRsqLz?gGvUVz>+er<+L1?(j?A z@mFXxU<2c_FJtIb7srAlDc0CuLcxlY6i%Ty#HiE=Bxe*DL@H4dQrHk&I4B8*5yBtE z(=ViMv`Gbt5Qa0rMkAN2NybJZ5TeErh@$0kh_KRfh(xV4iPMOhz-TEfP=x(m^FkK| zL_%x&x6h|SI6R*##vu%oOPHFrWA&ZF#7VL;EGfgo!@_n!=MO6ZAgIb{&{;fJ`?vNu zx{&eubHl^Gi&!@M_1?NS%8h8=y=}SE>M~|TJ-z^+1mO0t!65%~TD-Wt89HAX>5Z*< zDyyxG9Dlnk2nio&cl6ab(e~iSyY}90y(wPrt1=Me z-F)KIJRPHv3=U0@pQ-NMq?Tm$b+JKVjbWbw7bQLsU70Vkih1Db_NXIKHE?lnf=svM7qZByV+99{hu6yW-o>vT*v%9|(F^A@h z95CaF^$3P(MdCP z+tya>Tkl(2o>h+gO^80y)+@DcFchHHs8`PI6}%;V;wbk+5i zB@2Kz{?c?&z)XszU zxNn)f`O$j;!_?Hz?+!dnYMR}AY@+CFO&kSZtbZtNw}w+g2k#`UTzaG;hZ(42CoX0? zCjq|!6KQao?|v=%PjSAnS0V;FW1M^AJ)z#V>ccsJtRDOrY@5o_$s(u&hZ_0tW3nqy=O4yP?%wx(-skr`zvnBr zLz})RJTy8K01&QDQ)aTOn|+f*IPAAOC@r4EH)MmKw^^1Mj8qz2GUcxW~+?bf3BGenT;~; z3V{aI*c4QrIc>e2TDCr2XINigkQlj13!y}plr>3at*QOU50wD`odSF~WsL zRhR-9cZ^iFMhhuuI|Ye&7;HdM6cR~zdekJ=QxY@*!ciPUFdV@IFpf!affN%!;}4hh zXE&Opnab30Z|q6N&0`pw6hWL$C(lXnXnQV#NhA^k#St8bSq<1xWMxPfY<0x>Ehs66 z!EUxOX4(q*ERuS9EhFQyT*rd2*fg3~hOLhARIy1zT%--bcqn4A_#zwCb}*UL|1{pH z?a&q3C?u0|&};1mwj!oDKbXzl+a387SvJxPyO}KuS*WB9Yb}(OQ7dI!_J(IP8>J#4 zUrY!@3PLEBW0*=IC&WUfTp~yjDEJDMNa(lmCM=FB#X^B7B?XfUeOR%Qz!fSC#fVfK zQ;J1?tlH{eNUMSJ`!%zE$FcIaVxs+_` zDn7PeKqo6MJ^$3>ZM#`DomTI9d2HU!w#eSCd*kN>jXa%*c*7nBo(I0AAN*E)V|q`^ zB=5AYrpx-S2_YdJJ&IMKW4a81FloYK~9 zN(tHPlr-(H#A7(a#lZ*e{MfIa$(i@4OSmcMYEU}J3%CPLwbX-?Kng57>Osiz*|ia1 z%kbjlKQ#}}PuW=e)4{5nm6lxBA3F)a|L}49R1v_t+lL!*t^0)XdLJ2;ykO6U_pdjd zEO+a+uDli7w4kOja!$}Wg|4^Z>#%1B;u?Yzz~7SnU}Hf^eD&a!sxVDPA!vT^ApftS zvf|K3&mUWIYj^{BB;n4S6uo4y=qX1~5nZj(eFwB1GWXn&g*;tol6gnbt>AkBb-_8y zuAW?g#>DEwOggAGpdkF4;~%ZQ(tc33=d^n=)EQKK)YE$@Ay}*0xK5kDKjzxfvcTkU zGIf4OeNRKiTc-)`0pMot`vL?9uxE!OeV5skigl zvk3XN;>M2ftkbimwcYrt;psmOo;A*hYljaeA@J`<{qu^&G1F`l^P}1h#NLgZo7xrqa)SFw#!T-(L;DY5twia?cQ5o8Uc7sCJFm3+ zW_3aIl68W*D(_TxYg@JB-;&k0Pto}~lhNsWcb!hIC`UL6J!sF!&M9|>RF|DugS@lz zZO20vfkT|c%H;IjoihwCR_3Z3M>bVF+A!4DQQx&D@`DLE{bXO1J1l;CTv~0Vc;cC% uI#1M-;;ei+yNlsmv>4MWm{doe}h_;uKYeFXY+ptN^hnB literal 0 HcmV?d00001 diff --git a/assets/dolphin/external/L3_Hijack_radio_128x64/frame_6.png b/assets/dolphin/external/L3_Hijack_radio_128x64/frame_6.png new file mode 100644 index 0000000000000000000000000000000000000000..db53a0bb41fea9c0862ba15807136063f3844e20 GIT binary patch literal 1609 zcmaJ>Yfuwc6y5;gA)w_^5p|q3T8oa!zVg^)2oSQN#1b1ZC}In4vKxpYyK%FafZ7IH ztBh@ZRIP1guv+m^>BEXfZGE;QGPI?F*1^$XsQhrs)OJd1%UIJJFxDTAJF|Q5J@jxQ@d7ji<>m*xw8PDcu$`@TaeCR^(`RL{ zi_y!Lsw}9*Yh-I&#SH?xxM88q(cpGy8CiZFoEy*q10GhS;ee->^XUS5*_d4&*hj>O z3?5Sv-Fn$Lsd9@IHu3@sYZRE=fubm^(JJhyleDv1bUuuuIEG+2f~n*7C~_Y$K^mn?yKiSIw0qKv!WI# z*5?phUeU#KaKs{Q=j%kh3~(I}!sE4A9vS9*4^st_h6HFYf+*MPL2dId1Rul}f_jE@QMZiY)lHdYmp=&ALQRiVf(M;)O;6}l?7@bC~ zBng$qNT^8zhM9~8f>cumt*TIER2oehb=1a_u!I3EEFuc=Ld>9!U`dL=jV27mh$0-L zNKF)L=6oW}IoPOQ7x0Ut6scBeOi#t?i~>uGykO(`+Gr10Yj~0O)$m>zCln~0W1$@` zE+Uy5snB@96f3w^vrLh|d*HDY>s(KuU?*q?;lKzvt07Ujl2zeyT8+_il@levL9Jz3 z5dJuxc`S9~O$sC+3~!W;PN^hm)=8sslq68OgHbBwT05hZ)0my12?iy#I3q&FXJe0iEyNP5Bwi}y zE}yNi?y8rdDX-n^2<_c>F)5h-AZyWWcm=s7X6@Yt-+0pFB==(14jno*S>Ll!EZ&~n zcI(dHOPadGl!4Jy+vN={?~?J>!HXp^sc-@*fs^6*XJ!pcf0On|YK*(3LAPn}h6Kv0 zO7A(9^w+({U%1-dOpoMg?LNbDUm1RI?R(GlWzte^cXk{-vK}oc86c;r`XCYG3QnCBXMPyNweQLUS(|%DQ%6 zIl_JEAA*jxH=oHqGxY1Gt=YnSx+jN}7W6+qaYbHx-|Dm+bU|Z&^}IZO+K*R`PS2>b zT;29z%;jrj9K6@rcQX9#)KEewYuiXi!H#RDATx2@gQcSdUm*+b9v)FF`{~@uv|AEy z%IAj0U2uQa&ks&lzS!p8bMo~ya~fLTcpDnlzx9fwytuKdX~Y?K3Ho8ik`rca)sE$o lZM}n?Vd*~3mcK4;3Y0#WaUi*Sv^(;1H=7nxpBAoY`VZU3L#_Y- literal 0 HcmV?d00001 diff --git a/assets/dolphin/external/L3_Hijack_radio_128x64/frame_7.png b/assets/dolphin/external/L3_Hijack_radio_128x64/frame_7.png new file mode 100644 index 0000000000000000000000000000000000000000..f2015a77d1776b3a6bf21928ba8b0df916b7b0dd GIT binary patch literal 1755 zcmaJ?c~BEq7=Iz+5kM&(94anR@l3LtJCOh(2Sy2`973@wo9qG+k`2ky1PUeMID^{a zMXU9uI98puibvI2QH!lmsMdN>)HEPe3tDSO5Gys^2w4Ac+?n0?-uJ%W_x-+WcC{`s zK7bL%000DN<|~t_)k(dvBk9z)bL2WLwS$P8_Q)IgZns8@&WFj*)x08udx3u?&2Nl1_97|k-~!&7INkP(wH(*;^s zYf<32#`(ooJf%1>)li&gkYLQ1Xei1dr3{#G5``S5e6vmJkTGA_l~Q}Jn8So#sE~Ow z<^ZV-tqxKURvZ$s5tadlVMrul>)~v%9+$v#Auh~CI0%=62v}T1$`wcv0W|n9DSuWh zTbis?4|=0cGG;DGTBIC~-EL>wd2GU(!$Bkx2?yqKxLg*c!Lk*ZNz}nI+old#P~tX& z)o3A&gcz8`%qO8<~v%Pvf=P zw$vgE&Pm2?M4{C{RU~`r5SYr|n;m%-DK^q1tC1=Tny(}bg(logYLqf2b;HJtm{cU> zi+KW(f+rNq5k#es^Ta}>Tq1}QDEJDMNH}EUby%Jpj#KmEgmH*m=*5baJg!28zz9#x zMU-OE5LRQhk*L{#5BW7xeh0CFH)5p6i;oMqEL4b~EI~HRqYgp| zj#J?e;IUUyH_)V%gbKql#74^Ji%~oqg;}te2eS+qpU;x$F+K}L^cc#+V6lXYF*y`P zj<;)G>7pSK)tcVz%c-CaFXsw3Q^RDXriPPtY$Y{u!*vO%Dv!rQZPUKH@&N!oE{#&2 z>S%4wSZk(7_#g3jJ{K8fmhf12YxeI8i($*{A4+6tW@1=x^pIx1h-L|T}6b*Hi z`fVb120HP+GfSE#(!*V}vz(GuWvZ%4d;YH5;e*NOLB~_pSIc~V7LDy4^L5{ezSww7 z(O!&p$6w!d;mJ6Df}I8}doX_2ZcTKFwp|PKjDvj^RTgb#`8;4XWzagnuyYc?zO#5( zv)|JYFb4!?Zs@lkWGsI)o_2bh``@MDOWjA?`dr5v7N3UbPS@%v!TA8N@+9krDUGqT z{OOz#!J`?nhn89TKA6M`R(R>-Nd}om6f2tBaF~g z2GX`jl8yHy{GYCb?H&Op$N13q#(eYr!6gw1$G6UfYO~bCtpP39vnIejtbm&f&ixwE zx~1yz_AeME)xG?+&6DOt`-aQg6?dWox4&~wxICw+x+gQxn5!_if+YTyb+y!g!g6_&($Fd80Uf)|; ZpmuW5!+&}%Zub6eG^#}9S8-Y8{{f+jhG_r* literal 0 HcmV?d00001 diff --git a/assets/dolphin/external/L3_Hijack_radio_128x64/frame_8.png b/assets/dolphin/external/L3_Hijack_radio_128x64/frame_8.png new file mode 100644 index 0000000000000000000000000000000000000000..39b8d5f8f57d1bdc48e5c4a35ccd6ff8c51e67a2 GIT binary patch literal 1754 zcmaJ?Yfuwc6utohh$4)rJk=%QtGdZ!>Zh+Bzs|aj+v$?SNusDubw?SP`{QrCO_imTm;BKOA>v_uhN%`Of*yYqnII zu+ZBp$O{1At&UUa*tLLtqdZ;N?>)~g8g>a}Vp5rf zsz!1?0Ir2pQYw?GiN_7JiBC9n_zshWMFTKD(qSPC*(3w$$qdRI!FybDjt5c32wsX< zgJ>*DGLwqSvyw~m5|Rvg*#^0h7r6kM@4#6DCXyi_hiRqRhC3p7ukGUO-YFLFpw}u) zb_8#jRH{Y`DQPPSN%<&jKoA6y%K3UEU8X1H$UI1h2vGql6rf^Qh~h#qj*6j?hsXM} z8q;x|Dt5#hdy3#?GK>Wm2<&z{-;VKVYlZ-o%jE(@C=d!^Rs*)>ni;|Yn{CraEvQJF z!Ae;eiZ(+|i-exeVIp`e*Wn;c7LDeOVY6){Rcz7(4#FZp`G~+|az^%A+s5d~|7pBa z+m@7TAq6_pM(0=!Y(>(ikAm6kz2A{jk!6D?S}C?H#7Y%y$T5*-My-nAu{V4pWyGZt zkqi?{m6$}PK+zbb0+UHp3b{C1tQ09@q>@n^@4{jVBsvz0Rz#x;i4!YRVM1jLilA7m z5LL;fqgb`s#t>!$IqH{U{f=Pe@5SOuD@ic4HHoHIj`n~ylV)gJCT)R)7$1RVYX}2n zc1q?rD>NLiinLOzNn@;)HbJjbj8pHRpvMRUWD<1V3ij}3u1GUGOjdSkJh&wt?8Lci*9v^w9vv+Lz*@b40kAK1A+ccb9uG_dci?=%m`qAiIPFV?$R{wxnJ_mh4!QF^d@ zTzX6K+=Kwif8ndLaIeUA*JiZllb>G>)|`ikYCo6K$7s{z`ziN&SJ#Z4Q1l!ObPo8n z_1^9Cz_*D@@0L{f7k33GiA!@IgUHRBYQ= zU#=GX9lDnr6&Lfw6b!UCQd|bIHoQ93`AoEcs&7iUoEDtLDFF|5HPn<;bG9Cvh7Il* zH*v)rUpTLv+q|eNp=h}@*=1`UC;q@IiQB>`ZtBDX0Ul@9IxZi-dB`Iw+&-pur^EnW zT}-Q>vh*HX%Mavu%P#&f6BM-cXsD{Xu250KAGcgH3w}-RE^S@T>*?5*Q;;;&8miu; z1tC|0c8BzLJ&GEf)E^SI3_~MNy9G@t)Nd)iVQypKeG|OCuT1o{ zZ4QPmmHPS&+Eb-#KmdFwFy^b9H8vFpCfhm}`CNQZDDl)**JeZ~bUj-#weR!ro11Em z`WM%I4I(&O)3~Q|Gp_Ib_%K&JDeKGQk=s7p-971vUVJiJ=sv@s?Y?BrA#%nq-MePp z-k{TulCObpr=H1exC3VKLJsQ;i>`H){UZmJr1x(3HHx0=d(??F`bgP#Pin`2hxU-# zf!wPvWp@g3x4(A(wjlRtUAt>lc-WD(KgyR~;ov^;2Y<=m;@Q8hIdgnjkmssvDXq#g ztNYGxF}Ap9Qg?#wnN9ci9X)q$!iI<2C!{ncyDsMKaqA4|JmG;r4Xqc7!e*?PIkxWE zi^=;>EpEKkHyggqEok93^?sVjnYXdI_e?S8AmgxA;n#~V^cQ!ffvSxs>dRf)UaT)n f*xYFBn_dfC1Nuh{S(fwqjR literal 0 HcmV?d00001 diff --git a/assets/dolphin/external/L3_Hijack_radio_128x64/frame_9.png b/assets/dolphin/external/L3_Hijack_radio_128x64/frame_9.png new file mode 100644 index 0000000000000000000000000000000000000000..8b5e6f5ee7d9cc21490a0b7f4a481114ffd1a64f GIT binary patch literal 1706 zcmaJ?c~BE)6yFd)4kJ?z5wvAls^Hipd*m(=LJ}2fAOk_8RhrFa0|Ana$pV1_2HF7` zoffUOo*iU77(3Wj#nPc_O07qsD&kbdqqX&_Rnbxvsx;jIvHinwcXq$;d;5Ox{oXa( zq|Khs35yQ{0DzOZK$Xj^Zsti3VKeU=As=d(C5~3>={(9zSKtm3P?#tq31(XHLNb@c zO_eK7lBoc|uCwU$v|h7NMo?BB?$hD9tab(s0I6v%J5H34G-xCXEjBqc*mVQ~Ehag% zSg3(Db|qP4Sy1I5^Qy9SL{$kPH9=`}!Bm%wF<>QW9CTSrZBCg>4vpEBF?*kw4}oJU zbcq}qC#BbDK_%rNK`{^E5-<#dVkyrEnY1~GTe!mvR?*vxxQmjnrAaR;<=qRex-vinril&@JlpRDd9t@^vaKd8q zNoM;hG#;>ubXdws(>w=d1;v%G+U5yJ_LKrk*TmcU#ADMY!r2*J5RGmJ3@k(4Bv z@W=6{|D|rcNf`+fhTYFbCJ;z)(u~7gSc1V^!XyxIrACv0iz7x8j+tPI6g5G7h9ckB zHUH}(zldo~-}d=bFo)-JMcSBQaxhb~wJ)-QnYdu>LY>;{^)lQ1?*3W;2x!k#DRi!Z zyZY6(-{8qfUhnRR3&t%~!%HSjo5E=@T9>Zgm6A2(Ht&mfar@wKch!1vcj0HPLpQe# zPw%N^JqZ8BcSiu8l_xzHI}XCJwe|}}gmYxzhsnKV0WingRWhP(Y!n0QALOV`D(bHl zhYi?5n=Yj+2q*~DLeF6Bx2e@FiS^SfKTRkdCA(5C2_MRXV)~Z@(G5*mS~c*_N1dFO z;%|;N&It%lkL?Uh{{#y-!8#FE!BVkk;K0nQL2iTk&-+0@;$f&|a8~CZ?6$6lyJm}u zF2(JAdqpttV^gZ|=p+EWd3IPHm*Q?$ox6+2xXYm@NLvk&%$gmZKaf~kmK~J1@p<_&Dbl zeDCX#p|kr&EoBkz&F$^V?AU3m?5$b%zM}iB;H9`Q^I7B2R(fA%J6mVds6mOLh4w)yQfdTuiq2TRswg_`{QTi*YzCk^Gx$> zoR1dQp~(qseJ|eYZHl;ltMx|S2Kmgz!5^qsg#xEo%M9TB=54E!XU+7qy}EpEZ=Rvp zru(UylRk*w4RzNfJV-j8uHDMk$0S}pGsU^+_dA=;1Fq@7U!4c_QxoJ#8UGxO#Ke2N bqfrLn%e<(hX6udDe1DHjb+&46hN1pnA>wj5 literal 0 HcmV?d00001 diff --git a/assets/dolphin/external/L3_Hijack_radio_128x64/meta.txt b/assets/dolphin/external/L3_Hijack_radio_128x64/meta.txt new file mode 100644 index 00000000000..1d415b4b85e --- /dev/null +++ b/assets/dolphin/external/L3_Hijack_radio_128x64/meta.txt @@ -0,0 +1,14 @@ +Filetype: Flipper Animation +Version: 1 + +Width: 128 +Height: 64 +Passive frames: 8 +Active frames: 8 +Frames order: 0 1 2 3 4 5 4 6 7 8 9 10 11 12 11 13 +Active cycles: 1 +Frame rate: 2 +Duration: 3600 +Active cooldown: 7 + +Bubble slots: 0 diff --git a/assets/dolphin/external/L3_Lab_research_128x54/frame_0.png b/assets/dolphin/external/L3_Lab_research_128x54/frame_0.png new file mode 100644 index 0000000000000000000000000000000000000000..c85bb77c410abb3e8b29008bfe585c29516f726c GIT binary patch literal 1687 zcmaJ?c~BE)6yFf#QVy+C3kAC_T1)9>&m5Z)t|Va82oo|&FJ+T#AVRVsSx8{&7`y{g zV{093hbbP|p;pv-pry)Dt#kzKF;cZ+si5^}6^m9YI&_1?`iJAr?0(<(zW00Y_pVuQ z&it&1@Yrww03tNARXTq4@UJ9P$bV%{dIP`2aOylRmo;-P+Q9(nCf2}!8Y^AE=os2m zUh+MY3;@Da7JVL74ROJoLIA|5)u#_>TOb2TPN7F2~Jc|M@Wf-YU24g0YfJq5S!W4zmFo7DxVgp9Hls8#y5+2(uU?V5y9h!Wc%HVTxu@SWKFv7-cq_#4;m<@Dve$=RDO( z0TJJx{_T^=;15q`i?Q(o<=`i$zoY7Xe(HjA=IPb^Ix;fSaPG5S00`QoQKjqM=a1Fa z*ovl4T+uz;dgn|}ho((ZS@!kE60J4s=tr_;^?xmPkE~rE9@6>C>9Dg$W0wGrx&||a z2ea=5dt3WoX z;1(H6u%Whb(YdnwXR7yuJhY{!du1fJskWi>I<>01uHyBSak6`9-llTkVLWii z@pD(o>YStbASehJDQMWBI&hu(p z)7o9YRw`rHfg?S?f3Z5&^A_aTeRH2e)b&C{=Bjh6uSFTHl`VQuFqzRaK8j>y?C^p}E@czEb`MtoyOWl#*qb zmUlHs*)!Y_z0J2Fz4*4Iq%mjs=0r1_u}r@!L;6lsPWalljpkF%be>JV3@wEXBjW~>5rCO@od_Cc+R(uyc^UF zuW*JZd1-Vf5=Yfv5|p`Y_w56~__XA`=B@VA8-(Xm1;N0DswtNeRl42&Uxh|JU)7Y6 Gzx+Q_EN*xJ literal 0 HcmV?d00001 diff --git a/assets/dolphin/external/L3_Lab_research_128x54/frame_1.png b/assets/dolphin/external/L3_Lab_research_128x54/frame_1.png new file mode 100644 index 0000000000000000000000000000000000000000..dedff602416aedff47635b5ad14871cab7575e36 GIT binary patch literal 1700 zcmaJ?Yfuwc6y6XJ1#!etB+B5rFg`kNvb)KWWKHCe1kFH@hB%;A>n7QR6!Yk2g#=`b z)-u9?fP=+4R7HHXwkV?&)T*&ywboJ}?NlrxRkYNKT3bMKID%-LopQbYM({zUX9D~#d#V-P7E`l{+r5F-)S=ZW}gi8*M*d^G#Pb`4I z5fvs!4vmt^(xih5J57ONJ_;KU1OdfTz8*12^pq4?0AdJ+3Q$ad;xL917*3!#IQBrS zKiX&_w94c$Z|q49WiyO}5D4<}^7wf|zMVD;P^nZZKrjJ@!K?=CblVux1>2l4ehW&< zX`n3*#$vaDK8vK@zK)SYEZ5N>tPYLlm0_E6ELCjM1TNAcK>3KkYV}1nqU~g~)PFSI zsO{9b9h5*zIqmCc16vVOj33Nq@Bbb76j?UJQrg0ng3drA@+uEv=|AA z2sao-aR^MAgc4XJ5}ROBZ<4}sdZQE|@9lOb&e%J194`X0lI{ufIqXo_U)w9al{>+gf~Y&&CjX4@SgCgfw_ zJPm2E*nE=tzAB9dt)ys6E@e!n?N)Fk&4lF*6yh*3MTsR67&VH7uqaL>f~8W7goTJ6 z$MvX)m5QJ-yz#a4jW#MPVZ(6v*$_fpC^X@y5Ee^BVi-k5CRj>R2#kx2VpM7}8F7gL z60j5nzRr2All&sKJ$>6(lffQd%@$>22a0AVXSO^3EIW1M(o=ORb{!rb-ru(SHUI?F zsg;R3*R7Tv#kK%+qVnSK@Qq~`ih9v|lF%uKR6U#SPB*U)I7=TLvZl7n83x8?peLXS7P>oQ2lr``VdY!hw>HlQemJ%~>aZ-Wr1Hz?rbjzd&mAdA zEjbhOd|#9qXe&Kw{e1KJl}l%Ao9$gu#RVgd>!KRq$mSxWA-+%rFq)qFxjJAG_k3pm zyCALmhPmjIg_)}c_#V6Gq4MnB2=l4~w|N6ofonkt^Ou*+o6MPbQM&&U!Zj9OI+@?w=UTHXJK^S? zfWHIj73Hf!^szOZtb)3hTeXh>bCh}(RHU_R>>ZDvTHk);BoTc%+*7+ayL}24F{e+_ z$g8e__SKYPig=Ezu_NZMKV#|Uq~J)bqgq*-s3aN&erefO+xHXiO2<~v)U@|Z1=RR* z!W|^{LHGw#o+qet11oF|34>J+`re)ttnj?kzeST6{!FrS;ES62*6@Uh`)*Wz%Dr0n z5O${z@0NN!2in59Gn4MeR4)vkQ~}Vv;*Br9uH?>%UX%A**sQHldw?x---`|DkCJ+a b0waM78B>4O7C#yE{WsLAG-Z9#noa)#m>PJ? literal 0 HcmV?d00001 diff --git a/assets/dolphin/external/L3_Lab_research_128x54/frame_10.png b/assets/dolphin/external/L3_Lab_research_128x54/frame_10.png new file mode 100644 index 0000000000000000000000000000000000000000..1a53ab75d5114b56cfad205e3bca9502735a84b2 GIT binary patch literal 1640 zcmaJ>Yfuwc6uu-V%A zWND_f=p>r}fV9G4$riFrv$ZzfDWm;5GOyDmq5()q^tx!ZZ@kd!(uC2Y9kpqaVC`D)rtn3tUyCvXCdd&dUf!iU9GtHi%}RF zR1ucy;2~1kCNpH<-7KV*;fM{xFi1_xte9P6Wl1a^l4Eil#pNijMC7iYM5m5v2lyU;?ML5r-fCY;6 z*xU}6;NUsPZ;`h0#exnNxef*4beT-g40E30REbGLy|fF(Wf7gG z?Xi@)STvLM@WpPMSP}cA09ef4|2y(4ifpuRyB%U#=t7FO6+2l@Fj6{Lypb^uMynx| zHil4P2y0hp5Q0$K5!z}e5tWr8l?037G)4#Pyavxw7|P9JYN{-19Jf{@SXzR1<4gMIW)~g z+Z>!<@}|E^LqSul+p&ygQr)~08ceg+@d64exte9w8V!OogaRQ{1c8vGoJJIwRjIV% zgeWE8VLbC(`i2@+l!#%t0&KJjr9xp>;tE8qA=C(t6Ly58SqxDUj2b8Hc1EeO!Kg?P z^>@y5ofHs>?djh>n+);rY_?cV94NOqIaM{kYs9G=X`XFK5!Zo%f%*%zmjICD8>wWA zxBKX(Fm5dtPW||>MVK2jaoGU4G?Bx@`2Aw5pz|b-M7F*88U& zt-c5SAML8u+MFp-fHXm5`Kx|PYGu8udR?Kb?mQ!>;2c*V=kIq9kMrn|np@ye=ME4C4{ zvcu!aC5hv&gUc(D&)G6MQ<7mxZ1JWoJ!1{wzA5j=JE!0GNu!IpTPJ6HxMTW~Bb!~S zV`PqRE_pD*JpV*67&i|xg)GdKovm1Ps^X|*a%4+LQqDOlh$^3!{!K}!>-9U0=Q}HB zfMea?MPa87#jUxk$NPU?2p%rD_|6{aR$PChwZ3wFQ^V;4sr82|t8-KDpmE&wUBOq7 z+;ul)jlZ0GGA5`n&ewTUedh488c9-jLDQHZ{n?8BZS7OW_xD|j%Hy}3m?@3!4{o?r zwes;H@NRt9BV*WxUEt%ki57*mDRU)X7xQ%+jZTy_H=~R(2HuD4@NFWYYP|mpI^H?w8?(At37(}XJHdQxz==M zafr9KDJE&(Td}8a8GPAwqX%rht5smb*3QfKwoAT9YwYa_0SR-SzHzJyNCAC)EL1si R?>+y&-(K0fJPPvp~e)V2Yp# zGHg}ZS(pfb{|0-WSu`87bym)SFNE{$fv_%dsejobE}uU8PcNs4j1I%)3};|gS4 zMJ!2DOpr1gbC7gSfQT9+Q7b_Zh+2zT2%E+NwM0CkB$OmhDsfVUDoLGEr6X0y~u}0N=h2;W_X;$2;AZDMmDbP5>4=b8qd^r zK;MT5Urai%p9rSXix!h6KqFjL*)q@MOB4N}$r{G%{5~k{Rh5J*7;~APJJn zRFZm)+J`kbT_WSOLZ5HD7a${YLLSGJ`uZTJm=ifyF~=iH3R5BrjEvRp z^h)BqRhkG|4+VP#WHSZMfsChFXMYBT1f?26wMK)IEKQ+w0!^b@t&%}0!lF`HNLrH8 zib*{CRQe_wRgy?y@IE#=N<~pN6-l9L4Xs8=lD45*1`?=>X4RzDW@A+vs{)rO;@-}A zs*`*osXe{hCzBx^p3D|>N&_WGlXLg*>QAJpljmgTWk~DT*x11@Gt2F3S^W6QN zyEhB#iQs_zu`$oy5B*BtXrW?Yaer5E!9Z1;xo-GhgEKHRtL2yZm*#Gi^NFq#g_nkg zK-J#5x;0|mp#VN!75_-CLBnfuKycY zBX0&T{%LEOEo$$QUqfS36|&AnJ&|YDhtKkp87k&nyNz#a!YlM~&9U$0TY@|R``!uM zKGeIi4Dey%TRYKn!UpH|v%iNS3k@{@;0I?9@x#OLtu9^hBAmx9*o;k57BuGdg+`#13q3T6QFH!2CrBe=YjhVp6-PQ zj$N+pySwhZ%-NJ&H1Fh?yxAz9cIaW|oX`JeFGm<>Hx)!D_8n}S(w(0^dY&IFZYdrT8|9RIc8cqjabqM7l@+zcX4jp75Hi!Nd^O+X1I;%2%lQ0E`UOYVNZ-}m?Ze7~RX z>(=Kj&Weei9t{A9$;sB`ORHacm62i6SLNltla^_s-Xs zJZG(0)y<~^5VpoqXcA4vMQV%SM7f|2>T|j!Gyv)Id~VKC&Wn(lFLSsw@ZhO)Fyydm z;3C?H8{Jyo?#Qn7@CCJt3oW(f7S;;Sn+v7;)RF-wFLIF2S>f`keHwVwu3Fj$#TX2Y zs)*$pc#M?EmgT3&QC(8s8XpdB;;FB@Od&Zj3;2%;^k9HmdCv^ZEa2yi?m- zSmWlgeBLWmdMr{!Y{?<8l)d*m3Mxu$)VUsqR2Hs6Cs-<-yi3f{X<+FFwK}Y76-8UD zloCgHn?i+96k|g;vyDZRW-CimJWg;p7qas%yncD#dvl4N+EQK=BZN+}RZNl^&Pk{qJI%`|N$C`n4e z<9O>^=^JZQNg{>e4zW=yXobQ?6AFY;Q4B&5lnr4y9!F@($`Gv0W~EgY7?UVs!OnTB zlR_e?J%igflOY}6%ogvG2FfE%&Zp)Xze!W~LEfT5y|e}bfsVc%_W_XGa&(!6zPqQl zHF|!x6aSR@j}bn^U7ch~FRoY)Csr_NY>| zBqAKN*lvXRVzR+kHCbOKyvn}}w%T1ESEseh1e}~K% z+zequSKkVJn>`cAoI_vWtABegQcPhU>ylK7ZMadCI5BF`|C#ADE+W+`R zck9hef5o-t0MYp@3+Qv(HnB-EbL**B)xgi}4(9|I)*YH( G+VmgBHA?>g literal 0 HcmV?d00001 diff --git a/assets/dolphin/external/L3_Lab_research_128x54/frame_13.png b/assets/dolphin/external/L3_Lab_research_128x54/frame_13.png new file mode 100644 index 0000000000000000000000000000000000000000..c46dc3babf7be71b3a3f35921a861035b33582bd GIT binary patch literal 1689 zcmaJ?Yfuwc6utpOiW6EYiilH}&@w#S>?0eJtVE-PK$K7lQQ`yYCfPs+l1-C^gji9m zjzVQrT3Z!cTB%d4sG}82b*L%WinT*kpgyraa5`42=m==hrW+vEAC5b-d+$B>eCK@U zHCvUPmCg^H8VUg5t22~2+`5W;lS2ZzuhcXkCe}&WX)wpg=xIo8p$h37 znlhHZcaly4AaJc&t7CPVOwzzugp^N5=(5;2Gyo~HT{g;4OtX-lE;L)^f_q1g2_Umk zF31yWP>n5>E;47h?R2g?OKWf!8)Qbo>{(EXi{uPgXqJLpmJ+LjbjbxHc1dpU6C(m> zM1?Ju3r0!lG}%xpW2YgB5Q7aUib4{ZP>-6VdRm6gfN&JY5DZ5!F^pp*E+#QCH1-HM ze|DpZ%u%Ywym2SFponE{B!W1dPN7pIWbB0qCX>k!6i09z<}_eOxs|0{u+;}V*dNTo1lBt$TgOc1b4hEuQz)r-Y? zjNqh%U<_}3E`6ho%1O8|Y<@PRNGuYW#Fz+{NC^pyVT1{mQ8WsR38Ms)nM_8p)F41O ziiodsp6evPh-**Z_Ss}`hi9`zTe*RU#kQ*s4~} z(Yh`k+E!_8M?;j;z22^_!*M@vZEw-UTDI516+fNey>a-MYeiLhO=QRIA$|$cFy7YM z)r+35I1;(udw1od;VogF=8u;=7-vgIAFFs*S9b%&y;FrilEzn*4LuEMX`O~Qf(&Me zhnEMJZvoxcQ^t3k&G;&B92DE{bw(;qzkl$DUElQ%>*JRGb_HY%MmO^(fbZk8fFdyw zI|Nqo-C+dEYnr*;RkL0J`V;QVS_IEc;!O@P>08I;g9DYdp7nJR%JVgfjzgiV_CHc& zmWF~O;G-JJUgEvK%BG*2oF52=d*D%IAc(0#`rR&RbQynnK1M%(E)7hki-y`Mx* zXu$FT{Icd`Q|V&98g7e*l9D$Bwd)+47tSy1Tl2c-lbaEWp6-QmDga&N4uwLUXPkfS zlkRTbpd^-@xp;it%dM(fcDP_*NjTIOy%D%BeVd(k?m+x~Q&0Ra z2{2E0>FR~?S~xRv-Q^8^xes(#Vy5t>)SmvkvXS4D%R@EkRDRjhDgiY8)|$`nC#+5! z+z6gT&p%ifv8~~#Rt+T{&TkL2Oj!4gredO}@#yxf`hsIX{Cim5+F(#8yEbiE(cWuK zmG>6`L(-bgP5nGiR(0cm?4A6xXFgaE)OX`?%iej8NGLO?e8ui=D9Lf+Q(eIy^5qZ9 zbZo=B0U;+FJDpRTtI~#dG_9=v@|Efpr3F0Fq{s-{`Q{hB_0s}>t#yPq&e*Av@-i+` zx~~TtiVJPG%41@x9dQo>H+}YD%!7*Ba{=H=bJm{$wGoK-_G_JY^<9He9=X)u7R=NB z+Zo&!9^ZDgc*wo@M-d=rFMM?ed~GR@3|K&i&TPw)-yDebfa5)rV(;wPR^$6wsME5P J`{piN{U76AYVQC5 literal 0 HcmV?d00001 diff --git a/assets/dolphin/external/L3_Lab_research_128x54/frame_2.png b/assets/dolphin/external/L3_Lab_research_128x54/frame_2.png new file mode 100644 index 0000000000000000000000000000000000000000..01f07c68df29a7319cb3d143560f99c85dd57beb GIT binary patch literal 1707 zcmaJ?Yfuwc6u!I!Q2|9!t7g`qMbu4plU*~+2;kjA*Iq}E6=kcP@JSY+Iu`bI8f(8;)& zxC&8O7ErKABh~Q}uy;wsL$YMx<2v9yM;G;M!KqUfPg5uEV!)5*1 zb$UsvTsi8EJ;}Ja3}cn>`A(;k=M?g2dk!BZ2!f9Y_yPgUYQTNcBB`PC7#Wx4`YH&sRi%1u*y0#X6`M4^i?s4l9>O=9J&}!QJD61Je;RMq zcBJQ9DSj&Dp!4inwj%oQF)*9GcRTVZvTP(Nb^}`$(j=#~d1lJOB+6x6_J*f3=pz#EIoXL7W0b zP@z(Q%Eh8FY@)@%kQOa9=G(yf9>t2^iIv3JDUzY>=`?K`>jQNz&Crfq+6oDTJOQ*o zMQRNek0jDlrB^}ADZ606gZ7KLFjK?q1#h-h$J zgJP@{o#sG-;8titZhumE}SWI zKR?*L{qlyq=`GLuHf?TiSO>dX_X!8QW^kr99tUO8rJPTz!Q6BlWKJA<5L4h@T@v^Tc>2JqRZ{^^B+a~u5s748r^%l z3{x^V0n~zjKXVQp3qCGLa&$blfdZS^T{l@}9`bT?u&Ol0+26y1cO;jrkGbcH>=e?zSPPo&$JF1kmfq$=<|J$`K-S=*Wm2WgIs&*v0D{6aPty*Q%;jF>FYM^|$ zybU~k{Ql17d(pcGUFwLQ2wRn)tGlHdgzWbDb4|mqciQ(g1s17-@qm?)@O#&Lyy+?Jv}^q;0eg6SP)4Z4cgYs*?RZl7i~p11B`j+XFW7Ec~#}C+NC}> zADi3XA5lld)Rcx4)=Y1e`px*Io{Fwa@+k~kK4AKOzcT4_?p039oa%Al_IO@>+4?IP z+xwsOD8JRoQ;u}{eIra!Lnl)^bIRvjU(_4lF9eUq=Ot8# fJAFIi-CkgF=G2C5SL>#Eejka7WcjIO*+u^WnIm@> literal 0 HcmV?d00001 diff --git a/assets/dolphin/external/L3_Lab_research_128x54/frame_3.png b/assets/dolphin/external/L3_Lab_research_128x54/frame_3.png new file mode 100644 index 0000000000000000000000000000000000000000..148fe46405f933f4c4afb993733866a6c4742d4a GIT binary patch literal 1680 zcmaJ?c~BE)6yFez7zU?Crdrf?T}IK`%^um1O-fKC2~Y`PAXU^_vq?5#g=Ew0rb*D& z$S6fBVy#uisiW2dJlZl<6g)--Ydyv)TC`OZ=;+ikQpKYdiY?u6SpRU`nceUE-u~Wu zzjy7f&dte)lO{+30Eo-V)a40lNVtaOuaL7|CxWTfY6Qg*9ESx2%mv*%6@cAb;)n$u z&Dp$+hi6zf7`8}RSs$;31g=9txI9MVGsA9fI8{Q@kO1XDFgc32T;a$D(Hx&g|4-wE zXwDq;&`2K5u|BU&sE8wRL|Mq*%N>P*0vnCV%Lrwmigm2b=c3(wmQD)^Z{&8yt|1Af z%}ykvFzrx~FhQssFlBY9;bf~_tt4m^qflzZ&WrR7XtDt(^~7u}O@(3lbW*3l)AbmN zDGWHKBUK~1S#FM}+%|f|HzWAg>6L~w)R6vCT}`@|rg+wCX4&GAKFBR(d6p|=Js_@- zdzaTQIgND{{EgaRg#2?AEDaSB$T zR;AL45rUL}hV|{wrEjQF1&I)bXM~MLp;RawN=yN(NJ0f;7~z1`6pg}4!mh&94u@Sy z+8{)rh=e=mxlS4p3GEr)KAQ~T@NBkdw=hs%VRAaXQpdy2YyI7{XX<>e#O=ij>68#*xgPVCR7hqVt%AD0{# zou1PoF1T-2MUofpMO@nYch$i1E@1!m)^+2W)`ESrqRH|VkWTtPWU}aPP(%2>@H3}HJ36|Au4n&0d=a)mm_hHC7?jcrZKb6L!AIG-Pdpx+K|vRwsuNB6C#*vvZp&Jv*o9;K-Fjk2hgQ5lw`EIvVb-<$4R4eA5_Vn;ZR~cSOB%n=6eWi{0z51gfeseD7TxKSx&G znB6$zVLVW`h@5DOPi^DXnQ5Nd?a^RGqqwe>NR&Le711*xh7q?$cDZkgdv~l7g*GI; zbAEJV+okWe?Ty`8KWoX#>P1BCf*Ihk!&fBw0{7CkNgWNw{w?y-eP=_a<4HhU$>B1S z^zzps16#Us_8Nl$G9UMpZL=5noOKU!A`dl-+Og}4W0p53t@){^r>|^x5+z9l{1x@{ znooE=ae({g$;zso8Gk|^@>k2G(S2q7Tq7R3QPaLTrsEZp=v?APBFNuK&$gYZ0WAB9 zB#(D@1p&<%i}OxN?=LHU`zNxpB4Z0)8?zaBItm5iAH{e73w}H`{Ex`e=jgtfZ7KZ^ D-1uoN literal 0 HcmV?d00001 diff --git a/assets/dolphin/external/L3_Lab_research_128x54/frame_4.png b/assets/dolphin/external/L3_Lab_research_128x54/frame_4.png new file mode 100644 index 0000000000000000000000000000000000000000..0d402b0dbfe4d4021bc076b83bf0098e9ec4ebe1 GIT binary patch literal 1691 zcmaJ=c~BE)6kl${BG}?l%Fs1Xi`Y$eHwif;5JHGh2_P~RXB^5VyMYywjhn>;>PWO| zvGt-;trw>#IBjXPfEp@Nr3hZdv6R6B#d^>|<**9as@(vw{^7VYyYKtnzTbPlcWp{Z zTIlN&=mP+NZ$i8>m6cZZjqrA3zhVa4mWxiw1zmXp0fk<`4|1A+kt=j5E-9k^_>sjI&gz zhSkPcBAbjapot{~Nom@G9IXWBL`Q*<7AfmMPcRs0(dQaWQj3f;?pMm59cms295-Qd zWSj|7>FN|PmZAwz#6=)248x#E!qvb!v4)VqAAu;0B0L1;Awmd6q^MAe2*JsR!^Wd= zoitUcnvBNYWSne3+=3UPW+5+*H8 z8X1x@fDVtChRS1P9G2@u5_+Rr{nD|)G+8RPXgmvM<}OLW4_$0s=-b7<2l09bN@Ts8Dg7Sb@Zd5F{>EtmLDyaR`j? zRVbnqi=5a5gNeZmTEZEdWMfZaMQ_APV`&0oC_0Uza-DOKl1(v`DVs8aD4&ahVQNfE z8XTH=jxJ3ktt4o26@ja0N)L{gSxUZ!LIf%z2$5I}A-I4K2_ggnNFqToh!1OoLJcBd zwF1s09)G2L6NAcX*ffkzHd4Nj&({eNJ|q$gL=b`qbdUriU`QyyMTkVF!-ZlkhsRRn zIVR_oNph;#@pK$tZU%dKxm$#RT_~E}oaS&+!)~2tN@7|ZD_^{LaiF{GIsmxtNl?b5 zS+2C~+G02jd#~R%Qur6SBIrHwMe(8Ev%hPo@+s>bJ&gS`wTl|68Co~|w9u{L+X^qZ z=lC@^v(f(BRo=eGrss9Q#zVi}_Aq|7eYM;rC?CjM9_(^Eg#>JkRHRMG->`Fc<AYsATYbM$kxC1 zW?_SSl6*7$?+MRit=j;_oLhl?Zi6cA^6(U`VwSb5J8bKv-~|`js=T<3pX|Jmym0P? zHFGSNw}!|io1t^FJw88P`c|mgI+QvMxY407wKQM?udlZ}8{FY4_pNW-ZF5bZ@Bhcc zTGumGRR?dyT1|d+efP6~n`hPJDBo{$Pp>fZQ}-Irrg@j@gxfFMcj`*bBf#kyOtm>6 z^+^Ejb=1TUxusFgLeRx6u5vLV@RqLCcPXaHkWv{182HV`%0m@E<)X(NK7 zZ7CFSKx~z^Rur*l6|8vSQP9$ zbMBH8v&%IHcdN&G%+?I<zi7*SMOa^6ck~3hVSqgO97TaBw!8XM#U%}PQw|svBCyToi>z1M#p>w)X}nb1 zrO$QHu#R>y*-jHz5lgHe%w_M@j(mz78#2Xd<;p@WRxze*8*OKkRB{1#BQ#shq!bsM z%y>Kk(H4;u!f}ZOqKp;-iZ_}GF-{{Wg;0JwFT-n)cnv01D-+PE5)@S{r797oRHFzg z(qO1cD)D2J>@JqFn`pmpE9bi(oA633sdUm5%Q*E6v)JDUsaXumxUv`rh>3(4I6+I9 ztahJdqOVGQL91w|bt!GuI2jw*n`YAb5(@E{gr+4@DTJDF5roI%I7AQ_1&I)&SZqXb zPKpcq@#YuO*Vm|=gbTyrXG4m_B9TRmiXe#;mp~|rTOfj>5lD=iB`9IBn8i|)0Olyd zzRr1}ll&sCJ$>8flffOH&lYXx2Fl4zP8AO==cX<=b%tKetzNHpbLYlO01!}@q?)RC zpFdW)`qR;9sH)oQy{Ye5H?Vee%l27S_s2GF(WGqn*zhR4C+6PlYrOkUo(84E${_~% zFZqVU**W3A-+1`Mt9+EV2k6k*Pe=|of{%;B3}#-|AsK(#j%~b#WnELAZRT%EpAIzG zhK$@b5CC|a?nNK13sS@fe-*wSh%0mF)xT*RXvkWA^j}$d=U)+xq0^Z})bp$)#5w+M zT}#^)>xjL!g68$ole~YrN7_71Ew2GT(Z9|#7xN<(wV8?mj^G&8z7_o6F7Y#fdDn@< zB}=0VEBLxmx~I3+d~k-hZY35xSvJ_i>=@)2@kQ$QF~D7oNv3yC96QgWCmSMnpEqrZ zuG$5_$J66VEj^(J&z8(?R)*3S#%X~{&>FCPl@mCoPyR9D+{)8Id$(`2M*tPI^*F`v znlyA-M%|d!>@9PSD?Q)w=d*JHyRPs&iS|?7?{4tMgi9CPiE4lYCbZnhFV(Ej)t{@$ zy>)4XqPQhNwjllFK{e4*l)#3uj(kCW;CoGV5s`Vj<+ttQwzAENh0OWPy;ZJ<6+HoI zJKu5u#Kll%e@E+=+17-V@I1e^{ESKx`YJC~j%W!q}_iop@YTsXQY(;pgZM~Q#^j#4*FH*)=0z8HM`tCGDqDfW`-QC`Mk!4}aaz=Kf%q5yyV!S5MK(-ad2SofY*tvBksx zEIyDb_~uC=6V-G*qCE0%^&6d`;Ah6=f2_UwVCLWuttaJT?3#ku(hHsKDc9MY62J)F zDVZ_c)3J49X~-ULJFqT!7-=NN^z6JaKDZRPf3sR~8Nn2-0o~pEyNQGa#6>Ep8Kz(9;;B>53(Gk$1O*craKOA>v_uhN%`Of*y zYqlyoD_y{!%m)AnG#RQKZe78>$zj3VSLUQPa?2z(P0!{sX4XYHXfVsf7-&dir3&dB znlhEYcbrZEAb7P!r)TxrOw!0$MU-DhH8|5b9%o$LMo8$~wX_kWA))JeObSs1-c1dpU7b8Mw zM1?I@2%nJBYqOzL#z8|;5e6Gk6osU6kpVT!4741b2H_}RavMvzVVg5HU_nJY zjSh>QwJ)ErL028aeWem)vnb(HEeT^rix1%;->5fCPERb)gRf2wv)}F|EKX> zZKtl>P9r(AlPPr=xr&%$17I$DFLvZtum{+XVu@I6mSAF7DkG#Yh7o31PSGeVAxu(CZZ?}FGNTaT zC?fvOd8U&BBCb9C+ozMk9iGk>ZQ};Y!A;J~6Zns~sSC}{)TME&&*$55uD%z5pv@Z9 zES>xOfi0D`b~H>i)#vN#IvDr!=JpnCtaWQGT=CN}-WvyxxR+I>*F<&P91@fu4P))C zUA^epibGLreYclC7~T}_ZT@)Cy)pK5^r4z}d1W_H-Z@bSq-g?W+0f&#mewhFBgkNe zczAhe`6kePHDzqa>5Q-P#z3+CK3A0T)X*z!OfOyr$_}-8E~Kpg-Z(j0N!QB;JG|v!QiNKG;`T>s?zHsXAMu>^Q(*vG;*8 zvy=}GfsbmWyJi1mw4Asa);zv2BCIY3sMVX3_FRZh>}}XD^8y z(}JY~_(kpUrqYE14crzDB_*#5Y1cb9&YxS>x9TByaR1mtr!-x2;Q?9@E z$aXfbQxS_!T%$rf>?H5NL(PRpYe2`%i>>NfcDP_*Q3TW%y&kwPe4CwjW?%eWb5Hy) z2{2E8;qtk$Iyf_P&Bb+nx%c#!VkYt?)}H*kvQf~J%R{y4RDRjxDj_uW#;VWnCag>x zTn`>a&)r`axuxN-P6H(#%x@32j$8AMw&HbfDh*NgTjtCcDg1vSEUVaYg%6aO{mn0W>!$?&TI-BxoVHyp<7J$u z^j{A)6c^fWl*hzWJLB#LZ}{xPn0pnqXM(_`=Bz)1Y9kTf%~v~b8@dK3c@;9FM>t3K zZ)a#5zVh5<`oO115=?T3n?I8tq6orXy zPH;2X8#JQq;jGR@0we;96PIaZo1*w)h6MzTZW@>v!>&M`e;6;h`~803-}m$Ve!j2V zE_24R&?&Q~000nbOfzJPt5* z6eiT<)H8NAt<=S2m1bmHOY^N78cs}r;yqf?fP)bz$m1yB+**$g9uSaD#v7o^t_9KR5A>)q9_WfG%^cnQ(G7f8VBJhj>$1xjwuiv)8Yy(rhq0MSoG(j zZQ4vj>V!A(q=W5(;MB_H#l^+4VnW8d^5mFCqmiSy9LEt+196vd0_8zCcTB*7fpJ@1 ztW#il4)R;1EPRomgGH|6K{%Wy(=)@Idm>e0(&Qe>DaT}}+~M#?Hm2e{$ zF@staz#2KXKyg+k;F}eFPhiQHVzqh~LkYYqo97DxePFip0`Io-P6#JtIJDSASy|36 ziS<`$JZJ;sVmC8%s*86(V`owB~IOBb9#1)xQ>pF)?cl?0RWQCMniJ8r@Q6T zJ={-daK+x?vODai!CZAu%c1w1(hAo-Ax1sE$L&v!c^0IbH=HJNTc*uw&C5{bwl+3* z-R0+$olXdE&5J$NJ3H4{ecc>%cWF3a9{elX+aU3ECN9tI>J8UV1+;Mz^xCgO*Cah7 z%GWvuD}$35W5{J+GY_ti1of0|1=p{u8$4E9eJ>`isqG7}PJ-U<>{!U%*;SehUTlmw zwckgCLRY=T6+hQv#$3=@Ucr48MMbXL-7!#K_f6d-Uv%q<#D$B3QyZ3ho6s8IV06d9 zc=Uo24f4+aJYh!RY&+2O;6r%+qXYk%C0ly0KTJNEf<&!dQoc7eOS<9jOXub!M|q&R zT|o2W?RUV;WLVNNaKiEQ=*;k-G~;G-bpfy>W48H~jq2Ft^Zux~Dc#n%7&wg2JKDMW zj1+j4G}8-?$F1paZ#`T2iFAEhI|x+O3-f|}?b2H{Ni0}$b~t3;kM}oJhqBWCNc}@r zdL`klf071=jP<|2O}|lLgEV0S`!9|p>~5TUBUV^e647v5*4+=@{0%ER{Iqh^NP%Ub zFWr09%^u|X7UN3L+qgBxtM|?j4j{LtByDRMku*?Q5#BIgcgUl)LfDRBVA_p}ld3PP zRsntPp7L+|&mU>hpD^CqcZZTp>J{GT(DOV0>{iUoA87G{ zJ6C=1OW4$Vyo5Z`-u7Lzv})344-zNGch-Eo<-MLgL%NV^xa7i);WuM0|1cWSwif^a YV`bz=*E`=i=KmEKQ!)(SFU{TlAI@}Lp#T5? literal 0 HcmV?d00001 diff --git a/assets/dolphin/external/L3_Lab_research_128x54/frame_8.png b/assets/dolphin/external/L3_Lab_research_128x54/frame_8.png new file mode 100644 index 0000000000000000000000000000000000000000..0f681e6abbffe2f8c4bad77476392253f324f0f0 GIT binary patch literal 1645 zcmaJ?Yfuwc6uuBq6ck@niWIjCt#-<0cau%BNr^%d&^QEQf{GN8O?LArNj4^{2?!c% zZPjTjw9_(GQ7hu3wOXwY>J#dtwu<13R;vTr(m|bSrPV4`=mv=OhvUxd-h0nI-#OoT z%`VqxPaZlXeh2_ysCJ6Rz^?)Rl|~BqFX^Q!`Q=3}Babt(7S2a`7?4i0CI-?vDJx@O zD7s|s4@@cmf~EG{JT6a{r7*KjAr;gS`kihb4M6H7znd}_GaO`Mtag_YzH{IR4B2TV zJX4~>bZ#|cvrj4YFvimCTytr$Sx&=~CPJxx1#iH~a1`WsI$U0bUkUfxRq*?u7=@u; z6|Ptb_mRre=^-`iVIY|hN6Z+8K{C0}gjq-vBgax85hlV>T!i8hM1(6u5(O@S`X8A0 z=b#?G^TrNj35h@ZPyawVeadDI%ae0$M7Br04 z?6JE!JL`gi7AX@uk5j@t*S;W}Zk_IlVVAc*ReaJ=KjlVoA%;4g!N_{Gy_|vhpT;w_ zy}2cB1~o8VcAm$~SHzMO0`u8>zN4Tb&qk5svGZl292(X<&&jwrtwss+H$vJ@D@a0O zrU@yAFcvY15QNNvP$r8Uk(y|^gkUh7!l;m)XW=n1CY2Eyxe8AwaXdp!YQ!RS29Dw4 zOcAajWg)EA<>e@snF;x}^S=AB_mb3?m~+1g8lxLP!Y$k;_FCBF0P-i3ulo zDFOH6>8H}y*QmUN55pZ|qYz8PVv7V9BQlbZAvjK05IMzQh=ibJxZGl)C8QZfd5UPT zbDrv?kce;3;P%O6@P{X}#klx^^6-;W$LXZ})D6^UAC*P z2R|F^ISNH*th>GFM)oLFWjk7TuTE>uIj!!>ho+RfA4TkokBMB_I$ocsifJp`v>(!+ zxjo?Fn${k6|D8+WG$`0RS=%B2 z2?6cuZx$NCHav26Gx+n>j!^|wJL8MahF|WkJaKn(6P9tTtl(Ul4U8=u2Cg66k=d~I z0ko#!({2^;mU zPneSuxF`5%DYa$s>di3$qoY%^QPK>67DO6UYgbgIfEvq*(xN>-zn(dAR=w`{`RF~3 z_?eRrKr2&Wra`+KP*!4{exP z5Qe=quBP62I4kx7JNoGK{K427V_nWmn%n1Y3dNr^zB9}EDVnSB;TPMdc5hvN>hA3D zN3T>j-cT1-)!rQ!eljbqxOPrT%L3nQkUw^4Cmhi3=kCjY+;IM1|Bk4Di+Xt<2!@DD)E!uWp;qJisWb4B_5#Wga@wkSSKmfir V#DeNB?Tz3MK%0@R*{&*j`#(KRS^)q6 literal 0 HcmV?d00001 diff --git a/assets/dolphin/external/L3_Lab_research_128x54/frame_9.png b/assets/dolphin/external/L3_Lab_research_128x54/frame_9.png new file mode 100644 index 0000000000000000000000000000000000000000..0f391b75e5977c5395829f3035b5f40916ab6bf2 GIT binary patch literal 1655 zcmaJ=c~BE)6#vqIWkjsj3!%>JL@H?6?3rr?B_yD+Tp||Kslz6_3lWly*~J9ZHc&k4 zC@98uz;^Iz8AefySSbR9wu57-N3m)LmFl!Aty0E1Y6a;Ai1iQ0o!Ncg_xAnX`@L&R zTFQcuv0-BY03oJ@#&k(~q*omzm%dtoE|Je5lY^fgJ3$H4nc7Q$6?6=77Fbm?S}2bOuq*sD_ERX zhiK*Pkk2D+<_pAFg~W9v37aE1`MG1eFj^|9Xo#D3Aea(GY&KtJ!`6bB&i+s1rPe}5 zp@T)zS%EKbTBMF}GyPzxdan-TGnCj+sZOiZ7CPU^TMBHfT{IbE71AFiV`V5Usj@Jn z8iiSo(846C;b7X#>0q^)(Wyul#b}iF`*|52GZ+aqp*O^1dM$<}7_>$LHzZ&vMkL~x zQLFJ|O?E+~?H1M_+bYE##m2u9OBtLjE%MF`p3nEsL0T>^@ZYeaGjUAzhyD7HgLl$|-G525!C}ZQYo(q>Kbf4h;<*y!!by0A5>TGU_wjzczgu z>}-d|1!g{K5hD*v(CAE; z=do+(Y+oh?`f9o>UT?MP`x9k7+qwXBW6yd|_zF+s+Mi#$mGT)EB`Z7m6zo#x40=J= z&F+A*hKhjO_X403tv3YTqkrIh_Fy7*c0xp`YPH-muC;VQD#%@&FPnV-z=@K~wudp{ zVPAui?#K@hHN*i&@ptg4sr1z4J3D$0r}6qpt*b!gAg28`qU}gv(?C>oT=%9gZpO($ zdHyO;S3EUt%5_tG{EV%;1KYSD&%3Q#22R)ga;Bp+a9vRLgx~7pd7+JS%$?x^8z)EY zI~{=5lrJicjN9Bg4ylK7cQcjcf6ux2(Z}uXmIqX z-1Ocm@9#4jYmypJ*_?=e0FG6pM0@5WJ>DLe9`fTm&#JQ1pWX@ls>}->{?M^5Otvwz zKBmGx-*&fmNz&311A*$sKS`=+PJQ#_{<$0O=dKJ`)_ri>ygS~MCq%`c9;5sb$e)#c z?-agxk0oOI3fcLpX0&xyTu|dbhmer-gOdbZ^)&U`F?Zx|-GYLr*ESmLou9};FL{n@ z-k<1_Rh_GrXI`wV>)r01wZ69auY?YB(ZGNJ@-9!?S{q*YM}s}QhYIbl{#WK%xnXHV zbEl#H%5{DjME2*TUOU&KICetDOl$e_WADQ==e-xH)#GpHywO#f7u>PG`XTM^TfVuV zw<)`wp1bdOXZ+Jj@O_P=?9xZzSX|z~j^apar`Sn0U1-jcEsm&r&~tlldGFPsEjJ$$3J=geHSqYK zNFGoMh&@B%4i=IfH;TKkpR8}&%t(N57IyIABa3~ zK=aIdZXogV^MU69fP=~*``$o)pS|^cA~*|#3jk6pym|-p{@<(OvA}GAwi!RQ|#c+3<9_nW{jpa1oC1`iwL3K)4Pn3iHSB=vD{I2|{DDuEaU>uG=J_mH){)6K}WtD^Y$s7IN z4Rr7Qf#Z4ylwtNKale1TexC1jdgV$7lo|FW0lzQD?cN8b0s;>`@_c_Y>ix=8J|d8T z2jPDQi+q9S7zd>N{($os2n@d+_jt$t0P&3i%YY9*`8-aeU;nLyfM5ase}&=?Ce_0p-AqKtmvqJwyP$0QwCO0pJe+cmRMN|Kf%K delta 517 zcmV+g0{Z={1i%CX0RTLa14n=Vf4~EGrNe^c0viM(Cjc{+0^vx54ag8#0HFSZ!@m!R zRDtCHsDs871swo)9YQ~-H;0ON|)YP6Sr zL<0B^KLy#4Fs`0kRd5H62p)NlZN>pg!9cX&@_@iW4jr}^aIX;ZpV|v9y$>De;|AadVGHr@_6vD+5q_j#$cc?yxbl-N>+jf4;$nP z7?2(Z`gRW;L@PmlEsf>_0|$?T;~xi(LM5QN1IPW~SQZ1`LlAo-#sNN35BXj&tVD}J z@}Q&30U>~LIQ;k=DiMDn4~+?yRuAX=?l*WaJug7=j6THfH~1*L?o^^-L7!q^8}tSh zNRk83fxv)+&wNi1dCGx9KPd5FmMih7O52Bn_4@K#+J$$3J=geHSqYK zNFGoMh&@B%4i=IfH;TKkpR8}&%t(N57IyIABa3~ zK=aIdZXogV^MU69fP=~*``$o)pS|^cA~*|#3jk6pym|-p{@<(OvA}GAwi!RQ|#c+3<9_nW{jpa1oC1`iwL3K)4Pn3iHSB=vD{I2|{DDuEaU>uG=J_mH){)6K}WtD^Y$s7IN z4Rr7Qf#Z4ylwtNKale1TexC1jdgV$7lo|FW0lzQD?cN8b0s;>`@_c_Y>ix=8J|d8T z2jPDQi+q9S7zd>N{($os2n@d+w|K|?0P&3i%YY9*={!!OU;nLyfM5ase?{UCCyE0z??*501%|O o5&nQF8w3YQ|AJl~FaZyS04XU1f$AUy@CVXAz%L*Jz#ahj05YiJK>z>% delta 519 zcmV+i0{H!{1i}OZ0RTRc14n=Vf4~EGrNe^c0viM(Cjc{+0^vx54ag8#0HFSZ!@m!R zRDtCHsDs871swo)9YQ~-H;0ON|)YP6Sr zL<0B^KLy#4Fs`0kRd5H62p)NlZN>pg!9cX&@_@iW4jr}^aIX;ZpV|v9y$>De;|AadVGHr@_6vD+5q_j#$cc?yxbl-N>+jf4;$nP z7?2(Z`gRW;L@PmlEsf>_0|$?T;~xi(LM5QN1IPW~SQZ1`LlAo-#sNN35BXj&tVD}J z@}Q&30U>~LIQ;k=DiMDn4~+?yRuAX=?l*WaJug7=j6THfH~1*L?o^^-L7!q^8}tSh zNRk83fxv)+&wNi1dCGx9KPdK!^Zu*T{PZ=}J5P1S0_fgagy~ zg**g;3M?3a%s>PA|3Lr2@&C@?p}~*?%oH$mNy#8=qJ#tU6=mL?jKy;t@CE?=$5cpsMl8{Iv0QT?)(mu-& JdjLEE;0+@K-Q)lO diff --git a/assets/resources/dolphin/L1_Laptop_128x51/frame_2.bm b/assets/resources/dolphin/L1_Laptop_128x51/frame_2.bm index 5b91677eaaed25bc256df84dfb32eb749c1aaf7f..ff2851c280846f4470944424c7acfaee9acc2d6f 100644 GIT binary patch delta 501 zcmVJ$$3J=geHSqYK zNFGoMh&@B%4i=IfH;TKkpR8}&%t(N57IyIABa3~ zK=aIdZXogV^MU69fP=~*``$o)pS|^cA~*|#3jk6pym|-p{@<(OvA}GAwi!RQ|#c+3<9_nW{jpa1oC1`iwL3K)4Pn3iHSB=vD{I2|{DDuEaU>uG=J_mH){)6K}WtD^Y$s7IN z4Rr7Qf#Z4ylwtNKale1TexC1jdgV$7lo|FW0lzQD?cN8b0s;>`@_c_Y>ix=8J|d8T z2jPDQi+q9S7zd)fU*-=nfPl;K(|3%2;13wkEVuyk_>;uyHUIk9NCp5O=ipu-@_;&s z_8>C8PXX!wV-5M7KmosB0qMYmU@$NcdNc$catJ8!U_&$f|Db7WQ=P#L-z-WRG<^c7z|Z&OKJh%~@gcu%jKzPF_1cQ!j0Hj7g{Qm$c rE(Cv|3LpTs2o96~1iU<80+;}VQc?*6)Iba152Sy9UO)$cJOS_k=ELW6 delta 521 zcmV+k0`~o|1jGab0RTXe14n=Vf4~EGrNe^c0viM(Cjc{+0^vx54ag8#0HFSZ!@m!R zRDtCHsDs871swo)9YQ~-H;0ON|)YP6Sr zL<0B^KLy#4Fs`0kRd5H62p)NlZN>pg!9cX&@_@iW4jr}^aIX;ZpV|v9y$>De;|AadVGHr@_6vD+5q_j#$cc?yxbl-N>+jf4;$nP z7?2(Z`gRW;L@PmlEsf>_0|$?T;~xi(LM5QN1IPW~SQZ1`LlAo-#sNN35BXj&tVD}J z@}Q&30U>~LIQ;k=DiMDn4~+?yRuAX=?l*WaJug7=j6THfH~1*L?o^^-L7!q^8}tSh zNRk83fxv)+&wNi1dCGx9KPdfa~_P2^@F5rs3Y9h!9xc`oRS9!fIK52S diff --git a/assets/resources/dolphin/L1_Laptop_128x51/frame_3.bm b/assets/resources/dolphin/L1_Laptop_128x51/frame_3.bm index 5453468d386943df39e2e00d94014fffd8c9ce3f..360d405abc216f7299277856dc37dcbec4360bd3 100644 GIT binary patch delta 497 zcmVJ$$3J=geHSqYK zNFGoMh&@B%4i=IfH;TKkpR8}&%t(N57IyIABa3~ zK=aIdZXogV^MU69fP=~*``$o)pS|^cA~*|#3jk6pym|-p{@<(OvA}GAwi!RQ|#c+3<9_nW{jpa1oC1`iwL3K)4Pn3iHSB=vD{I2|{DDuEaU>uG=J_mH){)6K}WtD^Y$s7IN z4Rr7Qf#Z4ylwtNKale1TexC1jdgV$7lo|FW0lzQD?cN8b0s;>`@_c_Y>ix=8J|d8T z2jP7Oi+q9S7zd=~{($os2n@d+mw3ni0P&3i%YY9*!8}f*U;nLyfM5ase+A+XC&1OC5*(}4&^j2IrD@%l(0sL_NB&-4F*txjck1s)7Q9$~SAwN6O` z77T!9C?WfU#41n;Z&XNJh%~@gcu%jKzPg`5K$RNHU#1$7ywQpA1MDo n6kxGz2puQ>33zzG1TGi=q@)rDsDKy1A4vZIynqh?cmv=7OF`la delta 519 zcmV+i0{H!`1i}OZ0RTRc14n=Vf4~EGrNe^c0viM(Cjc{+0^vx54ag8#0HFSZ!@m!R zRDtCHsDs871swo)9YQ~-H;0ON|)YP6Sr zL<0B^KLy#4Fs`0kRd5H62p)NlZN>pg!9cX&@_@iW4jr}^aIX;ZpV|v9y$>De;|AadVGHr@_6vD+5q_j#$cc?yxbl-N>+jf4;$nP z7?2(Z`gRW;L@PmlEsf>_0|$?T;~xi(LM5QN1IPW~SQZ1`LlAo-#sNN35BXj&tVD}J z@}Q&30U>~LIQ;k=DiMDn4~+?yRuAX=?l*WaJug7=j6THfH~1*L?o^^-L7!q^8}tSh zNRk83fxv)+&wNi1dCGx9KPdJ$$3J=geHSqYK zNFGoMh&@B%4i=IfH;TKkpR8}&%t(N57IyIABa3~ zK=aIdZXogV^MU69fP=~*``$o)pS|^cA~*;H2m~b|yT_n^Pwo1?D;$3XfF5)Uc067` z@AY^-Ux*h19-kk@JRX7a{y^pm0{hM27f=8Cy8{P}@&yb?4+H%>2c`J7H`oje9zG9@ zd>)q|c>lZ$0>FF7Vh?0^z$eN<|0~AnfBsi~R1|q&Brpy~AD;udZ~sB@p)$(B{A7*( z?*_Ve{=o6Q1IjS_6S#lh;J;6Iy1jCx1Ii5h69C_rj@!Ir{{VQ#fn~r4pZuODQLq2j!#^Mp08m0N5P3i% z902I7#2!Im52QX|O%`x~2mOBsrvecOfIxxhKUoA7Rxn6_Jilo__!`vba8Mw^0p=SR zJ5=P5Fi^w>LV_Q-JVK=ao&&}WAP1aJ;15+$!YBap;6`!~V0p;_<1mmC4mq#_kr==P rDJ}$mpbAF80n&fqmxqi1N%24k2xJlmsDKy1A4vZIynqh?cmv=7#E#gs delta 523 zcmV+m0`&c`1jYmd0RTdg14n=Vf4~EGrNe^c0viM(Cjc{+0^vx54ag8#0HFSZ!@m!R zRDtCHsDs871swo)9YQ~-H;0ON|)YP6Sr zL<0B^KLy#4Fs`0kRd5H62p)NlZN>pg!9cX&@_@iWg5(b$_kmzo4|xnh?2i}(`A9$Ic*3y~ zEeFbik1Pa+0m$R?;BbGaM1(#xCRtcNpYyog;K1~~1IjS_6S&{tqVu^@iG>DziGXj= z7*!%j4?YJ10uMd$JVECw1q}S8AVK(F0q_72dCo!OP>KW9zEBUxY~CpIjRMPn4?p=l zbN~_mt%Q6w0C^yUUOWgpykZ66J%~KQ!wLe3d|~qfXrM#@KkI+|1N5aG{{j&RfIxxh zKNKloBoI|t!6E?i{Qux#Api{S3JMrNJi$W;M4XZa0~mnFMFaN-tneN%X#hOpe*k)_ zh7mvqmjW}8gA33eGYJFu;UiwfHa&A*hv5Y diff --git a/assets/resources/dolphin/L1_Laptop_128x51/frame_5.bm b/assets/resources/dolphin/L1_Laptop_128x51/frame_5.bm index 322d55ea37799d49899231ae55665997c1967152..e56c3f1a8a92ba66f0cd2f50cf8e1344a11d2edc 100644 GIT binary patch delta 495 zcmVJ$$3J=geHSqYK zNFGoMh&@B%4i=IfH;TKkpR8}&%t(N57IyIABa3~ zK=aIdZXogV^MU69fP=~*``$o)pS|^cA~*;H2m~b|yT_n^Pwo1?D;$3XfF5)Uc067` z@AY^-Ux*h19-kk@JRX7a{y^pm0{hM27f=8Cy8{P}@&yb?4+H%>2c`J7H`oje9zG9@ zd>)q|c>lZ$0>FF7Vh?0^z$eN<|0~AnfBsi~R1|q&Brpy~AD;udZ~sB@p)$(B{A7*( z?*_Ve{=o6Q1IjS_6S#lh;J;6Iy1jCx1Ii5h69C_rj{Cf0{{VQ#fn~r4pZuODQLq2j!ay(ppoCr^@_;&s z_8{{gkbKy}2o`XF2mD_kd2k^d0qBF!ezFKGz}h1-{Qux)9YQ~-H;0ON|)YP6Sr zL<0B^KLy#4Fs`0kRd5H62p)NlZN>pg!9cX&@_@iWg5(b$_kmzo4|xnh?2i}(`A9$Ic*3y~ zEeFbik1Pa+0m$R?;BbGaM1(#xCRtcNpYyog;K1~~1IjS_6S&{tqVu^@iG>DziGXj= z7*!%j4?YJ10uMd$JVECw1q}S8AVK(F!SDbOd4)z5P>KW9zEBUxeBLPYjRMPn4?p=l zbN~_mt%UwSGC>Huco27Zx`_55^B<5DL*m8|K%hhbKjQfQl%sgR;6e|=4^jA`O93E) z%nhP5KhORK5)c5+;IN1U2p(XegQ8AJ17(a5BqD+PgVuQi0gNCXaX)}PRYed7mjW}8 zgA33eFlht$J$$3J=geHSqYK zNFGoMh&@B%4i=IfH;TKkpR8}&%t(N57IyIABa3~ zK=aIdZXogV^MU6%fP=~*``$o)pS|^cA~*}=3jk6pym|-p{@<(OvA}GAwi!RQ|#c+3<9_nW{jpa1oC1`iSV!x96)|4zZ_el3Z7U|{j^d}HAB zxdX@j;8+#|-a`<3BgO$fQV;oFH%tHWyYisGATS&Rh5^Xq^Wb+)|L8t6CRtcNjFG?H z;MY$7*d8~ac}5>%cN>5F7wPWzSFTi`c|o6IU>oxMe%;`DU?3p#-zUfOKCj%RL*gk2 z5Plc%c(=$Nae#VH-{=o9fPl;K-*=3E;13wkEVuyk|C7Y(HUIk9NCp5D5R1efPzO;S z#2#bv51SZ40?rTs|BK`gE(9ZhJrH^i)bf5So;o|@i{7eD@83cjqAO-LT&}e`U0C)qy1QrS3+yDRo delta 516 zcmV+f0{i``1iu6W0RTIZ14n=Vf4~EGrNe^c0viM(Cjc{+0^vx54ag8#0HFSZ!@m!R zRDtCHsDs871swo)9YQ~-H;0ON|)YP6Sr zL<0B^KLy#4Fs`0kRd5H62p)NlZN>pg!9cX&@|?gylZ$0>FF7Vh?0^z$eN<|0~87h>>VM zR2T#X1AvggIUIg`4i$e0kcY;E%PR--{&yR^7#^3Pc}5>%cN_c^UUw=`JfP39Fb(41QP&wNi1dCGx9cqs@Fei!h300bU$@OacBfc0;b1M%NCiag^$vfu;H{!bkM z1b^#cKadQNLN6W!9o{aYJ%~KVA@Yy(0Ym^6!2!~L;FpJt07vmK2nb{n2*5qO0rVOm1Hc{t G@Bskf$k&ko diff --git a/assets/resources/dolphin/L1_Laptop_128x51/frame_7.bm b/assets/resources/dolphin/L1_Laptop_128x51/frame_7.bm index 5fc27a008d9c8eb074000395e78cfec3ad7188de..4663c6b03717f3eeaa14f34f8d60fa47d2138456 100644 GIT binary patch delta 501 zcmVJ$$3J=geHSqYK zNFGoMh&@B%4i=IfH;TKkpR8}&%t(N57IyIABa3~ zK=aIdZXogV^MU6%fP=~*``$o)pS|^cA~*}=3jk6pym|-p{@<(OvA}pjV;+_vc`2)r0d)WWtFSP5kH!oS9tZk%4@>cEXE+!LJbWJ* z_&qK_@&8yL6Y==_%3=>>c<=*beE%!P>3{xLepDC)1_SU7k0X!If!#O%p!m?4W&C6b z+-~q|r+@4Z8_+zz@K=8sU*Nw_ce=fDr2>b6|9y#oZ_DxfcY*2fzk|j_f#)O#j2b{lIOf0#L}O5o r08(5C|3DN#0c;Q*5`!-f7yysrU=R?i{1jPgc0RTaf14n=Vf4~EGrNe^c0viM(Cjc{+0^vx54ag8#0HFSZ!@m!R zRDtCHsDs871swo)9YQ~-H;0ON|)YP6Sr zL<0B^KLy#4Fs`0kRd5H62p)NlZN>pg!9cX&@|?gyjVORKOcEaLF|tn0Bmoc<#@ue z5-kVHg8+cQegU!MaruAnI8-7+9~u)Zzn|~`-|p~WdR~F$|AM&6{{^_&m^K3aCW^=s*w|emmyzN1SLDPx1$d zkXNDsANpubWP?F?@F4E-eF$hl=szGRhs9Jg{{SdJ1O6|M=}LY({sbd{O%Qqy#R^yn z1QuY>7{ENgKlm6(Km$91!XOYJd4h%x1t+_1S0_hxEt6Wya)gUQR*)_1V+FO z7z#dS009CF48J-Eq+kdzV0?#$7!SetgUT2Wj0DDM1_$24#ZZHT@8NXYz`)}eH^;O4 zln0Ff9!T>Cm&*HI2dBgT|Br*uiEkH{03I;_V1S4oIgOnh9#a7PNI!D&c}#EsF#s4m zXdk)wKRg0)2jqdcKp~j}{2rI#`GeAE4@?L>Fc9#1l1u)|5J30??Qjs2sGv81IbH$f z7z30R03sOR9J>JWrT~WkKM=5p$R2=lpaaN!a14QHU=%PA$N}YmfP>co!TVQZpz$$? zJmMHIIHpPw{5g^&!Q(`-KaPz=2dsk)nViA^!vf9bU>pE(LIL9Kf8&^R9y0LUa6k1=GY_X{KMX`JK=Ot&20jlPVfbvp^#_wQv1j4L E03aFJ-~a#s literal 0 HcmV?d00001 diff --git a/assets/resources/dolphin/L1_Leaving_sad_128x64/frame_1.bm b/assets/resources/dolphin/L1_Leaving_sad_128x64/frame_1.bm new file mode 100644 index 0000000000000000000000000000000000000000..f1f0e89f0bf92ab9618b0b7416579212bc000e05 GIT binary patch literal 526 zcmV+p0`dI;015&CHUJ;s{|ER#!Tt~MGXFo|{elPhAK?E7_&#_a|NJ~3bO0E_0r~&_ zLc#fgffO%jd@DIoS1`k?5Jg5g@jzA#h^#`;X0Srf|yyOuW z1P%chN6f-ufGCIzOYxwJ1N1&T03g@_@;?xMU?ww55FB^__}Eyg7f^ltE}MHq0vrz` zdwV~*Nz?)(fWV{B9$zc%dTI|phyVW{2cHt(x13-k0P%=1v0-uyo>ePBWB90!&h3?!2O!Q0{p7_dCC zpkcTON(=%R2tDHf@`AtwMH2^>WEM2Q5a0*m79IdSg=IhomxF&H2aW?^2pSj&WB~FK z2t9BdAGLNm4-+9s0px5X$wEJX;sgu4ycA0#_~_I?d*){_fOx>OWpW>gJhl=j(JZhs zIS_oPAn~AVIgrQ@WOy9TXNTbjqrf6G4CF=*s2T-=A_*D<3CuAb20zRwDgDCDW&;)c z9#}s>cwiRH#v>4rD*!yO6Tj~B_v4;S=3w&RKp|EP2fGDB;&>?ZN+2|6;Pj2xeUtqL zWB?^WkORgEVDNb)aR_9BL;w?@$HC%4AAww;egp9H90pn$gh3`M(U>2GBG52-z$4)C QwjYMfA8E#S?_px7MM3xQx^3kK`}Tiwm85(F%jJEqWm+YG_<#TL@Okkq`+Gn<;s7xL5Il1m zIy_WAau3|UL_ahkgU*5bpV)!-;1i7eA94kW1N?u6bO-o8K?J8De83Tc1R#9>;NT$- zD*zy&ZL*Z{%g2S5Vf!RJH(Fg^1i1{$C69#S9!3=ifHE?@z?KL|d% zm=7q30jLxR6_aoeD=-0!D4-k$AOOf@fdj^70APEc-T}a0h&<2nK#&8_{@{_1gV6rt O_dmJ4&+Z;K;UD0o(vidf literal 0 HcmV?d00001 diff --git a/assets/resources/dolphin/L1_Leaving_sad_128x64/frame_11.bm b/assets/resources/dolphin/L1_Leaving_sad_128x64/frame_11.bm new file mode 100644 index 0000000000000000000000000000000000000000..fe93787f2dbaa45e6546910e547ae553947e3827 GIT binary patch literal 294 zcmV+>0oncm03rbZHUJ;s{|ER#!Tt~MGXFo|{elPhAK?E7_&#_a|NJ~3bO0E_0r~&_ zLc#fgf2W^ zzlsC&KlAbX1LA1{SLOPl6%XYHZzwnC|36wsz&$_tR*7If0CA6l+TIU1fDAxH4@mfb zwd3Hq#h!Rdepj07Hd7$hhjgMtU=fF3X~en5Nx{D^;}2uMGSqz}6Q z6oL3I-A zU;%;e5dbi}_5kv;02n@jLBL`F3=cTO2p%&q0|VUt@Hjv{Pw)>IKs?Xz!Vr2N;1(eC UKf$bFAA@-x-vpF literal 0 HcmV?d00001 diff --git a/assets/resources/dolphin/L1_Leaving_sad_128x64/frame_2.bm b/assets/resources/dolphin/L1_Leaving_sad_128x64/frame_2.bm new file mode 100644 index 0000000000000000000000000000000000000000..3050ba38f22ac4c8f1ccac17830bfd3455abaa1f GIT binary patch literal 542 zcmV+(0^$7u02%@SHUJ;s{|ER#!Tt~MGXFo|{elPhAK?E7_&#_a|NJ~3bO0E_0r~&_ zLc#fgfqEK2tVN7p!VtSN3MM3xQx^49f z64)Ex+5O6Pf#{Dgd3>+6?yMXhUl0HOJ`X-6zi()A7Q!F{5D^2%F|(u1K?EO(2ku`Q z510&q1P>Yq?tcyh7GNI!0XUP0A2I+StBHOf`cD)CI1M}S{K4z82c85Tm;~`aJU}5N zktnbL_27Vp;07X5KzIOhzySsw7z30R03r~1zyO0grUi(8FbKdr;vNhIgjQ4ld3Z17 zQuuH994Z(rWB~GjSO8_<&)6`WAGLNm4-*)N#sm`_1pknkC`a(-Q}Ym$hXWkAKaPz= z2a*U&1BZmnApl{4X7eCHm@J9`{)fg1Wr2~%gXB0U2jV{rB8pUboX-!!Za5?fLI|Tk zutZ`s3Ixb-K=SwsO5tX+0Z1N^i9if(nT$pu9#Ft}&p4aU-;Q}RnS;_`1s{JBhs5wv z=#)fI-{HV9dJJyI?4Rf}AOR{5f*u_i_v6Vwh(jb2AOM{QKN~+1+`sTY0r+`^qX(2< g0F@XN!2B@~xkuJylMpDtt%u>W2h<)+(#4;L5FzQ{VgLXD literal 0 HcmV?d00001 diff --git a/assets/resources/dolphin/L1_Leaving_sad_128x64/frame_3.bm b/assets/resources/dolphin/L1_Leaving_sad_128x64/frame_3.bm new file mode 100644 index 0000000000000000000000000000000000000000..0c0c832385caef6fc7bcbcfb485699100bc5df3e GIT binary patch literal 557 zcmV+|0@D2f04V|hHUJ;s{|ER#!Tt~MGXFo|{elPhAK?E7_&#_a|NJ~3bO0E_0r~&_ zLc#DX932A#1cd|R;s3{j^YQ=BgYt0z&jaQHJ{~{+LJv#8Jg^aQaR3H_4>~|Rs0U$k zhyZEk^9Q&19#!;ti_Sq2fCEG%H}reVCIIn|kcR$WeFRV*Fm#Cn+&*7890R})f%xD) zC?W^G0%J76d|D@A(0t2hK6TgA2?39|xQ;9$pFj8IWHH9v~i2 zM@g=T0Ca$QtxgaRI$@B%fYJw%0N@m0c~Pj8KzWQ3h7T;(XEF&a8l;b7BL|d-03q_> zhmXM`LKi!k%<%jm{xEso1LY8j#9}lG1PkU5Kk%TZ_Iov$3_$bXd&q?>#NraA0PhEm zcm3Xe{Btk>g3Fk$E&sa(L*jTSr|}ew|9~zm3~syZpXd+5e;NdU9)1rbjv)*`njmA~ v^Y|&xz}PCWh|3 literal 0 HcmV?d00001 diff --git a/assets/resources/dolphin/L1_Leaving_sad_128x64/frame_4.bm b/assets/resources/dolphin/L1_Leaving_sad_128x64/frame_4.bm new file mode 100644 index 0000000000000000000000000000000000000000..5e74ea12ae20161d809bc90a813fe9be78929a4a GIT binary patch literal 488 zcmV<%yeeI8=-kVJ3*^S`6sVK7#T|)H4`lBX0Km`YpD=k) eBhms0%n#(BICwm~5%75159Hf0d4Y-ri$9QvY}0N4 literal 0 HcmV?d00001 diff --git a/assets/resources/dolphin/L1_Leaving_sad_128x64/frame_5.bm b/assets/resources/dolphin/L1_Leaving_sad_128x64/frame_5.bm new file mode 100644 index 0000000000000000000000000000000000000000..5c556cfdfd3f46173b2f6eb279797637000bb792 GIT binary patch literal 469 zcmV;`0V@6h0MP*eHUJ;s{|ER#!Tt~MGXFo|{elPhAK?E7&*B~r-}nFi5g>enh5-l% z@AeiCt^hn>@SuH&L?4q6{r(6Kvhhd3?Exn!fI;JU2bKaZ4=(^bzu@tt1ImDQAbOj` zA44Jsh`i(x5P8qaM2}g7z@BmN82K!NwL zu~Z_U`}kcp@_>0y3GeLwR;45T*k7|G~gQ4?ejxO?ej~aA`OqCi4>)!L2OvL?oMYhjxF|&aL-?6Ppb`W58`K_LC<{bSXD1+1Da2WmI9#{ytJ%6C_|I$I_K!h9E093Gir^bE) z8~8k=5fFP5NBsu}l)_*SVz~bS=b(xY*a$y}7=BCQ1RsP1e>4gR5Ml`Oz)WV4AbspC zRS2j(EFiH5pTg<4lmpU!Ul4iwKe$!mPh|GQy|NKM%GztU?$+!oVnoUsPU@Z1)F@+QZ zfW%rd0CC0QF$n~L1IA}_h&D!LGns?j@-TpS(SV}>;4j1;d78*Pvq$ovNCD|0@eYbc pg)9Vo9*2KBl!o7_$TtjQ9y%<0*Hd~*c<== literal 0 HcmV?d00001 diff --git a/assets/resources/dolphin/L1_Leaving_sad_128x64/frame_7.bm b/assets/resources/dolphin/L1_Leaving_sad_128x64/frame_7.bm new file mode 100644 index 0000000000000000000000000000000000000000..e992d75c7a000c28168c9a683b2cd8a00694f195 GIT binary patch literal 486 zcmVMe+nUkfkr_Q z54bo%=P;NL-~7T&1W+FkKg4`LkPiSnhwcv>)B}Jo90bN`0tdAy)+X`TSgH|Fef%z) zc|twG=j{IFD@gXFKtbj5zSpv?62N>9gMSa765qG91I{3MC=fie8#+8xKGX2|$Uk!Z z5d6SoA`p2{KXdyKKKuf62h@RLK=zC)#2=7|CIEgya|g5tAF#*{3?3kYgag|h0KrE< zqKpurgV!_(8N37k2LT8@xq=M)6-f(h@=Z)VyHzy^BjPDE}MBlzG09LXZI;uN5DM3 zSK9VfqF4`y|NkEclnaS(+u8x=5CMn?ppXp4&W{xj%o0H${mb-2^FkN^aFQAa?tfwj z%@RT26O8;HGC_E(NFOsme@{P%ax;)U?2$lz(IS9?Q;@3zR|h04abzmBIiZc>&M>KfoDZ!RJH(ClbI9e8>TG15^G3%0vJ^7ruTp zKbSnZfCH9ZJRTo}A6?7`ltch?8H9p?K!I5|0P?c{5&>{BqJVH1fC2J9`1CSBf#Wj( xFg?%e02l`WejxKdwq^l9kOR>EfC2=Jd>)7N01*Ap=l~;opVb0D0)7$wKm>gitj+)c literal 0 HcmV?d00001 diff --git a/assets/resources/dolphin/L1_Leaving_sad_128x64/frame_9.bm b/assets/resources/dolphin/L1_Leaving_sad_128x64/frame_9.bm new file mode 100644 index 0000000000000000000000000000000000000000..6ebc55c16edc741797d5b69ba3482afcaa5896cc GIT binary patch literal 317 zcmV-D0mA+P0678wfENA-U;~5vAK?E7_&>qz12^~VKfwP7_&>q(KV=WVAA9f^{lWPF zf&Bsbe*OJH{txhfgV+2IoH#tM{(yY#!R5a@5xv3ok1=`o{mA|2^UM2R^@H?3|t=KG1jt$I{^1IinM(At_Me}}*z9sqgH@)V4?JpJG?0T4WF z^v%bpKYjQoLb^XRA%o9<1mI^u_a76F03Utzi39w9hI9w`K0yShAbkJPf&?IZz&`*X z59gkL|NaB+K8_!lKEMUfAJ_oF#^A1P~1p07L#i-~^w8-Y_m%fIZ~^^^^nOkS|#{89)P1Etm*= zm0x{IV1C`3Kw{ zUl05g9z*sAmGglI59B@p9uM9E2LPN0@K^H&_&`JApQtn<4FLW@)AI)6Pr>6456ln9z!-F3K7E?FeBggb ze*yzA52n1nVDe{=z`kMfUz88=7g!G5KH&0zLLd|k#UrhCo{!8Pa7LKyDITrVxIW+k zh6Bg#eV>Qa`YiIyQWir${QLjq^5KJrfdKqd!ROciuf!HB;WvyhKB@AsKpy%7)(4cp9x(y|1Jm3;5P4vawqu603MGK z|6k#NL4jZmA`fqbd>-Io2bch0!1@uK93Gem2tBa^^AIC!Y KBj9xacmu%J8sK#R literal 0 HcmV?d00001 diff --git a/assets/resources/dolphin/L1_Mad_fist_128x64/frame_1.bm b/assets/resources/dolphin/L1_Mad_fist_128x64/frame_1.bm new file mode 100644 index 0000000000000000000000000000000000000000..0ec761cbfd5c88d482ea64236928813bae064c6c GIT binary patch literal 540 zcmV+%0^|Jw02l&*&>#^A1P~1p07L#i-~^w8-Y_m%fIZ~^^^^nOkS|#{89)P1Etm*= zm0x{IV1C`3Kw{ zUl05g9z*sAmGglI59B@p9uM9E2LPN0@K^H&_&`JApQtn<4FLW@)AI)6Pr>6456ln9z!-F3K7E?FeBggb ze*yzA52n1nVDe{=z`kMfUz88=7g!G5KH&0zLLd|k#UrhCo{!8Pa7LKyDITrVxIW+k zh6Bg#eV>Qa`YiIyQWir${QLjq^5KJrfdKqd!ROciuf!HB;WvyhKB@AsKpy%7)(4cp9x(y|1Jm3;5P4vaHi0=0J@+7-~-X(KkNSj8vub|4I&R`2-so3^#zDL#v`MJgXBhjU_gV*0RacJA{Y-v e_?bi=kq_a4U|?mBlmq~f598r{5%4;IJOSX1q3;R+ literal 0 HcmV?d00001 diff --git a/assets/resources/dolphin/L1_Mad_fist_128x64/frame_10.bm b/assets/resources/dolphin/L1_Mad_fist_128x64/frame_10.bm new file mode 100644 index 0000000000000000000000000000000000000000..d4207c95d87c1178737332cfb846c4f3ef65a217 GIT binary patch literal 542 zcmV+(0^$7u02%^-P#_Tq1QG!O12ljT;Q#!8zzIJGykL5>0DH;->nI1mAYQU?GJpo2 z94H6~e3%FXf&mDCK(G{mddUIt{wOd$EyYNc9`7=z}mRhrgny-@$j3-BLbA^g9e z_$g>Z?hh#c0uB!$`vb>;1As?^_uxW|;6HN!c-RB-Ss3^{cm?@Cj4&QhH2p&$&hZ0)zhG90flh@xLfXo*%pP z1HsS_r)I7nJPi5)5by`rUSBu(m&Jf3^AD2zNrC_v9f1C!@&}j*LFLxE&qwADGWg5^ z3T8KacwU zA0+t`2Luloa6EI@dEMu%4@eXS0SyO~{2o5x_`qWn2owVVFD3}bY5JCa~EC@Xy7wBi=0q_SD{2suugQ`W&Fc|@q zLFh0X3=SL*pa9rlkZ^uPV36>6nFJoth$r~Id;omRAP_7B03I-aVG2YZQGkDc0p_m| gdqg0f2sk{I;tL>pL4jfbI2aWG5da#91Hc{tz=$g6mH+?% literal 0 HcmV?d00001 diff --git a/assets/resources/dolphin/L1_Mad_fist_128x64/frame_11.bm b/assets/resources/dolphin/L1_Mad_fist_128x64/frame_11.bm new file mode 100644 index 0000000000000000000000000000000000000000..35955bc2021298f14e78677f1134681ff57ed248 GIT binary patch literal 505 zcmV#^A1P}~AkN5#6;P;FNmS7KgKs{vu_v8!KP6ki_)5&H6A0`3; zAb>(35G(~C9j(HD4}m{eKjZ=jzz@#?gZ|(g1U{XbxO{=*eo&7*KDzSx zgT?{i=oipFOYy*9XV3_Tfc~NKzz+sKUmgHFde>R#{K4b^7#)BfKCRTaKE=^^2t0n* z+4z0S<1h!0`~N@u`~T(gUkoAv@Gpow`v3L#@HlV?Bmyvh5c((10YL|*d(Sz%^?~JJ zfKZ4d3e;@e$0tEoTe+%kt75Kve_yG5a!yyil vz(4`<2nYB*z`_6$NQ3+y|M&#^A1P~1p07L#i-~^w8-Y_m%fIZ~^^^^nOkS|#{89)P1Etm*= zm0x{Js!{oma;K$43z(1&bf#d)f9e^G^YpnEsVDkY8JiS|~aDB_; zFb9v?`#%q=_+bF^|9|KIpMU(mTsQ<00r)S7Jo^9j_>0DZ4;aDxL+GC?1OkLX7+^ee z-g(XEtPdh!;DO@~2d}t(Ao77gU=Yy!#wZXd1^`||_W#4dJ>d|@L*#G} r0DptT3?KmC0Pq2T&>#^A1P~1p07L#i-~^w8-Y_m%fIZ~^^^^nOkS|#{89)P1Etm*= zm0x{Js1Rit9339yu*Qi z2anqOKM$(-VH5iRJb%JL{QLjq^5K(&;3e?~pI`pJ5qQvGgAqT7eG}zifKZ4d7zd7f z&pEvHf#j?l5Ikdm_4g0N9#AL@0v;cj#R3HYz(WV{nh<#yM82lMUyL$9E*Jzb{wrbx z56)DQGV0M{4{fF8l&gT%q#^A1P~1p07L#i-~^w8-Y_m%fIZ~^^^^nOkS|#{89)P1Etm*= zm0x{JInK`3Kw{ zOQC{;$bP``pKu`I`@jQ6JRiOSSZ4wGERFq2J_7uo#$XQ~0)FEF@xVaS^baTiJcIEJ zCWt)4@eDwW0t~;XKj0oO!C%Z82?Ga=4L>k%6n+8xgQw;P@>mQW7$2A)>JQ*L2z>iB zaQXwrI1eEC>&xc@{zBFR`!AS$m*aqM3=#n#&IjBca3OH!DIII9^nPITPmnx)Td8n; z+v5SoQa;z&_2p zgWxF&QcRLOV9&uH3@{&207*tL9D!JX4o`rAgVs<5AOT7N>oCAZ0qZdTz(MEW7N`KQ zAoNd|h+qrvzz3^DZ}7-O z0tJ9Hh&{d$@Oy!T9$*231Ly{DaC%@MAoj!y)qW;X2c^UKU|1L#W9$Zie;o_pkAc(y F;15h-#^A1P~1p07L#i-~^w8-Y_m%fIZ~^^^^nOkS|#{89)P1Etm*= zm0x{JInK`3Kw{ zOQC{;$bP``pKu`I`@jQ6JRiOSSZ4wGERFq2J_7uo#$XQ~0)FEF@xVaS^baTiJcIEJ zCWt)4@eDwW0t~;XKj0oO!C%Z82?Ga=4L>k%6n+8xgQw;P@>mQW7$2A)>JQ*L2z>iB zaQc3ralm;8&t6|RAMz5gAK84v2mm}*LqGic|K;-GgT&rH>Ucc*|MmFrAP^q|09WE4MEMHF z1rQ(=BR%Jw-g?0Dm;=TTj}UtMhvE+`5kQ0U7@z~na1Rmtf8q295(GhlUqfK8#u*@h z!LSf~1tCgFl1Gdg_#@$l1L)cy0gPZd01tRg%Q8K6BlFaUa9C>IE@KKv9M1Z*Ck z@Onfr1=Ro#03NLozw;rm2o?a+Aolow?Xci_!U5=V9Xu=_AT#p;1Rhuj2tA=f&>#^A1P~1p07L#i-~^w8-Y_m%fIZ~^^^^nOkS|#{89)P1Etm*= zm0x{Js-G)4;UJLV1F1nd|=7=;6Q&cJAsfx@DDg}JcH%gtB2Hn zJ_u-iHRbbw{-BTuhxoo>@?Vbv0X%^VhZrAlc{>F@Ao1&6XQT56n|xpxYDcSeE)To{ zU=J^~_I@8(;5<#^gQP5mfBEd>}Xl_=C@{|6ho_U@(FJz(eYvD+B@re;WWi zbKZH)=d2GRSkQ_D4_|QnLF*h3%wmCp2aG&_ANYL&1q0xJ3+ikY_`@U$;g~}(6ojz? z1^|y3H-HjA`-lQcF@WR>!~k-91PmUsfGGe9P!Czg0x%C*hyDT&KR~rW1%U^rA_MRT zEc_n12t5J-2NpQMWB~PuM}hCb1CTtg0RHe$LGAwst^mIL0D8bb*Z2e?0Rq540qP19 zc)&sI1`v6`6#@^~1Q;He0WkmsvLPXc1JG#^A1P~1p07L#i-~^w8-Y_m%fIZ~^^^^nOkS|#{89)P1Etm*= zm0x{Js-G)4;UJLV1F1nd|=7=;6Q&cJAsfx@DDg}JcH%gtB2G4 zKOY1%KAQ6RgGLDeh<}UbA0_zk4Wj}V4lq98^AL;-9zAQU^nPITfPNqtYDcSeE)To{ zeh)9T_I@8(;Ko{FBl9G280m$r^>)?A0z_6 z4;=TNb9w6n%3%PZMj#Uadi#gs4>JJA1M?W5V1eTgAIJV5K!Fp7_+L|Cuf`c5R}8`# zfTSge5HJLI!Mp&H2i!msQH%#5Rv-hD;2>c2lmSQpQh<8iFbFXKB*Xs!2cMu?paQ^y z(-9B&1D1XdScUq40~iDl!ZHARd? zJ)jZ@WFi3qzy-t}fT0J-EP!VahXeK*0|%x80uM6Ch6E5m@?VH7f#?2UG!2yi1Vjs= JKpp__1AyX#(Xjvk literal 0 HcmV?d00001 diff --git a/assets/resources/dolphin/L1_Mad_fist_128x64/frame_6.bm b/assets/resources/dolphin/L1_Mad_fist_128x64/frame_6.bm new file mode 100644 index 0000000000000000000000000000000000000000..887a4b866414750fa353f434e7890755aabf34e8 GIT binary patch literal 524 zcmV+n0`vU=00;tr&>#^A1P~1p07L#i-~^w8-Y_m%fIZ~^^^^nOkS|#{89)P1Etm*= zm0x{Js-G)4;UJLV1F1nd|=7=;6Q&cJAsfx@DDg}JcH%gtB2G4 zKOY1%KAQ6RgGLDeh<}UbA0_zk4Wj}V4lq98^AL;-9zAQU^nPITfPNqtYDcSeE)Tx~ zeh)9T_I@8(%$N z{(tG<^C^n_VUh)K%psTxV%;DJ@q>641suR-f$Jh%ns01ONh O00d);od6yH@B{!JY}+dU literal 0 HcmV?d00001 diff --git a/assets/resources/dolphin/L1_Mad_fist_128x64/frame_7.bm b/assets/resources/dolphin/L1_Mad_fist_128x64/frame_7.bm new file mode 100644 index 0000000000000000000000000000000000000000..8e9a34e971bd15694ea1fbbb480a712b73950009 GIT binary patch literal 515 zcmV+e0{r~}0RI7i&>#^A1P~1p07L#i-~^w8-Y_m%fIZ~^^^^nOkS|#{89)P1Etm*= zm0x{Js-G)4;UJLV1F1nd|=7=;6Q&cJAsfx@DDg}JcH%gtB2G5 z30Mp?KAQ6RlST;uh!_U0A4T}^5u`30XW%v=^aq$kv5?N?)_OlMdVC-lXgA|^E)Tu} zeh)8&_I@8(;Ko{FBlFX2vacnC(6M9!7GNr z0paF6^PA6D9#a5#lty6z!{@=}?jMLeph^*rU~f6V`$i}bC^P~efq?%9>;H#?#sR^Q@$WSZ*-3{j$2f^%sWabcl!NKfz5P88k5HNc$#L6J@{1=!2FfdF25&`^kpaZ}j F0Dyyp+Bg6J literal 0 HcmV?d00001 diff --git a/assets/resources/dolphin/L1_Mad_fist_128x64/frame_8.bm b/assets/resources/dolphin/L1_Mad_fist_128x64/frame_8.bm new file mode 100644 index 0000000000000000000000000000000000000000..a430e480a6fff0f3e6a619747de0e6cb40819722 GIT binary patch literal 517 zcmV+g0{Z;{009Dk&>#^A1P~1p07L#i-~^w8-Y_m%fIZ~^^^^nOkS|#{89)P1Etm*= zm0x{Js; zhw2Q#90dJ;P&@Pj;qYJ75As4E0)DW6$OI37pPmK>{lGX32k;+$1qS^vfOFtK>bQJ+ zHE{WZ#a=xK3?Eh>EqQ$KGw1|CfG`pH2g!aT!H<{6fq;PP1L_YYaaaN4+`7+4<_|OI zgUi{vmj~Z50GK#O`F)><)_DM;1Iiix|IhzE|M`5la0wIx@&90mJi7n&_>0Da5`acH zG7$PF%E17kLk@|F2ed#QqOkxRowgwLLkIyS z0QCWgJ*FS{2t8Ni089uynj!#6_&w=>GJ+UJKo5E_J-8rp2b~NbxC#h8zu@$Qcni({ zQ;0np10YHi3jntudS`+11`q)9FyQ_EU_tKp5P8o50uN>QnM6KC=Ku^06(9o*3!y+B H0Pq8VP0`#< literal 0 HcmV?d00001 diff --git a/assets/resources/dolphin/L1_Mad_fist_128x64/frame_9.bm b/assets/resources/dolphin/L1_Mad_fist_128x64/frame_9.bm new file mode 100644 index 0000000000000000000000000000000000000000..487f50b354b087e2a65878b92ca3e653f1b244da GIT binary patch literal 526 zcmV+p0`dI;015(t&>#^A1P~1p07L#i-~^w8-Y_m%fIZ~^^^^nOkS|#{89)P1Etm*= zm0x{Jss;s6yGFo;0{j~F+A3NQ#jJYazLhy&9B85Rftr0uZ> ztOLv)AOOk%>H{XZ019FMfP>k7AOygJ-M%0LpM&Bs0~jHMWB~Yv1J{BJFd3c5A7*n0 zpZp$&@h><0>>%~LNC1Tbz#)hpU;&SV;Z{h}gM;!3{D1@70Rab}^L`I?_?bi=Mb-cm Q3>6>)4GDPw9suwJ09n4>asU7T literal 0 HcmV?d00001 diff --git a/assets/resources/dolphin/L1_Mad_fist_128x64/meta.txt b/assets/resources/dolphin/L1_Mad_fist_128x64/meta.txt new file mode 100644 index 00000000000..93e59e49b43 --- /dev/null +++ b/assets/resources/dolphin/L1_Mad_fist_128x64/meta.txt @@ -0,0 +1,23 @@ +Filetype: Flipper Animation +Version: 1 + +Width: 128 +Height: 64 +Passive frames: 7 +Active frames: 13 +Frames order: 0 1 0 1 2 3 4 5 6 7 8 9 10 11 12 13 12 13 12 13 +Active cycles: 1 +Frame rate: 2 +Duration: 3600 +Active cooldown: 7 + +Bubble slots: 1 + +Slot: 0 +X: 67 +Y: 24 +Text: Am I a joke\nto you?!?! +AlignH: Left +AlignV: Center +StartFrame: 15 +EndFrame: 19 diff --git a/assets/resources/dolphin/L2_Soldering_128x64/frame_0.bm b/assets/resources/dolphin/L2_Soldering_128x64/frame_0.bm new file mode 100644 index 0000000000000000000000000000000000000000..3fc3644065c7118acc02181bf59501908732b125 GIT binary patch literal 699 zcmV;s0z~}*0Jj4FfCfGf$p7FUupbCNU>qQN{0AfeDf|P74_<&hL4%kFv=0CeUw}U$ z;QxSl0sBA)zwdqz*j|DT1s}vdgXE6`-|ikC&OYPf7r=cdfcGbeJmc}D`*b3CAG{16 zU9fxV^-+412Js*Nhw|~C|NKYyIQ@ghI{@Hc+wuSXugYP76pcVikN|*`h5-zKLxb^u z2b2l{6bGRIV1M}j;2tm-1dtw{{rZrHD$M^G($N}S! z2Z?aK!1Dk7!RHWwhui=$_=f@>42~UJqSM`&-CydE|Od3pbU@dk(pe)D*Gq;Medn)&zO^^3>E140LmD=|NxemDa1 zh0p8|37|YdBfpq3igEt3^j~*Kuh<)aUfs$XY5Gs&7yaCY%odWRyQSg+4w=1yg|qkID<<)vNDd9{|YR;1AKy{v_k^4~~`r2*5zqBLet&|I!k9 z(O?iy_x^nVfW$YDaCp!G<3@l$;Lzy50s#>GK>R=Z_~>-x(YAXca{ze!ATtx0KqHa( h24lnIhl9ivFpznG2ski+AcM*d4`jHA#Oh?hfB?*oKqQN{0AfeDf|P74_<&hL4%kFv=0CeUw}U$ z;QxSl0sBA)zwdqz*j|DT1s}vdgXE6`-|ikC&OYPf7r=cdfcGbeJmc}D`*b3CAG{16 zU9fxV^-+412Js*Nhw|~C|NKYyIQ@ghI{@Hc+wuSXugYP76pcVikN|*`h5-zKLxb^u z2b2l{6bGRIV1M}j;2tm-1dtw{{rZrHD$M^G($N}S! z2Z?aK!1Dk7!RHWwhui=$_=f@>42~UJqS^Z)ja(BB|=SRLi({sY7sAR+tD#AATKgT`y;--Fga9uN%(9yqMT{(bo13(6lp zus|k&@dS?keQ@9k$K?;d1I8HuN0fSavJiPf|K0$3bOGa^2b5;V@`C?7FbR-6U^oc) zJhZt_loRpefN+812U3sVh9L9!ao{j0A3{I)v&_rlFB_B!G0cF#VT<#hm&_h8d|*6g z4)c%~&Sm0&XCQDI0DS@C1R1zUW!UwIhvH}g8ZG*9fd`*}Iw14FQXm>g1x5fbBKY@Y z`$z=?;8YNJ@F21IL410(edw6yVbP!G{}OTdhsR3*h+rUb>;wbh=l@7a=S6@*Ki~L! zh+-SaI6P&}?)rI1eAh55xbzj)zVo8)x(90|$@712H+20yvc%#pVbH7=Q?2 WAoBnez=R<5gM--MG4LS#6Ndmx6F-&! literal 0 HcmV?d00001 diff --git a/assets/resources/dolphin/L2_Soldering_128x64/frame_10.bm b/assets/resources/dolphin/L2_Soldering_128x64/frame_10.bm new file mode 100644 index 0000000000000000000000000000000000000000..f808193580805a0d405d7316ec33cc3708428222 GIT binary patch literal 699 zcmV;s0z~}*0Jj4FfCfGf$p7FUupbCNU>qQN{0AfeDf|P74_<&hL4%kFv=0CeUw}U$ z;QxSl0sBA)zwdqz*j|DT1s}vdgXE6`-|ikC&OYPf7r=cdfcGbeJmc}D`Fbr z;9&=kY#vwm;5@Z@sJ%)9c#r?V6@05Tu}|7a%==MeNb|NeYDLMlT4_&@L(06a;9 zz~}F(?t#L8)58DL5rOJGRqKzH{e7q3%Ty&^-wM;?FZLh`erCEF2UbFva=L z%ja^jU?BkUm^;l1Ao7_K1`-M$0DT=L|C_*Q5#ZTWL+>;PjN#%iDv&(90nrDXg5dz< zKx&Rb7m0j(vVEiiA>e>{AQeso7C$I2k5;d}M~Gx@@CWGU{}OTdhsR3*f?yzOk%4?X z|LF-l=%Athf9KE$3`2Pb2aNz8G;9O~+A($j#2CZj|KG<$r!I}N!4q%{L*W6KoXPqQN{0AfeDf|P74_<&hL4%kFv=0CeUw}U$ z;QxSl0sBA)zwdqz*j|DT1s}vdgXE6`-|ikC&OYPf7r=cdfcGbeJmc}D`*b3CAG{16 zU9fxV^-+412Js*Nhw|~C|NKYyIQ@ghI{@Hc+wuSXugYP76pcVikN|*`h5-zKLxb^u z2b2l{6bGRIV1M}j;2tm-1dtw{{rZrHD$M^G($N}S! z2Z?aK!1Dk7!RHWwhui=$_=f@>42~UJqS^Z)ja(BC0=z$^~(^Zxje?GWy2V?S!{{iC+fFsI0C=hwX|DF(ebOGa^2b5;V@`V08a0!q+U^oc) zJhZt_lq2EifN+812U3sVh9L5ScscMG6c3>v{8{E@@fVHC2{`OPU@*n`&&%g>fkCqr z7!1MQasv6xxKJI%4g)|Bpgcf>Hwg_hp0N=8O#nlR|4uL<^Y8~m9+@8ok^xbG3&_4b z**?%#J`0V=9y|yveo$W?tzUXXIoNb(`TxY66e01_k&15~z(5qE{*aT-ivWm!zwq}E z#5a&|c+dgkMs5rnc?*sM$MFO3|L^0W)4*VM&&SRN4qQN{0AfeDf|P74_<&hL4%kFv=0CeUw}U$ z;QxSl0sBA)zwdqz*j|DT1s}vdgXE6`-|ikC&OYPf7r=cdfcGbeJmc}D`*b3CAG{16 zU9fxV^-+412Js*Nhw|~C|NKYyIQ@ghI{@Hc+wuSXugYP76pcVikN|*`h5-zKLxb^u z2b2l{6bGRIV1M}j;2tm-1dtw{{rZrHD$M^G($N}S! z2Z?aK!1Dk7!RHWwhui=$_=f@>42~UJqS^Z)ja(BB|=SRLi({sY7sAR+tD#AATKgT`y;--Fga9)Ar89yqMT{(bo13(6lp zutFw)@dS?keQ@9k$K?;dSRs(e0z9MB#gK!_7yj@A%b*V&_&lRFKa>~w;f73s;{m`& z!R4jOe4w9?95aLu7&?@H1ThDn!;c+-K>88?#hzwg5qR97QI2GG0}NlB{JvoEgX1qS z8H2p!1@oDBpc%^?27n(xc!36P5*c^BVj=jN0EUZxoM1uc;0}m9@Dzy#k^xbG3&_4b z**?+%K=>5|9y|yveo$W?tzUX3IoNb(`TxY6ej)MFyGH>7k6<7l4?p@sPdY3D5&r+f z>;X~ULBZod2aOs527_avalm-~AbubH{B$~T7~4OeI2b&B5E+Tgpb^BV<}WZnIK%)$ X2?v+}rUW4eq#Pc{0gr(P;G8%BxBEH0 literal 0 HcmV?d00001 diff --git a/assets/resources/dolphin/L2_Soldering_128x64/frame_4.bm b/assets/resources/dolphin/L2_Soldering_128x64/frame_4.bm new file mode 100644 index 0000000000000000000000000000000000000000..a961f4c0a17681a1c74e2d84e79a148aad724c00 GIT binary patch literal 693 zcmV;m0!sY>0I>r9fCfGf$p7FUupbCNU>qQN{0AfeDf|P74_<&hL4%kFv=0CeUw}U$ z;QxSl0sBA)zwdqz*j|DT1s}vdgXE6`-|ikC&OYPf7r=cdfcGbeJmc}D`*b3CAG{16 zU9fxV^-+412Js*Nhw|~C|NKYyIQ@ghI{@Hc+wuSXugYP76pcVikN|*`h5-zKLxb^u z2b2l{6bGRIV1M}j;2tm-1dtw{{rZrHD$M^G($N}S! z2Z?aK!1Dk7!RHWwhui=$_=f@>42~UJqS2Y|N1+?Jbr-k z{z(Djpa0MQ+B-vhh2sFQJIl}f2Z%I4L-)VHpdSnfJZ8Rq_&sOy$OPhq4;)rve?I(h z1?4ZkSRoTYc!EcNKDclPWAcmtED%U!0UlA|K!eUF{P2Uzpbs4QJfk*0lqd1yf=q$q z0l-JW<)zAep&t)CBZLnaKY}0lA&5Mno(_Bl1q0|u{}y?fd`07Of=)XS7z{CfbMpDz zpipeUJZ28_kQdHn!hr4|a2f!80pbK1xJYT3_yzz!6F?B+uhWbOJp2LC2c|{=q<~al z0`f19c2BewkAeeo2af^^ACwozt5@EU4t5HgXpn2anqQN{0AfeDf|P74_<&hL4%kFv=0CeUw}U$ z;QxSl0sBA)zwdqz*j|DT1s}vdgXE6`-|ikC&OYPf7r=cdfcGbeJmc}D`*b3CAG{16 zU9fxV^-+412Js*Nhw|~C|NKYyIQ@ghI{@Hc+wuSXugYP76pcVikN|*`h5-zKLxb^u z2b2nd6bGRIV1M}j;2tm=1dtw{{rZrHP-5s;UI*I%px2mpVO z`b791w0H%49$)BuqF)3Dk01ZfhloW;KoQhW0pv^`2S0sRfWR<-@$>+M9*gn^j}!j` z^iSsi@oz8YPvr-l0s{YU&0HQZ77*Z5=pSegf*%P7uaEFQA1C}uIC(%k@BjTB;2u9f zc}FCG@z4L~|Lq;2zCiM@JIl}f2Z%I4L-(JE#{q!{jMvY<2dsWPAQ})naaoD{`|-dR zlsy+^C*#Ke;RD7Fr60izLFe$}z+g~5gn#j8nU};~Hz*WinE`;q7w11Om^@(k zzvVEiif$)HNAQeso7C$I2k5;d}6CK_F{T%<|PCpR%>0l8I1PxL!FNdG~At#*{ z0SNzp=gBM7f{zT>g@%TVyCo+IX5~G;> e`61x(1q>t}U;+*dAP6AxgM--MG4LS#6Ndn7H99^3 literal 0 HcmV?d00001 diff --git a/assets/resources/dolphin/L2_Soldering_128x64/frame_6.bm b/assets/resources/dolphin/L2_Soldering_128x64/frame_6.bm new file mode 100644 index 0000000000000000000000000000000000000000..2f030833a27a95c21247e158074d5fe721ef4e51 GIT binary patch literal 712 zcmV;(0yq5u0K@|SfCfGf$p7FUupbCNU>qQN{0AfeDf|P74_<&hL4%kFv=0CeUw}U$ z;QxSl0sBA)zwdqz*j|DT1s}vdgXE6`-|ikC&OYPf50nsIf%KjO&KOTXdB@{R^9P(y zBlm%W%eD_Vz&y2jsJ%)9c#r?V=Qt0&<3IoSgUaAPdB^M?G1vzJ{@;)P?S4}afTU^& zRDc8oq$T0FLxb^u2b2oo6bGRIV1M}j;2tm;gpeMd{rZrHD$M^G($RH4mfILfu?gy9u?hhygLINLf0LS7S2zWe@LZBde$RZGk5IpJl586z} zqb~=pzgPqi0RJKMiGV$5@Cx`mztH(af(Q>DKmVT(5Q>n1Bj^X2FnApO^0En z0)um)Fc@O|=jHRcc%V4oc+4H=ATONA1UYCN2Y??yc!36P4;dajHZ>6Y%?$%2zg!?y zAbEHLq7OO+;sMBj)gS`$FOPOlv=a(^e2@yK0t+9M7ssnt-oQQqk-NYjqo4dq$KoFy zECLaLfvQFY@bmwqB=e%cAfNC2`T+rmZy@0DpaaH@0D-}w(S8I1A^3s#fA{gw>B*yP u_C)3Y@%TVyCo+IXBk&Bzhsh5Ih$vwo^8gTVVE{n~lpG$(aS@5s$%6o#P)TY4 literal 0 HcmV?d00001 diff --git a/assets/resources/dolphin/L2_Soldering_128x64/frame_7.bm b/assets/resources/dolphin/L2_Soldering_128x64/frame_7.bm new file mode 100644 index 0000000000000000000000000000000000000000..4519819ea5c7e9d0127fbaf538f5aa276c881d4c GIT binary patch literal 732 zcmV<20weta0N4WmfCfGV7(hN_|A2W$0rLUygZ2T!2b6#WKLN=A3V#6N1J|GrP+;Z( z<=H`&OaarjzAtI!uJEq|Mv%+LINLf0LS7S z2zWe@LZBde$RZGk5IpJl586!O83}kjb^5>{fCu>xq)Y+pM}Sws<^G4tCGbFa@&Ekz zc!X4h0Ubo}9z?<5bNAJCP~idN=m7{l7vv8fC;kWMpUwf|-e1h0$`3jO1^(ZfxIADi zA;725KF}WoJ`xXKAK-pIPxzE@@_>2Y|N1+?Jbsz*c*i7w@z4L~|Lq;2zFzQn*d68P z{sY7sAR+tB;p&mVgT`y;--FgK9}o=)9yqMT{(bo13(6Nius|k&@dS?keQ@9t$K?aR zgT@&EN0fSavJiPe|K0$3bOGa^2b5;V@`C?7FbR-6U^oc)JhZt_loRpefN+812U3sV zh9L5RPB_pQ6c3>v{8{E@@fVHC1qSCpU@*n`&&%g>@j!9F@t8Z#KwmkK2y)Ok4*))Z z@d6Co9x^<5Y-%C*ni>X4ez-uYK=SYhL>_bt!~>B5sz3$gUmonAXeJc+`5+Ze1QtIi zFOOEQy?}fJBX@v5M?d(JkHkJYSOg;h15}I);phKIN#{j?K|kO5^a2AA-a*0RKnIN) z0Rw|WqWlO1L-7Of|L^0W)00No?1{_)Pl0{-8R|LuNL3;?8R z0#twm1f(zsWC9!?i}*aCPzazs2m=HE$M*p7fWRbx^!M-7gg+br*l7Utm+#?!{1`lF z0P(~J*d9N>oPIzL9DqDah3*HJ|LzYsgakg|0guEu5b${*g+M^{kVGL6AbHd9AGDdm zG7|85>-B&^01xsXNSFiGj{vWO%l!|OOW=U<G{Jc)zA=kKcOp~3^l z&;k&8FUTG|Py7$jKb!-_yuX=0lpb^l3;n+}aCpF2LxE4AeV{%Fd?X&eKfwHapYbT+ zMw89FhaaKmVWqw04I13&sIpcbA{|4-ja8hwp!ZDn|kj8Lyvy4_W;1 zU^F0j;e*`fHloP?vfWV-A2>;^GGcSm|Zcs_b zVgmt&FV22nJCq6ym3igEt8cGaefnh<)aOA;n*=5Gs&7 zyaCY%rbYqCfYl%Z@-L5ePqc22f&=7$RX7k>{Gh%)TE6s%cX$KzbN`7rC`03=BNQD{ zFeNDeq$KmAz#<>-{Q3a_h;Ja^@t_07jNBMBaxcINkKza6|KG<$r+~oipNO2m9zO^S n#O6>4=lTJd`1v8=@dXSd9$*3v3?K*~@`HofE-~;R{1b-&_Jm6b literal 0 HcmV?d00001 diff --git a/assets/resources/dolphin/L2_Soldering_128x64/frame_9.bm b/assets/resources/dolphin/L2_Soldering_128x64/frame_9.bm new file mode 100644 index 0000000000000000000000000000000000000000..1339c607e63f0d52de7d04b4076e94a820e1a774 GIT binary patch literal 698 zcmV;r0!94+0JZ}EfCfGf$p7FUupbCNU>qQN{0AfeDf|P74_<&hL4%kFv=0CeUw}U$ z;QxSl0sBA)zwdqz*j|DT1s}vdgXE6`-|ikC&OYPf7r=cdfcGbeJmc}D`Fbr z;9&=kY#vwm;5@Z@sJ%)9c#r?V6@05Tu}|7a%==MeNb|NeYDLMlT4_&@L(06a;9 zz~}F(?t#L8)58D(8>|NlpL2anUflp_fAGynPj`$uSRm%Pj-aR-l|_zw_hfQRq*hrm7pVdzbK`|x`8 z*MguBc;d4Y`S;_1FDzXBgdp++j{bdcG>ik~2Tl#*1dllM@bWl001;PbV2bX|4AoGx1ARLGd zQHUb(FOPOlw17lB5Dz2*slbBA0l5{1PxL!FNdG~ zAt#*_6hH6$`T+rmZy@0DpaaH@fPlfE5q1E?7{lTJ-^W9zE{(In6L1Ve;Q^SO$^jgQ gz%w2nAP`~zp;M3n1A@UIc|pPKml*gEehI^X01SRc?f?J) literal 0 HcmV?d00001 diff --git a/assets/resources/dolphin/L2_Soldering_128x64/meta.txt b/assets/resources/dolphin/L2_Soldering_128x64/meta.txt new file mode 100644 index 00000000000..b705bf62361 --- /dev/null +++ b/assets/resources/dolphin/L2_Soldering_128x64/meta.txt @@ -0,0 +1,23 @@ +Filetype: Flipper Animation +Version: 1 + +Width: 128 +Height: 64 +Passive frames: 9 +Active frames: 5 +Frames order: 0 1 2 3 4 5 6 7 8 9 10 9 10 9 +Active cycles: 1 +Frame rate: 2 +Duration: 3600 +Active cooldown: 7 + +Bubble slots: 1 + +Slot: 0 +X: 71 +Y: 28 +Text: I am busy rn +AlignH: Left +AlignV: Center +StartFrame: 10 +EndFrame: 13 diff --git a/assets/resources/dolphin/L3_Hijack_radio_128x64/frame_0.bm b/assets/resources/dolphin/L3_Hijack_radio_128x64/frame_0.bm new file mode 100644 index 0000000000000000000000000000000000000000..cf2120ff470ed140a0d47f8adcfedd64a8d20cd8 GIT binary patch literal 524 zcmV+n0`vU=00;vAfII=<4*+-rz#ahb2Y@^Q;12+J1Hc^RUH~ZK7yu!Ef~mg&l>gs< z0+a|ongB_2=NJzFKIZ&r9DHANybK@1{0G+80S$qCz@u&L?SMnp2bF384}p6D^MCHa z;m|ICK6moyY2a$|_{Be1B z_1@fzk3(N>7S?zlxT`9#A0ogVTq9g@ew41d(XP=VSg~;Hj|y3A{t&2LqOX zBrqU(%pwvm*nHFC4;V-A;4y&t56?soFT@N!Fvf^Kd8K*sdIr~590(U zs62`y4-ou9;1~gjhQ)p~0s7tW2a<#X=NDfII=<4*+-rz#ahb2Y@^Q;12+J1Hc^RUH~ZK7yu!Ef~mg&l>gs< z0+a|ongB_2=NJzFKIZ&r9DHANybK@1{0G+80S$qCz@u&L?SMnp2bF384}p6D^MCHa z;m|ICK6moydAvUe z4CbAH(1Y5=_NBlv@yzD~LFxymuRHCPz&0?<#{z&4SzY_JCBSe2<6sB2t&TES06g#j z_w~xK7yu)fFdrfL=z-<Ggk>LU;sg2?ePEr literal 0 HcmV?d00001 diff --git a/assets/resources/dolphin/L3_Hijack_radio_128x64/frame_10.bm b/assets/resources/dolphin/L3_Hijack_radio_128x64/frame_10.bm new file mode 100644 index 0000000000000000000000000000000000000000..1354c78f2ce9d20f8e2b08bad75be024c8b4018e GIT binary patch literal 550 zcmV+>0@?im03rhafIt8H0hjbC;12+J1Hc{t@CSfA0pJe+cmu!?uZ39z`kHnw)XbGA?pLmwE%~} zy@2_@_h9ho7eF67`E+st0xO6;`d`8WiKJjOAoj6;sc;N`6C=RTdV%Td&i`d_4UCf|z@P)xSAP9Ta2yHddcY5D zU;pbRfN%rjV88?4*DAnZ2jegY$6OvT0{Fay9`gBW6i?!y5PR3_um}%|P7f3M=-eY# z4~*V0FA#gz^x&a{#3T>}`sy9SPT;0k$7k=NpgZVC3@91cn6=9t;9u5Rrbv=ARIF!Y9FT7>Rtoa!<%S{|EAhPy^%- zU-Ud~P-+4FLFENYoC^Sd7$H4DLu*4rY^Z^6M{0Si0fBpab3Vf�Q4{f5&!@I literal 0 HcmV?d00001 diff --git a/assets/resources/dolphin/L3_Hijack_radio_128x64/frame_11.bm b/assets/resources/dolphin/L3_Hijack_radio_128x64/frame_11.bm new file mode 100644 index 0000000000000000000000000000000000000000..c15289b5ec4e1bf2622a9d4e63dabf35ff48e539 GIT binary patch literal 572 zcmV-C0>k|Q05}5wfII=<4*+-rz#ahb2Y@^Q;12+J1Hc^RUH~ZK7yu!Ef~mg&l>gs< z0+a|ongB_2=NJzFKIZ&r9DHANybK@1{0G+80S$qCz@u&L?SMnp2bF384}p6D^MCHa z;m|ICK6moyM;G#;+THpei>dh@^8Tmxey$#5tZuD#Z~-@3~0->EJGfjrMx z0ps8L-+TXkU;pbRfN%rjV89E+9y5$^JbiMk1^|9D0C@Gmn5fFIDpmcnf zp7Y|Lf8wRFCXWIH9}s$Q|M0MQ#tGvDk!Z!|WBz~Osj-6yNIo!fd1wMd0*DU=0WgS2 zzhU!Fh&*8v;JA!LzF#>fgs< z0+a|ongB_2=NJzFKIZ&r9DHANybK@1{0G+80S$qCz@u&L?SMnp2bF384}p6D^MCHa z;m|ICK6moyM;G#;ROdh@^8Tmxey$#5tD^_AbhQd|cDd7iKX+gJbk$zU7+ z_}DN2_w~xK7yDIo{EcjsC^iG+9t zG5_(!<>TT1B|@gs< z0+a|ongB_2=NJzFKIZ&r9DHANybK@1{0G+80S$qCz@u&L?SMnp2bF384}p6D^MCHa z;m|ICK6moyM;G#;+k_jh%>`t!fpTmxey$#5tZuYH%D-P_9V->EJGfjrMx z0poe!-}is*U;pbRfN%rjV8D8}`g!-iRu3Oss{w!?jKCf~ukD||x(AP39xwv#QwTB2-kz-2Z#&A9`*hBC}S|m1Oa}! zhj8DxG5-V(!2oZpv;9-P&)-ErfIrv4{kCslF9AsiJ>$PR(fmQ=V;}zDAj zh=ayO`{U>Qm!A~-{}nBWM0gM&`2){~|Am9Z`ZNe2e1+v>{(s=9v4%hm;vX0}9JB!; zfkZG6F$lyYP(C7k0pke21;#KRDn5EoNznt#@P8;}0!8BoxB4D8C^Z27qVj^J&IN!U zi9LbjVGwwS;uf9}h`|@-K*>)zAo9E54gs< z0+a|ongB_2=NJzFKIZ&r9DHANybK@1{0G+80S$qCz@u&L?SMnp2bF384}p6D^MCHa z;m|ICK6moydAvUe z3?`9)(1Y5={-wY%@JxpTLFxymuRHCPz&0TApaa%de*H;s8~}LO0qv_}jFtcoJODkj z{<&5I01p{}J@5Tsc)$zd@)3K><)~3Vihx1yTdu$$De(u1{d8^-uLs5t5EqC&>HDxy z#$l2O0{wLk;lFTW{s`lo%LzKVeWf3Ji4Y~H|L0+JAW$9{FA_=CvCKmItp zynH?6s8%5JkwEDADJ3VxKL5o_Vh<<~d_n2M|H8rNK!QlLV)L>8Kk!u8fCSzl@q>ZO zKoS@bJmwJz7wkT1@du0}_;47&e23?v2bbao9~fl-J|Oo0L&fC=pdZv;P*l0Vum|yi z6Vx6>5eJBVA#e-;#6x1g8UX!n_yfs80rQUm34lT8z!$CjJ|q-(p*+9)`S=`IVh^MN Q1IPRcAXxy-TqLo801PJV%>V!Z literal 0 HcmV?d00001 diff --git a/assets/resources/dolphin/L3_Hijack_radio_128x64/frame_3.bm b/assets/resources/dolphin/L3_Hijack_radio_128x64/frame_3.bm new file mode 100644 index 0000000000000000000000000000000000000000..dc0fb9b79cc78fac3cda74455bf92526b8504378 GIT binary patch literal 529 zcmV+s0`C0*01X2FfII=<4*+-rz#ahb2Y@^Q;12+J1Hc^RUH~ZK7yu!Ef~mg&l>gs< z0+a|ongB_2=NJzFKIZ&r9DHANybK@1{0G+80S$qCz@u&L?SMnp2bF384}p6D^MCHa z;m|ICK6moyx?2gVN&7l=LU z`|wc4VUh>}{dErEzi?yz2pxg|-&tq+r+uHkih%%suY>z+-oRc0k`Q~xes!bxgUH4| z{y4n6d_Ux zgMrIH5*QFX<`D@O>^^Dn2aF^5a2UXRhv%XPm*NH=7-axHAol-5#pMQ|AJkq@RJp*g z2l0Xv)E-3<2Z(+la0~#%Lt?)g0R3+G1Ia=G^N#@ufI;WL7p?q0Boud{Jiq(-_#9Yb T52OJD$NUK(SpdykB(Z=1M>Oxj literal 0 HcmV?d00001 diff --git a/assets/resources/dolphin/L3_Hijack_radio_128x64/frame_4.bm b/assets/resources/dolphin/L3_Hijack_radio_128x64/frame_4.bm new file mode 100644 index 0000000000000000000000000000000000000000..025477a7a943d7eac253ddddafe16f07fea0a0a4 GIT binary patch literal 571 zcmV-B0>u3R05<~vfII=<4*+-rz#ahb2Y@^Q;12+J1Hc^RUH~ZK7yu!Ef~mg&l>gs< z0+a|ongB_2=NJzFKIZ&r9DHANybK@1{0G+80S$qCz@u&L?SMnp2bF384}p6D^MCHa z;m|ICK6moy#QwTB2-kz-2Z#&A9`*hBC}S|m1Oa}!hj8Dx zG5-V(!2oZpv;9-P&)-ErfIrv4{kCslF9AsiJ>$PR(fmQ=V;}zDAjdC0$f zeE*X3;-7!wrLhN;2tGjb;s4=a^PoWk9JtssDFT@N!Fv JGgk>LU;r>`30MFC literal 0 HcmV?d00001 diff --git a/assets/resources/dolphin/L3_Hijack_radio_128x64/frame_5.bm b/assets/resources/dolphin/L3_Hijack_radio_128x64/frame_5.bm new file mode 100644 index 0000000000000000000000000000000000000000..89a4cd6acf85afc12c608940bc379d5b1464e61c GIT binary patch literal 574 zcmV-E0>S+O06GHyfII=<4*+-rz#ahb2Y@^Q;12+J1Hc^RUH~ZK7yu!Ef~mg&l>gs< z0+a|ongB_2=NJzFKIZ&r9DHANybK@1{0G+80S$qCz@u&L?SMnp2bF384}p6D^MCHa z;m|ICK6moyEJGfDao0 zJbV7%r~kLB|NUgJ0D0goL&5v*|KRcU%CHy#_{;(0wcGc8b?|ug!Q%igi^zRn|F`}> z_Xmu=T7?t%s0Y>D?$P#p(0JGDum}o#LE?X18-#1Y@q@$#;tzWM{1h>mWP$*{T|>BU z+!+6Y2Vj6V)>;0k-)HZlpg@lx1>$^;)8I6U}&_*gvX5J?w|UUom{{tBBA0Gq@?gHR9Z4=5^J;8+P4?4H2#D2O~m z@e6=p1|tMtl>;T`r09X;cfcM>5D%Pq2uuPGJ^;OM;qf4&y$R+2-_O9}!w`KS2p&J+ MNdm|QYT+e}07|gs< z0+a|ongB_2=NJzFKIZ&r9DHANybK@1{0G+80S$qCz@u&L?SMnp2bF384}p6D^MCHa z;m|ICK6moygT??~7m$PAUoAq3{8R!Ddi{0*0Z)iLPwS&_jd(sVc!0b??_b}7 zhBFM1Ko{$%cMbc4AMilz5C;0oKh-TT1B|@ZO zKoS@bJmwJz6c31>KzPDGhXITS$bNbtd43>a@rF<&UNC!qq2ls`P!H-aC@NgwSONHx z*d9d@2Z(+la0~#%V2kpg57zI1Jd_|GIPegd1Ri_=df&t1K}UKM%m2ThfyIU(`alpo Of54IjkPOwrOBeu5#pKBV literal 0 HcmV?d00001 diff --git a/assets/resources/dolphin/L3_Hijack_radio_128x64/frame_7.bm b/assets/resources/dolphin/L3_Hijack_radio_128x64/frame_7.bm new file mode 100644 index 0000000000000000000000000000000000000000..fb6d9bd292c739951e00a03612b86833b5222191 GIT binary patch literal 655 zcmV;A0&x8S0E+_ufIt852lspgKhS;iz(e>4-y8%#zgs<0+a|ong+SfFdhJW`Tz5N zG!8y5l&I41Fni(o&u{_Gwd0_X$Y z;r`#tqmT#@TtV!i9sF8g4;lbH%EMoU*a72!{{z^>Ao1V>%lHpousn6}Tm%I;Keha8 z!Gqy}z&`8v2b5|V0QG~`KqeZz1_1_$1IIKkPhxmM<>HaRIxwL6N<3fuygmU@qTo6p zfdCwjJl-FK2XjuqXhH2_|5D%>|E6Dop!IgYySuI5*PZ^#;2RlcYk@$ud+faK?%r2^ z{Yh{f38q@W4;#+@|GWQc|NmJm1AreJ1_RZ<)6c#7xnKX+D!^a|<1h!0tNUl~?xlau zxIAD5@p%ucy{-Q-23Po(%TS_!6#)9KcYfWnpR4>=>#zt4d_m%WT^w(JUJr~OATJPm zcdN6rHKZgN~2g{H1l72zw_<@JU89)z^J%7;gc|oWL^#_y{ zE^sUX{9uIj2a!ZU;vZQboc=Hj0K`LLzZwR5d3lj=zxR9rof1`a$*CIJVZ0A6_y p{rn^(6nCV8VdMYr=iqV&z2mSC6afRr{4F2=@9*sa->Za{FaVQOM?U}n literal 0 HcmV?d00001 diff --git a/assets/resources/dolphin/L3_Hijack_radio_128x64/frame_8.bm b/assets/resources/dolphin/L3_Hijack_radio_128x64/frame_8.bm new file mode 100644 index 0000000000000000000000000000000000000000..a0377f635fe25d6ae38494e2e28ec168af6f1f3d GIT binary patch literal 645 zcmV;00($)c0D%Jk|NZ~_|M&_Z3G;);_z%CBJbnQF`UCIo0uXceiGk!D-3L^J| z&NuYD3?IUn5PMnjAN{TZ8v=R)3!o2ykjtZx z2oan?^A?x`#()o+{4T%`90&LxTmX500q^tI!Eg{1;QrU~uLci>2LSu4*dQSCjYA+F zuzJV@!&iX7AkhGL=7s6({)5lOBY<>aLG+Y(zxjB40;5O3bU^|DIUaleOZY%_G`t3c z9@a1QE&-43Wq2A7R`StyE@tgPm*Gn$0|I`PJ1Jg=*53Be4-PiB> zxcs78g&U0(KsK)bH`m+QhsJ?LfIw5?4-@+6|M(h^d|>ebc!S=rxCIPm86bc!*HG>o z_Xa=Uf!H7o^_G9CciH>ss1OJG_&>JI>;>Q{AqTv7=UP9AJd9)i1Ro%I@c;0zc%Mdr1P_qBtbfn^6*e%)0lY)w2P2k)zyEwE%~}y@2@7+&i#%bPJ#liT>hU9DqQI;tz5V#iju9pabT=3$O#n z0saTq03Kh!d~4vi2nuk2XZY6x2g3t^ebw==1dM7K0QG~`KqeZz1_1_$1IIKkPiOQV zekmLSqY4kCqs9Nr!@+|^z;rScHu4_9LwW0+&T zdEe}=0kM{5xD*RlUh7@&-DP+0)RzIko@cB8@$da_z5l+i|Milhm&hJ9dh7xMpAdMT*GK=s z(}Uv&hzrCX^l|X`zcBd(0e-rNaNIaC_yj`10B@|b{Zqcr-$g)xKi9$iwr^lB0Z9lw zuABcR@;tv=__%1Pk`El}cen>q32l9qc zBw8?gf1%@YgHR9Z4=5^J;8+P4?4G{xc^E_jf@01)tm2VkEkh=8RH9=ZSk literal 0 HcmV?d00001 diff --git a/assets/resources/dolphin/L3_Hijack_radio_128x64/meta.txt b/assets/resources/dolphin/L3_Hijack_radio_128x64/meta.txt new file mode 100644 index 00000000000..1d415b4b85e --- /dev/null +++ b/assets/resources/dolphin/L3_Hijack_radio_128x64/meta.txt @@ -0,0 +1,14 @@ +Filetype: Flipper Animation +Version: 1 + +Width: 128 +Height: 64 +Passive frames: 8 +Active frames: 8 +Frames order: 0 1 2 3 4 5 4 6 7 8 9 10 11 12 11 13 +Active cycles: 1 +Frame rate: 2 +Duration: 3600 +Active cooldown: 7 + +Bubble slots: 0 diff --git a/assets/resources/dolphin/L3_Lab_research_128x54/frame_0.bm b/assets/resources/dolphin/L3_Lab_research_128x54/frame_0.bm new file mode 100644 index 0000000000000000000000000000000000000000..db283e81fbb46514ec3a63dedb87bba98daeb086 GIT binary patch literal 611 zcmV-p0-XH;0AB(C9v}oX06F|W|M~y;20#3`JpT|Kgajs8?>{Feln0y|4Y0(-C|H1b ze#7Yjgbl!hQGMmP^FfkZ{(4=*JIk|}|Q#BCT6`h2W`agbO8 zUe7-Od}#U4@H~1P4h3P}!192K27NKCgT@U8C!TZU4=M~g;13_bAXDh;6iC5=_{D9tfb60|+AxcxrGc1{wqGfrH#I zFh$UV$NuRUAk1~a@(CBh2dw^-#2!@PD1**04;T;f05=#8I0hgCg9FQe4>)8L9C!=} z{9rZ!dP0r`0JvZvKI!m1W`WXx!-Zq+;mlAa0)}!0#r}Z!AaVFSz#fwWuz&~_F!*F( z&`?Nc0vHcJ<_;Ga2dn}n4>*6q3viYd#bPmN1h5=j4j=vtFyjpbZXoffD~B~v1BMS0!Vg3qc>D(j1F-*q3?7~ge*j`T1L%MXMh`v)KESLHh=bRFH!b|) xaRBTC(n22@;1qe0==1{c4`bMf2Qi0(z%7CJ5D(+ROd0S!garY-UjV~52cXVC@<9Lq literal 0 HcmV?d00001 diff --git a/assets/resources/dolphin/L3_Lab_research_128x54/frame_1.bm b/assets/resources/dolphin/L3_Lab_research_128x54/frame_1.bm new file mode 100644 index 0000000000000000000000000000000000000000..c600743700f179ba45f3713af0d427024c0b683c GIT binary patch literal 614 zcmV-s0-5~*0Ad0F9v}oX06F|W|M~y;20#3`JpT|Kgajs8FFofaln0y|4Y0(-C|H1b zeuL=&gblVi*Vs{7vFNSUds*4@7v6$R3bLgaSUV zF#4v(5Rn;sJp2Lj&VPa9(BN<@4)+I)1W+^Sjbt7$XfQo8K=Po&t^o1;0t9}2Cs^b# z5MX%#2x1@s2bDts1^HjW=ji{x1RkOF03G-r)({Yz#6QwFEXW@hfDq_6kWYm?3^Cvk z;1_}qJp>E*UmSqstPzL>unH*g!9eZ-fnbXWT4E0>2l(zh5kV*h5JnpC)ZkDIGzZxO z2e@Ehi=hXP{n9W&nCpY&5-)@gS^X)9JgLG_2b^FYFdyUqZZI5h3_u442bTaIaL6b) z@E8&Jz-$2Yg&Yb2aKJ!))8Kl|1Em3n3dh~Un4n4p4CD)o{Q>YmT9()Xafmk6C2d@Bb zTlvJ|0oVtmgg!ICDDxxH=mp>&$FUF&V-E*_TLbVQAIF54GvIp&3Ilk)0fuf5K-I|j AUjP6A literal 0 HcmV?d00001 diff --git a/assets/resources/dolphin/L3_Lab_research_128x54/frame_10.bm b/assets/resources/dolphin/L3_Lab_research_128x54/frame_10.bm new file mode 100644 index 0000000000000000000000000000000000000000..694302a9de7918f0009e738f417aee84929cc94a GIT binary patch literal 576 zcmV-G0>AwM06YQ!9v}oX06F|W|M~y;20#3`JpT|Kgajs8FFofaln0y|4Y0(-C|H1a z{(s=~fWiji4`F%WAQ1rjUtk&Vc?bqT4?=ju_#g0jNIn4(1Ld6mKx2@~WCOWRcd$IXkvtp&@n2DjkU{6tfMm3Sv7B52LevrY zgU1zU6^t^#@(=)wL;xW1;?zOo0|%$0|NozZ#!FIw90UR&2ERZjwde=N0uPG_eBrP! z@P0?-|HA*l?pz#HpjbYjc}IXlfP;g}B_y0cKUeTrjz$4sj6g3C1o(wV{Xc*(NrWvi ztUxmYvj0ch#Gn{Mlud(R1c^Xl;P>4E2^v4~ki;MmC;`4`{>`4n793gXT2=jDH}1^mv2X86<#s1EcsD2sA<>MHmz^P);C_ z@!(+hKM_1<_3cxEV0<=bAA8&^YMpFP7%pt(_jsnU6)DW1% zh3SCDumk|1^+<{YKnn{Z68!)T3&0ix064&W*c=DE2gD~q4FZ>7A20}z6te*NkV^oi O7ze{pY5-D3m;pc_5AB-( literal 0 HcmV?d00001 diff --git a/assets/resources/dolphin/L3_Lab_research_128x54/frame_11.bm b/assets/resources/dolphin/L3_Lab_research_128x54/frame_11.bm new file mode 100644 index 0000000000000000000000000000000000000000..246b955cf93c8b6abccaef6f44dd1b8fcf01e296 GIT binary patch literal 585 zcmV-P0=E4D07U`-9v}oX06F|W|M~y;20#3`JpT|Kgajs8?Qy>+`d;`bH6T!eM0P%w<1Ri}T21`kR2cO}nAoays z1!4~%0SrU{Ao1eVLF4$pgU`|b|IfkWC8+{O@m~j+0PoNV?RY*h%fLPCA@jh%>;d^7 zmBs*~5Cazn6)3=ef#)6p4gwAjER>Uh0fGMkVmTNEf-wLj3VeT`_-76P!4P=FBngp# zWDVEGEIQ0!9He2gc|SKmmpW#vuTKKp=xL2Z$g*0)HTTR-hpA4v0Ki zg9Hea2Rs810L%a+4`{>`4p8U;;6d*i1d2RL0uOj(kXAFnh{1uR5fHe*p^}1VqsIZm zfrH%qa1Q_^jv}!rAU$s%2pB!Z;s7b|2t*?wR*1|)>42l~90EraAeP1)4?l(-AV2|! zgvuN*KlUF0V-Ny|&w>9BkK_ITSXmIDAIxBNfCCG_76bqw`mi_;cn^q9f*J)bz&>CR XASq@6^B|T1N&FxOY7IaNNYel)t_A1i literal 0 HcmV?d00001 diff --git a/assets/resources/dolphin/L3_Lab_research_128x54/frame_12.bm b/assets/resources/dolphin/L3_Lab_research_128x54/frame_12.bm new file mode 100644 index 0000000000000000000000000000000000000000..b6fb1130bb895889494bb5ade77a02bde7d64d3f GIT binary patch literal 571 zcmV-B0>u3R05<{v9v}oX06F|W|M~y;20#3`JpT|Kgajs8?>{Feln0y|4Y0(-C|H1b zf5GVigbl{$PW`(gUcXM5qN{j$Y?L&5Mnlr2>m`&KzT+3=VWyFD^hl;o$Q4Kxh#Hc>DwBo`b-F<2Zqz;2w~8Fg*W?^nruNfdGyx%sy0bd3hl7 z2n4a7egOE<^PlJpav4m3cPZ}m2cMEBgMfZ3>M>FYJhPuD21`gQ8O6XPEkRGD0~Kf$ zj55IT5CDus03h+=)Is9|2dAU||DS`#OHzOw1Ogxizd$Fo=m*9E4~qzV;jl08en;j1 z!vDeUTpU!OSU#Y6M}R|sgM-T@B%DA$SMXSlMgd@qKravk_=QLPKW_?DSVGep!~-xZ zFZ6x9N&$p9MA$X}NR$R14}H)ek)!_^3_<|{fI$Xg4-i1WJ|FlPJ?l^qd4E6RvIdAm zpgG_ekBFo|_KZP5KREVHN0I;$lFVFzcya8Z91B?gFfxvsfd_r^(&?$BS^8kqfOE3?a1h5KGfP6Iu JpamppfE4a4{Feln0y|4Y0(-C|H1b zf5GVigblZNCreNFnGtz;#ePmJcH%p#C)WX z@VLR?5QvR~01sUxE&&9G1Ir*$5qN{k$Y&TQ9>x3~evkkDfAWB6JP|>8fE)Y|7=%=KG%$PcLE|5b#6J}9{zM^_zb^tK2MT9Le2aW^z$AG~B z;`StforZh`8I0jlDDeliXbLdlK-vT25P(3S5J8ycfTRx?z&;~TP&onw9xTBNh$LV! z=+Hdia{znBB#A=cKmqeuI0yhC~6P5ffOzqZ9xjyjs2bT_F4@nFI7?mIP z{sA9@mq;F$2y_GS!!3+4h#>XC3JV8-g~kEz0H-gD;RU!A$R3bNfD~Zg$SlGP4?xk! B`X>MY literal 0 HcmV?d00001 diff --git a/assets/resources/dolphin/L3_Lab_research_128x54/frame_2.bm b/assets/resources/dolphin/L3_Lab_research_128x54/frame_2.bm new file mode 100644 index 0000000000000000000000000000000000000000..1025137e462b44c2341e193471c8b457d4451c1e GIT binary patch literal 618 zcmV-w0+sy%0A>OJ9v}oX06F|W|M~y;20#3`JpT|Kgajs8?>u;K^nyrYW-I1e0-Lm*#YJs^FyKMwk_VLr9dHMa;1D45={mx!Dc}Cya0zmyn=iw;9-vd zhXDr%rh*0hFOL9nRtUrb*aZ}L;GlO12ZI0!7=(ZxbPw^|cp&kBs0I*58t~NMPz*E& zVFL%dXkd$>2ao;IFhQ8>gX9t~gb#84DTq9&!chmDU>-1URk2L^%fAlv|X z!yusJz+hlI$PIuVkfVV>E*J<7+I|mNpmd-x;aKgt^AKo+Mj6N#7y1L>f!yPh0D4Rg z!T=yx&gKz=K|vv$2w*(_m^o`OLFoXAgU%oDi|{3daafF60W1d>1Bd^Ma5%$38;Cq= z3gdudj6(*8h6o-aQh;wT6fk&}5PBf<$KWU`;s1aP9-a(;0^tMTA4C9BFnRDX_5~QI zgdU@F-_AS&K?kISJ~O~5^CQ=Y12{qIdl3NUAo1rIhu}azj0_$DI0vwRpf`_!a7M%c EAd|oRBLDyZ literal 0 HcmV?d00001 diff --git a/assets/resources/dolphin/L3_Lab_research_128x54/frame_3.bm b/assets/resources/dolphin/L3_Lab_research_128x54/frame_3.bm new file mode 100644 index 0000000000000000000000000000000000000000..e623a1c0fa5cba36a8a2f364e19c96d49a644e13 GIT binary patch literal 608 zcmV-m0-yZ>09*n99v}oX06F|W|M~y;20#3`JpT|Kgajs8?>{Feln0y|4Y0(-C|H1b ze#7Yjgbl!hQGMmP^FfkZ{(4=*JIk|}|Q#BCT6`h2W`agbO8 zUe7-Od}#U4@H~1P4h3P}!192K27NKCgT@U8C!TZU4=M~g;13_bAXDh;6iC5=tAQr$VqsIjUxHpA@EFo!#Jg6VzxbR>SMhK(?j5Xn@z@Qjt54r{qaKOPA zLje*Cq+o+F*9XWXUkDuRra#0%CzE6f=-6FZ2h%Ul;_y9+LyGfCv^pvlyBR z2@K#v0q6X|@!{b0fJDLP4@eEpSXUK@#h?7QS@!$>1e>g3O uJ!B#Ao&iUh9*jUOfc8CzfO8OdbOOvDfdKw6Fn9#m9>M~E-aG}tnS;Vi*Vs{7vFNSUds*4@7v6$R3bLgaSUV zF#4v(5Rn;sJp2Lj&VPa9(BN<@4)+I)1W+^Sjbt7$XfQo8K=Po&t^o1;0t9}2Cs^b# z5MX%#2x1@s2bDts1^HjW=ji{x1RkOF03G-r)({Yz#6QwFEXW@hfDq_6kWYm?3^Cvk z;1_}qJp>E*UmO7BtPzL>unH*g!9eZ>QUr`arXcd5e~#n9fKC`9kPsM1NMJPVh<{CltJehf$JbY$N=16IN%t74h#=206gK4 zP;uZeBk_RP0qF`j6awLZfZM0Q^_mAt0}d6ByMZx4lnNQh7Z>^i;DP(#a{ziw4#EH+ zSjXV;gF!(doCsh%|Cl&@Fdnc7m^|VC2wmb>R~3lGpc24wa5#VXEW?a65x9fKpsqLu zI36%)cwm9zB`5~-0mCl|VF#iQJbnX%1K5AS1`kgLKY{Ro><^*OJ9v}oX06F|W|M~y;20#3`JpT|Kgajs8?>u;K^nyrYW-I1e0-Lm*#YJs^FyKMwk_VLr9dHMa;1D45={mEOrk1|zUOhybKu^WbCb3c(17 zJ$M6h-_9ox4!}JmA@QC8N0}avKraCHJ&1sF7{Feln0y|4Y0(-C|H1b zf5GVigblZNCreNFnGtz;#ePmJcH%p#C)WX z@VLR?5QvR~01sUxE&&9G1Ir*$5qN{k$Y&TQ9>x3~evkkDfAWB6JP|>8fE)Y|7=%=KG%$PcLE|5b#6J}9{zM^_zb^tK2MT9Le2aW^z$AG~B z;`StforZh`8I0jlDDeliXbLdlK-vT25P(3S5J8ycfTRx?z&;~TP&onw9xTBNh$LV! z=+Hdia{znBB#A=cKmqeuI0yhC~6P5ffOzqZ9xjyjs2bT_F4@nFI7?mIP z{sA9@mq;F$2y_GS!!3+4h#>XC3JV8-g~kEz0H-gD;RU!A$R3bNfD~Zg$SlGP4?xk! B`X>MY literal 0 HcmV?d00001 diff --git a/assets/resources/dolphin/L3_Lab_research_128x54/frame_7.bm b/assets/resources/dolphin/L3_Lab_research_128x54/frame_7.bm new file mode 100644 index 0000000000000000000000000000000000000000..c9b99a0144864d530c76fb9864ad23ebd5351253 GIT binary patch literal 585 zcmV-P0=E4D07U`-9v}oX06F|W|M~y;20#3`JpT|Kgajs8FFofaln0y|4Y0(-C|H1a z{(s=~fWiji4`F%WAQ1rjUtk&Vc?bqT4?=ju_#g0jNIn4(1Ld6mKx2@~WCFPFaCvzmcsK=M9x!DfgU_V^$!P^*4==+|N9GS4 zRiIWN@&FLTKmrdQEkqtai}*bKAOHOP9x_^xB!3m~d4LZ60G`)_;~cyL-ohU|3=Y5_ zk@;L;3LyY7aB)(M2lyUw;1J*-;PS~yI1m^g@D?MHfLJ3C0zjw7`TvG+;0zLB3ruSe z49ETl0O^aw6e02zP;f$bQAfyx~KJP1AGK#@m@Ktb;ek_yInF&Hp3f+80f6f#gv6nNk` za4>tHjsf5Vk;GOd1P86-;R6S_yg&s$0SJU-3eg#eeJ~V$1As{4gc8`pf#>kUqzC{o z@R>t}=l;Xs3}OIK`S3sC@%(?l3kxC?1Nn>&umE9r0>FR-A65qe?*Z`%&_h6_*ayr4 XBn2$MK4cQWDL;e&?LnvkNg7}UlQy?A6d%eNqrfDR ze?Q`~28cwUIp7$Nh@?RFj6p!-;A;pzV^9dk@(2G%h&`c_NC$vAKY@UQL?R?nfkPz( z;t3BP1`l)b6UKhh5m>|)B?JeeM4({z7mxs~0{Feln0y|4Y0(-C|H1b zf5GVigbl{$PW`(gUcXM5qN{j$Y?L&5Mnlr2>m`&KzT+3=VWyFD^hl;o$Q4Kxh#Hc>DwBo`b-F<2Zqz;2w~8Fg*W?^nruNfdGyx%sy0bd3hl7 z2n4a7egOE<^PlJpav4m3R~_sRKO|2F0IUPX45SiyXFgC2mXKB;^87UgK9CGmpjIIA z01(7L0uLT7L>@nj_&og||NQ(OGFp%%e--d~fDZitp4Wrp9J~YG!XG>g4!|Fg`CMQM zApkLOaZ-#2_#ScK5a1x-^2td!5Eviu79){>SR)VuK&Qv~|Auhe!j%>fw8pUj%zxl; z4w$?_LZBEzSWSaq1dIY`4~@_ufCCH%j6wkdfI$Xg4-i0r1pYwwtw2HK9T0f41_%)- z4tNG20hj9HGzyz=Pg22^4sg1Rn6oAgpJD5rYFrA|Y{sLnQ>!M~(xB0|&YI z;2r=;97SSKKziOj5HNd-!~j#^5Qs)Vtr3`q(*Z}|I0TL;K`o3p9)AovK!5`e36wZq zf9yU0#vla`p9B6MAIJOvu(BaQKbXMl00tL;EC>KW^ Date: Thu, 14 Apr 2022 20:02:16 +0300 Subject: [PATCH 14/20] [FL-2433] Archive: Fix favourites rescan (#1112) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Archive: fix favourites rescan * Archive: fix favourites move Co-authored-by: あく --- applications/archive/helpers/archive_browser.c | 3 +-- applications/archive/helpers/archive_favorites.c | 8 ++++++++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/applications/archive/helpers/archive_browser.c b/applications/archive/helpers/archive_browser.c index 418fdb47b6d..10f5ea3e294 100644 --- a/applications/archive/helpers/archive_browser.c +++ b/applications/archive/helpers/archive_browser.c @@ -120,13 +120,12 @@ void archive_file_array_swap(ArchiveBrowserView* browser, int8_t dir) { ArchiveFile_t_clear(&temp); } else if(model->item_idx == array_size && dir > 0) { ArchiveFile_t_init(&temp); - files_array_pop_at(&temp, model->files, model->item_idx); + files_array_pop_at(&temp, model->files, 0); files_array_push_at(model->files, array_size, temp); ArchiveFile_t_clear(&temp); } else { files_array_swap_at(model->files, model->item_idx, swap_idx); } - return false; }); } diff --git a/applications/archive/helpers/archive_favorites.c b/applications/archive/helpers/archive_favorites.c index ef8f1b2257c..ac5b9d294f9 100644 --- a/applications/archive/helpers/archive_favorites.c +++ b/applications/archive/helpers/archive_favorites.c @@ -106,6 +106,8 @@ static bool archive_favourites_rescan() { if(file_exists) { storage_file_close(fav_item_file); archive_file_append(ARCHIVE_FAV_TEMP_PATH, "%s\n", string_get_cstr(buffer)); + } else { + storage_file_close(fav_item_file); } } } @@ -116,6 +118,7 @@ static bool archive_favourites_rescan() { storage_file_close(file); storage_common_remove(fs_api, ARCHIVE_FAV_PATH); storage_common_rename(fs_api, ARCHIVE_FAV_TEMP_PATH, ARCHIVE_FAV_PATH); + storage_common_remove(fs_api, ARCHIVE_FAV_TEMP_PATH); storage_file_free(file); storage_file_free(fav_item_file); @@ -163,10 +166,12 @@ bool archive_favorites_read(void* context) { bool file_exists = storage_file_open( fav_item_file, string_get_cstr(buffer), FSAM_READ, FSOM_OPEN_EXISTING); if(file_exists) { + storage_common_stat(fs_api, string_get_cstr(buffer), &file_info); storage_file_close(fav_item_file); archive_add_file_item(browser, &file_info, string_get_cstr(buffer)); file_count++; } else { + storage_file_close(fav_item_file); need_refresh = true; } } @@ -224,6 +229,7 @@ bool archive_favorites_delete(const char* format, ...) { storage_file_close(file); storage_common_remove(fs_api, ARCHIVE_FAV_PATH); storage_common_rename(fs_api, ARCHIVE_FAV_TEMP_PATH, ARCHIVE_FAV_PATH); + storage_common_remove(fs_api, ARCHIVE_FAV_TEMP_PATH); storage_file_free(file); furi_record_close("storage"); @@ -308,6 +314,7 @@ bool archive_favorites_rename(const char* src, const char* dst) { storage_file_close(file); storage_common_remove(fs_api, ARCHIVE_FAV_PATH); storage_common_rename(fs_api, ARCHIVE_FAV_TEMP_PATH, ARCHIVE_FAV_PATH); + storage_common_remove(fs_api, ARCHIVE_FAV_TEMP_PATH); storage_file_free(file); furi_record_close("storage"); @@ -335,6 +342,7 @@ void archive_favorites_save(void* context) { storage_common_remove(fs_api, ARCHIVE_FAV_PATH); storage_common_rename(fs_api, ARCHIVE_FAV_TEMP_PATH, ARCHIVE_FAV_PATH); + storage_common_remove(fs_api, ARCHIVE_FAV_TEMP_PATH); storage_file_free(file); furi_record_close("storage"); From 935db361b8dd034a6255cd1264be210637ca0739 Mon Sep 17 00:00:00 2001 From: Anna Prosvetova Date: Thu, 14 Apr 2022 20:05:45 +0300 Subject: [PATCH 15/20] CI: clean up after archiving update bundle (#1116) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * CI: clean up after archiving update bundle * CI: fix bundle path * CI: trust me i know what i'm doing Co-authored-by: あく --- .github/workflows/build.yml | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 9e5f3c7296c..308aa942884 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -102,14 +102,17 @@ jobs: - name: 'Bundle self-update package' if: ${{ !github.event.pull_request.head.repo.fork }} - run: | - set -e - for UPDATEBUNDLE in artifacts/*/ - do - BUNDLE_NAME=`echo $UPDATEBUNDLE | cut -d'/' -f2` - echo Packaging ${BUNDLE_NAME} - tar czpf artifacts/flipper-z-${BUNDLE_NAME}.tgz -C artifacts ${BUNDLE_NAME} - done + uses: ./.github/actions/docker + with: + run: | + set -e + for UPDATEBUNDLE in artifacts/*/ + do + BUNDLE_NAME=`echo $UPDATEBUNDLE | cut -d'/' -f2` + echo Packaging ${BUNDLE_NAME} + tar czpf artifacts/flipper-z-${BUNDLE_NAME}.tgz -C artifacts ${BUNDLE_NAME} + rm -rf artifacts/${BUNDLE_NAME} + done - name: 'Bundle resources' if: ${{ !github.event.pull_request.head.repo.fork }} From 3e5b0306630c5018696c0c106db0230658cf7730 Mon Sep 17 00:00:00 2001 From: Dmitry Pavlov Date: Thu, 14 Apr 2022 20:14:41 +0300 Subject: [PATCH 16/20] [FL-2458] Change iButton read success picture (#1115) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: あく --- applications/ibutton/scene/ibutton_scene_read_success.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/applications/ibutton/scene/ibutton_scene_read_success.cpp b/applications/ibutton/scene/ibutton_scene_read_success.cpp index edf7d914e12..c4523904d32 100644 --- a/applications/ibutton/scene/ibutton_scene_read_success.cpp +++ b/applications/ibutton/scene/ibutton_scene_read_success.cpp @@ -44,7 +44,7 @@ void iButtonSceneReadSuccess::on_enter(iButtonApp* app) { dialog_ex_set_text(dialog_ex, app->get_text_store(), 95, 30, AlignCenter, AlignCenter); dialog_ex_set_left_button_text(dialog_ex, "Retry"); dialog_ex_set_right_button_text(dialog_ex, "More"); - dialog_ex_set_icon(dialog_ex, 0, 1, &I_DolphinExcited_64x63); + dialog_ex_set_icon(dialog_ex, 0, 1, &I_DolphinReadingSuccess_59x63); dialog_ex_set_result_callback(dialog_ex, dialog_ex_callback); dialog_ex_set_context(dialog_ex, app); From 9b654332113629f24b04b48b61e2c43c91a66fa8 Mon Sep 17 00:00:00 2001 From: Nikolay Minaylov Date: Thu, 14 Apr 2022 20:46:07 +0300 Subject: [PATCH 17/20] Region names fix (#1118) --- firmware/targets/f7/furi_hal/furi_hal_version.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/firmware/targets/f7/furi_hal/furi_hal_version.c b/firmware/targets/f7/furi_hal/furi_hal_version.c index fdc4d2030ec..e580c978c57 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_version.c +++ b/firmware/targets/f7/furi_hal/furi_hal_version.c @@ -255,15 +255,15 @@ const FuriHalVersionRegion furi_hal_version_get_hw_region() { const char* furi_hal_version_get_hw_region_name() { switch(furi_hal_version_get_hw_region()) { case FuriHalVersionRegionUnknown: - return "D"; - case FuriHalVersionRegionJp: - return "Jp"; + return "R00"; case FuriHalVersionRegionEuRu: - return "Eu"; + return "R01"; case FuriHalVersionRegionUsCaAu: - return "Us"; + return "R02"; + case FuriHalVersionRegionJp: + return "R03"; } - return "U"; + return "R??"; } const FuriHalVersionDisplay furi_hal_version_get_hw_display() { From c209ec56fc0b5efe6c91d44a8663206b15f15b09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=82=E3=81=8F?= Date: Fri, 15 Apr 2022 19:31:25 +0300 Subject: [PATCH 18/20] Release Candidate Bug Fixes and Improvements (#1121) * Notification: use all input for backlight, otherwise it is causing issues on repeat. Dolphin: rework debug tools. * Notification: remove unused variable * Applications: fix incorrect count in system apps list * SubGhz: fix memory leak in settings * SubGhz: fix incorrect frequency in newly created keys * Loader: make cli command parallel safe --- applications/applications.c | 16 +++---- .../desktop/scenes/desktop_scene_debug.c | 4 +- .../desktop/views/desktop_view_debug.c | 14 ++++-- applications/dolphin/helpers/dolphin_deed.h | 5 ++- applications/dolphin/helpers/dolphin_state.c | 17 +++++++ applications/loader/loader.c | 9 +++- applications/notification/notification_app.c | 5 +-- .../subghz/scenes/subghz_scene_read_raw.c | 3 +- .../subghz/scenes/subghz_scene_receiver.c | 3 +- .../scenes/subghz_scene_receiver_config.c | 12 ++--- .../subghz/scenes/subghz_scene_set_type.c | 4 +- applications/subghz/subghz.c | 3 +- applications/subghz/subghz_i.c | 2 +- applications/subghz/subghz_setting.c | 44 +++++++++++-------- applications/subghz/subghz_setting.h | 9 ++++ 15 files changed, 92 insertions(+), 58 deletions(-) diff --git a/applications/applications.c b/applications/applications.c index d5e7efd79f0..aba50fee7ef 100644 --- a/applications/applications.c +++ b/applications/applications.c @@ -131,7 +131,7 @@ const FlipperApplication FLIPPER_SERVICES[] = { #endif }; -const size_t FLIPPER_SERVICES_COUNT = sizeof(FLIPPER_SERVICES) / sizeof(FlipperApplication); +const size_t FLIPPER_SERVICES_COUNT = COUNT_OF(FLIPPER_SERVICES); const FlipperApplication FLIPPER_SYSTEM_APPS[] = { #ifdef APP_UPDATER @@ -142,7 +142,7 @@ const FlipperApplication FLIPPER_SYSTEM_APPS[] = { #endif }; -const size_t FLIPPER_SYSTEM_APPS_COUNT = sizeof(FLIPPER_SERVICES) / sizeof(FlipperApplication); +const size_t FLIPPER_SYSTEM_APPS_COUNT = COUNT_OF(FLIPPER_SYSTEM_APPS); // Main menu APP const FlipperApplication FLIPPER_APPS[] = { @@ -181,7 +181,7 @@ const FlipperApplication FLIPPER_APPS[] = { }; -const size_t FLIPPER_APPS_COUNT = sizeof(FLIPPER_APPS) / sizeof(FlipperApplication); +const size_t FLIPPER_APPS_COUNT = COUNT_OF(FLIPPER_APPS); // On system start hooks const FlipperOnStartHook FLIPPER_ON_SYSTEM_START[] = { @@ -228,8 +228,7 @@ const FlipperOnStartHook FLIPPER_ON_SYSTEM_START[] = { #endif }; -const size_t FLIPPER_ON_SYSTEM_START_COUNT = - sizeof(FLIPPER_ON_SYSTEM_START) / sizeof(FlipperOnStartHook); +const size_t FLIPPER_ON_SYSTEM_START_COUNT = COUNT_OF(FLIPPER_ON_SYSTEM_START); // Plugin menu const FlipperApplication FLIPPER_PLUGINS[] = { @@ -246,7 +245,7 @@ const FlipperApplication FLIPPER_PLUGINS[] = { #endif }; -const size_t FLIPPER_PLUGINS_COUNT = sizeof(FLIPPER_PLUGINS) / sizeof(FlipperApplication); +const size_t FLIPPER_PLUGINS_COUNT = COUNT_OF(FLIPPER_PLUGINS); // Plugin menu const FlipperApplication FLIPPER_DEBUG_APPS[] = { @@ -307,7 +306,7 @@ const FlipperApplication FLIPPER_DEBUG_APPS[] = { #endif }; -const size_t FLIPPER_DEBUG_APPS_COUNT = sizeof(FLIPPER_DEBUG_APPS) / sizeof(FlipperApplication); +const size_t FLIPPER_DEBUG_APPS_COUNT = COUNT_OF(FLIPPER_DEBUG_APPS); #ifdef APP_ARCHIVE const FlipperApplication FLIPPER_ARCHIVE = @@ -352,5 +351,4 @@ const FlipperApplication FLIPPER_SETTINGS_APPS[] = { #endif }; -const size_t FLIPPER_SETTINGS_APPS_COUNT = - sizeof(FLIPPER_SETTINGS_APPS) / sizeof(FlipperApplication); \ No newline at end of file +const size_t FLIPPER_SETTINGS_APPS_COUNT = COUNT_OF(FLIPPER_SETTINGS_APPS); diff --git a/applications/desktop/scenes/desktop_scene_debug.c b/applications/desktop/scenes/desktop_scene_debug.c index 99fcad87ef1..4945f7acebb 100644 --- a/applications/desktop/scenes/desktop_scene_debug.c +++ b/applications/desktop/scenes/desktop_scene_debug.c @@ -34,13 +34,13 @@ bool desktop_scene_debug_on_event(void* context, SceneManagerEvent event) { break; case DesktopDebugEventDeed: - dolphin_deed(dolphin, DolphinDeedIbuttonEmulate); + dolphin_deed(dolphin, DolphinDeedTestRight); desktop_debug_get_dolphin_data(desktop->debug_view); consumed = true; break; case DesktopDebugEventWrongDeed: - dolphin_deed(dolphin, DolphinDeedIbuttonRead); + dolphin_deed(dolphin, DolphinDeedTestLeft); desktop_debug_get_dolphin_data(desktop->debug_view); consumed = true; break; diff --git a/applications/desktop/views/desktop_view_debug.c b/applications/desktop/views/desktop_view_debug.c index 75a9bab1ab0..6ac62b49bc1 100644 --- a/applications/desktop/views/desktop_view_debug.c +++ b/applications/desktop/views/desktop_view_debug.c @@ -111,7 +111,10 @@ bool desktop_debug_input(InputEvent* event, void* context) { DesktopDebugView* debug_view = context; - if(event->type != InputTypeShort) return false; + if(event->type != InputTypeShort && event->type != InputTypeRepeat) { + return false; + } + DesktopViewStatsScreens current = 0; with_view_model( debug_view->view, (DesktopDebugViewModel * model) { @@ -125,11 +128,16 @@ bool desktop_debug_input(InputEvent* event, void* context) { return true; }); + size_t count = (event->type == InputTypeRepeat) ? 10 : 1; if(current == DesktopViewStatsMeta) { if(event->key == InputKeyLeft) { - debug_view->callback(DesktopDebugEventWrongDeed, debug_view->context); + while(count-- > 0) { + debug_view->callback(DesktopDebugEventWrongDeed, debug_view->context); + } } else if(event->key == InputKeyRight) { - debug_view->callback(DesktopDebugEventDeed, debug_view->context); + while(count-- > 0) { + debug_view->callback(DesktopDebugEventDeed, debug_view->context); + } } else if(event->key == InputKeyOk) { debug_view->callback(DesktopDebugEventSaveState, debug_view->context); } else { diff --git a/applications/dolphin/helpers/dolphin_deed.h b/applications/dolphin/helpers/dolphin_deed.h index 20e18d70541..1f63db3ff8f 100644 --- a/applications/dolphin/helpers/dolphin_deed.h +++ b/applications/dolphin/helpers/dolphin_deed.h @@ -52,7 +52,10 @@ typedef enum { DolphinDeedU2fAuthorized, - DolphinDeedMAX + DolphinDeedMAX, + + DolphinDeedTestLeft, + DolphinDeedTestRight, } DolphinDeed; typedef struct { diff --git a/applications/dolphin/helpers/dolphin_state.c b/applications/dolphin/helpers/dolphin_state.c index 08a7dae36cf..bfd467b8b0e 100644 --- a/applications/dolphin/helpers/dolphin_state.c +++ b/applications/dolphin/helpers/dolphin_state.c @@ -126,6 +126,23 @@ uint32_t dolphin_state_xp_to_levelup(uint32_t icounter) { } void dolphin_state_on_deed(DolphinState* dolphin_state, DolphinDeed deed) { + // Special case for testing + if(deed > DolphinDeedMAX) { + if(deed == DolphinDeedTestLeft) { + dolphin_state->data.butthurt = + CLAMP(dolphin_state->data.butthurt + 1, BUTTHURT_MAX, BUTTHURT_MIN); + if(dolphin_state->data.icounter > 0) dolphin_state->data.icounter--; + dolphin_state->data.timestamp = dolphin_state_timestamp(); + dolphin_state->dirty = true; + } else if(deed == DolphinDeedTestRight) { + dolphin_state->data.butthurt = BUTTHURT_MIN; + if(dolphin_state->data.icounter < UINT32_MAX) dolphin_state->data.icounter++; + dolphin_state->data.timestamp = dolphin_state_timestamp(); + dolphin_state->dirty = true; + } + return; + } + DolphinApp app = dolphin_deed_get_app(deed); int8_t weight_limit = dolphin_deed_get_app_limit(app) - dolphin_state->data.icounter_daily_limit[app]; diff --git a/applications/loader/loader.c b/applications/loader/loader.c index 054562a2f6e..dafe255a38b 100644 --- a/applications/loader/loader.c +++ b/applications/loader/loader.c @@ -101,6 +101,11 @@ const FlipperApplication* loader_find_application_by_name(const char* name) { } void loader_cli_open(Cli* cli, string_t args, Loader* instance) { + if(loader_is_locked(instance)) { + printf("Can't start, furi application is running"); + return; + } + string_t application_name; string_init(application_name); @@ -292,7 +297,7 @@ static Loader* loader_alloc() { #ifdef SRV_CLI instance->cli = furi_record_open("cli"); - cli_add_command(instance->cli, "loader", CliCommandFlagDefault, loader_cli, instance); + cli_add_command(instance->cli, "loader", CliCommandFlagParallelSafe, loader_cli, instance); #else UNUSED(loader_cli); #endif @@ -488,4 +493,4 @@ int32_t loader_srv(void* p) { FuriPubSub* loader_get_pubsub(Loader* instance) { return instance->pubsub; -} \ No newline at end of file +} diff --git a/applications/notification/notification_app.c b/applications/notification/notification_app.c index 447bf9034fa..1e2e2dde9c7 100644 --- a/applications/notification/notification_app.c +++ b/applications/notification/notification_app.c @@ -418,11 +418,8 @@ static bool notification_save_settings(NotificationApp* app) { static void input_event_callback(const void* value, void* context) { furi_assert(value); furi_assert(context); - const InputEvent* event = value; NotificationApp* app = context; - if(event->type == InputTypePress) { - notification_message(app, &sequence_display_on); - } + notification_message(app, &sequence_display_on); } // App alloc diff --git a/applications/subghz/scenes/subghz_scene_read_raw.c b/applications/subghz/scenes/subghz_scene_read_raw.c index cbd64f8f7f8..10248c357b1 100644 --- a/applications/subghz/scenes/subghz_scene_read_raw.c +++ b/applications/subghz/scenes/subghz_scene_read_raw.c @@ -127,8 +127,7 @@ bool subghz_scene_read_raw_on_event(void* context, SceneManagerEvent event) { scene_manager_next_scene(subghz->scene_manager, SubGhzSceneNeedSaving); } else { //Restore default setting - subghz->txrx->frequency = subghz_setting_get_frequency( - subghz->setting, subghz_setting_get_frequency_default_index(subghz->setting)); + subghz->txrx->frequency = subghz_setting_get_default_frequency(subghz->setting); subghz->txrx->preset = FuriHalSubGhzPresetOok650Async; if(!scene_manager_search_and_switch_to_previous_scene( subghz->scene_manager, SubGhzSceneSaved)) { diff --git a/applications/subghz/scenes/subghz_scene_receiver.c b/applications/subghz/scenes/subghz_scene_receiver.c index 8a5ee9218d3..7183410b2aa 100644 --- a/applications/subghz/scenes/subghz_scene_receiver.c +++ b/applications/subghz/scenes/subghz_scene_receiver.c @@ -120,8 +120,7 @@ bool subghz_scene_receiver_on_event(void* context, SceneManagerEvent event) { subghz_sleep(subghz); }; subghz->txrx->hopper_state = SubGhzHopperStateOFF; - subghz->txrx->frequency = subghz_setting_get_frequency( - subghz->setting, subghz_setting_get_frequency_default_index(subghz->setting)); + subghz->txrx->frequency = subghz_setting_get_default_frequency(subghz->setting); subghz->txrx->preset = FuriHalSubGhzPresetOok650Async; subghz->txrx->idx_menu_chosen = 0; subghz_receiver_set_rx_callback(subghz->txrx->receiver, NULL, subghz); diff --git a/applications/subghz/scenes/subghz_scene_receiver_config.c b/applications/subghz/scenes/subghz_scene_receiver_config.c index f2ae749f029..d98f45af072 100644 --- a/applications/subghz/scenes/subghz_scene_receiver_config.c +++ b/applications/subghz/scenes/subghz_scene_receiver_config.c @@ -111,19 +111,13 @@ static void subghz_scene_receiver_config_set_hopping_runing(VariableItem* item) sprintf( text_buf, "%lu.%02lu", - subghz_setting_get_frequency( - subghz->setting, subghz_setting_get_frequency_default_index(subghz->setting)) / - 1000000, - (subghz_setting_get_frequency( - subghz->setting, subghz_setting_get_frequency_default_index(subghz->setting)) % - 1000000) / - 10000); + subghz_setting_get_default_frequency(subghz->setting) / 1000000, + (subghz_setting_get_default_frequency(subghz->setting) % 1000000) / 10000); variable_item_set_current_value_text( (VariableItem*)scene_manager_get_scene_state( subghz->scene_manager, SubGhzSceneReceiverConfig), text_buf); - subghz->txrx->frequency = subghz_setting_get_frequency( - subghz->setting, subghz_setting_get_frequency_default_index(subghz->setting)); + subghz->txrx->frequency = subghz_setting_get_default_frequency(subghz->setting); variable_item_set_current_value_index( (VariableItem*)scene_manager_get_scene_state( subghz->scene_manager, SubGhzSceneReceiverConfig), diff --git a/applications/subghz/scenes/subghz_scene_set_type.c b/applications/subghz/scenes/subghz_scene_set_type.c index 4fb36467f98..22a151434d5 100644 --- a/applications/subghz/scenes/subghz_scene_set_type.c +++ b/applications/subghz/scenes/subghz_scene_set_type.c @@ -46,7 +46,7 @@ bool subghz_scene_set_type_submenu_gen_data_protocol( if(!subghz_protocol_decoder_base_serialize( subghz->txrx->decoder_result, subghz->txrx->fff_data, - subghz_setting_get_frequency_default_index(subghz->setting), + subghz_setting_get_default_frequency(subghz->setting), FuriHalSubGhzPresetOok650Async)) { FURI_LOG_E(TAG, "Unable to serialize"); break; @@ -213,7 +213,7 @@ bool subghz_scene_set_type_on_event(void* context, SceneManagerEvent event) { 0x2, 0x0003, "DoorHan", - subghz_setting_get_frequency_default_index(subghz->setting), + subghz_setting_get_default_frequency(subghz->setting), FuriHalSubGhzPresetOok650Async); generated_protocol = true; } else { diff --git a/applications/subghz/subghz.c b/applications/subghz/subghz.c index 80c69734386..5a59d89bb1e 100644 --- a/applications/subghz/subghz.c +++ b/applications/subghz/subghz.c @@ -130,8 +130,7 @@ SubGhz* subghz_alloc() { //init Worker & Protocol & History subghz->txrx = malloc(sizeof(SubGhzTxRx)); - subghz->txrx->frequency = subghz_setting_get_frequency( - subghz->setting, subghz_setting_get_frequency_default_index(subghz->setting)); + subghz->txrx->frequency = subghz_setting_get_default_frequency(subghz->setting); subghz->txrx->preset = FuriHalSubGhzPresetOok650Async; subghz->txrx->txrx_state = SubGhzTxRxStateSleep; subghz->txrx->hopper_state = SubGhzHopperStateOFF; diff --git a/applications/subghz/subghz_i.c b/applications/subghz/subghz_i.c index 5740ea9d84c..60938d17592 100644 --- a/applications/subghz/subghz_i.c +++ b/applications/subghz/subghz_i.c @@ -246,7 +246,7 @@ bool subghz_key_load(SubGhz* subghz, const char* file_path) { break; } - if(!flipper_format_read_uint32(fff_data_file, "Frequency", (uint32_t*)&temp_data32, 1)) { + if(!flipper_format_read_uint32(fff_data_file, "Frequency", &temp_data32, 1)) { FURI_LOG_E(TAG, "Missing Frequency"); break; } diff --git a/applications/subghz/subghz_setting.c b/applications/subghz/subghz_setting.c index 98a8a16eb37..4d40d49ee84 100644 --- a/applications/subghz/subghz_setting.c +++ b/applications/subghz/subghz_setting.c @@ -152,12 +152,11 @@ static const uint32_t subghz_hopper_frequencies_region_jp[] = { }; static const uint32_t subghz_frequency_default_index_region_jp = 9; -LIST_DEF(frequencies_list, uint32_t) -LIST_DEF(hopper_frequencies_list, uint32_t) +LIST_DEF(FrequenciesList, uint32_t) struct SubGhzSetting { - frequencies_list_t frequencies; - hopper_frequencies_list_t hopper_frequencies; + FrequenciesList_t frequencies; + FrequenciesList_t hopper_frequencies; size_t frequencies_count; size_t hopper_frequencies_count; uint32_t frequency_default_index; @@ -165,15 +164,15 @@ struct SubGhzSetting { SubGhzSetting* subghz_setting_alloc(void) { SubGhzSetting* instance = malloc(sizeof(SubGhzSetting)); - frequencies_list_init(instance->frequencies); - hopper_frequencies_list_init(instance->hopper_frequencies); + FrequenciesList_init(instance->frequencies); + FrequenciesList_init(instance->hopper_frequencies); return instance; } void subghz_setting_free(SubGhzSetting* instance) { furi_assert(instance); - frequencies_list_clear(instance->frequencies); - hopper_frequencies_list_clear(instance->hopper_frequencies); + FrequenciesList_clear(instance->frequencies); + FrequenciesList_clear(instance->hopper_frequencies); free(instance); } @@ -184,18 +183,18 @@ void subghz_setting_load_default( const uint32_t frequency_default_index) { furi_assert(instance); size_t i = 0; - frequencies_list_clear(instance->frequencies); - hopper_frequencies_list_clear(instance->hopper_frequencies); + FrequenciesList_clear(instance->frequencies); + FrequenciesList_clear(instance->hopper_frequencies); i = 0; while(frequencies[i]) { - frequencies_list_push_back(instance->frequencies, frequencies[i]); + FrequenciesList_push_back(instance->frequencies, frequencies[i]); i++; } instance->frequencies_count = i; i = 0; while(hopper_frequencies[i]) { - hopper_frequencies_list_push_back(instance->hopper_frequencies, hopper_frequencies[i]); + FrequenciesList_push_back(instance->hopper_frequencies, hopper_frequencies[i]); i++; } instance->hopper_frequencies_count = i; @@ -206,8 +205,8 @@ void subghz_setting_load_default( void subghz_setting_load(SubGhzSetting* instance, const char* file_path) { furi_assert(instance); - frequencies_list_clear(instance->frequencies); - hopper_frequencies_list_clear(instance->hopper_frequencies); + FrequenciesList_clear(instance->frequencies); + FrequenciesList_clear(instance->hopper_frequencies); Storage* storage = furi_record_open("storage"); FlipperFormat* fff_data_file = flipper_format_file_alloc(storage); @@ -246,7 +245,7 @@ void subghz_setting_load(SubGhzSetting* instance, const char* file_path) { fff_data_file, "Frequency", (uint32_t*)&temp_data32, 1)) { if(furi_hal_subghz_is_frequency_valid(temp_data32)) { FURI_LOG_I(TAG, "Frequency loaded %lu", temp_data32); - frequencies_list_push_back(instance->frequencies, temp_data32); + FrequenciesList_push_back(instance->frequencies, temp_data32); i++; } else { FURI_LOG_E(TAG, "Frequency not supported %lu", temp_data32); @@ -263,7 +262,7 @@ void subghz_setting_load(SubGhzSetting* instance, const char* file_path) { fff_data_file, "Hopper_frequency", (uint32_t*)&temp_data32, 1)) { if(furi_hal_subghz_is_frequency_valid(temp_data32)) { FURI_LOG_I(TAG, "Hopper frequency loaded %lu", temp_data32); - hopper_frequencies_list_push_back(instance->hopper_frequencies, temp_data32); + FrequenciesList_push_back(instance->hopper_frequencies, temp_data32); i++; } else { FURI_LOG_E(TAG, "Hopper frequency not supported %lu", temp_data32); @@ -297,6 +296,8 @@ void subghz_setting_load(SubGhzSetting* instance, const char* file_path) { } } while(false); } + + string_clear(temp_str); flipper_format_free(fff_data_file); furi_record_close("storage"); @@ -347,15 +348,20 @@ size_t subghz_setting_get_hopper_frequency_count(SubGhzSetting* instance) { uint32_t subghz_setting_get_frequency(SubGhzSetting* instance, size_t idx) { furi_assert(instance); - return *frequencies_list_get(instance->frequencies, idx); + return *FrequenciesList_get(instance->frequencies, idx); } uint32_t subghz_setting_get_hopper_frequency(SubGhzSetting* instance, size_t idx) { furi_assert(instance); - return *hopper_frequencies_list_get(instance->hopper_frequencies, idx); + return *FrequenciesList_get(instance->hopper_frequencies, idx); } uint32_t subghz_setting_get_frequency_default_index(SubGhzSetting* instance) { furi_assert(instance); return instance->frequency_default_index; -} \ No newline at end of file +} + +uint32_t subghz_setting_get_default_frequency(SubGhzSetting* instance) { + furi_assert(instance); + return *FrequenciesList_get(instance->frequencies, instance->frequency_default_index); +} diff --git a/applications/subghz/subghz_setting.h b/applications/subghz/subghz_setting.h index cdf607974ea..58a898c569c 100644 --- a/applications/subghz/subghz_setting.h +++ b/applications/subghz/subghz_setting.h @@ -8,10 +8,19 @@ typedef struct SubGhzSetting SubGhzSetting; SubGhzSetting* subghz_setting_alloc(void); + void subghz_setting_free(SubGhzSetting* instance); + void subghz_setting_load(SubGhzSetting* instance, const char* file_path); + size_t subghz_setting_get_frequency_count(SubGhzSetting* instance); + size_t subghz_setting_get_hopper_frequency_count(SubGhzSetting* instance); + uint32_t subghz_setting_get_frequency(SubGhzSetting* instance, size_t idx); + 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); From 827e30aa5a6405f9f1510a550f3816a6e11db757 Mon Sep 17 00:00:00 2001 From: hedger Date: Fri, 15 Apr 2022 19:47:57 +0300 Subject: [PATCH 19/20] [FL-2468] Reboot to update with RPC (#1122) * Added update boot mode for RPC * Fixed FLIPPER_SYSTEM_APPS_COUNT & updater app arg parsing * Bumped RPC version * Moved boot mode --- applications/power/power_service/power.h | 1 + applications/power/power_service/power_api.c | 2 ++ applications/rpc/rpc_system.c | 4 +++- applications/updater/updater.c | 4 +++- assets/compiled/system.pb.h | 13 +++++++------ assets/protobuf | 2 +- 6 files changed, 17 insertions(+), 9 deletions(-) diff --git a/applications/power/power_service/power.h b/applications/power/power_service/power.h index 093c52ed9a6..92cca6f7230 100644 --- a/applications/power/power_service/power.h +++ b/applications/power/power_service/power.h @@ -9,6 +9,7 @@ typedef struct Power Power; typedef enum { PowerBootModeNormal, PowerBootModeDfu, + PowerBootModeUpdateStart, } PowerBootMode; typedef enum { diff --git a/applications/power/power_service/power_api.c b/applications/power/power_service/power_api.c index 28c23fcff43..b290cb831d8 100644 --- a/applications/power/power_service/power_api.c +++ b/applications/power/power_service/power_api.c @@ -17,6 +17,8 @@ void power_reboot(PowerBootMode mode) { furi_hal_rtc_set_boot_mode(FuriHalRtcBootModeNormal); } else if(mode == PowerBootModeDfu) { furi_hal_rtc_set_boot_mode(FuriHalRtcBootModeDfu); + } else if(mode == PowerBootModeUpdateStart) { + furi_hal_rtc_set_boot_mode(FuriHalRtcBootModePreUpdate); } furi_hal_power_reset(); } diff --git a/applications/rpc/rpc_system.c b/applications/rpc/rpc_system.c index f54bb19791f..9ce7e34a38e 100644 --- a/applications/rpc/rpc_system.c +++ b/applications/rpc/rpc_system.c @@ -61,6 +61,8 @@ static void rpc_system_system_reboot_process(const PB_Main* request, void* conte power_reboot(PowerBootModeNormal); } else if(mode == PB_System_RebootRequest_RebootMode_DFU) { power_reboot(PowerBootModeDfu); + } else if(mode == PB_System_RebootRequest_RebootMode_UPDATE) { + power_reboot(PowerBootModeUpdateStart); } else { rpc_send_and_release_empty( session, request->command_id, PB_CommandStatus_ERROR_INVALID_PARAMETERS); @@ -274,7 +276,7 @@ static void rpc_system_system_update_request_process(const PB_Main* request, voi furi_assert(session); bool update_prepare_result = - update_operation_prepare(request->content.system_update_request.update_folder) == + update_operation_prepare(request->content.system_update_request.update_manifest) == UpdatePrepareResultOK; PB_Main* response = malloc(sizeof(PB_Main)); diff --git a/applications/updater/updater.c b/applications/updater/updater.c index dbad239b0f1..519ba167da6 100644 --- a/applications/updater/updater.c +++ b/applications/updater/updater.c @@ -80,7 +80,9 @@ Updater* updater_alloc(const char* arg) { #ifdef FURI_RAM_EXEC if(true) { #else - if(!arg) { + FuriHalRtcBootMode boot_mode = furi_hal_rtc_get_boot_mode(); + if(!arg && ((boot_mode == FuriHalRtcBootModePreUpdate) || + (boot_mode == FuriHalRtcBootModePostUpdate))) { #endif updater->update_task = update_task_alloc(); update_task_set_progress_cb(updater->update_task, status_update_cb, updater->main_view); diff --git a/assets/compiled/system.pb.h b/assets/compiled/system.pb.h index 0932c6fb6c0..978219ae02b 100644 --- a/assets/compiled/system.pb.h +++ b/assets/compiled/system.pb.h @@ -12,7 +12,8 @@ /* Enum definitions */ typedef enum _PB_System_RebootRequest_RebootMode { PB_System_RebootRequest_RebootMode_OS = 0, - PB_System_RebootRequest_RebootMode_DFU = 1 + PB_System_RebootRequest_RebootMode_DFU = 1, + PB_System_RebootRequest_RebootMode_UPDATE = 2 } PB_System_RebootRequest_RebootMode; /* Struct definitions */ @@ -59,7 +60,7 @@ typedef struct _PB_System_ProtobufVersionRequest { } PB_System_ProtobufVersionRequest; typedef struct _PB_System_UpdateRequest { - char *update_folder; + char *update_manifest; } PB_System_UpdateRequest; typedef struct _PB_System_DateTime { @@ -96,8 +97,8 @@ typedef struct _PB_System_SetDateTimeRequest { /* Helper constants for enums */ #define _PB_System_RebootRequest_RebootMode_MIN PB_System_RebootRequest_RebootMode_OS -#define _PB_System_RebootRequest_RebootMode_MAX PB_System_RebootRequest_RebootMode_DFU -#define _PB_System_RebootRequest_RebootMode_ARRAYSIZE ((PB_System_RebootRequest_RebootMode)(PB_System_RebootRequest_RebootMode_DFU+1)) +#define _PB_System_RebootRequest_RebootMode_MAX PB_System_RebootRequest_RebootMode_UPDATE +#define _PB_System_RebootRequest_RebootMode_ARRAYSIZE ((PB_System_RebootRequest_RebootMode)(PB_System_RebootRequest_RebootMode_UPDATE+1)) #ifdef __cplusplus @@ -145,7 +146,7 @@ extern "C" { #define PB_System_PingResponse_data_tag 1 #define PB_System_PowerInfoResponse_key_tag 1 #define PB_System_PowerInfoResponse_value_tag 2 -#define PB_System_UpdateRequest_update_folder_tag 1 +#define PB_System_UpdateRequest_update_manifest_tag 1 #define PB_System_DateTime_hour_tag 1 #define PB_System_DateTime_minute_tag 2 #define PB_System_DateTime_second_tag 3 @@ -236,7 +237,7 @@ X(a, STATIC, SINGULAR, UINT32, minor, 2) #define PB_System_ProtobufVersionResponse_DEFAULT NULL #define PB_System_UpdateRequest_FIELDLIST(X, a) \ -X(a, POINTER, SINGULAR, STRING, update_folder, 1) +X(a, POINTER, SINGULAR, STRING, update_manifest, 1) #define PB_System_UpdateRequest_CALLBACK NULL #define PB_System_UpdateRequest_DEFAULT NULL diff --git a/assets/protobuf b/assets/protobuf index 0403ae1ba7a..0ad90705b94 160000 --- a/assets/protobuf +++ b/assets/protobuf @@ -1 +1 @@ -Subproject commit 0403ae1ba7a4501274da54b3aa6274f76fdd090c +Subproject commit 0ad90705b9434b6f8fb2c4b605069f0d56d8cc70 From 000ebb8f962e0743df977a6df430a95f6806cee7 Mon Sep 17 00:00:00 2001 From: hedger Date: Fri, 15 Apr 2022 20:26:23 +0300 Subject: [PATCH 20/20] Fixed README formatting & outdated information (#1123) --- ReadMe.md | 2 +- RoadMap.md | 1 - firmware/ReadMe.md | 11 +++++++---- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/ReadMe.md b/ReadMe.md index 9a355ebacee..c6b73c8ba3e 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -16,7 +16,7 @@ Flipper Zero's firmware consists of two components: - Core2 firmware set - proprietary components by ST: FUS + radio stack. FUS is flashed at factory and you should never update it. - Core1 Firmware - HAL + OS + Drivers + Applications. -All 3 of them must be flashed in order described. +They both must be flashed in order described. ## With STLink diff --git a/RoadMap.md b/RoadMap.md index e8b2bf099ea..32ed860f24e 100644 --- a/RoadMap.md +++ b/RoadMap.md @@ -35,7 +35,6 @@ Main goal for 1.0.0 is to provide first stable version for both Users and Develo ## What we're planning to implement in 1.0.0 -- Updating firmware from SD (work in progress, almost done) - Loading applications from SD (tested as PoC, work scheduled for Q2) - More protocols (gathering feedback) - User documentation (work in progress) diff --git a/firmware/ReadMe.md b/firmware/ReadMe.md index f12f2e7bd4c..38271fd276e 100644 --- a/firmware/ReadMe.md +++ b/firmware/ReadMe.md @@ -10,10 +10,9 @@ What does it do? # Targets -| Name | Firmware | Reset | DFU | -| | Address | Combo | Combo | ---------------------------------------------------------------------------------- -| f7 | 0x08000000 | L+Back, release both | L+Back, release Back | +| Name | Firmware Address | Reset Combo | DFU Combo | +|-----------|-------------------|-----------------------|-----------------------| +| f7 | 0x08000000 | L+Back, release both | L+Back, release Back | Also there is a "hardware" ST bootloader combo available even on a bricked or empty device: L+Ok+Back, release Back, Left. Target independent code and headers in `target/include` folders. More details in `documentation/KeyCombo.md` @@ -35,6 +34,10 @@ Target independent code and headers in `target/include` folders. More details in - `TARGET` - string - target to build. Default is `f7`. - `RAM_EXEC` - 0/1 - whether to build full firmware or RAM-based stage for firmware update. 0 is default, builds firmware. +# Building self-update package + +`make DEBUG=0 COMPACT=1 updater_package` + # Flashing Using SWD (STLink):