cancel
Showing results for 
Search instead for 
Did you mean: 

Interrupt on RTC Alarm

new
Associate II
Posted on September 11, 2012 at 15:27

Hi guys,

I'm trying to get the RTC alarm to cause an interrupt on an STM32F101 but I'm having issues. The RTC is running but the interrupt doesn't seem to be being triggered.

I'd be very grateful if anyone could help me with the code below. But if there is a simple code sample somewhere that would be very useful. The examples I've found so far, seem to match my code, but are also heavy integrated into larger frameworks.

This is the code I'm using to do the configuration:

typedef struct rtc_reg_map {

    __io uint32 CRH;            /**< Control register high */

    __io uint32 CRL;            /**< Control register low */

    __io uint32 PRLH;           /**< Prescaler load register high */

    __io uint32 PRLL;           /**< Prescaler load register low */

    __io uint32 DIVH;           /**< Prescaler divider register high */

    __io uint32 DIVL;           /**< Prescaler divider register low */

    __io uint32 CNTH;           /**< Counter register high */

    __io uint32 CNTL;           /**< Counter register low */

    __io uint32 ALRH;           /**< Alarm register high */

    __io uint32 ALRL;           /**< Alarm register low */

} rtc_reg_map;

/** RTC register map base pointer */

#define RTC_BASE                       ((struct rtc_reg_map*)0x40002800)

rtc_dev *RTC;

rtc_dev = RTC_BASE;

void rtoff_wait(rtc_dev *dev) {

  dev->regs->CRL &= (uint16)~RTC_CRL_RSF;

  while(!(dev->regs->CRL & RTC_CRL_RTOFF));

}

// configure the alarm

bkp_enable_writes();

rtoff_wait(dev);

for(;((RTC->CRL & RTC_CRL_CNF) == 0);) RTC->CRL |= RTC_CRL_CNF;

rtoff_wait(dev);

RTC->regs->ALRH = (uint16) 0;

rtoff_wait(dev);

RTC->regs->ALRL = (uint16) 10;

rtoff_wait(dev);

RTC->CRL &= ~RTC_CRL_CNF;

rtoff_wait(dev);

bkp_disable_writes();

// enable the interrupt

bkp_enable_writes();

rtoff_wait(dev);

RTC->CRH = 0x3;

rtoff_wait(dev);

bkp_disable_writes();

I then have an interrupt handler in the NVIC table. I've also tried enabling the interrupt in the NVIC ISER, but this doesn't seem to help. In fact when I enable the RTC interrupt the system hangs.
4 REPLIES 4
Posted on September 11, 2012 at 15:55

But if there is a simple code sample somewhere that would be very useful.

STM32F10x_StdPeriph_Lib_V3.5.0\Project\STM32F10x_StdPeriph_Examples\PWR\STOP\main.c

In fact when I enable the RTC interrupt the system hangs.

An unserviced/cleared interrupt will result in an interrupt storm. The processor will continually tail-chain back into the routines, and no foreground code will run.

A bad or missing service routine in the vector table will typically result in a Hard Fault, and being stuck in a while(1) loop.

A debugger should permit you to identify where it is ''hanging'' up.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
new
Associate II
Posted on September 13, 2012 at 12:50

Thanks!

Couple of things I don't understand in that example, it appears to use the following to clear the interrupt:

/* Clear EXTI line17 pending bit */

EXTI_ClearITPendingBit(EXTI_Line17);

RTC_ClearITPendingBit(RTC_IT_ALR);

Firstly, I thought the RTC alarm went though the NVIC directly, not via exti? Though I guess I'm mistaken. Secondly, digging around in RTC_ClearITPendingBit seems to indicate that it sets a bit in RTC_CRL which from the documentation is said to be readonly.

I've worked on the code a bit more, and by disabling the interrupt in the NVIC, the interrupt will return, but it seems to trigger multiple times before returning.

I'm also currently handling IRQ_RTC rather than IRQ_RTCALARM, what's the difference between these? IRQ_RTC seems to be triggered by the alarm.

Thanks again for your help.

Posted on September 13, 2012 at 14:23

The EXTI relates mostly to the lower power modes, where other portions of the design are not powered and/or clocked.

Do you mean reserved, or read-only? The clearing function merely masks certain bits to zero, and leaves others alone, which might be preferable seeing a writing '1' is a do-nothing operation for many of the bits. The library, thankfully, shields a lot of the register level minutia.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
new
Associate II
Posted on September 13, 2012 at 16:14

gah, I was being stupid. Yep, the documentation says ''Writing ‘1’ has no effect.'', but not writing 0 of course. I also couldn't see anywhere stating it must be cleared in the interrupt in RM0041. But thanks I understand now.

Yes, I guess the STM32 library helps a lot. Unfortunately by project is based on libmaple, which is missing RTC functionally so I'm forced to operate at the register level for this.

Thanks again, your help has been very useful.