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