diff --git a/bsp/gd32103c-eval/Kconfig b/bsp/gd32103c-eval/Kconfig index 07915b789581ee2a7e1d716f3123e1bc216f67f7..faa13654166b842090b2c5791a8450d5dc4292c2 100644 --- a/bsp/gd32103c-eval/Kconfig +++ b/bsp/gd32103c-eval/Kconfig @@ -96,5 +96,8 @@ menu "On-chip Peripheral Drivers" bool "using hwtimer7" default n endif - + config BSP_USING_WDT + bool "Enable Watchdog Timer" + select RT_USING_WDT + default n endmenu diff --git a/bsp/gd32103c-eval/README.md b/bsp/gd32103c-eval/README.md index 1f3c3d3425ad5961370710abf3265e63cdc5c95a..1f78ccd1ae1bd5f5308a8a02ab276c413041a0aa 100644 --- a/bsp/gd32103c-eval/README.md +++ b/bsp/gd32103c-eval/README.md @@ -48,6 +48,7 @@ msh /> | GPIO | 支持 | GPIOA~G | | ADC | 支持 | ADC0~1 | | HWTIMER | 支持 | TIMER0~7 | +| WDT | 支持 | Free watchdog timer | | IIC | 未支持 | I2C0~1 | | SPI | 未支持 | SPI0~2 | | ETH | 未支持 | | diff --git a/bsp/gd32103c-eval/drivers/SConscript b/bsp/gd32103c-eval/drivers/SConscript index 35734e9d102756036f3834505a6a68c99b6e0bad..bc87770a78a947c7539ee57dc432593aed016b84 100644 --- a/bsp/gd32103c-eval/drivers/SConscript +++ b/bsp/gd32103c-eval/drivers/SConscript @@ -24,6 +24,9 @@ if GetDepend('RT_USING_ADC'): if GetDepend('RT_USING_HWTIMER'): src += ['drv_hwtimer.c'] +if GetDepend('RT_USING_WDT'): + src += ['drv_iwdt.c'] + group = DefineGroup('Drivers', src, depend = [''], CPPPATH = CPPPATH) Return('group') diff --git a/bsp/gd32103c-eval/drivers/drv_iwdt.c b/bsp/gd32103c-eval/drivers/drv_iwdt.c new file mode 100644 index 0000000000000000000000000000000000000000..f218f4610458a619fee52881a6c2cf28a6542c71 --- /dev/null +++ b/bsp/gd32103c-eval/drivers/drv_iwdt.c @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2021-03-03 iysheng first version + */ + +#include + +#define DBG_TAG "drv.wdt" +#define DBG_LVL DBG_INFO +#include + +#ifdef RT_USING_WDT + +typedef struct { + struct rt_watchdog_device wdt; + rt_uint32_t min_threshold_s; + rt_uint32_t max_threshold_s; + rt_uint32_t current_threshold_s; +} gd32_wdt_device_t; + +static gd32_wdt_device_t g_wdt_dev; + +static rt_err_t gd32_iwdt_init(rt_watchdog_t *wdt) +{ + rcu_osci_on(RCU_IRC40K); + if (ERROR == rcu_osci_stab_wait(RCU_IRC40K)) + { + LOG_E("failed init IRC40K clock for free watchdog."); + return -EINVAL; + } + + g_wdt_dev.min_threshold_s = 1; + g_wdt_dev.max_threshold_s = (0xfff << 8) / 40000; + LOG_I("threshold section [%u, %d]", \ + g_wdt_dev.min_threshold_s, g_wdt_dev.max_threshold_s); + + IWDG_Write_Enable(IWDG_WRITEACCESS_ENABLE); + IWDG_SetPrescaler(IWDG_PRESCALER_256); + IWDG_SetReloadValue(0xfff); + IWDG_Write_Enable(IWDG_WRITEACCESS_DISABLE); + + return 0; +} + +static rt_err_t gd32_iwdt_control(rt_watchdog_t *wdt, int cmd, void *arg) +{ + rt_uint32_t param; + + switch (cmd) + { + case RT_DEVICE_CTRL_WDT_KEEPALIVE: + IWDG_ReloadCounter(); + break; + case RT_DEVICE_CTRL_WDT_SET_TIMEOUT: + param = *(rt_uint32_t *) arg; + if ((param > g_wdt_dev.max_threshold_s) || \ + (param < g_wdt_dev.min_threshold_s)) + { + LOG_E("invalid param@%u.", param); + return -E2BIG; + } + else + { + g_wdt_dev.current_threshold_s = param; + } + IWDG_Write_Enable(IWDG_WRITEACCESS_ENABLE); + IWDG_SetReloadValue(param * 40000 >> 8); + IWDG_Write_Enable(IWDG_WRITEACCESS_DISABLE); + break; + case RT_DEVICE_CTRL_WDT_GET_TIMEOUT: + *(rt_uint32_t *)arg = g_wdt_dev.current_threshold_s; + break; + case RT_DEVICE_CTRL_WDT_START: + IWDG_Enable(); + break; + default: + LOG_W("This command is not supported."); + return -RT_ERROR; + } + + return RT_EOK; +} + +static struct rt_watchdog_ops g_wdt_ops = { + gd32_iwdt_init, + gd32_iwdt_control, +}; + +static int rt_hw_iwdt_init(void) +{ + rt_err_t ret; + + g_wdt_dev.wdt.ops = &g_wdt_ops; + /* register watchdog device */ + if (rt_hw_watchdog_register(&g_wdt_dev.wdt, "iwdt", \ + RT_DEVICE_FLAG_DEACTIVATE, RT_NULL) != RT_EOK) + { + LOG_E("wdt device register failed."); + return -RT_ERROR; + } + LOG_D("wdt device register success."); + + return ret; +} +INIT_BOARD_EXPORT(rt_hw_iwdt_init); +#endif