mirror of
https://github.com/meshtastic/firmware.git
synced 2026-11-06 22:34:13 -05:00
fix(stm32wl): improve reboot-to-DFU reliability (#11698)
- In enter_dfu, arm enterDfuAtMsec = millis() + 5s and return instead of resetting inline; the want_response ACK then goes out the normal path and Power::powerCommandsCheck() calls enterDfuMode() at the deadline. Nudge the deadline off 0 in the rare case the addition wraps to it, since powerCommandsCheck() reads 0 as unarmed. The delay is the client's detach window - and the margin a WebSerial web flasher needs (meshtastic/web-flasher#426). - In enterDfuMode(), stop the GPS and drain/end every configured UART before the reset. The ROM bootloader autobauds off the first byte on USART1 (PB6/PB7) or USART2 (PA2/PA3), and on every WL variant a console UART or the GPS stream sits on those pins. Factor the drain into quiesceSerial() and reuse it in cpuDeepSleep(). - Move earlyBootCheck from constructor(101) to .preinit_array, ahead of the core's premain()/SystemClock_Config() whatever the link order, and reset RCC before jumping to system memory. The handler used to reset the MCU inline, before the ACK was sent and while the client still held the console UART. The STM32WL ROM bootloader autobauds off the first byte received; a stray byte during the handoff (a trailing protobuf frame, a port-close DTR/RTS glitch) desynced it and left the device unreachable at any baud until a hard reset. STM32WL only: every hunk is behind #if defined(ARCH_STM32) or lives in main-stm32wl.cpp. nrf52, rp2040 and the rest are unchanged. Known limitation: gps->disable() only issues a UBX sleep command, so a non-u-blox or otherwise free-running GPS with no hardware enable/standby pin keeps transmitting on its UART past this point. If that UART is USART1 (PB6/PB7) or USART2 (PA2/PA3), the ROM bootloader can still autobaud onto the GPS stream instead of the host. New STM32WL hardware designs should keep GPS UARTs off those two bootloader-autobaud pins, or provide a way to power down or hold the GPS in reset before DFU. Assisted-by: Claude Sonnet 5 <noreply@anthropic.com> Signed-off-by: Andrew Yong <me@ndoo.sg>
This commit is contained in:
1 parent
fa65b0797e
commit
3c04a79031
6 files changed
+90
-28
No files matched your search
@@ -68,6 +68,11 @@
|
||||
|
||||
AdminModule *adminModule;
|
||||
|
||||
#ifdef ARCH_STM32
|
||||
// Client detach window before the DFU jump (see the enter_dfu case).
|
||||
static constexpr uint32_t STM32_DFU_DETACH_DELAY_MS = 5000;
|
||||
#endif
|
||||
|
||||
#if !(MESHTASTIC_EXCLUDE_PKI_KEYGEN || MESHTASTIC_EXCLUDE_PKI)
|
||||
static bool licensedIdentityWillMigrate()
|
||||
{
|
||||
@@ -619,7 +624,15 @@ bool AdminModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshta
|
||||
#if HAS_SCREEN
|
||||
IF_SCREEN(screen->showSimpleBanner("Device is rebooting\ninto DFU mode.", 0));
|
||||
#endif
|
||||
#if defined(ARCH_NRF52) || defined(ARCH_RP2040) || defined(ARCH_STM32)
|
||||
#if defined(ARCH_STM32)
|
||||
// Delay the jump so this ACK reaches the client and it releases the port before the
|
||||
// STM32WL ROM bootloader takes the UART and autobauds off the next byte it sees.
|
||||
LOG_INFO("Entering DFU in %us - disconnect now", (STM32_DFU_DETACH_DELAY_MS + 999) / 1000);
|
||||
enterDfuAtMsec = millis() + STM32_DFU_DETACH_DELAY_MS;
|
||||
// Guard against enterDfuAtMsec rolling over to 0, the sentinel powerCommandsCheck() reads as unarmed.
|
||||
if (enterDfuAtMsec == 0)
|
||||
enterDfuAtMsec = 1;
|
||||
#elif defined(ARCH_NRF52) || defined(ARCH_RP2040)
|
||||
enterDfuMode();
|
||||
#endif
|
||||
break;
|
||||
|
||||
Reference in new issue
Block a user