3535 */
3636
3737#include "rtc.h"
38+ #include <string.h>
3839
3940#if defined(STM32_CORE_VERSION ) && (STM32_CORE_VERSION > 0x01090000 ) && \
4041 defined(HAL_RTC_MODULE_ENABLED ) && !defined(HAL_RTC_MODULE_ONLY )
@@ -367,17 +368,36 @@ void RTC_init(hourFormat_t format, sourceClock_t source, bool reset)
367368 RtcHandle .Init .OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN ;
368369#endif /* STM32F1xx */
369370
371+ /* Ensure backup domain is enabled before we init the RTC so we can use the backup registers for date retention on stm32f1xx baords */
372+ enableBackupDomain ();
373+
370374 HAL_RTC_Init (& RtcHandle );
371375
376+ #if defined(STM32F1xx )
377+ // Copy RTC date back out of the BackUp registers
378+ uint32_t BackupDate ;
379+ /* date from backup battery was not reset, load it */
380+ if (!reset ) {
381+ BackupDate = getBackupRegister (RTC_BKP_DATE ) << 16 ;
382+ BackupDate |= getBackupRegister (RTC_BKP_DATE + 1 ) & 0xFFFF ;
383+ if (BackupDate != 0 ) {
384+ /* cannot force the date to be 0 but 1/1/2000 is the reset value, always */
385+ memcpy (& RtcHandle .DateToUpdate , & BackupDate , 4 );
386+ /* and fill the new RTC Date value */
387+ RTC_SetDate (RtcHandle .DateToUpdate .Year , RtcHandle .DateToUpdate .Month ,
388+ RtcHandle .DateToUpdate .Date , RtcHandle .DateToUpdate .WeekDay );
389+ }
390+ }
391+ RTC_StoreDate ();
392+ #endif /* STM32F1xx */
393+
372394#if defined(RTC_CR_BYPSHAD )
373395 /* Enable Direct Read of the calendar registers (not through Shadow) */
374396 HAL_RTCEx_EnableBypassShadow (& RtcHandle );
375397#endif
376398
377399 HAL_NVIC_SetPriority (RTC_Alarm_IRQn , RTC_IRQ_PRIO , RTC_IRQ_SUBPRIO );
378400 HAL_NVIC_EnableIRQ (RTC_Alarm_IRQn );
379- /* Ensure backup domain is enabled */
380- enableBackupDomain ();
381401}
382402
383403/**
@@ -460,6 +480,12 @@ void RTC_GetTime(uint8_t *hours, uint8_t *minutes, uint8_t *seconds, uint32_t *s
460480 RTC_TimeTypeDef RTC_TimeStruct ;
461481
462482 if ((hours != NULL ) && (minutes != NULL ) && (seconds != NULL )) {
483+ #if defined(STM32F1xx )
484+ /* Store the date prior to checking the time, this may roll over to the next day as part of the time check,
485+ we need to the new date details in the backup registers if it changes */
486+ uint8_t current_date = RtcHandle .DateToUpdate .Date ;
487+ #endif
488+
463489 HAL_RTC_GetTime (& RtcHandle , & RTC_TimeStruct , RTC_FORMAT_BIN );
464490 * hours = RTC_TimeStruct .Hours ;
465491 * minutes = RTC_TimeStruct .Minutes ;
@@ -482,6 +508,10 @@ void RTC_GetTime(uint8_t *hours, uint8_t *minutes, uint8_t *seconds, uint32_t *s
482508#else
483509 UNUSED (period );
484510 UNUSED (subSeconds );
511+
512+ if (current_date != RtcHandle .DateToUpdate .Date ) {
513+ RTC_StoreDate ();
514+ }
485515#endif /* !STM32F1xx */
486516 }
487517}
@@ -505,6 +535,9 @@ void RTC_SetDate(uint8_t year, uint8_t month, uint8_t day, uint8_t wday)
505535 RTC_DateStruct .WeekDay = wday ;
506536 HAL_RTC_SetDate (& RtcHandle , & RTC_DateStruct , RTC_FORMAT_BIN );
507537 setBackupRegister (RTC_BKP_INDEX , RTC_BKP_VALUE );
538+ #if defined(STM32F1xx )
539+ RTC_StoreDate ();
540+ #endif /* STM32F1xx */
508541 }
509542}
510543
@@ -526,6 +559,9 @@ void RTC_GetDate(uint8_t *year, uint8_t *month, uint8_t *day, uint8_t *wday)
526559 * month = RTC_DateStruct .Month ;
527560 * day = RTC_DateStruct .Date ;
528561 * wday = RTC_DateStruct .WeekDay ;
562+ #if defined(STM32F1xx )
563+ RTC_StoreDate ();
564+ #endif /* STM32F1xx */
529565 }
530566}
531567
@@ -834,6 +870,17 @@ void RTC_WKUP_IRQHandler(void)
834870#endif /* STM32F1xx */
835871#endif /* ONESECOND_IRQn */
836872
873+ #if defined(STM32F1xx )
874+ void RTC_StoreDate (void )
875+ {
876+ /* Store the date in the backup registers */
877+ uint32_t dateToStore ;
878+ memcpy (& dateToStore , & RtcHandle .DateToUpdate , 4 );
879+ setBackupRegister (RTC_BKP_DATE , dateToStore >> 16 );
880+ setBackupRegister (RTC_BKP_DATE + 1 , dateToStore & 0xffff );
881+ }
882+ #endif
883+
837884#ifdef __cplusplus
838885}
839886#endif
0 commit comments