summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBernard Xiong <[email protected]>2019-05-08 15:25:21 +0800
committerGitHub <[email protected]>2019-05-08 15:25:21 +0800
commit7ff7fde4c991e626798fe072ed52fa4305d6952a (patch)
tree5a6d7417481aa2925ca44b53e2e12f660204ec58
parentdfaced4cb6bd48eaf3dc1c11545b1150455b30e9 (diff)
parentf74f6e8c55de0a462c950ad85b17261c650cb021 (diff)
Merge pull request #2656 from sundm75/sundm75
[bsp][ls1c] Add watchdog library function and driver .
-rw-r--r--bsp/ls1cdev/drivers/drv_wdt.c199
-rw-r--r--bsp/ls1cdev/drivers/drv_wdt.h23
-rw-r--r--bsp/ls1cdev/libraries/ls1c_wdog.c91
-rw-r--r--bsp/ls1cdev/libraries/ls1c_wdog.h32
4 files changed, 345 insertions, 0 deletions
diff --git a/bsp/ls1cdev/drivers/drv_wdt.c b/bsp/ls1cdev/drivers/drv_wdt.c
new file mode 100644
index 0000000000..4a42220000
--- /dev/null
+++ b/bsp/ls1cdev/drivers/drv_wdt.c
@@ -0,0 +1,199 @@
+/*
+ * Copyright (c) 2006-2018, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2019-05-06 sundm75 first version
+ */
+
+#include <rtthread.h>
+#include <rtdevice.h>
+
+#ifdef RT_USING_WDT
+
+#include <drivers/watchdog.h>
+#include "drv_wdt.h"
+
+#include "ls1c_wdog.h"
+#include "ls1c_clock.h"
+
+typedef enum
+{
+ RESTENABLE = 0x0,
+ INTERRUPTENABLE = 0x1,
+}wdt_enable_mode;
+
+static rt_uint32_t heartbeat = 0;
+
+static rt_err_t wdt_stop(void)
+{
+ rt_err_t ret = RT_EOK;
+
+ Wdog_Reset();
+ ret = (rt_err_t) Wdog_Disable();
+ if (ret != RT_EOK)
+ {
+ rt_kprintf("Wdog_Disable error!\n");
+ return RT_ERROR;
+ }
+ return ret;
+}
+
+static rt_err_t wdt_start(int mode)
+{
+ rt_err_t ret = RT_EOK;
+ wdt_enable_mode wdt_mode = RESTENABLE;
+
+ ret = (rt_err_t) Wdog_Disable();
+ if (ret != RT_EOK)
+ {
+ rt_kprintf("Wdog_Disable error!\n");
+ return RT_ERROR;
+ }
+
+ if((mode == RESTENABLE) || (mode == INTERRUPTENABLE))
+ {
+ wdt_mode = mode;
+ }
+ Wdog_Enable();
+ Wdog_Set();
+ if (ret != RT_EOK)
+ {
+ rt_kprintf("Wdog_Enable error!\n");
+ return RT_ERROR;
+ }
+
+ return ret;
+}
+
+static rt_err_t wdt_keepalive(void)
+{
+ rt_err_t ret = RT_EOK;
+ rt_uint32_t index = 0;
+
+ index = heartbeat * clk_get_apb_rate();
+ ret = (rt_err_t) Wdog_LoadValue(index);
+ Wdog_Set();
+ if (ret != 0)
+ {
+ rt_kprintf("LS1C_Wdog_ClrTimeout error!\n");
+ return RT_ERROR;
+ }
+
+ return ret;
+}
+
+static rt_uint32_t wdt_get_timeleft(void)
+{
+ rt_uint32_t cnt = 0;
+ rt_uint32_t second = 0;
+
+ cnt = (rt_uint32_t) Wdog_GetValue();
+ second = cnt/clk_get_apb_rate();
+
+ return second;
+}
+
+static rt_err_t wdt_set_timeout(rt_uint32_t second)
+{
+ rt_err_t ret = RT_EOK;
+ rt_uint32_t index = 0;
+
+ index = second * clk_get_apb_rate();
+ ret = (rt_err_t) Wdog_LoadValue(index);
+ if (ret != RT_EOK)
+ {
+ rt_kprintf("Wdog_LoadValue error!\n");
+ return RT_ERROR;
+ }
+ return ret;
+}
+
+static rt_err_t watchdog_init(rt_watchdog_t *wdt)
+{
+ struct wdt_driver *wdt_drv = wdt->parent.user_data;
+ if (wdt_drv->in_use) return -RT_EBUSY;
+
+ Wdog_Init();
+
+ return RT_EOK;
+}
+
+static rt_err_t 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));
+ wdt_start(mode);
+ break;
+
+ case RT_DEVICE_CTRL_WDT_STOP:
+ Wdog_Disable();
+ break;
+
+ case RT_DEVICE_CTRL_WDT_KEEPALIVE:
+ wdt_keepalive();
+ break;
+
+ case RT_DEVICE_CTRL_WDT_SET_TIMEOUT:
+ heartbeat = *((rt_uint32_t *)(arg));
+ wdt_set_timeout(heartbeat);
+ break;
+
+ case RT_DEVICE_CTRL_WDT_GET_TIMEOUT:
+ arg = &heartbeat;
+ break;
+
+ case RT_DEVICE_CTRL_WDT_GET_TIMELEFT:
+ val = (rt_uint32_t) wdt_get_timeleft();
+ arg = &val;
+ break;
+
+ default:
+ return -RT_EIO;
+ }
+ return RT_EOK;
+}
+
+struct rt_watchdog_ops watchdog_ops =
+{
+ .init = &watchdog_init,
+ .control = &watchdog_ctrl,
+};
+
+int wdt_exit(void *priv_data)
+{
+ return 0;
+}
+
+int rt_hw_wdt_init(void)
+{
+ 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 = &watchdog_ops;
+
+ rt_hw_watchdog_register(wdt_dev, "wdt", RT_DEVICE_OFLAG_RDWR, wdt_drv);
+
+ return 0;
+}
+
+INIT_BOARD_EXPORT(rt_hw_wdt_init);
+
+#endif
diff --git a/bsp/ls1cdev/drivers/drv_wdt.h b/bsp/ls1cdev/drivers/drv_wdt.h
new file mode 100644
index 0000000000..a017edb19a
--- /dev/null
+++ b/bsp/ls1cdev/drivers/drv_wdt.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2006-2018, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2019-05-06 sundm75 first version
+ */
+
+#ifndef WDT_H_
+#define WDT_H_
+
+struct wdt_driver
+{
+ unsigned long in_use;
+
+ void* priv;
+};
+
+int rt_hw_wdt_init(void);
+
+#endif /* WDT_H_ */
diff --git a/bsp/ls1cdev/libraries/ls1c_wdog.c b/bsp/ls1cdev/libraries/ls1c_wdog.c
new file mode 100644
index 0000000000..4034281d10
--- /dev/null
+++ b/bsp/ls1cdev/libraries/ls1c_wdog.c
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2006-2018, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2019-05-06 sundm75 first version
+ */
+
+#include "ls1c.h"
+#include "ls1c_wdog.h"
+
+/*
+系统先配置看门狗使能位 WDT_EN;
+然后配置看门狗计数器的初始值 WDT_TIMER;
+当设置 WDT_SET 后,计数器开始减计数;
+当还没有减到 0 时,重置看门狗计数器,系统不会重启;
+当看门狗计数器减到 0 时,则系统重启。
+*/
+
+static unsigned int WDT_timer = 0;
+
+/* 暂时为空 */
+unsigned int Wdog_Init(void)
+{
+ return 0;
+}
+
+/* 配置看门狗使能寄存器(WDT_EN) */
+unsigned int Wdog_Enable(void)
+{
+ unsigned int ctrl;
+ ctrl = (WDT_EN);
+ ctrl |= 0x01;
+
+ WDT_EN = ctrl;
+ return 0;
+}
+
+/* 配置看门狗失能寄存器(WDT_EN) */
+unsigned int Wdog_Disable(void)
+{
+ unsigned int ctrl;
+ ctrl = (WDT_EN);
+ ctrl &= ~0x01;
+ WDT_EN = ctrl;
+ return 0;
+}
+
+/* 配置看门狗设置寄存器 (WDT_SET) */
+unsigned int Wdog_Set(void)
+{
+ unsigned int ctrl;
+ ctrl = (WDT_SET);
+ ctrl |= 0x01;
+ WDT_SET = ctrl;
+ return 0;
+}
+
+/* 配置看门狗设置寄存器 (WDT_SET) */
+unsigned int Wdog_Reset(void)
+{
+ unsigned int ctrl;
+ ctrl = (WDT_SET);
+ ctrl &= ~0x01;
+ WDT_SET = ctrl;
+ return 0;
+}
+
+/* 获得看门狗计数器(WDT_timer) 的值*/
+unsigned int Wdog_GetValue(void)
+{
+ unsigned int cnt;
+ cnt = (WDT_TIMER);
+ return cnt;
+}
+
+/* 配置看门狗计数器(WDT_timer)的值*/
+unsigned int Wdog_LoadValue(unsigned int cnt)
+{
+ WDT_TIMER = cnt;
+ WDT_timer = cnt;
+ return 0;
+}
+
+/* 获得看门狗计数器设定值 */
+unsigned int Wdog_GetPreValue(void)
+{
+ return WDT_timer;
+}
diff --git a/bsp/ls1cdev/libraries/ls1c_wdog.h b/bsp/ls1cdev/libraries/ls1c_wdog.h
new file mode 100644
index 0000000000..a4717eedbf
--- /dev/null
+++ b/bsp/ls1cdev/libraries/ls1c_wdog.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2006-2018, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2019-05-06 sundm75 first version
+ */
+
+#ifndef _LS1C_WDOG_H_
+#define _LS1C_WDOG_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+unsigned int Wdog_Init(void); // 暂时为空
+unsigned int Wdog_Enable(void); // 看门狗使能寄存器(WDT_EN)
+unsigned int Wdog_Disable(void); // 看门狗失能寄存器(WDT_EN)
+unsigned int Wdog_Set(void); // 看门狗设置寄存器 (WDT_SET)
+unsigned int Wdog_Reset(void); // 看门狗设置寄存器 (WDT_SET)
+unsigned int Wdog_GetValue(void); // 获得看门狗计数器(WDT_timer)
+unsigned int Wdog_LoadValue(unsigned int cnt); // 设置看门狗计数器(WDT_timer)
+unsigned int Wdog_GetPreValue(void); // 获得看门狗计数器设定值
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _LS1C_WDOG_H_ */
+