From c10ab5d2c0320b4877b5e0531eb4a98daca2af96 Mon Sep 17 00:00:00 2001 From: "F. Ramu" Date: Tue, 12 Mar 2024 10:32:22 +0100 Subject: [PATCH 1/2] 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 --- src/rtc.c | 41 ++++++++++++++++++++++++++++++++++------- src/rtc.h | 1 + 2 files changed, 35 insertions(+), 7 deletions(-) diff --git a/src/rtc.c b/src/rtc.c index 0cc6f4f..c348f92 100644 --- a/src/rtc.c +++ b/src/rtc.c @@ -829,19 +829,20 @@ void RTC_GetDate(uint8_t *year, uint8_t *month, uint8_t *day, uint8_t *wday) } /** - * @brief Set RTC alarm and activate it with IT mode + * @brief Set RTC alarm and activate it with IT mode with 64bit accuracy on subsecond param + * Mainly used by Lorawan in RTC BIN or MIX mode * @param name: ALARM_A or ALARM_B if exists * @param day: 1-31 (day of the month) * @param hours: 0-12 or 0-23 depends on the hours mode. * @param minutes: 0-59 * @param seconds: 0-59 - * @param subSeconds: 0-999 milliseconds + * @param subSeconds: 0-999 milliseeconds or 64bit nb of milliseconds in no BCD mode * @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. * @retval None */ -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) +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) { #if !defined(RTC_SSR_SS) UNUSED(subSeconds); @@ -879,9 +880,9 @@ void RTC_StartAlarm(alarm_t name, uint8_t day, uint8_t hours, uint8_t minutes, u */ if ((initMode == MODE_BINARY_ONLY) || (initMode == MODE_BINARY_MIX)) { /* the subsecond is the millisecond to be converted in a subsecond downcounter value */ - RTC_AlarmStructure.AlarmTime.SubSeconds = UINT32_MAX - (subSeconds * (predivSync + 1)) / 1000; + RTC_AlarmStructure.AlarmTime.SubSeconds = UINT32_MAX - ((uint32_t)subSeconds * (predivSync + 1)) / 1000; } else { - RTC_AlarmStructure.AlarmTime.SubSeconds = predivSync - (subSeconds * (predivSync + 1)) / 1000; + RTC_AlarmStructure.AlarmTime.SubSeconds = predivSync - ((uint32_t)subSeconds * (predivSync + 1)) / 1000; } } else { 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 #if defined(RTC_ICSR_BIN) if ((initMode == MODE_BINARY_ONLY) || (initMode == MODE_BINARY_MIX)) { /* We have an SubSecond alarm to set in RTC_BINARY_MIX or RTC_BINARY_ONLY mode */ - /* The subsecond in ms is converted in ticks unit 1 tick is 1000 / fqce_apre */ - RTC_AlarmStructure.AlarmTime.SubSeconds = UINT32_MAX - (subSeconds * (predivSync + 1)) / 1000; + /* The subsecond in ms is converted in ticks unit 1 tick is 1000 / fqce_apre + * It keeps the subsecond accuracy on 64 bits if needed + */ + if (subSeconds > (uint64_t)UINT32_MAX) { + uint64_t tmp = (subSeconds * (uint64_t)(predivSync + 1)) / (uint64_t)1000; + RTC_AlarmStructure.AlarmTime.SubSeconds = (uint32_t)UINT32_MAX - (uint32_t)tmp; + } else { + RTC_AlarmStructure.AlarmTime.SubSeconds = (uint32_t)((uint32_t)UINT32_MAX - (uint32_t)(subSeconds * (predivSync + 1)) / 1000); + } } else #endif /* RTC_ICSR_BIN */ { @@ -960,6 +968,25 @@ void RTC_StartAlarm(alarm_t name, uint8_t day, uint8_t hours, uint8_t minutes, u #endif /* RTC_SSR_SS */ } +/** + * @brief Set RTC alarm and activate it with IT mode + * @param name: ALARM_A or ALARM_B if exists + * @param day: 1-31 (day of the month) + * @param hours: 0-12 or 0-23 depends on the hours mode. + * @param minutes: 0-59 + * @param seconds: 0-59 + * @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. + * @retval None + */ +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) +{ + /* Same RTC_StartAlarm where the nb of SubSeconds is lower than UINT32_MAX */ + RTC_StartAlarm64(name, day, hours, minutes, seconds, (uint64_t)subSeconds, period, mask); +} + /** * @brief Disable RTC alarm * @param name: ALARM_A or ALARM_B if exists diff --git a/src/rtc.h b/src/rtc.h index 5a20a35..80319e4 100644 --- a/src/rtc.h +++ b/src/rtc.h @@ -194,6 +194,7 @@ void RTC_SetDate(uint8_t year, uint8_t month, uint8_t day, uint8_t wday); void RTC_GetDate(uint8_t *year, uint8_t *month, uint8_t *day, uint8_t *wday); 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); +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); void RTC_StopAlarm(alarm_t name); bool RTC_IsAlarmSet(alarm_t name); 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); From ba9f36fb5b657177886bcccad372c47371639ca6 Mon Sep 17 00:00:00 2001 From: Frederic Pillon Date: Mon, 19 Aug 2024 10:51:44 +0200 Subject: [PATCH 2/2] fixup: typo Signed-off-by: Frederic Pillon --- src/rtc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rtc.c b/src/rtc.c index c348f92..f3e0bca 100644 --- a/src/rtc.c +++ b/src/rtc.c @@ -836,7 +836,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 milliseeconds or 64bit nb of milliseconds in no BCD mode + * @param subSeconds: 0-999 milliseconds or 64bit nb of milliseconds in no BCD mode * @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.