diff --git a/src/STM32RTC.cpp b/src/STM32RTC.cpp index 32e24ba..9737b94 100644 --- a/src/STM32RTC.cpp +++ b/src/STM32RTC.cpp @@ -62,11 +62,19 @@ void STM32RTC::begin(bool resetTime, Hour_Format format) bool reinit; _format = format; +#if defined(RCC_RTC_WDG_BLEWKUP_CLKSOURCE_HSI64M_DIV2048) + reinit = RTC_init((format == HOUR_12) ? HOUR_FORMAT_12 : HOUR_FORMAT_24, + (_mode == MODE_MIX) ? ::MODE_BINARY_MIX : ((_mode == MODE_BIN) ? ::MODE_BINARY_ONLY : ::MODE_BINARY_NONE), + (_clockSource == LSE_CLOCK) ? ::LSE_CLOCK : + (_clockSource == HSI_CLOCK) ? ::HSI_CLOCK : ::LSI_CLOCK + , resetTime); +#else reinit = RTC_init((format == HOUR_12) ? HOUR_FORMAT_12 : HOUR_FORMAT_24, (_mode == MODE_MIX) ? ::MODE_BINARY_MIX : ((_mode == MODE_BIN) ? ::MODE_BINARY_ONLY : ::MODE_BINARY_NONE), (_clockSource == LSE_CLOCK) ? ::LSE_CLOCK : (_clockSource == HSE_CLOCK) ? ::HSE_CLOCK : ::LSI_CLOCK , resetTime); +#endif /* RCC_RTC_WDG_BLEWKUP_CLKSOURCE_HSI64M_DIV2048 */ _timeSet = !reinit; syncDate(); @@ -137,8 +145,13 @@ void STM32RTC::setClockSource(Source_Clock source, uint32_t predivA, uint32_t pr { if (IS_CLOCK_SOURCE(source)) { _clockSource = source; +#if defined(RCC_RTC_WDG_BLEWKUP_CLKSOURCE_HSI64M_DIV2048) + RTC_SetClockSource((_clockSource == LSE_CLOCK) ? ::LSE_CLOCK : + (_clockSource == HSI_CLOCK) ? ::HSI_CLOCK : ::LSI_CLOCK); +#else RTC_SetClockSource((_clockSource == LSE_CLOCK) ? ::LSE_CLOCK : (_clockSource == HSE_CLOCK) ? ::HSE_CLOCK : ::LSI_CLOCK); +#endif /* RCC_RTC_WDG_BLEWKUP_CLKSOURCE_HSI64M_DIV2048 */ } RTC_setPrediv(predivA, predivS); } diff --git a/src/STM32RTC.h b/src/STM32RTC.h index e7c9611..2981385 100644 --- a/src/STM32RTC.h +++ b/src/STM32RTC.h @@ -68,8 +68,13 @@ typedef void(*voidFuncPtr)(void *); +#if defined(RCC_RTC_WDG_BLEWKUP_CLKSOURCE_HSI64M_DIV2048) +#define IS_CLOCK_SOURCE(SRC) (((SRC) == STM32RTC::LSI_CLOCK) || ((SRC) == STM32RTC::LSE_CLOCK) ||\ + ((SRC) == STM32RTC::HSI_CLOCK)) +#else #define IS_CLOCK_SOURCE(SRC) (((SRC) == STM32RTC::LSI_CLOCK) || ((SRC) == STM32RTC::LSE_CLOCK) ||\ ((SRC) == STM32RTC::HSE_CLOCK)) +#endif /* RCC_RTC_WDG_BLEWKUP_CLKSOURCE_HSI64M_DIV2048 */ #define IS_HOUR_FORMAT(FMT) (((FMT) == STM32RTC::HOUR_12) || ((FMT) == STM32RTC::HOUR_24)) class STM32RTC { @@ -107,7 +112,11 @@ class STM32RTC { enum Source_Clock : uint8_t { LSI_CLOCK = ::LSI_CLOCK, LSE_CLOCK = ::LSE_CLOCK, +#if defined(RCC_RTC_WDG_BLEWKUP_CLKSOURCE_HSI64M_DIV2048) + HSI_CLOCK = ::HSI_CLOCK, +#else HSE_CLOCK = ::HSE_CLOCK +#endif /* RCC_RTC_WDG_BLEWKUP_CLKSOURCE_HSI64M_DIV2048 */ }; enum Alarm : uint32_t { diff --git a/src/rtc.c b/src/rtc.c index 46faf88..148a10c 100644 --- a/src/rtc.c +++ b/src/rtc.c @@ -187,16 +187,20 @@ static void RTC_initClock(sourceClock_t source) if (source == LSE_CLOCK) { /* Enable the clock if not already set by user */ enableClock(LSE_CLOCK); - +#if defined(RCC_PERIPHCLK_RTC_WDG_BLEWKUP) + PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_RTC_WDG_BLEWKUP; + PeriphClkInit.RTCWDGBLEWKUPClockSelection = RCC_RTC_WDG_BLEWKUP_CLKSOURCE_LSE; + } else if (source == HSI_CLOCK) { + /* Enable the clock if not already set by user */ + enableClock(HSI_CLOCK); + PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_RTC_WDG_BLEWKUP; + PeriphClkInit.RTCWDGBLEWKUPClockSelection = RCC_RTC_WDG_BLEWKUP_CLKSOURCE_HSI64M_DIV2048; +#else PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_RTC; PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_LSE; - if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) { - Error_Handler(); - } } else if (source == HSE_CLOCK) { /* Enable the clock if not already set by user */ enableClock(HSE_CLOCK); - /* HSE division factor for RTC clock must be set to ensure that * the clock supplied to the RTC is less than or equal to 1 MHz */ @@ -230,21 +234,27 @@ static void RTC_initClock(sourceClock_t source) #else #error "Could not define RTCClockSelection" #endif /* STM32F1xx */ - if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) { - Error_Handler(); - } +#endif /* RCC_PERIPHCLK_RTC_WDG_BLEWKUP */ } else if (source == LSI_CLOCK) { /* Enable the clock if not already set by user */ enableClock(LSI_CLOCK); - +#if defined(RCC_PERIPHCLK_RTC_WDG_BLEWKUP) + PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_RTC_WDG_BLEWKUP; + PeriphClkInit.RTCWDGBLEWKUPClockSelection = RCC_RTC_WDG_BLEWKUP_CLKSOURCE_LSI; +#else PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_RTC; PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_LSI; - if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) { - Error_Handler(); - } +#endif /* RCC_PERIPHCLK_RTC_WDG_BLEWKUP */ } else { + /* Invalid clock source */ + Error_Handler(); + } + if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) { Error_Handler(); } +#if defined(__HAL_RCC_RTC_CLK_ENABLE) + __HAL_RCC_RTC_CLK_ENABLE(); +#endif } /** @@ -451,7 +461,9 @@ bool RTC_init(hourFormat_t format, binaryMode_t mode, sourceClock_t source, bool RtcHandle.Init.HourFormat = (format == HOUR_FORMAT_12) ? RTC_HOURFORMAT_12 : RTC_HOURFORMAT_24; RtcHandle.Init.OutPut = RTC_OUTPUT_DISABLE; RtcHandle.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH; +#if defined(RTC_OUTPUT_TYPE_OPENDRAIN) RtcHandle.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN; +#endif #if defined(RTC_OUTPUT_PULLUP_NONE) RtcHandle.Init.OutPutPullUp = RTC_OUTPUT_PULLUP_NONE; #endif @@ -507,6 +519,14 @@ bool RTC_init(hourFormat_t format, binaryMode_t mode, sourceClock_t source, bool reinit = true; } else { // RTC is already initialized +#if defined(__HAL_RCC_GET_RTC_WDG_BLEWKUP_CLK_CONFIG) + uint32_t oldRtcClockSource = __HAL_RCC_GET_RTC_WDG_BLEWKUP_CLK_CONFIG(); + oldRtcClockSource = ((oldRtcClockSource == RCC_RTC_WDG_BLEWKUP_CLKSOURCE_LSE) ? LSE_CLOCK : + (oldRtcClockSource == RCC_RTC_WDG_BLEWKUP_CLKSOURCE_LSI) ? LSI_CLOCK : + (oldRtcClockSource == RCC_RTC_WDG_BLEWKUP_CLKSOURCE_HSI64M_DIV2048) ? HSI_CLOCK : + // default case corresponding to no clock source + 0xFFFFFFFF); +#else uint32_t oldRtcClockSource = __HAL_RCC_GET_RTC_SOURCE(); oldRtcClockSource = ((oldRtcClockSource == RCC_RTCCLKSOURCE_LSE) ? LSE_CLOCK : (oldRtcClockSource == RCC_RTCCLKSOURCE_LSI) ? LSI_CLOCK : @@ -521,7 +541,7 @@ bool RTC_init(hourFormat_t format, binaryMode_t mode, sourceClock_t source, bool #endif // default case corresponding to no clock source 0xFFFFFFFF); - +#endif #if defined(STM32F1xx) if ((RtcHandle.DateToUpdate.WeekDay == 0) && (RtcHandle.DateToUpdate.Month == 0) @@ -711,8 +731,8 @@ void RTC_SetTime(uint8_t hours, uint8_t minutes, uint8_t seconds, uint32_t subSe /*RTC_TimeStruct.SubSeconds = subSeconds;*/ /*RTC_TimeStruct.SecondFraction = 0;*/ #endif /* RTC_SSR_SS */ - RTC_TimeStruct.DayLightSaving = RTC_STOREOPERATION_RESET; - RTC_TimeStruct.StoreOperation = RTC_DAYLIGHTSAVING_NONE; + RTC_TimeStruct.DayLightSaving = RTC_DAYLIGHTSAVING_NONE; + RTC_TimeStruct.StoreOperation = RTC_STOREOPERATION_RESET; #else UNUSED(period); #endif /* !STM32F1xx */ @@ -1192,7 +1212,8 @@ void RTC_Alarm_IRQHandler(void) defined(STM32F091xC) || defined(STM32F098xx) || defined(STM32F070xB) || \ defined(STM32F030xC) || defined(STM32G0xx) || defined(STM32H5xx) || \ defined(STM32L0xx) || defined(STM32L5xx) || defined(STM32U0xx) ||\ - defined(STM32U3xx) || defined(STM32U5xx) || defined(STM32WBAxx) + defined(STM32U3xx) || defined(STM32U5xx) || defined(STM32WB0x) || \ + defined(STM32WBAxx) // In some cases, the same vector is used to manage WakeupTimer, // but with a dedicated HAL IRQHandler HAL_RTCEx_WakeUpTimerIRQHandler(&RtcHandle); diff --git a/src/rtc.h b/src/rtc.h index 63b406e..b4e9f0f 100644 --- a/src/rtc.h +++ b/src/rtc.h @@ -130,7 +130,8 @@ typedef void(*voidCallbackPtr)(void *); #if defined(STM32C0xx) || defined(STM32F0xx) || defined(STM32H5xx) || \ defined(STM32L0xx) || defined(STM32L5xx) || defined(STM32U3xx) || \ - defined(STM32U3xx) || defined(STM32U5xx) || defined(STM32WBAxx) + defined(STM32U3xx) || defined(STM32U5xx) || defined(STM32WB0x) || \ + defined(STM32WBAxx) #define RTC_Alarm_IRQn RTC_IRQn #define RTC_Alarm_IRQHandler RTC_IRQHandler #endif @@ -142,7 +143,8 @@ typedef void(*voidCallbackPtr)(void *); /* mapping the IRQn for the one-second interrupt depending on the soc */ #if defined(STM32F1xx) || (defined(STM32F0xx) && defined(RTC_CR_WUTE)) || \ defined(STM32H5xx) || defined(STM32L0xx) || defined(STM32L5xx) || \ - defined(STM32U3xx) || defined(STM32U5xx) || defined(STM32WBAxx) + defined(STM32U3xx) || defined(STM32U5xx) || defined(STM32WB0x) || \ + defined(STM32WBAxx) // specific WakeUp interrupt #define ONESECOND_IRQn RTC_IRQn #elif defined(STM32MP1xx)