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

Some event prevent the uC to enter low power mode

Hi,

After configure IO and RTC I tried to enter into low power mode however the current consumption doesn't decrease until I call again __SEV(); / __WFE(); / __WFE(); on CIO::buttonInterruptHandler per example.

In the code block below you can see the IO and RTC configuration. If instead of two __WFE() calls I do 4 calls the current consumption decrease to low power levels.

How can I find out which event is preventing nrf51822 to go into low power mode?

/* Configure inputs */
nrf_drv_gpiote_init();
nrf_drv_gpiote_in_config_t in_config;
in_config.is_watcher = false;
in_config.hi_accuracy = false;
in_config.pull = NRF_GPIO_PIN_PULLUP;
in_config.sense = NRF_GPIOTE_POLARITY_HITOLO;

/* Enable interrupt at button down */
nrf_drv_gpiote_in_init(BUTTON_DOWN, &in_config, CIO::buttonInterruptHandler);
nrf_drv_gpiote_in_event_enable(BUTTON_DOWN, true);

/* Enable interrupt at button up */
nrf_drv_gpiote_in_init(BUTTON_UP, &in_config, CIO::buttonInterruptHandler);
nrf_drv_gpiote_in_event_enable(BUTTON_UP, true);

/* Configure pin as output */
nrf_gpio_cfg_output(PIN_UPDOWN);
nrf_gpio_cfg_output(PIN_ENDISABLE);

nrf_drv_clock_init();
nrf_drv_clock_lfclk_request(NULL);

//Initialize RTC instance
nrf_drv_rtc_config_t config;// = NRF_DRV_RTC_DEFAULT_CONFIG;
config.interrupt_priority = RTC_DEFAULT_CONFIG_IRQ_PRIORITY;
config.reliable = RTC_DEFAULT_CONFIG_RELIABLE;
config.tick_latency = RTC_US_TO_TICKS(NRF_MAXIMUM_LATENCY_US, RTC_DEFAULT_CONFIG_FREQUENCY);
config.prescaler = 4095;
nrf_drv_rtc_init(&rtc, &config, rtc_handler);

//Power on RTC instance
nrf_drv_rtc_enable(&rtc);

__SEV();
__WFE();
__WFE();
  • "However, if it is required (for testing or for other purposes) to demonstrate a guaranteed period of sleep caused by WFE - and assuming that the processor does implement WFE sleep behavior - the following approach can be used.

    If you are not executing any instructions which can cause exceptions (eg. LDR/STR, SVC) and you do not have any asynchronous sources of exceptions active (NMI, INTISR, SysTick) and you do not have a debugger attached which could issue a debug HALT, then there is nothing to cause the event register to become set unexpectedly.

    In this scenario, you can use the sequence:

    SEV WFE WFE

    The SEV will set the event register, causing the first WFE to complete execution immediately. The second WFE will then be executed with the event register cleared, and in the absence of any of the other possible mechanisms for setting the event register, this will put the processor to sleep until the RXEV input goes HIGH."

    In the bottom of the page it says that is possible to make it sleep with the above sequence.

Related