Board/Setup:
-
Board: nRF9151 DK / nRF9151 SoC
-
Peripheral: External BLE module connected via UART1
-
Use case: BLE module is only needed during commissioning. After commissioning, it can remain powered down to save energy.
Scenario / Problem:
We are using Zephyr OS with the nRF Connect SDK. Our goal is to reduce power consumption when the BLE module is not needed.
-
With UART1 running continuously for BLE communication, the device consumes ~7 mA.
-
When we suspend UART1 using Zephyr PM (
pm_device_action_run(uart_dev, PM_DEVICE_ACTION_SUSPEND)), the current drops to ~700 μA, which is acceptable. -
Issue: After suspending UART1, attempting to resume it using
pm_device_action_run(uart_dev, PM_DEVICE_ACTION_RESUME)followed byuart_config_get()oruart_configure()consistently fails with-134 (EIO).
From investigation:
-
The PM resume successfully powers the UART peripheral, but the hardware is not responsive immediately.
-
uart_config_get()fails both before suspend and after resume if the BLE transport or peripheral is active, because the driver cannot communicate with the hardware. -
Adding delays after resume does not solve the problem.
Goal:
-
Suspend UART1 to save power when BLE is not needed.
-
Be able to resume UART1 reliably when commissioning is required again.
-
Avoid relying on
uart_config_get()since it fails with the current setup.
My Code:
/* Suspend UART device */
int ble_uart_suspend(void)
{
int err;
if (!device_is_ready(uart_dev))
{
WR_ERR("UART device not ready\n");
return -ENODEV;
}
err = pm_device_action_run(uart_dev, PM_DEVICE_ACTION_SUSPEND);
if (err)
{
WR_ERR("Failed to suspend UART: %d\n", err);
return err;
}
WR_INF("UART suspended successfully\n");
return 0;
}
/* Resume UART device */
int ble_uart_resume(void)
{
int err;
if (!device_is_ready(uart_dev))
{
WR_ERR("UART device not ready");
return -ENODEV;
}
err = pm_device_action_run(uart_dev, PM_DEVICE_ACTION_RESUME);
if (err)
{
WR_ERR("Failed to resume UART: %d", err);
return err;
}
WR_INF("UART resumed successfully");
return 0;
}
Support Needed:
-
Is there a recommended way in Zephyr to safely resume a UART peripheral connected to a BLE module on nRF9151 after PM suspend?
-
Are there any platform-specific constraints on nRF91 UART peripherals that we need to account for when suspending/resuming?
-
Can the approach of using a static UART configuration safely replace
uart_config_get()in this scenario?