1 //*****************************************************************************
2 //
3 //! @file am_hal_wdt.h
4 //!
5 //! @brief Watchdog Timer
6 //!
7 //! @addtogroup wdt_4p WDT - Watchdog Timer Functionality
8 //! @ingroup apollo4p_hal
9 //! @{
10 //
11 //*****************************************************************************
12 
13 //*****************************************************************************
14 //
15 // Copyright (c) 2023, Ambiq Micro, Inc.
16 // All rights reserved.
17 //
18 // Redistribution and use in source and binary forms, with or without
19 // modification, are permitted provided that the following conditions are met:
20 //
21 // 1. Redistributions of source code must retain the above copyright notice,
22 // this list of conditions and the following disclaimer.
23 //
24 // 2. Redistributions in binary form must reproduce the above copyright
25 // notice, this list of conditions and the following disclaimer in the
26 // documentation and/or other materials provided with the distribution.
27 //
28 // 3. Neither the name of the copyright holder nor the names of its
29 // contributors may be used to endorse or promote products derived from this
30 // software without specific prior written permission.
31 //
32 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
33 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
34 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
35 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
36 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
37 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
38 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
39 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
40 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
41 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42 // POSSIBILITY OF SUCH DAMAGE.
43 //
44 // This is part of revision release_sdk_4_4_0-3c5977e664 of the AmbiqSuite Development Package.
45 //
46 //*****************************************************************************
47 #ifndef AM_HAL_WDT_H
48 #define AM_HAL_WDT_H
49 
50 #ifdef __cplusplus
51 extern "C"
52 {
53 #endif
54 
55 //*****************************************************************************
56 //
57 //! @brief Convenience macros for watchdog locking/restarting.
58 //! @name watchdog_macros
59 //! @{
60 //
61 //*****************************************************************************
62 #define AM_HAL_WDT_MCU_LOCK_KEY      WDT_LOCK_LOCK_KEYVALUE
63 #define AM_HAL_WDT_DSP0_LOCK_KEY     WDT_DSP0TLOCK_DSP0LOCK_KEYVALUE
64 #define AM_HAL_WDT_DSP1_LOCK_KEY     WDT_DSP1TLOCK_DSP1LOCK_KEYVALUE
65 
66 #define AM_HAL_WDT_MCU_RESTART_KEY   WDT_RSTRT_RSTRT_KEYVALUE
67 #define AM_HAL_WDT_DSP0_RESTART_KEY  WDT_DSP0RSTRT_DSP0RSTART_KEYVALUE
68 #define AM_HAL_WDT_DSP1_RESTART_KEY  WDT_DSP1RSTRT_DSP1RSTART_KEYVALUE
69 //! @}
70 
71 //*****************************************************************************
72 //
73 //! Enumeration used to select a watchdog timer.
74 //
75 //*****************************************************************************
76 typedef enum
77 {
78     AM_HAL_WDT_MCU,
79     AM_HAL_WDT_DSP0,
80     AM_HAL_WDT_DSP1,
81 }
82 am_hal_wdt_select_e;
83 
84 //*****************************************************************************
85 //
86 //! Enumeration used to select a watchdog clock source.
87 //
88 //*****************************************************************************
89 typedef enum
90 {
91     AM_HAL_WDT_OFF    = WDT_CFG_CLKSEL_OFF,
92     AM_HAL_WDT_128HZ  = WDT_CFG_CLKSEL_128HZ,
93     AM_HAL_WDT_16HZ   = WDT_CFG_CLKSEL_16HZ,
94     AM_HAL_WDT_1HZ    = WDT_CFG_CLKSEL_1HZ,
95     AM_HAL_WDT_1_16HZ = WDT_CFG_CLKSEL_1_16HZ,
96 }
97 am_hal_wdt_clock_select_e;
98 
99 //*****************************************************************************
100 //
101 //! Watchdog timer configuration structure.
102 //
103 //*****************************************************************************
104 typedef struct
105 {
106     //! Source clock for the watchdog timer.
107     am_hal_wdt_clock_select_e eClockSource;
108 
109     //! Generate a watchdog interrupt.
110     bool bInterruptEnable;
111 
112     //! Count value at which the watchdog timer will generate an interrupt.
113     uint32_t ui32InterruptValue;
114 
115     //! Generate a watchdog interrupt.
116     bool bResetEnable;
117 
118     //! Count value at which the watchdog timer with generate a reset.
119     uint32_t ui32ResetValue;
120 
121     //! If true, the MCU watchdog will generate a separate interrupt for the MCU
122     //! when a DSP watchdog issues a reset.
123     bool bAlertOnDSPReset;
124 }
125 am_hal_wdt_config_t;
126 
127 //*****************************************************************************
128 //
129 //! Watchdog timer dsp configuration structure.
130 //
131 //*****************************************************************************
132 typedef struct
133 {
134     //! Generate a watchdog interrupt.
135     bool bInterruptEnable;
136 
137     //! Count value at which the watchdog timer will generate an interrupt.
138     uint32_t ui32InterruptValue;
139 
140     //! Generate a watchdog interrupt.
141     bool bResetEnable;
142 
143     //! Count value at which the watchdog timer with generate a reset.
144     uint32_t ui32ResetValue;
145 
146     //! Reset this DSP's power module when the watchdog expires.
147     bool bPMResetEnable;
148 
149     //! Count value at which to generate a power manager reset.
150     uint32_t ui32PMResetValue;
151 }
152 am_hal_wdt_config_dsp_t;
153 
154 //*****************************************************************************
155 //
156 //!brief  WDT interrupts.
157 //! @name watchdog_interrupt_macros
158 //! @{
159 //
160 //*****************************************************************************
161 #define AM_HAL_WDT_INTERRUPT_DSP_RESET    WDT_WDTIEREN_DSPRESETINT_Msk
162 #define AM_HAL_WDT_INTERRUPT_MCU          WDT_WDTIEREN_WDTINT_Msk
163 #define AM_HAL_WDT_INTERRUPT_DSP0         WDT_DSP0IERSTAT_DSP0INT_Msk
164 #define AM_HAL_WDT_INTERRUPT_DSP1         WDT_DSP1IERSTAT_DSP1INT_Msk
165 //! @}
166 
167 //*****************************************************************************
168 //
169 //! @brief Configure the watchdog timer.
170 //!
171 //! @param eTimer selects the desired watchdog timer.
172 //! @param pvConfig is a pointer to a configuration structure for the timer.
173 //!
174 //! This function applies a configuration to the selected watchdog timer.
175 //!
176 //! @return WDT status code.
177 //
178 //*****************************************************************************
179 extern uint32_t am_hal_wdt_config(am_hal_wdt_select_e eTimer, void *pvConfig);
180 
181 //*****************************************************************************
182 //
183 //! @brief Enables the watchdog timer.
184 //!
185 //! @param eTimer selects the desired watchdog timer.
186 //! @param bLock can be used to lock the watchdog.
187 //!
188 //! This function will start the selected watchdog timer. If the \e bLock
189 //! parameter is set, for the correct watchdog instance, it will also activate
190 //! the LOCK register. Once a watchdog is enabled and locked, its configuration
191 //! cannot be changed until a device reset.
192 //!
193 //! @return WDT status code.
194 //
195 //*****************************************************************************
196 extern uint32_t am_hal_wdt_start(am_hal_wdt_select_e eTimer, bool bLock);
197 
198 //*****************************************************************************
199 //
200 //! @brief Disables the watchdog timer.
201 //!
202 //! @param eTimer selects the desired watchdog timer.
203 //!
204 //! This function will stop the selected watchdog. It will not work if the WDT
205 //! is already locked.
206 //!
207 //! @return WDT status code.
208 //
209 //*****************************************************************************
210 extern uint32_t am_hal_wdt_stop(am_hal_wdt_select_e eTimer);
211 
212 //*****************************************************************************
213 //
214 //! @brief Restart (pet/feed) the watchdgog
215 //!
216 //! @param eTimer selects the desired watchdog timer.
217 //!
218 //! This funtion forces the watchdog timer to start over from its beginning
219 //! value. The key value is supplied manually to help mitigate the risk of
220 //! accidental watchdog restarts due to runaway code.
221 //!
222 //! @return WDT status code.
223 //
224 //*****************************************************************************
225 extern uint32_t am_hal_wdt_restart(am_hal_wdt_select_e eTimer);
226 
227 //*****************************************************************************
228 //
229 //! @brief Reads the watchdog timer's current value.
230 //!
231 //! @param eTimer selects the desired watchdog timer.
232 //! @param pui32Value is the destination for the watchdog timer value.
233 //!
234 //! This function reads the current counter value for the selected timer.
235 //!
236 //! @return WDT status code.
237 //
238 //*****************************************************************************
239 extern uint32_t am_hal_wdt_read(am_hal_wdt_select_e eTimer, uint32_t *pui32Value);
240 
241 //*****************************************************************************
242 //
243 //! @brief Watchdog interrupt enable.
244 //!
245 //! @param eTimer selects the desired watchdog timer.
246 //! @param ui32InterruptMask is an OR'ed together set of interrupts.
247 //!
248 //! Enables a set of interrupts for a specific watchdog TIMER.
249 //!
250 //! @note Each WDT instance has its own interrupt register. This function
251 //! cannot access more than one register at once. If you want to interact with
252 //! more than one interrupt, you will need to call this function more than
253 //! once.
254 //!
255 //! For example:
256 //!
257 //! @code
258 //! // WRONG (The DSP0 interrupt doesn't belong to the MCU watchdog)
259 //! am_hal_wdt_interrupt_enable(AM_HAL_WDT_MCU,
260 //!                             (AM_HAL_WDT_INTERRUPT_MCU |
261 //!                              AM_HAL_WDT_INTERRUPT_DSP_RESET |
262 //!                              AM_HAL_WDT_INTERRUPT_DSP0));
263 //!
264 //! // RIGHT
265 //! am_hal_wdt_interrupt_enable(AM_HAL_WDT_MCU,
266 //!                             (AM_HAL_WDT_INTERRUPT_MCU |
267 //!                              AM_HAL_WDT_INTERRUPT_DSP_RESET));
268 //!
269 //! am_hal_wdt_interrupt_enable(AM_HAL_WDT_DSP0,
270 //!                             AM_HAL_WDT_INTERRUPT_DSP0);
271 //!
272 //! @endcode
273 //!
274 //!
275 //! @return WDT status code.
276 //
277 //*****************************************************************************
278 extern uint32_t am_hal_wdt_interrupt_enable(am_hal_wdt_select_e eTimer,
279                                             uint32_t ui32InterruptMask);
280 
281 //*****************************************************************************
282 //
283 //! @brief Check to see which WDT interrupts are enabled.
284 //!
285 //! @param eTimer selects the desired watchdog timer.
286 //! @param pui32InterruptMask returns the set of enabled interrupts for the
287 //! selected timer.
288 //!
289 //! This function returns the set of enabled interrupts for a specific watchdog
290 //! timer.
291 //!
292 //! @return WDT status code.
293 //
294 //*****************************************************************************
295 extern uint32_t am_hal_wdt_interrupt_enable_get(am_hal_wdt_select_e eTimer,
296                                                 uint32_t *pui32InterruptMask);
297 
298 //*****************************************************************************
299 //
300 //! @brief Disable a WDT interrupt.
301 //!
302 //! @param eTimer selects the desired watchdog timer.
303 //! @param ui32InterruptMask is an OR'ed together set of interrupts to disable.
304 //!
305 //! This function disables WDT interrupts.
306 //!
307 //! @return WDT status code.
308 //
309 //*****************************************************************************
310 extern uint32_t am_hal_wdt_interrupt_disable(am_hal_wdt_select_e eTimer,
311                                              uint32_t ui32InterruptMask);
312 
313 //*****************************************************************************
314 //
315 //! @brief Read the WDT interrupt status.
316 //!
317 //! @param eTimer selects the desired watchdog timer.
318 //!
319 //! @param pui32InterruptMask returns the set of active interrupts
320 //!
321 //! @param bEnabledOnly will change ui32Interrupt mask to only show enabled
322 //!        interrupts
323 //!
324 //! This function reads the WDT interrupt status.
325 //!
326 //! @return WDT status code.
327 //
328 //*****************************************************************************
329 extern uint32_t am_hal_wdt_interrupt_status_get(am_hal_wdt_select_e eTimer,
330                                                 uint32_t *pui32InterruptMask,
331                                                 bool bEnabledOnly);
332 
333 //*****************************************************************************
334 //
335 //! @brief Clears the WDT interrupt.
336 //!
337 //! @param eTimer selects the desired watchdog timer.
338 //! @param ui32InterruptMask is an OR'ed together set of interrupts.
339 //!
340 //! Clears the WDT interrupt status.
341 //!
342 //! @return WDT status code.
343 //
344 //*****************************************************************************
345 extern uint32_t am_hal_wdt_interrupt_clear(am_hal_wdt_select_e eTimer,
346                                            uint32_t ui32InterruptMask);
347 
348 //*****************************************************************************
349 //
350 //! @brief Sets a WDT interrupt.
351 //!
352 //! @param eTimer selects the desired watchdog timer.
353 //! @param ui32InterruptMask is an OR'ed together set of interrupts to activate.
354 //!
355 //! Sets a WDT interrupt directly through software.
356 //!
357 //! @return WDT status code.
358 //
359 //*****************************************************************************
360 extern uint32_t am_hal_wdt_interrupt_set(am_hal_wdt_select_e eTimer,
361                                          uint32_t ui32InterruptMask);
362 
363 #ifdef __cplusplus
364 }
365 #endif
366 
367 #endif // AM_HAL_WDT_H
368 
369 //*****************************************************************************
370 //
371 // End Doxygen group.
372 //! @}
373 //
374 //*****************************************************************************
375 
376