Hi,
I encountered an issue with the STM32/LLD/RTCv1 driver when setting a new date/time.
The issue can be reproduced by first setting a new date using the rtcSetTime() function (which calls rtc_lld_set_time() ) and immediately reading the new value using rtcGetTime() (which calls rtc_lld_get_time() ). The RTC driver should wait until the write process is completed and the registers are valid before reading. There is already a function rtc_wait_write_completed() doing just what it says, but in the certain case it will not be called between the write and read access.
Note that this process is not completely deterministic since the registers might be updated right in time and everything is fine. Repeating the test multiple times should reveal the issue.
rtc_lld_set_time() calls rtc_acquire_access() before writing the new values to the registers and releases it afterwards (rtc_release_access() ). rtc_acquire_access() waits for the last write to complete by calling rtc_wait_write_completed() before setting the CNF bit, whereas rtc_release_access() does not wait afterwards. I think this is just how it should be so no time is wasted after each access, but note that the registers are not valid for reading when rtc_lld_set_time() returns.
When calling rtc_lld_get_time() now, it will not call rtc_acquire_access() again, since there should be no mutual exclusion for reading. Hence rtc_wait_write_completed() is not called implicitly. Unfortunately it is not called at all which causes the function to read possibly invalid values.
Adding an additional call of rtc_wait_write_completed() in rtcSTM32GetSecMSec() (which is called by rtc_lld_get_time() ) solved the issue for me. For some reason I am unable to attach a file with the diff, so I post it just below.
Best regards,
Thomas
diff --git a/os/hal/ports/STM32/LLD/RTCv1/rtc_lld.c b/os/hal/ports/STM32/LLD/RTCv1/rtc_lld.c
index d318a92..b1a0106 100644
--- a/os/hal/ports/STM32/LLD/RTCv1/rtc_lld.c
+++ b/os/hal/ports/STM32/LLD/RTCv1/rtc_lld.c
@@ -399,6 +399,9 @@ void rtcSTM32GetSecMsec(RTCDriver *rtcp, uint32_t *tv_sec, uint32_t *tv_msec) {
/* Required because access to CNT and DIV.*/
rtc_apb1_sync();
+ /* wait for previous write accesses to complete */
+ rtc_wait_write_completed();
+
/* Loops until two consecutive read returning the same value.*/
do {
*tv_sec = ((uint32_t)(rtcp->rtc->CNTH) << 16) + rtcp->rtc->CNTL;
STM32 RTCv1 not syncing corretly Topic is solved
- Giovanni
- Site Admin
- Posts: 14455
- Joined: Wed May 27, 2009 8:48 am
- Location: Salerno, Italy
- Has thanked: 1076 times
- Been thanked: 922 times
- Contact:
- Giovanni
- Site Admin
- Posts: 14455
- Joined: Wed May 27, 2009 8:48 am
- Location: Salerno, Italy
- Has thanked: 1076 times
- Been thanked: 922 times
- Contact:
Re: STM32 RTCv1 not syncing corretly
Hi,
I committed the change, could you confirm everything is as expected?
Giovanni
I committed the change, could you confirm everything is as expected?
Giovanni
- Giovanni
- Site Admin
- Posts: 14455
- Joined: Wed May 27, 2009 8:48 am
- Location: Salerno, Italy
- Has thanked: 1076 times
- Been thanked: 922 times
- Contact:
Who is online
Users browsing this forum: No registered users and 13 guests