1 /*
2 * Copyright (c) 2021-2023 HPMicro
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7
8 #ifndef HPM_WDG_DRV_H
9 #define HPM_WDG_DRV_H
10
11 /**
12 * @brief WDG APIs
13 * @defgroup wdg_interface WDG driver APIs
14 * @ingroup wdg_interfaces
15 * @{
16 */
17
18
19 #include "hpm_common.h"
20 #include "hpm_wdg_regs.h"
21
22 /**
23 * @brief WDG Reset Interval definitions
24 */
25 typedef enum reset_interval_enum {
26 reset_interval_clock_period_mult_128 = 0,
27 reset_interval_clock_period_mult_256 = 1,
28 reset_interval_clock_period_mult_512 = 2,
29 reset_interval_clock_period_mult_1k = 3,
30 reset_interval_clock_period_mult_2k = 4,
31 reset_interval_clock_period_mult_4k = 5,
32 reset_interval_clock_period_mult_8k = 6,
33 reset_interval_clock_period_mult_16k = 7,
34 reset_interval_max = reset_interval_clock_period_mult_16k,
35 reset_interval_out_of_range,
36 } reset_interval_t;
37
38 /**
39 * @brief WDG Interrupt interval definitions
40 */
41 typedef enum interrupt_interval_enum {
42 interrupt_interval_clock_period_multi_64 = 0,
43 interrupt_interval_clock_period_multi_256 = 1,
44 interrupt_interval_clock_period_multi_1k = 2,
45 interrupt_interval_clock_period_multi_2k = 3,
46 interrupt_interval_clock_period_multi_4k = 4,
47 interrupt_interval_clock_period_multi_8k = 5,
48 interrupt_interval_clock_period_multi_16k = 6,
49 interrupt_interval_clock_period_multi_32k = 7,
50 interrupt_interval_clock_period_multi_128k = 8,
51 interrupt_interval_clock_period_multi_512k = 9,
52 interrupt_interval_clock_period_multi_2m = 10,
53 interrupt_interval_clock_period_multi_8m = 11,
54 interrupt_interval_clock_period_multi_32m = 12,
55 interrupt_interval_clock_period_multi_128m = 13,
56 interrupt_interval_clock_period_multi_512m = 14,
57 interrupt_interval_clock_period_multi_2g = 15,
58 interrupt_interval_max = interrupt_interval_clock_period_multi_2g,
59 interrupt_interval_out_of_range,
60 } interrupt_interval_t;
61
62 /**
63 * @brief WDG clock source definitions
64 */
65 typedef enum wdg_clksrc_enum {
66 wdg_clksrc_extclk, /**< WDG clock source: external clock */
67 wdg_clksrc_pclk, /**< WDG clock source: Peripheral clock */
68 wdg_clksrc_max = wdg_clksrc_pclk
69 } wdg_clksrc_t;
70
71 /**
72 * @brief WDG Control configuration structure
73 * @note WDG reset time = reset_interval + interrupt interval
74 */
75 typedef struct wdg_control_struct {
76 reset_interval_t reset_interval; /**< WDG reset interval */
77 interrupt_interval_t interrupt_interval; /**< WDG interrupt interval */
78 bool reset_enable; /**< WDG reset enable */
79 bool interrupt_enable; /**< WDG interrupt enable */
80 wdg_clksrc_t clksrc; /**< WDG clock source */
81 bool wdg_enable; /**< WDG enable */
82 } wdg_control_t;
83
84 #define WDG_WRITE_ENABLE_MAGIC_NUM (0x5AA5UL) /**< WDG enable magic number */
85 #define WDG_RESTART_MAGIC_NUM (0xCAFEUL) /**< WDG restart magic number */
86
87 #define WDG_EXT_CLK_FREQ (32768UL) /**< WDG External CLock frequency: 32768 Hz */
88
89 #ifdef __cplusplus
90 extern "C" {
91 #endif
92
93 /**
94 * @brief WDG write enable function
95 *
96 * @param [in] base WDG base address
97 */
wdg_write_enable(WDG_Type * base)98 static inline void wdg_write_enable(WDG_Type *base)
99 {
100 base->WREN = WDG_WRITE_ENABLE_MAGIC_NUM;
101 }
102
103 /**
104 * @brief WDG Enable function
105 *
106 * @param [in] base WDG base address
107 */
wdg_enable(WDG_Type * base)108 static inline void wdg_enable(WDG_Type *base)
109 {
110 wdg_write_enable(base);
111 base->CTRL |= WDG_CTRL_EN_MASK;
112 }
113
114 /**
115 * @brief WDG Disable function
116 *
117 * @param [in] base WDG base address
118 */
wdg_disable(WDG_Type * base)119 static inline void wdg_disable(WDG_Type *base)
120 {
121 wdg_write_enable(base);
122 base->CTRL &= ~WDG_CTRL_EN_MASK;
123 }
124
125 /**
126 * @brief WDG reset enable function
127 *
128 * @param [in] base WDG base address
129 */
wdg_reset_enable(WDG_Type * base)130 static inline void wdg_reset_enable(WDG_Type *base)
131 {
132 wdg_write_enable(base);
133 base->CTRL |= WDG_CTRL_RSTEN_MASK;
134 }
135
136 /**
137 * @brief WDG reset disable function
138 *
139 * @param [in] base WDG base address
140 */
wdg_reset_disable(WDG_Type * base)141 static inline void wdg_reset_disable(WDG_Type *base)
142 {
143 wdg_write_enable(base);
144 base->CTRL &= ~WDG_CTRL_RSTEN_MASK;
145 }
146
147
148 /**
149 * @brief WDG interrupt enable function
150 *
151 * @param [in] base WDG base address
152 */
wdg_interrupt_enable(WDG_Type * base)153 static inline void wdg_interrupt_enable(WDG_Type *base)
154 {
155 wdg_write_enable(base);
156 base->CTRL |= WDG_CTRL_INTEN_MASK;
157 }
158
159 /**
160 * @brief WDG interrupt disable function
161 *
162 * @param [in] base WDG base address
163 */
wdg_interrupt_disable(WDG_Type * base)164 static inline void wdg_interrupt_disable(WDG_Type *base)
165 {
166 wdg_write_enable(base);
167 base->CTRL &= ~WDG_CTRL_INTEN_MASK;
168 }
169
170 /**
171 * @brief WDG Clock Source selection function
172 *
173 * @param [in] base WDG base address
174 * @param [in] clksrc WDG clock source
175 * @arg wdg_clksrc_extclk External clock
176 * @arg wdg_clksrc_pclk Peripheral clock
177 */
wdg_clksrc_select(WDG_Type * base,wdg_clksrc_t clksrc)178 static inline void wdg_clksrc_select(WDG_Type *base, wdg_clksrc_t clksrc)
179 {
180 if (clksrc == wdg_clksrc_extclk) {
181 base->CTRL &= ~WDG_CTRL_CLKSEL_MASK;
182 } else {
183 base->CTRL |= WDG_CTRL_CLKSEL_MASK;
184 }
185 }
186
187 /**
188 * @brief WDG restart function
189 *
190 * @param [in] base WDG base address
191 */
wdg_restart(WDG_Type * base)192 static inline void wdg_restart(WDG_Type *base)
193 {
194 wdg_write_enable(base);
195 base->RESTART = WDG_RESTART_MAGIC_NUM;
196 }
197
198 /**
199 * @brief WDG Get Status function
200 *
201 * @param [in] base WDG base address
202 * @retval WDG status register value
203 */
wdg_get_status(WDG_Type * base)204 static inline uint32_t wdg_get_status(WDG_Type *base)
205 {
206 return base->ST;
207 }
208
209 /**
210 * @brief WDG clear status function
211 *
212 * @param [in] base WDG base address
213 * @param [in] status_mask WDG status mask value
214 */
wdg_clear_status(WDG_Type * base,uint32_t status_mask)215 static inline void wdg_clear_status(WDG_Type *base, uint32_t status_mask)
216 {
217 base->ST = status_mask;
218 }
219
220 /**
221 * @brief WDG initialization function
222 *
223 * @param [in] base WDG base address
224 * @param [in] wdg_ctrl WDG control structure
225 * @retval API execution status
226 */
227 hpm_stat_t wdg_init(WDG_Type *base, wdg_control_t *wdg_ctrl);
228
229 /**
230 * @brief Convert the Reset interval value based on the WDG source clock frequency and the expected reset interval
231 * in terms of microseconds
232 *
233 * @param [in] src_freq WDG source clock frequency
234 * @param [in] reset_us Expected Reset interval in terms of microseconds
235 * @retval Converted WDG reset interval
236 */
237 reset_interval_t wdg_convert_reset_interval_from_us(const uint32_t src_freq, const uint32_t reset_us);
238
239 /**
240 * @brief Convert the interrupt interval value based on the WDG source clock frequency and the expected interrupt interval
241 * in terms of microseconds
242 *
243 * @param [in] src_freq WDG source clock frequency
244 * @param [in] interval Expected Interrupt interval
245 * @retval Converted WDG interrupt interval in us
246 */
247 uint64_t wdg_convert_interrupt_interval_to_us(const uint32_t src_freq, interrupt_interval_t interval);
248
249 /**
250 * @brief Convert the Reset interval value based on the WDG source clock frequency and the expected reset interval
251 * in terms of microseconds
252 *
253 * @param [in] src_freq WDG source clock frequency
254 * @param [in] interval Expected Reset interval
255 * @retval Converted WDG reset interval in us
256 */
257 uint32_t wdg_convert_reset_interval_to_us(const uint32_t src_freq, reset_interval_t interval);
258
259 /**
260 * @brief Convert the interrupt interval value based on the WDG source clock frequency and the expected interrupt interval
261 * in terms of microseconds
262 *
263 * @param [in] src_freq WDG source clock frequency
264 * @param [in] interval_us Expected Interrupt interval in terms of microseconds
265 * @retval Converted WDG interrupt interval
266 */
267 interrupt_interval_t wdg_convert_interrupt_interval_from_us(const uint32_t src_freq, uint32_t interval_us);
268
269 /**
270 * @brief Get Actual WDG Interrupt Interval in terms of microseconds
271 *
272 * @param [in] base WDG base address
273 * @param [in] src_freq WDG source clock frequency
274 * @return Converted WDG interrupt interval in terms of microseconds
275 */
276 uint64_t wdg_get_interrupt_interval_in_us(WDG_Type *base, const uint32_t src_freq);
277
278 /**
279 * @brief Get Actual WDG Reset Interval in terms of microseconds
280 *
281 * @param [in] base WDG base address
282 * @param [in] src_freq WDG source clock frequency
283 * @return Converted WDG total reset interval in terms of microseconds
284 */
285 uint64_t wdg_get_total_reset_interval_in_us(WDG_Type *base, const uint32_t src_freq);
286
287 #ifdef __cplusplus
288 }
289 #endif
290
291 /**
292 * @}
293 */
294
295 #endif /* HPM_WDG_DRV_H */
296