@@ -73,6 +73,7 @@ static uint8_t HSEDiv = 0;
73
73
static uint8_t predivSync_bits = 0xFF ;
74
74
static uint32_t predivAsync = (PREDIVA_MAX + 1 );
75
75
static uint32_t predivSync = (PREDIVS_MAX + 1 );
76
+ static uint32_t fqce_apre ;
76
77
#else
77
78
/* Default, let HAL calculate the prescaler*/
78
79
static uint32_t predivAsync = RTC_AUTO_1_SECOND ;
@@ -335,6 +336,8 @@ static void RTC_computePrediv(uint32_t *asynch, uint32_t *synch)
335
336
Error_Handler ();
336
337
}
337
338
* synch = predivS ;
339
+
340
+ fqce_apre = clkVal / (* asynch + 1 );
338
341
}
339
342
#endif /* !STM32F1xx */
340
343
@@ -597,14 +600,14 @@ bool RTC_IsConfigured(void)
597
600
* @param hours: 0-12 or 0-23. Depends on the format used.
598
601
* @param minutes: 0-59
599
602
* @param seconds: 0-59
600
- * @param subSeconds: 0-999
603
+ * @param subSeconds: 0-999 (not used)
601
604
* @param period: select HOUR_AM or HOUR_PM period in case RTC is set in 12 hours mode. Else ignored.
602
605
* @retval None
603
606
*/
604
607
void RTC_SetTime (uint8_t hours , uint8_t minutes , uint8_t seconds , uint32_t subSeconds , hourAM_PM_t period )
605
608
{
606
609
RTC_TimeTypeDef RTC_TimeStruct ;
607
- UNUSED (subSeconds );
610
+ UNUSED (subSeconds ); /* not used (read-only register) */
608
611
/* Ignore time AM PM configuration if in 24 hours format */
609
612
if (initFormat == HOUR_FORMAT_24 ) {
610
613
period = HOUR_AM ;
@@ -670,7 +673,16 @@ void RTC_GetTime(uint8_t *hours, uint8_t *minutes, uint8_t *seconds, uint32_t *s
670
673
}
671
674
#if defined(RTC_SSR_SS )
672
675
if (subSeconds != NULL ) {
673
- * subSeconds = ((predivSync - RTC_TimeStruct .SubSeconds ) * 1000 ) / (predivSync + 1 );
676
+ if (initMode == MODE_BINARY_MIX ) {
677
+ /* The subsecond is the free-running downcounter, to be converted in milliseconds */
678
+ * subSeconds = (((UINT32_MAX - RTC_TimeStruct .SubSeconds + 1 ) & UINT32_MAX )
679
+ * 1000 ) / fqce_apre ; /* give one more to compensate the 3.9ms uncertainty */
680
+ * subSeconds = * subSeconds % 1000 ; /* nb of milliseconds */
681
+ /* predivAsync is 0x7F with LSE clock source */
682
+ } else {
683
+ /* the subsecond register value is converted in millisec */
684
+ * subSeconds = ((predivSync - RTC_TimeStruct .SubSeconds ) * 1000 ) / (predivSync + 1 );
685
+ }
674
686
}
675
687
#else
676
688
UNUSED (subSeconds );
@@ -738,7 +750,7 @@ void RTC_GetDate(uint8_t *year, uint8_t *month, uint8_t *day, uint8_t *wday)
738
750
* @param hours: 0-12 or 0-23 depends on the hours mode.
739
751
* @param minutes: 0-59
740
752
* @param seconds: 0-59
741
- * @param subSeconds: 0-999
753
+ * @param subSeconds: 0-999 milliseconds
742
754
* @param period: HOUR_AM or HOUR_PM if in 12 hours mode else ignored.
743
755
* @param mask: configure alarm behavior using alarmMask_t combination.
744
756
* See AN4579 Table 5 for possible values.
@@ -753,11 +765,12 @@ void RTC_StartAlarm(alarm_t name, uint8_t day, uint8_t hours, uint8_t minutes, u
753
765
period = HOUR_AM ;
754
766
}
755
767
768
+ /* Use alarm A by default because it is common to all STM32 HAL */
769
+ RTC_AlarmStructure .Alarm = name ;
770
+
756
771
if ((((initFormat == HOUR_FORMAT_24 ) && IS_RTC_HOUR24 (hours )) || IS_RTC_HOUR12 (hours ))
757
772
&& IS_RTC_DATE (day ) && IS_RTC_MINUTES (minutes ) && IS_RTC_SECONDS (seconds )) {
758
773
/* Set RTC_AlarmStructure with calculated values*/
759
- /* Use alarm A by default because it is common to all STM32 HAL */
760
- RTC_AlarmStructure .Alarm = name ;
761
774
RTC_AlarmStructure .AlarmTime .Seconds = seconds ;
762
775
RTC_AlarmStructure .AlarmTime .Minutes = minutes ;
763
776
RTC_AlarmStructure .AlarmTime .Hours = hours ;
@@ -772,7 +785,12 @@ void RTC_StartAlarm(alarm_t name, uint8_t day, uint8_t hours, uint8_t minutes, u
772
785
{
773
786
RTC_AlarmStructure .AlarmSubSecondMask = predivSync_bits << RTC_ALRMASSR_MASKSS_Pos ;
774
787
}
775
- RTC_AlarmStructure .AlarmTime .SubSeconds = predivSync - (subSeconds * (predivSync + 1 )) / 1000 ;
788
+ if (initMode == MODE_BINARY_MIX ) {
789
+ /* the subsecond is the millisecond to be converted in a subsecond downcounter value */
790
+ RTC_AlarmStructure .AlarmTime .SubSeconds = UINT32_MAX - ((subSeconds * fqce_apre ) / 1000 + 1 );
791
+ } else {
792
+ RTC_AlarmStructure .AlarmTime .SubSeconds = predivSync - (subSeconds * (predivSync + 1 )) / 1000 ;
793
+ }
776
794
} else {
777
795
RTC_AlarmStructure .AlarmSubSecondMask = RTC_ALARMSUBSECONDMASK_ALL ;
778
796
}
@@ -813,6 +831,41 @@ void RTC_StartAlarm(alarm_t name, uint8_t day, uint8_t hours, uint8_t minutes, u
813
831
UNUSED (mask );
814
832
#endif /* !STM32F1xx */
815
833
834
+ /* Set RTC_Alarm */
835
+ HAL_RTC_SetAlarm_IT (& RtcHandle , & RTC_AlarmStructure , RTC_FORMAT_BIN );
836
+ HAL_NVIC_SetPriority (RTC_Alarm_IRQn , RTC_IRQ_PRIO , RTC_IRQ_SUBPRIO );
837
+ HAL_NVIC_EnableIRQ (RTC_Alarm_IRQn );
838
+ #if defined(RTC_ICSR_BIN )
839
+ } else if (RtcHandle .Init .BinMode != RTC_BINARY_NONE ) {
840
+ /* We have an SubSecond alarm to set in RTC_BINARY_MIX or RTC_BINARY_ONLY mode */
841
+ #else
842
+ } else {
843
+ #endif /* RTC_ICSR_BIN */
844
+ #if defined(RTC_SSR_SS )
845
+ {
846
+ #if defined(RTC_ALRMASSR_SSCLR )
847
+ RTC_AlarmStructure .BinaryAutoClr = RTC_ALARMSUBSECONDBIN_AUTOCLR_NO ;
848
+ #endif /* RTC_ALRMASSR_SSCLR */
849
+ RTC_AlarmStructure .AlarmMask = RTC_ALARMMASK_ALL ;
850
+
851
+ #ifdef RTC_ALARM_B
852
+ if (name == ALARM_B )
853
+ {
854
+ /* Expecting RTC_ALARMSUBSECONDBINMASK_NONE for the subsecond mask on ALARM B */
855
+ RTC_AlarmStructure .AlarmSubSecondMask = mask << RTC_ALRMBSSR_MASKSS_Pos ;
856
+ } else
857
+ #endif
858
+ {
859
+ /* Expecting RTC_ALARMSUBSECONDBINMASK_NONE for the subsecond mask on ALARM A */
860
+ RTC_AlarmStructure .AlarmSubSecondMask = mask << RTC_ALRMASSR_MASKSS_Pos ;
861
+ }
862
+ /* The subsecond in ms is converted in ticks unit 1 tick is 1000 / fqce_apre */
863
+ RTC_AlarmStructure .AlarmTime .SubSeconds = UINT32_MAX - (subSeconds * fqce_apre ) / 1000 ;
864
+ }
865
+
866
+ #else
867
+ UNUSED (subSeconds );
868
+ #endif /* RTC_SSR_SS */
816
869
/* Set RTC_Alarm */
817
870
HAL_RTC_SetAlarm_IT (& RtcHandle , & RTC_AlarmStructure , RTC_FORMAT_BIN );
818
871
HAL_NVIC_SetPriority (RTC_Alarm_IRQn , RTC_IRQ_PRIO , RTC_IRQ_SUBPRIO );
@@ -903,7 +956,15 @@ void RTC_GetAlarm(alarm_t name, uint8_t *day, uint8_t *hours, uint8_t *minutes,
903
956
}
904
957
#if defined(RTC_SSR_SS )
905
958
if (subSeconds != NULL ) {
906
- * subSeconds = ((predivSync - RTC_AlarmStructure .AlarmTime .SubSeconds ) * 1000 ) / (predivSync + 1 );
959
+ if (initMode == MODE_BINARY_MIX ) {
960
+ /*
961
+ * The subsecond is the bit SS[14:0] of the ALARM SSR register (not ALARMxINR)
962
+ * to be converted in milliseconds
963
+ */
964
+ * subSeconds = (((0x7fff - RTC_AlarmStructure .AlarmTime .SubSeconds + 1 ) & 0x7fff ) * 1000 ) / fqce_apre ;
965
+ } else {
966
+ * subSeconds = ((predivSync - RTC_AlarmStructure .AlarmTime .SubSeconds ) * 1000 ) / (predivSync + 1 );
967
+ }
907
968
}
908
969
#else
909
970
UNUSED (subSeconds );
0 commit comments