From e4297595cf42dc4535e519cffe741c4678e7fa26 Mon Sep 17 00:00:00 2001 From: Kemal Hadimli Date: Tue, 2 Jun 2026 00:16:12 +0100 Subject: [PATCH] nrf52: turn off BLE connection LED before SYSTEMOFF Bluefruit's autoConnLed (on by default) drives LED_CONN. nRF52 SYSTEMOFF only halts the core and leaves GPIO outputs latched in their last drive state, so the BLE LED stayed lit through hibernation -- solid when a companion app was connected, or caught mid-blink while advertising. In the shared enterSystemOff() funnel, disable autoConnLed and stop advertising so BLE no longer drives the pin, then pull LED_CONN low with the polarity-aware ledOff() macro (respects each variant's LED_STATE_ON). This covers every board that hibernates through enterSystemOff() -- rak3401, rak4631 and xiao_nrf52 -- in one place. The Bluefruit calls are gated on the SoftDevice being enabled so the early low-voltage / boot-protect path (before Bluefruit.begin()) is safe; ledOff() always runs. Awake behavior is unchanged -- the LED still indicates BLE status. Note: promicro and rak_wismesh_tag call sd_power_system_off() directly rather than via enterSystemOff(), so they are not covered by this change. Co-Authored-By: Claude Opus 4.8 --- src/helpers/NRF52Board.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/helpers/NRF52Board.cpp b/src/helpers/NRF52Board.cpp index 2c8753d464..716284d0ab 100644 --- a/src/helpers/NRF52Board.cpp +++ b/src/helpers/NRF52Board.cpp @@ -156,6 +156,18 @@ void NRF52Board::enterSystemOff(uint8_t reason) { NRF_POWER->GPREGRET2 = reason; } + // Turn off the BLE connection LED before deep sleep. Bluefruit's autoConnLed + // (on by default) drives LED_CONN; nRF52 SYSTEMOFF only halts the core and + // leaves GPIO outputs latched in their last state, so the LED would otherwise + // stay lit through hibernation. Stop BLE re-driving the pin, then pull it low. + if (sd_enabled) { + Bluefruit.autoConnLed(false); // stop BLE re-driving the LED + Bluefruit.Advertising.stop(); // stop advertising + its blink timer + } +#if defined(LED_CONN) && (LED_CONN >= 0) + ledOff(LED_CONN); // polarity-aware (respects LED_STATE_ON) +#endif + // Flush serial buffers Serial.flush(); delay(100);