Skip to content

Commit 62a49d8

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 Signed-off-by: Francois Ramu <[email protected]>
1 parent fa25cbf commit 62a49d8

File tree

2 files changed

+28
-24
lines changed

2 files changed

+28
-24
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: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,8 @@ static int16_t predivSync = -1;
7676
static uint32_t prediv = RTC_AUTO_1_SECOND;
7777
#endif /* !STM32F1xx */
7878

79+
static uint32_t fqce_apre;
80+
7981
static hourFormat_t initFormat = HOUR_FORMAT_12;
8082
static binaryMode_t initMode = MODE_BINARY_NONE;
8183

@@ -373,6 +375,8 @@ static void RTC_computePrediv(int8_t *asynch, int16_t *synch)
373375
Error_Handler();
374376
}
375377
*synch = (int16_t)predivS;
378+
379+
fqce_apre = clkVal / (*asynch + 1);
376380
}
377381
#endif /* !STM32F1xx */
378382

@@ -707,8 +711,13 @@ void RTC_GetTime(uint8_t *hours, uint8_t *minutes, uint8_t *seconds, uint32_t *s
707711
#if defined(RTC_SSR_SS)
708712
if (subSeconds != NULL) {
709713
if (initMode == MODE_BINARY_MIX) {
710-
*subSeconds = UINT32_MAX - RTC_TimeStruct.SubSeconds;
714+
/* The subsecond is the free-running downcounter, to be converted in milliseconds */
715+
*subSeconds = (((UINT32_MAX - RTC_TimeStruct.SubSeconds + 1) & UINT32_MAX)
716+
* 1000) / fqce_apre; /* give one more to compensate the 3.9ms uncertainty */
717+
*subSeconds = *subSeconds % 1000; /* nb of milliseconds */
718+
/* predivAsync is 0x7F with LSE clock source */
711719
} else {
720+
/* the subsecond register value is converted in millisec */
712721
*subSeconds = ((predivSync - RTC_TimeStruct.SubSeconds) * 1000) / (predivSync + 1);
713722
}
714723
}
@@ -778,7 +787,7 @@ void RTC_GetDate(uint8_t *year, uint8_t *month, uint8_t *day, uint8_t *wday)
778787
* @param hours: 0-12 or 0-23 depends on the hours mode.
779788
* @param minutes: 0-59
780789
* @param seconds: 0-59
781-
* @param subSeconds: 0-999
790+
* @param subSeconds: 0-999 milliseconds
782791
* @param period: HOUR_AM or HOUR_PM if in 12 hours mode else ignored.
783792
* @param mask: configure alarm behavior using alarmMask_t combination.
784793
* See AN4579 Table 5 for possible values.
@@ -813,7 +822,12 @@ void RTC_StartAlarm(alarm_t name, uint8_t day, uint8_t hours, uint8_t minutes, u
813822
{
814823
RTC_AlarmStructure.AlarmSubSecondMask = predivSync_bits << RTC_ALRMASSR_MASKSS_Pos;
815824
}
816-
RTC_AlarmStructure.AlarmTime.SubSeconds = predivSync - (subSeconds * (predivSync + 1)) / 1000;
825+
if (initMode == MODE_BINARY_MIX) {
826+
/* the subsecond is the millisecond to be converted in a subsecond downcounter value */
827+
RTC_AlarmStructure.AlarmTime.SubSeconds = UINT32_MAX - ((subSeconds * fqce_apre) / 1000 + 1);
828+
} else {
829+
RTC_AlarmStructure.AlarmTime.SubSeconds = predivSync - (subSeconds * (predivSync + 1)) / 1000;
830+
}
817831
} else {
818832
RTC_AlarmStructure.AlarmSubSecondMask = RTC_ALARMSUBSECONDMASK_ALL;
819833
}
@@ -882,8 +896,8 @@ void RTC_StartAlarm(alarm_t name, uint8_t day, uint8_t hours, uint8_t minutes, u
882896
/* Expecting RTC_ALARMSUBSECONDBINMASK_NONE for the subsecond mask on ALARM A */
883897
RTC_AlarmStructure.AlarmSubSecondMask = mask << RTC_ALRMASSR_MASKSS_Pos;
884898
}
885-
/* Special case for ALARM B configuration when using subsecond reg. in RTC Mix mode */
886-
RTC_AlarmStructure.AlarmTime.SubSeconds = subSeconds;
899+
/* The subsecond in ms is converted in ticks unit 1 tick is 1000 / fqce_apre */
900+
RTC_AlarmStructure.AlarmTime.SubSeconds = UINT32_MAX - (subSeconds * fqce_apre) / 1000;
887901
}
888902

889903
#else
@@ -980,7 +994,11 @@ void RTC_GetAlarm(alarm_t name, uint8_t *day, uint8_t *hours, uint8_t *minutes,
980994
#if defined(RTC_SSR_SS)
981995
if (subSeconds != NULL) {
982996
if (initMode == MODE_BINARY_MIX) {
983-
*subSeconds = UINT32_MAX - RTC_AlarmStructure.AlarmTime.SubSeconds;
997+
/*
998+
* The subsecond is the bit SS[14:0] of the ALARM SSR register (not ALARMxINR)
999+
* to be converted in milliseconds
1000+
*/
1001+
*subSeconds = (((0x7fff - RTC_AlarmStructure.AlarmTime.SubSeconds + 1) & 0x7fff) * 1000) / fqce_apre;
9841002
} else {
9851003
*subSeconds = ((predivSync - RTC_AlarmStructure.AlarmTime.SubSeconds) * 1000) / (predivSync + 1);
9861004
}

0 commit comments

Comments
 (0)