• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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