2023-01-30 03:38 AM
I am trying to do RTC wakeup interrupt using STM32L412RBT6 microcomtroller in baremetal c, but the interrupt is not firing, below mentioning my code.
int main(void)
{
LedConfig();
Tim6Config();
RTC_ClockConfig();
RTC_Init();
/* Loop forever */
while(1)
{
GPIOB->BSRR |= (1U<<13);
Delay_ms(1000);
GPIOB->BSRR |= (1U<<29);
SysTick->CTRL &= ~SysTick_CTRL_TICKINT_Msk;
RTC_SetWakeUpTimer_IT(RTC_WAKEUP_TIME_IN_SECONDS, WakeUpAutoClr);
PWR_EnterStopMode();
RTC_DeactivateWakeUpTimer();
RTC_ClockConfig();
SysTick->CTRL |= SysTick_CTRL_TICKINT_Msk;
}
}
void RTC_ClockConfig(void)
{
/* Enable Clock for Power interface.*/
RCC->APB1ENR1 |= (1U<<28);
/*Disable backup domain write protection*/
PWR->CR1 |= (1U<<8);
while((PWR->CR1 & (1U<<8))==0);
/*Reset the Backup domain*/
RCC->BDCR |= (1U<<16);
RCC->BDCR &= ~(1U<<16);
/*Enable LSE Clock source and wait until LSERDY bit to set*/
RCC->BDCR |= (1U<<0);
while ((RCC->BDCR & (1U<<1)) == 0);
/*Select LSE as RTC Clock*/
RCC->BDCR |= (1U<<8);
RCC->BDCR &= ~(1U<<9);
/*Enable RTC Clock*/
RCC->BDCR |= (1U<<15);
/*Disable access to RTC registers*/
RCC->APB1ENR1 &= ~(1U<<28);
}
void RTC_Init(void)
{
/* Disable the write protection for RTC registers */
RTC->WPR = 0xCA;
RTC->WPR = 0x53;
/* Check if the Initialization mode is set */
if((RTC->ICSR & (1U<<6))==0)
{
/* Set the Initialization mode */
RTC->ICSR |= (1U<<7);
/* Wait till RTC is in INIT state*/
while((RTC->ICSR & (1U<<6))==0);
}
/* Clear RTC_CR FMT, OSEL, POL and TAMPOE Bits */
RTC->CR &= ~(1U<<6); //FMT
RTC->CR &= ~(1U<<20); //POL
RTC->CR &= ~(1U<<21); //OSEL
RTC->CR &= ~(1U<<22); //OSEL
RTC->CR &= ~(1U<<26); //TAMPOE
/* Set RTC_CR register */
RTC->CR &= ~(1U<<6); //FMT bit set as Zero,Hour Format Selected as 24
RTC->CR &= ~(1U<<20); //POL bit set as Zero, Output polarity selected as high.
RTC->CR &= ~(1U<<21); //OSEL[22:21] set as zero, output selection disabled.
RTC->CR &= ~(1U<<22);
/* Configure the RTC PRER */
RTC->PRER = 0xFF; // Synchronus value set as 255
RTC->PRER |= (0x7F<<16); // Asynchronus value set as 127.
/* Exit Initialization mode */
RTC->ICSR &= ~(1U<<7); // Clear INIT bit.
/* Clear RTC_CR TAMPALRM_PU, TAMPALRM_TYPE and OUT2EN Bits */
RTC->CR &= ~(1U<<29);
RTC->CR &= ~(1U<<30);
RTC->CR &= ~(1U<<31);
/*Set Output type as open drain pullup*/
RTC->CR |= (1U<<30);
/* Enable the write protection for RTC registers */
RTC->WPR = 0xFF;
}
void RTC_DeactivateWakeUpTimer(void)
{
/*Disable Write protection for RTC Registers*/
RTC->WPR = 0xCA;
RTC->WPR = 0x53;
/*Disable the Wakeup Timer*/
RTC->CR &= ~(1U<<10);
/*In case of interrupt mode is used, the interrupt source must disabled*/
RTC->CR &= ~(1U<<14);
/* Wait till RTC WUTWF flag is set */
while ((RTC->ICSR & (1U<<2)) == 0);
/* Enable the write protection for RTC registers */
RTC->WPR = 0xFF;
}
void RTC_SetWakeUpTimer_IT(uint32_t RTC_WAKEUP_TIME_IN_SECONDS,uint32_t WakeUpAutoClr)
{
/* Disable the write protection for RTC registers */
RTC->WPR = 0xCA;
RTC->WPR = 0x53;
/* Clear WUTE in RTC_CR to disable the wakeup timer */
RTC->CR &= ~(1U<<10);
/* Clear flag Wake-Up */
RTC->SCR = (1U<<2);
/* Poll WUTWF until it is set in RTC_ICSR to make sure the access to wakeup autoreload
counter and to WUCKSEL[2:0] bits is allowed. */
if((RTC->ICSR & (1U<<6))==0)
{
while((RTC->ICSR & (1U<<2))==0);
}
/* Configure the Wakeup Timer counter and auto clear value */
RTC->WUTR |= (RTC_WAKEUP_TIME_IN_SECONDS-1);
RTC->WUTR |= (WakeUpAutoClr<<16);
/* Configure the clock source */
RTC->CR &= ~(1U<<0);
RTC->CR &= ~(1U<<1);
RTC->CR |= (1U<<2);
/* RTC WakeUpTimer EXTI Configuration: Interrupt configuration */
EXTI->IMR1 |= (1U<<20);
EXTI->RTSR1 |= (1U<<20);
/* Configure the Interrupt in the RTC_CR register */
RTC->CR |= (1U<<14);
/* Enable the Wakeup Timer */
RTC->CR |= (1U<<10);
/* Enable the write protection for RTC registers */
RTC->WPR = 0xFF;
NVIC_EnableIRQ(RTC_WKUP_IRQn);
}
void RTC_WKUP_IRQHandler(void)
{
EXTI->PR1 = (1U<<20);
if((RTC->MISR & (1U<<2))!=0)
{
RTC->SCR |= (1U<<2);
}
}
void LedConfig(void)
{
RCC->AHB2ENR |= (1U<<1);
GPIOB->MODER |= (1U<<26);
GPIOB->MODER &= ~(1U<<27);
}
void PWR_EnterStopMode()
{
/* Stop 1 mode with Low-Power Regulator */
PWR->CR1 |= (1U<<0);
PWR->CR1 &= ~(1U<<1);
PWR->CR1 &= ~(1U<<2);
/* Set SLEEPDEEP bit of Cortex System Control Register */
SCB->SCR |= (1U<<2);
/* Request Wait For Interrupt */
__WFI();
/* Reset SLEEPDEEP bit of Cortex System Control Register */
SCB->SCR &= ~(1U<<2);
}
void Tim6Config(void)
{
RCC->APB1ENR1 |= (1U<<4); // Timer 6 enabled.
TIM6->PSC = 4-1; // Prescaler Value;
TIM6->ARR = 0xFFFF; // Auto Reload Value.
TIM6->CR1 |= (1U<<0); // Enable Counter.
while (!(TIM6->SR & (1U<<0))); // Wait until Update interrupt flag to be set.
}
void Delay_ms(uint16_t ms)
{
for(uint16_t i=0;i<ms;i++)
{
TIM6->CNT = 0;
while(TIM6->CNT < 1000);
}
}
Solved! Go to Solution.
2023-01-31 01:49 AM
The issue is solved, before setting values to RTC_WUTR register we have to set the register to zero since its reset value is 0x0000FFFF. Once I done that my interrupt started to working.
2023-01-31 01:49 AM
The issue is solved, before setting values to RTC_WUTR register we have to set the register to zero since its reset value is 0x0000FFFF. Once I done that my interrupt started to working.