cancel
Showing results for 
Search instead for 
Did you mean: 

RTC Wake Up Interrupt not firing on STM32L0 using LL Low Layer Libraries

HMcKi
Associate III

Took me a little while to work this one out so though i'd share.

My goal was to use the RTC wake up interrupt as the time source to periodically flash a LED.  

STM32CubeMx Configuration:

HMcKi_0-1744336044132.png

HMcKi_1-1744336060547.png

HMcKi_2-1744336074357.png

To configure the RTC, I used the code from the cube L0 firmware example RTC_ExitStandbyWithWakeUpTimer for STM32L073RZ_NUCLEO to get started. The RTC configuration:

LL_RTC_DisableWriteProtection(RTC);
LL_RTC_WAKEUP_Disable(RTC);
while(LL_RTC_IsActiveFlag_WUTW(RTC)==0) {}
LL_RTC_WAKEUP_SetAutoReload(RTC,200); //RTC_WUTR_WUT value can be written only when WUTWF is set to 1 in RTC_ISR
LL_RTC_WAKEUP_SetClock(RTC, LL_RTC_WAKEUPCLOCK_DIV_16); //RTC_CR_WUCKSEL reg is write-protected. Bit can be written only when RTC_CR WUTE bit = 0 and RTC_ISR WUTWF bit = 1
LL_RTC_WAKEUP_Enable(RTC); //WUTE flag = Wakeup Timer Enable. WUTE Bit is write protected. 
LL_RTC_ClearFlag_WUT(RTC);
LL_RTC_EnableIT_WUT(RTC); //RTC_CR_WUTIE Bit is write-protected.
LL_RTC_EnableWriteProtection(RTC);

uint32_t getClock,getAutoReload,getIsEnabledIT_WUT,getRTC_WAKEUP_IsEnabled;
getClock=LL_RTC_WAKEUP_GetClock(RTC);
getAutoReload=LL_RTC_WAKEUP_GetAutoReload(RTC);
getIsEnabledIT_WUT=LL_RTC_IsEnabledIT_WUT(RTC);
getRTC_WAKEUP_IsEnabled=LL_RTC_WAKEUP_IsEnabled(RTC);

What I noticed was the interrupt never fired.

uint32_t myRTC_IRQHandler;
void RTC_IRQHandler(void)
{
  /* USER CODE BEGIN RTC_IRQn 0 */
	myRTC_IRQHandler++;
	LL_RTC_ClearFlag_WUT(RTC);
	MyCallback();
  /* USER CODE END RTC_IRQn 0 */

  /* USER CODE BEGIN RTC_IRQn 1 */

  /* USER CODE END RTC_IRQn 1 */
}

 

There is a subtle difference in waking up from stop mode compared to standby mode. The reference manual page 159:

To wake up from the Stop mode with an RTC Wakeup event, it is necessary to:
a) Configure the EXTI Line 20 to be sensitive to rising edges (Interrupt or Event
modes)
b) Enable the RTC Wakeup Interrupt in the RTC_CR register
c) Configure the RTC to generate the RTC Wakeup event

To wake up from the Standby mode with an RTC Wakeup event, it is necessary to:
a) Enable the RTC Wakeup Interrupt in the RTC_CR register
b) Configure the RTC to generate the RTC Wakeup event

After adding the following code, the interrupt then triggered once.

LL_EXTI_InitTypeDef eitd;
	
//configure the EXTI 
eitd.Line_0_31   = LL_EXTI_LINE_20;
eitd.LineCommand = ENABLE;
eitd.Mode        = LL_EXTI_MODE_IT;
eitd.Trigger     = LL_EXTI_TRIGGER_RISING;
LL_EXTI_Init(&eitd);
  
LL_EXTI_ClearFlag_0_31(LL_EXTI_LINE_20);
LL_EXTI_EnableIT_0_31(LL_EXTI_LINE_20);	

 

Since the wake up interrupt has an auto reload, to re-arm the interrupt the following was added to the ISR.

uint32t myRTC_IRQHandler,myEXTI20ActiveFlag;
void RTC_IRQHandler(void)
{
  /* USER CODE BEGIN RTC_IRQn 0 */
	myRTC_IRQHandler++;
	if(LL_EXTI_IsActiveFlag_0_31(LL_EXTI_LINE_20)) 
	{
		myEXTI20ActiveFlag++;
	}		

	LL_EXTI_ClearFlag_0_31(LL_EXTI_LINE_20);
	LL_RTC_ClearFlag_WUT(RTC);
	LL_EXTI_EnableIT_0_31(LL_EXTI_LINE_20);
	MyCallback();
  /* USER CODE END RTC_IRQn 0 */

  /* USER CODE BEGIN RTC_IRQn 1 */

  /* USER CODE END RTC_IRQn 1 */
}

 

1 REPLY 1
HMcKi
Associate III

Looking through the HAL libraries, this configures the EXTI interrupt for you in 

file - stm32l0xx_hal_rtc_ex.c

function - HAL_RTCEx_SetWakeUpTimer_IT

  /* Enable and configure the EXTI line associated to the RTC Wakeup Timer interrupt */
  __HAL_RTC_WAKEUPTIMER_EXTI_ENABLE_IT();
  __HAL_RTC_WAKEUPTIMER_EXTI_ENABLE_RISING_EDGE();