Skip to content

Commit 87aec09

Browse files
committed
stm32RTC with subsecond to milliseconds conversion
The binaryMode_t is retrieved directly from the RTC mode, not as a parameter. The Subsecond parameter is expressed in millisecond in RTC_SetTime/GetTime RTC_StartAlarm/GetAlarm
1 parent 1a4506f commit 87aec09

File tree

2 files changed

+32
-25
lines changed

2 files changed

+32
-25
lines changed

src/STM32RTC.cpp

Lines changed: 4 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -242,13 +242,13 @@ void STM32RTC::enableAlarm(Alarm_Match match, Alarm name)
242242
#ifdef RTC_ALARM_B
243243
if (name == ALARM_B) {
244244
RTC_StartAlarm(::ALARM_B, 0, 0, 0, 0,
245-
(UINT32_MAX - _alarmBSubSeconds), (_alarmBPeriod == AM) ? HOUR_AM : HOUR_PM,
245+
_alarmBSubSeconds, (_alarmBPeriod == AM) ? HOUR_AM : HOUR_PM,
246246
static_cast<uint8_t>(31UL));
247247
} else
248248
#endif
249249
{
250250
RTC_StartAlarm(::ALARM_A, 0, 0, 0, 0,
251-
(UINT32_MAX - _alarmSubSeconds), (_alarmPeriod == AM) ? HOUR_AM : HOUR_PM,
251+
_alarmSubSeconds, (_alarmPeriod == AM) ? HOUR_AM : HOUR_PM,
252252
static_cast<uint8_t>(31UL));
253253
}
254254
break;
@@ -647,7 +647,7 @@ uint8_t STM32RTC::getAlarmYear(void)
647647

