From 81587f8b3776de238fc01f7b0c83c5798587619c Mon Sep 17 00:00:00 2001 From: me Date: Fri, 5 Jun 2026 17:00:26 -0700 Subject: [PATCH 1/3] fix(t114): delegate powerOff() to initiateShutdown() for proper SYSTEMOFF T114Board::powerOff() was calling sd_power_system_off() directly with no error handling. If the SoftDevice returns NRF_ERROR_BUSY or any other error, execution silently returned and the device kept running. Delegating to initiateShutdown(SHUTDOWN_REASON_USER) fixes this by: - powering down the SX1262 (SX126X_POWER_EN LOW) before SYSTEMOFF, preventing immediate GPIO wakeup via DIO1 - going through enterSystemOff() which handles SD errors and falls back to NRF_POWER->SYSTEMOFF then NVIC_SystemReset() --- variants/heltec_t114/T114Board.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/variants/heltec_t114/T114Board.h b/variants/heltec_t114/T114Board.h index f27dc291d0..49f5a06dbf 100644 --- a/variants/heltec_t114/T114Board.h +++ b/variants/heltec_t114/T114Board.h @@ -50,10 +50,14 @@ class T114Board : public NRF52BoardDCDC { #ifdef LED_PIN digitalWrite(LED_PIN, HIGH); #endif +#ifdef NRF52_POWER_MANAGEMENT + initiateShutdown(SHUTDOWN_REASON_USER); +#else #if ENV_INCLUDE_GPS == 1 pinMode(GPS_EN, OUTPUT); digitalWrite(GPS_EN, LOW); #endif sd_power_system_off(); +#endif } }; From d9e9eb993e937a5e4702ad84db01e08d43372abb Mon Sep 17 00:00:00 2001 From: me Date: Sat, 6 Jun 2026 13:20:55 -0700 Subject: [PATCH 2/3] fix(rak4631): add powerOff() delegating to initiateShutdown() RAK4631Board had no powerOff() override, so the CLI poweroff command called the base class no-op and the device kept running. Add powerOff() following the R1NeoBoard pattern: delegate to initiateShutdown(SHUTDOWN_REASON_USER) which powers down the SX1262, then goes through enterSystemOff() with proper error handling and fallback to NRF_POWER->SYSTEMOFF. --- variants/rak4631/RAK4631Board.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/variants/rak4631/RAK4631Board.h b/variants/rak4631/RAK4631Board.h index 7e67165b19..44dd32a03b 100644 --- a/variants/rak4631/RAK4631Board.h +++ b/variants/rak4631/RAK4631Board.h @@ -35,4 +35,10 @@ class RAK4631Board : public NRF52BoardDCDC { const char* getManufacturerName() const override { return "RAK 4631"; } + +#ifdef NRF52_POWER_MANAGEMENT + void powerOff() override { + initiateShutdown(SHUTDOWN_REASON_USER); + } +#endif }; From 90b07b57371c57dd5eedc18cd4db47ceec31a37c Mon Sep 17 00:00:00 2001 From: me Date: Sat, 6 Jun 2026 16:18:19 -0700 Subject: [PATCH 3/3] fix(rak4631): clear DIO1 SENSE in initiateShutdown() to prevent wakeup RAK4631 has no buttons. After SX1262 is powered down, DIO1 (P_LORA_DIO_1) is the only GPIO with SENSE configured (set by RadioLib's attachInterrupt). The floating pin can trigger an immediate GPIO wakeup from SYSTEMOFF. Clear the SENSE configuration with nrf_gpio_cfg_default() before entering SYSTEMOFF to prevent this. --- variants/rak4631/RAK4631Board.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/variants/rak4631/RAK4631Board.cpp b/variants/rak4631/RAK4631Board.cpp index 9fb47b432e..1aa5098f27 100644 --- a/variants/rak4631/RAK4631Board.cpp +++ b/variants/rak4631/RAK4631Board.cpp @@ -15,6 +15,9 @@ const PowerMgtConfig power_config = { void RAK4631Board::initiateShutdown(uint8_t reason) { // Disable LoRa module power before shutdown digitalWrite(SX126X_POWER_EN, LOW); + // RAK4631 has no buttons; clear DIO1 SENSE (set by RadioLib) so the + // floating pin doesn't trigger an immediate wakeup from SYSTEMOFF. + nrf_gpio_cfg_default(P_LORA_DIO_1); if (reason == SHUTDOWN_REASON_LOW_VOLTAGE || reason == SHUTDOWN_REASON_BOOT_PROTECT) {