@@ -73,6 +73,7 @@ static uint8_t HSEDiv = 0;
7373static uint8_t predivSync_bits = 0xFF ;
7474static uint32_t predivAsync = (PREDIVA_MAX + 1 );
7575static uint32_t predivSync = (PREDIVS_MAX + 1 );
76+ static uint32_t fqce_apre ;
7677#else
7778/* Default, let HAL calculate the prescaler*/
7879static uint32_t predivAsync = RTC_AUTO_1_SECOND ;
@@ -335,6 +336,8 @@ static void RTC_computePrediv(uint32_t *asynch, uint32_t *synch)
335336 Error_Handler ();
336337 }
337338 * synch = predivS ;
339+
340+ fqce_apre = clkVal / (* asynch + 1 );
338341}
339342#endif /* !STM32F1xx */
340343
@@ -597,14 +600,14 @@ bool RTC_IsConfigured(void)
597600 * @param hours: 0-12 or 0-23. Depends on the format used.
598601 * @param minutes: 0-59
599602 * @param seconds: 0-59
600- * @param subSeconds: 0-999
603+ * @param subSeconds: 0-999 (not used)
601604 * @param period: select HOUR_AM or HOUR_PM period in case RTC is set in 12 hours mode. Else ignored.
602605 * @retval None
603606 */
604607void RTC_SetTime (uint8_t hours , uint8_t minutes , uint8_t seconds , uint32_t subSeconds , hourAM_PM_t period )
605608{
606609 RTC_TimeTypeDef RTC_TimeStruct ;
607- UNUSED (subSeconds );
610+ UNUSED (subSeconds ); /* not used (read-only register) */
608611 /* Ignore time AM PM configuration if in 24 hours format */
609612 if (initFormat == HOUR_FORMAT_24 ) {
610613 period = HOUR_AM ;
@@ -670,7 +673,16 @@ void RTC_GetTime(uint8_t *hours, uint8_t *minutes, uint8_t *seconds, uint32_t *s
670673 }
671674#if defined(RTC_SSR_SS )
672675 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+ }
674686 }
675687#else
676688 UNUSED (subSeconds );
@@ -738,7 +750,7 @@ void RTC_GetDate(uint8_t *year, uint8_t *month, uint8_t *day, uint8_t *wday)
738750 * @param hours: 0-12 or 0-23 depends on the hours mode.
739751 * @param minutes: 0-59
740752 * @param seconds: 0-59
741- * @param subSeconds: 0-999
753+ * @param subSeconds: 0-999 milliseconds
742754 * @param period: HOUR_AM or HOUR_PM if in 12 hours mode else ignored.
743755 * @param mask: configure alarm behavior using alarmMask_t combination.
744756 * 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
753765 period = HOUR_AM ;
754766 }
755767
768+ /* Use alarm A by default because it is common to all STM32 HAL */
769+ RTC_AlarmStructure .Alarm = name ;
770+
756771 if ((((initFormat == HOUR_FORMAT_24 ) && IS_RTC_HOUR24 (hours )) || IS_RTC_HOUR12 (hours ))
757772 && IS_RTC_DATE (day ) && IS_RTC_MINUTES (minutes ) && IS_RTC_SECONDS (seconds )) {
758773 /* 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 ;
761774 RTC_AlarmStructure .AlarmTime .Seconds = seconds ;
762775 RTC_AlarmStructure .AlarmTime .Minutes = minutes ;
763776 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
772785 {
773786 RTC_AlarmStructure .AlarmSubSecondMask = predivSync_bits << RTC_ALRMASSR_MASKSS_Pos ;
774787 }
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+ }
776794 } else {
777795 RTC_AlarmStructure .AlarmSubSecondMask = RTC_ALARMSUBSECONDMASK_ALL ;
778796 }
@@ -813,6 +831,41 @@ void RTC_StartAlarm(alarm_t name, uint8_t day, uint8_t hours, uint8_t minutes, u
813831 UNUSED (mask );
814832#endif /* !STM32F1xx */
815833
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 */
816869 /* Set RTC_Alarm */
817870 HAL_RTC_SetAlarm_IT (& RtcHandle , & RTC_AlarmStructure , RTC_FORMAT_BIN );
818871 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,
903956 }
904957#if defined(RTC_SSR_SS )
905958 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+ }
907968 }
908969#else
909970 UNUSED (subSeconds );
0 commit comments