Skip to content

Commit f9de290

Browse files
wdfk-progRbb666
authored andcommitted
fix[STM32][RTC]: Compute tv_usec from SecondFraction/SubSeconds and skip during shift pending
Use the generic SecondFraction/SubSeconds formula when SSR/PRER are available. If SHPF is present and a shift is pending, keep tv_usec at 0. Platforms without SSR/PRER (e.g. F1) default to 0.
1 parent 06e829b commit f9de290

File tree

1 file changed

+25
-4
lines changed
  • bsp/stm32/libraries/HAL_Drivers/drivers

1 file changed

+25
-4
lines changed

bsp/stm32/libraries/HAL_Drivers/drivers/drv_rtc.c

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
* 2021-02-05 Meco Man fix the problem of mixing local time and UTC time
1111
* 2021-07-05 iysheng implement RTC framework V2.0
1212
* 2025-06-05 RCSN add local time conversion for get timeval and set stamp
13+
* 0206-02-03 wdfk_prog compute tv_usec from SecondFraction/SubSeconds
1314
*/
1415

1516
#include "board.h"
@@ -85,10 +86,30 @@ static rt_err_t stm32_rtc_get_timeval(struct timeval *tv)
8586
#else
8687
tv->tv_sec = timegm(&tm_new);
8788
#endif
88-
#if defined(SOC_SERIES_STM32H7)
89-
tv->tv_usec = (255.0 - RTC_TimeStruct.SubSeconds * 1.0) / 256.0 * 1000.0 * 1000.0;
90-
#endif
91-
89+
tv->tv_usec = 0U;
90+
/* F1 RTC does not have SSR/PRER */
91+
#if defined(RTC_SSR_SS) && defined(RTC_PRER_PREDIV_S)
92+
/*
93+
* You can use SubSeconds and SecondFraction (sTime structure fields
94+
* returned) to convert SubSeconds value in second fraction ratio with
95+
* time unit following generic formula:
96+
* Second fraction ratio * time_unit =
97+
* [(SecondFraction - SubSeconds) / (SecondFraction + 1)] * time_unit
98+
* This conversion can be performed only if no shift operation is pending
99+
* (ie. SHFP=0) when PREDIV_S >= SS
100+
*/
101+
#if defined(RTC_ISR_SHPF)
102+
if (READ_BIT(RTC->ISR, RTC_ISR_SHPF) == 0U)
103+
#endif /* RTC_ISR_SHPF */
104+
{
105+
uint32_t sf = RTC_TimeStruct.SecondFraction;
106+
uint32_t ss = RTC_TimeStruct.SubSeconds;
107+
if ((sf != 0U) && (ss <= sf))
108+
{
109+
tv->tv_usec = (uint32_t)(((sf - ss) * 1000000ULL) / (sf + 1U));
110+
}
111+
}
112+
#endif /* defined(RTC_SSR_SS) && defined(RTC_PRER_PREDIV_S) */
92113
return RT_EOK;
93114
}
94115

0 commit comments

Comments
 (0)