Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs

nrf5340 SDK 1.9.1 idle mode consumption and power management

Problem: I see a constant 1.4-1.5mA power consumption that I am unable to explain, can;t reduce despite trying a few things and need help debugging further

SDK: 1.9.1

MCU: nrf5340 running at 128MHz (not the default 64MHz)

Board: custom with multiple external components (PMIC, Accel, and few other things)

Environment: SES

Build: secure build 

We have BLE enabled (few 100 bytes being sent exactly every second), MCUBoot, and DFU.. everything works as expected with zero issues (functionally and timing wise).. except for this current consumption we can not explain

What I have done

1. Basic stuff
Turned off serial/uart/log in prj.conf (for application core AND network core (hci_rpmsg).. we use MCUboot and turned off UART there too
CONFIG_ASSERT=n
CONFIG_LOG=n
CONFIG_CONSOLE=n
CONFIG_SERIAL=n

// UART debug port
&uart0 {
status = "okay";
//status = "disabled";
/delete-property/ rts-pin;
/delete-property/ cts-pin;
tx-pin = < 0x19 >;
rx-pin = < 0x1a >;
current-speed = <460800>;
};

#power management
CONFIG_PM=y
CONFIG_PM_DEVICE=y
CONFIG_PM_DEVICE_RUNTIME=y

and i have added  the following too

#include <pm/pm.h>
#include <device.h> 

I have added 
/* Prevent deep sleep (system off) from being entered */
pm_constraint_set(PM_STATE_SOFT_OFF);

Questions:

1a. FPU is ON.. does it make any difference (we need it and hence can't turn it off).. 

1b: shutting UART off should reduce power by 500uA right ? or is it more ? 

2. I have a few GPIOs configured as interrupt pins.. most are edge triggered GPIO_INT_EDGE_FALLING or GPIO_INT_EDGE_RISING (won;t work otherwise so, i cant go for level triggered at this time)..Only button is GPIO_INT_LEVEL_INACTIVE..  Looks like in 1.9.1 we need to add an entry in overlay to take care of masking for sense-edge and i did..

&gpio0 {
status = "okay";
sense-edge-mask = < 0xffffffff >;
};

&gpio1 {
status = "okay";
sense-edge-mask = < 0xffffffff >;
};

Will making interrupts edge triggered add 100s of uA like it is mentioned in some older tickets ? is there a way around that I am missing ?

3. do we have to add CONFIG_PM=y  and CONFIG_PM_DEVICE=y to mcuboot and hci_rpmsg conf files too ? I haven't tried it yet

4. looks like idle thread runs.. (i even added a dummy idle with low priority to see if CPU is always busy doing stuff.. and i see that my dummy thread gets called ample times too..

just for testing, I enabled UART and added a print  (

if (pm_system_suspend(_kernel.idle) == false) {
printk("\n suspend failed");
k_cpu_idle();
}

and I see that print suspend failed ALL the time which is worrying.. but wasn't sure if it's the print that's making it fail or is it really failing.. hence asking you guys if this is something worth worrying  and investigating

5. using my PMIC , I cut off power for all external components and I still see suspend failed and still this additional power consumption.  I disconnect the JTAG and reset the board after flashing .. just to avoid answering "is JTAG somehow enabled.. have you reset the board"

6. I do have I2c2 and 3 turned on  configured at I2C_BITRATE_STANDARD (not doing transactions at the time of measurement).. according to datasheet, this should not add 100s of uAs  but may be 10of uA..  I also have one SPI port configured (but NOT doing any transactions).. Is this ok  or should I shut down everything except when i am using (makes the application design a bit more complex :-) )

7. I use QSPI (single wire) to talk to a Display controller and when display is not in use, QSPI is shutdown and pins are disconnected.

8. Eventually, I shutdown all peripherals and I still see no evidence of CPU going to idle and power consumption is close to 1 mA which really kind of shocked me.so I am questioning what else do i have to do .. base don what i have read, CONFIG_PM=y will ensure idle thread will run (and i verified that it does) and will ALSO push the cores to a lower power mode (which I don't see).. 
CONFIG_PM_DEVICE=y will need explicit power management api calls and implementations from individual drivers.. i have done that for my display driver (and have verified that it shuts down)
CONFIG_PM_DEVICE_RUNTIME=y --> I am not sure if this needed or should I removed it

I am close to the point of factory production of our device and this issue has become critical given this extra current consumption has reduced the battery life to half of what we would need it to be

Parents
  • Before looking into all your questions, try the following:

    • Run nrfjprog --recover --coprocessor CP_NETWORK && nrfjprog --recover
    • Run nrfjprog --program app_core_image.hex --chiperase
      • I have attached app_core_image.hex
      • If --coprocessor is not specificed it will program to app core by default
    • Run nrfjprog --pinreset

    After I completed these steps I saw a current of 2.5uA on the nRF5340 DK

    7180.app_core_image.hex

    Best regards,

    Simon

  • Simon,

    found one issue that seems to help get better power numbers.. we use SPI4 to access our NAND chip and looks like CS (SS) was low even when SPI4 is uninitialized.. Since our Nand is powered all the time, this CS staying low seems to trigge tit to some kind of active mode and henc etalke almost 500uA extra current.  Checked SPI code.. 

    Found that SPI uninit API from Nrf SDK doesn't configure the CS (SS) pin to pull up .. needed SDK change in the function 
    spi uninit with CS pull up
    void nrfx_spim_uninit(nrfx_spim_t const * p_instance) in C:\ncs\v1.9.1\modules\hal\nordic\nrfx\drivers\src\nrfx_spim.c
    if (p_cb->ss_pin != NRFX_SPIM_PIN_NOT_USED)
    {
    //nrf_gpio_cfg_default(p_cb->ss_pin);
    nrf_gpio_cfg_spi(p_cb->ss_pin);  ----> newly added
    }

    new api nrf_gpio_cfg_spi in C:\ncs\v1.9.1\modules\hal\nordic\nrfx\hal\nrf_gpio.h
    NRF_STATIC_INLINE void nrf_gpio_cfg_spi(uint32_t pin_number)
    {
    nrf_gpio_cfg(
    pin_number,
    NRF_GPIO_PIN_DIR_INPUT,
    NRF_GPIO_PIN_INPUT_DISCONNECT,
    NRF_GPIO_PIN_PULLUP,
    NRF_GPIO_PIN_S0S1,
    NRF_GPIO_PIN_NOSENSE);
    }

    Checked with the probe that this ensure CS stays high.. and now i see my baseline current below 500uA..

    I do have a few more things to check.. I am doubting I2C current (when not doing transactions) is not as low as what's mentioned in the nrf5340 spec and will disable them while not in use and enable only when needed and see if that helps

    I confirm that k_cpu_idle gets called but given only way to confirm that was using the debugger, I didn't bother checking the power numbers..

Reply
  • Simon,

    found one issue that seems to help get better power numbers.. we use SPI4 to access our NAND chip and looks like CS (SS) was low even when SPI4 is uninitialized.. Since our Nand is powered all the time, this CS staying low seems to trigge tit to some kind of active mode and henc etalke almost 500uA extra current.  Checked SPI code.. 

    Found that SPI uninit API from Nrf SDK doesn't configure the CS (SS) pin to pull up .. needed SDK change in the function 
    spi uninit with CS pull up
    void nrfx_spim_uninit(nrfx_spim_t const * p_instance) in C:\ncs\v1.9.1\modules\hal\nordic\nrfx\drivers\src\nrfx_spim.c
    if (p_cb->ss_pin != NRFX_SPIM_PIN_NOT_USED)
    {
    //nrf_gpio_cfg_default(p_cb->ss_pin);
    nrf_gpio_cfg_spi(p_cb->ss_pin);  ----> newly added
    }

    new api nrf_gpio_cfg_spi in C:\ncs\v1.9.1\modules\hal\nordic\nrfx\hal\nrf_gpio.h
    NRF_STATIC_INLINE void nrf_gpio_cfg_spi(uint32_t pin_number)
    {
    nrf_gpio_cfg(
    pin_number,
    NRF_GPIO_PIN_DIR_INPUT,
    NRF_GPIO_PIN_INPUT_DISCONNECT,
    NRF_GPIO_PIN_PULLUP,
    NRF_GPIO_PIN_S0S1,
    NRF_GPIO_PIN_NOSENSE);
    }

    Checked with the probe that this ensure CS stays high.. and now i see my baseline current below 500uA..

    I do have a few more things to check.. I am doubting I2C current (when not doing transactions) is not as low as what's mentioned in the nrf5340 spec and will disable them while not in use and enable only when needed and see if that helps

    I confirm that k_cpu_idle gets called but given only way to confirm that was using the debugger, I didn't bother checking the power numbers..

Children
  • I'm happy you found one cause of the high current consumption.

    sshenoy105 said:
    I do have a few more things to check.. I am doubting I2C current (when not doing transactions) is not as low as what's mentioned in the nrf5340 spec and will disable them while not in use and enable only when needed and see if that helps

    Would you be able to open a new ticket about this? I know that this question is still in in-scope of this ticket, but I see that this ticket is starting to get quite long and unorganized, also current consumption is not my expertise, so if you open a new ticket it will get assigned to an engineer with more knowledge about this. A huge part of the support team are on vacation, so it may take a little longer time than usual before you get a reply.

    Best regards,

    Simon

Related