This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

nRF52840 System OFF RAM power consumption

  • SDK15.3
  • SES
  • nRF52840

Hello Folks,

I'm trying to reduce my applications power consumption further in system off mode. For testing my IO configuration and System OFF, I've reduced the application to just the GPIO initialization and going to System OFF with a call to nrf_pwr_mgmt_shutdown as I don't even have the soft device enabled.

My test code is as following:

int main(void)
{
	uint32_t ret;

    GpioInit();
    
    #if NRF_LOG_USES_TIMESTAMP
		ret = NRF_LOG_INIT(get_timestamp_counter);
    #else
		ret = NRF_LOG_INIT(NULL);
    #endif   

    APP_ERROR_CHECK(ret);
    NRF_LOG_DEFAULT_BACKENDS_INIT();
  
    while (1)
    {
        nrf_pwr_mgmt_shutdown(NRF_PWR_MGMT_SHUTDOWN_STAY_IN_SYSOFF);
    }
}

With this piece of code I have a power consumption of 1.766uA when measured with an Power Profiler Kit.

This comes close to the specified current consumption in the product Specification of having all RAM retained during System Off.

IOFF_RAMON_RESET System OFF, full 256 kB RAM retention, wake on reset 1.86 μA

As I don't need RAM retention due to the reset of the wake-up from System Off. I'd like to disable RAM retention. I couldn't find any specification whether the nrf_pwr_mgmt_shutdown(NRF_PWR_MGMT_SHUTDOWN_STAY_IN_SYSOFF) or sd_power_system_off() disable all RAM retention dusring System Off, but from my current measurement it looks like they don't. So according to the following examples; https://github.com/NordicPlayground/nrf51-powerdown-examples and the RAM retention example in the SDK, I've come up with the following:

#define NRF52_ONRAM1_OFFRAM0   ((POWER_RAM_POWER_S0POWER_On       << POWER_RAM_POWER_S0POWER_Pos)      |\
                                (POWER_RAM_POWER_S1POWER_On       << POWER_RAM_POWER_S1POWER_Pos)      |\
                                (POWER_RAM_POWER_S2POWER_On       << POWER_RAM_POWER_S2POWER_Pos)      |\
                                (POWER_RAM_POWER_S3POWER_On       << POWER_RAM_POWER_S3POWER_Pos)      |\
                                (POWER_RAM_POWER_S4POWER_On       << POWER_RAM_POWER_S4POWER_Pos)      |\
                                (POWER_RAM_POWER_S5POWER_On       << POWER_RAM_POWER_S5POWER_Pos)      |\
                                (POWER_RAM_POWER_S6POWER_On       << POWER_RAM_POWER_S6POWER_Pos)      |\
                                (POWER_RAM_POWER_S7POWER_On       << POWER_RAM_POWER_S7POWER_Pos)      |\
                                (POWER_RAM_POWER_S8POWER_On       << POWER_RAM_POWER_S8POWER_Pos)      |\
                                (POWER_RAM_POWER_S9POWER_On       << POWER_RAM_POWER_S9POWER_Pos)      |\
                                (POWER_RAM_POWER_S10POWER_On      << POWER_RAM_POWER_S10POWER_Pos)     |\
                                (POWER_RAM_POWER_S11POWER_On      << POWER_RAM_POWER_S11POWER_Pos)     |\
                                (POWER_RAM_POWER_S12POWER_On      << POWER_RAM_POWER_S12POWER_Pos)     |\
                                (POWER_RAM_POWER_S13POWER_On      << POWER_RAM_POWER_S13POWER_Pos)     |\
                                (POWER_RAM_POWER_S14POWER_On      << POWER_RAM_POWER_S14POWER_Pos)     |\
                                (POWER_RAM_POWER_S15POWER_On      << POWER_RAM_POWER_S15POWER_Pos)     |\
                                (POWER_RAM_POWER_S0RETENTION_Off  << POWER_RAM_POWER_S0RETENTION_Pos)  |\
                                (POWER_RAM_POWER_S1RETENTION_Off  << POWER_RAM_POWER_S1RETENTION_Pos)  |\
                                (POWER_RAM_POWER_S2RETENTION_Off  << POWER_RAM_POWER_S2RETENTION_Pos)  |\
                                (POWER_RAM_POWER_S3RETENTION_Off  << POWER_RAM_POWER_S3RETENTION_Pos)  |\
                                (POWER_RAM_POWER_S4RETENTION_Off  << POWER_RAM_POWER_S4RETENTION_Pos)  |\
                                (POWER_RAM_POWER_S5RETENTION_Off  << POWER_RAM_POWER_S5RETENTION_Pos)  |\
                                (POWER_RAM_POWER_S6RETENTION_Off  << POWER_RAM_POWER_S6RETENTION_Pos)  |\
                                (POWER_RAM_POWER_S7RETENTION_Off  << POWER_RAM_POWER_S7RETENTION_Pos)  |\
                                (POWER_RAM_POWER_S8RETENTION_Off  << POWER_RAM_POWER_S8RETENTION_Pos)  |\
                                (POWER_RAM_POWER_S9RETENTION_Off  << POWER_RAM_POWER_S9RETENTION_Pos)  |\
                                (POWER_RAM_POWER_S10RETENTION_Off << POWER_RAM_POWER_S10RETENTION_Pos) |\
                                (POWER_RAM_POWER_S11RETENTION_Off << POWER_RAM_POWER_S11RETENTION_Pos) |\
                                (POWER_RAM_POWER_S12RETENTION_Off << POWER_RAM_POWER_S12RETENTION_Pos) |\
                                (POWER_RAM_POWER_S13RETENTION_Off << POWER_RAM_POWER_S13RETENTION_Pos) |\
                                (POWER_RAM_POWER_S14RETENTION_Off << POWER_RAM_POWER_S14RETENTION_Pos) |\
                                (POWER_RAM_POWER_S15RETENTION_Off << POWER_RAM_POWER_S15RETENTION_Pos))






