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
  • Hi

    To disable logging completely you should indeed also disable CONFIG_RTT_CONSOLE, which lets you emit console messages to a RAM buffer that can be read by a connected SEGGER J-Link software and display on a computer in real-time. The board needs to be connected to a companion board supporting Segger J-Link for this config to have an effect.

    To get to the lowest power with logging disabled, you can set all of the following configs to n

    # Enable RTT
    CONFIG_USE_SEGGER_RTT=y            # [B] 0411 present and equally assigned in custom and low power projects - TMH
    CONFIG_LOG=y                       # 0411 added to match hello_world config
    
    # Send log over RTT
    CONFIG_LOG_BACKEND_RTT=y           # [B] 0411 present and equally assigned in custom and low power projects
    #(Optionally also CONFIG_LOG_BACKEND_UART=n, you'll probably get some Kconfig warnings without)
    CONFIG_LOG_BACKEND_UART=n          # [B] 0411 present and equally assigned in custom and low power projects
    
    # Send printk/printf over RTT
    CONFIG_RTT_CONSOLE=y               # [B] 0411 present and equally assigned in custom and low power projects
    #(Optionally also CONFIG_UART_CONSOLE=n)
    CONFIG_UART_CONSOLE=n              # [B] 0411 present and equally assigned in custom and low power projects
    # - DEV 0308 END -
    CONFIG_SERIAL=n                    # 0411 added to match hello_world config

    Indeed, if you get down to ~20µA then the UART should be disabled, but there might still be other things enabled that draw some current. Regarding the Power profiler graph you're seeing, could you upload the Power Profiler trace here (in a .zip file as DevZone doesn't support the .ppk files) so we can take a look to see if it might be leakage or something else.

    Best regards,

    Simon

Reply
  • Hi

    To disable logging completely you should indeed also disable CONFIG_RTT_CONSOLE, which lets you emit console messages to a RAM buffer that can be read by a connected SEGGER J-Link software and display on a computer in real-time. The board needs to be connected to a companion board supporting Segger J-Link for this config to have an effect.

    To get to the lowest power with logging disabled, you can set all of the following configs to n

    # Enable RTT
    CONFIG_USE_SEGGER_RTT=y            # [B] 0411 present and equally assigned in custom and low power projects - TMH
    CONFIG_LOG=y                       # 0411 added to match hello_world config
    
    # Send log over RTT
    CONFIG_LOG_BACKEND_RTT=y           # [B] 0411 present and equally assigned in custom and low power projects
    #(Optionally also CONFIG_LOG_BACKEND_UART=n, you'll probably get some Kconfig warnings without)
    CONFIG_LOG_BACKEND_UART=n          # [B] 0411 present and equally assigned in custom and low power projects
    
    # Send printk/printf over RTT
    CONFIG_RTT_CONSOLE=y               # [B] 0411 present and equally assigned in custom and low power projects
    #(Optionally also CONFIG_UART_CONSOLE=n)
    CONFIG_UART_CONSOLE=n              # [B] 0411 present and equally assigned in custom and low power projects
    # - DEV 0308 END -
    CONFIG_SERIAL=n                    # 0411 added to match hello_world config

    Indeed, if you get down to ~20µA then the UART should be disabled, but there might still be other things enabled that draw some current. Regarding the Power profiler graph you're seeing, could you upload the Power Profiler trace here (in a .zip file as DevZone doesn't support the .ppk files) so we can take a look to see if it might be leakage or something else.

    Best regards,

    Simon

Children
  • Good morning Simonr,

    Thank you for your detailed reply, and for reviewing the long code excerpts in my recent posts to this Devzone thread.  I think I have made a breakthrough.  My finding is firmware related, but lies outside my project's Kconfig symbols.  In two experimental branches, one whose prj.conf you just reviewed here, and another where several firmware library facilities are enabled I had measured a best floor current around 20uA.

    The key change I made is in our custom board's dts file.  I am now disabling the on-chip I2C peripheral we need to use in our planned design:

    &i2c1 {
            compatible = "nordic,nrf-twim";
    //      status = "okay";
            status = "disabled";
            sda-pin = <6>;
            scl-pin = <5>;
            clock-frequency = <I2C_BITRATE_FAST>;
    };

    My team's lead hardware engineer carried out some excellent sleuthing last Friday and narrowed down suspected current flow from the SiP to a power rail which was powered off by firmware, but still showing a non-zero voltage.  There were a limited number of GPIOs effectively connected to that rail indirectly, but still connected.  That's when we began to suspect there might be internal pull-ups of the ARM-Cortex M33 core bleeding current, even though high speed clocks to drive I2C and related serial peripherals are disabled in prj.conf.

    Our custom hardware now we can observe to draw just 4.4uA, on par with the nRF9160DK board where we achieved the same a couple weeks ago.  I am now delving into Zephyr sources to see whether I can locate the code that's generated by DTS which sets &i2c1 to status = "ok".

    Both Kconfig and DTS are compile time choices.  We don't really get any dynamic configuration through these project configuration mechanisms.  I may likely open a new Devzone ticket if I reach an impasse in my search for Zephyr's way of configuring i2c devices.  I expect need to review some specific nRF9160 and M33 Hardware Abstraction Layer code too.

    Thank you again for your help, Simonr!

    - Ted

  • Glad to hear about your breakthrough Ted. Don't hesitate to open a new ticket if you're in need of further support! I guess we can close this case then.

    Best regards,

    Simon

Related