From 2844950a39f3b6a71253b1ddf10b2a3f74050313 Mon Sep 17 00:00:00 2001 From: crasbe Date: Fri, 31 Oct 2025 18:25:47 +0100 Subject: [PATCH 1/6] cpu/stm32: style improvements of rtc_all.c --- cpu/stm32/periph/rtc_all.c | 192 ++++++++++++++++++------------------- 1 file changed, 96 insertions(+), 96 deletions(-) diff --git a/cpu/stm32/periph/rtc_all.c b/cpu/stm32/periph/rtc_all.c index c77d20f64ede..944f401966d9 100644 --- a/cpu/stm32/periph/rtc_all.c +++ b/cpu/stm32/periph/rtc_all.c @@ -26,109 +26,109 @@ /* map some CPU specific register names */ #if defined (CPU_FAM_STM32L0) || defined(CPU_FAM_STM32L1) -#define EN_REG (RCC->CSR) -#define EN_BIT (RCC_CSR_RTCEN) -#define CLKSEL_MASK (RCC_CSR_RTCSEL) -#define CLKSEL_LSE (RCC_CSR_RTCSEL_LSE) -#define CLKSEL_LSI (RCC_CSR_RTCSEL_LSI) +# define EN_REG (RCC->CSR) +# define EN_BIT (RCC_CSR_RTCEN) +# define CLKSEL_MASK (RCC_CSR_RTCSEL) +# define CLKSEL_LSE (RCC_CSR_RTCSEL_LSE) +# define CLKSEL_LSI (RCC_CSR_RTCSEL_LSI) #else -#define EN_REG (RCC->BDCR) -#define EN_BIT (RCC_BDCR_RTCEN) -#define CLKSEL_MASK (RCC_BDCR_RTCSEL_0 | RCC_BDCR_RTCSEL_1) -#define CLKSEL_LSE (RCC_BDCR_RTCSEL_0) -#define CLKSEL_LSI (RCC_BDCR_RTCSEL_1) +# define EN_REG (RCC->BDCR) +# define EN_BIT (RCC_BDCR_RTCEN) +# define CLKSEL_MASK (RCC_BDCR_RTCSEL_0 | RCC_BDCR_RTCSEL_1) +# define CLKSEL_LSE (RCC_BDCR_RTCSEL_0) +# define CLKSEL_LSI (RCC_BDCR_RTCSEL_1) #endif /* map some EXTI register names */ #if defined(CPU_FAM_STM32L4) || defined(CPU_FAM_STM32WB) || \ defined(CPU_FAM_STM32G4) -#define EXTI_REG_RTSR (EXTI->RTSR1) -#define EXTI_REG_FTSR (EXTI->FTSR1) -#define EXTI_REG_PR (EXTI->PR1) -#define EXTI_REG_IMR (EXTI->IMR1) +# define EXTI_REG_RTSR (EXTI->RTSR1) +# define EXTI_REG_FTSR (EXTI->FTSR1) +# define EXTI_REG_PR (EXTI->PR1) +# define EXTI_REG_IMR (EXTI->IMR1) #elif defined(CPU_FAM_STM32G0) || defined(CPU_FAM_STM32U5) -#define EXTI_REG_RTSR (EXTI->RTSR1) -#define EXTI_REG_FTSR (EXTI->FTSR1) -#define EXTI_REG_PR (EXTI->RPR1) -#define EXTI_REG_IMR (EXTI->IMR1) +# define EXTI_REG_RTSR (EXTI->RTSR1) +# define EXTI_REG_FTSR (EXTI->FTSR1) +# define EXTI_REG_PR (EXTI->RPR1) +# define EXTI_REG_IMR (EXTI->IMR1) #elif defined(CPU_FAM_STM32L5) -#define EXTI_REG_IMR (EXTI->IMR1) +# define EXTI_REG_IMR (EXTI->IMR1) #else -#define EXTI_REG_RTSR (EXTI->RTSR) -#define EXTI_REG_FTSR (EXTI->FTSR) -#define EXTI_REG_PR (EXTI->PR) -#define EXTI_REG_IMR (EXTI->IMR) +# define EXTI_REG_RTSR (EXTI->RTSR) +# define EXTI_REG_FTSR (EXTI->FTSR) +# define EXTI_REG_PR (EXTI->PR) +# define EXTI_REG_IMR (EXTI->IMR) #endif /* map some RTC register names and bitfield */ #if defined(CPU_FAM_STM32G4) || defined(CPU_FAM_STM32G0) -#define RTC_REG_ISR RTC->ICSR -#define RTC_REG_SR RTC->SR -#define RTC_REG_SCR RTC->SCR -#define RTC_ISR_RSF RTC_ICSR_RSF -#define RTC_ISR_INIT RTC_ICSR_INIT -#define RTC_ISR_INITF RTC_ICSR_INITF -#define RTC_ISR_ALRAWF RTC_ICSR_ALRAWF -#define RTC_ISR_ALRAF RTC_SR_ALRAF +# define RTC_REG_ISR RTC->ICSR +# define RTC_REG_SR RTC->SR +# define RTC_REG_SCR RTC->SCR +# define RTC_ISR_RSF RTC_ICSR_RSF +# define RTC_ISR_INIT RTC_ICSR_INIT +# define RTC_ISR_INITF RTC_ICSR_INITF +# define RTC_ISR_ALRAWF RTC_ICSR_ALRAWF +# define RTC_ISR_ALRAF RTC_SR_ALRAF #elif defined(CPU_FAM_STM32L5) -#define RTC_REG_ISR RTC->ICSR -#define RTC_REG_SR RTC->SR -#define RTC_REG_SCR RTC->SCR -#define RTC_ISR_RSF RTC_ICSR_RSF -#define RTC_ISR_INIT RTC_ICSR_INIT -#define RTC_ISR_INITF RTC_ICSR_INITF +# define RTC_REG_ISR RTC->ICSR +# define RTC_REG_SR RTC->SR +# define RTC_REG_SCR RTC->SCR +# define RTC_ISR_RSF RTC_ICSR_RSF +# define RTC_ISR_INIT RTC_ICSR_INIT +# define RTC_ISR_INITF RTC_ICSR_INITF #elif defined(CPU_FAM_STM32U5) -#define RTC_REG_ISR RTC->ICSR -#define RTC_REG_SR RTC->SR -#define RTC_REG_SCR RTC->SCR -#define RTC_ISR_RSF RTC_ICSR_RSF -#define RTC_ISR_INIT RTC_ICSR_INIT -#define RTC_ISR_INITF RTC_ICSR_INITF -#define RTC_ISR_ALRAF RTC_SR_ALRAF +# define RTC_REG_ISR RTC->ICSR +# define RTC_REG_SR RTC->SR +# define RTC_REG_SCR RTC->SCR +# define RTC_ISR_RSF RTC_ICSR_RSF +# define RTC_ISR_INIT RTC_ICSR_INIT +# define RTC_ISR_INITF RTC_ICSR_INITF +# define RTC_ISR_ALRAF RTC_SR_ALRAF #else -#define RTC_REG_ISR RTC->ISR +# define RTC_REG_ISR RTC->ISR #endif /* interrupt line name mapping */ #if defined(CPU_FAM_STM32F0) || defined(CPU_FAM_STM32L0) || \ defined(CPU_FAM_STM32L5) || defined(CPU_FAM_STM32U5) -#define IRQN (RTC_IRQn) -#define ISR_NAME isr_rtc +# define IRQN (RTC_IRQn) +# define ISR_NAME isr_rtc #elif defined(CPU_FAM_STM32G0) -#define IRQN (RTC_TAMP_IRQn) -#define ISR_NAME isr_rtc_tamp +# define IRQN (RTC_TAMP_IRQn) +# define ISR_NAME isr_rtc_tamp #else -#define IRQN (RTC_Alarm_IRQn) -#define ISR_NAME isr_rtc_alarm +# define IRQN (RTC_Alarm_IRQn) +# define ISR_NAME isr_rtc_alarm #endif /* EXTI bitfield mapping */ #if defined(CPU_FAM_STM32L4) -#define EXTI_IMR_BIT (EXTI_IMR1_IM18) -#define EXTI_FTSR_BIT (EXTI_FTSR1_FT18) -#define EXTI_RTSR_BIT (EXTI_RTSR1_RT18) -#define EXTI_PR_BIT (EXTI_PR1_PIF18) +# define EXTI_IMR_BIT (EXTI_IMR1_IM18) +# define EXTI_FTSR_BIT (EXTI_FTSR1_FT18) +# define EXTI_RTSR_BIT (EXTI_RTSR1_RT18) +# define EXTI_PR_BIT (EXTI_PR1_PIF18) #elif defined(CPU_FAM_STM32L5) -#define EXTI_IMR_BIT (EXTI_IMR1_IM17) +# define EXTI_IMR_BIT (EXTI_IMR1_IM17) #elif defined(CPU_FAM_STM32WB) || defined(CPU_FAM_STM32G4) -#define EXTI_IMR_BIT (EXTI_IMR1_IM17) -#define EXTI_FTSR_BIT (EXTI_FTSR1_FT17) -#define EXTI_RTSR_BIT (EXTI_RTSR1_RT17) -#define EXTI_PR_BIT (EXTI_PR1_PIF17) +# define EXTI_IMR_BIT (EXTI_IMR1_IM17) +# define EXTI_FTSR_BIT (EXTI_FTSR1_FT17) +# define EXTI_RTSR_BIT (EXTI_RTSR1_RT17) +# define EXTI_PR_BIT (EXTI_PR1_PIF17) #elif defined(CPU_FAM_STM32G0) || defined(CPU_FAM_STM32U5) -#define EXTI_IMR_BIT (EXTI_IMR1_IM11) -#define EXTI_FTSR_BIT (EXTI_FTSR1_FT11) -#define EXTI_RTSR_BIT (EXTI_RTSR1_RT11) -#define EXTI_PR_BIT (EXTI_RPR1_RPIF11) +# define EXTI_IMR_BIT (EXTI_IMR1_IM11) +# define EXTI_FTSR_BIT (EXTI_FTSR1_FT11) +# define EXTI_RTSR_BIT (EXTI_RTSR1_RT11) +# define EXTI_PR_BIT (EXTI_RPR1_RPIF11) #else -#if defined(CPU_FAM_STM32L0) -#define EXTI_IMR_BIT (EXTI_IMR_IM17) -#else -#define EXTI_IMR_BIT (EXTI_IMR_MR17) -#endif -#define EXTI_FTSR_BIT (EXTI_FTSR_TR17) -#define EXTI_RTSR_BIT (EXTI_RTSR_TR17) -#define EXTI_PR_BIT (EXTI_PR_PR17) +# if defined(CPU_FAM_STM32L0) +# define EXTI_IMR_BIT (EXTI_IMR_IM17) +# else +# define EXTI_IMR_BIT (EXTI_IMR_MR17) +# endif +# define EXTI_FTSR_BIT (EXTI_FTSR_TR17) +# define EXTI_RTSR_BIT (EXTI_RTSR_TR17) +# define EXTI_PR_BIT (EXTI_PR_PR17) #endif /* write protection values */ @@ -147,62 +147,62 @@ #define ALRM_M_MASK (RTC_ALRMAR_MNU | RTC_ALRMAR_MNT) #define ALRM_S_MASK (RTC_ALRMAR_SU | RTC_ALRMAR_ST) #ifndef RTC_DR_YU_Pos -#define RTC_DR_YU_Pos (16U) +# define RTC_DR_YU_Pos (16U) #endif #ifndef RTC_DR_MU_Pos -#define RTC_DR_MU_Pos (8U) +# define RTC_DR_MU_Pos (8U) #endif #ifndef RTC_DR_DU_Pos -#define RTC_DR_DU_Pos (0U) +# define RTC_DR_DU_Pos (0U) #endif #ifndef RTC_TR_HU_Pos -#define RTC_TR_HU_Pos (16U) +# define RTC_TR_HU_Pos (16U) #endif #ifndef RTC_TR_MNU_Pos -#define RTC_TR_MNU_Pos (8U) +# define RTC_TR_MNU_Pos (8U) #endif #ifndef RTC_TR_SU_Pos -#define RTC_TR_SU_Pos (0U) +# define RTC_TR_SU_Pos (0U) #endif #ifndef RTC_ALRMAR_DU_Pos -#define RTC_ALRMAR_DU_Pos (24U) +# define RTC_ALRMAR_DU_Pos (24U) #endif #ifndef RTC_ALRMAR_HU_Pos -#define RTC_ALRMAR_HU_Pos (16U) +# define RTC_ALRMAR_HU_Pos (16U) #endif #ifndef RTC_ALRMAR_MNU_Pos -#define RTC_ALRMAR_MNU_Pos (8U) +# define RTC_ALRMAR_MNU_Pos (8U) #endif #ifndef RTC_ALRMAR_SU_Pos -#define RTC_ALRMAR_SU_Pos (0U) +# define RTC_ALRMAR_SU_Pos (0U) #endif /* figure out sync and async prescaler */ #if IS_ACTIVE(CONFIG_BOARD_HAS_LSE) -#define PRE_SYNC (255) -#define PRE_ASYNC (127) +# define PRE_SYNC (255) +# define PRE_ASYNC (127) #elif (CLOCK_LSI == 40000) -#define PRE_SYNC (319) -#define PRE_ASYNC (124) +# define PRE_SYNC (319) +# define PRE_ASYNC (124) #elif (CLOCK_LSI == 37000) -#define PRE_SYNC (295) -#define PRE_ASYNC (124) +# define PRE_SYNC (295) +# define PRE_ASYNC (124) #elif (CLOCK_LSI == 32000) -#define PRE_SYNC (249) -#define PRE_ASYNC (127) +# define PRE_SYNC (249) +# define PRE_ASYNC (127) #else -#error "rtc: unable to determine RTC SYNC and ASYNC prescalers from LSI value" +# error "RTC: unable to determine RTC SYNC and ASYNC prescalers from LSI value" #endif /* struct tm counts years since 1900 but RTC has only two-digit year, hence the offset */ #define YEAR_OFFSET (RIOT_EPOCH - 1900) /* Use a magic number to determine the initial RTC source. This will be used - to know if a reset of the RTC is required at initialization. */ + * to know if a reset of the RTC is required at initialization. */ #if IS_ACTIVE(CONFIG_BOARD_HAS_LSE) -#define MAGIC_CLCK_NUMBER (0x1970) +# define MAGIC_CLCK_NUMBER (0x1970) #else -#define MAGIC_CLCK_NUMBER (0x1971) +# define MAGIC_CLCK_NUMBER (0x1971) #endif static struct { @@ -256,8 +256,8 @@ void rtc_init(void) stmclk_dbp_unlock(); #if defined(CPU_FAM_STM32L0) || defined(CPU_FAM_STM32L1) /* Compare the stored magic number with the current one. If it's different - it means the clock source has changed and thus a RTC reset is - required. */ + * it means the clock source has changed and thus a RTC reset is + * required. */ if (RTC->BKP0R != MAGIC_CLCK_NUMBER) { RCC->CSR |= RCC_CSR_RTCRST; RCC->CSR &= ~RCC_CSR_RTCRST; From 07cca537ffa0bbff8724d2c190082b8d71883ad0 Mon Sep 17 00:00:00 2001 From: Kasper Hjort Berthelsen Date: Wed, 3 Apr 2024 14:24:07 +0200 Subject: [PATCH 2/6] boards/nucleo-wl55jc: enable RTC peripheral --- boards/nucleo-wl55jc/Makefile.features | 1 + cpu/stm32/periph/rtc_all.c | 31 +++++++++++++++++++------- 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/boards/nucleo-wl55jc/Makefile.features b/boards/nucleo-wl55jc/Makefile.features index df235b4039c8..69aaeb97afad 100644 --- a/boards/nucleo-wl55jc/Makefile.features +++ b/boards/nucleo-wl55jc/Makefile.features @@ -5,6 +5,7 @@ CPU_MODEL = stm32wl55jc FEATURES_PROVIDED += periph_adc FEATURES_PROVIDED += periph_i2c FEATURES_PROVIDED += periph_lpuart +FEATURES_PROVIDED += periph_rtc FEATURES_PROVIDED += periph_rtt FEATURES_PROVIDED += periph_spi FEATURES_PROVIDED += periph_timer diff --git a/cpu/stm32/periph/rtc_all.c b/cpu/stm32/periph/rtc_all.c index 944f401966d9..c031f54576e4 100644 --- a/cpu/stm32/periph/rtc_all.c +++ b/cpu/stm32/periph/rtc_all.c @@ -46,7 +46,7 @@ # define EXTI_REG_FTSR (EXTI->FTSR1) # define EXTI_REG_PR (EXTI->PR1) # define EXTI_REG_IMR (EXTI->IMR1) -#elif defined(CPU_FAM_STM32G0) || defined(CPU_FAM_STM32U5) +#elif defined(CPU_FAM_STM32G0) || defined(CPU_FAM_STM32U5) || defined(CPU_FAM_STM32WL) # define EXTI_REG_RTSR (EXTI->RTSR1) # define EXTI_REG_FTSR (EXTI->FTSR1) # define EXTI_REG_PR (EXTI->RPR1) @@ -70,7 +70,7 @@ # define RTC_ISR_INITF RTC_ICSR_INITF # define RTC_ISR_ALRAWF RTC_ICSR_ALRAWF # define RTC_ISR_ALRAF RTC_SR_ALRAF -#elif defined(CPU_FAM_STM32L5) +#elif defined(CPU_FAM_STM32L5) || defined(CPU_FAM_STM32WL) # define RTC_REG_ISR RTC->ICSR # define RTC_REG_SR RTC->SR # define RTC_REG_SCR RTC->SCR @@ -108,7 +108,7 @@ # define EXTI_FTSR_BIT (EXTI_FTSR1_FT18) # define EXTI_RTSR_BIT (EXTI_RTSR1_RT18) # define EXTI_PR_BIT (EXTI_PR1_PIF18) -#elif defined(CPU_FAM_STM32L5) +#elif defined(CPU_FAM_STM32L5) || defined(CPU_FAM_STM32WL) # define EXTI_IMR_BIT (EXTI_IMR1_IM17) #elif defined(CPU_FAM_STM32WB) || defined(CPU_FAM_STM32G4) # define EXTI_IMR_BIT (EXTI_IMR1_IM17) @@ -271,7 +271,7 @@ void rtc_init(void) /* select input clock and enable the RTC */ stmclk_dbp_unlock(); -#if defined(CPU_FAM_STM32L5) +#if defined(CPU_FAM_STM32L5) || defined(CPU_FAM_STM32WL) periph_clk_en(APB1, RCC_APB1ENR1_RTCAPBEN); #elif defined(CPU_FAM_STM32G0) periph_clk_en(APB1, RCC_APBENR1_RTCAPBEN); @@ -296,7 +296,7 @@ void rtc_init(void) /* configure the EXTI channel, as RTC interrupts are routed through it. * Needs to be configured to trigger on rising edges. */ EXTI_REG_IMR |= EXTI_IMR_BIT; -#if !defined(CPU_FAM_STM32L5) +#if !(defined(CPU_FAM_STM32L5) || defined(CPU_FAM_STM32WL)) EXTI_REG_FTSR &= ~(EXTI_FTSR_BIT); EXTI_REG_RTSR |= EXTI_RTSR_BIT; EXTI_REG_PR = EXTI_PR_BIT; @@ -326,6 +326,21 @@ int rtc_set_time(struct tm *time) int rtc_get_time(struct tm *time) { +#if defined(CPU_FAM_STM32WL) + stmclk_dbp_unlock(); + /* unlock RTC */ + RTC->WPR = WPK1; + RTC->WPR = WPK2; + + RTC->ICSR &= ~RTC_ICSR_RSF; + + RTC->WPR = 0xff; + stmclk_dbp_lock(); + + /* waiting for the RSF bit to be set again */ + while (!(RTC_REG_ISR & RTC_ICSR_RSF)) {}; +#endif + /* save current time */ uint32_t tr = RTC->TR; uint32_t dr = RTC->DR; @@ -360,7 +375,7 @@ int rtc_set_alarm(struct tm *time, rtc_alarm_cb_t cb, void *arg) val2bcd(time->tm_sec, RTC_ALRMAR_SU_Pos, ALRM_S_MASK)); /* Enable Alarm A */ -#if !defined(CPU_FAM_STM32L5) +#if !(defined(CPU_FAM_STM32L5) || defined(CPU_FAM_STM32WL)) RTC_REG_ISR &= ~(RTC_ISR_ALRAF); #else RTC_REG_SCR = RTC_SCR_CALRAF; @@ -393,7 +408,7 @@ void rtc_clear_alarm(void) RTC->CR &= ~(RTC_CR_ALRAE | RTC_CR_ALRAIE); -#if !defined(CPU_FAM_STM32L5) && !defined(CPU_FAM_STM32U5) +#if !(defined(CPU_FAM_STM32L5) || defined(CPU_FAM_STM32U5) || defined(CPU_FAM_STM32WL)) while (!(RTC_REG_ISR & RTC_ISR_ALRAWF)) {} #else RTC_REG_SCR = RTC_SCR_CALRAF; @@ -421,7 +436,7 @@ void rtc_poweroff(void) void ISR_NAME(void) { -#if !defined(CPU_FAM_STM32L5) && !defined(CPU_FAM_STM32G0) && !defined(CPU_FAM_STM32U5) +#if !(defined(CPU_FAM_STM32L5) || defined(CPU_FAM_STM32WL) || defined(CPU_FAM_STM32G0) || defined(CPU_FAM_STM32U5)) if (RTC_REG_ISR & RTC_ISR_ALRAF) { if (isr_ctx.cb != NULL) { isr_ctx.cb(isr_ctx.arg); From 5afa6f726c07b7a58bf9efcbb7b117be8b9ae533 Mon Sep 17 00:00:00 2001 From: crasbe Date: Fri, 31 Oct 2025 18:07:42 +0100 Subject: [PATCH 3/6] tests/periph: use a year != RIOT_EPOCH for the RTC test --- tests/periph/rtc/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/periph/rtc/main.c b/tests/periph/rtc/main.c index d5433fee1c63..7d1fffa367ef 100644 --- a/tests/periph/rtc/main.c +++ b/tests/periph/rtc/main.c @@ -138,7 +138,7 @@ int main(void) } time = (struct tm){ - .tm_year = 2020 - 1900, /* years are counted from 1900 */ + .tm_year = 2025 - 1900, /* years are counted from 1900 */ .tm_mon = 1, /* 0 = January, 11 = December */ .tm_mday = 28, .tm_hour = 23, From 315e3dab3978f08ca32545790cbf5f3c8e5fffba Mon Sep 17 00:00:00 2001 From: Guillaume Meunier Date: Sat, 17 Aug 2019 18:56:01 +0200 Subject: [PATCH 4/6] cpu/stm32/periph/rtc: don't stop RTC for every lock --- cpu/stm32/periph/rtc_all.c | 82 ++++++++++++++++++++++---------------- 1 file changed, 48 insertions(+), 34 deletions(-) diff --git a/cpu/stm32/periph/rtc_all.c b/cpu/stm32/periph/rtc_all.c index c031f54576e4..e7d8fa59d70e 100644 --- a/cpu/stm32/periph/rtc_all.c +++ b/cpu/stm32/periph/rtc_all.c @@ -68,6 +68,7 @@ # define RTC_ISR_RSF RTC_ICSR_RSF # define RTC_ISR_INIT RTC_ICSR_INIT # define RTC_ISR_INITF RTC_ICSR_INITF +# define RTC_ISR_INITS RTC_ICSR_INITS # define RTC_ISR_ALRAWF RTC_ICSR_ALRAWF # define RTC_ISR_ALRAF RTC_SR_ALRAF #elif defined(CPU_FAM_STM32L5) || defined(CPU_FAM_STM32WL) @@ -77,6 +78,7 @@ # define RTC_ISR_RSF RTC_ICSR_RSF # define RTC_ISR_INIT RTC_ICSR_INIT # define RTC_ISR_INITF RTC_ICSR_INITF +# define RTC_ISR_INITS RTC_ICSR_INITS #elif defined(CPU_FAM_STM32U5) # define RTC_REG_ISR RTC->ICSR # define RTC_REG_SR RTC->SR @@ -84,6 +86,7 @@ # define RTC_ISR_RSF RTC_ICSR_RSF # define RTC_ISR_INIT RTC_ICSR_INIT # define RTC_ISR_INITF RTC_ICSR_INITF +# define RTC_ISR_INITS RTC_ICSR_INITS # define RTC_ISR_ALRAF RTC_SR_ALRAF #else # define RTC_REG_ISR RTC->ISR @@ -228,6 +231,14 @@ static int bcd2val(uint32_t val, int shift, uint32_t mask) return (((tmp >> 4) * 10) + (tmp & 0x0f)); } +void rtc_lock(void) +{ + /* lock RTC device */ + RTC->WPR = 0xff; + /* disable backup clock domain */ + stmclk_dbp_lock(); +} + void rtc_unlock(void) { /* enable backup clock domain */ @@ -235,20 +246,22 @@ void rtc_unlock(void) /* unlock RTC */ RTC->WPR = WPK1; RTC->WPR = WPK2; +} + +static inline void rtc_enter_init_mode(void) +{ + rtc_unlock(); /* enter RTC init mode */ RTC_REG_ISR |= RTC_ISR_INIT; while (!(RTC_REG_ISR & RTC_ISR_INITF)) {} } -void rtc_lock(void) +static inline void rtc_exit_init_mode(void) { /* exit RTC init mode */ RTC_REG_ISR &= ~RTC_ISR_INIT; while (RTC_REG_ISR & RTC_ISR_INITF) {} - /* lock RTC device */ - RTC->WPR = 0xff; - /* disable backup clock domain */ - stmclk_dbp_lock(); + rtc_lock(); } void rtc_init(void) @@ -264,8 +277,6 @@ void rtc_init(void) RTC->BKP0R = MAGIC_CLCK_NUMBER; /* Store the new magic number */ } #endif - stmclk_dbp_lock(); - /* enable low frequency clock */ stmclk_enable_lfclk(); @@ -278,20 +289,28 @@ void rtc_init(void) #elif defined(CPU_FAM_STM32U5) periph_clk_en(APB3, RCC_APB3ENR_RTCAPBEN); #endif - EN_REG &= ~(CLKSEL_MASK); + #if IS_ACTIVE(CONFIG_BOARD_HAS_LSE) - EN_REG |= (CLKSEL_LSE | EN_BIT); + if ((EN_REG & (CLKSEL_MASK | EN_BIT)) != (CLKSEL_LSE | EN_BIT)) { + EN_REG &= ~(CLKSEL_MASK); + EN_REG |= (CLKSEL_LSE | EN_BIT); + } #else - EN_REG |= (CLKSEL_LSI | EN_BIT); + if ((EN_REG & (CLKSEL_MASK | EN_BIT)) != (CLKSEL_LSI | EN_BIT)) { + EN_REG &= ~(CLKSEL_MASK); + EN_REG |= (CLKSEL_LSI | EN_BIT); + } #endif - rtc_unlock(); - /* reset configuration */ - RTC->CR = 0; - RTC_REG_ISR = RTC_ISR_INIT; - /* configure prescaler (RTC PRER) */ - RTC->PRER = (PRE_SYNC | (PRE_ASYNC << 16)); - rtc_lock(); + if (!(RTC_REG_ISR & RTC_ISR_INITS)) + { + rtc_enter_init_mode(); + /* reset configuration */ + RTC->CR = 0; + /* configure prescaler (RTC PRER) */ + RTC->PRER = (PRE_SYNC | (PRE_ASYNC << 16)); + rtc_exit_init_mode(); + } /* configure the EXTI channel, as RTC interrupts are routed through it. * Needs to be configured to trigger on rising edges. */ @@ -310,15 +329,14 @@ int rtc_set_time(struct tm *time) /* normalize input */ rtc_tm_normalize(time); - rtc_unlock(); - + rtc_enter_init_mode(); RTC->DR = (val2bcd((time->tm_year - YEAR_OFFSET), RTC_DR_YU_Pos, DR_Y_MASK) | val2bcd(time->tm_mon + 1, RTC_DR_MU_Pos, DR_M_MASK) | val2bcd(time->tm_mday, RTC_DR_DU_Pos, DR_D_MASK)); RTC->TR = (val2bcd(time->tm_hour, RTC_TR_HU_Pos, TR_H_MASK) | val2bcd(time->tm_min, RTC_TR_MNU_Pos, TR_M_MASK) | val2bcd(time->tm_sec, RTC_TR_SU_Pos, TR_S_MASK)); - rtc_lock(); + rtc_exit_init_mode(); while (!(RTC_REG_ISR & RTC_ISR_RSF)) {} return 0; @@ -326,20 +344,15 @@ int rtc_set_time(struct tm *time) int rtc_get_time(struct tm *time) { -#if defined(CPU_FAM_STM32WL) - stmclk_dbp_unlock(); - /* unlock RTC */ - RTC->WPR = WPK1; - RTC->WPR = WPK2; - - RTC->ICSR &= ~RTC_ICSR_RSF; - - RTC->WPR = 0xff; - stmclk_dbp_lock(); + /* After waking up from standby, the RSF flag has to be manually cleared. + * To be safe, we do it every time even though we might not have been in + * standby before. */ + rtc_unlock(); + RTC_REG_ISR &= ~RTC_ISR_RSF; + rtc_lock(); - /* waiting for the RSF bit to be set again */ - while (!(RTC_REG_ISR & RTC_ICSR_RSF)) {}; -#endif + /* waiting for the RSF bit to be set again before accessing the time */ + while (!(RTC_REG_ISR & RTC_ISR_RSF)) {}; /* save current time */ uint32_t tr = RTC->TR; @@ -436,7 +449,8 @@ void rtc_poweroff(void) void ISR_NAME(void) { -#if !(defined(CPU_FAM_STM32L5) || defined(CPU_FAM_STM32WL) || defined(CPU_FAM_STM32G0) || defined(CPU_FAM_STM32U5)) +#if !(defined(CPU_FAM_STM32L5) || defined(CPU_FAM_STM32WL) || defined(CPU_FAM_STM32G0) || \ + defined(CPU_FAM_STM32U5)) if (RTC_REG_ISR & RTC_ISR_ALRAF) { if (isr_ctx.cb != NULL) { isr_ctx.cb(isr_ctx.arg); From 71c2d4ab6aaa6d1d0883045f0f676311089e7175 Mon Sep 17 00:00:00 2001 From: crasbe Date: Fri, 31 Oct 2025 20:57:46 +0100 Subject: [PATCH 5/6] cpu/stm32: disable RTC MEM feature for F302 --- cpu/stm32/Makefile.features | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cpu/stm32/Makefile.features b/cpu/stm32/Makefile.features index f4db2fe0cb65..5996871677e6 100644 --- a/cpu/stm32/Makefile.features +++ b/cpu/stm32/Makefile.features @@ -35,7 +35,8 @@ ifneq (,$(filter $(CPU_FAM),c0 f0 f1 f3 g0 g4 l0 l1 l4 l5 u5 wb wl)) endif ifneq (,$(filter $(CPU_FAM),f0 f2 f3 f4 f7 l0 l1 l4 l5 u5 wb wl)) - CPU_MODELS_WITHOUT_RTC_BKPR += stm32f030% stm32f070% + CPU_MODELS_WITHOUT_RTC_BKPR += stm32f030% stm32f070% \ + stm32f302% ifeq (,$(filter $(CPU_MODELS_WITHOUT_RTC_BKPR),$(CPU_MODEL))) FEATURES_PROVIDED += periph_rtc_mem endif From 5c12ed9dbb152820d189ace21bc5786651fa6149 Mon Sep 17 00:00:00 2001 From: crasbe Date: Sat, 1 Nov 2025 00:48:34 +0100 Subject: [PATCH 6/6] boards/lora-e5-dev: enable RTC peripheral --- boards/lora-e5-dev/Makefile.features | 1 + 1 file changed, 1 insertion(+) diff --git a/boards/lora-e5-dev/Makefile.features b/boards/lora-e5-dev/Makefile.features index 424bffac743f..905c9845cf3c 100644 --- a/boards/lora-e5-dev/Makefile.features +++ b/boards/lora-e5-dev/Makefile.features @@ -5,6 +5,7 @@ CPU_MODEL = stm32wle5jc FEATURES_PROVIDED += periph_adc FEATURES_PROVIDED += periph_i2c FEATURES_PROVIDED += periph_lpuart +FEATURES_PROVIDED += periph_rtc FEATURES_PROVIDED += periph_rtt FEATURES_PROVIDED += periph_spi FEATURES_PROVIDED += periph_timer