nRF9160 low power with CONFIG_PM=y

Hello Devzone,

While developing an nRF9160 based, battery powered device (working on the firmware piece of the puzzle) I have run into a couple of issues in my effort to reach a deep sleep mode and floor current of four micro-amps (4uA) or less.  I am within about a current use factor of six, but only so when I disable Zephyr RTOS' power management option in my project's prj.conf file.

I am building against ncs v1.6.1, which includes Zephyr 2.6.0.

The firmware app by which I can reach floor current of about 22uA turns off UARTs of the 9160 (turns off high speed clocks used by UART RX pins), and does not explicitly set Zephyr `PM` symbol.  The result is that power management for run-time hardware config changes is disabled.

When I enable Zephyr's `PM` symbol, floor current rises from ~22uA to about 45uA.

Question (1)  what elements of Zephyr's Power Management feature draw about 25uA of current?

The demo code which for us achieves the lowest floor currents, on both nRF9160DK board and our custom board, is very limited in its functionality.  It is a low power Zephyr demo with nearly every peripheral and Zephyr RTOS feature turned off.  In real life we need to exercise UARTs and other peripherals some fraction of the time.  We would like to turn things on via firmware, run for a while, then return to deep sleep mode.  But so far only Zephyr's Power Management of `PM` feature allows us to turn UART clocks on and off at will.  Yet to enable power management, e.g. set CONFIG_PM=y we find our floor current increase in the deep sleep configuration we're able to achieve.  This is a problem.

For battery life requirements we need and want to have dynamic power management (Zephyr 'PM') and yet reach the single microamp floor currents of and in the nRF9160.

Searching Zephyr tree sources for its release tag 2.6.0, I see that CONFIG_PM symbol pulls in a couple of source files to Zephyr's build process:  ./subsys/pm/power.c and ./subsys/pm/pm_ctrl.c, and possibly ./soc/arm/nordic_nrf/nrf91/power.c.  It looks like one of these files enables a timer in the application processor.  I'm wondering whether such a time draws the extra current we observe.  And if yes, I wonder whether there is a config or programmatic way to dynamically disable that timer.

Question (2)  Is there some finer Zephyr PM configuration we can apply, so that the power management feature can itself be put to sleep temporarily and awake on next entry of hardware plus firmware into full active mode?

To rewrite parts of Zephyr source tree does not seem like a reasonable way to achieve and enjoy practical, battery supporting low power operation of the nRF9160.  Hoping there is some experience and perhaps even a vetted solution or example in the public / community domain on this topic.  Thanks!

- Ted

Parents
  • Hello Simonr,

    Thank you for the reply, and links to Nordic's on-line power profiler and the low power blog post by Stian.  I have read this post of Stian's.  A couple of weeks ago I was able to apply firmware to my team's nRF9160DK kit and measure as low as 4.5uA.  The code I ran to achieve this single microamp floor current -- a measurement of nRF9160 SiP current only -- is posted as one of the attached zip files in Devzone ticket 85747.  For some strange cyclic cmake behavior I could not build the low power hello_world samples which a colleague of yours sent me, but I was able to take the prj.conf settings, and a child_image/spm.conf file and apply those to the hello_world sample app in ncs v1.6.1, my local basis for Nordic Semi and Zephyr based projects.

    I am able, using a modified, very contrived hello_world app obtain single microamp current use in the nRF9160 of an nRF9160DK board. I say "contrived" because so many hardware and firmware library code features are disabled at compile time, mostly through Kconfig.  My hope is that we will, through development steps and learning, find ways to turn hardware and certain Zephyr and Nordic library code on and off at run time.

    In my team's custom board, the best I can achieve is a floor current of about 20uA.  I cannot directly build the low power hello_world for our board, as the dts and related .yml files differ too much from the dts board files of nrf9160dk_nrf9160ns.  But I did heavily edit our custom board's firmware's prj.conf file so that all CONFIG_ symbols match verbatim these Kconfig settings in the above linked low power sample code.  The only part of application code which runs is main.c@void main(), where I copied the hello_world sample app's main.c "forever" loop from Didrik R's low power sample.

    To the best of my knowledge my custom board low power code is functionally the same as the code Didrik and I finally got working on my end in post 85747.  The compiled binaries just don't match byte for byte.

    In our custom board two hardware engineers confirm that I have turned off all external parts to the 9160 SiP, save for one switching regulator which provides VDD_GPIO to the nRF9160 SICA B1A.  SICA VDD is at 3.6V, and VDD_GPIO is set to 1.8V.  As I understand it, some older silicon revs of nRF9160 experience leak currents when VDD_GPIO is less than VDD.  I also understand that the latest silicon revision of nRF9160 overcomes this problem.  Question (1) - Is this correct?

    This evening I notice one possibly important Kconfig setting difference between the low power sample, and Stian's prj.conf file.  He has symbol CONFIG_GPIO=n.  In my ncs v1.6.1 based project I don't call out this symbol explicitly, but `west build -t menuconfig` reports that it's enabled:

    west build -t menuconfig, showing CONFIG_GPIO=y

    Second question - is there a Zephyr API or other technique to disable and to enable GPIO functionality at run time?  It looks like Stian has this symbol set to 'n', and I'm guessing that's crucial to ultra low current draw.

    From time to time I dig some into Zephyr's source code.  But it could easily take days, maybe longer for me to grasp what changes in Zephyr's compiled sources between setting CONFIG_GPIO=y and CONFIG_GPIO=n.

    - Ted

