Skip to content

Commit

Permalink
stm32RTC with subsecond to milliseconds conversion
Browse files Browse the repository at this point in the history
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
  • Loading branch information
FRASTM committed Jul 21, 2023
1 parent 1a4506f commit 87aec09
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 25 deletions.
22 changes: 4 additions & 18 deletions src/STM32RTC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -242,13 +242,13 @@ void STM32RTC::enableAlarm(Alarm_Match match, Alarm name)
#ifdef RTC_ALARM_B
if (name == ALARM_B) {
RTC_StartAlarm(::ALARM_B, 0, 0, 0, 0,
(UINT32_MAX - _alarmBSubSeconds), (_alarmBPeriod == AM) ? HOUR_AM : HOUR_PM,
_alarmBSubSeconds, (_alarmBPeriod == AM) ? HOUR_AM : HOUR_PM,
static_cast<uint8_t>(31UL));
} else
#endif
{
RTC_StartAlarm(::ALARM_A, 0, 0, 0, 0,
(UINT32_MAX - _alarmSubSeconds), (_alarmPeriod == AM) ? HOUR_AM : HOUR_PM,
_alarmSubSeconds, (_alarmPeriod == AM) ? HOUR_AM : HOUR_PM,
static_cast<uint8_t>(31UL));
}
break;
Expand Down Expand Up @@ -647,7 +647,7 @@ uint8_t STM32RTC::getAlarmYear(void)

/**
* @brief set RTC subseconds.
* @param subseconds: 0-999
* @param subseconds: 0-999 milliseconds
* @retval none
*/
void STM32RTC::setSubSeconds(uint32_t subSeconds)
Expand Down Expand Up @@ -859,8 +859,7 @@ void STM32RTC::setDate(uint8_t weekDay, uint8_t day, uint8_t month, uint8_t year
*/
void STM32RTC::setAlarmSubSeconds(uint32_t subSeconds, Alarm name)
{

if (getBinaryMode() == MODE_MIX) {
if (subSeconds < 1000) {
#ifdef RTC_ALARM_B
if (name == ALARM_B) {
_alarmBSubSeconds = subSeconds;
Expand All @@ -871,19 +870,6 @@ void STM32RTC::setAlarmSubSeconds(uint32_t subSeconds, Alarm name)
{
_alarmSubSeconds = subSeconds;
}
} else {
if (subSeconds < 1000) {
#ifdef RTC_ALARM_B
if (name == ALARM_B) {
_alarmBSubSeconds = subSeconds;
}
#else
UNUSED(name);
#endif
{
_alarmSubSeconds = subSeconds;
}
}
}
}

Expand Down
35 changes: 28 additions & 7 deletions src/rtc.c
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,9 @@ static int16_t predivSync = -1;
static uint32_t prediv = RTC_AUTO_1_SECOND;
#endif /* !STM32F1xx */

/* predivAsync is 0x7F with LSE clock source */
static uint32_t fqce_apre;

static hourFormat_t initFormat = HOUR_FORMAT_12;
static binaryMode_t initMode = MODE_BINARY_NONE;

Expand Down Expand Up @@ -326,6 +329,8 @@ static void RTC_computePrediv(int8_t *asynch, int16_t *synch)
Error_Handler();
}
*synch = (int16_t)predivS;

fqce_apre = clkVal / (*asynch + 1);
}
#endif /* !STM32F1xx */

Expand Down Expand Up @@ -586,7 +591,7 @@ bool RTC_IsConfigured(void)
* @param hours: 0-12 or 0-23. Depends on the format used.
* @param minutes: 0-59
* @param seconds: 0-59
* @param subSeconds: 0-999 (not used)
* @param subSeconds: 0-999 (not used and SSR register is set to 0xffffffff)
* @param period: select HOUR_AM or HOUR_PM period in case RTC is set in 12 hours mode. Else ignored.
* @retval None
*/
Expand Down Expand Up @@ -660,8 +665,13 @@ void RTC_GetTime(uint8_t *hours, uint8_t *minutes, uint8_t *seconds, uint32_t *s
#if defined(RTC_SSR_SS)
if (subSeconds != NULL) {
if (initMode == MODE_BINARY_MIX) {
*subSeconds = UINT32_MAX - RTC_TimeStruct.SubSeconds;
/* The subsecond is the free-running downcounter, to be converted in milliseconds */
*subSeconds = (((UINT32_MAX - RTC_TimeStruct.SubSeconds + 1) & UINT32_MAX)
* 1000) / fqce_apre;
/* give one more to compensate the 3.9ms uncertainty */
*subSeconds = *subSeconds % 1000; /* value in milliseconds [0-999] */
} else {
/* the subsecond register value is converted in millisec */
*subSeconds = ((predivSync - RTC_TimeStruct.SubSeconds) * 1000) / (predivSync + 1);
}
}
Expand Down Expand Up @@ -731,7 +741,7 @@ void RTC_GetDate(uint8_t *year, uint8_t *month, uint8_t *day, uint8_t *wday)
* @param hours: 0-12 or 0-23 depends on the hours mode.
* @param minutes: 0-59
* @param seconds: 0-59
* @param subSeconds: 0-999
* @param subSeconds: 0-999 milliseconds
* @param period: HOUR_AM or HOUR_PM if in 12 hours mode else ignored.
* @param mask: configure alarm behavior using alarmMask_t combination.
* See AN4579 Table 5 for possible values.
Expand Down Expand Up @@ -766,7 +776,13 @@ void RTC_StartAlarm(alarm_t name, uint8_t day, uint8_t hours, uint8_t minutes, u
{
RTC_AlarmStructure.AlarmSubSecondMask = predivSync_bits << RTC_ALRMASSR_MASKSS_Pos;
}
RTC_AlarmStructure.AlarmTime.SubSeconds = predivSync - (subSeconds * (predivSync + 1)) / 1000;
if (initMode == MODE_BINARY_MIX) {
/* the subsecond is the millisecond to be converted in a subsecond downcounter value */
RTC_AlarmStructure.AlarmTime.SubSeconds = UINT32_MAX - ((subSeconds * fqce_apre) / 1000 + 1);
/* give one more to compensate the 3.9ms uncertainty */
} else {
RTC_AlarmStructure.AlarmTime.SubSeconds = predivSync - (subSeconds * (predivSync + 1)) / 1000;
}
} else {
RTC_AlarmStructure.AlarmSubSecondMask = RTC_ALARMSUBSECONDMASK_ALL;
}
Expand Down Expand Up @@ -830,8 +846,8 @@ void RTC_StartAlarm(alarm_t name, uint8_t day, uint8_t hours, uint8_t minutes, u
/* Expecting RTC_ALARMSUBSECONDBINMASK_NONE for the subsecond mask on ALARM A */
RTC_AlarmStructure.AlarmSubSecondMask = mask << RTC_ALRMASSR_MASKSS_Pos;
}
/* Special case for ALARM B configuration for stm32WL Lorawan */
RTC_AlarmStructure.AlarmTime.SubSeconds = subSeconds;
/* The subsecond in ms is converted in ticks unit 1 tick is 1000 / fqce_apre */
RTC_AlarmStructure.AlarmTime.SubSeconds = UINT32_MAX - (subSeconds * fqce_apre) / 1000;
}

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

0 comments on commit 87aec09

Please sign in to comment.