• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 Winner Microelectronics Co., Ltd. All rights reserved.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 /**
17  * @file    wm_watchdog.c
18  *
19  * @brief   watchdog Driver Module
20  *
21  * @author  kevin
22  *
23  * Copyright (c) 2014 Winner Microelectronics Co., Ltd.
24  */
25 #include "wm_debug.h"
26 #include "wm_regs.h"
27 #include "wm_irq.h"
28 #include "wm_cpu.h"
29 #include "wm_watchdog.h"
30 
31 #define WDG_LOAD_VALUE_MAX  (0xFFFFFFFF / 40)
32 #define WDG_LOAD_VALUE_DEF  (20 * 1000 * 1000)
33 
34 static volatile u8 wdg_reset = 0;
35 static volatile u8 wdg_enable = 0;
36 static volatile u32 wdg_value_us = WDG_LOAD_VALUE_DEF;
37 static volatile u32 wdg_jumpclear_flag = 0; /* 0:donot jump clear, 1: jump clear, 2:close wdg */
WDG_IRQHandler(void)38 ATTRIBUTE_ISR void WDG_IRQHandler(void)
39 {
40     csi_kernel_intrpt_enter();
41     if (wdg_reset) {
42         csi_kernel_intrpt_exit();
43         return;
44     }
45     csi_kernel_intrpt_exit();
46 }
47 
48 /**
49  * @brief          This function is used to clear watchdog irq in case watchdog reset
50  *
51  * @param          None
52  *
53  * @return         None
54  *
55  * @note           None
56  */
tls_watchdog_clr(void)57 void tls_watchdog_clr(void)
58 {
59     if (wdg_jumpclear_flag == 0) {
60         tls_reg_write32(HR_WDG_INT_CLR, 0x01);
61     }
62 }
63 
__tls_watchdog_init(u32 usec)64 static void __tls_watchdog_init(u32 usec)
65 {
66     tls_sys_clk sysclk;
67 
68     tls_sys_clk_get(&sysclk);
69     tls_irq_enable(WDG_IRQn);
70 
71     tls_reg_write32(HR_WDG_LOAD_VALUE, sysclk.apbclk * usec);  /* 40M dominant frequency: 40 * 10^6 * (usec / 10^6) */
72     tls_reg_write32(HR_WDG_CTRL, 0x3);             /* enable irq & reset */
73 }
74 
__tls_watchdog_deinit(void)75 static void __tls_watchdog_deinit(void)
76 {
77     tls_irq_disable(WDG_IRQn);
78     tls_reg_write32(HR_WDG_CTRL, 0);
79     tls_reg_write32(HR_WDG_INT_CLR, 0x01);
80 }
81 
82 /**
83  * @brief          This function is used to init watchdog
84  *
85  * @param[in]      usec    microseconds
86  *
87  * @return         None
88  *
89  * @note           None
90  */
tls_watchdog_init(u32 usec)91 void tls_watchdog_init(u32 usec)
92 {
93     __tls_watchdog_init(usec);
94 
95     wdg_value_us = usec;
96     wdg_enable = 1;
97 }
98 
99 /**
100  * @brief          This function is used to deinit watchdog
101  *
102  * @param[in]     None
103  *
104  * @return         None
105  *
106  * @note           None
107  */
tls_watchdog_deinit(void)108 void tls_watchdog_deinit(void)
109 {
110     __tls_watchdog_deinit();
111 
112     wdg_value_us = WDG_LOAD_VALUE_DEF;
113     wdg_enable = 0;
114 }
115 
116 /**
117  * @brief          This function is used to start calculating elapsed time.
118  *
119  * @param[in]      None
120  *
121  * @return         elapsed time, unit:millisecond
122  *
123  * @note           None
124  */
tls_watchdog_start_cal_elapsed_time(void)125 void tls_watchdog_start_cal_elapsed_time(void)
126 {
127     if (wdg_enable) {
128         wdg_jumpclear_flag = 1;
129 
130         __tls_watchdog_deinit();
131 
132         __tls_watchdog_init(WDG_LOAD_VALUE_MAX);
133     } else {
134         wdg_jumpclear_flag = 2;
135         __tls_watchdog_init(WDG_LOAD_VALUE_MAX);
136     }
137 }
138 
139 /**
140  * @brief          This function is used to stop calculating & return elapsed time.
141  *
142  * @param[in]     none
143  *
144  * @return         elapsed time, unit:millisecond
145  *
146  * @note           None
147  */
tls_watchdog_stop_cal_elapsed_time(void)148 u32 tls_watchdog_stop_cal_elapsed_time(void)
149 {
150 #define RT_TIME_BASE (40)
151     u32 val = 0;
152 
153     switch (wdg_jumpclear_flag) {
154         case 1:
155             {
156                 val = (tls_reg_read32(HR_WDG_LOAD_VALUE) - tls_reg_read32(HR_WDG_CUR_VALUE))/RT_TIME_BASE;
157                 __tls_watchdog_deinit();
158                 __tls_watchdog_init(wdg_value_us);
159                 wdg_jumpclear_flag = 0;
160             }
161             break;
162 
163         case 2:
164             {
165                 val = (tls_reg_read32(HR_WDG_LOAD_VALUE) - tls_reg_read32(HR_WDG_CUR_VALUE))/RT_TIME_BASE;
166                 __tls_watchdog_deinit();
167                 wdg_jumpclear_flag = 0;
168             }
169             break;
170 
171         default:
172             wdg_jumpclear_flag = 0;
173             break;
174     }
175 
176     return val;
177 }
178 /**
179  * @brief          This function is used to reset system
180  *
181  * @param          None
182  *
183  * @return         None
184  *
185  * @note           None
186  */
tls_sys_reset(void)187 void tls_sys_reset(void)
188 {
189     tls_os_set_critical();
190     wdg_reset = 1;
191     __tls_watchdog_deinit();
192     tls_reg_write32(HR_WDG_LOCK, 0x1ACCE551);
193     tls_reg_write32(HR_WDG_LOAD_VALUE, 0x100);
194     tls_reg_write32(HR_WDG_CTRL, 0x3);
195     tls_reg_write32(HR_WDG_LOCK, 1);
196     while (1) {
197     }
198 }
199 
200