From 842a6ba02dfd95d0148491796b5b4b02785dc073 Mon Sep 17 00:00:00 2001 From: Francois Ramu Date: Tue, 24 Jan 2023 09:52:51 +0100 Subject: [PATCH] drivers: watchdog: stm32 iwdt enable and update during setup To follow the IWDG configuration sequence, the timeout install is just preparing the reload and prescaler parameters. Then during the iwdg setup the watchdog is enabled and configured at the same time. Signed-off-by: Francois Ramu --- drivers/watchdog/wdt_iwdg_stm32.c | 42 +++++++++++++++++++------------ drivers/watchdog/wdt_iwdg_stm32.h | 2 ++ 2 files changed, 28 insertions(+), 16 deletions(-) diff --git a/drivers/watchdog/wdt_iwdg_stm32.c b/drivers/watchdog/wdt_iwdg_stm32.c index 50b59476b7e..df3d42d83a7 100644 --- a/drivers/watchdog/wdt_iwdg_stm32.c +++ b/drivers/watchdog/wdt_iwdg_stm32.c @@ -84,7 +84,9 @@ static void iwdg_stm32_convert_timeout(uint32_t timeout, static int iwdg_stm32_setup(const struct device *dev, uint8_t options) { + struct iwdg_stm32_data *data = IWDG_STM32_DATA(dev); IWDG_TypeDef *iwdg = IWDG_STM32_STRUCT(dev); + uint32_t tickstart; /* Deactivate running when debugger is attached. */ if (options & WDT_OPT_PAUSE_HALTED_BY_DBG) { @@ -106,8 +108,24 @@ static int iwdg_stm32_setup(const struct device *dev, uint8_t options) return -ENOTSUP; } - /* Enable the IWDG now (timeout has been installed previoulsy) */ - LL_IWDG_Enable(iwdg); /* No need to Reload counter */ + /* Enable the IWDG now and write IWDG registers at the same time */ + LL_IWDG_Enable(iwdg); + LL_IWDG_EnableWriteAccess(iwdg); + /* Write the prescaler and reload counter to the IWDG registers*/ + LL_IWDG_SetPrescaler(iwdg, data->prescaler); + LL_IWDG_SetReloadCounter(iwdg, data->reload); + + tickstart = k_uptime_get_32(); + + /* Wait for the update operation completed */ + while (LL_IWDG_IsReady(iwdg) == 0) { + if ((k_uptime_get_32() - tickstart) > IWDG_SR_UPDATE_TIMEOUT) { + return -ENODEV; + } + } + + /* Reload counter just before leaving */ + LL_IWDG_ReloadCounter(iwdg); return 0; } @@ -123,16 +141,16 @@ static int iwdg_stm32_disable(const struct device *dev) static int iwdg_stm32_install_timeout(const struct device *dev, const struct wdt_timeout_cfg *config) { - IWDG_TypeDef *iwdg = IWDG_STM32_STRUCT(dev); + struct iwdg_stm32_data *data = IWDG_STM32_DATA(dev); uint32_t timeout = config->window.max * USEC_PER_MSEC; uint32_t prescaler = 0U; uint32_t reload = 0U; - uint32_t tickstart; if (config->callback != NULL) { return -ENOTSUP; } + /* Calculating parameters to be applied later, on setup */ iwdg_stm32_convert_timeout(timeout, &prescaler, &reload); if (!(IS_IWDG_TIMEOUT(timeout) && IS_IWDG_PRESCALER(prescaler) && @@ -141,19 +159,11 @@ static int iwdg_stm32_install_timeout(const struct device *dev, return -EINVAL; } - tickstart = k_uptime_get_32(); - - /* Do not enable the wdg during install but during wdt_setup() */ - LL_IWDG_EnableWriteAccess(iwdg); - LL_IWDG_SetPrescaler(iwdg, prescaler); - - /* Wait for the update operation completed */ - while (LL_IWDG_IsActiveFlag_PVU(iwdg) == 0) { - if ((k_uptime_get_32() - tickstart) > IWDG_SR_UPDATE_TIMEOUT) { - return -ENODEV; - } - } + /* Store the calculated values to write in the iwdg registers */ + data->prescaler = prescaler; + data->reload = reload; + /* Do not enable and update the iwdg here but during wdt_setup() */ return 0; } diff --git a/drivers/watchdog/wdt_iwdg_stm32.h b/drivers/watchdog/wdt_iwdg_stm32.h index 64e91cfa63c..d953f61b99d 100644 --- a/drivers/watchdog/wdt_iwdg_stm32.h +++ b/drivers/watchdog/wdt_iwdg_stm32.h @@ -24,6 +24,8 @@ struct iwdg_stm32_data { /* IWDG peripheral instance. */ IWDG_TypeDef *Instance; + uint32_t prescaler; + uint32_t reload; }; #define IWDG_STM32_DATA(dev) \