From 5e525dc10883200debb72700be8614b8da705c79 Mon Sep 17 00:00:00 2001 From: Frederic Pillon Date: Wed, 17 Jun 2026 17:28:17 +0200 Subject: [PATCH 1/2] chore: add HAL v2 support Signed-off-by: Frederic Pillon --- README.md | 5 +- examples/RTCReset/RTCReset.ino | 14 +- .../advancedRTCAlarm/advancedRTCAlarm.ino | 6 +- .../bin_onlyRTCAlarm/bin_onlyRTCAlarm.ino | 8 +- examples/mixRTCAlarm/mixRTCAlarm.ino | 8 +- src/STM32RTC.cpp | 54 +- src/STM32RTC.h | 14 +- src/rtc.c | 644 +++++++++++++++--- src/rtc.h | 54 +- 9 files changed, 664 insertions(+), 143 deletions(-) diff --git a/README.md b/README.md index 2819fc1..32507d1 100644 --- a/README.md +++ b/README.md @@ -144,7 +144,7 @@ To know if a time has already been set use: ### Since STM32RTC version higher than 1.3.4 _Second alarm (Alarm B)_ -Some STM32 RTC have a second alarm named `RTC_ALARM_B`. +Some STM32 RTC have a second alarm named `ALARM_B`. It is possible to use it thanks all alarm API with an extra argument: - `STM32RTC::ALARM_A` - `STM32RTC::ALARM_B` @@ -158,7 +158,8 @@ It is possible to use it thanks all alarm API with an extra argument: ### Since STM32RTC version higher than 1.3.7 _Get the RTC handle_ - +> [!NOTE] +> Only available for the STM32 HAL driver version 1 * **`RTC_HandleTypeDef *RTC_GetHandle(void)`** _binary and mix modes_ diff --git a/examples/RTCReset/RTCReset.ino b/examples/RTCReset/RTCReset.ino index f05ea6e..8982f50 100644 --- a/examples/RTCReset/RTCReset.ino +++ b/examples/RTCReset/RTCReset.ino @@ -37,7 +37,7 @@ typedef struct { } cb_data_t; static cb_data_t atime = { 2222, true }; -#ifdef RTC_ALARM_B +#if defined(ALARM_B_AVAILABLE) static cb_data_t btime = { 3333, false }; #endif static byte seconds = 0; @@ -107,7 +107,7 @@ void setup() { // In any case attach a callback to the RTC alarm interrupt. rtc.attachInterrupt(alarmMatch, &atime); -#ifdef RTC_ALARM_B +#ifdef ALARM_B_AVAILABLE rtc.attachInterrupt(alarmMatch, &btime, STM32RTC::ALARM_B); #endif rtc.begin(); // Initialize RTC 24H format @@ -120,7 +120,7 @@ void setup() { rtc.setAlarmDay(day); rtc.setAlarmTime(hours, minutes, seconds + 5, 567); rtc.enableAlarm(rtc.MATCH_DHHMMSS); -#ifdef RTC_ALARM_B +#ifdef ALARM_B_AVAILABLE // ALARM_B rtc.setAlarmDay(day, STM32RTC::ALARM_B); rtc.setAlarmTime(hours, minutes, seconds + 5, 567, STM32RTC::ALARM_B); @@ -144,7 +144,7 @@ void setup() { Serial.printf("Alarm A was enabled and restored\n"); } } -#ifdef RTC_ALARM_B +#ifdef ALARM_B_AVAILABLE // ALARM_B if (rtc.isAlarmEnabled(STM32RTC::ALARM_B)) { rtc.enableAlarm(rtc.MATCH_DHHMMSS, STM32RTC::ALARM_B); @@ -168,7 +168,7 @@ void setup() { rtc.setAlarmTime(hours, minutes, seconds + 5, 567); rtc.enableAlarm(rtc.MATCH_DHHMMSS); } -#ifdef RTC_ALARM_B +#ifdef ALARM_B_AVAILABLE bool alarmB = rtc.isAlarmEnabled(STM32RTC::ALARM_B); Serial.printf("Alarm B enable status: %s\n", (alarmB) ? "True" : "False"); if (!alarmB) { @@ -187,7 +187,7 @@ void loop() { Serial.printf("\n%02d/%02d/%02d %02d:%02d:%02d.%03d\n", rtc.getDay(), rtc.getMonth(), rtc.getYear(), hours, minutes, seconds, subSeconds); // Print current alarm configuration Serial.printf("Alarm A: %02d %02d:%02d:%02d.%03d\n", rtc.getAlarmDay(), rtc.getAlarmHours(), rtc.getAlarmMinutes(), rtc.getAlarmSeconds(), rtc.getAlarmSubSeconds()); -#ifdef RTC_ALARM_B +#ifdef ALARM_B_AVAILABLE Serial.printf("Alarm B: %02d %02d:%02d:%02d.%03d\n", rtc.getAlarmDay(STM32RTC::ALARM_B), rtc.getAlarmHours(STM32RTC::ALARM_B), rtc.getAlarmMinutes(STM32RTC::ALARM_B), rtc.getAlarmSeconds(STM32RTC::ALARM_B), rtc.getAlarmSubSeconds(STM32RTC::ALARM_B)); #endif delay(1000); @@ -227,7 +227,7 @@ void alarmMatch(void* data) { Serial.printf("\t\t\tAlarm A Match %i\n", ++alarmMatch_counter); rtc.setAlarmEpoch(epoc + sec, STM32RTC::MATCH_SS, epoc_ms); } -#ifdef RTC_ALARM_B +#ifdef ALARM_B_AVAILABLE else { Serial.printf("\t\t\tAlarm B Match %i\n", ++alarmMatchB_counter); rtc.setAlarmEpoch(epoc + sec, STM32RTC::MATCH_SS, epoc_ms, STM32RTC::ALARM_B); diff --git a/examples/advancedRTCAlarm/advancedRTCAlarm.ino b/examples/advancedRTCAlarm/advancedRTCAlarm.ino index e59d440..1806fb2 100644 --- a/examples/advancedRTCAlarm/advancedRTCAlarm.ino +++ b/examples/advancedRTCAlarm/advancedRTCAlarm.ino @@ -25,7 +25,7 @@ STM32RTC& rtc = STM32RTC::getInstance(); /* Declare it volatile since it's incremented inside an interrupt */ volatile int alarmMatch_counter = 0; -#ifdef RTC_ALARM_B +#if defined(ALARM_B_AVAILABLE) volatile int alarmBMatch_counter = 0; #endif @@ -64,7 +64,7 @@ void setup() rtc.setAlarmTime(16, 0, 10, 567); rtc.enableAlarm(rtc.MATCH_DHHMMSS); -#ifdef RTC_ALARM_B +#if defined(ALARM_B_AVAILABLE) rtc.attachInterrupt(alarmBMatch, STM32RTC::ALARM_B); rtc.setAlarmDay(day, STM32RTC::ALARM_B); rtc.setAlarmTime(16, 0, 11, 567, STM32RTC::ALARM_B); @@ -110,7 +110,7 @@ void alarmMatch(void *data) rtc.setAlarmEpoch(epoc + sec, STM32RTC::MATCH_SS, epoc_ms); } -#ifdef RTC_ALARM_B +#if defined(ALARM_B_AVAILABLE) void alarmBMatch(void *data) { (void)data; diff --git a/examples/bin_onlyRTCAlarm/bin_onlyRTCAlarm.ino b/examples/bin_onlyRTCAlarm/bin_onlyRTCAlarm.ino index e10d869..0ec3d80 100644 --- a/examples/bin_onlyRTCAlarm/bin_onlyRTCAlarm.ino +++ b/examples/bin_onlyRTCAlarm/bin_onlyRTCAlarm.ino @@ -49,7 +49,7 @@ void setup() rtc.enableAlarm(rtc.MATCH_SUBSEC); Serial.printf("Set Alarm A in 12s (at %d ms)\r\n", rtc.getAlarmSubSeconds()); -#ifdef RTC_ALARM_B +#if defined(ALARM_B_AVAILABLE) /* Program ALARM B in 600ms ms from now (keep timeout < 1000ms) */ timeout = rtc.getSubSeconds() + 600; @@ -58,7 +58,7 @@ void setup() rtc.enableAlarm(rtc.MATCH_SUBSEC, STM32RTC::ALARM_B); Serial.printf("Set Alarm B (in %d ms) at %d ms\r\n", 600, rtc.getAlarmSubSeconds(STM32RTC::ALARM_B)); -#endif /* RTC_ALARM_B */ +#endif /* ALARM_B_AVAILABLE */ } @@ -74,12 +74,12 @@ void alarmAMatch(void *data) Serial.printf("Alarm A Match at %d ms \r\n", rtc.getSubSeconds()); } -#ifdef RTC_ALARM_B +#if defined(ALARM_B_AVAILABLE) void alarmBMatch(void *data) { UNUSED(data); rtc.disableAlarm(STM32RTC::ALARM_B); /* Else it will trig again */ Serial.printf("Alarm B Match at %d ms\r\n", rtc.getSubSeconds()); } -#endif /* RTC_ALARM_B */ +#endif /* ALARM_B_AVAILABLE */ diff --git a/examples/mixRTCAlarm/mixRTCAlarm.ino b/examples/mixRTCAlarm/mixRTCAlarm.ino index 429181d..8e5271f 100644 --- a/examples/mixRTCAlarm/mixRTCAlarm.ino +++ b/examples/mixRTCAlarm/mixRTCAlarm.ino @@ -64,7 +64,7 @@ void setup() Serial.printf("Set Alarm A in 12s (at %02d:%02d:%02d)\r\n", rtc.getAlarmHours(), rtc.getAlarmMinutes(), rtc.getAlarmSeconds()); -#ifdef RTC_ALARM_B +#if defined(ALARM_B_AVAILABLE) /* Program ALARM B in 600ms ms from now (keep timeout < 1000ms) */ timeout = rtc.getSubSeconds() + 600; @@ -73,7 +73,7 @@ void setup() rtc.enableAlarm(rtc.MATCH_SUBSEC, STM32RTC::ALARM_B); Serial.printf("Set Alarm B (in %d ms) at %d ms\r\n", 600, rtc.getAlarmSubSeconds(STM32RTC::ALARM_B)); -#endif /* RTC_ALARM_B */ +#endif /* ALARM_B_AVAILABLE */ } void loop() @@ -89,11 +89,11 @@ void alarmAMatch(void *data) rtc.getHours(), rtc.getMinutes(), rtc.getSeconds()); } -#ifdef RTC_ALARM_B +#if defined(ALARM_B_AVAILABLE) void alarmBMatch(void *data) { UNUSED(data); rtc.disableAlarm(STM32RTC::ALARM_B); Serial.printf("Alarm B Match at %d ms\r\n", rtc.getSubSeconds()); } -#endif /* RTC_ALARM_B */ +#endif /* ALARM_B_AVAILABLE */ diff --git a/src/STM32RTC.cpp b/src/STM32RTC.cpp index 05edd58..adf3e07 100644 --- a/src/STM32RTC.cpp +++ b/src/STM32RTC.cpp @@ -96,7 +96,7 @@ void STM32RTC::begin(bool resetTime, Hour_Format format) _alarmSubSeconds = _subSeconds; _alarmPeriod = _hoursPeriod; } -#ifdef RTC_ALARM_B +#if defined(ALARM_B_AVAILABLE) syncAlarmTime(ALARM_B); if (!IS_RTC_DATE(_alarmBDay)) { // Use current time to init alarm members, @@ -173,13 +173,13 @@ STM32RTC::Binary_Mode STM32RTC::getBinaryMode(void) */ void STM32RTC::setBinaryMode(Binary_Mode mode) { -#if defined(RTC_BINARY_NONE) +#if defined(LL_RTC_BINARY_NONE) _mode = mode; #else #warning "only BCD mode is supported" UNUSED(mode); _mode = MODE_BCD; -#endif /* RTC_BINARY_NONE */ +#endif /* LL_RTC_BINARY_NONE */ } /** @@ -224,7 +224,7 @@ void STM32RTC::setPrediv(uint32_t predivA, uint32_t predivS) */ void STM32RTC::enableAlarm(Alarm_Match match, Alarm name) { -#ifdef RTC_ALARM_B +#if defined(ALARM_B_AVAILABLE) if (name == ALARM_B) { _alarmBMatch = match; } else @@ -236,7 +236,7 @@ void STM32RTC::enableAlarm(Alarm_Match match, Alarm name) } switch (match) { case MATCH_OFF: -#ifdef RTC_ALARM_B +#if defined(ALARM_B_AVAILABLE) if (name == ALARM_B) { RTC_StopAlarm(::ALARM_B); } else @@ -247,7 +247,7 @@ void STM32RTC::enableAlarm(Alarm_Match match, Alarm name) break; case MATCH_SUBSEC: /* force _alarmday to 0 to go to the right alarm config in MIX mode */ -#ifdef RTC_ALARM_B +#if defined(ALARM_B_AVAILABLE) if (name == ALARM_B) { RTC_StartAlarm(::ALARM_B, 0, 0, 0, 0, _alarmBSubSeconds, (_alarmBPeriod == AM) ? HOUR_AM : HOUR_PM, @@ -266,7 +266,7 @@ void STM32RTC::enableAlarm(Alarm_Match match, Alarm name) case MATCH_HHMMSS: case MATCH_MMSS: case MATCH_SS: -#ifdef RTC_ALARM_B +#if defined(ALARM_B_AVAILABLE) if (name == ALARM_B) { RTC_StartAlarm(::ALARM_B, _alarmBDay, _alarmBHours, _alarmBMinutes, _alarmBSeconds, _alarmBSubSeconds, (_alarmBPeriod == AM) ? HOUR_AM : HOUR_PM, @@ -538,7 +538,7 @@ uint32_t STM32RTC::getAlarmSubSeconds(Alarm name) { uint32_t alarmSubSeconds = 0; syncAlarmTime(name); -#ifdef RTC_ALARM_B +#if defined(ALARM_B_AVAILABLE) if (name == ALARM_B) { alarmSubSeconds = _alarmBSubSeconds; } else @@ -559,7 +559,7 @@ uint8_t STM32RTC::getAlarmSeconds(Alarm name) { uint8_t alarmSeconds = 0; syncAlarmTime(name); -#ifdef RTC_ALARM_B +#if defined(ALARM_B_AVAILABLE) if (name == ALARM_B) { alarmSeconds = _alarmBSeconds; } else @@ -580,7 +580,7 @@ uint8_t STM32RTC::getAlarmMinutes(Alarm name) { uint8_t alarmMinutes = 0; syncAlarmTime(name); -#ifdef RTC_ALARM_B +#if defined(ALARM_B_AVAILABLE) if (name == ALARM_B) { alarmMinutes = _alarmBMinutes; } else @@ -614,7 +614,7 @@ uint8_t STM32RTC::getAlarmHours(AM_PM *period, Alarm name) { uint8_t alarmHours = 0; syncAlarmTime(name); -#ifdef RTC_ALARM_B +#if defined(ALARM_B_AVAILABLE) if (name == ALARM_B) { if (period != nullptr) { *period = _alarmBPeriod; @@ -641,7 +641,7 @@ uint8_t STM32RTC::getAlarmDay(Alarm name) { uint8_t alarmDay = 0; syncAlarmTime(name); -#ifdef RTC_ALARM_B +#if defined(ALARM_B_AVAILABLE) if (name == ALARM_B) { alarmDay = _alarmBDay; } else @@ -892,11 +892,11 @@ void STM32RTC::setDate(uint8_t weekDay, uint8_t day, uint8_t month, uint8_t year */ void STM32RTC::setAlarmSubSeconds(uint32_t subSeconds, Alarm name) { -#ifndef RTC_ALARM_B +#if !defined(RTC_ALARM_B) && !defined(USE_HALV2_DRIVER) UNUSED(name); #endif if ((_mode == MODE_BIN) || (subSeconds < 1000)) { -#ifdef RTC_ALARM_B +#if defined(ALARM_B_AVAILABLE) if (name == ALARM_B) { _alarmBSubSeconds = subSeconds; } else @@ -917,7 +917,7 @@ void STM32RTC::setAlarmSubSeconds(uint32_t subSeconds, Alarm name) void STM32RTC::setAlarmSeconds(uint8_t seconds, Alarm name) { if (seconds < 60) { -#ifdef RTC_ALARM_B +#if defined(ALARM_B_AVAILABLE) if (name == ALARM_B) { _alarmBSeconds = seconds; } else @@ -940,7 +940,7 @@ void STM32RTC::setAlarmSeconds(uint8_t seconds, Alarm name) void STM32RTC::setAlarmMinutes(uint8_t minutes, Alarm name) { if (minutes < 60) { -#ifdef RTC_ALARM_B +#if defined(ALARM_B_AVAILABLE) if (name == ALARM_B) { _alarmBMinutes = minutes; } else @@ -976,7 +976,7 @@ void STM32RTC::setAlarmHours(uint8_t hours, Alarm name) void STM32RTC::setAlarmHours(uint8_t hours, AM_PM period, Alarm name) { if (hours < 24) { -#ifdef RTC_ALARM_B +#if defined(ALARM_B_AVAILABLE) if (name == ALARM_B) { _alarmBHours = hours; if (_format == HOUR_12) { @@ -1063,7 +1063,7 @@ void STM32RTC::setAlarmTime(uint8_t hours, uint8_t minutes, uint8_t seconds, uin void STM32RTC::setAlarmDay(uint8_t day, Alarm name) { if ((day >= 1) && (day <= 31)) { -#ifdef RTC_ALARM_B +#if defined(ALARM_B_AVAILABLE) if (name == ALARM_B) { _alarmBDay = day; } @@ -1193,7 +1193,7 @@ time_t STM32RTC::getAlarmEpoch(uint32_t *subSeconds, Alarm name) tm.tm_year = _year + EPOCH_TIME_YEAR_OFF; tm.tm_mon = _month - 1; syncAlarmTime(name); -#ifdef RTC_ALARM_B +#if defined(ALARM_B_AVAILABLE) if (name == ALARM_B) { tm.tm_mday = _alarmBDay; tm.tm_hour = _alarmBHours; @@ -1274,7 +1274,11 @@ void STM32RTC::setEpoch(time_t ts, uint32_t subSeconds) _month = tmp->tm_mon + 1; _day = tmp->tm_mday; if (tmp->tm_wday == 0) { +#if defined(USE_HALV2_DRIVER) + _wday = HAL_RTC_WEEKDAY_SUNDAY; +#else _wday = RTC_WEEKDAY_SUNDAY; +#endif } else { _wday = tmp->tm_wday; } @@ -1303,7 +1307,10 @@ void STM32RTC::setY2kEpoch(time_t ts) */ void STM32RTC::configForLowPower(Source_Clock source) { -#if defined(HAL_PWR_MODULE_ENABLED) +#if defined(HAL_PWR_MODULE_ENABLED) || (defined(USE_HAL_PWR_MODULE) && (USE_HAL_PWR_MODULE == 1)) +#if defined(USE_HALV2_DRIVER) + HAL_RCC_LP_RTCAPB_EnableClockInStopMode(); +#else #ifdef __HAL_RCC_RTCAPB_CLKAM_ENABLE __HAL_RCC_RTCAPB_CLKAM_ENABLE(); #endif @@ -1319,6 +1326,7 @@ void STM32RTC::configForLowPower(Source_Clock source) #if defined(PWR_WAKEUP_PIN7_HIGH_3) HAL_PWR_EnableWakeUpPin(PWR_WAKEUP_PIN7_HIGH_3); #endif +#endif /* USE_HALV2_DRIVER */ setClockSource(source); begin(); @@ -1373,7 +1381,7 @@ void STM32RTC::syncAlarmTime(Alarm name) { hourAM_PM_t p = HOUR_AM; uint8_t match; -#ifdef RTC_ALARM_B +#if defined(ALARM_B_AVAILABLE) if (name == ALARM_B) { RTC_GetAlarm(::ALARM_B, &_alarmBDay, &_alarmBHours, &_alarmBMinutes, &_alarmBSeconds, &_alarmBSubSeconds, &p, &match); @@ -1395,7 +1403,7 @@ void STM32RTC::syncAlarmTime(Alarm name) case MATCH_HHMMSS: case MATCH_MMSS: case MATCH_SS: -#ifdef RTC_ALARM_B +#if defined(ALARM_B_AVAILABLE) if (name == ALARM_B) { _alarmBMatch = static_cast(match); } else @@ -1405,7 +1413,7 @@ void STM32RTC::syncAlarmTime(Alarm name) } break; default: -#ifdef RTC_ALARM_B +#if defined(ALARM_B_AVAILABLE) if (name == ALARM_B) { _alarmBMatch = MATCH_OFF; } else diff --git a/src/STM32RTC.h b/src/STM32RTC.h index d6ae77c..5032b06 100644 --- a/src/STM32RTC.h +++ b/src/STM32RTC.h @@ -42,9 +42,10 @@ #error "This library is not compatible with core version used. Please update the core." #endif #include "rtc.h" -// Check if RTC HAL enable in variants/board_name/stm32yzxx_hal_conf.h -#ifndef HAL_RTC_MODULE_ENABLED - #error "RTC configuration is missing. Check flag HAL_RTC_MODULE_ENABLED in variants/board_name/stm32yzxx_hal_conf.h" +// Check if RTC HAL is enabled +#if (!defined(HAL_RTC_MODULE_ENABLED) && (!defined(USE_HAL_ADC_MODULE) || \ + (defined(USE_HAL_ADC_MODULE) && (USE_HAL_ADC_MODULE == 0)))) +#error "HAL RTC module is not enabled." #endif #include @@ -120,7 +121,7 @@ class STM32RTC { enum Alarm : uint32_t { ALARM_A = ::ALARM_A, -#ifdef RTC_ALARM_B +#if defined(ALARM_B_AVAILABLE) ALARM_B = ::ALARM_B #endif }; @@ -140,12 +141,13 @@ class STM32RTC { void end(void); +#if !defined(USE_HALV2_DRIVER) // Could be used to mix Arduino API and STM32Cube HAL API (ex: DMA). Use at your own risk. RTC_HandleTypeDef *getHandle(void) { return RTC_GetHandle(); } - +#endif Source_Clock getClockSource(void); void setClockSource(Source_Clock source, uint32_t predivA = (PREDIVA_MAX + 1), uint32_t predivS = (PREDIVS_MAX + 1)); void getPrediv(uint32_t *predivA, uint32_t *predivS); @@ -289,7 +291,7 @@ class STM32RTC { AM_PM _alarmPeriod; Alarm_Match _alarmMatch; -#ifdef RTC_ALARM_B +#if defined(ALARM_B_AVAILABLE) /* ALARM B */ uint8_t _alarmBDay; uint8_t _alarmBHours; diff --git a/src/rtc.c b/src/rtc.c index 22dc997..4d1ee7f 100644 --- a/src/rtc.c +++ b/src/rtc.c @@ -35,10 +35,12 @@ */ #include "rtc.h" +#include "stm32yyxx_ll_rcc.h" #include "stm32yyxx_ll_rtc.h" #include -#if defined(HAL_RTC_MODULE_ENABLED) && !defined(HAL_RTC_MODULE_ONLY) +#if !defined(HAL_RTC_MODULE_ONLY) && \ + (defined(HAL_RTC_MODULE_ENABLED) || (defined(USE_HAL_RTC_MODULE) && (USE_HAL_RTC_MODULE == 1))) #if defined(STM32MP1xx) /** * Currently there is no RTC driver for STM32MP1xx. If RTC is used in the future @@ -54,12 +56,34 @@ extern "C" { #endif /* Private define ------------------------------------------------------------*/ +#if defined(USE_HALV2_DRIVER) +#define IS_RTC_ASYNCH_PREDIV(PREDIV) ((PREDIV) <= 0x7FU) +/* ToDo: check if mode is needed */ +/** + * Test synchronous prescaler value if mode is HAL_RTC_MODE_BCD. + */ +/* #define IS_RTC_SYNCH_PREDIV(prediv, mode) (((mode) != HAL_RTC_MODE_BCD) || ((prediv) <= 0x7FFFU))*/ +#define IS_RTC_SYNCH_PREDIV(PREDIV) ((PREDIV) <= 0x7FFFU) +#endif /* Private macro -------------------------------------------------------------*/ /* Private variables ---------------------------------------------------------*/ +#if defined(USE_HALV2_DRIVER) +static hal_rtc_config_t rtc_config = { + .mode = HAL_RTC_MODE_BCD, + .asynch_prediv = 0x7F, + .synch_prediv = 0x00FF, + .bcd_update = HAL_RTC_BCD_UPDATE_8BITS +}; +hal_rtc_calendar_config_t calendar_config = { + .hour_format = HAL_RTC_CALENDAR_HOUR_FORMAT_24, + .bypass_shadow_register = HAL_RTC_CALENDAR_SHADOW_REG_BYPASS +}; +#else static RTC_HandleTypeDef RtcHandle = {.Instance = RTC}; +#endif static voidCallbackPtr RTCUserCallback = NULL; static void *callbackUserData = NULL; -#ifdef RTC_ALARM_B +#if defined(ALARM_B_AVAILABLE) static voidCallbackPtr RTCUserCallbackB = NULL; static void *callbackUserDataB = NULL; #endif @@ -93,7 +117,7 @@ static void RTC_initClock(sourceClock_t source); #if !defined(STM32F1xx) static void RTC_computePrediv(uint32_t *asynch, uint32_t *synch); #endif /* !STM32F1xx */ -#if defined(RTC_BINARY_NONE) +#if defined(LL_RTC_BINARY_NONE) static void RTC_BinaryConf(binaryMode_t mode); static void RTC_SetBinaryConf(void); #endif @@ -104,6 +128,7 @@ static inline int _log2(int x) } /* Exported functions --------------------------------------------------------*/ +#if !defined(USE_HALV2_DRIVER) /** * @brief Get pointer to RTC_HandleTypeDef * @param None @@ -113,6 +138,7 @@ RTC_HandleTypeDef *RTC_GetHandle(void) { return &RtcHandle; } +#endif /* !USE_HALV2_DRIVER */ /** * @brief Set RTC clock source @@ -192,6 +218,25 @@ void RTC_SetClockSource(sourceClock_t source) */ static void RTC_initClock(sourceClock_t source) { +#if defined(USE_HALV2_DRIVER) + hal_status_t status = HAL_ERROR; + RTC_SetClockSource(source); + if (source == LSE_CLOCK) { + enableClock(LSE_CLOCK); + status = HAL_RCC_RTC_SetKernelClkSource(HAL_RCC_RTC_CLK_SRC_LSE); + } else if (source == LSI_CLOCK) { + enableClock(LSI_CLOCK); + status = HAL_RCC_RTC_SetKernelClkSource(HAL_RCC_RTC_CLK_SRC_LSI); + } else if (source == HSE_CLOCK) { + enableClock(HSE_CLOCK); + status = HAL_RCC_RTC_SetKernelClkSource(HAL_RCC_RTC_CLK_SRC_HSE_DIV); + } + if (status != HAL_OK) { + Error_Handler(); + } + /* Enable the RTC peripheral */ + LL_RCC_EnableRTC(); +#else RCC_PeriphCLKInitTypeDef PeriphClkInit; RTC_SetClockSource(source); if (source == LSE_CLOCK) { @@ -276,6 +321,7 @@ static void RTC_initClock(sourceClock_t source) #if defined(__HAL_RCC_RTC_CLK_ENABLE) __HAL_RCC_RTC_CLK_ENABLE(); #endif +#endif /* USE_HALV2_DRIVER */ } /** @@ -289,7 +335,7 @@ static void RTC_initClock(sourceClock_t source) void RTC_setPrediv(uint32_t asynch, uint32_t synch) { #if defined(STM32F1xx) - UNUSED(synch); + (void)synch; /* set the prescaler for a stm32F1 (value is hold by one param) */ predivAsync = asynch; if (!IS_RTC_ASYNCH_PREDIV(predivAsync)) { @@ -319,18 +365,27 @@ void RTC_setPrediv(uint32_t asynch, uint32_t synch) void RTC_getPrediv(uint32_t *asynch, uint32_t *synch) { #if defined(STM32F1xx) - UNUSED(synch); + (void)synch; /* get the prescaler for a stm32F1 (value is hold by one param) */ predivAsync = LL_RTC_GetDivider(RTC); *asynch = predivAsync; #else if ((!IS_RTC_SYNCH_PREDIV(predivSync)) || (!IS_RTC_ASYNCH_PREDIV(predivAsync))) { - if (!LL_RTC_IsActiveFlag_INITS(RtcHandle.Instance)) { +#if defined(USE_HALV2_DRIVER) + if (!LL_RTC_IsActiveFlag_INITS()) { RTC_computePrediv(&predivAsync, &predivSync); } else { - predivAsync = LL_RTC_GetAsynchPrescaler(RtcHandle.Instance); - predivSync = LL_RTC_GetSynchPrescaler(RtcHandle.Instance); + predivAsync = LL_RTC_GetAsynchPrescaler(); + predivSync = LL_RTC_GetSynchPrescaler(); } +#else + if (!LL_RTC_IsActiveFlag_INITS(RTC)) { + RTC_computePrediv(&predivAsync, &predivSync); + } else { + predivAsync = LL_RTC_GetAsynchPrescaler(RTC); + predivSync = LL_RTC_GetSynchPrescaler(RTC); + } +#endif } if ((asynch != NULL) && (synch != NULL)) { *asynch = predivAsync; @@ -386,9 +441,35 @@ static void RTC_computePrediv(uint32_t *asynch, uint32_t *synch) } #endif /* !STM32F1xx */ -#if defined(RTC_BINARY_NONE) +#if defined(LL_RTC_BINARY_NONE) static void RTC_BinaryConf(binaryMode_t mode) { +#if defined(USE_HALV2_DRIVER) + rtc_config.mode = (mode == MODE_BINARY_MIX) ? HAL_RTC_MODE_MIX : ((mode == MODE_BINARY_ONLY) ? HAL_RTC_MODE_BINARY : HAL_RTC_MODE_BCD); + if (rtc_config.mode == HAL_RTC_MODE_MIX) { + /* Configure the 1s BCD calendar increment */ + uint32_t inc = 1 / (1.0 / ((float)clkVal / (float)(predivAsync + 1.0))); + if (inc <= 256) { + rtc_config.bcd_update = HAL_RTC_BCD_UPDATE_8BITS; + } else if (inc < (256 << 1)) { + rtc_config.bcd_update = HAL_RTC_BCD_UPDATE_9BITS; + } else if (inc < (256 << 2)) { + rtc_config.bcd_update = HAL_RTC_BCD_UPDATE_10BITS; + } else if (inc < (256 << 3)) { + rtc_config.bcd_update = HAL_RTC_BCD_UPDATE_11BITS; + } else if (inc < (256 << 4)) { + rtc_config.bcd_update = HAL_RTC_BCD_UPDATE_12BITS; + } else if (inc < (256 << 5)) { + rtc_config.bcd_update = HAL_RTC_BCD_UPDATE_13BITS; + } else if (inc < (256 << 6)) { + rtc_config.bcd_update = HAL_RTC_BCD_UPDATE_14BITS; + } else if (inc < (256 << 7)) { + rtc_config.bcd_update = HAL_RTC_BCD_UPDATE_15BITS; + } else { + Error_Handler(); + } + } +#else RtcHandle.Init.BinMode = (mode == MODE_BINARY_MIX) ? RTC_BINARY_MIX : ((mode == MODE_BINARY_ONLY) ? RTC_BINARY_ONLY : RTC_BINARY_NONE); if (RtcHandle.Init.BinMode == RTC_BINARY_MIX) { /* Configure the 1s BCD calendar increment */ @@ -414,6 +495,7 @@ static void RTC_BinaryConf(binaryMode_t mode) Error_Handler(); } } +#endif } /* @@ -423,27 +505,43 @@ static void RTC_BinaryConf(binaryMode_t mode) * 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 !defined(USE_HALV2_DRIVER) #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 +#endif /* !USE_HALV2_DRIVER */ static void RTC_SetBinaryConf(void) { - if (LL_RTC_GetBinaryMode(RtcHandle.Instance) != RtcHandle.Init.BinMode) { - LL_RTC_DisableWriteProtection(RtcHandle.Instance); - LL_RTC_EnableInitMode(RtcHandle.Instance); +#if defined(USE_HALV2_DRIVER) + if (LL_RTC_GetBinaryMode() != rtc_config.mode) { + LL_RTC_DisableWriteProtection(); + LL_RTC_EnableInitMode(); + + LL_RTC_SetBinaryMode(rtc_config.mode); + if (rtc_config.mode == HAL_RTC_MODE_MIX) { + LL_RTC_SetBinMixBCDU(rtc_config.bcd_update); + } + LL_RTC_DisableInitMode(); + LL_RTC_EnableWriteProtection(); + } +#else + if (LL_RTC_GetBinaryMode(RTC) != RtcHandle.Init.BinMode) { + LL_RTC_DisableWriteProtection(RTC); + LL_RTC_EnableInitMode(RTC); - LL_RTC_SetBinaryMode(RtcHandle.Instance, RtcHandle.Init.BinMode); + LL_RTC_SetBinaryMode(RTC, RtcHandle.Init.BinMode); if (RtcHandle.Init.BinMode == RTC_BINARY_MIX) { - LL_RTC_SetBinMixBCDU(RtcHandle.Instance, RtcHandle.Init.BinMixBcdU); + LL_RTC_SetBinMixBCDU(RTC, RtcHandle.Init.BinMixBcdU); } - LL_RTC_ExitInitMode(RtcHandle.Instance); - LL_RTC_EnableWriteProtection(RtcHandle.Instance); + LL_RTC_ExitInitMode(RTC); + LL_RTC_EnableWriteProtection(RTC); } +#endif /* USE_HALV2_DRIVER */ } -#endif /* RTC_BINARY_NONE */ +#endif /* LL_RTC_BINARY_NONE */ /** * @brief RTC Initialization @@ -464,7 +562,7 @@ bool RTC_init(hourFormat_t format, binaryMode_t mode, sourceClock_t source, bool uint8_t seconds = 0, minutes = 0, hours = 0, weekDay = 0, days = 0, month = 0, years = 0; uint8_t alarmMask = 0, alarmDay = 0, alarmHours = 0, alarmMinutes = 0, alarmSeconds = 0; bool isAlarmASet = false; -#ifdef RTC_ALARM_B +#if defined(ALARM_B_AVAILABLE) hourAM_PM_t alarmBPeriod = HOUR_AM; uint8_t alarmBMask = 0, alarmBDay = 0, alarmBHours = 0, alarmBMinutes = 0, alarmBSeconds = 0; uint32_t alarmBSubseconds = 0; @@ -473,6 +571,15 @@ bool RTC_init(hourFormat_t format, binaryMode_t mode, sourceClock_t source, bool initFormat = format; initMode = mode; + +#if defined(USE_HALV2_DRIVER) + /* Ensure backup domain is enabled before we init the RTC so we can use the backup registers for date retention on stm32f1xx boards */ + enableBackupDomain(); + + if (reset) { + resetBackupDomain(); + } +#else /* Ensure all RtcHandle properly set */ RtcHandle.Instance = RTC; #if defined(STM32F1xx) @@ -506,8 +613,9 @@ bool RTC_init(hourFormat_t format, binaryMode_t mode, sourceClock_t source, bool #ifdef __HAL_RCC_RTC_ENABLE __HAL_RCC_RTC_ENABLE(); #endif +#endif /* USE_HALV2_DRIVER */ isAlarmASet = RTC_IsAlarmSet(ALARM_A); -#ifdef RTC_ALARM_B +#if defined(ALARM_B_AVAILABLE) isAlarmBSet = RTC_IsAlarmSet(ALARM_B); #endif #if defined(STM32F1xx) @@ -519,21 +627,41 @@ bool RTC_init(hourFormat_t format, binaryMode_t mode, sourceClock_t source, bool // Init RTC clock RTC_initClock(source); #else - if (!LL_RTC_IsActiveFlag_INITS(RtcHandle.Instance) || reset) { +#if defined(USE_HALV2_DRIVER) + if (!LL_RTC_IsActiveFlag_INITS() || reset) { +#else + if (!LL_RTC_IsActiveFlag_INITS(RTC) || reset) { +#endif + // RTC needs initialization // Init RTC clock RTC_initClock(source); +#if defined(USE_HALV2_DRIVER) + RTC_getPrediv(&(rtc_config.asynch_prediv), &(rtc_config.synch_prediv)); +#else RTC_getPrediv(&(RtcHandle.Init.AsynchPrediv), &(RtcHandle.Init.SynchPrediv)); -#if defined(RTC_BINARY_NONE) +#endif +#if defined(LL_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 /* LL_RTC_BINARY_NONE */ #endif // STM32F1xx +#if defined(USE_HALV2_DRIVER) + rtc_config.mode = (initMode == MODE_BINARY_MIX) ? HAL_RTC_MODE_MIX : (initMode == MODE_BINARY_ONLY ? HAL_RTC_MODE_BINARY : HAL_RTC_MODE_BCD); + calendar_config.hour_format = (format == HOUR_FORMAT_24) ? HAL_RTC_CALENDAR_HOUR_FORMAT_24 : HAL_RTC_CALENDAR_HOUR_FORMAT_AMPM; + HAL_RTC_DisableWriteProtection(); + if ((HAL_RTC_EnterInitMode() != HAL_OK) || (HAL_RTC_SetConfig(&rtc_config) != HAL_OK) || + (HAL_RTC_CALENDAR_SetConfig(&calendar_config) != HAL_OK) || + (HAL_RTC_ExitInitMode() != HAL_OK) || (HAL_RTC_EnableWriteProtection() != HAL_OK)) { + Error_Handler(); + } +#else HAL_RTC_Init(&RtcHandle); +#endif // Default: saturday 1st of January 2001 // Note: year 2000 is invalid as it is the hardware reset value and doesn't raise INITS flag RTC_SetDate(1, 1, 1, 6); @@ -555,17 +683,19 @@ bool RTC_init(hourFormat_t format, binaryMode_t mode, sourceClock_t source, bool // default case corresponding to no clock source 0xFFFFFFFF); #else - uint32_t oldRtcClockSource = __HAL_RCC_GET_RTC_SOURCE(); - oldRtcClockSource = ((oldRtcClockSource == RCC_RTCCLKSOURCE_LSE) ? LSE_CLOCK : - (oldRtcClockSource == RCC_RTCCLKSOURCE_LSI) ? LSI_CLOCK : -#if defined(RCC_RTCCLKSOURCE_HSE_DIVX) - (oldRtcClockSource == RCC_RTCCLKSOURCE_HSE_DIVX) ? HSE_CLOCK : -#elif defined(RCC_RTCCLKSOURCE_HSE_DIV32) - (oldRtcClockSource == RCC_RTCCLKSOURCE_HSE_DIV32) ? HSE_CLOCK : -#elif defined(RCC_RTCCLKSOURCE_HSE_DIV) - (oldRtcClockSource == RCC_RTCCLKSOURCE_HSE_DIV) ? HSE_CLOCK : -#elif defined(RCC_RTCCLKSOURCE_HSE_DIV128) - (oldRtcClockSource == RCC_RTCCLKSOURCE_HSE_DIV128) ? HSE_CLOCK : +#if defined(STM32U3xx) + uint32_t oldRtcClockSource = LL_RCC_GetRTCClockSource(0); +#else + uint32_t oldRtcClockSource = LL_RCC_GetRTCClockSource(); +#endif + oldRtcClockSource = ((oldRtcClockSource == LL_RCC_RTC_CLKSOURCE_LSE) ? LSE_CLOCK : + (oldRtcClockSource == LL_RCC_RTC_CLKSOURCE_LSI) ? LSI_CLOCK : +#if defined(LL_RCC_RTC_CLKSOURCE_HSE) + (oldRtcClockSource == LL_RCC_RTC_CLKSOURCE_HSE) ? HSE_CLOCK : +#elif defined(LL_RCC_RTC_CLKSOURCE_HSE_DIV32) + (oldRtcClockSource == LL_RCC_RTC_CLKSOURCE_HSE_DIV32) ? HSE_CLOCK : +#elif defined(LL_RCC_RTC_CLKSOURCE_HSE_DIV128) + (oldRtcClockSource == LL_RCC_RTC_CLKSOURCE_HSE_DIV128) ? HSE_CLOCK : #endif // default case corresponding to no clock source 0xFFFFFFFF); @@ -579,7 +709,6 @@ bool RTC_init(hourFormat_t format, binaryMode_t mode, sourceClock_t source, bool memcpy(&RtcHandle.DateToUpdate, &BackupDate, 4); } #endif // STM32F1xx - if (source != oldRtcClockSource) { // RTC is already initialized, but RTC clock source is changed // In case of RTC source clock change, Backup Domain is reset by RTC_initClock() @@ -595,7 +724,7 @@ bool RTC_init(hourFormat_t format, binaryMode_t mode, sourceClock_t source, bool if (isAlarmASet) { RTC_GetAlarm(ALARM_A, &alarmDay, &alarmHours, &alarmMinutes, &alarmSeconds, &alarmSubseconds, &alarmPeriod, &alarmMask); } -#ifdef RTC_ALARM_B +#if defined(ALARM_B_AVAILABLE) if (isAlarmBSet) { RTC_GetAlarm(ALARM_B, &alarmBDay, &alarmBHours, &alarmBMinutes, &alarmBSeconds, &alarmBSubseconds, &alarmBPeriod, &alarmBMask); } @@ -605,24 +734,38 @@ bool RTC_init(hourFormat_t format, binaryMode_t mode, sourceClock_t source, bool RTC_initClock(source); #if defined(STM32F1xx) RTC_getPrediv(&(RtcHandle.Init.AsynchPrediv), NULL); +#elif defined(USE_HALV2_DRIVER) + RTC_getPrediv(&(rtc_config.asynch_prediv), &(rtc_config.synch_prediv)); #else RTC_getPrediv(&(RtcHandle.Init.AsynchPrediv), &(RtcHandle.Init.SynchPrediv)); #endif -#if defined(RTC_BINARY_NONE) +#if defined(LL_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 /* LL_RTC_BINARY_NONE */ +#if defined(USE_HALV2_DRIVER) + rtc_config.mode = (initMode == MODE_BINARY_MIX) ? HAL_RTC_MODE_MIX : (initMode == MODE_BINARY_ONLY ? HAL_RTC_MODE_BINARY : HAL_RTC_MODE_BCD); + calendar_config.hour_format = (format == HOUR_FORMAT_24) ? HAL_RTC_CALENDAR_HOUR_FORMAT_24 : HAL_RTC_CALENDAR_HOUR_FORMAT_AMPM; + + HAL_RTC_DisableWriteProtection(); + if ((HAL_RTC_EnterInitMode() != HAL_OK) || (HAL_RTC_SetConfig(&rtc_config) != HAL_OK) || + (HAL_RTC_CALENDAR_SetConfig(&calendar_config) != HAL_OK) || + (HAL_RTC_ExitInitMode() != HAL_OK) || (HAL_RTC_EnableWriteProtection() != HAL_OK)) { + Error_Handler(); + } +#else HAL_RTC_Init(&RtcHandle); +#endif /* USE_HALV2_DRIVER */ // Restore config RTC_SetTime(hours, minutes, seconds, subSeconds, period); RTC_SetDate(years, month, days, weekDay); if (isAlarmASet) { RTC_StartAlarm(ALARM_A, alarmDay, alarmHours, alarmMinutes, alarmSeconds, alarmSubseconds, alarmPeriod, alarmMask); } -#ifdef RTC_ALARM_B +#if defined(ALARM_B_AVAILABLE) if (isAlarmBSet) { RTC_StartAlarm(ALARM_B, alarmBDay, alarmBHours, alarmBMinutes, alarmBSeconds, alarmBSubseconds, alarmBPeriod, alarmBMask); } @@ -634,10 +777,12 @@ bool RTC_init(hourFormat_t format, binaryMode_t mode, sourceClock_t source, bool // This initialize variables: predivAsync, predivSync and predivSync_bits #if defined(STM32F1xx) RTC_getPrediv(&(RtcHandle.Init.AsynchPrediv), NULL); +#elif defined(USE_HALV2_DRIVER) + RTC_getPrediv(&(rtc_config.asynch_prediv), &(rtc_config.synch_prediv)); #else RTC_getPrediv(&(RtcHandle.Init.AsynchPrediv), &(RtcHandle.Init.SynchPrediv)); #endif -#if defined(RTC_BINARY_NONE) +#if defined(LL_RTC_BINARY_NONE) RTC_BinaryConf(mode); /* * RTC is already initialized, but RTC BIN mode is changed : @@ -646,7 +791,7 @@ bool RTC_init(hourFormat_t format, binaryMode_t mode, sourceClock_t source, bool */ RTC_SetBinaryConf(); -#endif /* RTC_BINARY_NONE */ +#endif /* LL_RTC_BINARY_NONE */ #if defined(STM32F1xx) memcpy(&RtcHandle.DateToUpdate, &BackupDate, 4); /* Update date automatically by calling HAL_RTC_GetDate */ @@ -660,8 +805,12 @@ bool RTC_init(hourFormat_t format, binaryMode_t mode, sourceClock_t source, bool #if defined(RTC_CR_BYPSHAD) /* Enable Direct Read of the calendar registers (not through Shadow) */ +#if defined(USE_HALV2_DRIVER) + LL_RTC_EnableBypassShadowReg(); +#else HAL_RTCEx_EnableBypassShadow(&RtcHandle); #endif +#endif /* RTC_CR_BYPSHAD */ /* * NOTE: freezing the RTC during stop mode (lowPower deepSleep) @@ -678,6 +827,15 @@ bool RTC_init(hourFormat_t format, binaryMode_t mode, sourceClock_t source, bool */ void RTC_DeInit(bool reset_cb) { +#if defined(USE_HALV2_DRIVER) + resetBackupDomain(); + LL_RCC_DisableRTC(); + HAL_RCC_RTCAPB_DisableClock(); + HAL_CORTEX_NVIC_DisableIRQ(RTC_Alarm_IRQn); +#ifdef ONESECOND_IRQn + HAL_CORTEX_NVIC_DisableIRQ(ONESECOND_IRQn); +#endif +#else HAL_RTC_DeInit(&RtcHandle); /* Peripheral clock disable */ #ifdef __HAL_RCC_RTC_DISABLE @@ -693,10 +851,11 @@ void RTC_DeInit(bool reset_cb) #ifdef STM32WLxx HAL_NVIC_DisableIRQ(TAMP_STAMP_LSECSS_SSRU_IRQn); #endif +#endif /* USE_HALV2_DRIVER */ if (reset_cb) { RTCUserCallback = NULL; callbackUserData = NULL; -#ifdef RTC_ALARM_B +#if defined(ALARM_B_AVAILABLE) RTCUserCallbackB = NULL; callbackUserDataB = NULL; #endif @@ -721,7 +880,11 @@ bool RTC_IsConfigured(void) BackupDate |= getBackupRegister(RTC_BKP_DATE + 1) & 0xFFFF; return (BackupDate != 0); #else - return LL_RTC_IsActiveFlag_INITS(RtcHandle.Instance); +#if defined(USE_HALV2_DRIVER) + return LL_RTC_IsActiveFlag_INITS(); +#else + return LL_RTC_IsActiveFlag_INITS(RTC); +#endif #endif } @@ -736,8 +899,26 @@ bool RTC_IsConfigured(void) */ void RTC_SetTime(uint8_t hours, uint8_t minutes, uint8_t seconds, uint32_t subSeconds, hourAM_PM_t period) { +#if defined(USE_HALV2_DRIVER) + hal_rtc_time_t rtc_time; + (void)subSeconds; /* not used (read-only register) */ + /* Ignore time AM PM configuration if in 24 hours format */ + if (initFormat == HOUR_FORMAT_24) { + period = HOUR_AM; + } + rtc_time.am_pm = (period == HOUR_PM) ? HAL_RTC_TIME_FORMAT_PM : HAL_RTC_TIME_FORMAT_AM_24H; + rtc_time.hour = hours; + rtc_time.min = minutes; + rtc_time.sec = seconds; + HAL_RTC_DisableWriteProtection(); + if (HAL_RTC_EnterInitMode() != HAL_OK || HAL_RTC_CALENDAR_SetTime(&rtc_time) != HAL_OK || + HAL_RTC_ExitInitMode() != HAL_OK || HAL_RTC_EnableWriteProtection() != HAL_OK) { + Error_Handler(); + } +#else + RTC_TimeTypeDef RTC_TimeStruct; - UNUSED(subSeconds); /* not used (read-only register) */ + (void)subSeconds; /* not used (read-only register) */ /* Ignore time AM PM configuration if in 24 hours format */ if (initFormat == HOUR_FORMAT_24) { period = HOUR_AM; @@ -762,11 +943,12 @@ void RTC_SetTime(uint8_t hours, uint8_t minutes, uint8_t seconds, uint32_t subSe RTC_TimeStruct.DayLightSaving = RTC_DAYLIGHTSAVING_NONE; RTC_TimeStruct.StoreOperation = RTC_STOREOPERATION_RESET; #else - UNUSED(period); + (void)period; #endif /* !STM32F1xx */ HAL_RTC_SetTime(&RtcHandle, &RTC_TimeStruct, RTC_FORMAT_BIN); } +#endif /* USE_HALV2_DRIVER */ } /** @@ -780,6 +962,38 @@ void RTC_SetTime(uint8_t hours, uint8_t minutes, uint8_t seconds, uint32_t subSe */ void RTC_GetTime(uint8_t *hours, uint8_t *minutes, uint8_t *seconds, uint32_t *subSeconds, hourAM_PM_t *period) { +#if defined(USE_HALV2_DRIVER) + if ((hours != NULL) && (minutes != NULL) && (seconds != NULL)) { + hal_rtc_time_t rtc_time; + if (HAL_RTC_CALENDAR_GetTime(&rtc_time) == HAL_OK) { /* in BIN mode, only the subsecond is used */ + *hours = rtc_time.hour; + *minutes = rtc_time.min; + *seconds = rtc_time.sec; + if (period != NULL) { + if (rtc_time.am_pm == HAL_RTC_TIME_FORMAT_PM) { + *period = HOUR_PM; + } else { + *period = HOUR_AM; + } + } + if (subSeconds != NULL) { + /* + * The subsecond is the free-running downcounter, to be converted in milliseconds. + */ + if (initMode == MODE_BINARY_ONLY) { + *subSeconds = (((UINT32_MAX - rtc_time.subsec + 1) & UINT32_MAX) + * 1000) / fqce_apre; + } else if (initMode == MODE_BINARY_MIX) { + *subSeconds = (((UINT32_MAX - rtc_time.subsec) & predivSync) + * 1000) / fqce_apre; + } else { + /* the subsecond register value is converted in millisec on 32bit */ + *subSeconds = ((predivSync - rtc_time.subsec) * 1000) / (predivSync + 1); + } + } + } + } +#else RTC_TimeTypeDef RTC_TimeStruct = {0}; /* in BIN mode, only the subsecond is used */ if ((hours != NULL) && (minutes != NULL) && (seconds != NULL)) { @@ -818,17 +1032,18 @@ void RTC_GetTime(uint8_t *hours, uint8_t *minutes, uint8_t *seconds, uint32_t *s } } #else - UNUSED(subSeconds); + (void)subSeconds; #endif /* RTC_SSR_SS */ #else - UNUSED(period); - UNUSED(subSeconds); + (void)period; + (void)subSeconds; if (current_date != RtcHandle.DateToUpdate.Date) { RTC_StoreDate(); } #endif /* !STM32F1xx */ } +#endif /* USE_HALV2_DRIVER */ } /** @@ -841,6 +1056,21 @@ void RTC_GetTime(uint8_t *hours, uint8_t *minutes, uint8_t *seconds, uint32_t *s */ void RTC_SetDate(uint8_t year, uint8_t month, uint8_t day, uint8_t wday) { +#if defined(USE_HALV2_DRIVER) + hal_rtc_date_t rtc_date; + + if (IS_RTC_YEAR(year) && IS_RTC_MONTH(month) && IS_RTC_DATE(day) && IS_RTC_WEEKDAY(wday)) { + rtc_date.year = year; + rtc_date.mon = month; + rtc_date.mday = day; + rtc_date.wday = wday; + HAL_RTC_DisableWriteProtection(); + if (HAL_RTC_EnterInitMode() != HAL_OK || HAL_RTC_CALENDAR_SetDate(&rtc_date) != HAL_OK || + HAL_RTC_ExitInitMode() != HAL_OK || HAL_RTC_EnableWriteProtection() != HAL_OK) { + Error_Handler(); + } + } +#else RTC_DateTypeDef RTC_DateStruct; if (IS_RTC_YEAR(year) && IS_RTC_MONTH(month) && IS_RTC_DATE(day) && IS_RTC_WEEKDAY(wday)) { @@ -853,6 +1083,7 @@ void RTC_SetDate(uint8_t year, uint8_t month, uint8_t day, uint8_t wday) RTC_StoreDate(); #endif /* STM32F1xx */ } +#endif } /** @@ -865,6 +1096,17 @@ 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) { +#if defined(USE_HALV2_DRIVER) + if ((year != NULL) && (month != NULL) && (day != NULL) && (wday != NULL)) { + hal_rtc_date_t rtc_date; + if (HAL_RTC_CALENDAR_GetDate(&rtc_date) == HAL_OK) { /* in BIN mode, the date is not used */ + *year = rtc_date.year; + *month = rtc_date.mon; + *day = rtc_date.mday; + *wday = rtc_date.wday; + } + } +#else RTC_DateTypeDef RTC_DateStruct = {0}; /* in BIN mode, the date is not used */ if ((year != NULL) && (month != NULL) && (day != NULL) && (wday != NULL)) { @@ -874,6 +1116,7 @@ void RTC_GetDate(uint8_t *year, uint8_t *month, uint8_t *day, uint8_t *wday) *day = RTC_DateStruct.Date; *wday = RTC_DateStruct.WeekDay; } +#endif } /** @@ -892,8 +1135,109 @@ void RTC_GetDate(uint8_t *year, uint8_t *month, uint8_t *day, uint8_t *wday) */ 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(USE_HALV2_DRIVER) + hal_rtc_alarm_t rtc_alarm = (name == ALARM_A) ? HAL_RTC_ALARM_A : HAL_RTC_ALARM_B; + hal_rtc_alarm_config_t rtc_alarm_config; + hal_rtc_alarm_date_time_t rtc_alarm_date_time; + /* Ignore time AM PM configuration if in 24 hours format */ + if (initFormat == HOUR_FORMAT_24) { + period = HOUR_AM; + } + + if ((((initFormat == HOUR_FORMAT_24) && IS_RTC_HOUR24(hours)) || IS_RTC_HOUR12(hours)) + && IS_RTC_DATE(day) && IS_RTC_MINUTES(minutes) && IS_RTC_SECONDS(seconds)) { + rtc_alarm_date_time.time.hour = hours; + rtc_alarm_date_time.time.min = minutes; + rtc_alarm_date_time.time.sec = seconds; + rtc_alarm_date_time.time.am_pm = (period == HOUR_PM) ? HAL_RTC_TIME_FORMAT_PM : HAL_RTC_TIME_FORMAT_AM_24H; + rtc_alarm_date_time.mday_wday_selection = HAL_RTC_ALARM_DAY_TYPE_SEL_MONTHDAY; + rtc_alarm_date_time.wday_mday.mday = day; + rtc_alarm_date_time.mask = mask; + /* configure AlarmMask (M_MSK and Y_MSK ignored) */ + if (mask == OFF_MSK) { + rtc_alarm_date_time.mask = HAL_RTC_ALARM_MASK_ALL; + } else { + rtc_alarm_date_time.mask = HAL_RTC_ALARM_MASK_NONE; + if (!(mask & SS_MSK)) { + rtc_alarm_date_time.mask |= HAL_RTC_ALARM_MASK_SECONDS; + } + if (!(mask & MM_MSK)) { + rtc_alarm_date_time.mask |= HAL_RTC_ALARM_MASK_MINUTES; + } + if (!(mask & HH_MSK)) { + rtc_alarm_date_time.mask |= HAL_RTC_ALARM_MASK_HOURS; + } + if (!(mask & D_MSK)) { + rtc_alarm_date_time.mask |= HAL_RTC_ALARM_MASK_DAY; + } + } + + if (subSeconds < 1000) { + if (name == ALARM_B) { + rtc_alarm_date_time.subsec_mask = predivSync_bits << RTC_ALRMBSSR_MASKSS_Pos; + } else { + rtc_alarm_date_time.subsec_mask = predivSync_bits << RTC_ALRMASSR_MASKSS_Pos; + } + /* + * The subsecond param is a nb of milliseconds to be converted in a subsecond + * downcounter value and to be compared to the SubSecond register + */ + if ((initMode == MODE_BINARY_ONLY) || (initMode == MODE_BINARY_MIX)) { + /* the subsecond is the millisecond to be converted in a subsecond downcounter value */ + uint64_t tmp = (subSeconds * (uint64_t)(predivSync + 1)) / (uint64_t)1000; + rtc_alarm_date_time.time.subsec = (uint32_t)UINT32_MAX - (uint32_t)tmp; + } else { + rtc_alarm_date_time.time.subsec = predivSync - ((uint32_t)subSeconds * (predivSync + 1)) / 1000; + } + } else { + rtc_alarm_date_time.subsec_mask = HAL_RTC_ALARM_MASK_ALL; + } + } else { + /* SS have to be managed*/ + rtc_alarm_config.subsec_auto_reload = HAL_RTC_ALARM_SUBSECONDS_AUTO_RELOAD_DISABLE; + rtc_alarm_config.auto_clear = HAL_ALARM_AUTO_CLEAR_DISABLE; + rtc_alarm_date_time.mask = HAL_RTC_ALARM_MASK_ALL; + if (name == ALARM_B) { + /* Expecting RTC_ALARMSUBSECONDBINMASK_NONE for the subsecond mask on ALARM B */ + rtc_alarm_date_time.subsec_mask = mask << RTC_ALRMBSSR_MASKSS_Pos; + } else { + /* Expecting RTC_ALARMSUBSECONDBINMASK_NONE for the subsecond mask on ALARM A */ + rtc_alarm_date_time.subsec_mask = mask << RTC_ALRMASSR_MASKSS_Pos; + } + 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 + * For the conversion, we keep the accuracy on 64 bits, since otherwise we might + * have an overflow even though the conversion result still fits in 32 bits. + */ + uint64_t tmp = (subSeconds * (uint64_t)(predivSync + 1)) / (uint64_t)1000; + rtc_alarm_date_time.time.subsec = (uint32_t)UINT32_MAX - (uint32_t)tmp; + } else { + rtc_alarm_date_time.time.subsec = predivSync - subSeconds * (predivSync + 1) / 1000; + } + } + HAL_RTC_DisableWriteProtection(); + if (LL_RTC_ALM_IsStarted((uint32_t)rtc_alarm) == 1U) { + HAL_RTC_ALARM_Stop(rtc_alarm); + if (rtc_alarm == HAL_RTC_ALARM_A) { + LL_RTC_ClearFlag_ALRA(); + } else { + LL_RTC_ClearFlag_ALRB(); + } + } + if (HAL_RTC_ALARM_SetConfig(rtc_alarm, &rtc_alarm_config) == HAL_OK) { + if (HAL_RTC_ALARM_SetDateTime(rtc_alarm, &rtc_alarm_date_time) == HAL_OK) { + HAL_RTC_ALARM_Start(rtc_alarm, HAL_RTC_ALARM_IT_ENABLE); + HAL_CORTEX_NVIC_SetPriority(RTC_Alarm_IRQn, RTC_IRQ_PRIO, RTC_IRQ_SUBPRIO); + HAL_CORTEX_NVIC_EnableIRQ(RTC_Alarm_IRQn); + } + } + if (HAL_RTC_EnableWriteProtection() != HAL_OK) { + Error_Handler(); + } +#else /* !USE_HALV2_DRIVER */ #if !defined(RTC_SSR_SS) - UNUSED(subSeconds); + (void)subSeconds; #endif RTC_AlarmTypeDef RTC_AlarmStructure; @@ -902,8 +1246,16 @@ void RTC_StartAlarm64(alarm_t name, uint8_t day, uint8_t hours, uint8_t minutes, period = HOUR_AM; } - /* Use alarm A by default because it is common to all STM32 HAL */ - RTC_AlarmStructure.Alarm = name; +#if !defined(ALARM_B_AVAILABLE) + (void)name; +#else + if (name == ALARM_B) { + RTC_AlarmStructure.Alarm = RTC_ALARM_B; + } else +#endif + { + RTC_AlarmStructure.Alarm = RTC_ALARM_A; + } if ((((initFormat == HOUR_FORMAT_24) && IS_RTC_HOUR24(hours)) || IS_RTC_HOUR12(hours)) && IS_RTC_DATE(day) && IS_RTC_MINUTES(minutes) && IS_RTC_SECONDS(seconds)) { @@ -914,7 +1266,7 @@ void RTC_StartAlarm64(alarm_t name, uint8_t day, uint8_t hours, uint8_t minutes, #if !defined(STM32F1xx) #if defined(RTC_SSR_SS) if (subSeconds < 1000) { -#ifdef RTC_ALARM_B +#if defined(ALARM_B_AVAILABLE) if (name == ALARM_B) { RTC_AlarmStructure.AlarmSubSecondMask = predivSync_bits << RTC_ALRMBSSR_MASKSS_Pos; } else @@ -965,9 +1317,9 @@ void RTC_StartAlarm64(alarm_t name, uint8_t day, uint8_t hours, uint8_t minutes, } } #else - UNUSED(period); - UNUSED(day); - UNUSED(mask); + (void)period; + (void)day; + (void)mask; #endif /* !STM32F1xx */ /* Set RTC_Alarm */ @@ -982,7 +1334,7 @@ void RTC_StartAlarm64(alarm_t name, uint8_t day, uint8_t hours, uint8_t minutes, RTC_AlarmStructure.BinaryAutoClr = RTC_ALARMSUBSECONDBIN_AUTOCLR_NO; #endif /* RTC_ALRMASSR_SSCLR */ RTC_AlarmStructure.AlarmMask = RTC_ALARMMASK_ALL; -#ifdef RTC_ALARM_B +#if defined(ALARM_B_AVAILABLE) if (name == ALARM_B) { /* Expecting RTC_ALARMSUBSECONDBINMASK_NONE for the subsecond mask on ALARM B */ RTC_AlarmStructure.AlarmSubSecondMask = mask << RTC_ALRMBSSR_MASKSS_Pos; @@ -1012,6 +1364,7 @@ void RTC_StartAlarm64(alarm_t name, uint8_t day, uint8_t hours, uint8_t minutes, HAL_NVIC_EnableIRQ(RTC_Alarm_IRQn); } #endif /* RTC_SSR_SS */ +#endif /* USE_HALV2_DRIVER */ } /** @@ -1041,7 +1394,16 @@ void RTC_StartAlarm(alarm_t name, uint8_t day, uint8_t hours, uint8_t minutes, u void RTC_StopAlarm(alarm_t name) { /* Clear RTC Alarm Flag */ -#ifdef RTC_ALARM_B +#if defined(USE_HALV2_DRIVER) + if (name == ALARM_A) { + LL_RTC_ClearFlag_ALRA(); + HAL_RTC_ALARM_Stop(HAL_RTC_ALARM_A); + } else { + LL_RTC_ClearFlag_ALRB(); + HAL_RTC_ALARM_Stop(HAL_RTC_ALARM_B); + } +#else +#if defined(ALARM_B_AVAILABLE) if (name == ALARM_B) { __HAL_RTC_ALARM_CLEAR_FLAG(&RtcHandle, RTC_FLAG_ALRBF); } else @@ -1051,6 +1413,7 @@ void RTC_StopAlarm(alarm_t name) } /* Disable the Alarm A interrupt */ HAL_RTC_DeactivateAlarm(&RtcHandle, name); +#endif } /** @@ -1062,18 +1425,24 @@ bool RTC_IsAlarmSet(alarm_t name) { bool status = false; #if defined(STM32F1xx) - UNUSED(name); - status = LL_RTC_IsEnabledIT_ALR(RtcHandle.Instance); + (void)name; + status = LL_RTC_IsEnabledIT_ALR(RTC); +#elif defined(USE_HALV2_DRIVER) + if (name == ALARM_A) { + status = LL_RTC_IsEnabledIT_ALRA(); + } else { + status = LL_RTC_IsEnabledIT_ALRB(); + } #else -#ifdef RTC_ALARM_B +#if defined(ALARM_B_AVAILABLE) if (name == ALARM_B) { - status = LL_RTC_IsEnabledIT_ALRB(RtcHandle.Instance); + status = LL_RTC_IsEnabledIT_ALRB(RTC); } else #else - UNUSED(name); + (void)name; #endif { - status = LL_RTC_IsEnabledIT_ALRA(RtcHandle.Instance); + status = LL_RTC_IsEnabledIT_ALRA(RTC); } #endif return status; @@ -1094,6 +1463,63 @@ 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) { +#if defined(USE_HALV2_DRIVER) + if ((hours != NULL) && (minutes != NULL) && (seconds != NULL)) { + hal_rtc_alarm_t rtc_alarm = (name == ALARM_A) ? HAL_RTC_ALARM_A : HAL_RTC_ALARM_B; + hal_rtc_alarm_date_time_t rtc_alarm_date_time; + + HAL_RTC_ALARM_GetDateTime(rtc_alarm, &rtc_alarm_date_time); + *seconds = rtc_alarm_date_time.time.sec; + *minutes = rtc_alarm_date_time.time.min; + *hours = rtc_alarm_date_time.time.hour; + if (day != NULL) { + *day = rtc_alarm_date_time.wday_mday.mday; + } + if (period != NULL) { + if (rtc_alarm_date_time.time.am_pm == HAL_RTC_TIME_FORMAT_PM) { + *period = HOUR_PM; + } else { + *period = HOUR_AM; + } + } + if (mask != NULL) { + *mask = OFF_MSK; + if (!(rtc_alarm_date_time.mask & HAL_RTC_ALARM_MASK_SECONDS)) { + *mask |= SS_MSK; + } + if (!(rtc_alarm_date_time.mask & HAL_RTC_ALARM_MASK_MINUTES)) { + *mask |= MM_MSK; + } + if (!(rtc_alarm_date_time.mask & HAL_RTC_ALARM_MASK_HOURS)) { + *mask |= HH_MSK; + } + if (!(rtc_alarm_date_time.mask & HAL_RTC_ALARM_MASK_DAY)) { + *mask |= D_MSK; + } + } + if (period != NULL) { + if (rtc_alarm_date_time.time.am_pm == HAL_RTC_TIME_FORMAT_PM) { + *period = HOUR_PM; + } else { + *period = HOUR_AM; + } + } + if (day != NULL) { + *day = rtc_alarm_date_time.wday_mday.mday; + } + if (subSeconds != NULL) { + /* + * The subsecond is the bit SS[14:0] of the ALARM SSR register (not ALARMxINR) + * to be converted in milliseconds + */ + if ((initMode == MODE_BINARY_ONLY) || (initMode == MODE_BINARY_MIX)) { + /* read the ALARM SSR register on SS[14:0] bits --> 0x7FFF */ + *subSeconds = (((0x7fff - HAL_RTC_ALARM_GetBinaryTime(rtc_alarm) + 1) & 0x7fff) * 1000) / fqce_apre; + } else { + *subSeconds = ((predivSync - rtc_alarm_date_time.time.subsec) * 1000) / (predivSync + 1); + } + } +#else RTC_AlarmTypeDef RTC_AlarmStructure; if ((hours != NULL) && (minutes != NULL) && (seconds != NULL)) { @@ -1128,7 +1554,7 @@ void RTC_GetAlarm(alarm_t name, uint8_t *day, uint8_t *hours, uint8_t *minutes, } } #else - UNUSED(subSeconds); + (void)subSeconds; #endif /* RTC_SSR_SS */ if (mask != NULL) { *mask = OFF_MSK; @@ -1146,11 +1572,12 @@ void RTC_GetAlarm(alarm_t name, uint8_t *day, uint8_t *hours, uint8_t *minutes, } } #else - UNUSED(day); - UNUSED(period); - UNUSED(subSeconds); - UNUSED(mask); + (void)day; + (void)period; + (void)subSeconds; + (void)mask; #endif /* !STM32F1xx */ +#endif } } @@ -1163,13 +1590,13 @@ void RTC_GetAlarm(alarm_t name, uint8_t *day, uint8_t *hours, uint8_t *minutes, */ void attachAlarmCallback(voidCallbackPtr func, void *data, alarm_t name) { -#ifdef RTC_ALARM_B +#if defined(ALARM_B_AVAILABLE) if (name == ALARM_B) { RTCUserCallbackB = func; callbackUserDataB = data; } else #else - UNUSED(name); + (void)name; #endif { RTCUserCallback = func; @@ -1184,13 +1611,13 @@ void attachAlarmCallback(voidCallbackPtr func, void *data, alarm_t name) */ void detachAlarmCallback(alarm_t name) { -#ifdef RTC_ALARM_B +#if defined(ALARM_B_AVAILABLE) if (name == ALARM_B) { RTCUserCallbackB = NULL; callbackUserDataB = NULL; } else #else - UNUSED(name); + (void)name; #endif { RTCUserCallback = NULL; @@ -1198,21 +1625,41 @@ void detachAlarmCallback(alarm_t name) } } +#if defined(USE_HALV2_DRIVER) /** * @brief Alarm A callback. - * @param hrtc RTC handle + * @param None * @retval None */ +void HAL_RTC_AlarmAEventCallback(void) +{ + if (RTCUserCallback != NULL) { + RTCUserCallback(callbackUserData); + } +} + +/** + * @brief Alarm B callback. + * @param None + * @retval None + */ +void HAL_RTC_AlarmBEventCallback(void) +{ + if (RTCUserCallbackB != NULL) { + RTCUserCallbackB(callbackUserDataB); + } +} +#else void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc) { - UNUSED(hrtc); + (void)hrtc; if (RTCUserCallback != NULL) { RTCUserCallback(callbackUserData); } } -#ifdef RTC_ALARM_B +#if defined(ALARM_B_AVAILABLE) /** * @brief Alarm B callback. * @param hrtc RTC handle @@ -1220,14 +1667,14 @@ void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc) */ void HAL_RTCEx_AlarmBEventCallback(RTC_HandleTypeDef *hrtc) { - UNUSED(hrtc); + (void)hrtc; if (RTCUserCallbackB != NULL) { RTCUserCallbackB(callbackUserDataB); } } #endif - +#endif /* USE_HALV2_DRIVER */ /** * @brief RTC Alarm IRQHandler * @param None @@ -1235,8 +1682,11 @@ void HAL_RTCEx_AlarmBEventCallback(RTC_HandleTypeDef *hrtc) */ void RTC_Alarm_IRQHandler(void) { +#if defined(USE_HALV2_DRIVER) + HAL_RTC_ALARM_IRQHandler(); + HAL_RTC_WAKEUP_IRQHandler(); +#else HAL_RTC_AlarmIRQHandler(&RtcHandle); - #if defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F078xx) || \ defined(STM32F091xC) || defined(STM32F098xx) || defined(STM32F070xB) || \ defined(STM32F030xC) || defined(STM32G0xx) || defined(STM32H5xx) || \ @@ -1247,6 +1697,7 @@ void RTC_Alarm_IRQHandler(void) // but with a dedicated HAL IRQHandler HAL_RTCEx_WakeUpTimerIRQHandler(&RtcHandle); #endif +#endif } #ifdef ONESECOND_IRQn @@ -1259,26 +1710,36 @@ void RTC_Alarm_IRQHandler(void) */ void attachSecondsIrqCallback(voidCallbackPtr func) { + RTCSecondsIrqCallback = func; +#if defined(USE_HALV2_DRIVER) + hal_rtc_wakeup_config_t wakeup_config; + hal_rtc_time_t auto_reload_time = {.hour = 0, .min = 0, .sec = 1, .subsec = 0}; /* 1 second */ + hal_rtc_time_t auto_clear_time = {.hour = 0, .min = 0, .sec = 1, .subsec = 0}; /* 1 second */ + wakeup_config.clock = HAL_RTC_WAKEUP_TIMER_CLOCK_BCD_UPDATE; + if (HAL_RTC_WAKEUP_SetConfig(&wakeup_config) == HAL_OK) { + if (HAL_RTC_WAKEUP_SetPeriod(&auto_reload_time, &auto_clear_time) == HAL_OK) { + HAL_RTC_WAKEUP_Start(HAL_RTC_WAKEUP_IT_ENABLE); + } + } + /* Enable the IRQ that will trig the one-second interrupt */ + HAL_CORTEX_NVIC_EnableIRQ(ONESECOND_IRQn); +#else #if defined(STM32F1xx) /* callback called on Seconds interrupt */ - RTCSecondsIrqCallback = func; - HAL_RTCEx_SetSecond_IT(&RtcHandle); __HAL_RTC_SECOND_CLEAR_FLAG(&RtcHandle, RTC_FLAG_SEC); #else /* callback called on wakeUp interrupt for One-Second purpose*/ - RTCSecondsIrqCallback = func; - /* for MCUs using the wakeup feature : irq each second */ #if defined(RTC_WUTR_WUTOCLR) HAL_RTCEx_SetWakeUpTimer_IT(&RtcHandle, 0, RTC_WAKEUPCLOCK_CK_SPRE_16BITS, 0); #else HAL_RTCEx_SetWakeUpTimer_IT(&RtcHandle, 0, RTC_WAKEUPCLOCK_CK_SPRE_16BITS); #endif /* RTC_WUTR_WUTOCLR */ - #endif /* STM32F1xx */ /* enable the IRQ that will trig the one-second interrupt */ HAL_NVIC_EnableIRQ(ONESECOND_IRQn); +#endif /* USE_HALV2_DRIVER */ } /** @@ -1306,7 +1767,7 @@ void detachSecondsIrqCallback(void) */ void HAL_RTCEx_RTCEventCallback(RTC_HandleTypeDef *hrtc) { - UNUSED(hrtc); + (void)hrtc; if (RTCSecondsIrqCallback != NULL) { RTCSecondsIrqCallback(NULL); @@ -1329,14 +1790,23 @@ void RTC_IRQHandler(void) * @param hrtc RTC handle * @retval None */ +#if defined(USE_HALV2_DRIVER) +void HAL_RTC_WakeUpTimerEventCallback() +{ + if (RTCSecondsIrqCallback != NULL) { + RTCSecondsIrqCallback(NULL); + } +} +#else void HAL_RTCEx_WakeUpTimerEventCallback(RTC_HandleTypeDef *hrtc) { - UNUSED(hrtc); + (void)hrtc; if (RTCSecondsIrqCallback != NULL) { RTCSecondsIrqCallback(NULL); } } +#endif /** * @brief This function handles RTC Seconds through wakeup interrupt request. @@ -1345,7 +1815,11 @@ void HAL_RTCEx_WakeUpTimerEventCallback(RTC_HandleTypeDef *hrtc) */ void RTC_WKUP_IRQHandler(void) { +#if defined(USE_HALV2_DRIVER) + HAL_RTC_WAKEUP_IRQHandler(); +#else HAL_RTCEx_WakeUpTimerIRQHandler(&RtcHandle); +#endif } #endif /* STM32F1xx */ #endif /* ONESECOND_IRQn */ @@ -1407,6 +1881,6 @@ void RTC_StoreDate(void) } #endif -#endif /* HAL_RTC_MODULE_ENABLED && !HAL_RTC_MODULE_ONLY */ +#endif /* !HAL_RTC_MODULE_ONLY && (HAL_RTC_MODULE_ENABLED || (USE_HAL_RTC_MODULE...) */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/src/rtc.h b/src/rtc.h index 34af735..1fe1e31 100644 --- a/src/rtc.h +++ b/src/rtc.h @@ -43,12 +43,20 @@ #include "backup.h" #include "clock.h" -#if defined(HAL_RTC_MODULE_ENABLED) && !defined(HAL_RTC_MODULE_ONLY) +#if !defined(HAL_RTC_MODULE_ONLY) && \ + (defined(HAL_RTC_MODULE_ENABLED) || (defined(USE_HAL_RTC_MODULE) && (USE_HAL_RTC_MODULE == 1))) #ifdef __cplusplus extern "C" { #endif +#if defined(RTC_CR_ALRBE) +#if defined(RTC_ALARM_B) && (RTC_ALARM_B != RTC_CR_ALRBE) +#error "RTC_ALARM_B is not equal to RTC_CR_ALRBE" +#endif +#define ALARM_B_AVAILABLE +#endif /* RTC_CR_ALRBE */ + /* Exported types ------------------------------------------------------------*/ typedef enum { HOUR_FORMAT_12, @@ -82,16 +90,20 @@ typedef enum { } alarmMask_t; typedef enum { +#if defined(USE_HALV2_DRIVER) + ALARM_A = HAL_RTC_ALARM_A, + ALARM_B = HAL_RTC_ALARM_B +#else ALARM_A = RTC_ALARM_A, -#ifdef RTC_ALARM_B +#if defined(ALARM_B_AVAILABLE) ALARM_B = RTC_ALARM_B #endif +#endif } alarm_t; typedef void(*voidCallbackPtr)(void *); /* Exported constants --------------------------------------------------------*/ - #if defined(STM32F1xx) /* select 32 bits in backup memory to store date. 2 consecutive 16bit reg. are reserved: RTC_BKP_DATE & RTC_BKP_DATE + 1 */ @@ -128,10 +140,10 @@ typedef void(*voidCallbackPtr)(void *); #define PREDIVS_MAX 0xFFFFFFFFU /* Unused for STM32F1xx series */ #endif /* !STM32F1xx */ -#if defined(STM32C0xx) || defined(STM32F0xx) || defined(STM32H5xx) || \ - defined(STM32L0xx) || defined(STM32L5xx) || defined(STM32U3xx) || \ - defined(STM32U3xx) || defined(STM32U5xx) || defined(STM32WB0x) || \ - defined(STM32WBAxx) || defined(STM32WL3x) +#if defined(STM32C0xx) || defined(STM32C5xx) || defined(STM32F0xx) || \ + defined(STM32H5xx) || defined(STM32L0xx) || defined(STM32L5xx) || \ + defined(STM32U3xx) || defined(STM32U3xx) || defined(STM32U5xx) || \ + defined(STM32WB0x) || defined(STM32WBAxx) || defined(STM32WL3x) #define RTC_Alarm_IRQn RTC_IRQn #define RTC_Alarm_IRQHandler RTC_IRQHandler #endif @@ -141,7 +153,8 @@ typedef void(*voidCallbackPtr)(void *); #endif /* mapping the IRQn for the one-second interrupt depending on the soc */ -#if defined(STM32F1xx) || (defined(STM32F0xx) && defined(RTC_CR_WUTE)) || \ +#if defined(STM32C5xx) || defined(STM32F1xx) || \ + (defined(STM32F0xx) && defined(RTC_CR_WUTE)) || \ defined(STM32H5xx) || defined(STM32L0xx) || defined(STM32L5xx) || \ defined(STM32U3xx) || defined(STM32U5xx) || defined(STM32WB0x) || \ defined(STM32WBAxx) || defined(STM32WL3x) @@ -178,9 +191,32 @@ typedef void(*voidCallbackPtr)(void *); #define IS_RTC_HOUR12(HOUR) IS_RTC_HOUR24(HOUR) #endif /* !STM32F1xx && !IS_RTC_WEEKDAY */ +#if defined(USE_HALV2_DRIVER) +/* HALv2 provides equivalent macro checks when assert is enabled but + * they are private and not available when assert is disabled. + * So public macro checks are provided for the RTC driver. + */ +#define IS_RTC_YEAR(YEAR) ((YEAR) <= 99U) +#define IS_RTC_MONTH(MONTH) (((MONTH) >= 1U) && ((MONTH) <= 12U)) +#define IS_RTC_WEEKDAY(WEEKDAY) (((WEEKDAY) == HAL_RTC_WEEKDAY_MONDAY) \ + || ((WEEKDAY) == HAL_RTC_WEEKDAY_TUESDAY) \ + || ((WEEKDAY) == HAL_RTC_WEEKDAY_WEDNESDAY) \ + || ((WEEKDAY) == HAL_RTC_WEEKDAY_THURSDAY) \ + || ((WEEKDAY) == HAL_RTC_WEEKDAY_FRIDAY) \ + || ((WEEKDAY) == HAL_RTC_WEEKDAY_SATURDAY) \ + || ((WEEKDAY) == HAL_RTC_WEEKDAY_SUNDAY)) +#define IS_RTC_DATE(DATE) (((DATE) >= 1U) && ((DATE) <= 31U)) +#define IS_RTC_HOUR12(HOUR) (((HOUR) > 0U) && ((HOUR) <= 12U)) +#define IS_RTC_HOUR24(HOUR) ((HOUR) <= 23U) +#define IS_RTC_MINUTES(MINUTES) ((MINUTES) <= 59U) +#define IS_RTC_SECONDS(SECONDS) ((SECONDS) <= 59U) +#endif /* USE_HALV2_DRIVER */ + /* Exported macro ------------------------------------------------------------*/ /* Exported functions ------------------------------------------------------- */ +#if !defined(USE_HALV2_DRIVER) RTC_HandleTypeDef *RTC_GetHandle(void); +#endif void RTC_SetClockSource(sourceClock_t source); void RTC_getPrediv(uint32_t *asynch, uint32_t *synch); void RTC_setPrediv(uint32_t asynch, uint32_t synch); @@ -218,7 +254,7 @@ void RTC_StoreDate(void); } #endif -#endif /* HAL_RTC_MODULE_ENABLED && !HAL_RTC_MODULE_ONLY */ +#endif /* !HAL_RTC_MODULE_ONLY && (HAL_RTC_MODULE_ENABLED || (USE_HAL_RTC_MODULE...) */ #endif /* __RTC_H */ From 39a933a7bf8734ec72c9730260b84da485babae7 Mon Sep 17 00:00:00 2001 From: Frederic Pillon Date: Fri, 3 Jul 2026 10:56:19 +0200 Subject: [PATCH 2/2] ci: enhance compile-examples - remove deprecated input - add token - add Nucleo C562RE Signed-off-by: Frederic Pillon --- .github/workflows/Continuous-Integration.yml | 4 +- extras/rtc_cores_config.json | 787 +------------------ 2 files changed, 3 insertions(+), 788 deletions(-) diff --git a/.github/workflows/Continuous-Integration.yml b/.github/workflows/Continuous-Integration.yml index 1e66fff..edc91a8 100644 --- a/.github/workflows/Continuous-Integration.yml +++ b/.github/workflows/Continuous-Integration.yml @@ -31,8 +31,8 @@ jobs: with: custom-config: "./extras/rtc_cores_config.json" additional-url: 'https://github.com/stm32duino/BoardManagerFiles/raw/dev/package_stmicroelectronics_index.json' - use-core-repo: 'true' - + env: + GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} # Use the output from the `Compile` step - name: Compilation Errors if: failure() diff --git a/extras/rtc_cores_config.json b/extras/rtc_cores_config.json index 3190b19..52affb2 100644 --- a/extras/rtc_cores_config.json +++ b/extras/rtc_cores_config.json @@ -22,797 +22,12 @@ } ], "sketches": [ - { - "pattern": "^.*$", - "applicable": false, - "boards": [ - "AFROFLIGHT_F103CB_12M", - "BLACKPILL_F103CB", - "BLACKPILL_F401CC", - "BLACK_F407VG", - "BLACK_F407ZE", - "BLACK_F407ZG", - "BLUEBUTTON_F103R8T", - "BLUEBUTTON_F103RCT", - "BLUEPILL_F103C6", - "BLUEPILL_F103CB", - "DEMO_F030F4_16M", - "DEMO_F030F4_HSI", - "GENERIC_C011D6YX", - "GENERIC_C011F4PX", - "GENERIC_C011F4UX", - "GENERIC_C011F6PX", - "GENERIC_C011F6UX", - "GENERIC_C031C4TX", - "GENERIC_C031C4UX", - "GENERIC_C031C6TX", - "GENERIC_C031F4PX", - "GENERIC_F031C4TX", - "GENERIC_F031E6YX", - "GENERIC_F031F4PX", - "GENERIC_F031G4UX", - "GENERIC_F031K4UX", - "GENERIC_F042C4TX", - "GENERIC_F042C4UX", - "GENERIC_F042C6TX", - "GENERIC_F042F4PX", - "GENERIC_F042G4UX", - "GENERIC_F042K4TX", - "GENERIC_F051C4TX", - "GENERIC_F051K6UX", - "GENERIC_F058R8HX", - "GENERIC_F071C8TX", - "GENERIC_F071C8UX", - "GENERIC_F071CBTX", - "GENERIC_F071CBUX", - "GENERIC_F071V8HX", - "GENERIC_F071V8TX", - "GENERIC_F071VBHX", - "GENERIC_F072C8TX", - "GENERIC_F072C8UX", - "GENERIC_F072CBTX", - "GENERIC_F072CBUX", - "GENERIC_F072R8TX", - "GENERIC_F072RBHX", - "GENERIC_F072RBTX", - "GENERIC_F072V8HX", - "GENERIC_F072V8TX", - "GENERIC_F072VBHX", - "GENERIC_F078CBTX", - "GENERIC_F078CBUX", - "GENERIC_F078RBHX", - "GENERIC_F078VBHX", - "GENERIC_F091CBTX", - "GENERIC_F091CBUX", - "GENERIC_F091CCTX", - "GENERIC_F091RBTX", - "GENERIC_F091RCHX", - "GENERIC_F091RCTX", - "GENERIC_F091VBTX", - "GENERIC_F091VCTX", - "GENERIC_F098CCTX", - "GENERIC_F098RCHX", - "GENERIC_F098RCTX", - "GENERIC_F098VCHX", - "GENERIC_F100C4TX", - "GENERIC_F100C8TX", - "GENERIC_F100R4HX", - "GENERIC_F100R8TX", - "GENERIC_F100V8TX", - "GENERIC_F100ZCTX", - "GENERIC_F100ZDTX", - "GENERIC_F101C4TX", - "GENERIC_F101R4TX", - "GENERIC_F101T4UX", - "GENERIC_F101V8TX", - "GENERIC_F101ZCTX", - "GENERIC_F101ZDTX", - "GENERIC_F103C4TX", - "GENERIC_F103C6TX", - "GENERIC_F103C8TX", - "GENERIC_F103CBTX", - "GENERIC_F103R4HX", - "GENERIC_F103R4TX", - "GENERIC_F103R8HX", - "GENERIC_F103R8TX", - "GENERIC_F103RCTX", - "GENERIC_F103RCYX", - "GENERIC_F103RDTX", - "GENERIC_F103RDYX", - "GENERIC_F103RFTX", - "GENERIC_F103T4UX", - "GENERIC_F103T8UX", - "GENERIC_F103V8HX", - "GENERIC_F103V8TX", - "GENERIC_F103VBHX", - "GENERIC_F103VBTX", - "GENERIC_F103VCHX", - "GENERIC_F103VCTX", - "GENERIC_F103VDHX", - "GENERIC_F103VDTX", - "GENERIC_F103VEHX", - "GENERIC_F103VFTX", - "GENERIC_F103ZCHX", - "GENERIC_F103ZCTX", - "GENERIC_F103ZDHX", - "GENERIC_F103ZDTX", - "GENERIC_F103ZEHX", - "GENERIC_F103ZFHX", - "GENERIC_F103ZFTX", - "GENERIC_F103ZGHX", - "GENERIC_F205RBTX", - "GENERIC_F205RCTX", - "GENERIC_F205RETX", - "GENERIC_F205REYX", - "GENERIC_F205RFTX", - "GENERIC_F205RGEX", - "GENERIC_F205RGTX", - "GENERIC_F205RGYX", - "GENERIC_F205VBTX", - "GENERIC_F205VCTX", - "GENERIC_F205VETX", - "GENERIC_F205VFTX", - "GENERIC_F205VGTX", - "GENERIC_F205ZCTX", - "GENERIC_F205ZETX", - "GENERIC_F205ZFTX", - "GENERIC_F205ZGTX", - "GENERIC_F207ICHX", - "GENERIC_F207ICTX", - "GENERIC_F207IEHX", - "GENERIC_F207IETX", - "GENERIC_F207IFHX", - "GENERIC_F207IFTX", - "GENERIC_F207IGHX", - "GENERIC_F207IGTX", - "GENERIC_F207VCTX", - "GENERIC_F207VETX", - "GENERIC_F207VFTX", - "GENERIC_F207VGTX", - "GENERIC_F207ZCTX", - "GENERIC_F207ZETX", - "GENERIC_F207ZFTX", - "GENERIC_F207ZGTX", - "GENERIC_F215RETX", - "GENERIC_F215VETX", - "GENERIC_F215ZETX", - "GENERIC_F217IEHX", - "GENERIC_F217IETX", - "GENERIC_F217IGHX", - "GENERIC_F217VETX", - "GENERIC_F217ZETX", - "GENERIC_F301C6TX", - "GENERIC_F301C8TX", - "GENERIC_F301K6TX", - "GENERIC_F301R6TX", - "GENERIC_F302R6TX", - "GENERIC_F303C6TX", - "GENERIC_F303C8TX", - "GENERIC_F303CBTX", - "GENERIC_F303K6TX", - "GENERIC_F303K8TX", - "GENERIC_F303R6TX", - "GENERIC_F303R8TX", - "GENERIC_F303RBTX", - "GENERIC_F303RDTX", - "GENERIC_F303VBTX", - "GENERIC_F318C8TX", - "GENERIC_F334C4TX", - "GENERIC_F334C6TX", - "GENERIC_F334K4TX", - "GENERIC_F334K6TX", - "GENERIC_F334R6TX", - "GENERIC_F378RCTX", - "GENERIC_F378VCHX", - "GENERIC_F401CBUX", - "GENERIC_F401CBYX", - "GENERIC_F401CCUX", - "GENERIC_F401CCYX", - "GENERIC_F401CDUX", - "GENERIC_F401CDYX", - "GENERIC_F401CEUX", - "GENERIC_F401CEYX", - "GENERIC_F401RBTX", - "GENERIC_F401RCTX", - "GENERIC_F401RDTX", - "GENERIC_F401VBTX", - "GENERIC_F401VCTX", - "GENERIC_F401VDTX", - "GENERIC_F405RGTX", - "GENERIC_F407VETX", - "GENERIC_F407VGTX", - "GENERIC_F407ZETX", - "GENERIC_F407ZGTX", - "GENERIC_F410C8TX", - "GENERIC_F410C8UX", - "GENERIC_F410R8IX", - "GENERIC_F410R8TX", - "GENERIC_F410RBIX", - "GENERIC_F410T8YX", - "GENERIC_F411CCUX", - "GENERIC_F411CCYX", - "GENERIC_F411CEUX", - "GENERIC_F411RCTX", - "GENERIC_F412CEUX", - "GENERIC_F412RETX", - "GENERIC_F412REYX", - "GENERIC_F412REYXP", - "GENERIC_F412RGTX", - "GENERIC_F412RGYX", - "GENERIC_F412ZEJX", - "GENERIC_F412ZETX", - "GENERIC_F412ZGJX", - "GENERIC_F413CGUX", - "GENERIC_F413CHUX", - "GENERIC_F413RGTX", - "GENERIC_F413RHTX", - "GENERIC_F413ZGJX", - "GENERIC_F413ZGTX", - "GENERIC_F413ZHJX", - "GENERIC_F413ZHTX", - "GENERIC_F417VETX", - "GENERIC_F417ZETX", - "GENERIC_F423ZHJX", - "GENERIC_F427ZGTX", - "GENERIC_F427ZITX", - "GENERIC_F429ZETX", - "GENERIC_F429ZGTX", - "GENERIC_F429ZGYX", - "GENERIC_F429ZITX", - "GENERIC_F429ZIYX", - "GENERIC_F437ZGTX", - "GENERIC_F437ZITX", - "GENERIC_F439ZGTX", - "GENERIC_F439ZGYX", - "GENERIC_F439ZITX", - "GENERIC_F446RCTX", - "GENERIC_F446VCTX", - "GENERIC_F446ZCHX", - "GENERIC_F446ZCJX", - "GENERIC_F446ZCTX", - "GENERIC_F446ZEHX", - "GENERIC_F446ZEJX", - "GENERIC_F722RCTX", - "GENERIC_F722RETX", - "GENERIC_F722ZCTX", - "GENERIC_F722ZETX", - "GENERIC_F730R8TX", - "GENERIC_F745ZETX", - "GENERIC_F745ZGTX", - "GENERIC_F746BETX", - "GENERIC_F746BGTX", - "GENERIC_F746NEHX", - "GENERIC_F746NGHX", - "GENERIC_F746ZETX", - "GENERIC_F746ZEYX", - "GENERIC_F746ZGTX", - "GENERIC_F746ZGYX", - "GENERIC_F750N8HX", - "GENERIC_F750Z8TX", - "GENERIC_F756BGTX", - "GENERIC_F756ZGTX", - "GENERIC_F765IGKX", - "GENERIC_F765IGTX", - "GENERIC_F765IIKX", - "GENERIC_F765IITX", - "GENERIC_F765VGHX", - "GENERIC_F765VGTX", - "GENERIC_F765VIHX", - "GENERIC_F765VITX", - "GENERIC_F765ZGTX", - "GENERIC_F765ZITX", - "GENERIC_F767IGKX", - "GENERIC_F767IGTX", - "GENERIC_F767IIKX", - "GENERIC_F767IITX", - "GENERIC_F767VGHX", - "GENERIC_F767VGTX", - "GENERIC_F767VIHX", - "GENERIC_F767VITX", - "GENERIC_F767ZGTX", - "GENERIC_F767ZITX", - "GENERIC_F777IIKX", - "GENERIC_F777VIHX", - "GENERIC_G030C6TX", - "GENERIC_G030K6TX", - "GENERIC_G031C4TX", - "GENERIC_G031C4UX", - "GENERIC_G031C6TX", - "GENERIC_G031C6UX", - "GENERIC_G031C8TX", - "GENERIC_G031C8UX", - "GENERIC_G031F4PX", - "GENERIC_G031F6PX", - "GENERIC_G031F8PX", - "GENERIC_G031G4UX", - "GENERIC_G031G6UX", - "GENERIC_G031G8UX", - "GENERIC_G031J4MX", - "GENERIC_G031J6MX", - "GENERIC_G031K4TX", - "GENERIC_G031K4UX", - "GENERIC_G031K6TX", - "GENERIC_G031K6UX", - "GENERIC_G031K8TX", - "GENERIC_G031K8UX", - "GENERIC_G031Y8YX", - "GENERIC_G041C6TX", - "GENERIC_G041C6UX", - "GENERIC_G041C8TX", - "GENERIC_G041F6PX", - "GENERIC_G041F8PX", - "GENERIC_G041G6UX", - "GENERIC_G041K6TX", - "GENERIC_G041K6UX", - "GENERIC_G041K8TX", - "GENERIC_G050C6TX", - "GENERIC_G050K6TX", - "GENERIC_G051C6TX", - "GENERIC_G051C6UX", - "GENERIC_G051C8TX", - "GENERIC_G051C8UX", - "GENERIC_G051F6PX", - "GENERIC_G051F8PX", - "GENERIC_G051F8YX", - "GENERIC_G051G6UX", - "GENERIC_G051G8UX", - "GENERIC_G051K6TX", - "GENERIC_G051K6UX", - "GENERIC_G051K8TX", - "GENERIC_G051K8UX", - "GENERIC_G061C6TX", - "GENERIC_G061C6UX", - "GENERIC_G061C8TX", - "GENERIC_G061F6PX", - "GENERIC_G061F8PX", - "GENERIC_G061G6UX", - "GENERIC_G061K6TX", - "GENERIC_G061K6UX", - "GENERIC_G061K8TX", - "GENERIC_G071C6TX", - "GENERIC_G071C6UX", - "GENERIC_G071C8TX", - "GENERIC_G071C8UX", - "GENERIC_G071CBTX", - "GENERIC_G071CBUX", - "GENERIC_G071EBYX", - "GENERIC_G071G6UX", - "GENERIC_G071G8UX", - "GENERIC_G071G8UXN", - "GENERIC_G071GBUX", - "GENERIC_G071GBUXN", - "GENERIC_G071K6TX", - "GENERIC_G071K6UX", - "GENERIC_G071K8TX", - "GENERIC_G071K8UX", - "GENERIC_G071KBTX", - "GENERIC_G071KBUX", - "GENERIC_G071R6TX", - "GENERIC_G071R8TX", - "GENERIC_G071RBIX", - "GENERIC_G071RBTX", - "GENERIC_G081CBTX", - "GENERIC_G081KBTX", - "GENERIC_G081RBIX", - "GENERIC_G0B1CBTX", - "GENERIC_G0B1CBUX", - "GENERIC_G0B1CCTX", - "GENERIC_G0B1CCUX", - "GENERIC_G0B1CETX", - "GENERIC_G0B1CEUX", - "GENERIC_G0B1KBTX", - "GENERIC_G0B1KBUX", - "GENERIC_G0B1KCTX", - "GENERIC_G0B1KCUX", - "GENERIC_G0B1KETX", - "GENERIC_G0B1KEUX", - "GENERIC_G0B1MBTX", - "GENERIC_G0B1MCTX", - "GENERIC_G0B1METX", - "GENERIC_G0B1NEYX", - "GENERIC_G0B1RBTX", - "GENERIC_G0B1RCTX", - "GENERIC_G0B1RETX", - "GENERIC_G0B1VBIX", - "GENERIC_G0B1VBTX", - "GENERIC_G0B1VCIX", - "GENERIC_G0B1VCTX", - "GENERIC_G0B1VEIX", - "GENERIC_G0B1VETX", - "GENERIC_G0C1CCTX", - "GENERIC_G0C1CCUX", - "GENERIC_G0C1CETX", - "GENERIC_G0C1KCTX", - "GENERIC_G0C1KCUX", - "GENERIC_G0C1KETX", - "GENERIC_G0C1MCTX", - "GENERIC_G0C1RCTX", - "GENERIC_G0C1VCIX", - "GENERIC_G0C1VCTX", - "GENERIC_G0C1VEIX", - "GENERIC_G431C6TX", - "GENERIC_G431C6UX", - "GENERIC_G431C8TX", - "GENERIC_G431C8UX", - "GENERIC_G431CBTX", - "GENERIC_G431CBUX", - "GENERIC_G431K6TX", - "GENERIC_G431K6UX", - "GENERIC_G431K8TX", - "GENERIC_G431K8UX", - "GENERIC_G431KBTX", - "GENERIC_G431KBUX", - "GENERIC_G431M6TX", - "GENERIC_G431M8TX", - "GENERIC_G431MBTX", - "GENERIC_G431R6IX", - "GENERIC_G431R6TX", - "GENERIC_G431R8IX", - "GENERIC_G431R8TX", - "GENERIC_G431RBIX", - "GENERIC_G431RBTX", - "GENERIC_G431V6TX", - "GENERIC_G431V8TX", - "GENERIC_G431VBTX", - "GENERIC_G441KBTX", - "GENERIC_G441RBIX", - "GENERIC_G471CCTX", - "GENERIC_G471MCTX", - "GENERIC_G471QCTX", - "GENERIC_G471RCTX", - "GENERIC_G471VCHX", - "GENERIC_G471VCIX", - "GENERIC_G471VCTX", - "GENERIC_G471VEHX", - "GENERIC_G471VEIX", - "GENERIC_G473CBTX", - "GENERIC_G473CCTX", - "GENERIC_G473CETX", - "GENERIC_G473MBTX", - "GENERIC_G473MCTX", - "GENERIC_G473METX", - "GENERIC_G473PBIX", - "GENERIC_G473PCIX", - "GENERIC_G473PEIX", - "GENERIC_G473QBTX", - "GENERIC_G473QCTX", - "GENERIC_G473QETX", - "GENERIC_G473RBTX", - "GENERIC_G473RCTX", - "GENERIC_G473RETX", - "GENERIC_G473VBHX", - "GENERIC_G473VBTX", - "GENERIC_G473VCHX", - "GENERIC_G473VCTX", - "GENERIC_G473VEHX", - "GENERIC_G473VETX", - "GENERIC_G474CBTX", - "GENERIC_G474CCTX", - "GENERIC_G474CETX", - "GENERIC_G474MBTX", - "GENERIC_G474MCTX", - "GENERIC_G474METX", - "GENERIC_G474PBIX", - "GENERIC_G474PCIX", - "GENERIC_G474PEIX", - "GENERIC_G474QBTX", - "GENERIC_G474QCTX", - "GENERIC_G474QETX", - "GENERIC_G474RBTX", - "GENERIC_G474RCTX", - "GENERIC_G474RETX", - "GENERIC_G474VBHX", - "GENERIC_G474VBTX", - "GENERIC_G474VCHX", - "GENERIC_G474VCTX", - "GENERIC_G474VEHX", - "GENERIC_G474VETX", - "GENERIC_G483CETX", - "GENERIC_G483METX", - "GENERIC_G483PEIX", - "GENERIC_G483QETX", - "GENERIC_G483RETX", - "GENERIC_G483VEHX", - "GENERIC_G483VETX", - "GENERIC_G484VEHX", - "GENERIC_G491CCTX", - "GENERIC_G491CETX", - "GENERIC_G491KCUX", - "GENERIC_G491KEUX", - "GENERIC_G491MCSX", - "GENERIC_G491MCTX", - "GENERIC_G491MESX", - "GENERIC_G491METX", - "GENERIC_G491RCIX", - "GENERIC_G491RCTX", - "GENERIC_G491REIX", - "GENERIC_G491RETX", - "GENERIC_G491REYX", - "GENERIC_G491VCTX", - "GENERIC_G491VETX", - "GENERIC_G4A1MESX", - "GENERIC_G4A1REIX", - "GENERIC_G4A1RETX", - "GENERIC_H563ZGTX", - "GENERIC_H723ZETX", - "GENERIC_H723ZGTX", - "GENERIC_H730ZBTX", - "GENERIC_H742IGKX", - "GENERIC_H742IGTX", - "GENERIC_H742IIKX", - "GENERIC_H742IITX", - "GENERIC_H742VGHX", - "GENERIC_H742VGTX", - "GENERIC_H742VIHX", - "GENERIC_H742VITX", - "GENERIC_H742ZGTX", - "GENERIC_H742ZITX", - "GENERIC_H743IGKX", - "GENERIC_H743IGTX", - "GENERIC_H743IIKX", - "GENERIC_H743IITX", - "GENERIC_H743VGHX", - "GENERIC_H743VGTX", - "GENERIC_H743VIHX", - "GENERIC_H743VITX", - "GENERIC_H743ZGTX", - "GENERIC_H743ZITX", - "GENERIC_H747AGIX", - "GENERIC_H747AIIX", - "GENERIC_H747IGTX", - "GENERIC_H747IITX", - "GENERIC_H750IBKX", - "GENERIC_H750IBTX", - "GENERIC_H750VBTX", - "GENERIC_H750ZBTX", - "GENERIC_H753IIKX", - "GENERIC_H753VIHX", - "GENERIC_H753ZITX", - "GENERIC_H757AIIX", - "GENERIC_L010F4PX", - "GENERIC_L010K4TX", - "GENERIC_L011D3PX", - "GENERIC_L011D4PX", - "GENERIC_L011E3YX", - "GENERIC_L011F3PX", - "GENERIC_L011F3UX", - "GENERIC_L011F4PX", - "GENERIC_L011F4UX", - "GENERIC_L011G3UX", - "GENERIC_L011G4UX", - "GENERIC_L011K3TX", - "GENERIC_L011K3UX", - "GENERIC_L011K4TX", - "GENERIC_L011K4UX", - "GENERIC_L031C4TX", - "GENERIC_L031C4UX", - "GENERIC_L031C6TX", - "GENERIC_L031C6UX", - "GENERIC_L031E4YX", - "GENERIC_L031E6YX", - "GENERIC_L031F4PX", - "GENERIC_L031F6PX", - "GENERIC_L031G4UX", - "GENERIC_L031G6UX", - "GENERIC_L031K4TX", - "GENERIC_L031K6TX", - "GENERIC_L041C4TX", - "GENERIC_L041C6TX", - "GENERIC_L051C6TX", - "GENERIC_L051C6UX", - "GENERIC_L051C8TX", - "GENERIC_L052C6TX", - "GENERIC_L052C6UX", - "GENERIC_L052C8TX", - "GENERIC_L052C8UX", - "GENERIC_L052K6TX", - "GENERIC_L052K8TX", - "GENERIC_L052R6HX", - "GENERIC_L052R6TX", - "GENERIC_L052R8HX", - "GENERIC_L052R8TX", - "GENERIC_L052T6YX", - "GENERIC_L052T8YX", - "GENERIC_L053C6TX", - "GENERIC_L053C6UX", - "GENERIC_L053C8TX", - "GENERIC_L053C8UX", - "GENERIC_L053R6HX", - "GENERIC_L053R6TX", - "GENERIC_L053R8TX", - "GENERIC_L062C8UX", - "GENERIC_L063C8TX", - "GENERIC_L072CBTX", - "GENERIC_L072CBUX", - "GENERIC_L072CBYX", - "GENERIC_L072CZEX", - "GENERIC_L072CZTX", - "GENERIC_L072CZUX", - "GENERIC_L072CZYX", - "GENERIC_L072KBTX", - "GENERIC_L072KBUX", - "GENERIC_L072KZTX", - "GENERIC_L072KZUX", - "GENERIC_L072RBHX", - "GENERIC_L072RBIX", - "GENERIC_L072RBTX", - "GENERIC_L072RZHX", - "GENERIC_L072RZIX", - "GENERIC_L072RZTX", - "GENERIC_L072V8IX", - "GENERIC_L072V8TX", - "GENERIC_L072VBIX", - "GENERIC_L072VBTX", - "GENERIC_L072VZIX", - "GENERIC_L072VZTX", - "GENERIC_L073CBTX", - "GENERIC_L073CBUX", - "GENERIC_L073CZTX", - "GENERIC_L073CZUX", - "GENERIC_L073CZYX", - "GENERIC_L073RBHX", - "GENERIC_L073RBTX", - "GENERIC_L073RZHX", - "GENERIC_L073RZIX", - "GENERIC_L073RZTX", - "GENERIC_L073V8IX", - "GENERIC_L073V8TX", - "GENERIC_L073VBIX", - "GENERIC_L073VBTX", - "GENERIC_L073VZIX", - "GENERIC_L073VZTX", - "GENERIC_L082CZUX", - "GENERIC_L082KBTX", - "GENERIC_L082KBUX", - "GENERIC_L083CBTX", - "GENERIC_L083CZTX", - "GENERIC_L083RBHX", - "GENERIC_L083RBTX", - "GENERIC_L083V8IX", - "GENERIC_L083VBIX", - "GENERIC_L083VBTX", - "GENERIC_L083VZIX", - "GENERIC_L083VZTX", - "GENERIC_L100C6UX", - "GENERIC_L100C6UXA", - "GENERIC_L151C6TX", - "GENERIC_L151C6TXA", - "GENERIC_L151C6UX", - "GENERIC_L151C6UXA", - "GENERIC_L151C8TX", - "GENERIC_L151C8TXA", - "GENERIC_L151C8UX", - "GENERIC_L151C8UXA", - "GENERIC_L151CBTX", - "GENERIC_L151CBTXA", - "GENERIC_L151CBUX", - "GENERIC_L151CBUXA", - "GENERIC_L151RETX", - "GENERIC_L151ZDTX", - "GENERIC_L152C6TX", - "GENERIC_L152C6TXA", - "GENERIC_L152C6UX", - "GENERIC_L152C6UXA", - "GENERIC_L152C8TX", - "GENERIC_L152C8TXA", - "GENERIC_L152C8UX", - "GENERIC_L152C8UXA", - "GENERIC_L152CBTX", - "GENERIC_L152CBTXA", - "GENERIC_L152CBUX", - "GENERIC_L152RETX", - "GENERIC_L152ZDTX", - "GENERIC_L412K8TX", - "GENERIC_L412K8UX", - "GENERIC_L412KBTX", - "GENERIC_L412KBUX", - "GENERIC_L422KBTX", - "GENERIC_L431RBIX", - "GENERIC_L431RBTX", - "GENERIC_L431RBYX", - "GENERIC_L431RCIX", - "GENERIC_L431RCTX", - "GENERIC_L432KBUX", - "GENERIC_L432KCUX", - "GENERIC_L433CBTX", - "GENERIC_L433CBUX", - "GENERIC_L433CCTX", - "GENERIC_L433CCUX", - "GENERIC_L433RBIX", - "GENERIC_L433RBTX", - "GENERIC_L433RBYX", - "GENERIC_L433RCIX", - "GENERIC_L433RCTX", - "GENERIC_L433RCYX", - "GENERIC_L443CCTX", - "GENERIC_L443RCIX", - "GENERIC_L443RCTX", - "GENERIC_L452RCIX", - "GENERIC_L452RCTX", - "GENERIC_L452RCYX", - "GENERIC_L452REIX", - "GENERIC_L452RETX", - "GENERIC_L452REYX", - "GENERIC_L452REYXP", - "GENERIC_L462REIX", - "GENERIC_L462RETX", - "GENERIC_L475RCTX", - "GENERIC_L475RETX", - "GENERIC_L475RGTX", - "GENERIC_L475VCTX", - "GENERIC_L475VETX", - "GENERIC_L475VGTX", - "GENERIC_L476RCTX", - "GENERIC_L476RETX", - "GENERIC_L476RGTX", - "GENERIC_L476VCTX", - "GENERIC_L476VETX", - "GENERIC_L476VGTX", - "GENERIC_L496ZETX", - "GENERIC_L496ZGTX", - "GENERIC_L496ZGTXP", - "GENERIC_L4R5VGTX", - "GENERIC_L4R5VITX", - "GENERIC_L4R5ZGTX", - "GENERIC_L4R5ZGYX", - "GENERIC_L4R5ZITX", - "GENERIC_L4R5ZIYX", - "GENERIC_L4R7VITX", - "GENERIC_L4R7ZITX", - "GENERIC_L4R9ZGJX", - "GENERIC_L4R9ZGYX", - "GENERIC_L4R9ZIJX", - "GENERIC_L4R9ZIYX", - "GENERIC_L4S5VITX", - "GENERIC_L4S5ZITX", - "GENERIC_L4S5ZIYX", - "GENERIC_L552ZCTXQ", - "GENERIC_L552ZETXQ", - "GENERIC_MP153AACX", - "GENERIC_MP153CACX", - "GENERIC_MP153DACX", - "GENERIC_MP153FACX", - "GENERIC_MP157AACX", - "GENERIC_MP157CACX", - "GENERIC_MP157DACX", - "GENERIC_U575AGIXQ", - "GENERIC_U575AIIXQ", - "GENERIC_U575ZGTXQ", - "GENERIC_U575ZITXQ", - "GENERIC_WB35CCUXA", - "GENERIC_WB35CEUXA", - "GENERIC_WB55CCUX", - "GENERIC_WB55CEUX", - "GENERIC_WB55RCVX", - "GENERIC_WB55REVX", - "GENERIC_WL54CCUX", - "GENERIC_WL54JCIX", - "GENERIC_WL55CCUX", - "GENERIC_WL55JCIX", - "GENERIC_WLE4C8UX", - "GENERIC_WLE4CBUX", - "GENERIC_WLE4CCUX", - "GENERIC_WLE4J8IX", - "GENERIC_WLE4JBIX", - "GENERIC_WLE4JCIX", - "GENERIC_WLE5C8UX", - "GENERIC_WLE5CBUX", - "GENERIC_WLE5J8IX", - "GENERIC_WLE5JBIX", - "NUCLEO_H743ZI", - "NUCLEO_L496ZG", - "NUCLEO_L4R5ZI", - "PYBSTICK26_DUINO", - "PYBSTICK26_LITE", - "PYBSTICK26_STD", - "RAK811_TRACKERA" - ] - }, { "pattern": "^[^F][^1].*", "applicable": true, "boards": [ "NUCLEO_C031C6", + "NUCLEO_C562RE", "NUCLEO_F091RC", "NUCLEO_F103RB", "NUCLEO_F207ZG",