Problems putting UART into PM_DEVICE_ACTION_SUSPEND

This is my environment

  • IDE: VSC
  • SDK: NCS v2.2.0
  • nRF52-DK

I've been trying to get my current consumption down during System On Idle mode (spec sheet says I can get sub-2uA).  I can get this to work with a simple example code I've put together, and I simply make a call  to:

pm_device_action_run(uart, PM_DEVICE_ACTION_SUSPEND);
This seems to drop the current from ~ 200uA down to around 1.5uA.
However, in my more complex version (that is enabled with all the functionality I need for my custom hardware), it looks like I'm having issues getting the UART to actually go into the mode it needs to to get the current down.  This version is using the Async UART functionality, and I have a separate thread to process all the UART RX.  When this code goes into idle mode, I'm seeing around 300-400uA current drain.
In this version, I actually stop the UART RX first, then attempt to put the UART into suspend mode:
ret = uart_rx_disable(uart);
if (ret !=0) {
	LOG_WRN("Error disabling UART: err %d\n", ret);
}

ret = pm_device_action_run(uart, PM_DEVICE_ACTION_SUSPEND);
if (ret !=0) {
	LOG_WRN("Error suspending device: err %d\n", ret);
}
What I am seeing when I attempt to put the UART into low power mode is the following LOG info:
[00:12:21.031,707] <wrn> idle_mode: Error suspending device: err -120
[00:12:22.031,860] <wrn> idle_mode: Error suspending device: err -120
This is the return error from the pm_device_action_run(uart,PM_DEVICE_ACTION_SUSPEND) API, and according to Zephyr it means:
EALREADY   120 Operation already in progress.
What I'm trying to work out is:
1. Can I check somehow that the UART is actually suspended using a call to an API?  I'm trying to confirm if it is actually going into suspend mode and hence is the cause of my higher than expended current drain.  I am pretty sure it is, but wanted to check
2. I'm not getting these error codes in my simple version of firmware, so what might be causing this?  I can see the call to uart_rx_disable is successful (return code = 0),but the attempt at suspending the UART isn't.
Regards,
Mike
Parents
  • Hi Mike

    In versions prior to NCS v2.4.0, there is a known issue where after suspending UARTE0 with the PM device, you need to also make sure UARTE1 is disabled, as it was enabled by default in the devicetree in these older SDK versions. Here for more details: https://github.com/nrfconnect/sdk-zephyr/blob/fcaa60a99fa9d5256078ed28557856ec3709cfa9/boards/arm/nrf52840dk_nrf52840/nrf52840dk_nrf52840.dts#L151 

    Best regards,

    Simon

  • Hi Simon,

    Thanks for that info. Not sure that’s my issue though as I’m using an nRF52832 that only has the one UART. Sorry, I should have mentioned that in my original post.

    Also, I started with a very simple version of my firmware that just uses a timer to go in and out of idle mode. That shows the behavior I was expecting, with idle state current down around 2uA.

    I’m slowly adding the functionality I need to this and monitoring the idle state current to see if I can see what causes it to jump up once it’s been added. Haven’t found anything as yet!

    I did add a call to pm_device_state_get() before the calls I have to suspend and resume the UART, just to ensure I’m only attempting to do that when the UART is in the appropriate state. That seems to prevent the -120 errors I was seeing, so my firmware must have been making multiple calls to the API’s to suspend the device for some reason (not sure why yet)

    Anyway, I’ll keep going with my “add functionality to a simple version of code that works until it breaks” approach and see what I uncover. Then, if I need further help, I’ll report back here.

    Thansks again,

    Mike

Reply
  • Hi Simon,

    Thanks for that info. Not sure that’s my issue though as I’m using an nRF52832 that only has the one UART. Sorry, I should have mentioned that in my original post.

    Also, I started with a very simple version of my firmware that just uses a timer to go in and out of idle mode. That shows the behavior I was expecting, with idle state current down around 2uA.

    I’m slowly adding the functionality I need to this and monitoring the idle state current to see if I can see what causes it to jump up once it’s been added. Haven’t found anything as yet!

    I did add a call to pm_device_state_get() before the calls I have to suspend and resume the UART, just to ensure I’m only attempting to do that when the UART is in the appropriate state. That seems to prevent the -120 errors I was seeing, so my firmware must have been making multiple calls to the API’s to suspend the device for some reason (not sure why yet)

    Anyway, I’ll keep going with my “add functionality to a simple version of code that works until it breaks” approach and see what I uncover. Then, if I need further help, I’ll report back here.

    Thansks again,

    Mike

Children
No Data
Related