Skip to content

ports/nrf: Add Zephyr BLE with on-core controller support.#22

Merged
andrewleech merged 0 commit intopr/zephyr-ble-zephyrfrom
pr/zephyr-ble-nrf
Apr 20, 2026
Merged

ports/nrf: Add Zephyr BLE with on-core controller support.#22
andrewleech merged 0 commit intopr/zephyr-ble-zephyrfrom
pr/zephyr-ble-nrf

Conversation

@andrewleech
Copy link
Copy Markdown
Owner

Summary

Adds Zephyr BLE support to the nRF port (PCA10056 DK and PCA10059 dongle) using the Zephyr BLE host stack with an on-core BLE controller. Unlike the RP2 and STM32 integrations which rely on external BLE controllers (CYW43, STM32WB M0+), the nRF52840 runs the Zephyr BLE controller directly on the application core alongside MicroPython.

This required building the full Zephyr BLE controller (link layer, radio HAL, ticker) against the HAL shim layer, plus IRQ management shims that bridge Zephyr's irq_connect_dynamic() / irq_enable() / irq_disable() to NVIC operations. The controller's radio ISR and ticker timing run at hardware interrupt priority while the host stack processes events cooperatively from the main task via mp_sched_schedule_node().

Also adds SysTick, soft timer, and PendSV dispatch infrastructure to the nRF port which were previously missing and are needed for the scheduler-based BLE polling.

Depends on #21.

Testing

12/12 BLE multitests passing on nRF52840 DK with PYBD as central, and 12/12 Z2Z (DK as peripheral + PCA10059 dongle as central). Bond persistence test passes via the SUSPENDED mode reactivation path (on-core controller can't cleanly restart after bt_disable()).

Performance: ~35ms/notification (GATT), ~2184 B/s (L2CAP) with PYBD; ~25ms/notification, ~2681 B/s Z2Z.

428KB flash (42%), ~220KB RAM (84%) on PCA10056.

Trade-offs and Alternatives

The on-core controller means bt_disable() can't cleanly shut down and restart the radio — the Zephyr controller wasn't designed for this. Instead, ble.active(0) enters a SUSPENDED state that stops advertising/scanning/connections but leaves the stack running. This wastes some power but avoids the need for a full chip reset to reinitialise.

The hci_driver_wrapper.c wraps Zephyr's hci_driver.c to expose file-scope variables for RX polling, avoiding a submodule patch.

Generative AI

I used generative AI tools when creating this PR, but a human has checked the code and is responsible for the description above.

@andrewleech andrewleech force-pushed the pr/zephyr-ble-zephyr branch from 209f127 to e5ef1fe Compare March 5, 2026 04:34
@andrewleech andrewleech force-pushed the pr/zephyr-ble-zephyr branch from e5ef1fe to 1b4ef75 Compare March 5, 2026 05:54
@andrewleech andrewleech force-pushed the pr/zephyr-ble-zephyr branch from 1b4ef75 to 67b0f9a Compare March 5, 2026 06:33
@andrewleech andrewleech force-pushed the pr/zephyr-ble-zephyr branch from 67b0f9a to ced1184 Compare March 5, 2026 06:54
@andrewleech andrewleech force-pushed the pr/zephyr-ble-zephyr branch from ced1184 to 4442799 Compare March 5, 2026 12:38
@andrewleech andrewleech force-pushed the pr/zephyr-ble-zephyr branch from 4442799 to 08fc8bd Compare March 6, 2026 02:53
@andrewleech andrewleech force-pushed the pr/zephyr-ble-zephyr branch from 08fc8bd to 4e2de49 Compare March 6, 2026 06:26
@andrewleech andrewleech force-pushed the pr/zephyr-ble-nrf branch 2 times, most recently from abf7346 to efca591 Compare March 6, 2026 23:09
@andrewleech andrewleech force-pushed the pr/zephyr-ble-zephyr branch from 4e2de49 to d00aaec Compare March 6, 2026 23:09
@andrewleech andrewleech force-pushed the pr/zephyr-ble-zephyr branch 2 times, most recently from 4545298 to b3e9a17 Compare March 11, 2026 11:22
@andrewleech andrewleech force-pushed the pr/zephyr-ble-nrf branch 2 times, most recently from 574626e to f40367e Compare March 11, 2026 12:08
@andrewleech andrewleech force-pushed the pr/zephyr-ble-zephyr branch 2 times, most recently from cdaf654 to e04c581 Compare March 16, 2026 05:11
@andrewleech andrewleech force-pushed the pr/zephyr-ble-zephyr branch from e04c581 to 3c83b20 Compare March 16, 2026 05:56
@andrewleech andrewleech force-pushed the pr/zephyr-ble-zephyr branch from 3c83b20 to 9fed0a4 Compare March 16, 2026 06:36
@andrewleech andrewleech force-pushed the pr/zephyr-ble-zephyr branch from 9fed0a4 to aa4123e Compare March 16, 2026 08:09
@andrewleech andrewleech force-pushed the pr/zephyr-ble-zephyr branch from aa4123e to f2f7cc8 Compare March 16, 2026 09:32
@andrewleech andrewleech force-pushed the pr/zephyr-ble-zephyr branch from f2f7cc8 to 6492bd2 Compare March 16, 2026 10:15
@andrewleech andrewleech merged commit 9be0165 into pr/zephyr-ble-zephyr Apr 20, 2026
@andrewleech andrewleech force-pushed the pr/zephyr-ble-zephyr branch from 6492bd2 to 45850ad Compare April 20, 2026 21:04
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.

1 participant