NRF9160 Deep Sleep Power Consumption Help

Hello,

I am using mfw1.3.0 and NCS 1.7.0 developing an application on a custom board implementing the NRF9160 and NRF52820 (The 52820 is put into very low power using nrf_pwr_mgmt_shutdown(NRF_PWR_MGMT_SHUTDOWN_STAY_IN_SYSOFF);). 

There is a state in the application where we would like the device to go into a deep sleep mode where the device ideally consumes <200uA of current (Lower is even better). The device is awoken by a state change on a configured Sense pin. 

In the current stage of development, everything is working decently well with the modem powering off and then the device being set to deep sleep. The issue is that we are seeing around 900uA of average current draw (It seems to be fluctuating between about 500uA and 1200uA). I know some of this current is due to on-board peripheral parts drawing a bit of power but it really should only be accounting for around 150uA or so and is something we are working on separately.

I have read pretty much every post out there about low power mode on the NRF9160 and it seems that the first thing to check is if CONFIG_SERIAL is disabled in both the application config as well as the SPM config. Our application will be using serial but we want to shut it down before going into deepsleep with this function: 

pm_device_state_set(uart_0_dev, PM_DEVICE_STATE_OFF);
This behavior is found in the serial_lte_modem example. The problem is that using this line to disable uart seems to have no effect on current draw.
I also tried just not using serial at all in the application and ensuring that CONFIG_SERIAL is not set in either the application config or SPM config. This also did not have any affect which was surprising to me and leads me to believe that there is another peripheral that we have enabled which is causing the same current draw that having the serial peripheral does.
My questions that can't be answered by other tickets are:
1. What is the real reason that turning serial off saves power in deep sleep? From looking at other tickets I think that the root cause of the power draw is keeping the HF clock active in deep sleep which can draw a decent amount of current.
2. Are there other peripherals that could be causing the same issue for us still? We use I2C, SPI, UART, PWM, and GPIO in the application.
3. What is the best way to have serial enabled in the application but turn the peripheral off before sleeping in NCS1.7.0 and mfw1.3.0?
Also, we have tried with mfw1.3.1 which supposedly has a fix for a deep sleep power issue but that has no affect. 
Thanks!
Tyler
Parents
  • Hi, sorry for the late response.

    What is the real reason that turning serial off saves power in deep sleep? From looking at other tickets I think that the root cause of the power draw is keeping the HF clock active in deep sleep which can draw a decent amount of current.

    The UART, more specifically the UART receiver is using the HF clock constantly, because it is always ready to receive data. The UART peripherals are automatically enabled in zephyr, and thus also the UART receivers. This includes the logging module which is using UART0, but also UART1 and UART2, even though they may not be used at all. You will have to explicitly disable these peripherals if they are not used in the .overlay file.

    Using CONFIG_SERIAL=n is a quick way to turn off all UARTs. But as you say, if you are actually going to use any of the UARTs, it can not be used. I would recommend to only use this config in the SPM config file, as this will turn off the logging module in the SPM, and then you can still use UART in the application.

    The HF clock current does not add up when enabling several peripherals that are using the HF clock. So the current will stay at 5-600 uA and not go down until all peripherals requiring the clock are disabled.

    Are there other peripherals that could be causing the same issue for us still? We use I2C, SPI, UART, PWM, and GPIO in the application.

    I2C slave, GPIOTE IN event and SPI slave will use a pin sense mechanism which will consume current in the 20-50 uA range. The HF clock will only be started when there is a transaction. PWM and other "master" peripherals will only use the HF clock when they are active (as in ongoing transaction, or PWM output)

    What is the best way to have serial enabled in the application but turn the peripheral off before sleeping in NCS1.7.0 and mfw1.3.0?

    Power management API

    The best way is to use the power management API:

    • Add CONFIG_SERIAL=n to the SPM prj.conf
    • Add CONFIG_DEVICE_POWER_MANAGEMENT=y to the application prj.conf
    • And the following to main in order to turn off logging (and UART0)

    #include <pm/pm.h>
    
    void main(void)
    {
        const struct device *console;
        console = device_get_binding(DT_LABEL(DT_CHOSEN(zephyr_console)));
        pm_device_state_set(console, PM_DEVICE_STATE_OFF, NULL, NULL);
        
        .....
    }

    Then you can use the same pm_device_state_set() function to turn the UART1 or UART2 on or off dynamically. Use PM_DEVICE_STATE_SUSPENDED and PM_DEVICE_STATE_ACTIVE.

    Using an overlay file

    It's also a good idea to use an .overlay file to modify the device tree so that peripherals you are not using are disabled. Below is an example where UART1, UART2, and the receiving part of UART0 is disabled. Now UART0 is available for log output, but the receiver is switched off, which means that UART0 will not request the HF clock and neither will UART1 or UART2, so the current consumption should go down to about 50 uA which is the "enabled only" current for UART0. (Note: You can not disable UART0 completely using the overlay file, as this is used by the logging module, unless you disable the logging module in the config files)

    The overlay file should be named the same as the board you are compiling for, and be put in the project folder. E.g. nrf9160dk_nrf9160ns.overlay

    &uart0 {
        /delete-property/ rx-pin;
    };
    &uart1 {
        status = "disabled";
    };
    &uart2 {
        status = "disabled";
    };

    So to summarize:

    • CONFIG_SERIAL=n only in SPM project
    • Use power management API to dynamically power on/off the UARTs. The UART should not consume any current when suspended.
    • Use power management API to turn off logging module (UART0), if it's not needed.
    • Use .overlay file to disable unused peripherals.
    • Use .overlay file to turn off RX, of you are only using TX. In this mode the peripheral will consume about 50 uA, and you do not have to use the power management API if 50 uA is acceptable. You can use this method on the logging module (UART0)
