Просмотр исходного кода

Implement auto-reset for supported boards and reset/boot menu items

0xchocolate 2 лет назад
Родитель
Сommit
80685060a8
6 измененных файлов с 91 добавлено и 3 удалено
  1. 3 0
      esp_flasher_app.c
  2. 1 1
      esp_flasher_app.h
  3. 3 0
      esp_flasher_app_i.h
  4. 60 2
      esp_flasher_worker.c
  5. 2 0
      esp_flasher_worker.h
  6. 22 0
      scenes/esp_flasher_scene_start.c

+ 3 - 0
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;

+ 1 - 1
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;
 

+ 3 - 0
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];

+ 60 - 2
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) {

+ 2 - 0
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

+ 22 - 0
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);
     }