Merge pull request #2656 from sundm75/sundm75
[bsp][ls1c] Add watchdog library function and driver .
This commit is contained in:
commit
7ff7fde4c9
|
@ -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
|
|
@ -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_ */
|
|
@ -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;
|
||||
}
|
|
@ -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_ */
|
||||
|
Loading…
Reference in New Issue