Skip to content

Commit 380b8b9

Browse files
committed
stm32RTC start alarm with a 64bit accuracy on Subseconds param
When the number of SubSeconds exceeds 32bit value during calculations the Alarm still needs to be set with bigger range. This is done with a new RTC_StartAlarm64 function. Signed-off-by: F. Ramu <[email protected]>
1 parent fd5a7bc commit 380b8b9

File tree

2 files changed

+35
-7
lines changed

2 files changed

+35
-7
lines changed

src/rtc.c

+34-7
Original file line numberDiff line numberDiff line change
@@ -829,19 +829,20 @@ void RTC_GetDate(uint8_t *year, uint8_t *month, uint8_t *day, uint8_t *wday)
829829
}
830830

831831
/**
832-
* @brief Set RTC alarm and activate it with IT mode
832+
* @brief Set RTC alarm and activate it with IT mode with 64bit accuracy on subsecond param
833+
* Mainly used by Lorawan in RTC BIN or MIX mode
833834
* @param name: ALARM_A or ALARM_B if exists
834835
* @param day: 1-31 (day of the month)
835836
* @param hours: 0-12 or 0-23 depends on the hours mode.
836837
* @param minutes: 0-59
837838
* @param seconds: 0-59
838-
* @param subSeconds: 0-999 milliseconds
839+
* @param subSeconds: 0-999 milliseeconds or 64bit nb of milliseconds in no BCD mode
839840
* @param period: HOUR_AM or HOUR_PM if in 12 hours mode else ignored.
840841
* @param mask: configure alarm behavior using alarmMask_t combination.
841842
* See AN4579 Table 5 for possible values.
842843
* @retval None
843844
*/
844-
void RTC_StartAlarm(alarm_t name, uint8_t day, uint8_t hours, uint8_t minutes, uint8_t seconds, uint32_t subSeconds, hourAM_PM_t period, uint8_t mask)
845+
void RTC_StartAlarm64(alarm_t name, uint8_t day, uint8_t hours, uint8_t minutes, uint8_t seconds, uint64_t subSeconds, hourAM_PM_t period, uint8_t mask)
845846
{
846847
#if !defined(RTC_SSR_SS)
847848
UNUSED(subSeconds);
@@ -879,9 +880,9 @@ void RTC_StartAlarm(alarm_t name, uint8_t day, uint8_t hours, uint8_t minutes, u
879880
*/
880881
if ((initMode == MODE_BINARY_ONLY) || (initMode == MODE_BINARY_MIX)) {
881882
/* the subsecond is the millisecond to be converted in a subsecond downcounter value */
882-
RTC_AlarmStructure.AlarmTime.SubSeconds = UINT32_MAX - (subSeconds * (predivSync + 1)) / 1000;
883+
RTC_AlarmStructure.AlarmTime.SubSeconds = UINT32_MAX - ((uint32_t)subSeconds * (predivSync + 1)) / 1000;
883884
} else {
884-
RTC_AlarmStructure.AlarmTime.SubSeconds = predivSync - (subSeconds * (predivSync + 1)) / 1000;
885+
RTC_AlarmStructure.AlarmTime.SubSeconds = predivSync - ((uint32_t)subSeconds * (predivSync + 1)) / 1000;
885886
}
886887
} else {
887888
RTC_AlarmStructure.AlarmSubSecondMask = RTC_ALARMSUBSECONDMASK_ALL;
@@ -945,8 +946,15 @@ void RTC_StartAlarm(alarm_t name, uint8_t day, uint8_t hours, uint8_t minutes, u
945946
#if defined(RTC_ICSR_BIN)
946947
if ((initMode == MODE_BINARY_ONLY) || (initMode == MODE_BINARY_MIX)) {
947948
/* We have an SubSecond alarm to set in RTC_BINARY_MIX or RTC_BINARY_ONLY mode */
948-
/* The subsecond in ms is converted in ticks unit 1 tick is 1000 / fqce_apre */
949-
RTC_AlarmStructure.AlarmTime.SubSeconds = UINT32_MAX - (subSeconds * (predivSync + 1)) / 1000;
949+
/* The subsecond in ms is converted in ticks unit 1 tick is 1000 / fqce_apre
950+
* It keeps the subsecond accuracy on 64 bits if needed
951+
*/
952+
if (subSeconds > (uint64_t)UINT32_MAX) {
953+
uint64_t tmp = ((uint64_t)subSeconds * (predivSync + 1)) / (uint64_t)1000;
954+
RTC_AlarmStructure.AlarmTime.SubSeconds = (uint32_t)UINT32_MAX - (uint32_t)tmp;
955+
} else {
956+
RTC_AlarmStructure.AlarmTime.SubSeconds = (uint32_t)(UINT32_MAX - (subSeconds * (predivSync + 1)) / 1000);
957+
}
950958
} else
951959
#endif /* RTC_ICSR_BIN */
952960
{
@@ -960,6 +968,25 @@ void RTC_StartAlarm(alarm_t name, uint8_t day, uint8_t hours, uint8_t minutes, u
960968
#endif /* RTC_SSR_SS */
961969
}
962970

971+
/**
972+
* @brief Set RTC alarm and activate it with IT mode
973+
* @param name: ALARM_A or ALARM_B if exists
974+
* @param day: 1-31 (day of the month)
975+
* @param hours: 0-12 or 0-23 depends on the hours mode.
976+
* @param minutes: 0-59
977+
* @param seconds: 0-59
978+
* @param subSeconds: 0-999 milliseconds
979+
* @param period: HOUR_AM or HOUR_PM if in 12 hours mode else ignored.
980+
* @param mask: configure alarm behavior using alarmMask_t combination.
981+
* See AN4579 Table 5 for possible values.
982+
* @retval None
983+
*/
984+
void RTC_StartAlarm(alarm_t name, uint8_t day, uint8_t hours, uint8_t minutes, uint8_t seconds, uint32_t subSeconds, hourAM_PM_t period, uint8_t mask)
985+
{
986+
/* Same RTC_StartAlarm where the nb of SubSeconds is lower than UINT32_MAX */
987+
RTC_StartAlarm64(name, day, hours, minutes, seconds, (uint64_t)subSeconds, period, mask);
988+
}
989+
963990
/**
964991
* @brief Disable RTC alarm
965992
* @param name: ALARM_A or ALARM_B if exists

src/rtc.h

+1
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,7 @@ void RTC_SetDate(uint8_t year, uint8_t month, uint8_t day, uint8_t wday);
194194
void RTC_GetDate(uint8_t *year, uint8_t *month, uint8_t *day, uint8_t *wday);
195195

196196
void RTC_StartAlarm(alarm_t name, uint8_t day, uint8_t hours, uint8_t minutes, uint8_t seconds, uint32_t subSeconds, hourAM_PM_t period, uint8_t mask);
197+
void RTC_StartAlarm64(alarm_t name, uint8_t day, uint8_t hours, uint8_t minutes, uint8_t seconds, uint64_t subSeconds, hourAM_PM_t period, uint8_t mask);
197198
void RTC_StopAlarm(alarm_t name);
198199
bool RTC_IsAlarmSet(alarm_t name);
199200
void RTC_GetAlarm(alarm_t name, uint8_t *day, uint8_t *hours, uint8_t *minutes, uint8_t *seconds, uint32_t *subSeconds, hourAM_PM_t *period, uint8_t *mask);

0 commit comments

Comments
 (0)