cinterruptcortex-mreal-time-clockstm32f1

How to trigger RTC global interrupt on stm32f103 blue pill


I am trying to use the RTC global interrupt for the stm32f103c8t6, but I have had no luck.

I am not sure if this is an issue with my configuration, or if the RTC global interrupt handler is not used for the second interrupt at all. I have been scouring through the reference manual, but I have not been able to find what exactly triggers the "RTC global interrupt", as it is referred to.

Regardless, I am able to see that the second flag is being set, by checking it manually. Which is the commented section in the main below, the code toggles an LED when the second flag is set.

int main(void)
{
    initGPIO(C, 13, OUTPUT50, GP_PP);
    initRTC();

    while(1){
        // if (RTC->CRL & (1<<0)) {
        //  RTC->CRL &= ~(1<<0);
        //  toggleGPIO(C,13);
        // }
    }
}

However, when this code is commented, and I rely on my interrupt handler, nothing happens. I know that my handler is being placed in the right place in memory, as per my .elf file (0x80004c is the right place for the RTC global interrupt), shown below.

Disassembly of section .text:

08000000 <vectors>:
 8000000:   20005000    andcs   r5, r0, r0
 8000004:   08000ea9    stmdaeq r0, {r0, r3, r5, r7, r9, sl, fp}
    ...
 800003c:   08000f09    stmdaeq r0, {r0, r3, r8, r9, sl, fp}
    ...
 800004c:   08000f19    stmdaeq r0, {r0, r3, r4, r8, r9, sl, fp}

I am configuring the RTC like this:

void initRTC(void)
{
    RCC->APB1ENR |= 0x18000000; // enable PWR and BKP clocks
    PWR->CR |= 0x100; // enable access to RTC and BKP register

    RCC->BDCR |= 1; // enable LSE
    while(!(RCC->BDCR & 0x2)){} // wait on LSE clock
    RCC->BDCR |= 0x8100; // enable RTC and select clock

    // RTC config sequence
    while((RTC->CRL & 0x20) == 0) {}
    RTC->CRL |= 0x0010; // put into config mode
    RTC->CRL &= ~(1<<0); // clear second flag
    RTC->PRLH |= 0x0000;
    RTC->PRLL |= 0x7FFF; // set prescaler value
    RTC->CRH |= 0x0001; // enable second interrupt
    RTC->CRL &= ~(1<<4); // take out of config mode
    while((RTC->CRL & 0x20) == 0) {}
}

And my handler looks like:

void RTC_Handler(void)
{
  RTC->CRL &= ~(1<<0);
  toggleGPIO(C, 13);
}

The rest of my code is here.


Solution

    1. Magic numbers - never use them. Use human readable CMIS definitions.
    2. You never enable the interrupt in the NVIC controller, so it is disabled. Use NVIC functions from the CMSIS package for that. You will avoid many errors.

    There is more than then Reference Manual needed. To understand the core and core peripheral system you need to read the programming manual as well https://www.st.com/resource/en/programming_manual/pm0056-stm32f10xxx20xxx21xxxl1xxxx-cortexm3-programming-manual-stmicroelectronics.pdf