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 <francois.ramu@st.com>
This commit is contained in:
Francois Ramu 2023-01-24 09:52:51 +01:00 committed by Fabio Baltieri
parent 66a4fab571
commit 842a6ba02d
2 changed files with 28 additions and 16 deletions

View file

@ -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;
}

View file

@ -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) \