@@ -202,10 +202,6 @@ static void RTC_initClock(sourceClock_t source)
202
202
} else {
203
203
Error_Handler ();
204
204
}
205
- #ifdef __HAL_RCC_RTCAPB_CLK_ENABLE
206
- __HAL_RCC_RTCAPB_CLK_ENABLE ();
207
- #endif
208
- __HAL_RCC_RTC_ENABLE ();
209
205
}
210
206
211
207
#if defined(STM32F1xx )
@@ -342,44 +338,47 @@ static void RTC_computePrediv(int8_t *asynch, int16_t *synch)
342
338
bool RTC_init (hourFormat_t format , sourceClock_t source , bool reset )
343
339
{
344
340
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
345
352
346
353
initFormat = format ;
347
-
348
- /* Init RTC clock */
349
- RTC_initClock (source );
350
-
351
354
RtcHandle .Instance = RTC ;
352
355
353
356
/* Ensure backup domain is enabled before we init the RTC so we can use the backup registers for date retention on stm32f1xx boards */
354
357
enableBackupDomain ();
355
358
356
359
if (reset ) {
357
360
resetBackupDomain ();
358
- RTC_initClock (source );
359
361
}
360
362
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
+
361
370
#if defined(STM32F1xx )
362
371
uint32_t BackupDate ;
363
372
BackupDate = getBackupRegister (RTC_BKP_DATE ) << 16 ;
364
373
BackupDate |= getBackupRegister (RTC_BKP_DATE + 1 ) & 0xFFFF ;
365
374
if ((BackupDate == 0 ) || reset ) {
375
+ // RTC needs initialization
366
376
/* Let HAL calculate the prescaler */
367
377
RtcHandle .Init .AsynchPrediv = prediv ;
368
378
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
- }
380
379
#else
381
-
382
380
if (!LL_RTC_IsActiveFlag_INITS (RtcHandle .Instance ) || reset ) {
381
+ // RTC needs initialization
383
382
RtcHandle .Init .HourFormat = format == HOUR_FORMAT_12 ? RTC_HOURFORMAT_12 : RTC_HOURFORMAT_24 ;
384
383
RtcHandle .Init .OutPut = RTC_OUTPUT_DISABLE ;
385
384
RtcHandle .Init .OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH ;
@@ -389,17 +388,87 @@ bool RTC_init(hourFormat_t format, sourceClock_t source, bool reset)
389
388
#endif /* RTC_OUTPUT_REMAP_NONE */
390
389
391
390
RTC_getPrediv ((int8_t * ) & (RtcHandle .Init .AsynchPrediv ), (int16_t * ) & (RtcHandle .Init .SynchPrediv ));
391
+ #endif // STM32F1xx
392
+ // Init RTC clock
393
+ RTC_initClock (source );
392
394
393
395
HAL_RTC_Init (& RtcHandle );
394
396
// Default: saturday 1st of January 2001
395
397
// Note: year 2000 is invalid as it is the hardware reset value and doesn't raise INITS flag
396
398
RTC_SetDate (1 , 1 , 1 , 6 );
397
399
reinit = true;
398
400
} 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
+ }
401
471
}
402
- #endif /* STM32F1xx */
403
472
404
473
#if defined(RTC_CR_BYPSHAD )
405
474
/* 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)
573
642
* month = RTC_DateStruct .Month ;
574
643
* day = RTC_DateStruct .Date ;
575
644
* wday = RTC_DateStruct .WeekDay ;
576
- #if defined(STM32F1xx )
577
- RTC_StoreDate ();
578
- #endif /* STM32F1xx */
579
645
}
580
646
}
581
647
0 commit comments