From 5da16e62583082001f2ee5c0891ae38c8718a09b Mon Sep 17 00:00:00 2001 From: Francois RAMU Date: Thu, 8 Feb 2024 17:27:11 +0100 Subject: [PATCH 1/7] stm32RTC can give the hour Format 24 or 12 hours Adding a boolean (true) if the Hour format is 24 Hours. Signed-off-by: Francois RAMU --- README.md | 6 ++++++ src/STM32RTC.h | 4 ++++ 2 files changed, 10 insertions(+) diff --git a/README.md b/README.md index bc11b65..bbcc584 100644 --- a/README.md +++ b/README.md @@ -190,6 +190,12 @@ underflow. Used by STM32LoRaWAN. Refer to the Arduino RTC documentation for the other functions http://arduino.cc/en/Reference/RTC +### Since STM32RTC version higher than 1.4.0 +_IsFormat_24Hour_ + +Returns True if the current Hour Format is HOUR_24 else false if Hour format is HOUR_12 + + ## Source Source files available at: diff --git a/src/STM32RTC.h b/src/STM32RTC.h index fe0374c..e7c9611 100644 --- a/src/STM32RTC.h +++ b/src/STM32RTC.h @@ -240,6 +240,10 @@ class STM32RTC { { return RTC_IsConfigured(); } + bool isFormat_24hour(void) + { + return (_format == HOUR_24); + } bool isAlarmEnabled(Alarm name = ALARM_A); bool isTimeSet(void) { From ce1122e2fd181d0cb4ce8a51363890c066e328bb Mon Sep 17 00:00:00 2001 From: Frederic Pillon Date: Mon, 26 Feb 2024 17:01:36 +0100 Subject: [PATCH 2/7] feat(WBA): Add RTC STM32WBAxx support Signed-off-by: Frederic Pillon --- src/rtc.c | 8 ++++++-- src/rtc.h | 5 +++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/rtc.c b/src/rtc.c index 73c911f..536d7c4 100644 --- a/src/rtc.c +++ b/src/rtc.c @@ -441,8 +441,9 @@ bool RTC_init(hourFormat_t format, binaryMode_t mode, sourceClock_t source, bool #ifdef __HAL_RCC_RTCAPB_CLK_ENABLE __HAL_RCC_RTCAPB_CLK_ENABLE(); #endif +#ifdef __HAL_RCC_RTC_ENABLE __HAL_RCC_RTC_ENABLE(); - +#endif isAlarmASet = RTC_IsAlarmSet(ALARM_A); #ifdef RTC_ALARM_B isAlarmBSet = RTC_IsAlarmSet(ALARM_B); @@ -591,7 +592,9 @@ void RTC_DeInit(bool reset_cb) { HAL_RTC_DeInit(&RtcHandle); /* Peripheral clock disable */ +#ifdef __HAL_RCC_RTC_DISABLE __HAL_RCC_RTC_DISABLE(); +#endif #ifdef __HAL_RCC_RTCAPB_CLK_DISABLE __HAL_RCC_RTCAPB_CLK_DISABLE(); #endif @@ -1124,7 +1127,8 @@ void RTC_Alarm_IRQHandler(void) #if defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F078xx) || \ defined(STM32F091xC) || defined(STM32F098xx) || defined(STM32F070xB) || \ defined(STM32F030xC) || defined(STM32G0xx) || defined(STM32H5xx) || \ - defined(STM32L0xx) || defined(STM32L5xx) || defined(STM32U5xx) + defined(STM32L0xx) || defined(STM32L5xx) || defined(STM32U5xx) || \ + defined(STM32WBAxx) // In some cases, the same vector is used to manage WakeupTimer, // but with a dedicated HAL IRQHandler HAL_RTCEx_WakeUpTimerIRQHandler(&RtcHandle); diff --git a/src/rtc.h b/src/rtc.h index 8d0bcd8..5a20a35 100644 --- a/src/rtc.h +++ b/src/rtc.h @@ -129,7 +129,8 @@ typedef void(*voidCallbackPtr)(void *); #endif /* !STM32F1xx */ #if defined(STM32C0xx) || defined(STM32F0xx) || defined(STM32H5xx) || \ - defined(STM32L0xx) || defined(STM32L5xx) || defined(STM32U5xx) + defined(STM32L0xx) || defined(STM32L5xx) || defined(STM32U5xx) || \ + defined(STM32WBAxx) #define RTC_Alarm_IRQn RTC_IRQn #define RTC_Alarm_IRQHandler RTC_IRQHandler #endif @@ -141,7 +142,7 @@ typedef void(*voidCallbackPtr)(void *); /* mapping the IRQn for the one-second interrupt depending on the soc */ #if defined(STM32F1xx) || (defined(STM32F0xx) && defined(RTC_CR_WUTE)) || \ defined(STM32H5xx) || defined(STM32L0xx) || defined(STM32L5xx) || \ - defined(STM32U5xx) + defined(STM32U5xx) || defined(STM32WBAxx) // specific WakeUp interrupt #define ONESECOND_IRQn RTC_IRQn #elif defined(STM32MP1xx) From 1c66643f8867148d7d9d2749797ff365a32b232d Mon Sep 17 00:00:00 2001 From: Francois RAMU Date: Mon, 26 Feb 2024 15:57:48 +0100 Subject: [PATCH 3/7] stm32RTC change the binary Mode in case the RTC is already init When the RTC is already initialized, but RTC BIN mode must be changed this is done by writing the RTC ICSR register on BIN[] and BCDU[] bit-field with a new `RTC_SetBinaryConf()` function. Signed-off-by: Francois Ramu --- src/rtc.c | 44 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 42 insertions(+), 2 deletions(-) diff --git a/src/rtc.c b/src/rtc.c index 536d7c4..0cc6f4f 100644 --- a/src/rtc.c +++ b/src/rtc.c @@ -93,6 +93,7 @@ static void RTC_computePrediv(uint32_t *asynch, uint32_t *synch); #endif /* !STM32F1xx */ #if defined(RTC_BINARY_NONE) static void RTC_BinaryConf(binaryMode_t mode); +static void RTC_SetBinaryConf(void); #endif static inline int _log2(int x) @@ -383,6 +384,34 @@ static void RTC_BinaryConf(binaryMode_t mode) } } } + +/* +* Function to check if the RTC ICSR register must be updated with new bit +* field BIN and BCDU. To be called just after the RTC_BinaryConf +* Map the LL RTC bin mode to the corresponding RtcHandle.Init.BinMode values +* assuming the LL_RTC_BINARY_xxx is identical to RTC_BINARY_xxx (RTC_ICSR_BIN_xxx) +* Idem for the LL_RTC_BINARY_MIX_BCDU_n and RTC_BINARY_MIX_BCDU_n +*/ +#if (RTC_BINARY_MIX != LL_RTC_BINARY_MIX) +#error "RTC_BINARY_MIX and LL_RTC_BINARY_MIX do not match" +#endif +#if (RTC_BINARY_MIX_BCDU_7 != LL_RTC_BINARY_MIX_BCDU_7) +#error "RTC_BINARY_MIX_BCDU_n and LL_RTC_BINARY_MIX_BCDU_n do not match" +#endif +static void RTC_SetBinaryConf(void) +{ + if (LL_RTC_GetBinaryMode(RtcHandle.Instance) != RtcHandle.Init.BinMode) { + LL_RTC_DisableWriteProtection(RtcHandle.Instance); + LL_RTC_EnableInitMode(RtcHandle.Instance); + + LL_RTC_SetBinaryMode(RtcHandle.Instance, RtcHandle.Init.BinMode); + if (RtcHandle.Init.BinMode == RTC_BINARY_MIX) { + LL_RTC_SetBinMixBCDU(RtcHandle.Instance, RtcHandle.Init.BinMixBcdU); + } + LL_RTC_ExitInitMode(RtcHandle.Instance); + LL_RTC_EnableWriteProtection(RtcHandle.Instance); + } +} #endif /* RTC_BINARY_NONE */ /** @@ -463,6 +492,10 @@ bool RTC_init(hourFormat_t format, binaryMode_t mode, sourceClock_t source, bool RTC_initClock(source); RTC_getPrediv(&(RtcHandle.Init.AsynchPrediv), &(RtcHandle.Init.SynchPrediv)); #if defined(RTC_BINARY_NONE) + /* + * If RTC BIN mode changed, calling the HAL_RTC_Init will + * force the update of the BIN register in the RTC_ICSR + */ RTC_BinaryConf(mode); #endif /* RTC_BINARY_NONE */ #endif // STM32F1xx @@ -527,11 +560,11 @@ bool RTC_init(hourFormat_t format, binaryMode_t mode, sourceClock_t source, bool #else RTC_getPrediv(&(RtcHandle.Init.AsynchPrediv), &(RtcHandle.Init.SynchPrediv)); #endif +#if defined(RTC_BINARY_NONE) /* - * TODO: RTC is already initialized, but RTC BIN mode is changed + * If RTC BIN mode changed, calling the HAL_RTC_Init will * force the update of the BIN register in the RTC_ICSR */ -#if defined(RTC_BINARY_NONE) RTC_BinaryConf(mode); #endif /* RTC_BINARY_NONE */ HAL_RTC_Init(&RtcHandle); @@ -558,6 +591,13 @@ bool RTC_init(hourFormat_t format, binaryMode_t mode, sourceClock_t source, bool #endif #if defined(RTC_BINARY_NONE) RTC_BinaryConf(mode); + /* + * RTC is already initialized, but RTC BIN mode is changed : + * force the update of the BIN register and BCDu in the RTC_ICSR + * by the RTC_SetBinaryConf function + */ + RTC_SetBinaryConf(); + #endif /* RTC_BINARY_NONE */ #if defined(STM32F1xx) memcpy(&RtcHandle.DateToUpdate, &BackupDate, 4); From fd5a7bc2dd8c229d546a7130a5f3de59720294b6 Mon Sep 17 00:00:00 2001 From: Francois RAMU Date: Wed, 28 Feb 2024 11:45:46 +0100 Subject: [PATCH 4/7] new sketch to demonstrate the RTC mode change New application to demonstrate that changing the RTC mode from BIN to BCD does not affect the calendar nor Alarm. Signed-off-by: F. Ramu --- examples/changeMode/changeMode.ino | 82 ++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 examples/changeMode/changeMode.ino diff --git a/examples/changeMode/changeMode.ino b/examples/changeMode/changeMode.ino new file mode 100644 index 0000000..2d85bd2 --- /dev/null +++ b/examples/changeMode/changeMode.ino @@ -0,0 +1,82 @@ +/* + change RTC mode from BCD --> MIX --> BIN + + This sketch shows that changing the RTC mode does not affect the calendar + Configure the RTC, set an alarm, on alarm match change the RTC mode. + + Creation 01 march 2024 + by Francois Ramu for STMicroelectronics + + This example code is in the public domain. + + https://github.com/stm32duino/STM32RTC +*/ + +#include + +/* Get the rtc object */ +STM32RTC& rtc = STM32RTC::getInstance(); +bool rtc_mode_changed; + +void setup() +{ + Serial.begin(115200); + + // Select RTC clock source: LSI_CLOCK, LSE_CLOCK or HSE_CLOCK. + rtc.setClockSource(STM32RTC::LSE_CLOCK); + + /* Configure the RTC mode */ + rtc.setBinaryMode(STM32RTC::MODE_BCD); + rtc_mode_changed = true; + + /* RTC mode is in BCD mode by default */ + rtc.begin(true, STM32RTC::HOUR_24); + + /* wait for a while */ + delay(500); + + // Set the calendar + rtc.setDate(01, 03, 24); + rtc.setTime(14, 02, 58); + + // Program ALARM A to change the RTC mode (set then enable) + rtc.attachInterrupt(alarmMatch); + rtc.setAlarmSeconds(5, STM32RTC::ALARM_A); + rtc.enableAlarm(rtc.MATCH_SS, STM32RTC::ALARM_A); +} + +void loop() +{ + /* Reports the RTC mode when it has been changed */ + if (rtc_mode_changed) { + if (rtc.getBinaryMode() == STM32RTC::MODE_BCD) { + Serial.printf("RTC mode is MODE_BCD at "); + } else if (rtc.getBinaryMode() == STM32RTC::MODE_MIX) { + Serial.printf("RTC mode is MODE_MIX at "); + } else { + Serial.printf("RTC mode is MODE_BIN at "); + } + + Serial.printf("%02d/%02d/%02d - ", rtc.getDay(), rtc.getMonth(), rtc.getYear()); + Serial.printf("%02d:%02d:%02d \n", rtc.getHours(), rtc.getMinutes(), rtc.getSeconds()); + + rtc_mode_changed = false; + } +} + +void alarmMatch(void *data) +{ + UNUSED(data); + Serial.printf("Alarm A Match! : change RTC mode at "); + Serial.printf("%02d:%02d:%02d \n", rtc.getHours(), rtc.getMinutes(), rtc.getSeconds()); + + /* Configure the new RTC mode */ + if (rtc.getBinaryMode() == STM32RTC::MODE_BCD) { + rtc.setBinaryMode(STM32RTC::MODE_MIX); + } else if (rtc.getBinaryMode() == STM32RTC::MODE_MIX) { + rtc.setBinaryMode(STM32RTC::MODE_BIN); + } else { + rtc.setBinaryMode(STM32RTC::MODE_BCD); + } + rtc_mode_changed = true; +} From 62a61755a6dd803ba70a6c68be7b747c6ff05973 Mon Sep 17 00:00:00 2001 From: FRASTM <51417392+FRASTM@users.noreply.github.com> Date: Mon, 19 Aug 2024 10:52:10 +0200 Subject: [PATCH 5/7] stm32RTC start alarm with a 64bit accuracy on Subseconds param (#109) * 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 Co-authored-by: Frederic Pillon --- 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..f3e0bca 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 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. * @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 f2c0b20ede33e431f98dd96948a88da363730873 Mon Sep 17 00:00:00 2001 From: Frederic Pillon Date: Mon, 19 Aug 2024 10:52:51 +0200 Subject: [PATCH 6/7] chore: update library version Signed-off-by: Frederic Pillon --- library.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library.properties b/library.properties index 4666e3a..814896b 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=STM32duino RTC -version=1.4.0 +version=1.5.0 author=STMicroelectronics maintainer=stm32duino sentence=Allows to use the RTC functionalities of STM32 based boards. From 622310a196e151b381747db73710a4df26048057 Mon Sep 17 00:00:00 2001 From: Frederic Pillon Date: Mon, 19 Aug 2024 10:53:09 +0200 Subject: [PATCH 7/7] chore: update library version Signed-off-by: Frederic Pillon --- library.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library.json b/library.json index 5c570df..c485639 100644 --- a/library.json +++ b/library.json @@ -7,7 +7,7 @@ "type": "git", "url": "https://github.com/stm32duino/STM32RTC" }, - "version": "1.4.0", + "version": "1.5.0", "frameworks": "arduino", "platforms": "ststm32", "build": {