#include "esp_log.h" #include "esp_system.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "flow3r_bsp.h" #include "st3m_fs.h" #include "st3m_fs_flash.h" #include "st3m_fs_sd.h" #include "st3m_gfx.h" #include "st3m_io.h" #include "st3m_usb.h" #include "rec_fatal.h" #include "rec_gui.h" #include "rec_vfs.h" static const char *TAG = "flow3r-recovery"; static menu_t *_cur_menu = NULL; static menu_t _main_menu; static menu_t _diskmode_menu; static menu_t _erasedone_menu; static bool _usb_initialized = false; static void _main_reboot(void) { esp_restart(); } static void _main_disk_mode_flash(void) { _cur_menu = &_diskmode_menu; _cur_menu->selected = 0; if (!_usb_initialized) { _usb_initialized = true; st3m_usb_init(); vTaskDelay(100 / portTICK_PERIOD_MS); } rec_vfs_wl_msc_start_flash(); } static void _main_disk_mode_sd(void) { _cur_menu = &_diskmode_menu; _cur_menu->selected = 0; if (!_usb_initialized) { _usb_initialized = true; st3m_usb_init(); vTaskDelay(100 / portTICK_PERIOD_MS); } rec_vfs_wl_msc_start_sd(); } static void _main_erase_fat32(void) { rec_erasing_draw(); esp_err_t ret = st3m_fs_flash_erase(); if (ret != ESP_OK) { rec_fatal("Erase failed"); } _cur_menu = &_erasedone_menu; _cur_menu->selected = 0; } static void _diskmode_exit(void) { _cur_menu = &_main_menu; _cur_menu->selected = 0; st3m_usb_mode_t usb_mode = { .kind = st3m_usb_mode_kind_disabled, }; st3m_usb_mode_switch(&usb_mode); } static menu_entry_t _main_menu_entries[] = { { .label = "Reboot", .enter = _main_reboot }, { .label = "Disk Mode (Flash)", .enter = _main_disk_mode_flash }, { .label = "Disk Mode (SD)", .enter = _main_disk_mode_sd }, { .label = "Erase FAT32", .enter = _main_erase_fat32 }, }; static menu_t _main_menu = { .entries = _main_menu_entries, .entries_count = 4, .selected = 0, }; static menu_entry_t _diskmode_menu_entries[] = { { .label = "Exit", .enter = _diskmode_exit }, }; static menu_t _diskmode_menu = { .help = "Connect the badge to a PC to\naccess the internal flash\nFAT32 " "partition.", .entries = _diskmode_menu_entries, .entries_count = 1, .selected = 0, }; static menu_entry_t _erasedone_menu_entries[] = { { .label = "Reboot", .enter = _main_reboot }, }; static menu_t _erasedone_menu = { .help = "Erase done.\nBadge will now restart.", .entries = _erasedone_menu_entries, .entries_count = 1, .selected = 0, }; void app_main(void) { ESP_LOGI(TAG, "Starting..."); _cur_menu = &_main_menu; st3m_gfx_init(); for (int i = 0; i < 4; i++) { st3m_gfx_splash(""); } flow3r_bsp_display_set_backlight(100); flow3r_bsp_i2c_init(); st3m_io_init(); st3m_fs_init(); if (st3m_fs_sd_get_status() != st3m_fs_sd_status_probed) { _main_menu_entries[2].disabled = true; } TickType_t last_wake; last_wake = xTaskGetTickCount(); for (;;) { vTaskDelayUntil(&last_wake, 100 / portTICK_PERIOD_MS); rec_menu_draw(_cur_menu); rec_menu_process(_cur_menu); } }