Reply
  • Hello Simonr,

    Thank you for the reply, and links to Nordic's on-line power profiler and the low power blog post by Stian.  I have read this post of Stian's.  A couple of weeks ago I was able to apply firmware to my team's nRF9160DK kit and measure as low as 4.5uA.  The code I ran to achieve this single microamp floor current -- a measurement of nRF9160 SiP current only -- is posted as one of the attached zip files in Devzone ticket 85747.  For some strange cyclic cmake behavior I could not build the low power hello_world samples which a colleague of yours sent me, but I was able to take the prj.conf settings, and a child_image/spm.conf file and apply those to the hello_world sample app in ncs v1.6.1, my local basis for Nordic Semi and Zephyr based projects.

    I am able, using a modified, very contrived hello_world app obtain single microamp current use in the nRF9160 of an nRF9160DK board. I say "contrived" because so many hardware and firmware library code features are disabled at compile time, mostly through Kconfig.  My hope is that we will, through development steps and learning, find ways to turn hardware and certain Zephyr and Nordic library code on and off at run time.

    In my team's custom board, the best I can achieve is a floor current of about 20uA.  I cannot directly build the low power hello_world for our board, as the dts and related .yml files differ too much from the dts board files of nrf9160dk_nrf9160ns.  But I did heavily edit our custom board's firmware's prj.conf file so that all CONFIG_ symbols match verbatim these Kconfig settings in the above linked low power sample code.  The only part of application code which runs is main.c@void main(), where I copied the hello_world sample app's main.c "forever" loop from Didrik R's low power sample.

    To the best of my knowledge my custom board low power code is functionally the same as the code Didrik and I finally got working on my end in post 85747.  The compiled binaries just don't match byte for byte.

    In our custom board two hardware engineers confirm that I have turned off all external parts to the 9160 SiP, save for one switching regulator which provides VDD_GPIO to the nRF9160 SICA B1A.  SICA VDD is at 3.6V, and VDD_GPIO is set to 1.8V.  As I understand it, some older silicon revs of nRF9160 experience leak currents when VDD_GPIO is less than VDD.  I also understand that the latest silicon revision of nRF9160 overcomes this problem.  Question (1) - Is this correct?

    This evening I notice one possibly important Kconfig setting difference between the low power sample, and Stian's prj.conf file.  He has symbol CONFIG_GPIO=n.  In my ncs v1.6.1 based project I don't call out this symbol explicitly, but `west build -t menuconfig` reports that it's enabled:

    west build -t menuconfig, showing CONFIG_GPIO=y

    Second question - is there a Zephyr API or other technique to disable and to enable GPIO functionality at run time?  It looks like Stian has this symbol set to 'n', and I'm guessing that's crucial to ultra low current draw.

    From time to time I dig some into Zephyr's source code.  But it could easily take days, maybe longer for me to grasp what changes in Zephyr's compiled sources between setting CONFIG_GPIO=y and CONFIG_GPIO=n.

    - Ted

Children
Related