From 120d547a3085a834c79d76a2a5ea65ddd1acfb7a Mon Sep 17 00:00:00 2001 From: Frederic Pillon Date: Tue, 3 Oct 2023 15:37:52 +0200 Subject: [PATCH 1/4] chore: harden deinit Signed-off-by: Frederic Pillon --- src/rtc.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/rtc.c b/src/rtc.c index f28f68e..dd952ad 100644 --- a/src/rtc.c +++ b/src/rtc.c @@ -132,17 +132,11 @@ void HAL_RTC_MspDeInit(RTC_HandleTypeDef *rtcHandle) { if (rtcHandle->Instance == RTC) { - /* Peripheral clock disable */ - __HAL_RCC_RTC_DISABLE(); -#ifdef __HAL_RCC_RTCAPB_CLK_DISABLE - __HAL_RCC_RTCAPB_CLK_DISABLE(); -#endif /* RTC interrupt Deinit */ #if defined(STM32WLxx) /* Only the STM32WLxx series has a TAMP_STAMP_LSECSS_SSRU_IRQn */ HAL_NVIC_DisableIRQ(TAMP_STAMP_LSECSS_SSRU_IRQn); #endif /* STM32WLxx */ - HAL_NVIC_DisableIRQ(RTC_Alarm_IRQn); } } @@ -635,6 +629,15 @@ bool RTC_init(hourFormat_t format, binaryMode_t mode, sourceClock_t source, bool void RTC_DeInit(bool reset_cb) { HAL_RTC_DeInit(&RtcHandle); + /* Peripheral clock disable */ + __HAL_RCC_RTC_DISABLE(); +#ifdef __HAL_RCC_RTCAPB_CLK_DISABLE + __HAL_RCC_RTCAPB_CLK_DISABLE(); +#endif + HAL_NVIC_DisableIRQ(RTC_Alarm_IRQn); +#ifdef ONESECOND_IRQn + HAL_NVIC_DisableIRQ(ONESECOND_IRQn); +#endif if (reset_cb) { RTCUserCallback = NULL; callbackUserData = NULL; From 2ccc178dc91de1ccb438ac5706f1341e59515b0f Mon Sep 17 00:00:00 2001 From: Frederic Pillon Date: Thu, 5 Oct 2023 09:34:33 +0200 Subject: [PATCH 2/4] chore: factorize code Signed-off-by: Frederic Pillon --- src/STM32RTC.cpp | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/src/STM32RTC.cpp b/src/STM32RTC.cpp index 1a8eb84..64b8e70 100644 --- a/src/STM32RTC.cpp +++ b/src/STM32RTC.cpp @@ -851,16 +851,7 @@ void STM32RTC::setAlarmSubSeconds(uint32_t subSeconds, Alarm name) #ifndef RTC_ALARM_B UNUSED(name); #endif - if (_mode == MODE_BIN) { -#ifdef RTC_ALARM_B - if (name == ALARM_B) { - _alarmBSubSeconds = subSeconds; - } else -#endif - { - _alarmSubSeconds = subSeconds; - } - } else if (subSeconds < 1000) { + if ((_mode == MODE_BIN) || (subSeconds < 1000)) { #ifdef RTC_ALARM_B if (name == ALARM_B) { _alarmBSubSeconds = subSeconds; From 82267c2564305f7cbfe349d0cb7c6b12019b871d Mon Sep 17 00:00:00 2001 From: Frederic Pillon Date: Thu, 5 Oct 2023 16:01:59 +0200 Subject: [PATCH 3/4] chore: RTCSecondsIrqCallback only when ONESECOND_IRQn Signed-off-by: Frederic Pillon --- src/rtc.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/rtc.c b/src/rtc.c index dd952ad..c68a92f 100644 --- a/src/rtc.c +++ b/src/rtc.c @@ -63,8 +63,9 @@ static void *callbackUserData = NULL; static voidCallbackPtr RTCUserCallbackB = NULL; static void *callbackUserDataB = NULL; #endif +#ifdef ONESECOND_IRQn static voidCallbackPtr RTCSecondsIrqCallback = NULL; - +#endif static sourceClock_t clkSrc = LSI_CLOCK; static uint32_t clkVal = LSI_VALUE; static uint8_t HSEDiv = 0; @@ -645,7 +646,9 @@ void RTC_DeInit(bool reset_cb) RTCUserCallbackB = NULL; callbackUserDataB = NULL; #endif +#ifdef ONESECOND_IRQn RTCSecondsIrqCallback = NULL; +#endif } } From dccec10583947b6a22da5b6692dab5a8656f5065 Mon Sep 17 00:00:00 2001 From: Frederic Pillon Date: Thu, 5 Oct 2023 16:42:07 +0200 Subject: [PATCH 4/4] feat: add SubSecondinterrupt underflow api for STM32WLxx Signed-off-by: Frederic Pillon --- README.md | 8 +++++ keywords.txt | 2 ++ src/STM32RTC.cpp | 25 +++++++++++++ src/STM32RTC.h | 5 +++ src/rtc.c | 94 ++++++++++++++++++++++++++---------------------- src/rtc.h | 13 +++++-- 6 files changed, 101 insertions(+), 46 deletions(-) diff --git a/README.md b/README.md index fbf5d80..bc11b65 100644 --- a/README.md +++ b/README.md @@ -179,6 +179,14 @@ by the RTC. Thus the getEpoch function is only to be called to get the subsecond (returned time_t is not valid). The setAlarmEpoch only uses the sub-second [0..0xFFFFFFFF] (time_t value is useless). +_SubSeconds underflow_ + +Only dor STM32WLxx. Manage interrupt (SSRU) when SubSeconds register +underflow. Used by STM32LoRaWAN. + +* **`void attachSubSecondsUnderflowInterrupt(voidFuncPtr callback);`** +* **`void detachSubSecondsUnderflowInterrupt(void);`** + Refer to the Arduino RTC documentation for the other functions http://arduino.cc/en/Reference/RTC diff --git a/keywords.txt b/keywords.txt index 0c1af19..37fcf3d 100644 --- a/keywords.txt +++ b/keywords.txt @@ -72,6 +72,8 @@ attachInterrupt KEYWORD2 detachInterrupt KEYWORD2 attachSecondsInterrupt KEYWORD2 detachSecondsInterrupt KEYWORD2 +attachSubSecondsUnderflowInterrupt KEYWORD2 +detachSubSecondsUnderflowInterrupt KEYWORD2 getClockSource KEYWORD2 setClockSource KEYWORD2 diff --git a/src/STM32RTC.cpp b/src/STM32RTC.cpp index 64b8e70..4a29928 100644 --- a/src/STM32RTC.cpp +++ b/src/STM32RTC.cpp @@ -334,6 +334,31 @@ void STM32RTC::detachSecondsInterrupt(void) } #endif /* ONESECOND_IRQn */ + +#ifdef STM32WLxx +/** + * @brief attach a callback to the RTC SubSeconds underflow interrupt. + * @note only for STM32WLxx + * @param callback: pointer to the callback + * @retval None + */ +void STM32RTC::attachSubSecondsUnderflowInterrupt(voidFuncPtr callback) +{ + attachSubSecondsUnderflowIrqCallback(callback); +} + +/** + * @brief detach the RTC SubSeconds underflow callback. + * @retval None + */ +void STM32RTC::detachSubSecondsUnderflowInterrupt(void) +{ + detachSubSecondsUnderflowIrqCallback(); +} + +#endif /* STM32WLxx */ + + // Kept for compatibility. Use STM32LowPower library. void STM32RTC::standbyMode(void) { diff --git a/src/STM32RTC.h b/src/STM32RTC.h index 0854727..6235b6c 100644 --- a/src/STM32RTC.h +++ b/src/STM32RTC.h @@ -159,6 +159,11 @@ class STM32RTC { void detachSecondsInterrupt(void); #endif /* ONESECOND_IRQn */ +#ifdef STM32WLxx + // STM32WLxx has a dedicated IRQ + void attachSubSecondsUnderflowInterrupt(voidFuncPtr callback); + void detachSubSecondsUnderflowInterrupt(void); +#endif /* STM32WLxx */ // Kept for compatibility: use STM32LowPower library. void standbyMode(); diff --git a/src/rtc.c b/src/rtc.c index c68a92f..73c911f 100644 --- a/src/rtc.c +++ b/src/rtc.c @@ -66,6 +66,9 @@ static void *callbackUserDataB = NULL; #ifdef ONESECOND_IRQn static voidCallbackPtr RTCSecondsIrqCallback = NULL; #endif +#ifdef STM32WLxx +static voidCallbackPtr RTCSubSecondsUnderflowIrqCallback = NULL; +#endif static sourceClock_t clkSrc = LSI_CLOCK; static uint32_t clkVal = LSI_VALUE; static uint8_t HSEDiv = 0; @@ -98,49 +101,6 @@ static inline int _log2(int x) } /* Exported functions --------------------------------------------------------*/ - -/* HAL MSP function used for RTC_Init */ -void HAL_RTC_MspInit(RTC_HandleTypeDef *rtcHandle) -{ -#if defined(RTC_SCR_CSSRUF) - if (rtcHandle->Instance == RTC) { - /* In BINARY mode (MIX or ONLY), set the SSR Underflow interrupt */ - if (rtcHandle->Init.BinMode != RTC_BINARY_NONE) { -#if defined(STM32WLxx) - /* Only the STM32WLxx series has a TAMP_STAMP_LSECSS_SSRU_IRQn */ - if (HAL_RTCEx_SetSSRU_IT(rtcHandle) != HAL_OK) { - Error_Handler(); - } - /* Give init value for the RtcFeatures enable */ - rtcHandle->IsEnabled.RtcFeatures = 0; - - /* RTC interrupt Init */ - HAL_NVIC_SetPriority(TAMP_STAMP_LSECSS_SSRU_IRQn, 0, 0); - HAL_NVIC_EnableIRQ(TAMP_STAMP_LSECSS_SSRU_IRQn); -#else - /* The STM32U5, STM32H5, STM32L4plus have common RTC interrupt and a SSRU flag */ - __HAL_RTC_SSRU_ENABLE_IT(rtcHandle, RTC_IT_SSRU); -#endif /* STM32WLxx */ - } - } -#else /* RTC_SCR_CSSRUF */ - UNUSED(rtcHandle); -#endif /* RTC_SCR_CSSRUF */ - /* RTC_Alarm_IRQn is enabled when enabling Alarm */ -} - -void HAL_RTC_MspDeInit(RTC_HandleTypeDef *rtcHandle) -{ - - if (rtcHandle->Instance == RTC) { - /* RTC interrupt Deinit */ -#if defined(STM32WLxx) - /* Only the STM32WLxx series has a TAMP_STAMP_LSECSS_SSRU_IRQn */ - HAL_NVIC_DisableIRQ(TAMP_STAMP_LSECSS_SSRU_IRQn); -#endif /* STM32WLxx */ - } -} - /** * @brief Get pointer to RTC_HandleTypeDef * @param None @@ -638,6 +598,9 @@ void RTC_DeInit(bool reset_cb) HAL_NVIC_DisableIRQ(RTC_Alarm_IRQn); #ifdef ONESECOND_IRQn HAL_NVIC_DisableIRQ(ONESECOND_IRQn); +#endif +#ifdef STM32WLxx + HAL_NVIC_DisableIRQ(TAMP_STAMP_LSECSS_SSRU_IRQn); #endif if (reset_cb) { RTCUserCallback = NULL; @@ -648,6 +611,9 @@ void RTC_DeInit(bool reset_cb) #endif #ifdef ONESECOND_IRQn RTCSecondsIrqCallback = NULL; +#endif +#ifdef STM32WLxx + RTCSubSecondsUnderflowIrqCallback = NULL; #endif } } @@ -1266,6 +1232,48 @@ void RTC_WKUP_IRQHandler(void) #endif /* STM32F1xx */ #endif /* ONESECOND_IRQn */ +#ifdef STM32WLxx +/** + * @brief Attach SubSeconds underflow interrupt callback. + * @param func: pointer to the callback + * @retval None + */ +void attachSubSecondsUnderflowIrqCallback(voidCallbackPtr func) +{ + /* Callback called on SSRU interrupt */ + RTCSubSecondsUnderflowIrqCallback = func; + + /* Enable the IRQ that will trig the one-second interrupt */ + if (HAL_RTCEx_SetSSRU_IT(&RtcHandle) != HAL_OK) { + Error_Handler(); + } + HAL_NVIC_SetPriority(TAMP_STAMP_LSECSS_SSRU_IRQn, RTC_IRQ_SSRU_PRIO, RTC_IRQ_SSRU_SUBPRIO); + HAL_NVIC_EnableIRQ(TAMP_STAMP_LSECSS_SSRU_IRQn); +} + +/** + * @brief Detach SubSeconds underflow interrupt callback. + * @param None + * @retval None + */ +void detachSubSecondsUnderflowIrqCallback(void) +{ + RTCSubSecondsUnderflowIrqCallback = NULL; + if (HAL_RTCEx_DeactivateSSRU(&RtcHandle) != HAL_OK) { + Error_Handler(); + } + HAL_NVIC_DisableIRQ(TAMP_STAMP_LSECSS_SSRU_IRQn); +} + +void HAL_RTCEx_SSRUEventCallback(RTC_HandleTypeDef *hrtc) +{ + (void)hrtc; + if (RTCSubSecondsUnderflowIrqCallback != NULL) { + RTCSubSecondsUnderflowIrqCallback(NULL); + } +} +#endif /* STM32WLxx */ + #if defined(STM32F1xx) void RTC_StoreDate(void) { diff --git a/src/rtc.h b/src/rtc.h index 4983148..8d0bcd8 100644 --- a/src/rtc.h +++ b/src/rtc.h @@ -108,8 +108,12 @@ typedef void(*voidCallbackPtr)(void *); #ifndef RTC_IRQ_SUBPRIO #define RTC_IRQ_SUBPRIO 0 #endif - - +#ifndef RTC_IRQ_SSRU_PRIO +#define RTC_IRQ_SSRU_PRIO 0 +#endif +#ifndef RTC_IRQ_SSRU_SUBPRIO +#define RTC_IRQ_SSRU_SUBPRIO 0 +#endif #define HSE_RTC_MAX 1000000U #if !defined(STM32F1xx) @@ -198,7 +202,10 @@ void detachAlarmCallback(alarm_t name); void attachSecondsIrqCallback(voidCallbackPtr func); void detachSecondsIrqCallback(void); #endif /* ONESECOND_IRQn */ - +#ifdef STM32WLxx +void attachSubSecondsUnderflowIrqCallback(voidCallbackPtr func); +void detachSubSecondsUnderflowIrqCallback(void); +#endif /* STM32WLxx */ #if defined(STM32F1xx) void RTC_StoreDate(void); #endif