Environment:
-
SoC: nRF52832
-
SDK: nRF Connect SDK v3.3.1 (Zephyr)
-
CONFIG_MPSL=y
-
CONFIG_PM=n (not supported on nRF52832)
Goal: Completely disable the UARTE peripheral during idle to reduce power consumption (~0.3–0.4 mA overhead observed), then re-enable it on demand, without breaking BLE connectivity.
Reference (working baseline): In nRF5 SDK 17.0 (no MPSL), the following pattern worked correctly with no BLE impact:
// Sleep
app_uart_close(); // → nrf_uarte_disable()
// Wake
uart_init(NRF_UART_BAUDRATE_9600);Attempted approaches in NCS v3.3.1:
Approach A – Disable IRQ only (current workaround)
// Sleep
uart_irq_rx_disable(uart_dev);
gpio_pin_interrupt_configure(gpio_dev, UART_RX_PIN, GPIO_INT_EDGE_TO_ACTIVE);
// Wake
gpio_pin_interrupt_configure(gpio_dev, UART_RX_PIN, GPIO_INT_DISABLE);
uart_irq_rx_enable(uart_dev);Result: BLE | UARTE peripheral remains active
(~0.3–0.4 mA extra)
Approach B – Direct register access via nrf_uarte HAL
// Sleep
uart_irq_rx_disable(uart_dev);
nrf_uarte_task_trigger(NRF_UARTE0, NRF_UARTE_TASK_STOPRX);
nrf_uarte_task_trigger(NRF_UARTE0, NRF_UARTE_TASK_STOPTX);
while (!nrf_uarte_event_check(NRF_UARTE0, NRF_UARTE_EVENT_TXSTOPPED)) {}
while (!nrf_uarte_event_check(NRF_UARTE0, NRF_UARTE_EVENT_RXTO)) {}
nrf_uarte_disable(NRF_UARTE0);
// Wake
nrf_uarte_enable(NRF_UARTE0);
uart_irq_rx_enable(uart_dev);Result: BLE advertising works but connection fails (GATT CONN TIMEOUT / service discovery failure)
Variants tested:
| Variant | BLE Result |
|---|---|
STOPRX/STOPTX + disable + nrf_uarte_int_disable(0xFFFFFFFF) |
|
| STOPRX/STOPTX + disable (no int_disable) | |
| STOPRX/STOPTX only (no disable) |
Approach C – Async API
// Sleep
uart_rx_disable(uart_dev);
// wait for UART_RX_DISABLED callback via semaphore, then configure GPIO wakeup
// Wake (via k_work, deferred from GPIO ISR)
uart_rx_enable(uart_dev, rx_buf[0], RX_BUF_SIZE, 100000);Issues fixed before testing: buffer index flip timing, missing semaphore sync on uart_rx_disable(), direct API call from ISR context, stack sizes increased (MAIN: 3072, SYSTEM_WORKQUEUE: 6144).
Result: BLE connection fails | RAM overflow by 2736 bytes
Questions:
-
Is there a supported way in NCS v3.3.1 to fully disable and re-enable UARTE at runtime on nRF52832 with MPSL active, without affecting BLE?
-
Does MPSL place any constraints on UARTE peripheral access (e.g. interrupt priority, shared resources) that would explain why direct register manipulation breaks BLE?
-
Is there an nRFx or Zephyr API equivalent to
nrf_uarte_disable()that is MPSL-safe? -
nrfx_uart_pwr_manage()was suggested but does not appear to exist in NCS v3.3.1 — is there an alternative?