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
  • Hi,

    Are you starting the LFCLK together with the RTC? If you are, how do you do this?

    You can read out the POWER Registers and CLOCK Registers with your debugger to see which EVENTS have been generated, and which interrupts are enabled (in the INTENSET registers).

    Best regards,
    Jørgen

  • 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

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

Children
No Data
Related