1 /*
2  * Copyright (c) 2006-2025, RT-Thread Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author            Notes
8  * 2020-08-18     ylz0923           first version
9  * 2021-08-12     chenyingchun      optimize wdt_control arg usage
10  */
11 
12 #include <board.h>
13 #include <rtdevice.h>
14 #include <nrfx_wdt.h>
15 
16 #ifdef RT_USING_WDT
17 
18 struct nrf5x_wdt_obj
19 {
20     rt_watchdog_t watchdog;
21     nrfx_wdt_t wdt;
22     nrfx_wdt_channel_id ch;
23     rt_uint16_t is_start;
24 };
25 static struct nrf5x_wdt_obj nrf5x_wdt = {
26     .wdt = NRFX_WDT_INSTANCE(0),
27 };
28 static nrfx_wdt_config_t nrf5x_wdt_cfg = NRFX_WDT_DEFAULT_CONFIG;
29 static struct rt_watchdog_ops ops;
30 
wdt_init(rt_watchdog_t * wdt)31 static rt_err_t wdt_init(rt_watchdog_t *wdt)
32 {
33     return RT_EOK;
34 }
35 
wdt_control(rt_watchdog_t * wdt,int cmd,void * arg)36 static rt_err_t wdt_control(rt_watchdog_t *wdt, int cmd, void *arg)
37 {
38     switch (cmd)
39     {
40     /* feed the watchdog */
41     case RT_DEVICE_CTRL_WDT_KEEPALIVE:
42         nrfx_wdt_feed(&nrf5x_wdt.wdt);
43         break;
44     /* set watchdog timeout */
45     case RT_DEVICE_CTRL_WDT_SET_TIMEOUT:
46         nrf5x_wdt_cfg.reload_value = (*((rt_uint32_t*)arg)) * 1000;
47         break;
48     case RT_DEVICE_CTRL_WDT_GET_TIMEOUT:
49         *((rt_uint32_t*)arg) = nrf5x_wdt_cfg.reload_value;
50         break;
51     case RT_DEVICE_CTRL_WDT_START:
52         if (nrf5x_wdt.is_start != 1)
53         {
54             nrfx_wdt_init(&nrf5x_wdt.wdt, &nrf5x_wdt_cfg, RT_NULL);
55             nrfx_wdt_channel_alloc(&nrf5x_wdt.wdt, &nrf5x_wdt.ch);
56             nrfx_wdt_enable(&nrf5x_wdt.wdt);
57             nrf5x_wdt.is_start = 1;
58         }
59         break;
60     default:
61         return -RT_ERROR;
62     }
63     return RT_EOK;
64 }
65 
rt_wdt_init(void)66 int rt_wdt_init(void)
67 {
68     nrf5x_wdt.is_start = 0;
69     ops.init = &wdt_init;
70     ops.control = &wdt_control;
71     nrf5x_wdt.watchdog.ops = &ops;
72     /* register watchdog device */
73     if (rt_hw_watchdog_register(&nrf5x_wdt.watchdog, "wdt", RT_DEVICE_FLAG_DEACTIVATE, RT_NULL) != RT_EOK)
74     {
75         return -RT_ERROR;
76     }
77     return RT_EOK;
78 }
79 INIT_BOARD_EXPORT(rt_wdt_init);
80 
wdt_sample(int argc,char * argv[])81 static int wdt_sample(int argc, char *argv[])
82 {
83     rt_uint32_t timeout = 2;                    /* 溢出时间,单位:秒*/
84     rt_device_t wdt = rt_device_find("wdt");
85     rt_device_init(wdt);
86     rt_device_control(wdt, RT_DEVICE_CTRL_WDT_SET_TIMEOUT, &timeout);
87     rt_device_control(wdt, RT_DEVICE_CTRL_WDT_START, RT_NULL);
88 }
89 MSH_CMD_EXPORT(wdt_sample, wdt sample);
90 
91 #endif /* RT_USING_WDT */
92 
93