From fc9e0b3c7be55922171f8e094ea3c4f4de61dd64 Mon Sep 17 00:00:00 2001 From: Wessel Nieboer Date: Fri, 6 Mar 2026 10:40:35 +0100 Subject: [PATCH] nRF52 BLE: wait for LFXO crystal before enabling SoftDevice The Adafruit framework starts the LFXO in init() but never waits for EVENTS_LFCLKSTARTED. On first boot the filesystem format (~600ms of page erases) gives the crystal time to stabilize. On subsequent boots only quick mounts happen, so sd_softdevice_enable() inside Bluefruit.begin() can be called while the crystal is still starting, which hangs indefinitely. Poll EVENTS_LFCLKSTARTED before Bluefruit.begin() so the wait is exact rather than a blind delay. fixes: #1780 --- src/helpers/nrf52/SerialBLEInterface.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/helpers/nrf52/SerialBLEInterface.cpp b/src/helpers/nrf52/SerialBLEInterface.cpp index 75a4e3b06..4de1d40a4 100644 --- a/src/helpers/nrf52/SerialBLEInterface.cpp +++ b/src/helpers/nrf52/SerialBLEInterface.cpp @@ -129,6 +129,15 @@ void SerialBLEInterface::begin(const char* prefix, char* name, uint32_t pin_code char charpin[20]; snprintf(charpin, sizeof(charpin), "%lu", (unsigned long)pin_code); + // Ensure LFXO crystal is fully started before enabling SoftDevice. + // The framework starts LFXO in init() but doesn't wait for it. + // On fast boots (filesystem already formatted), Bluefruit.begin() can + // be called before the crystal is stable, hanging sd_softdevice_enable(). + // See: https://github.com/meshcore-dev/MeshCore/issues/1780 + while (!NRF_CLOCK->EVENTS_LFCLKSTARTED) { + delay(1); + } + // If we want to control BLE LED ourselves, uncomment this: // Bluefruit.autoConnLed(false); Bluefruit.configPrphBandwidth(BANDWIDTH_MAX);