From a4f5f87e298d65292ec00e7d09d71abf95bc84e9 Mon Sep 17 00:00:00 2001 From: Johan Lafon Date: Mon, 11 Sep 2023 17:23:56 +0200 Subject: [PATCH] drivers: rtc: stm32: avoid infinite blocking loop Use the less CPU intensive and timeout capable WAIT_FOR zephyr provided macro Signed-off-by: Johan Lafon --- drivers/rtc/rtc_ll_stm32.c | 35 +++++++++++++++++++++++++++++------ 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/drivers/rtc/rtc_ll_stm32.c b/drivers/rtc/rtc_ll_stm32.c index feb7ff387a2..12dc6784e39 100644 --- a/drivers/rtc/rtc_ll_stm32.c +++ b/drivers/rtc/rtc_ll_stm32.c @@ -57,6 +57,9 @@ LOG_MODULE_REGISTER(rtc_stm32, CONFIG_RTC_LOG_LEVEL); #define MAX_PPB NB_PULSES_TO_PPB(MAX_CALP) #define MIN_PPB -NB_PULSES_TO_PPB(MAX_CALM) +/* Timeout in microseconds used to wait for flags */ +#define RTC_TIMEOUT 1000000 + struct rtc_stm32_config { LL_RTC_InitTypeDef ll_rtc_config; const struct stm32_pclken *pclken; @@ -66,6 +69,24 @@ struct rtc_stm32_data { /* Currently empty */ }; +static int rtc_stm32_enter_initialization_mode(void) +{ + LL_RTC_EnableInitMode(RTC); + + bool success = WAIT_FOR(LL_RTC_IsActiveFlag_INIT(RTC), RTC_TIMEOUT, k_msleep(1)); + + if (!success) { + return -EIO; + } + + return 0; +} + +static inline void rtc_stm32_leave_initialization_mode(void) +{ + LL_RTC_DisableInitMode(RTC); +} + static int rtc_stm32_configure(const struct device *dev) { const struct rtc_stm32_config *cfg = dev->config; @@ -158,6 +179,8 @@ static int rtc_stm32_set_time(const struct device *dev, const struct rtc_time *t { uint32_t real_year = timeptr->tm_year + TM_YEAR_REF; + int err = 0; + if (real_year < RTC_YEAR_REF) { /* RTC does not support years before 2000 */ return -EINVAL; @@ -171,10 +194,10 @@ static int rtc_stm32_set_time(const struct device *dev, const struct rtc_time *t LOG_INF("Setting clock"); LL_RTC_DisableWriteProtection(RTC); - LL_RTC_EnableInitMode(RTC); - - while (!LL_RTC_IsActiveFlag_INIT(RTC)) { - }; + err = rtc_stm32_enter_initialization_mode(); + if (err) { + return err; + } LL_RTC_DATE_SetYear(RTC, __LL_RTC_CONVERT_BIN2BCD(real_year - RTC_YEAR_REF)); LL_RTC_DATE_SetMonth(RTC, __LL_RTC_CONVERT_BIN2BCD(timeptr->tm_mon + 1)); @@ -193,11 +216,11 @@ static int rtc_stm32_set_time(const struct device *dev, const struct rtc_time *t LL_RTC_TIME_SetMinute(RTC, __LL_RTC_CONVERT_BIN2BCD(timeptr->tm_min)); LL_RTC_TIME_SetSecond(RTC, __LL_RTC_CONVERT_BIN2BCD(timeptr->tm_sec)); - LL_RTC_DisableInitMode(RTC); + rtc_stm32_leave_initialization_mode(); LL_RTC_EnableWriteProtection(RTC); - return 0; + return err; } static int rtc_stm32_get_time(const struct device *dev, struct rtc_time *timeptr)