123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239 |
- /*
- * File : drv_wdt.c
- * This file is part of GK710X BSP for RT-Thread distribution.
- *
- * Copyright (c) 2017 GOKE Microelectronics Co., Ltd.
- * All rights reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Visit http://www.goke.com to get contact with Goke.
- *
- * Change Logs:
- * Date Author Notes
- */
- #include "drv_wdt.h"
- #include <rtdef.h>
- #include <rtthread.h>
- #include <rtdevice.h>
- #include <drivers/watchdog.h>
- #include "gtypes.h"
- #include "gd_wdog.h"
- #include "gd_timer.h"
- #include "platform.h"
- typedef enum
- {
- RESTENABLE = 0x4,
- INTERRUPTENABLE = 0x2,
- }wdt_enable_mode;
- static rt_uint32_t heartbeat = 0;
- static rt_err_t gk_wdt_start(int mode)
- {
- rt_err_t ret = RT_EOK;
- wdt_enable_mode wdt_mode = RESTENABLE;
- ret = GD_Wdog_Disable();
- if (ret != RT_EOK)
- {
- rt_kprintf("GD_Wdog_Disable error!\n");
- return RT_ERROR;
- }
- if ((mode == RESTENABLE) || (mode == INTERRUPTENABLE))
- {
- wdt_mode = mode;
- }
- ret = GD_Wdog_Enable(wdt_mode);
- if (ret != RT_EOK)
- {
- rt_kprintf("GD_Wdog_Enable error!\n");
- return RT_ERROR;
- }
- return ret;
- }
- static rt_err_t gk_wdt_keepalive(void)
- {
- rt_err_t ret = RT_EOK;
- ret = GD_Wdog_ClrTimeout();
- if (ret != GD_OK)
- {
- rt_kprintf("GD_Wdog_ClrTimeout error!\n");
- return RT_ERROR;
- }
- return ret;
- }
- static rt_uint32_t gk_wdt_get_timeleft(void)
- {
- GERR index = GD_OK;
- rt_uint32_t second = 0;
- index = GD_Wdog_GetValue();
- if (index < GD_OK )
- {
- rt_kprintf("GD_Wdog_GetValue error!\n");
- return RT_ERROR;
- }
- second = index/GD_GET_APB_ClkHz();
- return second;
- }
- static rt_err_t gk_wdt_set_timeout(rt_uint32_t second)
- {
- rt_err_t ret = RT_EOK;
- rt_uint32_t index = 0;
- index = second * GD_GET_APB_ClkHz();
- ret = GD_Wdog_LoadValue(index);
- if (ret != GD_OK)
- {
- rt_kprintf("GD_Wdog_LoadValue error!\n");
- return RT_ERROR;
- }
- return ret;
- }
- static rt_err_t gk_watchdog_init(rt_watchdog_t *wdt)
- {
- struct wdt_driver *wdt_drv = wdt->parent.user_data;
- if (wdt_drv->in_use) return -RT_EBUSY;
- GD_Wdog_Init();
- return RT_EOK;
- }
- static rt_err_t gk_watchdog_ctrl(rt_watchdog_t *wdt, int cmd, void *arg)
- {
- rt_uint32_t val;
- int mode;
- switch (cmd)
- {
- case RT_DEVICE_CTRL_WDT_START:
- mode = *((int *)(arg));
- gk_wdt_start(mode);
- break;
- case RT_DEVICE_CTRL_WDT_STOP:
- GD_Wdog_Disable();
- break;
- case RT_DEVICE_CTRL_WDT_KEEPALIVE:
- gk_wdt_keepalive();
- break;
- case RT_DEVICE_CTRL_WDT_SET_TIMEOUT:
- heartbeat = *((rt_uint32_t *)(arg));
- gk_wdt_set_timeout(heartbeat);
- break;
- case RT_DEVICE_CTRL_WDT_GET_TIMEOUT:
- arg = &heartbeat;
- break;
- case RT_DEVICE_CTRL_WDT_GET_TIMELEFT:
- val = gk_wdt_get_timeleft();
- arg = &val;
- break;
- default:
- return -RT_EIO;
- }
- return RT_EOK;
- }
- struct rt_watchdog_ops gk_watchdog_ops = {
- .init = &gk_watchdog_init, .control = &gk_watchdog_ctrl,
- };
- int gk_wdt_probe(void *priv_data)
- {
- rt_watchdog_t *wdt_dev;
- struct wdt_driver *wdt_drv;
- wdt_drv = (struct wdt_driver *)rt_malloc(sizeof(struct wdt_driver));
- rt_memset(wdt_drv, 0, sizeof(struct wdt_driver));
- wdt_dev = (rt_watchdog_t *)rt_malloc(sizeof(rt_watchdog_t));
- if (wdt_dev == RT_NULL)
- {
- rt_kprintf("ERROR: %s rt_watchdog_t malloc failed\n", __func__);
- }
- wdt_dev->ops = &gk_watchdog_ops;
- rt_hw_watchdog_register(wdt_dev, "gk_wdt", RT_DEVICE_OFLAG_RDWR, wdt_drv);
- return 0;
- }
- int gk_wdt_exit(void *priv_data) { return 0; }
- struct gk_platform_driver wdt_driver_ops = {
- .name = "wdt", .probe = gk_wdt_probe, .remove = gk_wdt_exit,
- };
- void rt_hw_wdt_init(void)
- {
- gk_platform_driver_init(&wdt_driver_ops);
- }
- void gk_wdt_test(int timeout, int mode)
- {
- rt_device_t wdt_dev;
- wdt_dev = rt_device_find("gk_wdt");
- if (!wdt_dev)
- {
- rt_kprintf("cann't find the wdt dev\n");
- }
- rt_device_open(wdt_dev, 0);
- rt_device_control(wdt_dev, RT_DEVICE_CTRL_WDT_SET_TIMEOUT, &timeout);
- rt_device_control(wdt_dev, RT_DEVICE_CTRL_WDT_START, &mode);
- rt_kprintf("system shall reboot in %d seconds.\n", timeout);
- for (; timeout > 0; timeout--)
- {
- rt_kprintf("kicked %d\n", timeout);
- rt_thread_delay(RT_TICK_PER_SECOND);
- }
- }
- #ifdef RT_USING_WDT
- #ifdef RT_USING_FINSH
- #include <finsh.h>
- FINSH_FUNCTION_EXPORT(gk_wdt_test, enable wdt);
- #endif
- #endif
|