cancel
Showing results for 
Search instead for 
Did you mean: 

Where to read length of sleep time on RTC WUT

LWill.4
Associate II

We are using the STM32L071RB, currently have the firmware set to go to sleep (stop mode) and wake up after ~5 minutes with the RTC WUT (see section 22.4.6 and A13.3 in RM0377). This works great, however this timer isn't the only wakeup source. If the device wakes up due to a external interrupt, the timer restarts back to another 5 minutes. So, for these external interrupt events we need to know how long it's already been asleep to compensate and have the periodic wakeup keep the same interval. My first thought was that we could just read the "wakeup timer" register to see how long it's been asleep, but can't find any information on where that is located... (RTC_WUTR is simply the reload register, so it doesn't change)

Does anyone know where the mcu is storing that counter/timer?

 

Alternatively we could set up with an alarm or store the RTC value before going to sleep and compare, but we are low on space and don't want to rewrite deployed code unless necessary

1 ACCEPTED SOLUTION

Accepted Solutions
Saket_Om
ST Employee

Hello @LWill.4 

There is no direct access to the wake-up timer to read its content.

As a workaround, if the wake-up timer is clocked via the synchronous prescaler (WUCKSEL [2:1] = 10 or 11 in the RTC_CR), you can read the RTC_TIME register:

  • first, when the wake-up timer is reloaded,
  • second, when the CPU wakes up from the low power mode,
  • then, calculate the difference. 

This is to answer the question.

However, it sounds unusual that the wake-up timer is reinitialized for 5 more minutes after each wake-up from low power mode, unless the application is explicitly doing it.

Indeed, as show in the table below (extract from RM0367), low power modes have no impact on RTC features and its registers that keep their values.

Saket_Om_1-1718983579912.jpeg

If it is the application that is reinitializing the wake-up timer after the wake-up from a low power mode, it should no longer do it.

Instead, after wake-up from low power modes, the application shall check the PWR flags (i.e., SBF and WUF in PWR_CSR)

  • If either or both are set, then the application shall not reinitialize the wake-up timer.

If your question is answered, please close this topic by clicking "Accept as Solution".

Thanks
Omar

View solution in original post

6 REPLIES 6
Saket_Om
ST Employee

Hello @LWill.4 

There is no direct access to the wake-up timer to read its content.

As a workaround, if the wake-up timer is clocked via the synchronous prescaler (WUCKSEL [2:1] = 10 or 11 in the RTC_CR), you can read the RTC_TIME register:

  • first, when the wake-up timer is reloaded,
  • second, when the CPU wakes up from the low power mode,
  • then, calculate the difference. 

This is to answer the question.

However, it sounds unusual that the wake-up timer is reinitialized for 5 more minutes after each wake-up from low power mode, unless the application is explicitly doing it.

Indeed, as show in the table below (extract from RM0367), low power modes have no impact on RTC features and its registers that keep their values.

Saket_Om_1-1718983579912.jpeg

If it is the application that is reinitializing the wake-up timer after the wake-up from a low power mode, it should no longer do it.

Instead, after wake-up from low power modes, the application shall check the PWR flags (i.e., SBF and WUF in PWR_CSR)

  • If either or both are set, then the application shall not reinitialize the wake-up timer.

If your question is answered, please close this topic by clicking "Accept as Solution".

Thanks
Omar

Yeah, the application is resetting the timer, will have to correct that. I just love inheriting code...

And thanks for the info! Will update for posterity if anything interesting comes up

tcampos
Associate

I would like to know if the solution to the problem has arrived, as I am facing the same issue.

 

The solution I ended up going with was to check the wakeup source, if it was from the WUT then proceed as normal and if not, simply skip the WUT setup code when it went to sleep. While of course checking that the WUT was set up correctly first (WUTIE, WUTR, etc...) and that it hadn't triggered during the wake period (WUTF)

Still can have a small delay the length of the external interrupt wakeup, but for this application we can live with that. Thinking about rewriting at some point in the future to use the RTC alarms instead to make the timing more consistent

I have an application where the MCU wakes up every 1 hour via RTC. Additionally, I have some GPIOs that wake up the MCU, count pulses, and go back to sleep. Unfortunately, the GPIOs interfere with the RTC, resetting its configuration. I want that when a GPIO interrupt occurs, I reprogram the RTC with the remaining time.

I am using rtc_time_before_sleep = RTC->TR; and uint32_t rtc_time_after_sleep = RTC->TR; to calculate the time difference."

 

 

 

volatile uint32_t rtc_time_before_sleep = 0;

void EnterStop2Mode(void) {
// Stores the value of the RTC_TIME register before entering low power mode
rtc_time_before_sleep = RTC->TR;

// Configures the WakeUp Timer
HAL_RTCEx_SetWakeUpTimer_IT(&hrtc, WAKEUP_TIME_SECONDS, RTC_WAKEUPCLOCK_CK_SPRE_16BITS);

// De-initializes peripherals to reduce power consumption
HAL_GPIO_DeInit(GPIOB, GPIO_PIN_4);
HAL_GPIO_DeInit(GPIOB, GPIO_PIN_6);
HAL_GPIO_DeInit(GPIOB, GPIO_PIN_12);
HAL_ADC_DeInit(&hadc);
__HAL_RCC_ADC1_CLK_DISABLE();
HAL_DMA_DeInit(&hdma_usart2_rx);
HAL_UART_DeInit(&huart2); // Disables UART2

// Enables ultra-low power mode
HAL_PWREx_EnableUltraLowPower();

// Suspends the system tick and enters STOP mode
HAL_SuspendTick();
HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);
}

void HAL_RTCEx_WakeUpTimerEventCallback(RTC_HandleTypeDef *hrtc) {
// Retrieves the value of the RTC_TIME register after waking up
uint32_t rtc_time_after_sleep = RTC->TR;

// Calculates the difference in seconds (assuming RTC is configured to count seconds directly)
uint32_t elapsed_seconds = rtc_time_after_sleep - rtc_time_before_sleep;

// Sends the elapsed time via UART1 for debugging
char buffer[32];
snprintf(buffer, sizeof(buffer), "Elapsed time: %lu seconds\n", elapsed_seconds);
HAL_UART_Transmit(&huart1, (uint8_t*)buffer, strlen(buffer), 100);

// Deactivates the WakeUp Timer
HAL_RTCEx_DeactivateWakeUpTimer(hrtc);
}

 

 

Hey Tcampos, if you have a specific question about your code, you'd likely be better off posting it to a new thread as a lot more people who are more knowledgeable than I am will see it