@@ -202,10 +202,6 @@ static void RTC_initClock(sourceClock_t source)
202202 } else {
203203 Error_Handler ();
204204 }
205- #ifdef __HAL_RCC_RTCAPB_CLK_ENABLE
206- __HAL_RCC_RTCAPB_CLK_ENABLE ();
207- #endif
208- __HAL_RCC_RTC_ENABLE ();
209205}
210206
211207#if defined(STM32F1xx )
@@ -342,44 +338,47 @@ static void RTC_computePrediv(int8_t *asynch, int16_t *synch)
342338bool RTC_init (hourFormat_t format , sourceClock_t source , bool reset )
343339{
344340 bool reinit = false;
341+ hourAM_PM_t period = HOUR_AM , alarmPeriod = HOUR_AM ;
342+ uint32_t subSeconds = 0 , alarmSubseconds = 0 ;
343+ uint8_t seconds = 0 , minutes = 0 , hours = 0 , weekDay = 0 , days = 0 , month = 0 , years = 0 ;
344+ uint8_t alarmMask = 0 , alarmDay = 0 , alarmHours = 0 , alarmMinutes = 0 , alarmSeconds = 0 ;
345+ bool isAlarmSet = false;
346+ #if defined(STM32F1xx )
347+ uint32_t asynch ;
348+ #else
349+ int8_t asynch ;
350+ int16_t sync ;
351+ #endif
345352
346353 initFormat = format ;
347-
348- /* Init RTC clock */
349- RTC_initClock (source );
350-
351354 RtcHandle .Instance = RTC ;
352355
353356 /* Ensure backup domain is enabled before we init the RTC so we can use the backup registers for date retention on stm32f1xx boards */
354357 enableBackupDomain ();
355358
356359 if (reset ) {
357360 resetBackupDomain ();
358- RTC_initClock (source );
359361 }
360362
363+ #ifdef __HAL_RCC_RTCAPB_CLK_ENABLE
364+ __HAL_RCC_RTCAPB_CLK_ENABLE ();
365+ #endif
366+ __HAL_RCC_RTC_ENABLE ();
367+
368+ isAlarmSet = RTC_IsAlarmSet ();
369+
361370#if defined(STM32F1xx )
362371 uint32_t BackupDate ;
363372 BackupDate = getBackupRegister (RTC_BKP_DATE ) << 16 ;
364373 BackupDate |= getBackupRegister (RTC_BKP_DATE + 1 ) & 0xFFFF ;
365374 if ((BackupDate == 0 ) || reset ) {
375+ // RTC needs initialization
366376 /* Let HAL calculate the prescaler */
367377 RtcHandle .Init .AsynchPrediv = prediv ;
368378 RtcHandle .Init .OutPut = RTC_OUTPUTSOURCE_NONE ;
369- HAL_RTC_Init (& RtcHandle );
370- // Default: saturday 1st of January 2001
371- // Note: year 2000 is invalid as it is the hardware reset value and doesn't raise INITS flag
372- RTC_SetDate (1 , 1 , 1 , 6 );
373- reinit = true;
374- } else {
375- memcpy (& RtcHandle .DateToUpdate , & BackupDate , 4 );
376- /* and fill the new RTC Date value */
377- RTC_SetDate (RtcHandle .DateToUpdate .Year , RtcHandle .DateToUpdate .Month ,
378- RtcHandle .DateToUpdate .Date , RtcHandle .DateToUpdate .WeekDay );
379- }
380379#else
381-
382380 if (!LL_RTC_IsActiveFlag_INITS (RtcHandle .Instance ) || reset ) {
381+ // RTC needs initialization
383382 RtcHandle .Init .HourFormat = format == HOUR_FORMAT_12 ? RTC_HOURFORMAT_12 : RTC_HOURFORMAT_24 ;
384383 RtcHandle .Init .OutPut = RTC_OUTPUT_DISABLE ;
385384 RtcHandle .Init .OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH ;
@@ -389,17 +388,87 @@ bool RTC_init(hourFormat_t format, sourceClock_t source, bool reset)
389388#endif /* RTC_OUTPUT_REMAP_NONE */
390389
391390 RTC_getPrediv ((int8_t * ) & (RtcHandle .Init .AsynchPrediv ), (int16_t * ) & (RtcHandle .Init .SynchPrediv ));
391+ #endif // STM32F1xx
392+ // Init RTC clock
393+ RTC_initClock (source );
392394
393395 HAL_RTC_Init (& RtcHandle );
394396 // Default: saturday 1st of January 2001
395397 // Note: year 2000 is invalid as it is the hardware reset value and doesn't raise INITS flag
396398 RTC_SetDate (1 , 1 , 1 , 6 );
397399 reinit = true;
398400 } else {
399- // This initialize variables: predivAsync, redivSync and predivSync_bits
400- RTC_getPrediv (NULL , NULL );
401+ // RTC is already initialized
402+ uint32_t oldRtcClockSource = __HAL_RCC_GET_RTC_SOURCE ();
403+ oldRtcClockSource = ((oldRtcClockSource == RCC_RTCCLKSOURCE_LSE ) ? LSE_CLOCK :
404+ (oldRtcClockSource == RCC_RTCCLKSOURCE_LSI ) ? LSI_CLOCK :
405+ #if defined(RCC_RTCCLKSOURCE_HSE_DIVX )
406+ (oldRtcClockSource == RCC_RTCCLKSOURCE_HSE_DIVX ) ? HSE_CLOCK :
407+ #elif defined(RCC_RTCCLKSOURCE_HSE_DIV32 )
408+ (oldRtcClockSource == RCC_RTCCLKSOURCE_HSE_DIV32 ) ? HSE_CLOCK :
409+ #elif defined(RCC_RTCCLKSOURCE_HSE_DIV )
410+ (oldRtcClockSource == RCC_RTCCLKSOURCE_HSE_DIV ) ? HSE_CLOCK :
411+ #elif defined(RCC_RTCCLKSOURCE_HSE_DIV128 )
412+ (oldRtcClockSource == RCC_RTCCLKSOURCE_HSE_DIV128 ) ? HSE_CLOCK :
413+ #endif
414+ // default case corresponding to no clock source
415+ 0xFFFFFFFF );
416+
417+ #if defined(STM32F1xx )
418+ if ((RtcHandle .DateToUpdate .WeekDay == 0 )
419+ && (RtcHandle .DateToUpdate .Month == 0 )
420+ && (RtcHandle .DateToUpdate .Date == 0 )
421+ && (RtcHandle .DateToUpdate .Year == 0 )) {
422+ // After a reset for example, restore HAL handle date with values from BackupRegister date
423+ memcpy (& RtcHandle .DateToUpdate , & BackupDate , 4 );
424+ }
425+ #endif // STM32F1xx
426+
427+ if (source != oldRtcClockSource ) {
428+ // RTC is already initialized, but RTC clock source is changed
429+ // In case of RTC source clock change, Backup Domain is reset by RTC_initClock()
430+ // Save current config before call to RTC_initClock()
431+ RTC_GetDate (& years , & month , & days , & weekDay );
432+ RTC_GetTime (& hours , & minutes , & seconds , & subSeconds , & period );
433+ #if defined(STM32F1xx )
434+ RTC_getPrediv (& asynch );
435+ #else
436+ RTC_getPrediv (& asynch , & sync );
437+ #endif // STM32F1xx
438+ if (isAlarmSet ) {
439+ RTC_GetAlarm (& alarmDay , & alarmHours , & alarmMinutes , & alarmSeconds , & alarmSubseconds , & alarmPeriod , & alarmMask );
440+ }
441+
442+ // Init RTC clock
443+ RTC_initClock (source );
444+
445+ // Restore config
446+ RTC_SetTime (hours , minutes , seconds , subSeconds , period );
447+ RTC_SetDate (years , month , days , weekDay );
448+ #if defined(STM32F1xx )
449+ RTC_setPrediv (asynch );
450+ #else
451+ RTC_setPrediv (asynch , sync );
452+ #endif // STM32F1xx
453+ if (isAlarmSet ) {
454+ RTC_StartAlarm (alarmDay , alarmHours , alarmMinutes , alarmSeconds , alarmSubseconds , alarmPeriod , alarmMask );
455+ }
456+ } else {
457+ // RTC is already initialized, and RTC stays on the same clock source
458+
459+ // Init RTC clock
460+ RTC_initClock (source );
461+ #if defined(STM32F1xx )
462+ memcpy (& RtcHandle .DateToUpdate , & BackupDate , 4 );
463+ /* and fill the new RTC Date value */
464+ RTC_SetDate (RtcHandle .DateToUpdate .Year , RtcHandle .DateToUpdate .Month ,
465+ RtcHandle .DateToUpdate .Date , RtcHandle .DateToUpdate .WeekDay );
466+ #else
467+ // This initialize variables: predivAsync, predivSync and predivSync_bits
468+ RTC_getPrediv (NULL , NULL );
469+ #endif // STM32F1xx
470+ }
401471 }
402- #endif /* STM32F1xx */
403472
404473#if defined(RTC_CR_BYPSHAD )
405474 /* Enable Direct Read of the calendar registers (not through Shadow) */
@@ -573,9 +642,6 @@ void RTC_GetDate(uint8_t *year, uint8_t *month, uint8_t *day, uint8_t *wday)
573642 * month = RTC_DateStruct .Month ;
574643 * day = RTC_DateStruct .Date ;
575644 * wday = RTC_DateStruct .WeekDay ;
576- #if defined(STM32F1xx )
577- RTC_StoreDate ();
578- #endif /* STM32F1xx */
579645 }
580646}
581647
0 commit comments