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