Reply
  • Hi, sorry for the late response.

    What is the real reason that turning serial off saves power in deep sleep? From looking at other tickets I think that the root cause of the power draw is keeping the HF clock active in deep sleep which can draw a decent amount of current.

    The UART, more specifically the UART receiver is using the HF clock constantly, because it is always ready to receive data. The UART peripherals are automatically enabled in zephyr, and thus also the UART receivers. This includes the logging module which is using UART0, but also UART1 and UART2, even though they may not be used at all. You will have to explicitly disable these peripherals if they are not used in the .overlay file.

    Using CONFIG_SERIAL=n is a quick way to turn off all UARTs. But as you say, if you are actually going to use any of the UARTs, it can not be used. I would recommend to only use this config in the SPM config file, as this will turn off the logging module in the SPM, and then you can still use UART in the application.

    The HF clock current does not add up when enabling several peripherals that are using the HF clock. So the current will stay at 5-600 uA and not go down until all peripherals requiring the clock are disabled.

    Are there other peripherals that could be causing the same issue for us still? We use I2C, SPI, UART, PWM, and GPIO in the application.

    I2C slave, GPIOTE IN event and SPI slave will use a pin sense mechanism which will consume current in the 20-50 uA range. The HF clock will only be started when there is a transaction. PWM and other "master" peripherals will only use the HF clock when they are active (as in ongoing transaction, or PWM output)

    What is the best way to have serial enabled in the application but turn the peripheral off before sleeping in NCS1.7.0 and mfw1.3.0?

    Power management API

    The best way is to use the power management API:

    • Add CONFIG_SERIAL=n to the SPM prj.conf
    • Add CONFIG_DEVICE_POWER_MANAGEMENT=y to the application prj.conf
    • And the following to main in order to turn off logging (and UART0)

    #include <pm/pm.h>
    
    void main(void)
    {
        const struct device *console;
        console = device_get_binding(DT_LABEL(DT_CHOSEN(zephyr_console)));
        pm_device_state_set(console, PM_DEVICE_STATE_OFF, NULL, NULL);
        
        .....
    }

    Then you can use the same pm_device_state_set() function to turn the UART1 or UART2 on or off dynamically. Use PM_DEVICE_STATE_SUSPENDED and PM_DEVICE_STATE_ACTIVE.

    Using an overlay file

    It's also a good idea to use an .overlay file to modify the device tree so that peripherals you are not using are disabled. Below is an example where UART1, UART2, and the receiving part of UART0 is disabled. Now UART0 is available for log output, but the receiver is switched off, which means that UART0 will not request the HF clock and neither will UART1 or UART2, so the current consumption should go down to about 50 uA which is the "enabled only" current for UART0. (Note: You can not disable UART0 completely using the overlay file, as this is used by the logging module, unless you disable the logging module in the config files)

    The overlay file should be named the same as the board you are compiling for, and be put in the project folder. E.g. nrf9160dk_nrf9160ns.overlay

    &uart0 {
        /delete-property/ rx-pin;
    };
    &uart1 {
        status = "disabled";
    };
    &uart2 {
        status = "disabled";
    };

    So to summarize:

    • CONFIG_SERIAL=n only in SPM project
    • Use power management API to dynamically power on/off the UARTs. The UART should not consume any current when suspended.
    • Use power management API to turn off logging module (UART0), if it's not needed.
    • Use .overlay file to disable unused peripherals.
    • Use .overlay file to turn off RX, of you are only using TX. In this mode the peripheral will consume about 50 uA, and you do not have to use the power management API if 50 uA is acceptable. You can use this method on the logging module (UART0)
Children
No Data
Related