nRF52832 + NCS v3.3.1 + MPSL: UARTE disable/enable at runtime breaks BLE connection

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 White check mark | UARTE peripheral remains active X (~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) X

Variants tested:

Variant BLE Result
STOPRX/STOPTX + disable + nrf_uarte_int_disable(0xFFFFFFFF) X Fail
STOPRX/STOPTX + disable (no int_disable) X Fail
STOPRX/STOPTX only (no disable) X Fail

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 X | RAM overflow by 2736 bytes X


Questions:

  1. 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?
  2. Does MPSL place any constraints on UARTE peripheral access (e.g. interrupt priority, shared resources) that would explain why direct register manipulation breaks BLE?
  3. Is there an nRFx or Zephyr API equivalent to nrf_uarte_disable() that is MPSL-safe?
  4. nrfx_uart_pwr_manage() was suggested but does not appear to exist in NCS v3.3.1 — is there an alternative?
Parents Reply Children
No Data
Related