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

Minimizing the power draw using System OFF and RAM retention

Hi everyone,

I'm having an issue with the power draw of my application (SDK 15.0.0, SD 132 v6, Sparkfun nRF52832 Breakout). The application does roughly the following: it sleeps until it receives an GPIO interrupt (there are two different GPIOs which can wake up the application), does some (non connectable) advertising and resumes sleeping.

According to the data sheet of the nRF52832 0.7 µA are possible with full RAM retention and in system state System OFF. The power draw of my application exceeds this number (around ten times higher), however I'm not utilising the System OFF mode yet (currently using only the nrf_pwr_mgmt_run() function).

I did some research and discovered the sd_power_off() function. When I add the sd_power_off() function to my code, the system "freezes" / 'hangs" and draws about 10mA.

I did take a look at the example "ble_app_pwr_profiling" but it is rather complex - has anyone created / found a simpler solution (do some advertising, go to System OFF with RAM retention, wake up to an GPIO interrupt, repeat) yet?

How can I differentiate the two different GPIO interrupt sources when using them to wake up? (I want to count the times my application has woken up to sources 1 and 2)


Best,

lhochstetter

  • Hi,

    waking up from Sytem OFF using following snippets works just fine, thanks alot!

    static void gpio_init(void)
    {
    	ret_code_t err_code;
    
    	err_code = nrf_drv_gpiote_init();
    	APP_ERROR_CHECK(err_code);
    
    	nrf_drv_gpiote_out_config_t out_config = GPIOTE_CONFIG_OUT_SIMPLE(true);
    	err_code = nrf_drv_gpiote_out_init(BSP_LED_0, &out_config);
    
    	APP_ERROR_CHECK(err_code);
    	err_code = nrf_drv_gpiote_out_init(BSP_LED_2, &out_config);
    
    	nrf_gpio_cfg_sense_input(BSP_BUTTON_0, NRF_GPIO_PIN_PULLUP, NRF_GPIO_PIN_SENSE_LOW);
    }

    void main()
    {
    	uint32_t j = ((uint32_t *) (0x2000F000))[0];
    
    	// Initialize.
    	gpio_init();
    	ble_stack_init();
        for (int i = 0; i < 8; i++) {
        	sd_power_ram_power_set(i,
        		                  (POWER_RAM_POWER_S0POWER_On << POWER_RAM_POWER_S0POWER_Pos)
        		                | (POWER_RAM_POWER_S1POWER_On << POWER_RAM_POWER_S1POWER_Pos)
        		                | (POWER_RAM_POWER_S0RETENTION_On << POWER_RAM_POWER_S0RETENTION_Pos)
        		                | (POWER_RAM_POWER_S1RETENTION_On << POWER_RAM_POWER_S1RETENTION_Pos));
        }
    	if (0 == nrf_gpio_pin_read(BSP_BUTTON_0)) {
    		nrf_drv_gpiote_out_clear(BSP_LED_0);
    	}
    
    	if (3 == j) {
    		nrf_drv_gpiote_out_clear(BSP_LED_2);
    		j = 0;
    	}
    
    	j++;
    	((uint32_t *) (0x2000F000))[0] = j;
    
    	nrf_delay_ms(1000);
    
    	nrf_drv_gpiote_out_set(BSP_LED_0);
    	nrf_drv_gpiote_out_set(BSP_LED_2);
    
    	sd_power_system_off();
    
    
    	for(;;) {
    		sd_app_evt_wait();
    	}
    }


    However, RAM retention doesn't (again using above shown snippets). I'm trying to retain the entire RAM of the nRF52832, but it seems that my for loop doesn't do it's job. I tried to only set the 7th RAM tile (both sections) but to no avail.

    What am I missing?

    Another question in the very same project popped up: I'm seeing 15-20mV spikes in intervals of around 45ms when advertising / when sd_app_evt_wait() is running.

    Could it be that some scanning related code is running in the background / softdevice in between advertisements? (I've largely adapted the ble_peripheral / ble_app_beacon example, but I'd argue that the scanning functionality isn't configured / started).

    Kind regards,

    lhochstetter

  • Hello,

     

    lhochstetter said:
    Another question in the very same project popped up: I'm seeing 15-20mV spikes in intervals of around 45ms when advertising / when sd_app_evt_wait() is running.

    These are due to the regulator refresh mode: https://devzone.nordicsemi.com/f/nordic-q-a/20121/periodic-current-during-waiting-event

    I assume you're using a 10 ohm resistor (1.5 to 2 mA) to monitor the current.

    lhochstetter said:
    However, RAM retention doesn't (again using above shown snippets). I'm trying to retain the entire RAM of the nRF52832, but it seems that my for loop doesn't do it's job. I tried to only set the 7th RAM tile (both sections) but to no avail.

    What am I missing?

     

    Pointing to a specific address is not a recommended approach, as you do not know if there's anything there already, like the .stack or .heap section. See this thread and the linked threads for more information on ram retention after system off:

    https://devzone.nordicsemi.com/f/nordic-q-a/36848/nrf52840-ram-retention-example-fails-with-max_test_iterations-1

    Kind regards,

    Håkon

  • Hi, I would ask what do you mean by "Are you debugging while trying to enter system off mode?". Do you mean connect your board with an usb to pc? if I unplug the board with the usb, is this mean I am not in the debug mode?

  • By debugging, I mean that you actively entered "debug mode" through your IDE and single-stepping through your code.

  • Hi Håkon,

    What do you mean "single-stepping through your code"?

    my code is just as simple as below:

    #include "boards.h"
    
    /**
    * @brief Function for application main entry.
    */
    int main(void)
    {
    NRF_POWER->SYSTEMOFF = 1;
    }
    /** @} */

    So am I in the debug mode?

    Thanks Slight smile

Related