Issue with resuming UART1 on nRF9151 after PM suspend with BLE module

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 by uart_config_get() or uart_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:

  1. Is there a recommended way in Zephyr to safely resume a UART peripheral connected to a BLE module on nRF9151 after PM suspend?

  2. Are there any platform-specific constraints on nRF91 UART peripherals that we need to account for when suspending/resuming?

  3. Can the approach of using a static UART configuration safely replace uart_config_get() in this scenario?

Parents Reply Children
Related