mirror of
https://github.com/RT-Thread/rt-thread.git
synced 2026-02-04 21:11:40 +00:00
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.
This commit is contained in:
@@ -10,6 +10,7 @@
|
||||
* 2021-02-05 Meco Man fix the problem of mixing local time and UTC time
|
||||
* 2021-07-05 iysheng implement RTC framework V2.0
|
||||
* 2025-06-05 RCSN add local time conversion for get timeval and set stamp
|
||||
* 0206-02-03 wdfk_prog compute tv_usec from SecondFraction/SubSeconds
|
||||
*/
|
||||
|
||||
#include "board.h"
|
||||
@@ -85,10 +86,30 @@ static rt_err_t stm32_rtc_get_timeval(struct timeval *tv)
|
||||
#else
|
||||
tv->tv_sec = timegm(&tm_new);
|
||||
#endif
|
||||
#if defined(SOC_SERIES_STM32H7)
|
||||
tv->tv_usec = (255.0 - RTC_TimeStruct.SubSeconds * 1.0) / 256.0 * 1000.0 * 1000.0;
|
||||
#endif
|
||||
|
||||
tv->tv_usec = 0U;
|
||||
/* F1 RTC does not have SSR/PRER */
|
||||
#if defined(RTC_SSR_SS) && defined(RTC_PRER_PREDIV_S)
|
||||
/*
|
||||
* You can use SubSeconds and SecondFraction (sTime structure fields
|
||||
* returned) to convert SubSeconds value in second fraction ratio with
|
||||
* time unit following generic formula:
|
||||
* Second fraction ratio * time_unit =
|
||||
* [(SecondFraction - SubSeconds) / (SecondFraction + 1)] * time_unit
|
||||
* This conversion can be performed only if no shift operation is pending
|
||||
* (ie. SHFP=0) when PREDIV_S >= SS
|
||||
*/
|
||||
#if defined(RTC_ISR_SHPF)
|
||||
if (READ_BIT(RTC->ISR, RTC_ISR_SHPF) == 0U)
|
||||
#endif /* RTC_ISR_SHPF */
|
||||
{
|
||||
uint32_t sf = RTC_TimeStruct.SecondFraction;
|
||||
uint32_t ss = RTC_TimeStruct.SubSeconds;
|
||||
if ((sf != 0U) && (ss <= sf))
|
||||
{
|
||||
tv->tv_usec = (uint32_t)(((sf - ss) * 1000000ULL) / (sf + 1U));
|
||||
}
|
||||
}
|
||||
#endif /* defined(RTC_SSR_SS) && defined(RTC_PRER_PREDIV_S) */
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user