Skip to content

[Enhancement] Add date retention functionality for STM32F1xx based boards #41

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 12 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 58 additions & 3 deletions src/rtc.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@
*
******************************************************************************
*/

#include "rtc.h"
#include <string.h>

#if defined(STM32_CORE_VERSION) && (STM32_CORE_VERSION > 0x01090000) &&\
defined(HAL_RTC_MODULE_ENABLED) && !defined(HAL_RTC_MODULE_ONLY)
Expand Down Expand Up @@ -346,17 +346,45 @@ void RTC_init(hourFormat_t format, sourceClock_t source, bool reset)
RtcHandle.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;
#endif /* STM32F1xx */

/* Ensure backup domain is enabled before we init the RTC so we can use the backup registers for date retention on stm32f1xx baords */
enableBackupDomain();

HAL_RTC_Init(&RtcHandle);

#if defined(STM32F1xx)
// Copy date data back out of the BackUp registers
RTC_DateTypeDef BackupDate;
RTC_TimeTypeDef DummyTime;
uint32_t dateMem;
dateMem = HAL_RTCEx_BKUPRead(&RtcHandle, RTC_BKP_SAVE_THE_DATE + 1);
dateMem |= HAL_RTCEx_BKUPRead(&RtcHandle, RTC_BKP_SAVE_THE_DATE) << 16;
memcpy(&BackupDate, &dateMem, sizeof(uint32_t));
if (IS_RTC_YEAR(BackupDate.Year) && IS_RTC_MONTH(BackupDate.Month) && IS_RTC_DATE(BackupDate.Date)) {
/* Change the date retrieved from the backup registers */
RtcHandle.DateToUpdate.Year = BackupDate.Year;
RtcHandle.DateToUpdate.Month = BackupDate.Month;
RtcHandle.DateToUpdate.Date = BackupDate.Date;
// Check for valid weekday separately so that if there is a problem we have still at least set the date
if (IS_RTC_WEEKDAY(BackupDate.WeekDay)) {
RtcHandle.DateToUpdate.WeekDay = BackupDate.WeekDay;
}
/* Read the time so that the date is rolled over if required */
HAL_RTC_GetTime(&RtcHandle, &DummyTime, RTC_FORMAT_BIN);
/* Store the date or it will revert again if we lose power before manually updating. */
if (BackupDate.Date != RtcHandle.DateToUpdate.Date) {
RTC_StoreDate();
}
}
#endif

#if !defined(STM32F1xx) && !defined(STM32F2xx) && !defined(STM32L1xx) || defined(STM32L1_ULPH)
/* Enable Direct Read of the calendar registers (not through Shadow) */
HAL_RTCEx_EnableBypassShadow(&RtcHandle);
#endif /* !STM32F1xx && !STM32F2xx */

HAL_NVIC_SetPriority(RTC_Alarm_IRQn, RTC_IRQ_PRIO, RTC_IRQ_SUBPRIO);
HAL_NVIC_EnableIRQ(RTC_Alarm_IRQn);
/* Ensure backup domain is enabled */
enableBackupDomain();

}

/**
Expand Down Expand Up @@ -438,6 +466,12 @@ void RTC_GetTime(uint8_t *hours, uint8_t *minutes, uint8_t *seconds, uint32_t *s
RTC_TimeTypeDef RTC_TimeStruct;

if ((hours != NULL) && (minutes != NULL) && (seconds != NULL)) {
#if defined(STM32F1xx)
/* Store the date prior to checking the time, this may roll over to the next day as part of the time check,
we need to the new date details in the backuip registers if it changes */
uint8_t current_date = RtcHandle.DateToUpdate.Date;
#endif

HAL_RTC_GetTime(&RtcHandle, &RTC_TimeStruct, RTC_FORMAT_BIN);
*hours = RTC_TimeStruct.Hours;
*minutes = RTC_TimeStruct.Minutes;
Expand All @@ -461,6 +495,13 @@ void RTC_GetTime(uint8_t *hours, uint8_t *minutes, uint8_t *seconds, uint32_t *s
UNUSED(period);
UNUSED(subSeconds);
#endif /* !STM32F1xx */

#if defined(STM32F1xx)
if (current_date != RtcHandle.DateToUpdate.Date) {
RTC_StoreDate();
}
#endif

}
}

Expand All @@ -483,6 +524,9 @@ void RTC_SetDate(uint8_t year, uint8_t month, uint8_t day, uint8_t wday)
RTC_DateStruct.WeekDay = wday;
HAL_RTC_SetDate(&RtcHandle, &RTC_DateStruct, RTC_FORMAT_BIN);
setBackupRegister(RTC_BKP_INDEX, RTC_BKP_VALUE);
#if defined(STM32F1xx)
RTC_StoreDate();
#endif
}
}

Expand Down Expand Up @@ -711,6 +755,17 @@ void RTC_Alarm_IRQHandler(void)
HAL_RTC_AlarmIRQHandler(&RtcHandle);
}

#if defined(STM32F1xx)
void RTC_StoreDate(void)
{
/* Store the date in the backup registers */
uint32_t dateToStore;
memcpy(&dateToStore, &RtcHandle.DateToUpdate, 4);
HAL_RTCEx_BKUPWrite(&RtcHandle, RTC_BKP_SAVE_THE_DATE, dateToStore >> 16);
HAL_RTCEx_BKUPWrite(&RtcHandle, RTC_BKP_SAVE_THE_DATE + 1, dateToStore & 0xffff);
}
#endif

#ifdef __cplusplus
}
#endif
Expand Down
6 changes: 6 additions & 0 deletions src/rtc.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@
#ifndef __RTC_H
#define __RTC_H

#define RTC_BKP_SAVE_THE_DATE RTC_BKP_DR2

/* Includes ------------------------------------------------------------------*/
#include <stdbool.h>
#include "stm32_def.h"
Expand Down Expand Up @@ -165,6 +167,10 @@ void RTC_GetAlarm(uint8_t *day, uint8_t *hours, uint8_t *minutes, uint8_t *secon
void attachAlarmCallback(voidCallbackPtr func, void *data);
void detachAlarmCallback(void);

#if defined(STM32F1xx)
void RTC_StoreDate(void);
#endif

#ifdef __cplusplus
}
#endif
Expand Down