1 //*****************************************************************************
2 //
3 // watchdog.c - Driver for the Watchdog Timer Module.
4 //
5 // Copyright (c) 2005-2012 Texas Instruments Incorporated.  All rights reserved.
6 // Software License Agreement
7 //
8 //   Redistribution and use in source and binary forms, with or without
9 //   modification, are permitted provided that the following conditions
10 //   are met:
11 //
12 //   Redistributions of source code must retain the above copyright
13 //   notice, this list of conditions and the following disclaimer.
14 //
15 //   Redistributions in binary form must reproduce the above copyright
16 //   notice, this list of conditions and the following disclaimer in the
17 //   documentation and/or other materials provided with the
18 //   distribution.
19 //
20 //   Neither the name of Texas Instruments Incorporated nor the names of
21 //   its contributors may be used to endorse or promote products derived
22 //   from this software without specific prior written permission.
23 //
24 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
27 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
28 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
29 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
30 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
31 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
32 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
34 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 //
36 // This is part of revision 9453 of the Stellaris Peripheral Driver Library.
37 //
38 //*****************************************************************************
39 
40 //*****************************************************************************
41 //
42 //! \addtogroup watchdog_api
43 //! @{
44 //
45 //*****************************************************************************
46 
47 #include "inc/hw_ints.h"
48 #include "inc/hw_memmap.h"
49 #include "inc/hw_types.h"
50 #include "inc/hw_watchdog.h"
51 #include "driverlib/debug.h"
52 #include "driverlib/interrupt.h"
53 #include "driverlib/watchdog.h"
54 
55 //*****************************************************************************
56 //
57 //! Determines if the watchdog timer is enabled.
58 //!
59 //! \param ulBase is the base address of the watchdog timer module.
60 //!
61 //! This function checks to see if the watchdog timer is enabled.
62 //!
63 //! \return Returns \b true if the watchdog timer is enabled and \b false
64 //! if it is not.
65 //
66 //*****************************************************************************
67 tBoolean
WatchdogRunning(unsigned long ulBase)68 WatchdogRunning(unsigned long ulBase)
69 {
70     //
71     // Check the arguments.
72     //
73     ASSERT((ulBase == WATCHDOG0_BASE) || (ulBase == WATCHDOG1_BASE));
74 
75     //
76     // See if the watchdog timer module is enabled, and return.
77     //
78     return(HWREG(ulBase + WDT_O_CTL) & WDT_CTL_INTEN);
79 }
80 
81 //*****************************************************************************
82 //
83 //! Enables the watchdog timer.
84 //!
85 //! \param ulBase is the base address of the watchdog timer module.
86 //!
87 //! This function enables the watchdog timer counter and interrupt.
88 //!
89 //! \note This function has no effect if the watchdog timer has been locked.
90 //!
91 //! \sa WatchdogLock(), WatchdogUnlock()
92 //!
93 //! \return None.
94 //
95 //*****************************************************************************
96 void
WatchdogEnable(unsigned long ulBase)97 WatchdogEnable(unsigned long ulBase)
98 {
99     //
100     // Check the arguments.
101     //
102     ASSERT((ulBase == WATCHDOG0_BASE) || (ulBase == WATCHDOG1_BASE));
103 
104     //
105     // Enable the watchdog timer module.
106     //
107     HWREG(ulBase + WDT_O_CTL) |= WDT_CTL_INTEN;
108 }
109 
110 //*****************************************************************************
111 //
112 //! Enables the watchdog timer reset.
113 //!
114 //! \param ulBase is the base address of the watchdog timer module.
115 //!
116 //! This function enables the capability of the watchdog timer to issue a reset
117 //! to the processor after a second timeout condition.
118 //!
119 //! \note This function has no effect if the watchdog timer has been locked.
120 //!
121 //! \sa WatchdogLock(), WatchdogUnlock()
122 //!
123 //! \return None.
124 //
125 //*****************************************************************************
126 void
WatchdogResetEnable(unsigned long ulBase)127 WatchdogResetEnable(unsigned long ulBase)
128 {
129     //
130     // Check the arguments.
131     //
132     ASSERT((ulBase == WATCHDOG0_BASE) || (ulBase == WATCHDOG1_BASE));
133 
134     //
135     // Enable the watchdog reset.
136     //
137     HWREG(ulBase + WDT_O_CTL) |= WDT_CTL_RESEN;
138 }
139 
140 //*****************************************************************************
141 //
142 //! Disables the watchdog timer reset.
143 //!
144 //! \param ulBase is the base address of the watchdog timer module.
145 //!
146 //! This function disables the capability of the watchdog timer to issue a
147 //! reset to the processor after a second timeout condition.
148 //!
149 //! \note This function has no effect if the watchdog timer has been locked.
150 //!
151 //! \sa WatchdogLock(), WatchdogUnlock()
152 //!
153 //! \return None.
154 //
155 //*****************************************************************************
156 void
WatchdogResetDisable(unsigned long ulBase)157 WatchdogResetDisable(unsigned long ulBase)
158 {
159     //
160     // Check the arguments.
161     //
162     ASSERT((ulBase == WATCHDOG0_BASE) || (ulBase == WATCHDOG1_BASE));
163 
164     //
165     // Disable the watchdog reset.
166     //
167     HWREG(ulBase + WDT_O_CTL) &= ~(WDT_CTL_RESEN);
168 }
169 
170 //*****************************************************************************
171 //
172 //! Enables the watchdog timer lock mechanism.
173 //!
174 //! \param ulBase is the base address of the watchdog timer module.
175 //!
176 //! This function locks out write access to the watchdog timer configuration
177 //! registers.
178 //!
179 //! \return None.
180 //
181 //*****************************************************************************
182 void
WatchdogLock(unsigned long ulBase)183 WatchdogLock(unsigned long ulBase)
184 {
185     //
186     // Check the arguments.
187     //
188     ASSERT((ulBase == WATCHDOG0_BASE) || (ulBase == WATCHDOG1_BASE));
189 
190     //
191     // Lock out watchdog register writes.  Writing anything to the WDT_O_LOCK
192     // register causes the lock to go into effect.
193     //
194     HWREG(ulBase + WDT_O_LOCK) = WDT_LOCK_LOCKED;
195 }
196 
197 //*****************************************************************************
198 //
199 //! Disables the watchdog timer lock mechanism.
200 //!
201 //! \param ulBase is the base address of the watchdog timer module.
202 //!
203 //! This function enables write access to the watchdog timer configuration
204 //! registers.
205 //!
206 //! \return None.
207 //
208 //*****************************************************************************
209 void
WatchdogUnlock(unsigned long ulBase)210 WatchdogUnlock(unsigned long ulBase)
211 {
212     //
213     // Check the arguments.
214     //
215     ASSERT((ulBase == WATCHDOG0_BASE) || (ulBase == WATCHDOG1_BASE));
216 
217     //
218     // Unlock watchdog register writes.
219     //
220     HWREG(ulBase + WDT_O_LOCK) = WDT_LOCK_UNLOCK;
221 }
222 
223 //*****************************************************************************
224 //
225 //! Gets the state of the watchdog timer lock mechanism.
226 //!
227 //! \param ulBase is the base address of the watchdog timer module.
228 //!
229 //! This function returns the lock state of the watchdog timer registers.
230 //!
231 //! \return Returns \b true if the watchdog timer registers are locked, and
232 //! \b false if they are not locked.
233 //
234 //*****************************************************************************
235 tBoolean
WatchdogLockState(unsigned long ulBase)236 WatchdogLockState(unsigned long ulBase)
237 {
238     //
239     // Check the arguments.
240     //
241     ASSERT((ulBase == WATCHDOG0_BASE) || (ulBase == WATCHDOG1_BASE));
242 
243     //
244     // Get the lock state.
245     //
246     return((HWREG(ulBase + WDT_O_LOCK) == WDT_LOCK_LOCKED) ? true : false);
247 }
248 
249 //*****************************************************************************
250 //
251 //! Sets the watchdog timer reload value.
252 //!
253 //! \param ulBase is the base address of the watchdog timer module.
254 //! \param ulLoadVal is the load value for the watchdog timer.
255 //!
256 //! This function configures the value to load into the watchdog timer when the
257 //! count reaches zero for the first time; if the watchdog timer is running
258 //! when this function is called, then the value is immediately loaded into the
259 //! watchdog timer counter.  If the \e ulLoadVal parameter is 0, then an
260 //! interrupt is immediately generated.
261 //!
262 //! \note This function has no effect if the watchdog timer has been locked.
263 //!
264 //! \sa WatchdogLock(), WatchdogUnlock(), WatchdogReloadGet()
265 //!
266 //! \return None.
267 //
268 //*****************************************************************************
269 void
WatchdogReloadSet(unsigned long ulBase,unsigned long ulLoadVal)270 WatchdogReloadSet(unsigned long ulBase, unsigned long ulLoadVal)
271 {
272     //
273     // Check the arguments.
274     //
275     ASSERT((ulBase == WATCHDOG0_BASE) || (ulBase == WATCHDOG1_BASE));
276 
277     //
278     // Set the load register.
279     //
280     HWREG(ulBase + WDT_O_LOAD) = ulLoadVal;
281 }
282 
283 //*****************************************************************************
284 //
285 //! Gets the watchdog timer reload value.
286 //!
287 //! \param ulBase is the base address of the watchdog timer module.
288 //!
289 //! This function gets the value that is loaded into the watchdog timer when
290 //! the count reaches zero for the first time.
291 //!
292 //! \sa WatchdogReloadSet()
293 //!
294 //! \return None.
295 //
296 //*****************************************************************************
297 unsigned long
WatchdogReloadGet(unsigned long ulBase)298 WatchdogReloadGet(unsigned long ulBase)
299 {
300     //
301     // Check the arguments.
302     //
303     ASSERT((ulBase == WATCHDOG0_BASE) || (ulBase == WATCHDOG1_BASE));
304 
305     //
306     // Get the load register.
307     //
308     return(HWREG(ulBase + WDT_O_LOAD));
309 }
310 
311 //*****************************************************************************
312 //
313 //! Gets the current watchdog timer value.
314 //!
315 //! \param ulBase is the base address of the watchdog timer module.
316 //!
317 //! This function reads the current value of the watchdog timer.
318 //!
319 //! \return Returns the current value of the watchdog timer.
320 //
321 //*****************************************************************************
322 unsigned long
WatchdogValueGet(unsigned long ulBase)323 WatchdogValueGet(unsigned long ulBase)
324 {
325     //
326     // Check the arguments.
327     //
328     ASSERT((ulBase == WATCHDOG0_BASE) || (ulBase == WATCHDOG1_BASE));
329 
330     //
331     // Get the current watchdog timer register value.
332     //
333     return(HWREG(ulBase + WDT_O_VALUE));
334 }
335 
336 //*****************************************************************************
337 //
338 //! Registers an interrupt handler for the watchdog timer interrupt.
339 //!
340 //! \param ulBase is the base address of the watchdog timer module.
341 //! \param pfnHandler is a pointer to the function to be called when the
342 //! watchdog timer interrupt occurs.
343 //!
344 //! This function does the actual registering of the interrupt handler.  This
345 //! function also enables the global interrupt in the interrupt controller; the
346 //! watchdog timer interrupt must be enabled via WatchdogEnable().  It is the
347 //! interrupt handler's responsibility to clear the interrupt source via
348 //! WatchdogIntClear().
349 //!
350 //! \sa IntRegister() for important information about registering interrupt
351 //! handlers.
352 //!
353 //! \note For parts with a watchdog timer module that has the ability to
354 //! generate an NMI instead of a standard interrupt, this function registers
355 //! the standard watchdog interrupt handler.  To register the NMI watchdog
356 //! handler, use IntRegister() to register the handler for the
357 //! \b FAULT_NMI interrupt.
358 //!
359 //! \return None.
360 //
361 //*****************************************************************************
362 void
WatchdogIntRegister(unsigned long ulBase,void (* pfnHandler)(void))363 WatchdogIntRegister(unsigned long ulBase, void (*pfnHandler)(void))
364 {
365     //
366     // Check the arguments.
367     //
368     ASSERT((ulBase == WATCHDOG0_BASE) || (ulBase == WATCHDOG1_BASE));
369 
370     //
371     // Register the interrupt handler.
372     //
373     IntRegister(INT_WATCHDOG, pfnHandler);
374 
375     //
376     // Enable the watchdog timer interrupt.
377     //
378     IntEnable(INT_WATCHDOG);
379 }
380 
381 //*****************************************************************************
382 //
383 //! Unregisters an interrupt handler for the watchdog timer interrupt.
384 //!
385 //! \param ulBase is the base address of the watchdog timer module.
386 //!
387 //! This function does the actual unregistering of the interrupt handler.  This
388 //! function clears the handler to be called when a watchdog timer interrupt
389 //! occurs.  This function also masks off the interrupt in the interrupt
390 //! controller so that the interrupt handler no longer is called.
391 //!
392 //! \sa IntRegister() for important information about registering interrupt
393 //! handlers.
394 //!
395 //! \note For parts with a watchdog timer module that has the ability to
396 //! generate an NMI instead of a standard interrupt, this function unregisters
397 //! the standard watchdog interrupt handler.  To unregister the NMI watchdog
398 //! handler, use IntUnregister() to unregister the handler for the
399 //! \b FAULT_NMI interrupt.
400 //!
401 //! \return None.
402 //
403 //*****************************************************************************
404 void
WatchdogIntUnregister(unsigned long ulBase)405 WatchdogIntUnregister(unsigned long ulBase)
406 {
407     //
408     // Check the arguments.
409     //
410     ASSERT((ulBase == WATCHDOG0_BASE) || (ulBase == WATCHDOG1_BASE));
411 
412     //
413     // Disable the interrupt.
414     //
415     IntDisable(INT_WATCHDOG);
416 
417     //
418     // Unregister the interrupt handler.
419     //
420     IntUnregister(INT_WATCHDOG);
421 }
422 
423 //*****************************************************************************
424 //
425 //! Enables the watchdog timer interrupt.
426 //!
427 //! \param ulBase is the base address of the watchdog timer module.
428 //!
429 //! This function enables the watchdog timer interrupt.
430 //!
431 //! \note This function has no effect if the watchdog timer has been locked.
432 //!
433 //! \sa WatchdogLock(), WatchdogUnlock(), WatchdogEnable()
434 //!
435 //! \return None.
436 //
437 //*****************************************************************************
438 void
WatchdogIntEnable(unsigned long ulBase)439 WatchdogIntEnable(unsigned long ulBase)
440 {
441     //
442     // Check the arguments.
443     //
444     ASSERT((ulBase == WATCHDOG0_BASE) || (ulBase == WATCHDOG1_BASE));
445 
446     //
447     // Enable the watchdog interrupt.
448     //
449     HWREG(ulBase + WDT_O_CTL) |= WDT_CTL_INTEN;
450 }
451 
452 //*****************************************************************************
453 //
454 //! Gets the current watchdog timer interrupt status.
455 //!
456 //! \param ulBase is the base address of the watchdog timer module.
457 //! \param bMasked is \b false if the raw interrupt status is required and
458 //! \b true if the masked interrupt status is required.
459 //!
460 //! This function returns the interrupt status for the watchdog timer module.
461 //! Either the raw interrupt status or the status of interrupt that is allowed
462 //! to reflect to the processor can be returned.
463 //!
464 //! \return Returns the current interrupt status, where a 1 indicates that the
465 //! watchdog interrupt is active, and a 0 indicates that it is not active.
466 //
467 //*****************************************************************************
468 unsigned long
WatchdogIntStatus(unsigned long ulBase,tBoolean bMasked)469 WatchdogIntStatus(unsigned long ulBase, tBoolean bMasked)
470 {
471     //
472     // Check the arguments.
473     //
474     ASSERT((ulBase == WATCHDOG0_BASE) || (ulBase == WATCHDOG1_BASE));
475 
476     //
477     // Return either the interrupt status or the raw interrupt status as
478     // requested.
479     //
480     if(bMasked)
481     {
482         return(HWREG(ulBase + WDT_O_MIS));
483     }
484     else
485     {
486         return(HWREG(ulBase + WDT_O_RIS));
487     }
488 }
489 
490 //*****************************************************************************
491 //
492 //! Clears the watchdog timer interrupt.
493 //!
494 //! \param ulBase is the base address of the watchdog timer module.
495 //!
496 //! The watchdog timer interrupt source is cleared, so that it no longer
497 //! asserts.
498 //!
499 //! \note Because there is a write buffer in the Cortex-M processor, it may
500 //! take several clock cycles before the interrupt source is actually cleared.
501 //! Therefore, it is recommended that the interrupt source be cleared early in
502 //! the interrupt handler (as opposed to the very last action) to avoid
503 //! returning from the interrupt handler before the interrupt source is
504 //! actually cleared.  Failure to do so may result in the interrupt handler
505 //! being immediately reentered (because the interrupt controller still sees
506 //! the interrupt source asserted).
507 //!
508 //! \return None.
509 //
510 //*****************************************************************************
511 void
WatchdogIntClear(unsigned long ulBase)512 WatchdogIntClear(unsigned long ulBase)
513 {
514     //
515     // Check the arguments.
516     //
517     ASSERT((ulBase == WATCHDOG0_BASE) || (ulBase == WATCHDOG1_BASE));
518 
519     //
520     // Clear the interrupt source.
521     //
522     HWREG(ulBase + WDT_O_ICR) = WDT_INT_TIMEOUT;
523 }
524 
525 //*****************************************************************************
526 //
527 //! Sets the type of interrupt generated by the watchdog.
528 //!
529 //! \param ulBase is the base address of the watchdog timer module.
530 //! \param ulType is the type of interrupt to generate.
531 //!
532 //! This function sets the type of interrupt that is generated if the watchdog
533 //! timer expires.  \e ulType can be either \b WATCHDOG_INT_TYPE_INT to
534 //! generate a standard interrupt (the default) or \b WATCHDOG_INT_TYPE_NMI to
535 //! generate a non-maskable interrupt (NMI).
536 //!
537 //! When configured to generate an NMI, the watchdog interrupt must still be
538 //! enabled with WatchdogIntEnable(), and it must still be cleared inside the
539 //! NMI handler with WatchdogIntClear().
540 //!
541 //! \note The ability to select an NMI interrupt varies with the Stellaris part
542 //! in use.  Please consult the datasheet for the part you are using to
543 //! determine whether this support is available.
544 //!
545 //! \return None.
546 //
547 //*****************************************************************************
548 void
WatchdogIntTypeSet(unsigned long ulBase,unsigned long ulType)549 WatchdogIntTypeSet(unsigned long ulBase, unsigned long ulType)
550 {
551     //
552     // Check the arguments.
553     //
554     ASSERT((ulBase == WATCHDOG0_BASE) || (ulBase == WATCHDOG1_BASE));
555     ASSERT((ulType == WATCHDOG_INT_TYPE_INT) ||
556            (ulType == WATCHDOG_INT_TYPE_NMI));
557 
558     //
559     // Set the interrupt type.
560     //
561     HWREG(ulBase + WDT_O_CTL) =
562         (HWREG(ulBase + WDT_O_CTL) & ~WDT_CTL_INTTYPE) | ulType;
563 }
564 
565 //*****************************************************************************
566 //
567 //! Enables stalling of the watchdog timer during debug events.
568 //!
569 //! \param ulBase is the base address of the watchdog timer module.
570 //!
571 //! This function allows the watchdog timer to stop counting when the processor
572 //! is stopped by the debugger.  By doing so, the watchdog is prevented from
573 //! expiring (typically almost immediately from a human time perspective) and
574 //! resetting the system (if reset is enabled).  The watchdog instead expires
575 //! after the appropriate number of processor cycles have been executed while
576 //! debugging (or at the appropriate time after the processor has been
577 //! restarted).
578 //!
579 //! \return None.
580 //
581 //*****************************************************************************
582 void
WatchdogStallEnable(unsigned long ulBase)583 WatchdogStallEnable(unsigned long ulBase)
584 {
585     //
586     // Check the arguments.
587     //
588     ASSERT((ulBase == WATCHDOG0_BASE) || (ulBase == WATCHDOG1_BASE));
589 
590     //
591     // Enable timer stalling.
592     //
593     HWREG(ulBase + WDT_O_TEST) |= WDT_TEST_STALL;
594 }
595 
596 //*****************************************************************************
597 //
598 //! Disables stalling of the watchdog timer during debug events.
599 //!
600 //! \param ulBase is the base address of the watchdog timer module.
601 //!
602 //! This function disables the debug mode stall of the watchdog timer.  By
603 //! doing so, the watchdog timer continues to count regardless of the processor
604 //! debug state.
605 //!
606 //! \return None.
607 //
608 //*****************************************************************************
609 void
WatchdogStallDisable(unsigned long ulBase)610 WatchdogStallDisable(unsigned long ulBase)
611 {
612     //
613     // Check the arguments.
614     //
615     ASSERT((ulBase == WATCHDOG0_BASE) || (ulBase == WATCHDOG1_BASE));
616 
617     //
618     // Disable timer stalling.
619     //
620     HWREG(ulBase + WDT_O_TEST) &= ~(WDT_TEST_STALL);
621 }
622 
623 //*****************************************************************************
624 //
625 // Close the Doxygen group.
626 //! @}
627 //
628 //*****************************************************************************
629