Skip to content

companion_radio: tear down QSPI peripheral when its init fails (fixes #2827)#2828

Open
benskigomez wants to merge 1 commit into
meshcore-dev:devfrom
benskigomez:fix/m6-ble-qspi-init-poisons-softdevice
Open

companion_radio: tear down QSPI peripheral when its init fails (fixes #2827)#2828
benskigomez wants to merge 1 commit into
meshcore-dev:devfrom
benskigomez:fix/m6-ble-qspi-init-poisons-softdevice

Conversation

@benskigomez

@benskigomez benskigomez commented Jun 24, 2026

Copy link
Copy Markdown

Problem

On nRF52 BLE companion builds, a failed external-flash init leaves BLE completely dead. The Elecrow ThinkNode M6 never advertises over BLE on any firmware version (#2827), even though the same unit runs fine over LoRa and pairs over BLE under other firmware.

Root cause

When nrfx_qspi_init() fails (the M6 returns NRFX_ERROR_TIMEOUT / 0xBAD0007 during QSPI activation), it has already enabled the QSPI peripheral and enabled QSPI_IRQn in the NVIC at priority 0 (reserved for the SoftDevice) — and cleans none of it up before returning. The next step, Bluefruit.begin() enabling the SoftDevice, then fails; every later BLE call returns NRF_ERROR_SOFTDEVICE_NOT_ENABLED, so the node never advertises. USB companion builds are unaffected because they never enable the SoftDevice.

Fix

On the QSPIFlash.begin() failure path, disable QSPI_IRQn and power the QSPI peripheral back down before continuing. Runs only on the failure path, so boards whose QSPI init succeeds are unaffected.

Validation

On a ThinkNode M6 (with the QSPI init still timing out): the SoftDevice now enables, the node advertises, and the MeshCore app pairs and exchanges frames. Confirmed via boot-stage instrumentation that the SoftDevice enable goes from failing to succeeding once the peripheral is torn down.

Notes

The underlying M6 QSPI-init timeout is a separate issue (the custom QSPI flash driver doesn't bring up the MX25R1635F); this PR makes BLE robust to that failure rather than fixing the flash itself.

Closes #2225

…eshcore-dev#2827)

On nRF52 BLE companion builds, a failed external-flash init left BLE
completely dead: the node never advertised on the Elecrow ThinkNode M6
on any firmware version, even though the same unit runs fine over LoRa
and pairs over BLE under other firmware.

Root cause: when nrfx_qspi_init() fails (the M6 returns
NRFX_ERROR_TIMEOUT / 0xBAD0007 during QSPI activation), it has already
enabled the QSPI peripheral and enabled QSPI_IRQn in the NVIC at
priority 0 (reserved for the SoftDevice), and it does not clean any of
that up before returning. The very next step, the SoftDevice enable in
Bluefruit.begin(), then fails (returns false) and every later BLE call
reports NRF_ERROR_SOFTDEVICE_NOT_ENABLED, so the node never advertises.
USB companion builds are unaffected because they never enable the
SoftDevice.

Fix: on the QSPIFlash.begin() failure path, disable QSPI_IRQn and
power the QSPI peripheral back down before continuing. This only runs
on the failure path, so boards whose QSPI init succeeds are unaffected,
and BLE now comes up cleanly even when the external flash is absent or
fails to initialize.

Validated on a ThinkNode M6: with the QSPI init still timing out, the
SoftDevice now enables, the node advertises, and the MeshCore app pairs
and exchanges frames.
@benskigomez benskigomez changed the base branch from main to dev June 26, 2026 14:45
@benskigomez benskigomez force-pushed the fix/m6-ble-qspi-init-poisons-softdevice branch from 3dffbf9 to 6faa289 Compare June 26, 2026 14:45
AtlavoxDev added a commit to AtlavoxDev/MeshCore that referenced this pull request Jun 26, 2026
Backports upstream PR meshcore-dev#2828 (not yet merged) which addresses issue meshcore-dev#2827:
ThinkNode M6 companion_radio_ble firmware doesn't advertise over BLE.

Root cause chain:
1. nrfx_qspi_init() times out on M6 (returns NRFX_ERROR_TIMEOUT/0xBAD0007)
   — separate underlying issue tracked as meshcore-dev#2829
2. The failure leaves the QSPI peripheral enabled and QSPI_IRQn enabled
   in the NVIC at priority 0
3. Priority 0 is reserved for the SoftDevice
4. Subsequent Bluefruit.begin() (the SoftDevice enable) fails silently
   due to the priority-0 conflict
5. No SoftDevice = no BLE advertising = node invisible to scanners

The customer's diagnostics traced this end-to-end; PR meshcore-dev#2828 has the fix.

Add cleanup inside the QSPIFlash.begin() failure branch:
- Disable QSPI_IRQn and clear any pending interrupt
- Deactivate and disable the QSPI peripheral

This frees priority 0 so the SoftDevice can start cleanly. The device
falls back to InternalFS for persistent storage (the underlying QSPI
issue itself is not fixed here — that's a separate investigation per
issue meshcore-dev#2829). Existing storage capacity is reduced (internal flash only,
no 2MB external) but BLE functionality is restored.

Verified compile: ThinkNode_M6_companion_radio_ble builds clean.

When upstream merges PR meshcore-dev#2828, this commit will rebase out cleanly.
AtlavoxDev added a commit to AtlavoxDev/MeshCore that referenced this pull request Jun 26, 2026
Backports upstream PR meshcore-dev#2828 (not yet merged) which addresses issue meshcore-dev#2827:
ThinkNode M6 companion_radio_ble firmware doesn't advertise over BLE.

Root cause chain:
1. nrfx_qspi_init() times out on M6 (returns NRFX_ERROR_TIMEOUT/0xBAD0007)
   — separate underlying issue tracked as meshcore-dev#2829
2. The failure leaves the QSPI peripheral enabled and QSPI_IRQn enabled
   in the NVIC at priority 0
3. Priority 0 is reserved for the SoftDevice
4. Subsequent Bluefruit.begin() (the SoftDevice enable) fails silently
   due to the priority-0 conflict
5. No SoftDevice = no BLE advertising = node invisible to scanners

The customer's diagnostics traced this end-to-end; PR meshcore-dev#2828 has the fix.

Add cleanup inside the QSPIFlash.begin() failure branch:
- Disable QSPI_IRQn and clear any pending interrupt
- Deactivate and disable the QSPI peripheral

This frees priority 0 so the SoftDevice can start cleanly. The device
falls back to InternalFS for persistent storage (the underlying QSPI
issue itself is not fixed here — that's a separate investigation per
issue meshcore-dev#2829). Existing storage capacity is reduced (internal flash only,
no 2MB external) but BLE functionality is restored.

Verified compile: ThinkNode_M6_companion_radio_ble builds clean.

When upstream merges PR meshcore-dev#2828, this commit will rebase out cleanly.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants