2013-05-09 01:05 PM
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
2013-05-10 08:47 AM
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 registersConfiguring RTC registersThe 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
2013-05-21 12:28 PM
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.
2013-05-24 08:33 AM
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.