@@ -190,6 +190,7 @@ safe_mode_t port_init(void) {
190190 _hrtc .Init .OutPut = RTC_OUTPUT_DISABLE ;
191191
192192 HAL_RTC_Init (& _hrtc );
193+ HAL_RTCEx_EnableBypassShadow (& _hrtc );
193194 HAL_NVIC_EnableIRQ (RTC_Alarm_IRQn );
194195
195196 // Turn off SysTick
@@ -328,9 +329,23 @@ volatile uint32_t cached_date = 0;
328329volatile uint32_t seconds_to_minute = 0 ;
329330volatile uint32_t cached_hours_minutes = 0 ;
330331uint64_t port_get_raw_ticks (uint8_t * subticks ) {
331- uint32_t subseconds = rtc_clock_frequency - (uint32_t )(RTC -> SSR );
332+ // Disable IRQs to ensure we read all of the RTC registers as close in time as possible. Read
333+ // SSR twice to make sure we didn't read across a tick.
334+ __disable_irq ();
335+ uint32_t first_ssr = (uint32_t )(RTC -> SSR );
332336 uint32_t time = (uint32_t )(RTC -> TR & RTC_TR_RESERVED_MASK );
333337 uint32_t date = (uint32_t )(RTC -> DR & RTC_DR_RESERVED_MASK );
338+ uint32_t ssr = (uint32_t )(RTC -> SSR );
339+ while (ssr != first_ssr ) {
340+ first_ssr = ssr ;
341+ time = (uint32_t )(RTC -> TR & RTC_TR_RESERVED_MASK );
342+ date = (uint32_t )(RTC -> DR & RTC_DR_RESERVED_MASK );
343+ ssr = (uint32_t )(RTC -> SSR );
344+ }
345+ __enable_irq ();
346+
347+ uint32_t subseconds = rtc_clock_frequency - 1 - ssr ;
348+
334349 if (date != cached_date ) {
335350 uint32_t year = (uint8_t )((date & (RTC_DR_YT | RTC_DR_YU )) >> 16U );
336351 uint8_t month = (uint8_t )((date & (RTC_DR_MT | RTC_DR_MU )) >> 8U );
@@ -349,6 +364,7 @@ uint64_t port_get_raw_ticks(uint8_t* subticks) {
349364 hours = (uint8_t )RTC_Bcd2ToByte (hours );
350365 minutes = (uint8_t )RTC_Bcd2ToByte (minutes );
351366 seconds_to_minute = 60 * (60 * hours + minutes );
367+ cached_hours_minutes = hours_minutes ;
352368 }
353369 uint8_t seconds = (uint8_t )(time & (RTC_TR_ST | RTC_TR_SU ));
354370 seconds = (uint8_t )RTC_Bcd2ToByte (seconds );
0 commit comments