int main(void)
{
	uint32_t ret;

    GpioInit();
    
    #if NRF_LOG_USES_TIMESTAMP
		ret = NRF_LOG_INIT(get_timestamp_counter);
    #else
		ret = NRF_LOG_INIT(NULL);
    #endif   

    APP_ERROR_CHECK(ret);
    NRF_LOG_DEFAULT_BACKENDS_INIT();
  
    while (1)
    {
        NRF_POWER->RAM[0].POWERSET = NRF52_ONRAM1_OFFRAM0;
        NRF_POWER->RAM[1].POWERSET = NRF52_ONRAM1_OFFRAM0;
        NRF_POWER->RAM[2].POWERSET = NRF52_ONRAM1_OFFRAM0;
        NRF_POWER->RAM[3].POWERSET = NRF52_ONRAM1_OFFRAM0;
        NRF_POWER->RAM[4].POWERSET = NRF52_ONRAM1_OFFRAM0;
        NRF_POWER->RAM[5].POWERSET = NRF52_ONRAM1_OFFRAM0;
        NRF_POWER->RAM[6].POWERSET = NRF52_ONRAM1_OFFRAM0;
        NRF_POWER->RAM[7].POWERSET = NRF52_ONRAM1_OFFRAM0;
        NRF_POWER->RAM[8].POWERSET = NRF52_ONRAM1_OFFRAM0;

        nrf_pwr_mgmt_shutdown(NRF_PWR_MGMT_SHUTDOWN_STAY_IN_SYSOFF);

    }
}

With the additional powerset register changes the power consumption is reduced to 1.383uA. However i have the following questions:

- My application needs to wake-up from two gpio events; a reed-switch and a tilt sensor. Is it possible to reduce the power consumption further? I think I've correctly disabled the RAM retention for System Off. But I doubt that without the hardware on my board the nRF52840 is actually drawing 0.4uA as specified in the product specification.

- On wake-up do I need to set the POWERSET registers back to default or are there contents not retained during the reset?

  • Hi Radiohead,

    note that the measurements of the Power Profiler might be  off by 15 to 20% and that the 0.4uA figure is a typical value and one should expect chip-to-chip variations. Yo uare doing the measurements on a custom board with the nRF52840 right?

    - My application needs to wake-up from two gpio events; a reed-switch and a tilt sensor. Is it possible to reduce the power consumption further? I think I've correctly disabled the RAM retention for System Off. But I doubt that without the hardware on my board the nRF52840 is actually drawing 0.4uA as specified in the product specification.

    SystemOFF is the lowest power state the NRF52840 can enter. If you want to clear the RAM Power registers then you should use  RAM[n].POWERCLR. However, the RAM blocks should by default be switched of and not retained in System OFF.  

    - On wake-up do I need to set the POWERSET registers back to default or are there contents not retained during the reset?

     Yes, after a reset the registers will be set to their default/reset value listed in the product specification.

    Best regards

    Bjørn

  • Hello Bjorn,

    The few test I did showed that the power consumption was reduced when I disabled the RAM with the POWERSET registers before entering SystemOFF. I'll do this again to see if I didn't make any mistake while measuring the current consumption.

    However, the RAM blocks should by default be switched of and not retained in System OFF.  

    It would be strange if SystemOFF disabled the RAM by default as this would prevent a developer from retaining the RAM if the application required it. 

    I'm currently more interested in the active power consumption reduction. Segger Studio shows only 30% of the RAM being used. So I want to try to disable around 50% of the RAM when my application is active where I'll use SystemON to sleep during short periods of inactivity. Is there somewhere more information about this? In particulair the following topics:

    - How to configure the SES project to only use the active RAM blocks?

    - I guess I'll need to disable the RAM blocks after initializing the soft device?

    - Does this have any consequences for my bootloader? I guess I'll need to set the same RAM parameters as in my application.

  • Hi. 

    Sorry about the late reply here. I took over this ticket from Bjørn when he was out of office. 

    __________

    You can find more information on how to configure the memory settings in SES in this blog-post: 
    https://devzone.nordicsemi.com/nordic/short-range-guides/b/getting-started/posts/adjustment-of-ram-and-flash-memory 

    If you are using a softdevice you can use the SD API after initializing the SD to power down unused RAM sections (ref. sd_power_ram_power_clr). If you don't want to use the SD API you should use RAM[n].POWERCLR before initializing the SD, due to a protection mechanism in the SD. (RAM power control

    If you take a look at this previous ticket: 
    https://devzone.nordicsemi.com/f/nordic-q-a/39396/nrf52840-ram-retention-in-system-on-mode/ 
    You can find an example to how this can be done. 

    Best regards, 
    Joakim

Related