From 80685060a81667d957e1b9b4a03c1d3160cdb577 Mon Sep 17 00:00:00 2001 From: 0xchocolate <0xchocolate@users.noreply.github.com> Date: Sat, 22 Jul 2023 11:37:24 -0700 Subject: [PATCH] Implement auto-reset for supported boards and reset/boot menu items --- esp_flasher_app.c | 3 ++ esp_flasher_app.h | 2 +- esp_flasher_app_i.h | 3 ++ esp_flasher_worker.c | 62 ++++++++++++++++++++++++++++++-- esp_flasher_worker.h | 2 ++ scenes/esp_flasher_scene_start.c | 22 ++++++++++++ 6 files changed, 91 insertions(+), 3 deletions(-) diff --git a/esp_flasher_app.c b/esp_flasher_app.c index e29bb14..c197a01 100644 --- a/esp_flasher_app.c +++ b/esp_flasher_app.c @@ -65,6 +65,9 @@ EspFlasherApp* esp_flasher_app_alloc() { app->flash_worker_busy = false; + app->reset = false; + app->boot = false; + scene_manager_next_scene(app->scene_manager, EspFlasherSceneStart); return app; diff --git a/esp_flasher_app.h b/esp_flasher_app.h index 413dd58..809fcc6 100644 --- a/esp_flasher_app.h +++ b/esp_flasher_app.h @@ -4,7 +4,7 @@ extern "C" { #endif -#define ESP_FLASHER_APP_VERSION "v1.0" +#define ESP_FLASHER_APP_VERSION "v1.1" typedef struct EspFlasherApp EspFlasherApp; diff --git a/esp_flasher_app_i.h b/esp_flasher_app_i.h index 9b8b81a..43161d8 100644 --- a/esp_flasher_app_i.h +++ b/esp_flasher_app_i.h @@ -54,6 +54,9 @@ struct EspFlasherApp { EspFlasherUart* uart; + bool reset; + bool boot; + bool selected_flash_options[NUM_FLASH_OPTIONS]; int num_selected_flash_options; char bin_file_path_boot[100]; diff --git a/esp_flasher_worker.c b/esp_flasher_worker.c index b5a647d..a1d7aa0 100644 --- a/esp_flasher_worker.c +++ b/esp_flasher_worker.c @@ -170,6 +170,7 @@ static int32_t esp_flasher_flash_bin(void* context) { furi_hal_uart_set_br(FuriHalUartIdUSART1, 115200); #endif loader_port_debug_print("Done flashing. Please reset the board manually.\n"); + loader_port_reset_target(); } // done @@ -182,6 +183,48 @@ static int32_t esp_flasher_flash_bin(void* context) { return 0; } +static void _initDTR(void) { + furi_hal_gpio_init(&gpio_ext_pc3, GpioModeOutputPushPull, GpioPullDown, GpioSpeedVeryHigh); +} + +static void _initRTS(void) { + furi_hal_gpio_init(&gpio_ext_pb2, GpioModeOutputPushPull, GpioPullDown, GpioSpeedVeryHigh); +} + +static void _setDTR(bool state) { + furi_hal_gpio_write(&gpio_ext_pc3, state); +} + +static void _setRTS(bool state) { + furi_hal_gpio_write(&gpio_ext_pb2, state); +} + +static int32_t esp_flasher_reset(void* context) { + EspFlasherApp* app = (void*)context; + + app->flash_worker_busy = true; + + _setDTR(false); + _initDTR(); + _setRTS(false); + _initRTS(); + + if (app->reset) { + loader_port_debug_print("Resetting board\n"); + loader_port_reset_target(); + } else if (app->boot) { + loader_port_debug_print("Entering bootloader\n"); + loader_port_enter_bootloader(); + } + + // done + app->flash_worker_busy = false; + app->reset = false; + app->boot = false; + + return 0; +} + void esp_flasher_worker_start_thread(EspFlasherApp* app) { global_app = app; @@ -189,7 +232,11 @@ void esp_flasher_worker_start_thread(EspFlasherApp* app) { furi_thread_set_name(app->flash_worker, "EspFlasherFlashWorker"); furi_thread_set_stack_size(app->flash_worker, 2048); furi_thread_set_context(app->flash_worker, app); - furi_thread_set_callback(app->flash_worker, esp_flasher_flash_bin); + if (app->reset || app->boot) { + furi_thread_set_callback(app->flash_worker, esp_flasher_reset); + } else { + furi_thread_set_callback(app->flash_worker, esp_flasher_flash_bin); + } furi_thread_start(app->flash_worker); } @@ -213,8 +260,19 @@ esp_loader_error_t loader_port_write(const uint8_t* data, uint16_t size, uint32_ return ESP_LOADER_SUCCESS; } +void loader_port_reset_target(void) { + _setDTR(true); + loader_port_delay_ms(SERIAL_FLASHER_RESET_HOLD_TIME_MS); + _setDTR(false); +} + void loader_port_enter_bootloader(void) { - // unimplemented + _setDTR(true); + loader_port_delay_ms(SERIAL_FLASHER_RESET_HOLD_TIME_MS); + _setRTS(true); + _setDTR(false); + loader_port_delay_ms(SERIAL_FLASHER_BOOT_HOLD_TIME_MS); + _setRTS(false); } void loader_port_delay_ms(uint32_t ms) { diff --git a/esp_flasher_worker.h b/esp_flasher_worker.h index 5df7539..44461e7 100644 --- a/esp_flasher_worker.h +++ b/esp_flasher_worker.h @@ -5,6 +5,8 @@ #ifndef SERIAL_FLASHER_INTERFACE_UART #define SERIAL_FLASHER_INTERFACE_UART /* TODO why is application.fam not passing this via cdefines */ #endif +#define SERIAL_FLASHER_RESET_HOLD_TIME_MS 100 +#define SERIAL_FLASHER_BOOT_HOLD_TIME_MS 50 #include "esp_loader_io.h" #define ESP_ADDR_BOOT_S3 0x0 diff --git a/scenes/esp_flasher_scene_start.c b/scenes/esp_flasher_scene_start.c index 82a3f5e..2d91f2d 100644 --- a/scenes/esp_flasher_scene_start.c +++ b/scenes/esp_flasher_scene_start.c @@ -3,6 +3,8 @@ enum SubmenuIndex { SubmenuIndexEspFlasherFlash, SubmenuIndexEspFlasherAbout, + SubmenuIndexEspFlasherReset, + SubmenuIndexEspFlasherBootloader, }; void esp_flasher_scene_start_submenu_callback(void* context, uint32_t index) { @@ -23,6 +25,18 @@ void esp_flasher_scene_start_on_enter(void* context) { SubmenuIndexEspFlasherFlash, esp_flasher_scene_start_submenu_callback, app); + submenu_add_item( + submenu, + "Reset Board", + SubmenuIndexEspFlasherReset, + esp_flasher_scene_start_submenu_callback, + app); + submenu_add_item( + submenu, + "Enter Bootloader", + SubmenuIndexEspFlasherBootloader, + esp_flasher_scene_start_submenu_callback, + app); submenu_add_item( submenu, "About", @@ -48,6 +62,14 @@ bool esp_flasher_scene_start_on_event(void* context, SceneManagerEvent event) { } else if(event.event == SubmenuIndexEspFlasherFlash) { scene_manager_next_scene(app->scene_manager, EspFlasherSceneBrowse); consumed = true; + } else if(event.event == SubmenuIndexEspFlasherReset) { + app->reset = true; + scene_manager_next_scene(app->scene_manager, EspFlasherSceneConsoleOutput); + consumed = true; + } else if(event.event == SubmenuIndexEspFlasherBootloader) { + app->boot = true; + scene_manager_next_scene(app->scene_manager, EspFlasherSceneConsoleOutput); + consumed = true; } scene_manager_set_scene_state(app->scene_manager, EspFlasherSceneStart, event.event); }