@@ -190,6 +190,7 @@ safe_mode_t port_init(void) {
190
190
_hrtc .Init .OutPut = RTC_OUTPUT_DISABLE ;
191
191
192
192
HAL_RTC_Init (& _hrtc );
193
+ HAL_RTCEx_EnableBypassShadow (& _hrtc );
193
194
HAL_NVIC_EnableIRQ (RTC_Alarm_IRQn );
194
195
195
196
// Turn off SysTick
@@ -328,9 +329,23 @@ volatile uint32_t cached_date = 0;
328
329
volatile uint32_t seconds_to_minute = 0 ;
329
330
volatile uint32_t cached_hours_minutes = 0 ;
330
331
uint64_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 );
332
336
uint32_t time = (uint32_t )(RTC -> TR & RTC_TR_RESERVED_MASK );
333
337
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
+
334
349
if (date != cached_date ) {
335
350
uint32_t year = (uint8_t )((date & (RTC_DR_YT | RTC_DR_YU )) >> 16U );
336
351
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) {
349
364
hours = (uint8_t )RTC_Bcd2ToByte (hours );
350
365
minutes = (uint8_t )RTC_Bcd2ToByte (minutes );
351
366
seconds_to_minute = 60 * (60 * hours + minutes );
367
+ cached_hours_minutes = hours_minutes ;
352
368
}
353
369
uint8_t seconds = (uint8_t )(time & (RTC_TR_ST | RTC_TR_SU ));
354
370
seconds = (uint8_t )RTC_Bcd2ToByte (seconds );
0 commit comments