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

Early wake-up from POWER/CLOCK IRQ when using RTC to wake up

Hello -

We are developing on a nRF52840 device, SDK v17.0.2 and FreeRTOS. Following the flow in the provided by the vPortSuppressTicksAndSleep() function, we've implemented a function to wake-up from RTC or any interrupt in System ON sleep mode. Our function also powers down most of the RAM sections before sleeping. After wake-up the function powers RAM back on and resets the device. That all seems to work well. We use the following loop while sleeping to wait for any event:

do {
  __WFE();
} while (0 == (NVIC->ISPR[0] | NVIC->ISPR[1]));

The problem is that if we call our RTC wake-up function soon after the device reboots, say within 200-400 ms of reboot, the sleep loop above exits early with ISPR[0] set to 1. If I understand the registers correctly, the value 1 corresponds to the POWER/CLOCK IRQn. Masking out this interrupt in the loop works around the problem:

do {
  __WFE();
} while (0 == ((NVIC->ISPR[0] & (~(uint32_t)(1L << POWER_CLOCK_IRQn))) | NVIC->ISPR[1]));

Am I correct that the POWER/CLOCK interrupt is set pending, and if so, what would lead to this condition and how can we best avoid it?

Regards,

Brian

Parents Reply Children
  • Hello -

    Thank you for the suggestions. The LFCLK is started at application launch when the RTC is initially configured. In our sleep function we basically reprogram the RTC for wake-up from System ON sleep after a specified period of time.

    I looked at the events and enabled interrupts per your suggestion. I think I found the problem. The LFCLKSTARTED interrupt was enabled and after the __WFE() loop exits, the EVENTS_LFCLKSTARTED event was generated. To resolve that I disabled LFLCK interrupts before entering the loop:

    nrf_clock_int_disable(CLOCK_INTENSET_LFCLKSTARTED_Msk);
    

    That seems to resolve the issue and wait loop no longer exits early:

    do {
      __WFE();
    } while (0 == (NVIC->ISPR[0] | NVIC->ISPR[1]));

    Regards,

    Brian

Related