mirror of
https://github.com/Next-Flip/Momentum-Firmware.git
synced 2026-05-14 12:18:35 -07:00
ESP Flasher dual boot
This commit is contained in:
Binary file not shown.
|
Before Width: | Height: | Size: 1.8 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 1.8 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 1.8 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 1.8 KiB |
@@ -117,6 +117,7 @@ int32_t esp_flasher_app(void* p) {
|
|||||||
UNUSED(p);
|
UNUSED(p);
|
||||||
|
|
||||||
uint8_t attempts = 0;
|
uint8_t attempts = 0;
|
||||||
|
bool otg_was_enabled = furi_hal_power_is_otg_enabled();
|
||||||
while(!furi_hal_power_is_otg_enabled() && attempts++ < 5) {
|
while(!furi_hal_power_is_otg_enabled() && attempts++ < 5) {
|
||||||
furi_hal_power_enable_otg();
|
furi_hal_power_enable_otg();
|
||||||
furi_delay_ms(10);
|
furi_delay_ms(10);
|
||||||
@@ -133,7 +134,7 @@ int32_t esp_flasher_app(void* p) {
|
|||||||
|
|
||||||
esp_flasher_app_free(esp_flasher_app);
|
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();
|
furi_hal_power_disable_otg();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define ESP_FLASHER_APP_VERSION "v1.1"
|
#define ESP_FLASHER_APP_VERSION "v1.2"
|
||||||
|
|
||||||
typedef struct EspFlasherApp EspFlasherApp;
|
typedef struct EspFlasherApp EspFlasherApp;
|
||||||
|
|
||||||
|
|||||||
@@ -34,11 +34,18 @@ typedef enum SelectedFlashOptions {
|
|||||||
SelectedFlashPart,
|
SelectedFlashPart,
|
||||||
SelectedFlashNvs,
|
SelectedFlashNvs,
|
||||||
SelectedFlashBootApp0,
|
SelectedFlashBootApp0,
|
||||||
SelectedFlashApp,
|
SelectedFlashAppA,
|
||||||
|
SelectedFlashAppB,
|
||||||
SelectedFlashCustom,
|
SelectedFlashCustom,
|
||||||
NUM_FLASH_OPTIONS
|
NUM_FLASH_OPTIONS
|
||||||
} SelectedFlashOptions;
|
} SelectedFlashOptions;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
SwitchNotSet,
|
||||||
|
SwitchToFirmwareA,
|
||||||
|
SwitchToFirmwareB,
|
||||||
|
} SwitchFirmware;
|
||||||
|
|
||||||
struct EspFlasherApp {
|
struct EspFlasherApp {
|
||||||
Gui* gui;
|
Gui* gui;
|
||||||
ViewDispatcher* view_dispatcher;
|
ViewDispatcher* view_dispatcher;
|
||||||
@@ -61,13 +68,16 @@ struct EspFlasherApp {
|
|||||||
bool boot;
|
bool boot;
|
||||||
bool quickflash;
|
bool quickflash;
|
||||||
|
|
||||||
|
SwitchFirmware switch_fw;
|
||||||
|
|
||||||
bool selected_flash_options[NUM_FLASH_OPTIONS];
|
bool selected_flash_options[NUM_FLASH_OPTIONS];
|
||||||
int num_selected_flash_options;
|
int num_selected_flash_options;
|
||||||
char bin_file_path_boot[100];
|
char bin_file_path_boot[100];
|
||||||
char bin_file_path_part[100];
|
char bin_file_path_part[100];
|
||||||
char bin_file_path_nvs[100];
|
char bin_file_path_nvs[100];
|
||||||
char bin_file_path_boot_app0[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];
|
char bin_file_path_custom[100];
|
||||||
FuriThread* flash_worker;
|
FuriThread* flash_worker;
|
||||||
bool flash_worker_busy;
|
bool flash_worker_busy;
|
||||||
|
|||||||
@@ -74,6 +74,85 @@ static esp_loader_error_t _flash_file(EspFlasherApp* app, char* filepath, uint32
|
|||||||
return ESP_LOADER_SUCCESS;
|
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 {
|
typedef struct {
|
||||||
SelectedFlashOptions selected;
|
SelectedFlashOptions selected;
|
||||||
const char* description;
|
const char* description;
|
||||||
@@ -85,7 +164,7 @@ static void _flash_all_files(EspFlasherApp* app) {
|
|||||||
esp_loader_error_t err;
|
esp_loader_error_t err;
|
||||||
const int num_steps = app->num_selected_flash_options;
|
const int num_steps = app->num_selected_flash_options;
|
||||||
|
|
||||||
#define NUM_FLASH_ITEMS 6
|
#define NUM_FLASH_ITEMS 7
|
||||||
FlashItem items[NUM_FLASH_ITEMS] = {
|
FlashItem items[NUM_FLASH_ITEMS] = {
|
||||||
{SelectedFlashBoot,
|
{SelectedFlashBoot,
|
||||||
"bootloader",
|
"bootloader",
|
||||||
@@ -94,7 +173,8 @@ static void _flash_all_files(EspFlasherApp* app) {
|
|||||||
{SelectedFlashPart, "partition table", app->bin_file_path_part, ESP_ADDR_PART},
|
{SelectedFlashPart, "partition table", app->bin_file_path_part, ESP_ADDR_PART},
|
||||||
{SelectedFlashNvs, "NVS", app->bin_file_path_nvs, ESP_ADDR_NVS},
|
{SelectedFlashNvs, "NVS", app->bin_file_path_nvs, ESP_ADDR_NVS},
|
||||||
{SelectedFlashBootApp0, "boot_app0", app->bin_file_path_boot_app0, ESP_ADDR_BOOT_APP0},
|
{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},
|
{SelectedFlashCustom, "custom data", app->bin_file_path_custom, 0x0},
|
||||||
/* if you add more entries, update NUM_FLASH_ITEMS above! */
|
/* 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) {
|
if(!err) {
|
||||||
loader_port_debug_print("Connected\n");
|
loader_port_debug_print("Connected\n");
|
||||||
_flash_all_files(app);
|
if(!_switch_fw(app)) {
|
||||||
|
_flash_all_files(app);
|
||||||
|
}
|
||||||
|
app->switch_fw = SwitchNotSet;
|
||||||
#if 0
|
#if 0
|
||||||
loader_port_debug_print("Restoring transmission rate\n");
|
loader_port_debug_print("Restoring transmission rate\n");
|
||||||
furi_hal_uart_set_br(FuriHalUartIdUSART1, 115200);
|
furi_hal_uart_set_br(FuriHalUartIdUSART1, 115200);
|
||||||
@@ -286,6 +369,8 @@ void loader_port_reset_target(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void loader_port_enter_bootloader(void) {
|
void loader_port_enter_bootloader(void) {
|
||||||
|
// adapted from custom usb-jtag-serial reset in esptool
|
||||||
|
// (works on official wifi dev board)
|
||||||
_setDTR(true);
|
_setDTR(true);
|
||||||
loader_port_delay_ms(SERIAL_FLASHER_RESET_HOLD_TIME_MS);
|
loader_port_delay_ms(SERIAL_FLASHER_RESET_HOLD_TIME_MS);
|
||||||
_setRTS(true);
|
_setRTS(true);
|
||||||
|
|||||||
@@ -14,7 +14,11 @@
|
|||||||
#define ESP_ADDR_PART 0x8000
|
#define ESP_ADDR_PART 0x8000
|
||||||
#define ESP_ADDR_NVS 0x9000
|
#define ESP_ADDR_NVS 0x9000
|
||||||
#define ESP_ADDR_BOOT_APP0 0xE000
|
#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_start_thread(EspFlasherApp* app);
|
||||||
void esp_flasher_worker_stop_thread(EspFlasherApp* app);
|
void esp_flasher_worker_stop_thread(EspFlasherApp* app);
|
||||||
|
|||||||
@@ -7,7 +7,8 @@ enum SubmenuIndex {
|
|||||||
SubmenuIndexPart,
|
SubmenuIndexPart,
|
||||||
SubmenuIndexNvs,
|
SubmenuIndexNvs,
|
||||||
SubmenuIndexBootApp0,
|
SubmenuIndexBootApp0,
|
||||||
SubmenuIndexApp,
|
SubmenuIndexAppA,
|
||||||
|
SubmenuIndexAppB,
|
||||||
SubmenuIndexCustom,
|
SubmenuIndexCustom,
|
||||||
SubmenuIndexFlash,
|
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);
|
view_dispatcher_send_custom_event(app->view_dispatcher, EspFlasherEventRefreshSubmenu);
|
||||||
break;
|
break;
|
||||||
case SubmenuIndexApp:
|
case SubmenuIndexAppA:
|
||||||
app->selected_flash_options[SelectedFlashApp] =
|
app->selected_flash_options[SelectedFlashAppA] =
|
||||||
!app->selected_flash_options[SelectedFlashApp];
|
!app->selected_flash_options[SelectedFlashAppA];
|
||||||
if(dialog_file_browser_show(
|
if(dialog_file_browser_show(
|
||||||
app->dialogs, selected_filepath, predefined_filepath, &browser_options)) {
|
app->dialogs, selected_filepath, predefined_filepath, &browser_options)) {
|
||||||
strncpy(
|
strncpy(
|
||||||
app->bin_file_path_app,
|
app->bin_file_path_app_a,
|
||||||
furi_string_get_cstr(selected_filepath),
|
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
|
// 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);
|
view_dispatcher_send_custom_event(app->view_dispatcher, EspFlasherEventRefreshSubmenu);
|
||||||
break;
|
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_PART "Part Table (" TOSTRING(ESP_ADDR_PART) ")"
|
||||||
#define STR_NVS "NVS (" TOSTRING(ESP_ADDR_NVS) ")"
|
#define STR_NVS "NVS (" TOSTRING(ESP_ADDR_NVS) ")"
|
||||||
#define STR_BOOT_APP0 "boot_app0 (" TOSTRING(ESP_ADDR_BOOT_APP0) ")"
|
#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_CUSTOM "Custom"
|
||||||
#define STR_FLASH_S3 "[>] FLASH (ESP32-S3)"
|
#define STR_FLASH_S3 "[>] FLASH (ESP32-S3)"
|
||||||
#define STR_FLASH "[>] FLASH"
|
#define STR_FLASH "[>] FLASH"
|
||||||
@@ -213,9 +231,16 @@ static void _refresh_submenu(EspFlasherApp* app) {
|
|||||||
app);
|
app);
|
||||||
submenu_add_item(
|
submenu_add_item(
|
||||||
submenu,
|
submenu,
|
||||||
app->selected_flash_options[SelectedFlashApp] ? STR_SELECT " " STR_APP :
|
app->selected_flash_options[SelectedFlashAppA] ? STR_SELECT " " STR_APP_A :
|
||||||
STR_UNSELECT " " STR_APP,
|
STR_UNSELECT " " STR_APP_A,
|
||||||
SubmenuIndexApp,
|
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,
|
esp_flasher_scene_browse_callback,
|
||||||
app);
|
app);
|
||||||
// TODO: custom addr
|
// 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_part[0] = '\0';
|
||||||
app->bin_file_path_nvs[0] = '\0';
|
app->bin_file_path_nvs[0] = '\0';
|
||||||
app->bin_file_path_boot_app0[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';
|
app->bin_file_path_custom[0] = '\0';
|
||||||
|
|
||||||
_refresh_submenu(app);
|
_refresh_submenu(app);
|
||||||
|
|||||||
@@ -4,12 +4,9 @@ enum QuickState {
|
|||||||
QuickStart,
|
QuickStart,
|
||||||
QuickBlackmagic,
|
QuickBlackmagic,
|
||||||
QuickBlackmagicWifidev,
|
QuickBlackmagicWifidev,
|
||||||
QuickEvilportal,
|
QuickDualboot,
|
||||||
QuickEvilportalWifidevS2,
|
QuickDualbootWifidevS2,
|
||||||
QuickEvilportalDevproWroom,
|
QuickDualbootDevproWroom,
|
||||||
QuickMarauder,
|
|
||||||
QuickMarauderWifidevS2,
|
|
||||||
QuickMarauderDevproWroom,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void esp_flasher_scene_quick_submenu_callback(void* context, uint32_t index) {
|
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) {
|
switch(state) {
|
||||||
case QuickStart:
|
case QuickStart:
|
||||||
case QuickBlackmagic:
|
case QuickBlackmagic:
|
||||||
case QuickEvilportal:
|
case QuickDualboot:
|
||||||
case QuickMarauder:
|
|
||||||
submenu_set_header(submenu, "Flash Firmware:");
|
submenu_set_header(submenu, "Flash Firmware:");
|
||||||
submenu_add_item(
|
submenu_add_item(
|
||||||
submenu, "Black Magic", QuickBlackmagic, esp_flasher_scene_quick_submenu_callback, app);
|
submenu, "Black Magic", QuickBlackmagic, esp_flasher_scene_quick_submenu_callback, app);
|
||||||
submenu_add_item(
|
submenu_add_item(
|
||||||
submenu, "Evil Portal", QuickEvilportal, esp_flasher_scene_quick_submenu_callback, app);
|
submenu,
|
||||||
submenu_add_item(
|
"EvilPortal + Marauder",
|
||||||
submenu, "Marauder", QuickMarauder, esp_flasher_scene_quick_submenu_callback, app);
|
QuickDualboot,
|
||||||
|
esp_flasher_scene_quick_submenu_callback,
|
||||||
|
app);
|
||||||
break;
|
break;
|
||||||
case QuickBlackmagicWifidev:
|
case QuickBlackmagicWifidev:
|
||||||
submenu_set_header(submenu, "Flash Black Magic To:");
|
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,
|
esp_flasher_scene_quick_submenu_callback,
|
||||||
app);
|
app);
|
||||||
break;
|
break;
|
||||||
case QuickEvilportalWifidevS2:
|
case QuickDualbootWifidevS2:
|
||||||
case QuickEvilportalDevproWroom:
|
case QuickDualbootDevproWroom:
|
||||||
submenu_set_header(submenu, "Flash Evil Portal To:");
|
submenu_set_header(submenu, "Flash EP+MR To:");
|
||||||
submenu_add_item(
|
submenu_add_item(
|
||||||
submenu,
|
submenu,
|
||||||
"WiFi Dev (ESP32-S2)",
|
"WiFi Dev (ESP32-S2)",
|
||||||
QuickEvilportalWifidevS2,
|
QuickDualbootWifidevS2,
|
||||||
esp_flasher_scene_quick_submenu_callback,
|
esp_flasher_scene_quick_submenu_callback,
|
||||||
app);
|
app);
|
||||||
submenu_add_item(
|
submenu_add_item(
|
||||||
submenu,
|
submenu,
|
||||||
"Dev Pro (ESP32-WROOM)",
|
"Dev Pro (ESP32-WROOM)",
|
||||||
QuickEvilportalDevproWroom,
|
QuickDualbootDevproWroom,
|
||||||
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,
|
|
||||||
esp_flasher_scene_quick_submenu_callback,
|
esp_flasher_scene_quick_submenu_callback,
|
||||||
app);
|
app);
|
||||||
break;
|
break;
|
||||||
@@ -100,47 +82,28 @@ bool esp_flasher_scene_quick_on_event(void* context, SceneManagerEvent event) {
|
|||||||
bool enter_bootloader = false;
|
bool enter_bootloader = false;
|
||||||
const char* boot = NULL; // 0x1000
|
const char* boot = NULL; // 0x1000
|
||||||
const char* part = NULL; // 0x8000
|
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
|
const char* firm = NULL; // 0x10000
|
||||||
|
|
||||||
switch(event.event) {
|
switch(event.event) {
|
||||||
case QuickBlackmagic:
|
case QuickBlackmagic:
|
||||||
case QuickEvilportal:
|
case QuickDualboot:
|
||||||
case QuickMarauder:
|
|
||||||
scene_manager_set_scene_state(
|
scene_manager_set_scene_state(
|
||||||
app->scene_manager, EspFlasherSceneQuick, event.event + 1);
|
app->scene_manager, EspFlasherSceneQuick, event.event + 1);
|
||||||
scene_manager_next_scene(app->scene_manager, EspFlasherSceneQuick);
|
scene_manager_next_scene(app->scene_manager, EspFlasherSceneQuick);
|
||||||
flash = false;
|
flash = false;
|
||||||
break;
|
break;
|
||||||
case QuickBlackmagicWifidev:
|
case QuickBlackmagicWifidev:
|
||||||
boot = APP_DATA_PATH("assets/blackmagic/wifidev/bootloader.bin");
|
boot = APP_DATA_PATH("assets/blackmagic/bootloader.bin");
|
||||||
part = APP_DATA_PATH("assets/blackmagic/wifidev/partition-table.bin");
|
part = APP_DATA_PATH("assets/blackmagic/partition-table.bin");
|
||||||
nvs = APP_DATA_PATH("assets/blackmagic/wifidev/nvs.bin");
|
firm = APP_DATA_PATH("assets/blackmagic/blackmagic.bin");
|
||||||
firm = APP_DATA_PATH("assets/blackmagic/wifidev/blackmagic.bin");
|
|
||||||
enter_bootloader = true;
|
enter_bootloader = true;
|
||||||
break;
|
break;
|
||||||
case QuickEvilportalWifidevS2:
|
case QuickDualbootWifidevS2:
|
||||||
boot = APP_DATA_PATH("assets/evilportal/wifidev-s2/EvilPortal.ino.bootloader.bin");
|
boot = APP_DATA_PATH("assets/dualboot/wifidev-s2.bin");
|
||||||
part = APP_DATA_PATH("assets/evilportal/EvilPortal.ino.partitions.bin");
|
|
||||||
firm = APP_DATA_PATH("assets/evilportal/wifidev-s2/EvilPortal.ino.bin");
|
|
||||||
enter_bootloader = true;
|
enter_bootloader = true;
|
||||||
break;
|
break;
|
||||||
case QuickEvilportalDevproWroom:
|
case QuickDualbootDevproWroom:
|
||||||
boot = APP_DATA_PATH("assets/evilportal/devpro-wroom/EvilPortal.ino.bootloader.bin");
|
boot = APP_DATA_PATH("assets/dualboot/devpro-wroom.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");
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
flash = false;
|
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_part[0] = '\0';
|
||||||
app->bin_file_path_nvs[0] = '\0';
|
app->bin_file_path_nvs[0] = '\0';
|
||||||
app->bin_file_path_boot_app0[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';
|
app->bin_file_path_custom[0] = '\0';
|
||||||
|
|
||||||
if(boot) {
|
if(boot) {
|
||||||
@@ -166,17 +130,9 @@ bool esp_flasher_scene_quick_on_event(void* context, SceneManagerEvent event) {
|
|||||||
app->selected_flash_options[SelectedFlashPart] = true;
|
app->selected_flash_options[SelectedFlashPart] = true;
|
||||||
strncpy(app->bin_file_path_part, part, sizeof(app->bin_file_path_part));
|
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) {
|
if(firm) {
|
||||||
app->selected_flash_options[SelectedFlashApp] = true;
|
app->selected_flash_options[SelectedFlashAppA] = true;
|
||||||
strncpy(app->bin_file_path_app, firm, sizeof(app->bin_file_path_app));
|
strncpy(app->bin_file_path_app_a, firm, sizeof(app->bin_file_path_app_a));
|
||||||
}
|
}
|
||||||
|
|
||||||
app->reset = false;
|
app->reset = false;
|
||||||
@@ -186,10 +142,8 @@ bool esp_flasher_scene_quick_on_event(void* context, SceneManagerEvent event) {
|
|||||||
}
|
}
|
||||||
} else if(event.type == SceneManagerEventTypeBack) {
|
} else if(event.type == SceneManagerEventTypeBack) {
|
||||||
uint32_t state = scene_manager_get_scene_state(app->scene_manager, EspFlasherSceneQuick);
|
uint32_t state = scene_manager_get_scene_state(app->scene_manager, EspFlasherSceneQuick);
|
||||||
if(state > QuickMarauder)
|
if(state > QuickDualboot)
|
||||||
state = QuickMarauder;
|
state = QuickDualboot;
|
||||||
else if(state > QuickEvilportal)
|
|
||||||
state = QuickEvilportal;
|
|
||||||
else if(state > QuickBlackmagic)
|
else if(state > QuickBlackmagic)
|
||||||
state = QuickBlackmagic;
|
state = QuickBlackmagic;
|
||||||
scene_manager_set_scene_state(app->scene_manager, EspFlasherSceneQuick, state);
|
scene_manager_set_scene_state(app->scene_manager, EspFlasherSceneQuick, state);
|
||||||
|
|||||||
@@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
enum SubmenuIndex {
|
enum SubmenuIndex {
|
||||||
SubmenuIndexEspFlasherQuickFlash,
|
SubmenuIndexEspFlasherQuickFlash,
|
||||||
|
SubmenuIndexEspFlasherSwitchA,
|
||||||
|
SubmenuIndexEspFlasherSwitchB,
|
||||||
SubmenuIndexEspFlasherManualFlash,
|
SubmenuIndexEspFlasherManualFlash,
|
||||||
SubmenuIndexEspFlasherReset,
|
SubmenuIndexEspFlasherReset,
|
||||||
SubmenuIndexEspFlasherBootloader,
|
SubmenuIndexEspFlasherBootloader,
|
||||||
@@ -27,6 +29,18 @@ void esp_flasher_scene_start_on_enter(void* context) {
|
|||||||
SubmenuIndexEspFlasherQuickFlash,
|
SubmenuIndexEspFlasherQuickFlash,
|
||||||
esp_flasher_scene_start_submenu_callback,
|
esp_flasher_scene_start_submenu_callback,
|
||||||
app);
|
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_add_item(
|
||||||
submenu,
|
submenu,
|
||||||
"Manual Flash",
|
"Manual Flash",
|
||||||
@@ -67,6 +81,14 @@ bool esp_flasher_scene_start_on_event(void* context, SceneManagerEvent event) {
|
|||||||
if(event.event == SubmenuIndexEspFlasherQuickFlash) {
|
if(event.event == SubmenuIndexEspFlasherQuickFlash) {
|
||||||
scene_manager_next_scene(app->scene_manager, EspFlasherSceneQuick);
|
scene_manager_next_scene(app->scene_manager, EspFlasherSceneQuick);
|
||||||
consumed = true;
|
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) {
|
} else if(event.event == SubmenuIndexEspFlasherManualFlash) {
|
||||||
scene_manager_next_scene(app->scene_manager, EspFlasherSceneBrowse);
|
scene_manager_next_scene(app->scene_manager, EspFlasherSceneBrowse);
|
||||||
consumed = true;
|
consumed = true;
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user