1 /******************************************************************************
2 *  Filename:       wdt.h
3 *  Revised:        2015-11-16 19:41:47 +0100 (Mon, 16 Nov 2015)
4 *  Revision:       45094
5 *
6 *  Description:    Defines and prototypes for the Watchdog Timer.
7 *
8 *  Copyright (c) 2015, Texas Instruments Incorporated
9 *  All rights reserved.
10 *
11 *  Redistribution and use in source and binary forms, with or without
12 *  modification, are permitted provided that the following conditions are met:
13 *
14 *  1) Redistributions of source code must retain the above copyright notice,
15 *     this list of conditions and the following disclaimer.
16 *
17 *  2) Redistributions in binary form must reproduce the above copyright notice,
18 *     this list of conditions and the following disclaimer in the documentation
19 *     and/or other materials provided with the distribution.
20 *
21 *  3) Neither the name of the ORGANIZATION nor the names of its contributors may
22 *     be used to endorse or promote products derived from this software without
23 *     specific prior written permission.
24 *
25 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
26 *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
29 *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30 *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31 *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32 *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33 *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34 *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35 *  POSSIBILITY OF SUCH DAMAGE.
36 *
37 ******************************************************************************/
38 
39 //*****************************************************************************
40 //
41 //! \addtogroup peripheral_group
42 //! @{
43 //! \addtogroup wdt_api
44 //! @{
45 //
46 //*****************************************************************************
47 
48 #ifndef __WDT_H__
49 #define __WDT_H__
50 
51 //*****************************************************************************
52 //
53 // If building with a C++ compiler, make all of the definitions in this header
54 // have a C binding.
55 //
56 //*****************************************************************************
57 #ifdef __cplusplus
58 extern "C"
59 {
60 #endif
61 
62 #include <stdbool.h>
63 #include <stdint.h>
64 #include <inc/hw_types.h>
65 #include <inc/hw_ints.h>
66 #include <inc/hw_memmap.h>
67 #include <inc/hw_wdt.h>
68 #include <driverlib/debug.h>
69 #include <driverlib/interrupt.h>
70 
71 //*****************************************************************************
72 //
73 // The following are defines for the bit fields in the WDT_O_LOCK register.
74 //
75 //*****************************************************************************
76 #define WATCHDOG_LOCK_UNLOCKED       0x00000000  // Unlocked
77 #define WATCHDOG_LOCK_LOCKED         0x00000001  // Locked
78 #define WATCHDOG_LOCK_UNLOCK         0x1ACCE551  // Unlocks the Watchdog Timer
79 
80 //*****************************************************************************
81 //
82 // The following are defines for the bit fields in the WDT_ISR, WDT_RIS, and
83 // WDT_MIS registers.
84 //
85 //*****************************************************************************
86 #define WATCHDOG_INT_TIMEOUT         0x00000001  // Watchdog timer expired
87 
88 //*****************************************************************************
89 //
90 // The type of interrupt that can be generated by the watchdog.
91 //
92 //*****************************************************************************
93 #define WATCHDOG_INT_TYPE_INT   0x00000000
94 #define WATCHDOG_INT_TYPE_NMI   0x00000004
95 
96 //*****************************************************************************
97 //
98 // API Functions and prototypes
99 //
100 //*****************************************************************************
101 
102 //*****************************************************************************
103 //
104 //! \brief Determines if the watchdog timer is enabled.
105 //!
106 //! This function checks to see if the watchdog timer is enabled.
107 //!
108 //! \return Returns status of Watchdog Timer:
109 //! - \c true  : Watchdog timer is enabled.
110 //! - \c false : Watchdog timer is disabled.
111 //
112 //*****************************************************************************
113 __STATIC_INLINE bool
WatchdogRunning(void)114 WatchdogRunning(void)
115 {
116     //
117     // See if the watchdog timer module is enabled, and return.
118     //
119     return((HWREG(WDT_BASE + WDT_O_CTL) & WDT_CTL_INTEN) ? true : false);
120 }
121 
122 //*****************************************************************************
123 //
124 //! \brief Enables the watchdog timer.
125 //!
126 //! This function enables the watchdog timer counter and interrupt.
127 //!
128 //! Once enabled, the watchdog interrupt can only be disabled by a hardware reset.
129 //!
130 //! \note This function has no effect if the watchdog timer has been locked.
131 //!
132 //! \return None
133 //!
134 //! \sa \ref WatchdogLock(), \ref WatchdogUnlock()
135 //
136 //*****************************************************************************
137 __STATIC_INLINE void
WatchdogEnable(void)138 WatchdogEnable(void)
139 {
140     // Enable the watchdog timer module.
141     HWREGBITW(WDT_BASE + WDT_O_CTL, WDT_CTL_INTEN_BITN) = 1;
142 }
143 
144 //*****************************************************************************
145 //
146 //! \brief Enables the watchdog timer reset.
147 //!
148 //! This function enables the capability of the watchdog timer to issue a reset
149 //! to the processor after a second timeout condition.
150 //!
151 //! \note This function has no effect if the watchdog timer has been locked.
152 //!
153 //! \return None
154 //!
155 //! \sa \ref WatchdogLock(), \ref WatchdogUnlock()
156 //
157 //*****************************************************************************
158 __STATIC_INLINE void
WatchdogResetEnable(void)159 WatchdogResetEnable(void)
160 {
161     // Enable the watchdog reset.
162     HWREGBITW(WDT_BASE + WDT_O_CTL, WDT_CTL_RESEN_BITN) = 1;
163 }
164 
165 //*****************************************************************************
166 //
167 //! \brief Disables the watchdog timer reset.
168 //!
169 //! This function disables the capability of the watchdog timer to issue a
170 //! reset to the processor after a second timeout condition.
171 //!
172 //! \note This function has no effect if the watchdog timer has been locked.
173 //!
174 //! \return None
175 //!
176 //! \sa \ref WatchdogLock(), \ref WatchdogUnlock()
177 //
178 //*****************************************************************************
179 __STATIC_INLINE void
WatchdogResetDisable(void)180 WatchdogResetDisable(void)
181 {
182     // Disable the watchdog reset.
183     HWREGBITW(WDT_BASE + WDT_O_CTL, WDT_CTL_RESEN_BITN) = 0;
184 }
185 
186 //*****************************************************************************
187 //
188 //! \brief Enables the watchdog timer lock mechanism.
189 //!
190 //! This function locks out write access to the watchdog timer configuration
191 //! registers.
192 //!
193 //! \return None
194 //
195 //*****************************************************************************
196 __STATIC_INLINE void
WatchdogLock(void)197 WatchdogLock(void)
198 {
199     //
200     // Lock out watchdog register writes. Writing anything to the WDT_O_LOCK
201     // register causes the lock to go into effect.
202     //
203     HWREG(WDT_BASE + WDT_O_LOCK) = WATCHDOG_LOCK_LOCKED;
204 }
205 
206 //*****************************************************************************
207 //
208 //! \brief Disables the watchdog timer lock mechanism.
209 //!
210 //! This function enables write access to the watchdog timer configuration
211 //! registers.
212 //!
213 //! \return None
214 //
215 //*****************************************************************************
216 __STATIC_INLINE void
WatchdogUnlock(void)217 WatchdogUnlock(void)
218 {
219     //
220     // Unlock watchdog register writes.
221     //
222     HWREG(WDT_BASE + WDT_O_LOCK) = WATCHDOG_LOCK_UNLOCK;
223 }
224 
225 //*****************************************************************************
226 //
227 //! \brief Gets the state of the watchdog timer lock mechanism.
228 //!
229 //! This function returns the lock state of the watchdog timer registers.
230 //!
231 //! \return Returns state of lock mechanism.
232 //! - \c true  : Watchdog timer registers are locked.
233 //! - \c false : Registers are not locked.
234 //
235 //*****************************************************************************
236 __STATIC_INLINE bool
WatchdogLockState(void)237 WatchdogLockState(void)
238 {
239     //
240     // Get the lock state.
241     //
242     return((HWREG(WDT_BASE + WDT_O_LOCK) == WATCHDOG_LOCK_LOCKED) ?
243                true : false);
244 }
245 
246 //*****************************************************************************
247 //
248 //! \brief Sets the watchdog timer reload value.
249 //!
250 //! This function configures the value to load into the watchdog timer when the
251 //! count reaches zero for the first time; if the watchdog timer is running
252 //! when this function is called, then the value is immediately loaded into the
253 //! watchdog timer counter.  If the \c ui32LoadVal parameter is 0, then an
254 //! interrupt is immediately generated.
255 //!
256 //! \note This function has no effect if the watchdog timer has been locked.
257 //!
258 //! \param ui32LoadVal is the load value for the watchdog timer.
259 //!
260 //! \return None
261 //!
262 //! \sa \ref WatchdogLock(), \ref WatchdogUnlock(), \ref WatchdogReloadGet()
263 //
264 //*****************************************************************************
265 __STATIC_INLINE void
WatchdogReloadSet(uint32_t ui32LoadVal)266 WatchdogReloadSet(uint32_t ui32LoadVal)
267 {
268     //
269     // Set the load register.
270     //
271     HWREG(WDT_BASE + WDT_O_LOAD) = ui32LoadVal;
272 }
273 
274 //*****************************************************************************
275 //
276 //! \brief Gets the watchdog timer reload value.
277 //!
278 //! This function gets the value that is loaded into the watchdog timer when
279 //! the count reaches zero for the first time.
280 //!
281 //! \return None
282 //!
283 //! \sa \ref WatchdogReloadSet()
284 //
285 //*****************************************************************************
286 __STATIC_INLINE uint32_t
WatchdogReloadGet(void)287 WatchdogReloadGet(void)
288 {
289     //
290     // Get the load register.
291     //
292     return(HWREG(WDT_BASE + WDT_O_LOAD));
293 }
294 
295 //*****************************************************************************
296 //
297 //! \brief Gets the current watchdog timer value.
298 //!
299 //! This function reads the current value of the watchdog timer.
300 //!
301 //! \return Returns the current value of the watchdog timer.
302 //
303 //*****************************************************************************
304 __STATIC_INLINE uint32_t
WatchdogValueGet(void)305 WatchdogValueGet(void)
306 {
307     //
308     // Get the current watchdog timer register value.
309     //
310     return(HWREG(WDT_BASE + WDT_O_VALUE));
311 }
312 
313 //*****************************************************************************
314 //
315 //! \brief Registers an interrupt handler for the watchdog timer interrupt.
316 //!
317 //! This function does the actual registering of the interrupt handler. This
318 //! function also enables the global interrupt in the interrupt controller; the
319 //! watchdog timer interrupt must be enabled via \ref WatchdogIntEnable(). It is the
320 //! interrupt handler's responsibility to clear the interrupt source via
321 //! \ref WatchdogIntClear().
322 //!
323 //! \note This function registers the standard watchdog interrupt handler. To
324 //! register the NMI watchdog handler, use \ref IntRegister() to register the
325 //! handler for the \b INT_NMI_FAULT interrupt.
326 //!
327 //! \param pfnHandler is a pointer to the function to be called when the
328 //! watchdog timer interrupt occurs.
329 //!
330 //! \return None
331 //!
332 //! \sa \ref IntRegister() for important information about registering interrupt
333 //! handlers.
334 //
335 //*****************************************************************************
336 __STATIC_INLINE void
WatchdogIntRegister(void (* pfnHandler)(void))337 WatchdogIntRegister(void (*pfnHandler)(void))
338 {
339     //
340     // Register the interrupt handler.
341     //
342     IntRegister(INT_WDT_IRQ, pfnHandler);
343 
344     //
345     // Enable the watchdog timer interrupt.
346     //
347     IntEnable(INT_WDT_IRQ);
348 }
349 
350 //*****************************************************************************
351 //
352 //! \brief Unregisters an interrupt handler for the watchdog timer interrupt.
353 //!
354 //! This function does the actual unregistering of the interrupt handler. This
355 //! function clears the handler to be called when a watchdog timer interrupt
356 //! occurs. This function also masks off the interrupt in the interrupt
357 //! controller so that the interrupt handler no longer is called.
358 //!
359 //! \note This function registers the standard watchdog interrupt handler. To
360 //! register the NMI watchdog handler, use \ref IntRegister() to register the
361 //! handler for the \b INT_NMI_FAULT interrupt.
362 //!
363 //! \return None
364 //!
365 //! \sa \ref IntRegister() for important information about registering interrupt
366 //! handlers.
367 //
368 //*****************************************************************************
369 __STATIC_INLINE void
WatchdogIntUnregister(void)370 WatchdogIntUnregister(void)
371 {
372     //
373     // Disable the interrupt.
374     //
375     IntDisable(INT_WDT_IRQ);
376 
377     //
378     // Unregister the interrupt handler.
379     //
380     IntUnregister(INT_WDT_IRQ);
381 }
382 
383 //*****************************************************************************
384 //
385 //! \brief Enables the watchdog timer.
386 //!
387 //! This function enables the watchdog timer interrupt by calling \ref WatchdogEnable().
388 //!
389 //! \return None
390 //!
391 //! \sa \ref WatchdogEnable()
392 //
393 //*****************************************************************************
394 __STATIC_INLINE void
WatchdogIntEnable(void)395 WatchdogIntEnable(void)
396 {
397     // Enable the Watchdog interrupt.
398     WatchdogEnable();
399 }
400 
401 //*****************************************************************************
402 //
403 //! \brief Gets the current watchdog timer interrupt status.
404 //!
405 //! This function returns the interrupt status for the watchdog timer module.
406 //!
407 //! \return Returns the interrupt status.
408 //! - 1 : Watchdog time-out has occurred.
409 //! - 0 : Watchdog time-out has not occurred.
410 //!
411 //! \sa \ref WatchdogIntClear();
412 //
413 //*****************************************************************************
414 __STATIC_INLINE uint32_t
WatchdogIntStatus(void)415 WatchdogIntStatus(void)
416 {
417     //
418     // Return either the interrupt status or the raw interrupt status as
419     // requested.
420     //
421     return(HWREG(WDT_BASE + WDT_O_RIS));
422 }
423 
424 //*****************************************************************************
425 //
426 //! \brief Clears the watchdog timer interrupt.
427 //!
428 //! The watchdog timer interrupt source is cleared, so that it no longer
429 //! asserts.
430 //!
431 //! \note Due to write buffers and synchronizers in the system it may take several
432 //! clock cycles from a register write clearing an event in a module and until the
433 //! event is actually cleared in the NVIC of the system CPU. It is recommended to
434 //! clear the event source early in the interrupt service routine (ISR) to allow
435 //! the event clear to propagate to the NVIC before returning from the ISR.
436 //! At the same time, an early event clear allows new events of the same type to be
437 //! pended instead of ignored if the event is cleared later in the ISR.
438 //! It is the responsibility of the programmer to make sure that enough time has passed
439 //! before returning from the ISR to avoid false re-triggering of the cleared event.
440 //! A simple, although not necessarily optimal, way of clearing an event before
441 //! returning from the ISR is:
442 //! -# Write to clear event (interrupt source). (buffered write)
443 //! -# Dummy read from the event source module. (making sure the write has propagated)
444 //! -# Wait two system CPU clock cycles (user code or two NOPs). (allowing cleared event to propagate through any synchronizers)
445 //!
446 //! \return None
447 //
448 //*****************************************************************************
449 __STATIC_INLINE void
WatchdogIntClear(void)450 WatchdogIntClear(void)
451 {
452     //
453     // Clear the interrupt source.
454     //
455     HWREG(WDT_BASE + WDT_O_ICR) = WATCHDOG_INT_TIMEOUT;
456 }
457 
458 //*****************************************************************************
459 //
460 //! \brief Sets the type of interrupt generated by the watchdog.
461 //!
462 //! This function sets the type of interrupt that is generated if the watchdog
463 //! timer expires.
464 //!
465 //! When configured to generate an NMI, the watchdog interrupt must still be
466 //! enabled with \ref WatchdogIntEnable(), and it must still be cleared inside the
467 //! NMI handler with \ref WatchdogIntClear().
468 //!
469 //! \param ui32Type is the type of interrupt to generate.
470 //! - \ref WATCHDOG_INT_TYPE_INT : Generate a standard interrupt (default).
471 //! - \ref WATCHDOG_INT_TYPE_NMI : Generate a non-maskable interrupt (NMI).
472 //!
473 //! \return None
474 //
475 //*****************************************************************************
476 __STATIC_INLINE void
WatchdogIntTypeSet(uint32_t ui32Type)477 WatchdogIntTypeSet(uint32_t ui32Type)
478 {
479     // Check the arguments.
480     ASSERT((ui32Type == WATCHDOG_INT_TYPE_INT) ||
481            (ui32Type == WATCHDOG_INT_TYPE_NMI));
482 
483     // Set the interrupt type.
484     HWREGBITW(WDT_BASE + WDT_O_CTL, WDT_CTL_INTTYPE_BITN) = (ui32Type == WATCHDOG_INT_TYPE_INT)? 0 : 1;
485 }
486 
487 //*****************************************************************************
488 //
489 //! \brief Enables stalling of the watchdog timer during debug events.
490 //!
491 //! This function allows the watchdog timer to stop counting when the processor
492 //! is stopped by the debugger. By doing so, the watchdog is prevented from
493 //! expiring and resetting the system (if reset is enabled). The watchdog instead expires
494 //! after the appropriate number of processor cycles have been executed while
495 //! debugging (or at the appropriate time after the processor has been
496 //! restarted).
497 //!
498 //! \return None
499 //
500 //*****************************************************************************
501 __STATIC_INLINE void
WatchdogStallEnable(void)502 WatchdogStallEnable(void)
503 {
504     // Enable timer stalling.
505     HWREGBITW(WDT_BASE + WDT_O_TEST, WDT_TEST_STALL_BITN) = 1;
506 }
507 
508 //*****************************************************************************
509 //
510 //! \brief Disables stalling of the watchdog timer during debug events.
511 //!
512 //! This function disables the debug mode stall of the watchdog timer. By
513 //! doing so, the watchdog timer continues to count regardless of the processor
514 //! debug state.
515 //!
516 //! \return None
517 //
518 //*****************************************************************************
519 __STATIC_INLINE void
WatchdogStallDisable(void)520 WatchdogStallDisable(void)
521 {
522     // Disable timer stalling.
523     HWREGBITW(WDT_BASE + WDT_O_TEST, WDT_TEST_STALL_BITN) = 0;
524 }
525 
526 //*****************************************************************************
527 //
528 // Mark the end of the C bindings section for C++ compilers.
529 //
530 //*****************************************************************************
531 #ifdef __cplusplus
532 }
533 #endif
534 
535 #endif // __WDT_H__
536 
537 //*****************************************************************************
538 //
539 //! Close the Doxygen group.
540 //! @}
541 //! @}
542 //
543 //*****************************************************************************
544