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. 

Parents
  • 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. 

Reply
  • 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. 

Children
Related