@@ -235,16 +235,24 @@ void rtc_unlock(void)
235235 /* unlock RTC */
236236 RTC -> WPR = WPK1 ;
237237 RTC -> WPR = WPK2 ;
238+ }
239+
240+ static inline void rtc_enter_init_mode (void )
241+ {
238242 /* enter RTC init mode */
239243 RTC_REG_ISR |= RTC_ISR_INIT ;
240244 while (!(RTC_REG_ISR & RTC_ISR_INITF )) {}
241245}
242246
243- void rtc_lock (void )
247+ static inline void rtc_exit_init_mode (void )
244248{
245249 /* exit RTC init mode */
246250 RTC_REG_ISR &= ~RTC_ISR_INIT ;
247251 while (RTC_REG_ISR & RTC_ISR_INITF ) {}
252+ }
253+
254+ static inline void rtc_lock (void )
255+ {
248256 /* lock RTC device */
249257 RTC -> WPR = 0xff ;
250258 /* disable backup clock domain */
@@ -266,32 +274,35 @@ void rtc_init(void)
266274#endif
267275 stmclk_dbp_lock ();
268276
269- /* enable low frequency clock */
270- stmclk_enable_lfclk ();
277+ if (!(RTC_REG_ISR & RTC_ISR_INITS ))
278+ {
279+ /* enable low frequency clock */
280+ stmclk_enable_lfclk ();
271281
272- /* select input clock and enable the RTC */
273- stmclk_dbp_unlock ();
282+ /* select input clock and enable the RTC */
283+ stmclk_dbp_unlock ();
274284#if defined(CPU_FAM_STM32L5 ) || defined(CPU_FAM_STM32WL )
275- periph_clk_en (APB1 , RCC_APB1ENR1_RTCAPBEN );
285+ periph_clk_en (APB1 , RCC_APB1ENR1_RTCAPBEN );
276286#elif defined(CPU_FAM_STM32G0 )
277- periph_clk_en (APB1 , RCC_APBENR1_RTCAPBEN );
287+ periph_clk_en (APB1 , RCC_APBENR1_RTCAPBEN );
278288#elif defined(CPU_FAM_STM32U5 )
279- periph_clk_en (APB3 , RCC_APB3ENR_RTCAPBEN );
289+ periph_clk_en (APB3 , RCC_APB3ENR_RTCAPBEN );
280290#endif
281- EN_REG &= ~(CLKSEL_MASK );
291+ EN_REG &= ~(CLKSEL_MASK );
282292#if IS_ACTIVE (CONFIG_BOARD_HAS_LSE )
283- EN_REG |= (CLKSEL_LSE | EN_BIT );
293+ EN_REG |= (CLKSEL_LSE | EN_BIT );
284294#else
285- EN_REG |= (CLKSEL_LSI | EN_BIT );
295+ EN_REG |= (CLKSEL_LSI | EN_BIT );
286296#endif
287297
288- rtc_unlock ();
289- /* reset configuration */
290- RTC -> CR = 0 ;
291- RTC_REG_ISR = RTC_ISR_INIT ;
292- /* configure prescaler (RTC PRER) */
293- RTC -> PRER = (PRE_SYNC | (PRE_ASYNC << 16 ));
294- rtc_lock ();
298+ rtc_unlock ();
299+ /* reset configuration */
300+ RTC -> CR = 0 ;
301+ RTC_REG_ISR = RTC_ISR_INIT ;
302+ /* configure prescaler (RTC PRER) */
303+ RTC -> PRER = (PRE_SYNC | (PRE_ASYNC << 16 ));
304+ rtc_lock ();
305+ }
295306
296307 /* configure the EXTI channel, as RTC interrupts are routed through it.
297308 * Needs to be configured to trigger on rising edges. */
@@ -311,13 +322,14 @@ int rtc_set_time(struct tm *time)
311322 rtc_tm_normalize (time );
312323
313324 rtc_unlock ();
314-
325+ rtc_enter_init_mode ();
315326 RTC -> DR = (val2bcd ((time -> tm_year - YEAR_OFFSET ), RTC_DR_YU_Pos , DR_Y_MASK ) |
316327 val2bcd (time -> tm_mon + 1 , RTC_DR_MU_Pos , DR_M_MASK ) |
317328 val2bcd (time -> tm_mday , RTC_DR_DU_Pos , DR_D_MASK ));
318329 RTC -> TR = (val2bcd (time -> tm_hour , RTC_TR_HU_Pos , TR_H_MASK ) |
319330 val2bcd (time -> tm_min , RTC_TR_MNU_Pos , TR_M_MASK ) |
320331 val2bcd (time -> tm_sec , RTC_TR_SU_Pos , TR_S_MASK ));
332+ rtc_exit_init_mode ();
321333 rtc_lock ();
322334 while (!(RTC_REG_ISR & RTC_ISR_RSF )) {}
323335
0 commit comments