Commit 842a6ba0 authored by Francois Ramu's avatar Francois Ramu Committed by Fabio Baltieri
Browse files

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: default avatarFrancois Ramu <francois.ramu@st.com>
parent 66a4fab5
Loading
Loading
Loading
Loading
+26 −16
Original line number Diff line number Diff line
@@ -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;
}

+2 −0
Original line number Diff line number Diff line
@@ -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)					\