From 47991686e640efa0accb4179af914beb8071816f Mon Sep 17 00:00:00 2001 From: Hao Luo Date: Thu, 10 Jul 2025 17:44:55 +0800 Subject: [PATCH] drivers: watchdog: bugfix for ambiq wdt clk select This commit fixed the watchdog clock select error in ambiq driver. Signed-off-by: Hao Luo --- drivers/watchdog/wdt_ambiq.c | 34 +++++++++++++++++++++++++++------- 1 file changed, 27 insertions(+), 7 deletions(-) diff --git a/drivers/watchdog/wdt_ambiq.c b/drivers/watchdog/wdt_ambiq.c index e2078730f98b2..a966198cd5a2a 100644 --- a/drivers/watchdog/wdt_ambiq.c +++ b/drivers/watchdog/wdt_ambiq.c @@ -20,7 +20,7 @@ typedef void (*ambiq_wdt_cfg_func_t)(void); struct wdt_ambiq_config { uint32_t base; uint32_t irq_num; - uint8_t clk_freq; + uint32_t clk_freq; ambiq_wdt_cfg_func_t cfg_func; }; @@ -30,6 +30,13 @@ struct wdt_ambiq_data { bool reset; }; +uint32_t wdt_ambiq_clk_select[] = +#if defined(CONFIG_SOC_SERIES_APOLLO3X) || defined(CONFIG_SOC_SERIES_APOLLO4X) + {128, 16, 1}; +#else + {128, 16, 1, 32768, 16384}; +#endif + static void wdt_ambiq_isr(void *arg) { const struct device *dev = (const struct device *)arg; @@ -39,7 +46,7 @@ static void wdt_ambiq_isr(void *arg) am_hal_wdt_int_clear(); #else uint32_t status; - am_hal_wdt_interrupt_status_get(AM_HAL_WDT_MCU, &status, false); + am_hal_wdt_interrupt_status_get(AM_HAL_WDT_MCU, &status, true); am_hal_wdt_interrupt_clear(AM_HAL_WDT_MCU, status); #endif @@ -79,7 +86,15 @@ static int wdt_ambiq_setup(const struct device *dev, uint8_t options) cfg.eClockSource = AM_HAL_WDT_16HZ; } else if (dev_cfg->clk_freq == 1) { cfg.eClockSource = AM_HAL_WDT_1HZ; +#if defined(CONFIG_SOC_SERIES_APOLLO5X) + } else if (dev_cfg->clk_freq == 32768) { + cfg.eClockSource = AM_HAL_WDT_XTAL_HS; + } else if (dev_cfg->clk_freq == 16384) { + cfg.eClockSource = AM_HAL_WDT_XTAL_HS_DIV2; } +#else + } +#endif cfg.bInterruptEnable = true; cfg.ui32InterruptValue = data->timeout; @@ -116,7 +131,7 @@ static int wdt_ambiq_install_timeout(const struct device *dev, const struct wdt_ return -EINVAL; } - data->timeout = cfg->window.max / 1000 * dev_cfg->clk_freq; + data->timeout = cfg->window.max * dev_cfg->clk_freq / 1000; data->callback = cfg->callback; switch (cfg->flags) { @@ -145,7 +160,6 @@ static int wdt_ambiq_feed(const struct device *dev, int channel_id) #else am_hal_wdt_restart(AM_HAL_WDT_MCU); #endif - LOG_DBG("Fed the watchdog"); return 0; } @@ -153,9 +167,15 @@ static int wdt_ambiq_feed(const struct device *dev, int channel_id) static int wdt_ambiq_init(const struct device *dev) { const struct wdt_ambiq_config *dev_cfg = dev->config; - - if (dev_cfg->clk_freq != 128 && dev_cfg->clk_freq != 16 && dev_cfg->clk_freq != 1) { - return -ENOTSUP; + uint8_t clk_index = sizeof(wdt_ambiq_clk_select) / sizeof(uint32_t); + + for (uint8_t i = 0; i < clk_index; i++) { + if (dev_cfg->clk_freq == wdt_ambiq_clk_select[i]) { + break; + } + if (i == clk_index - 1) { + return -ENOTSUP; + } } NVIC_ClearPendingIRQ(dev_cfg->irq_num);