648648
/**
649649
* @brief set RTC subseconds.
650-
* @param subseconds: 0-999
650+
* @param subseconds: 0-999 milliseconds
651651
* @retval none
652652
*/
653653
void STM32RTC::setSubSeconds(uint32_t subSeconds)
@@ -859,8 +859,7 @@ void STM32RTC::setDate(uint8_t weekDay, uint8_t day, uint8_t month, uint8_t year
859859
*/
860860
void STM32RTC::setAlarmSubSeconds(uint32_t subSeconds, Alarm name)
861861
{
862-
863-
if (getBinaryMode() == MODE_MIX) {
862+
if (subSeconds < 1000) {
864863
#ifdef RTC_ALARM_B
865864
if (name == ALARM_B) {
866865
_alarmBSubSeconds = subSeconds;
@@ -871,19 +870,6 @@ void STM32RTC::setAlarmSubSeconds(uint32_t subSeconds, Alarm name)
871870
{
872871
_alarmSubSeconds = subSeconds;
873872
}
874-
} else {
875-
if (subSeconds < 1000) {
876-
#ifdef RTC_ALARM_B
877-
if (name == ALARM_B) {
878-
_alarmBSubSeconds = subSeconds;
879-
}
880-
#else
881-
UNUSED(name);
882-
#endif
883-
{
884-
_alarmSubSeconds = subSeconds;
885-
}
886-
}
887873
}
888874
}
889875

src/rtc.c

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,9 @@ static int16_t predivSync = -1;
7676
static uint32_t prediv = RTC_AUTO_1_SECOND;
7777
#endif /* !STM32F1xx */
7878

79+
/* predivAsync is 0x7F with LSE clock source */
80+
static uint32_t fqce_apre;
81+
7982
static hourFormat_t initFormat = HOUR_FORMAT_12;
8083
static binaryMode_t initMode = MODE_BINARY_NONE;
8184

@@ -326,6 +329,8 @@ static void RTC_computePrediv(int8_t *asynch, int16_t *synch)
326329
Error_Handler();
327330
}
328331
*synch = (int16_t)predivS;
332+
333+
fqce_apre = clkVal / (*asynch + 1);
329334
}
330335
#endif /* !STM32F1xx */
331336

@@ -586,7 +591,7 @@ bool RTC_IsConfigured(void)
586591
* @param hours: 0-12 or 0-23. Depends on the format used.
587592
* @param minutes: 0-59
588593
* @param seconds: 0-59
589-
* @param subSeconds: 0-999 (not used)
594+
* @param subSeconds: 0-999 (not used and SSR register is set to 0xffffffff)
590595
* @param period: select HOUR_AM or HOUR_PM period in case RTC is set in 12 hours mode. Else ignored.
591596
* @retval None
592597
*/
@@ -660,8 +665,13 @@ void RTC_GetTime(uint8_t *hours, uint8_t *minutes, uint8_t *seconds, uint32_t *s
660665
#if defined(RTC_SSR_SS)
661666
if (subSeconds != NULL) {
662667
if (initMode == MODE_BINARY_MIX) {
663-
*subSeconds = UINT32_MAX - RTC_TimeStruct.SubSeconds;
668+
/* The subsecond is the free-running downcounter, to be converted in milliseconds */
669+
*subSeconds = (((UINT32_MAX - RTC_TimeStruct.SubSeconds + 1) & UINT32_MAX)
670+
* 1000) / fqce_apre;
671+
/* give one more to compensate the 3.9ms uncertainty */
672+
*subSeconds = *subSeconds % 1000; /* value in milliseconds [0-999] */
664673
} else {
674+
/* the subsecond register value is converted in millisec */
665675
*subSeconds = ((predivSync - RTC_TimeStruct.SubSeconds) * 1000) / (predivSync + 1);
666676
}
667677
}
@@ -731,7 +741,7 @@ void RTC_GetDate(uint8_t *year, uint8_t *month, uint8_t *day, uint8_t *wday)
731741
* @param hours: 0-12 or 0-23 depends on the hours mode.
732742
* @param minutes: 0-59
733743
* @param seconds: 0-59
734-
* @param subSeconds: 0-999
744+
* @param subSeconds: 0-999 milliseconds
735745
* @param period: HOUR_AM or HOUR_PM if in 12 hours mode else ignored.
736746
* @param mask: configure alarm behavior using alarmMask_t combination.
737747
* See AN4579 Table 5 for possible values.
@@ -766,7 +776,13 @@ void RTC_StartAlarm(alarm_t name, uint8_t day, uint8_t hours, uint8_t minutes, u
766776
{
767777
RTC_AlarmStructure.AlarmSubSecondMask = predivSync_bits << RTC_ALRMASSR_MASKSS_Pos;
768778
}
769-
RTC_AlarmStructure.AlarmTime.SubSeconds = predivSync - (subSeconds * (predivSync + 1)) / 1000;
779+
if (initMode == MODE_BINARY_MIX) {
780+
/* the subsecond is the millisecond to be converted in a subsecond downcounter value */
781+
RTC_AlarmStructure.AlarmTime.SubSeconds = UINT32_MAX - ((subSeconds * fqce_apre) / 1000 + 1);
782+
/* give one more to compensate the 3.9ms uncertainty */
783+
} else {
784+
RTC_AlarmStructure.AlarmTime.SubSeconds = predivSync - (subSeconds * (predivSync + 1)) / 1000;
785+
}
770786
} else {
771787
RTC_AlarmStructure.AlarmSubSecondMask = RTC_ALARMSUBSECONDMASK_ALL;
772788
}
@@ -830,8 +846,8 @@ void RTC_StartAlarm(alarm_t name, uint8_t day, uint8_t hours, uint8_t minutes, u
830846
/* Expecting RTC_ALARMSUBSECONDBINMASK_NONE for the subsecond mask on ALARM A */
831847
RTC_AlarmStructure.AlarmSubSecondMask = mask << RTC_ALRMASSR_MASKSS_Pos;
832848
}
833-
/* Special case for ALARM B configuration for stm32WL Lorawan */
834-
RTC_AlarmStructure.AlarmTime.SubSeconds = subSeconds;
849+
/* The subsecond in ms is converted in ticks unit 1 tick is 1000 / fqce_apre */
850+
RTC_AlarmStructure.AlarmTime.SubSeconds = UINT32_MAX - (subSeconds * fqce_apre) / 1000;
835851
}
836852

837853
#else
@@ -928,7 +944,12 @@ void RTC_GetAlarm(alarm_t name, uint8_t *day, uint8_t *hours, uint8_t *minutes,
928944
#if defined(RTC_SSR_SS)
929945
if (subSeconds != NULL) {
930946
if (initMode == MODE_BINARY_MIX) {
931-
*subSeconds = UINT32_MAX - RTC_AlarmStructure.AlarmTime.SubSeconds;
947+
/*
948+
* The subsecond is the bit SS[14:0] of the ALARM SSR register (not ALARMxINR)
949+
* to be converted in milliseconds
950+
*/
951+
*subSeconds = (((0x7fff - RTC_AlarmStructure.AlarmTime.SubSeconds + 1) & 0x7fff) * 1000) / fqce_apre;
952+
*subSeconds = *subSeconds % 1000; /* value in milliseconds [0-999] */
932953
} else {
933954
*subSeconds = ((predivSync - RTC_AlarmStructure.AlarmTime.SubSeconds) * 1000) / (predivSync + 1);
934955
}

0 commit comments

Comments
 (0)