cancel
Showing results for 
Search instead for 
Did you mean: 

Don't understand behaviour of RTC_AlarmCmd()

mk299
Associate III
Posted on May 09, 2013 at 22:05

I'm using the RTC on an STM32L151CB and at some point I'd like to disable both alarms and update alarm A. I'm using the following code which doesn't work:

RTC_AlarmCmd(RTC_Alarm_A | RTC_Alarm_B, DISABLE);
RTC_SetAlarm(RTC_Format_BIN, RTC_Alarm_A, &Alarm);
RTC_AlarmCmd(RTC_Alarm_A, ENABLE);

The alarm won't be updated this way. It works when I insert some kind of delay functionality before RTC_SetAlarm, or when I disable one alarm after the other, like:

RTC_AlarmCmd(RTC_Alarm_A, DISABLE);
RTC_AlarmCmd(RTC_Alarm_B, DISABLE);
RTC_SetAlarm(RTC_Format_BIN, RTC_Alarm_A, &Alarm);
RTC_AlarmCmd(RTC_Alarm_A, ENABLE);

Does someone have an idea what could cause this? #stm32l1-rtc-alarm
3 REPLIES 3
infoinfo980
Associate II
Posted on May 10, 2013 at 17:47

The RTC core is independent from the MCU bus. After writing to an RTC register you need to wait for that write to complete. In the reference manual, see:

Reading RTC registers

 

Configuring RTC registers

The std peripheral library provides functions like RTC_WaitForLastTask() and RTC_WaitForSynchro() to handle this for you, and the example projects show how to use them.

Regards,

- Andy

mk299
Associate III
Posted on May 21, 2013 at 21:28

Thanks for pointing me to that, as that really was the problem. For the STM32Lxxx there is no RTC_WaitForLastTask(), but the RTC_WaitForSynchro() exists and helps.

Interestingly it seems that it has to be added very often and at places that are not documented anywhere and I don't understand why. E.g.

RTC_WaitForSynchro(); // 1.

RTC_GetDate(RTC_Format_BIN, &Date);
RTC_WaitForSynchro(); // 2.

RTC_GetTime(RTC_Format_BIN, &Time);

Without the second call of RTC_WaitForSynchro() a wrong date is read back.

RTC_WaitForSynchro(); // 1.

RTC_AlarmCmd(RTC_Alarm_A | RTC_Alarm_B, DISABLE);
RTC_WaitForSynchro(); // 2.

RTC_SetAlarm(RTC_Format_BIN, RTC_Alarm_A, &Alarm);
RTC_WaitForSynchro(); // 3.

RTC_AlarmCmd(RTC_Alarm_A, ENABLE);

It seems that the third call of RTC_WaitForSynchro() is not necessary, but the other two are mandatory. It is surprising me that this is not done inside the peripheral drivers and that it isn't documented anywhere how to use it correctly. Maybe I'm doing something generally wrong, but my code is based on the peripheral examples, so I have no clue what. If there are more suggestions I'd greatly appreciate it.
infoinfo980
Associate II
Posted on May 24, 2013 at 17:33

I don't have the library sources to hand right now but I'd suspect that what's happening where you are seeing synchro as un-necessary is that the following call modifies a different register to the previous one, thereby not requiring the synchro call.

Remember that what the synchro call does is block until it's sure that the RTC peripheral has picked up the register write that you (or the library) made.