Commit 7f21dc2d authored by Michael Hope's avatar Michael Hope Committed by Benjamin Cabé
Browse files

drivers: watchdog: add a CH32V00x Independent Watchdog (IWDT) driver

The CH32V003 has a built-in watchdog that runs off the low speed
internal oscillator. Add a driver.

Signed-off-by: default avatarMichael Hope <michaelh@juju.nz>
parent e358713e
Loading
Loading
Loading
Loading
+1 −0
Changes for drivers/watchdog/CMakeLists.txt: 1 added line, 0 removed lines.
Original line number Diff line number Diff line
@@ -51,6 +51,7 @@ zephyr_library_sources_ifdef(CONFIG_WDT_AMBIQ wdt_ambiq.c)
zephyr_library_sources_ifdef(CONFIG_WDT_XMC4XXX wdt_xmc4xxx.c)
zephyr_library_sources_ifdef(CONFIG_WWDT_NUMAKER wdt_wwdt_numaker.c)
zephyr_library_sources_ifdef(CONFIG_WDT_ENE_KB1200 wdt_ene_kb1200.c)
zephyr_library_sources_ifdef(CONFIG_WDT_IWDG_WCH wdt_iwdg_wch.c)

zephyr_library_sources_ifdef(CONFIG_WDT_DW wdt_dw.c wdt_dw_common.c)
zephyr_library_sources_ifdef(CONFIG_WDT_INTEL_ADSP wdt_intel_adsp.c wdt_dw_common.c)
+2 −0
Changes for drivers/watchdog/Kconfig: 2 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -151,4 +151,6 @@ source "drivers/watchdog/Kconfig.rts5912"

source "drivers/watchdog/Kconfig.renesas_ra"

source "drivers/watchdog/Kconfig.wch"

endif # WATCHDOG
+10 −0
Changes for drivers/watchdog/Kconfig.wch: 10 added lines, 0 removed lines.
Original line number Diff line number Diff line
# Copyright (c) 2025 Michael Hope <michaelh@juju.nz>
# SPDX-License-Identifier: Apache-2.0

config WDT_IWDG_WCH
	bool "WCH Independent Watchdog (IWDG) driver"
	default y
	depends on DT_HAS_WCH_IWDG_ENABLED
	help
	  Enable the Independent Watchdog (IWDG) driver. Tested on the
	  CH32V003 and CH32V208.
+93 −0
Changes for drivers/watchdog/wdt_iwdg_wch.c: 93 added lines, 0 removed lines.
Original line number Diff line number Diff line
/*
 * Copyright (c) 2025 Michael Hope <michaelh@juju.nz>
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT wch_iwdg

#include <zephyr/drivers/watchdog.h>
#include <zephyr/kernel.h>
#include <zephyr/sys_clock.h>
#include <errno.h>

#include <ch32fun.h>

static int iwdg_wch_setup(const struct device *dev, uint8_t options)
{
	if (options != 0) {
		return -ENOTSUP;
	}

	IWDG->CTLR = CTLR_KEY_Enable;

	return 0;
}

static int iwdg_wch_disable(const struct device *dev)
{
	return -EPERM;
}

static int iwdg_wch_install_timeout(const struct device *dev,
					 const struct wdt_timeout_cfg *config)
{
	int prescaler = 0;
	/* The IWDT is driven by the 128 kHz LSI oscillator with at least a /4 prescaler. */
	uint32_t lsi_frequency = DT_PROP(DT_NODELABEL(clk_lsi), clock_frequency);
	uint32_t reload = config->window.max * (lsi_frequency / 1000 / 4);

	if (config->callback != NULL) {
		return -ENOTSUP;
	}
	if (config->window.min != 0) {
		return -ENOTSUP;
	}
	if ((config->flags & WDT_FLAG_RESET_MASK) != WDT_FLAG_RESET_SOC) {
		return -ENOTSUP;
	}

	for (; reload > IWDG_RL && prescaler < IWDG_PR;) {
		prescaler++;
		reload /= 2;
	}
	if (reload > IWDG_RL) {
		/* The reload is too high even with the maximum prescaler */
		return -EINVAL;
	}

	/* Wait for the watchdog to be idle, unlock it, update, and wait for idle. */
	while ((IWDG->STATR & (IWDG_RVU | IWDG_PVU)) != 0) {
	}

	IWDG->CTLR = IWDG_WriteAccess_Enable;
	IWDG->PSCR = prescaler;
	IWDG->RLDR = reload;

	while ((IWDG->STATR & (IWDG_RVU | IWDG_PVU)) != 0) {
	}

	return 0;
}

static int iwdg_wch_feed(const struct device *dev, int channel_id)
{
	IWDG->CTLR = CTLR_KEY_Reload;

	return 0;
}

static const struct wdt_driver_api iwdg_wch_api = {
	.setup = iwdg_wch_setup,
	.disable = iwdg_wch_disable,
	.install_timeout = iwdg_wch_install_timeout,
	.feed = iwdg_wch_feed,
};

static int iwdg_wch_init(const struct device *dev)
{
	return 0;
}

DEVICE_DT_INST_DEFINE(0, iwdg_wch_init, NULL, NULL, NULL, PRE_KERNEL_1,
		      CONFIG_KERNEL_INIT_PRIORITY_DEVICE, &iwdg_wch_api);
+12 −0
Changes for dts/bindings/watchdog/wch,iwdg.yaml: 12 added lines, 0 removed lines.
Original line number Diff line number Diff line
# Copyright (c) 2025 Michael Hope <michaelh@juju.nz>
# SPDX-License-Identifier: Apache-2.0

description: WCH Independent Watchdog (IWDG)

compatible: "wch,iwdg"

include: base.yaml

properties:
  reg:
    required: true
Loading