1 /*
2  * Copyright (c) 2020-2021, Bluetrum Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author            Notes
8  * 2020-11-30     greedyhao         first version
9  */
10 
11 #include <board.h>
12 
13 #ifdef RT_USING_WDT
14 
15 #include <drv_wdt.h>
16 
17 // #define DRV_DEBUG
18 #define LOG_TAG             "drv.wdt"
19 #include <drv_log.h>
20 
21 struct ab32_wdt_obj
22 {
23     rt_watchdog_t watchdog;
24 };
25 static struct ab32_wdt_obj ab32_wdt;
26 static struct rt_watchdog_ops ops;
27 
wdt_init(rt_watchdog_t * wdt)28 static rt_err_t wdt_init(rt_watchdog_t *wdt)
29 {
30     return RT_EOK;
31 }
32 
wdt_control(rt_watchdog_t * wdt,int cmd,void * arg)33 static rt_err_t wdt_control(rt_watchdog_t *wdt, int cmd, void *arg)
34 {
35     rt_uint32_t tmp = 0;
36 
37     switch (cmd)
38     {
39         /* feed the watchdog */
40     case RT_DEVICE_CTRL_WDT_KEEPALIVE:
41         WDTCON = 0xa;
42         break;
43         /* set watchdog timeout */
44     case RT_DEVICE_CTRL_WDT_SET_TIMEOUT:
45         if (arg == RT_NULL) {
46             LOG_E("The watchdog timeout argument cannot be NULL!");
47             break;
48         }
49 
50         tmp = WDTCON & ~(0x7 << 20);
51 
52         switch (*((rt_uint32_t *)arg))
53         {
54         case AB32_WDT_TIMEOUT_1MS:
55             LOG_I("The watchdog timeout is set to 1ms");
56             tmp |= (0xa << 24) | (0x00 << 20);
57             break;
58         case AB32_WDT_TIMEOUT_256MS:
59             LOG_I("The watchdog timeout is set to 256ms");
60             tmp |= (0xa << 24) | (0x01 << 20);
61             break;
62         case AB32_WDT_TIMEOUT_512MS:
63             LOG_I("The watchdog timeout is set to 512ms");
64             tmp |= (0xa << 24) | (0x02 << 20);
65             break;
66         case AB32_WDT_TIMEOUT_1024MS:
67             LOG_I("The watchdog timeout is set to 1024ms");
68             tmp |= (0xa << 24) | (0x03 << 20);
69             break;
70         case AB32_WDT_TIMEOUT_2048MS:
71             LOG_I("The watchdog timeout is set to 2048ms");
72             tmp |= (0xa << 24) | (0x04 << 20);
73             break;
74         case AB32_WDT_TIMEOUT_4096MS:
75             LOG_I("The watchdog timeout is set to 4096ms");
76             tmp |= (0xa << 24) | (0x05 << 20);
77             break;
78         case AB32_WDT_TIMEOUT_8192MS:
79             LOG_I("The watchdog timeout is set to 8192ms");
80             tmp |= (0xa << 24) | (0x06 << 20);
81             break;
82         case AB32_WDT_TIMEOUT_16384MS:
83             LOG_I("The watchdog timeout is set to 16384ms");
84             tmp |= (0xa << 24) | (0x07 << 20);
85             break;
86         default:
87             LOG_W("The watchdog timeout argument range from 0 to 7!");
88             tmp = WDTCON;
89             break;
90         }
91         WDTCON = tmp;
92         LOG_D("WDTCON=%X", WDTCON);
93         break;
94     case RT_DEVICE_CTRL_WDT_GET_TIMEOUT:
95         switch ((WDTCON >> 20) & 0x7)
96         {
97         case AB32_WDT_TIMEOUT_1MS:
98             LOG_D("The watchdog timeout is set to 1ms");
99             break;
100         case AB32_WDT_TIMEOUT_256MS:
101             LOG_D("The watchdog timeout is set to 256ms");
102             break;
103         case AB32_WDT_TIMEOUT_512MS:
104             LOG_D("The watchdog timeout is set to 512ms");
105             break;
106         case AB32_WDT_TIMEOUT_1024MS:
107             LOG_D("The watchdog timeout is set to 1024ms");
108             break;
109         case AB32_WDT_TIMEOUT_2048MS:
110             LOG_D("The watchdog timeout is set to 2048ms");
111             break;
112         case AB32_WDT_TIMEOUT_4096MS:
113             LOG_D("The watchdog timeout is set to 4096ms");
114             break;
115         case AB32_WDT_TIMEOUT_8192MS:
116             LOG_D("The watchdog timeout is set to 8192ms");
117             break;
118         case AB32_WDT_TIMEOUT_16384MS:
119             LOG_D("The watchdog timeout is set to 16384ms");
120             break;
121         default:
122             break;
123         }
124         break;
125     case RT_DEVICE_CTRL_WDT_START:
126         WDTCON = 0x110;
127         break;
128     default:
129         LOG_W("This command is not supported.");
130         return -RT_ERROR;
131     }
132     return RT_EOK;
133 }
134 
rt_wdt_init(void)135 int rt_wdt_init(void)
136 {
137     ops.init = &wdt_init;
138     ops.control = &wdt_control;
139     ab32_wdt.watchdog.ops = &ops;
140     /* register watchdog device */
141     if (rt_hw_watchdog_register(&ab32_wdt.watchdog, "wdt", RT_DEVICE_FLAG_DEACTIVATE, RT_NULL) != RT_EOK)
142     {
143         LOG_E("wdt device register failed.");
144         return -RT_ERROR;
145     }
146     LOG_D("wdt device register success.");
147     return RT_EOK;
148 }
149 INIT_BOARD_EXPORT(rt_wdt_init);
150 
151 #endif /* RT_USING_WDT */
152