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

Ultra low power mode - nRF52832

Hi,

I am using nRF52832 with sdk 15, freertos.

I need to implement the following logic:

1. Get into low power mode, while keeping a timer running.

2. Every 10 mins the system needs to 'wake up', run some commands and return to low power mode.

From the datasheet i understand that the most suitable mode is "System ON, Full RAM retention, Wake on any event" (17.1.1 page 77). 

1. Am I correct?

2. Is there any code sample for this power mode? 

3. Is there any API documentation for power mode configuration?

4. I am using the freeRTOS port from the HRM example, does this require any special adjustments?

5. I am using BLE on my device, does this require any special adjustments as well? (I don't need to maintain active connection during the low power state)

Thanks,

Shaked. 

  • Hi Shaked, 

    Q1: Yes, going to System On with full RAM retention and then waking up on a timer interrupt sounds like the way to go. 

    Q2: If the SoftDevice is enabled you simply call sd_app_evt_wait() and the SoftDevice will go to System ON: Low Power mode untill the next interrupt occurs. If you're not using the SoftDevice then you call _WFE() ( wait for event )

    Q3: See sd_app_evt_wait and http://www.keil.com/support/man/docs/armasm/armasm_dom1361289926047.htm

    Q4: The FreeRTOS kernel takes care of this automatically, i.e. whenever there is no task to run it will call __WFE(); or sd_app_evt_wait();

    Q5: No, the SoftDevice will manage the connections for you. 

    Best regards

    Bjørn

  • Hi Bjorn,

    Thank you for your answer. 

    I am now using sd_app_evt_wait() like you advised, and I am removing all interrupts before-

    	sd_nvic_ClearPendingIRQ(Reset_IRQn);
    	while(1) //#65 while button isn't pressed
    	{
    		ret_code_t ret_code = sd_app_evt_wait();
    		ASSERT((ret_code == NRF_SUCCESS) || (ret_code == NRF_ERROR_SOFTDEVICE_NOT_ENABLED));
    		sd_nvic_ClearPendingIRQ(Reset_IRQn);
    
    	}

    In order to the sd_app_evt_wait() function to work, in 'port_cmsis_systick.c' file, i changed the 'if 0' to be 'if 1' as following:

    #if 1  // With FreeRTOS sd_app_evt_wait increases power consumption with FreeRTOS compared to _WFE (NRFFOSDK-11174)
    #ifdef SOFTDEVICE_PRESENT
                if (nrf_sdh_is_enabled())
                {
                    uint32_t err_code = sd_app_evt_wait();
                    APP_ERROR_CHECK(err_code);
                }
                else
    #endif

    without changing it, the function isn't called at all (since it is in the 'ifdef'), and after changing it, the current gets higher than the original one.

    Please advise.

    Thank you, 

    Shaked. 

  • As the comment states: With FreeRTOS sd_app_evt_wait increases power consumption with FreeRTOS compared to _WFE (NRFFOSDK-11174). 
    Hence I would leave the implementation as it is, i.e. with the #if 0 statement. 

  • Hi,

    Keeping it as 'if 0' will cause it to ignore the whole part in the 'ifdef', so it seems it isn't getting into sleep mode at all.

    Let me make my question clearer. 

    I am using the next code in order for the device to go into sleep mode:

    	sd_nvic_ClearPendingIRQ(Reset_IRQn);
    	while(1) //#65 while button isn't pressed
    	{
    		ret_code_t ret_code = sd_app_evt_wait();
    		ASSERT((ret_code == NRF_SUCCESS) || (ret_code == NRF_ERROR_SOFTDEVICE_NOT_ENABLED));
    		sd_nvic_ClearPendingIRQ(Reset_IRQn);
    
    	}

    but I see the device isn't going into sleeping mode. 

    May it be because i am using ticks as well? maybe i need to use "vPortSuppressTicksAndSleep" ? 

    How can i get it so go into sleep mode ?

    Thanks,

    Shaked. 

  • HI Shaked,

    Yes, you need to use FreeRTOS in Tickless Idle mode, so that the idle task calls portSUPPRESS_TICKS_AND_SLEEP, which is defined as vPortSuppressTicksAndSleep(). 

    Best regards
    Bjørn

Related