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