Skip to content

Commit 8d61abf

Browse files
committed
store and retrieve the RTC Date into backup reg on stm32F1
The stm32F1 RTC date value are read/write from/to a BackUp register : RTC_BKP_DATE The BackUp register DR6 is choosen and can be changed easily, with a not-already-used one. The stm32F1 has 16bit backup reg. : 2 consecutive addresses are reserved. Signed-off-by: Francois Ramu <[email protected]>
1 parent 04f5706 commit 8d61abf

File tree

2 files changed

+63
-2
lines changed

2 files changed

+63
-2
lines changed

src/rtc.c

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
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

src/rtc.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,16 @@ typedef enum {
7777
typedef void(*voidCallbackPtr)(void *);
7878

7979
/* Exported constants --------------------------------------------------------*/
80+
81+
#if defined(STM32F1xx)
82+
/* select 32 bits in backup memory to store date.
83+
2 consecutive 16bit reg. are reserved: RTC_BKP_DATE & RTC_BKP_DATE + 1 */
84+
#if !defined(RTC_BKP_DATE)
85+
/* can be changed for your convenience (here : LL_RTC_BKP_DR6 & LL_RTC_BKP_DR7) */
86+
#define RTC_BKP_DATE LL_RTC_BKP_DR6
87+
#endif
88+
#endif /* STM32F1xx */
89+
8090
/* Interrupt priority */
8191
#ifndef RTC_IRQ_PRIO
8292
#define RTC_IRQ_PRIO 2
@@ -188,6 +198,10 @@ void attachSecondsIrqCallback(voidCallbackPtr func);
188198
void detachSecondsIrqCallback(void);
189199
#endif /* ONESECOND_IRQn */
190200

201+
#if defined(STM32F1xx)
202+
void RTC_StoreDate(void);
203+
#endif
204+
191205
#ifdef __cplusplus
192206
}
193207
#endif

0 commit comments

Comments
 (0)