Skip to content

Optional softdevice in nordic port - #11251

Merged
tannewt merged 5 commits into
adafruit:mainfrom
FoamyGuy:optional_softdevice
Aug 27, 2026
Merged

tannewt merged 5 commits into
adafruit:mainfrom
FoamyGuy:optional_softdevice

Conversation

@FoamyGuy

Copy link
Copy Markdown
Collaborator

This change adds a build flag to disable SoftDevice, set SD= in mpconfigboard.mk file to disable.

My testing was performed on a CircuitPlayground bluefruit and the LED Glasses driver device.

Flashing the UF2 file from a no SD build will wipe the SD from flash. Afterwards, flashing back to a normal with a SD-enabled UF2 file does not work. It flashes but the resulting firmware can't boot successfully. Getting back to a functional SD-enabled firmware requires using SWD to erase, and flash the bootloader+sd hex, then a standard release UF2 can be used to load CircuitPython and bring the device back to normal.

A board sets `SD =` (empty) in its mpconfigboard.mk to build without a
SoftDevice, reclaiming the MBR + SoftDevice flash and the 56kB of low RAM
they reserve. Boards that do not opt out are unaffected.

- Makefile: build the bluetooth sources only when SD is set, and link
  firmware.hex rather than firmware.combined.hex when there is no
  SoftDevice hex to merge in. Guard the bluetooth_common.mk include with
  VALID_BOARD so non-board rules such as fetch-port-submodules do not
  evaluate SoftDevice paths built from an unset MCU_VARIANT.
- mpconfigport.mk: force _bleio and the BLE file/serial services off when
  SD is empty.
- mpconfigport.h: without a SoftDevice its headers are not on the include
  path, so define MBR_SIZE and SD_FLASH_SIZE to 0 locally, and zero both
  CIRCUITPY_BLE_CONFIG_SIZE (nothing to bond) and SOFTDEVICE_RAM_SIZE.
- startup_nrf52840.c: with a SoftDevice the MBR at 0x0 owns the vector
  table and has already pointed VTOR at ours. Without one, set it.
- microcontroller/__init__.c: replace the sd_nvic critical-region calls
  with PRIMASK save/mask/restore, and write GPREGRET directly.
- port.c, PinAlarm.c, neopixel_write, nvm.h: guard SoftDevice headers and
  calls. port_idle_until_interrupt()'s existing non-SoftDevice path
  becomes the fallthrough.

Built and verified on feather_nrf52840_express (SoftDevice, byte-identical
apart from port_idle_until_interrupt), microbit_v2 (nRF52833), and a
throwaway SD-less board.

@tannewt tannewt left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of introducing a SD make variable, let's use CIRCUITPY_BLEIO_NATIVE throughout. The mpconfigport does this as ?= so the board should be able to override it.

(I'm sure the actual code changes are fine.)

@FoamyGuy

FoamyGuy commented Aug 26, 2026 •

Copy link
Copy Markdown
Collaborator Author

Changed in the latest commit to use CIRCUITPY_BLEIO_NATIVE = 0 to disable SoftDevice instead of SD=. Some parts of the code still use BLUETOOTH_SD which was preexisting and still has many usages outside this change as well.

I retested it successfully on CPB. Same flashing warning from the original comment stands. It's possible to flash to a No-SD build with UF2, but SWD is required to return back to a standard build with SD.

@tannewt tannewt left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you!

@tannewt
tannewt merged commit 973bacf into adafruit:main Aug 27, 2026
67 checks passed
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