cancel
Showing results for 
Search instead for 
Did you mean: 

STM32 RTC Wakeup interrupt not working?

SSaiy.1
Associate III

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);

}

}

1 ACCEPTED SOLUTION

Accepted Solutions
SSaiy.1
Associate III

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.

View solution in original post

1 REPLY 1
SSaiy.1
Associate III

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.