diff --git a/applications/external/esp_flasher/assets/KeyBackspaceSelected_16x9.png b/applications/external/esp_flasher/assets/KeyBackspaceSelected_16x9.png deleted file mode 100644 index 7cc0759a8..000000000 Binary files a/applications/external/esp_flasher/assets/KeyBackspaceSelected_16x9.png and /dev/null differ diff --git a/applications/external/esp_flasher/assets/KeyBackspace_16x9.png b/applications/external/esp_flasher/assets/KeyBackspace_16x9.png deleted file mode 100644 index 9946232d9..000000000 Binary files a/applications/external/esp_flasher/assets/KeyBackspace_16x9.png and /dev/null differ diff --git a/applications/external/esp_flasher/assets/KeySaveSelected_24x11.png b/applications/external/esp_flasher/assets/KeySaveSelected_24x11.png deleted file mode 100644 index eeb3569d3..000000000 Binary files a/applications/external/esp_flasher/assets/KeySaveSelected_24x11.png and /dev/null differ diff --git a/applications/external/esp_flasher/assets/KeySave_24x11.png b/applications/external/esp_flasher/assets/KeySave_24x11.png deleted file mode 100644 index e7dba987a..000000000 Binary files a/applications/external/esp_flasher/assets/KeySave_24x11.png and /dev/null differ diff --git a/applications/external/esp_flasher/esp_flasher_app.c b/applications/external/esp_flasher/esp_flasher_app.c index d58d96844..ce8fdf5a8 100644 --- a/applications/external/esp_flasher/esp_flasher_app.c +++ b/applications/external/esp_flasher/esp_flasher_app.c @@ -117,6 +117,7 @@ int32_t esp_flasher_app(void* p) { UNUSED(p); uint8_t attempts = 0; + bool otg_was_enabled = furi_hal_power_is_otg_enabled(); while(!furi_hal_power_is_otg_enabled() && attempts++ < 5) { furi_hal_power_enable_otg(); furi_delay_ms(10); @@ -133,7 +134,7 @@ int32_t esp_flasher_app(void* p) { esp_flasher_app_free(esp_flasher_app); - if(furi_hal_power_is_otg_enabled()) { + if(furi_hal_power_is_otg_enabled() && !otg_was_enabled) { furi_hal_power_disable_otg(); } diff --git a/applications/external/esp_flasher/esp_flasher_app.h b/applications/external/esp_flasher/esp_flasher_app.h index 809fcc6fc..3a30d16c0 100644 --- a/applications/external/esp_flasher/esp_flasher_app.h +++ b/applications/external/esp_flasher/esp_flasher_app.h @@ -4,7 +4,7 @@ extern "C" { #endif -#define ESP_FLASHER_APP_VERSION "v1.1" +#define ESP_FLASHER_APP_VERSION "v1.2" typedef struct EspFlasherApp EspFlasherApp; diff --git a/applications/external/esp_flasher/esp_flasher_app_i.h b/applications/external/esp_flasher/esp_flasher_app_i.h index 4cbd54064..e67f8a50f 100644 --- a/applications/external/esp_flasher/esp_flasher_app_i.h +++ b/applications/external/esp_flasher/esp_flasher_app_i.h @@ -34,11 +34,18 @@ typedef enum SelectedFlashOptions { SelectedFlashPart, SelectedFlashNvs, SelectedFlashBootApp0, - SelectedFlashApp, + SelectedFlashAppA, + SelectedFlashAppB, SelectedFlashCustom, NUM_FLASH_OPTIONS } SelectedFlashOptions; +typedef enum { + SwitchNotSet, + SwitchToFirmwareA, + SwitchToFirmwareB, +} SwitchFirmware; + struct EspFlasherApp { Gui* gui; ViewDispatcher* view_dispatcher; @@ -61,13 +68,16 @@ struct EspFlasherApp { bool boot; bool quickflash; + SwitchFirmware switch_fw; + bool selected_flash_options[NUM_FLASH_OPTIONS]; int num_selected_flash_options; char bin_file_path_boot[100]; char bin_file_path_part[100]; char bin_file_path_nvs[100]; char bin_file_path_boot_app0[100]; - char bin_file_path_app[100]; + char bin_file_path_app_a[100]; + char bin_file_path_app_b[100]; char bin_file_path_custom[100]; FuriThread* flash_worker; bool flash_worker_busy; diff --git a/applications/external/esp_flasher/esp_flasher_worker.c b/applications/external/esp_flasher/esp_flasher_worker.c index 06d5555c3..be5da85db 100644 --- a/applications/external/esp_flasher/esp_flasher_worker.c +++ b/applications/external/esp_flasher/esp_flasher_worker.c @@ -74,6 +74,85 @@ static esp_loader_error_t _flash_file(EspFlasherApp* app, char* filepath, uint32 return ESP_LOADER_SUCCESS; } +// This in-app FW switch "exploits" the otadata (boot_app0) +// - the first four bytes of each array are the counter and the last four bytes are just a CRC of that counter +// - the bootloader will just boot whichever app has the highest counter in the otadata partition +// so we'll just pick 1 for A, and then B will use either 0 or 2 depending on whether it's the slot in use + +#define MAGIC_PAYLOAD_SIZE (32) + +const uint8_t magic_payload_app_a[MAGIC_PAYLOAD_SIZE] = {0x01, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x9a, 0x98, 0x43, 0x47}; + +const uint8_t magic_payload_app_b_unset[MAGIC_PAYLOAD_SIZE] = { + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + +const uint8_t magic_payload_app_b_set[MAGIC_PAYLOAD_SIZE] = { + 0x02, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x74, 0x37, 0xf6, 0x55}; + +// return true if "switching" fw selected instead of flashing new fw +// (this does not indicate success) +static bool _switch_fw(EspFlasherApp* app) { + if(app->switch_fw == SwitchNotSet) { + return false; + } + + esp_loader_error_t err; + char user_msg[256]; + + loader_port_debug_print("Preparing to set flags for firmware A\n"); + err = esp_loader_flash_start( + ESP_ADDR_BOOT_APP0 + ESP_ADDR_OTADATA_OFFSET_APP_A, + MAGIC_PAYLOAD_SIZE, + MAGIC_PAYLOAD_SIZE); + if(err != ESP_LOADER_SUCCESS) { + snprintf(user_msg, sizeof(user_msg), "Erasing flash failed with error %d\n", err); + loader_port_debug_print(user_msg); + return true; + } + + loader_port_debug_print("Setting flags for firmware A\n"); + const uint8_t* which_payload_app_a = magic_payload_app_a; + err = esp_loader_flash_write((void*)which_payload_app_a, MAGIC_PAYLOAD_SIZE); + if(err != ESP_LOADER_SUCCESS) { + snprintf(user_msg, sizeof(user_msg), "Packet could not be written! Error: %u\n", err); + loader_port_debug_print(user_msg); + return true; + } + + loader_port_debug_print("Preparing to set flags for firmware B\n"); + err = esp_loader_flash_start( + ESP_ADDR_BOOT_APP0 + ESP_ADDR_OTADATA_OFFSET_APP_B, + MAGIC_PAYLOAD_SIZE, + MAGIC_PAYLOAD_SIZE); + if(err != ESP_LOADER_SUCCESS) { + snprintf(user_msg, sizeof(user_msg), "Erasing flash failed with error %d\n", err); + loader_port_debug_print(user_msg); + return true; + } + + loader_port_debug_print("Setting flags for firmware B\n"); + const uint8_t* which_payload_app_b = + (app->switch_fw == SwitchToFirmwareB ? magic_payload_app_b_set : + magic_payload_app_b_unset); + err = esp_loader_flash_write((void*)which_payload_app_b, MAGIC_PAYLOAD_SIZE); + if(err != ESP_LOADER_SUCCESS) { + snprintf(user_msg, sizeof(user_msg), "Packet could not be written! Error: %u\n", err); + loader_port_debug_print(user_msg); + return true; + } + + loader_port_debug_print("Finished programming\n"); + return true; +} + typedef struct { SelectedFlashOptions selected; const char* description; @@ -85,7 +164,7 @@ static void _flash_all_files(EspFlasherApp* app) { esp_loader_error_t err; const int num_steps = app->num_selected_flash_options; -#define NUM_FLASH_ITEMS 6 +#define NUM_FLASH_ITEMS 7 FlashItem items[NUM_FLASH_ITEMS] = { {SelectedFlashBoot, "bootloader", @@ -94,7 +173,8 @@ static void _flash_all_files(EspFlasherApp* app) { {SelectedFlashPart, "partition table", app->bin_file_path_part, ESP_ADDR_PART}, {SelectedFlashNvs, "NVS", app->bin_file_path_nvs, ESP_ADDR_NVS}, {SelectedFlashBootApp0, "boot_app0", app->bin_file_path_boot_app0, ESP_ADDR_BOOT_APP0}, - {SelectedFlashApp, "firmware", app->bin_file_path_app, ESP_ADDR_APP}, + {SelectedFlashAppA, "firmware A", app->bin_file_path_app_a, ESP_ADDR_APP_A}, + {SelectedFlashAppB, "firmware B", app->bin_file_path_app_b, ESP_ADDR_APP_B}, {SelectedFlashCustom, "custom data", app->bin_file_path_custom, 0x0}, /* if you add more entries, update NUM_FLASH_ITEMS above! */ }; @@ -167,7 +247,10 @@ static int32_t esp_flasher_flash_bin(void* context) { if(!err) { loader_port_debug_print("Connected\n"); - _flash_all_files(app); + if(!_switch_fw(app)) { + _flash_all_files(app); + } + app->switch_fw = SwitchNotSet; #if 0 loader_port_debug_print("Restoring transmission rate\n"); furi_hal_uart_set_br(FuriHalUartIdUSART1, 115200); @@ -286,6 +369,8 @@ void loader_port_reset_target(void) { } void loader_port_enter_bootloader(void) { + // adapted from custom usb-jtag-serial reset in esptool + // (works on official wifi dev board) _setDTR(true); loader_port_delay_ms(SERIAL_FLASHER_RESET_HOLD_TIME_MS); _setRTS(true); diff --git a/applications/external/esp_flasher/esp_flasher_worker.h b/applications/external/esp_flasher/esp_flasher_worker.h index 44461e7d4..0dba16f0c 100644 --- a/applications/external/esp_flasher/esp_flasher_worker.h +++ b/applications/external/esp_flasher/esp_flasher_worker.h @@ -14,7 +14,11 @@ #define ESP_ADDR_PART 0x8000 #define ESP_ADDR_NVS 0x9000 #define ESP_ADDR_BOOT_APP0 0xE000 -#define ESP_ADDR_APP 0x10000 +#define ESP_ADDR_APP_A 0x10000 +#define ESP_ADDR_APP_B 0x150000 + +#define ESP_ADDR_OTADATA_OFFSET_APP_A 0x0 +#define ESP_ADDR_OTADATA_OFFSET_APP_B 0x1000 void esp_flasher_worker_start_thread(EspFlasherApp* app); void esp_flasher_worker_stop_thread(EspFlasherApp* app); diff --git a/applications/external/esp_flasher/scenes/esp_flasher_scene_browse.c b/applications/external/esp_flasher/scenes/esp_flasher_scene_browse.c index 88a9b25e4..8b223b29a 100644 --- a/applications/external/esp_flasher/scenes/esp_flasher_scene_browse.c +++ b/applications/external/esp_flasher/scenes/esp_flasher_scene_browse.c @@ -7,7 +7,8 @@ enum SubmenuIndex { SubmenuIndexPart, SubmenuIndexNvs, SubmenuIndexBootApp0, - SubmenuIndexApp, + SubmenuIndexAppA, + SubmenuIndexAppB, SubmenuIndexCustom, SubmenuIndexFlash, }; @@ -97,19 +98,35 @@ static void esp_flasher_scene_browse_callback(void* context, uint32_t index) { } view_dispatcher_send_custom_event(app->view_dispatcher, EspFlasherEventRefreshSubmenu); break; - case SubmenuIndexApp: - app->selected_flash_options[SelectedFlashApp] = - !app->selected_flash_options[SelectedFlashApp]; + case SubmenuIndexAppA: + app->selected_flash_options[SelectedFlashAppA] = + !app->selected_flash_options[SelectedFlashAppA]; if(dialog_file_browser_show( app->dialogs, selected_filepath, predefined_filepath, &browser_options)) { strncpy( - app->bin_file_path_app, + app->bin_file_path_app_a, furi_string_get_cstr(selected_filepath), - sizeof(app->bin_file_path_app)); + sizeof(app->bin_file_path_app_a)); } - if(app->bin_file_path_app[0] == '\0') { + if(app->bin_file_path_app_a[0] == '\0') { // if user didn't select a file, leave unselected - app->selected_flash_options[SelectedFlashApp] = false; + app->selected_flash_options[SelectedFlashAppA] = false; + } + view_dispatcher_send_custom_event(app->view_dispatcher, EspFlasherEventRefreshSubmenu); + break; + case SubmenuIndexAppB: + app->selected_flash_options[SelectedFlashAppB] = + !app->selected_flash_options[SelectedFlashAppB]; + if(dialog_file_browser_show( + app->dialogs, selected_filepath, predefined_filepath, &browser_options)) { + strncpy( + app->bin_file_path_app_b, + furi_string_get_cstr(selected_filepath), + sizeof(app->bin_file_path_app_b)); + } + if(app->bin_file_path_app_b[0] == '\0') { + // if user didn't select a file, leave unselected + app->selected_flash_options[SelectedFlashAppB] = false; } view_dispatcher_send_custom_event(app->view_dispatcher, EspFlasherEventRefreshSubmenu); break; @@ -157,7 +174,8 @@ static void esp_flasher_scene_browse_callback(void* context, uint32_t index) { #define STR_PART "Part Table (" TOSTRING(ESP_ADDR_PART) ")" #define STR_NVS "NVS (" TOSTRING(ESP_ADDR_NVS) ")" #define STR_BOOT_APP0 "boot_app0 (" TOSTRING(ESP_ADDR_BOOT_APP0) ")" -#define STR_APP "Firmware (" TOSTRING(ESP_ADDR_APP) ")" +#define STR_APP_A "FirmwareA(" TOSTRING(ESP_ADDR_APP_A) ")" +#define STR_APP_B "FirmwareB(" TOSTRING(ESP_ADDR_APP_B) ")" #define STR_CUSTOM "Custom" #define STR_FLASH_S3 "[>] FLASH (ESP32-S3)" #define STR_FLASH "[>] FLASH" @@ -213,9 +231,16 @@ static void _refresh_submenu(EspFlasherApp* app) { app); submenu_add_item( submenu, - app->selected_flash_options[SelectedFlashApp] ? STR_SELECT " " STR_APP : - STR_UNSELECT " " STR_APP, - SubmenuIndexApp, + app->selected_flash_options[SelectedFlashAppA] ? STR_SELECT " " STR_APP_A : + STR_UNSELECT " " STR_APP_A, + SubmenuIndexAppA, + esp_flasher_scene_browse_callback, + app); + submenu_add_item( + submenu, + app->selected_flash_options[SelectedFlashAppB] ? STR_SELECT " " STR_APP_B : + STR_UNSELECT " " STR_APP_B, + SubmenuIndexAppB, esp_flasher_scene_browse_callback, app); // TODO: custom addr @@ -241,7 +266,8 @@ void esp_flasher_scene_browse_on_enter(void* context) { app->bin_file_path_part[0] = '\0'; app->bin_file_path_nvs[0] = '\0'; app->bin_file_path_boot_app0[0] = '\0'; - app->bin_file_path_app[0] = '\0'; + app->bin_file_path_app_a[0] = '\0'; + app->bin_file_path_app_b[0] = '\0'; app->bin_file_path_custom[0] = '\0'; _refresh_submenu(app); diff --git a/applications/external/esp_flasher/scenes/esp_flasher_scene_quick.c b/applications/external/esp_flasher/scenes/esp_flasher_scene_quick.c index 8b2e942f1..008ffa1bf 100644 --- a/applications/external/esp_flasher/scenes/esp_flasher_scene_quick.c +++ b/applications/external/esp_flasher/scenes/esp_flasher_scene_quick.c @@ -4,12 +4,9 @@ enum QuickState { QuickStart, QuickBlackmagic, QuickBlackmagicWifidev, - QuickEvilportal, - QuickEvilportalWifidevS2, - QuickEvilportalDevproWroom, - QuickMarauder, - QuickMarauderWifidevS2, - QuickMarauderDevproWroom, + QuickDualboot, + QuickDualbootWifidevS2, + QuickDualbootDevproWroom, }; void esp_flasher_scene_quick_submenu_callback(void* context, uint32_t index) { @@ -28,15 +25,16 @@ void esp_flasher_scene_quick_on_enter(void* context) { switch(state) { case QuickStart: case QuickBlackmagic: - case QuickEvilportal: - case QuickMarauder: + case QuickDualboot: submenu_set_header(submenu, "Flash Firmware:"); submenu_add_item( submenu, "Black Magic", QuickBlackmagic, esp_flasher_scene_quick_submenu_callback, app); submenu_add_item( - submenu, "Evil Portal", QuickEvilportal, esp_flasher_scene_quick_submenu_callback, app); - submenu_add_item( - submenu, "Marauder", QuickMarauder, esp_flasher_scene_quick_submenu_callback, app); + submenu, + "EvilPortal + Marauder", + QuickDualboot, + esp_flasher_scene_quick_submenu_callback, + app); break; case QuickBlackmagicWifidev: submenu_set_header(submenu, "Flash Black Magic To:"); @@ -47,35 +45,19 @@ void esp_flasher_scene_quick_on_enter(void* context) { esp_flasher_scene_quick_submenu_callback, app); break; - case QuickEvilportalWifidevS2: - case QuickEvilportalDevproWroom: - submenu_set_header(submenu, "Flash Evil Portal To:"); + case QuickDualbootWifidevS2: + case QuickDualbootDevproWroom: + submenu_set_header(submenu, "Flash EP+MR To:"); submenu_add_item( submenu, "WiFi Dev (ESP32-S2)", - QuickEvilportalWifidevS2, + QuickDualbootWifidevS2, esp_flasher_scene_quick_submenu_callback, app); submenu_add_item( submenu, "Dev Pro (ESP32-WROOM)", - QuickEvilportalDevproWroom, - esp_flasher_scene_quick_submenu_callback, - app); - break; - case QuickMarauderWifidevS2: - case QuickMarauderDevproWroom: - submenu_set_header(submenu, "Flash Marauder To:"); - submenu_add_item( - submenu, - "WiFi Dev (ESP32-S2)", - QuickMarauderWifidevS2, - esp_flasher_scene_quick_submenu_callback, - app); - submenu_add_item( - submenu, - "Dev Pro (ESP32-WROOM)", - QuickMarauderDevproWroom, + QuickDualbootDevproWroom, esp_flasher_scene_quick_submenu_callback, app); break; @@ -100,47 +82,28 @@ bool esp_flasher_scene_quick_on_event(void* context, SceneManagerEvent event) { bool enter_bootloader = false; const char* boot = NULL; // 0x1000 const char* part = NULL; // 0x8000 - const char* nvs = NULL; // 0x9000 - const char* app0 = APP_DATA_PATH("assets/boot_app0.bin"); // 0xE000 const char* firm = NULL; // 0x10000 switch(event.event) { case QuickBlackmagic: - case QuickEvilportal: - case QuickMarauder: + case QuickDualboot: scene_manager_set_scene_state( app->scene_manager, EspFlasherSceneQuick, event.event + 1); scene_manager_next_scene(app->scene_manager, EspFlasherSceneQuick); flash = false; break; case QuickBlackmagicWifidev: - boot = APP_DATA_PATH("assets/blackmagic/wifidev/bootloader.bin"); - part = APP_DATA_PATH("assets/blackmagic/wifidev/partition-table.bin"); - nvs = APP_DATA_PATH("assets/blackmagic/wifidev/nvs.bin"); - firm = APP_DATA_PATH("assets/blackmagic/wifidev/blackmagic.bin"); + boot = APP_DATA_PATH("assets/blackmagic/bootloader.bin"); + part = APP_DATA_PATH("assets/blackmagic/partition-table.bin"); + firm = APP_DATA_PATH("assets/blackmagic/blackmagic.bin"); enter_bootloader = true; break; - case QuickEvilportalWifidevS2: - boot = APP_DATA_PATH("assets/evilportal/wifidev-s2/EvilPortal.ino.bootloader.bin"); - part = APP_DATA_PATH("assets/evilportal/EvilPortal.ino.partitions.bin"); - firm = APP_DATA_PATH("assets/evilportal/wifidev-s2/EvilPortal.ino.bin"); + case QuickDualbootWifidevS2: + boot = APP_DATA_PATH("assets/dualboot/wifidev-s2.bin"); enter_bootloader = true; break; - case QuickEvilportalDevproWroom: - boot = APP_DATA_PATH("assets/evilportal/devpro-wroom/EvilPortal.ino.bootloader.bin"); - part = APP_DATA_PATH("assets/evilportal/EvilPortal.ino.partitions.bin"); - firm = APP_DATA_PATH("assets/evilportal/devpro-wroom/EvilPortal.ino.bin"); - break; - case QuickMarauderWifidevS2: - boot = APP_DATA_PATH("assets/marauder/wifidev-s2/bootloader.bin"); - part = APP_DATA_PATH("assets/marauder/partitions.bin"); - firm = APP_DATA_PATH("assets/marauder/wifidev-s2/flipper_sd_serial.bin"); - enter_bootloader = true; - break; - case QuickMarauderDevproWroom: - boot = APP_DATA_PATH("assets/marauder/devpro-wroom/bootloader.bin"); - part = APP_DATA_PATH("assets/marauder/partitions.bin"); - firm = APP_DATA_PATH("assets/marauder/devpro-wroom/marauder_dev_board_pro.bin"); + case QuickDualbootDevproWroom: + boot = APP_DATA_PATH("assets/dualboot/devpro-wroom.bin"); break; default: flash = false; @@ -155,7 +118,8 @@ bool esp_flasher_scene_quick_on_event(void* context, SceneManagerEvent event) { app->bin_file_path_part[0] = '\0'; app->bin_file_path_nvs[0] = '\0'; app->bin_file_path_boot_app0[0] = '\0'; - app->bin_file_path_app[0] = '\0'; + app->bin_file_path_app_a[0] = '\0'; + app->bin_file_path_app_b[0] = '\0'; app->bin_file_path_custom[0] = '\0'; if(boot) { @@ -166,17 +130,9 @@ bool esp_flasher_scene_quick_on_event(void* context, SceneManagerEvent event) { app->selected_flash_options[SelectedFlashPart] = true; strncpy(app->bin_file_path_part, part, sizeof(app->bin_file_path_part)); } - if(nvs) { - app->selected_flash_options[SelectedFlashNvs] = true; - strncpy(app->bin_file_path_nvs, nvs, sizeof(app->bin_file_path_nvs)); - } - if(app0) { - app->selected_flash_options[SelectedFlashBootApp0] = true; - strncpy(app->bin_file_path_boot_app0, app0, sizeof(app->bin_file_path_boot_app0)); - } if(firm) { - app->selected_flash_options[SelectedFlashApp] = true; - strncpy(app->bin_file_path_app, firm, sizeof(app->bin_file_path_app)); + app->selected_flash_options[SelectedFlashAppA] = true; + strncpy(app->bin_file_path_app_a, firm, sizeof(app->bin_file_path_app_a)); } app->reset = false; @@ -186,10 +142,8 @@ bool esp_flasher_scene_quick_on_event(void* context, SceneManagerEvent event) { } } else if(event.type == SceneManagerEventTypeBack) { uint32_t state = scene_manager_get_scene_state(app->scene_manager, EspFlasherSceneQuick); - if(state > QuickMarauder) - state = QuickMarauder; - else if(state > QuickEvilportal) - state = QuickEvilportal; + if(state > QuickDualboot) + state = QuickDualboot; else if(state > QuickBlackmagic) state = QuickBlackmagic; scene_manager_set_scene_state(app->scene_manager, EspFlasherSceneQuick, state); diff --git a/applications/external/esp_flasher/scenes/esp_flasher_scene_start.c b/applications/external/esp_flasher/scenes/esp_flasher_scene_start.c index 7ac899145..ad1bcf912 100644 --- a/applications/external/esp_flasher/scenes/esp_flasher_scene_start.c +++ b/applications/external/esp_flasher/scenes/esp_flasher_scene_start.c @@ -2,6 +2,8 @@ enum SubmenuIndex { SubmenuIndexEspFlasherQuickFlash, + SubmenuIndexEspFlasherSwitchA, + SubmenuIndexEspFlasherSwitchB, SubmenuIndexEspFlasherManualFlash, SubmenuIndexEspFlasherReset, SubmenuIndexEspFlasherBootloader, @@ -27,6 +29,18 @@ void esp_flasher_scene_start_on_enter(void* context) { SubmenuIndexEspFlasherQuickFlash, esp_flasher_scene_start_submenu_callback, app); + submenu_add_item( + submenu, + "Switch to Firmware A", + SubmenuIndexEspFlasherSwitchA, + esp_flasher_scene_start_submenu_callback, + app); + submenu_add_item( + submenu, + "Switch to Firmware B", + SubmenuIndexEspFlasherSwitchB, + esp_flasher_scene_start_submenu_callback, + app); submenu_add_item( submenu, "Manual Flash", @@ -67,6 +81,14 @@ bool esp_flasher_scene_start_on_event(void* context, SceneManagerEvent event) { if(event.event == SubmenuIndexEspFlasherQuickFlash) { scene_manager_next_scene(app->scene_manager, EspFlasherSceneQuick); consumed = true; + } else if(event.event == SubmenuIndexEspFlasherSwitchA) { + app->switch_fw = SwitchToFirmwareA; + scene_manager_next_scene(app->scene_manager, EspFlasherSceneConsoleOutput); + consumed = true; + } else if(event.event == SubmenuIndexEspFlasherSwitchB) { + app->switch_fw = SwitchToFirmwareB; + scene_manager_next_scene(app->scene_manager, EspFlasherSceneConsoleOutput); + consumed = true; } else if(event.event == SubmenuIndexEspFlasherManualFlash) { scene_manager_next_scene(app->scene_manager, EspFlasherSceneBrowse); consumed = true; diff --git a/assets/resources/apps_data/esp_flasher/assets/blackmagic/wifidev/blackmagic.bin b/assets/resources/apps_data/esp_flasher/assets/blackmagic/blackmagic.bin similarity index 100% rename from assets/resources/apps_data/esp_flasher/assets/blackmagic/wifidev/blackmagic.bin rename to assets/resources/apps_data/esp_flasher/assets/blackmagic/blackmagic.bin diff --git a/assets/resources/apps_data/esp_flasher/assets/blackmagic/wifidev/bootloader.bin b/assets/resources/apps_data/esp_flasher/assets/blackmagic/bootloader.bin similarity index 100% rename from assets/resources/apps_data/esp_flasher/assets/blackmagic/wifidev/bootloader.bin rename to assets/resources/apps_data/esp_flasher/assets/blackmagic/bootloader.bin diff --git a/assets/resources/apps_data/esp_flasher/assets/blackmagic/wifidev/partition-table.bin b/assets/resources/apps_data/esp_flasher/assets/blackmagic/partition-table.bin similarity index 100% rename from assets/resources/apps_data/esp_flasher/assets/blackmagic/wifidev/partition-table.bin rename to assets/resources/apps_data/esp_flasher/assets/blackmagic/partition-table.bin diff --git a/assets/resources/apps_data/esp_flasher/assets/blackmagic/wifidev/nvs.bin b/assets/resources/apps_data/esp_flasher/assets/blackmagic/wifidev/nvs.bin deleted file mode 100644 index f10174f3b..000000000 Binary files a/assets/resources/apps_data/esp_flasher/assets/blackmagic/wifidev/nvs.bin and /dev/null differ diff --git a/assets/resources/apps_data/esp_flasher/assets/boot_app0.bin b/assets/resources/apps_data/esp_flasher/assets/boot_app0.bin deleted file mode 100644 index 13562cabb..000000000 Binary files a/assets/resources/apps_data/esp_flasher/assets/boot_app0.bin and /dev/null differ diff --git a/assets/resources/apps_data/esp_flasher/assets/dualboot/devpro-wroom.bin b/assets/resources/apps_data/esp_flasher/assets/dualboot/devpro-wroom.bin new file mode 100644 index 000000000..8135e44f1 Binary files /dev/null and b/assets/resources/apps_data/esp_flasher/assets/dualboot/devpro-wroom.bin differ diff --git a/assets/resources/apps_data/esp_flasher/assets/dualboot/wifidev-s2.bin b/assets/resources/apps_data/esp_flasher/assets/dualboot/wifidev-s2.bin new file mode 100644 index 000000000..868e3fbfd Binary files /dev/null and b/assets/resources/apps_data/esp_flasher/assets/dualboot/wifidev-s2.bin differ diff --git a/assets/resources/apps_data/esp_flasher/assets/evilportal/EvilPortal.ino.partitions.bin b/assets/resources/apps_data/esp_flasher/assets/evilportal/EvilPortal.ino.partitions.bin deleted file mode 100644 index 2108af950..000000000 Binary files a/assets/resources/apps_data/esp_flasher/assets/evilportal/EvilPortal.ino.partitions.bin and /dev/null differ diff --git a/assets/resources/apps_data/esp_flasher/assets/evilportal/devpro-wroom/EvilPortal.ino.bin b/assets/resources/apps_data/esp_flasher/assets/evilportal/devpro-wroom/EvilPortal.ino.bin deleted file mode 100644 index 9d463929d..000000000 Binary files a/assets/resources/apps_data/esp_flasher/assets/evilportal/devpro-wroom/EvilPortal.ino.bin and /dev/null differ diff --git a/assets/resources/apps_data/esp_flasher/assets/evilportal/devpro-wroom/EvilPortal.ino.bootloader.bin b/assets/resources/apps_data/esp_flasher/assets/evilportal/devpro-wroom/EvilPortal.ino.bootloader.bin deleted file mode 100644 index 25c62a975..000000000 Binary files a/assets/resources/apps_data/esp_flasher/assets/evilportal/devpro-wroom/EvilPortal.ino.bootloader.bin and /dev/null differ diff --git a/assets/resources/apps_data/esp_flasher/assets/evilportal/wifidev-s2/EvilPortal.ino.bin b/assets/resources/apps_data/esp_flasher/assets/evilportal/wifidev-s2/EvilPortal.ino.bin deleted file mode 100644 index ce5b19724..000000000 Binary files a/assets/resources/apps_data/esp_flasher/assets/evilportal/wifidev-s2/EvilPortal.ino.bin and /dev/null differ diff --git a/assets/resources/apps_data/esp_flasher/assets/evilportal/wifidev-s2/EvilPortal.ino.bootloader.bin b/assets/resources/apps_data/esp_flasher/assets/evilportal/wifidev-s2/EvilPortal.ino.bootloader.bin deleted file mode 100644 index eee12915e..000000000 Binary files a/assets/resources/apps_data/esp_flasher/assets/evilportal/wifidev-s2/EvilPortal.ino.bootloader.bin and /dev/null differ diff --git a/assets/resources/apps_data/esp_flasher/assets/marauder/devpro-wroom/bootloader.bin b/assets/resources/apps_data/esp_flasher/assets/marauder/devpro-wroom/bootloader.bin deleted file mode 100644 index 05f670d0c..000000000 Binary files a/assets/resources/apps_data/esp_flasher/assets/marauder/devpro-wroom/bootloader.bin and /dev/null differ diff --git a/assets/resources/apps_data/esp_flasher/assets/marauder/devpro-wroom/marauder_dev_board_pro.bin b/assets/resources/apps_data/esp_flasher/assets/marauder/devpro-wroom/marauder_dev_board_pro.bin deleted file mode 100644 index 6b9a53e88..000000000 Binary files a/assets/resources/apps_data/esp_flasher/assets/marauder/devpro-wroom/marauder_dev_board_pro.bin and /dev/null differ diff --git a/assets/resources/apps_data/esp_flasher/assets/marauder/partitions.bin b/assets/resources/apps_data/esp_flasher/assets/marauder/partitions.bin deleted file mode 100644 index fa042d671..000000000 Binary files a/assets/resources/apps_data/esp_flasher/assets/marauder/partitions.bin and /dev/null differ diff --git a/assets/resources/apps_data/esp_flasher/assets/marauder/wifidev-s2/bootloader.bin b/assets/resources/apps_data/esp_flasher/assets/marauder/wifidev-s2/bootloader.bin deleted file mode 100644 index 08c257b11..000000000 Binary files a/assets/resources/apps_data/esp_flasher/assets/marauder/wifidev-s2/bootloader.bin and /dev/null differ diff --git a/assets/resources/apps_data/esp_flasher/assets/marauder/wifidev-s2/flipper_sd_serial.bin b/assets/resources/apps_data/esp_flasher/assets/marauder/wifidev-s2/flipper_sd_serial.bin deleted file mode 100644 index fb247ad7d..000000000 Binary files a/assets/resources/apps_data/esp_flasher/assets/marauder/wifidev-s2/flipper_sd_serial.bin and /dev/null differ