From 04f1c3cce170983ce8df195348aff81722b5ba2d Mon Sep 17 00:00:00 2001 From: tyeth Date: Tue, 17 Dec 2024 18:04:13 +0000 Subject: [PATCH 1/4] USB Reattach fixes + Specify reset time remaining + secrets != 0xFF --- platformio.ini | 51 +++++++++++++------ src/Wippersnapper.cpp | 12 ++++- src/provisioning/tinyusb/Wippersnapper_FS.cpp | 17 +++++-- 3 files changed, 60 insertions(+), 20 deletions(-) diff --git a/platformio.ini b/platformio.ini index dd4acafc2..7e1733d34 100644 --- a/platformio.ini +++ b/platformio.ini @@ -16,8 +16,16 @@ framework = arduino monitor_speed = 115200 lib_compat_mode = strict lib_deps = + ;;;;;;;;;;; FunHouse / LVGL Boards uncomment these ;;;;;;;;;;;;;; + ; https://github.com/adafruit/Adafruit_HX8357_Library.git + ; https://github.com/adafruit/Adafruit_ILI9341.git + ; https://github.com/adafruit/Adafruit_STMPE610.git + ; https://github.com/adafruit/Adafruit-ST7735-Library.git + ; https://github.com/adafruit/Adafruit_TouchScreen.git + ; https://github.com/brentru/lvgl.git#wippersnapper + ; https://github.com/brentru/Adafruit_LvGL_Glue.git#development + ;;;;;;;;;;; All Boards need these libraries included ;;;;;;;;;;;;;; adafruit/Adafruit Zero DMA Library - https://github.com/adafruit/Adafruit_TinyUSB_Arduino.git adafruit/Adafruit NeoPixel adafruit/Adafruit SPIFlash adafruit/Adafruit DotStar @@ -78,14 +86,8 @@ lib_deps = https://github.com/Sensirion/arduino-i2c-sen5x.git https://github.com/adafruit/WiFiNINA.git https://github.com/Starmbi/hp_BH1750.git - ;;;;;;;;;;; FunHouse / LVGL Boards ;;;;;;;;;;;;;; - https://github.com/adafruit/Adafruit_HX8357_Library.git - https://github.com/adafruit/Adafruit_ILI9341.git - https://github.com/adafruit/Adafruit_STMPE610.git - https://github.com/adafruit/Adafruit-ST7735-Library.git - https://github.com/adafruit/Adafruit_TouchScreen.git - https://github.com/brentru/lvgl.git#wippersnapper - https://github.com/brentru/Adafruit_LvGL_Glue.git#development + https://github.com/adafruit/Adafruit_TinyUSB_Arduino.git + ; Common build environment for ESP32 platform @@ -107,9 +109,10 @@ platform = atmelsam platform_packages = platformio/framework-arduino-samd-adafruit@^1.7.13 platformio/tool-jlink@^1.78811.0 -lib_ldf_mode = deep +lib_ldf_mode = chain+ +lib_compat_mode = strict lib_archive = no ; debug timer issues see https://community.platformio.org/t/choose-usb-stack-as-tiny-usb/22451/5 -lib_ignore = OneWire +lib_ignore = OneWire, USBHost [common:rp2040] platform = https://github.com/maxgerhardt/platform-raspberrypi.git @@ -408,7 +411,23 @@ extra_scripts = pre:rename_usb_config.py [env:huzzah] extends=common:esp8266 board = huzzah -build_flags = -DARDUINO_ESP8266_ADAFRUIT_HUZZAH +board_build.f_cpu = 80000000L +; Arduino CLI uses this from adafruit_ci#ci-wippersnapper +; esp8266:esp8266:huzzah:xtal=80,vt=flash,exception=disabled,stacksmash=disabled,ssl=all,mmu=3232,non32xfer=fast,eesz=4M2M,ip=lm2f,dbg=Disabled,lvl=None____,wipe=none,baud=115200 +build_flags = + -Wl,--gc-sections + -Wl,-Map=output.map + -DARDUINO_ESP8266_ADAFRUIT_HUZZAH + -DDEBUG_ESP_PORT=Serial + -DVTABLES_IN_FLASH + -DNO_EXCEPTIONS + -DNO_STACK_SMASH_PROTECTION + -DSSL_ALL + -DMMU_3232 + -DNON32XFER_FAST + -DDEBUG_DISABLED + -DDEBUG_LEVEL_NONE +board_build.eesz=4M2M board_build.filesystem = littlefs upload_port = /dev/cu.SLAB_USBtoUART @@ -418,8 +437,9 @@ upload_port = /dev/cu.SLAB_USBtoUART [env:adafruit_pyportal_m4] extends = common:atsamd board = adafruit_pyportal_m4 -build_flags = -DUSE_TINYUSB=1 +build_flags = -DUSE_TINYUSB -DADAFRUIT_PYPORTAL +extra_scripts = pre:rename_usb_config.py ; Adafruit PyPortal M4 Titano [env:adafruit_pyportal_m4_titano] @@ -463,8 +483,9 @@ build_flags = -DUSE_TINYUSB [env:adafruit_metro_m4_airliftlite] extends = common:atsamd board = adafruit_metro_m4_airliftlite -build_flags = -DUSE_TINYUSB=1 +build_flags = -DUSE_TINYUSB -DADAFRUIT_METRO_M4_AIRLIFT_LITE +; extra_scripts = pre:rename_usb_config.py upload_port = /dev/cu.usbmodem1201 @@ -494,7 +515,7 @@ build_flags = -DDEBUG_RP2040_CORE -DDEBUG_RP2040_WIFI -DNDEBUG - -DLWIP_DEBUG + -DLWIP_DEBUG=1 -DDEBUG_RP2040_PORT=Serial1 -DDEBUG_RP2040_UART_1 -DDEBUG_RP2040_UART=1 diff --git a/src/Wippersnapper.cpp b/src/Wippersnapper.cpp index a4c190825..a7ad455bd 100644 --- a/src/Wippersnapper.cpp +++ b/src/Wippersnapper.cpp @@ -2500,8 +2500,10 @@ void Wippersnapper::runNetFSM() { */ /**************************************************************************/ void Wippersnapper::haltError(String error, ws_led_status_t ledStatusColor) { - for (;;) { - WS_DEBUG_PRINT("ERROR [WDT RESET]: "); + for (int i = 0;; i++) { + WS_DEBUG_PRINT("ERROR [WDT RESET IN "); + WS_DEBUG_PRINT(25 - i); + WS_DEBUG_PRINTLN("]: "); WS_DEBUG_PRINTLN(error); // let the WDT fail out and reset! statusLEDSolid(ledStatusColor); @@ -2512,6 +2514,12 @@ void Wippersnapper::haltError(String error, ws_led_status_t ledStatusColor) { // hardware and software watchdog timers, delayMicroseconds does not. delayMicroseconds(1000000); #endif + if (i < 20) { + yield(); + WS.feedWDT(); // feed the WDT for the first 20 seconds + } else if (i == 20) { + WS.enableWDT(5000); + } } } diff --git a/src/provisioning/tinyusb/Wippersnapper_FS.cpp b/src/provisioning/tinyusb/Wippersnapper_FS.cpp index e4fa0ee72..a84647fb3 100644 --- a/src/provisioning/tinyusb/Wippersnapper_FS.cpp +++ b/src/provisioning/tinyusb/Wippersnapper_FS.cpp @@ -106,6 +106,7 @@ Wippersnapper_FS::Wippersnapper_FS() { // If a filesystem does not already exist - attempt to initialize a new // filesystem if (!initFilesystem() && !initFilesystem(true)) { + TinyUSBDevice.attach(); setStatusLEDColor(RED); fsHalt("ERROR Initializing Filesystem"); } @@ -217,7 +218,12 @@ void Wippersnapper_FS::initUSBMSC() { // init MSC usb_msc.begin(); + // Attach MSC and wait for enumeration + if (TinyUSBDevice.mounted()) { + TinyUSBDevice.detach(); + delay(10); + } TinyUSBDevice.attach(); delay(500); } @@ -232,6 +238,13 @@ bool Wippersnapper_FS::configFileExists() { // Does secrets.json file exist? if (!wipperFatFs.exists("/secrets.json")) return false; + File32 file = wipperFatFs.open("/secrets.json", FILE_READ); + if (!file) + return false; + int firstChar = file.peek(); + file.close(); + if (firstChar <= 0 || firstChar == 255) + return false; return true; } @@ -318,7 +331,7 @@ bool Wippersnapper_FS::createBootFile() { void Wippersnapper_FS::createSecretsFile() { // Open file for writing File32 secretsFile = wipperFatFs.open("/secrets.json", FILE_WRITE); - + secretsFile.truncate(0); // Create a default secretsConfig structure secretsConfig secretsConfig; strcpy(secretsConfig.aio_user, "YOUR_IO_USERNAME_HERE"); @@ -485,8 +498,6 @@ void Wippersnapper_FS::writeToBootOut(PGM_P str) { */ /**************************************************************************/ void Wippersnapper_FS::fsHalt(String msg) { - TinyUSBDevice.attach(); - delay(500); statusLEDSolid(WS_LED_STATUS_FS_WRITE); while (1) { WS_DEBUG_PRINTLN("Fatal Error: Halted execution!"); From 04dbf36da5980fef2a8813785659728567a19bec Mon Sep 17 00:00:00 2001 From: tyeth Date: Thu, 19 Dec 2024 17:15:46 +0000 Subject: [PATCH 2/4] Parameterise the reset timeout for haltError --- src/Wippersnapper.cpp | 13 ++++++++----- src/Wippersnapper.h | 3 ++- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/Wippersnapper.cpp b/src/Wippersnapper.cpp index a7ad455bd..47e472c39 100644 --- a/src/Wippersnapper.cpp +++ b/src/Wippersnapper.cpp @@ -2499,10 +2499,13 @@ void Wippersnapper::runNetFSM() { The desired color to blink. */ /**************************************************************************/ -void Wippersnapper::haltError(String error, ws_led_status_t ledStatusColor) { +void Wippersnapper::haltError(String error, ws_led_status_t ledStatusColor, + uint8_t seconds_until_reboot) { + uint8_t wdt_timeout = 5; // future platform-specific differences + int seconds_until_wdt_enable = seconds_until_reboot - wdt_timeout; for (int i = 0;; i++) { WS_DEBUG_PRINT("ERROR [WDT RESET IN "); - WS_DEBUG_PRINT(25 - i); + WS_DEBUG_PRINT(seconds_until_reboot - i); WS_DEBUG_PRINTLN("]: "); WS_DEBUG_PRINTLN(error); // let the WDT fail out and reset! @@ -2514,11 +2517,11 @@ void Wippersnapper::haltError(String error, ws_led_status_t ledStatusColor) { // hardware and software watchdog timers, delayMicroseconds does not. delayMicroseconds(1000000); #endif - if (i < 20) { + if (i < seconds_until_wdt_enable) { yield(); WS.feedWDT(); // feed the WDT for the first 20 seconds - } else if (i == 20) { - WS.enableWDT(5000); + } else if (i == seconds_until_reboot) { + WS.enableWDT(wdt_timeout * 1000); } } } diff --git a/src/Wippersnapper.h b/src/Wippersnapper.h index ede523228..2962b7710 100644 --- a/src/Wippersnapper.h +++ b/src/Wippersnapper.h @@ -306,7 +306,8 @@ class Wippersnapper { // Error handling helpers void haltError(String error, - ws_led_status_t ledStatusColor = WS_LED_STATUS_ERROR_RUNTIME); + ws_led_status_t ledStatusColor = WS_LED_STATUS_ERROR_RUNTIME, + uint8_t seconds_until_reboot = 25); void errorWriteHang(String error); // MQTT topic callbacks // From f87a2083acffc3831d62de1c11a3d26c62ce7cca Mon Sep 17 00:00:00 2001 From: tyeth Date: Thu, 19 Dec 2024 17:22:34 +0000 Subject: [PATCH 3/4] Swap WDT timeout to milliseconds in haltError to match Arch differerences --- src/Wippersnapper.cpp | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/Wippersnapper.cpp b/src/Wippersnapper.cpp index 47e472c39..3c222a21b 100644 --- a/src/Wippersnapper.cpp +++ b/src/Wippersnapper.cpp @@ -2494,15 +2494,19 @@ void Wippersnapper::runNetFSM() { @brief Prints an error to the serial and halts the hardware until the WDT bites. @param error - The desired error to print to serial. + The error to print to serial. @param ledStatusColor - The desired color to blink. + The color to blink. + @param seconds_until_reboot + The amount of time to wait before rebooting. */ /**************************************************************************/ void Wippersnapper::haltError(String error, ws_led_status_t ledStatusColor, uint8_t seconds_until_reboot) { - uint8_t wdt_timeout = 5; // future platform-specific differences - int seconds_until_wdt_enable = seconds_until_reboot - wdt_timeout; + uint8_t wdt_timeout_ms = 5000; // future platform-specific differences + int seconds_until_wdt_enable = + seconds_until_reboot - (int)(wdt_timeout_ms / 1000); + for (int i = 0;; i++) { WS_DEBUG_PRINT("ERROR [WDT RESET IN "); WS_DEBUG_PRINT(seconds_until_reboot - i); @@ -2521,7 +2525,7 @@ void Wippersnapper::haltError(String error, ws_led_status_t ledStatusColor, yield(); WS.feedWDT(); // feed the WDT for the first 20 seconds } else if (i == seconds_until_reboot) { - WS.enableWDT(wdt_timeout * 1000); + WS.enableWDT(wdt_timeout_ms); } } } From b594a3b872961c2627423aac1595faa0d017e388 Mon Sep 17 00:00:00 2001 From: tyeth Date: Thu, 19 Dec 2024 18:25:55 +0000 Subject: [PATCH 4/4] Add custom WDT timeout for ESP8266 --- src/Wippersnapper.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/Wippersnapper.cpp b/src/Wippersnapper.cpp index 3c222a21b..7488787af 100644 --- a/src/Wippersnapper.cpp +++ b/src/Wippersnapper.cpp @@ -2503,7 +2503,11 @@ void Wippersnapper::runNetFSM() { /**************************************************************************/ void Wippersnapper::haltError(String error, ws_led_status_t ledStatusColor, uint8_t seconds_until_reboot) { - uint8_t wdt_timeout_ms = 5000; // future platform-specific differences +#ifdef ARDUINO_ARCH_ESP8266 + uint8_t wdt_timeout_ms = 3200; +#else + uint8_t wdt_timeout_ms = 5000; +#endif int seconds_until_wdt_enable = seconds_until_reboot - (int)(wdt_timeout_ms / 1000); @@ -2523,7 +2527,7 @@ void Wippersnapper::haltError(String error, ws_led_status_t ledStatusColor, #endif if (i < seconds_until_wdt_enable) { yield(); - WS.feedWDT(); // feed the WDT for the first 20 seconds + WS.feedWDT(); // feed the WDT for the first X-5 seconds } else if (i == seconds_until_reboot) { WS.enableWDT(wdt_timeout_ms); }