Improved accuracy
[hackover2013-badge-firmware.git] / core / wdt / wdt.c
1 /**************************************************************************/
2 /*!
3 @file wdt.c
4 @author K. Townsend (microBuilder.eu)
5 @date 22 March 2010
6 @version 0.10
7
8 @section DESCRIPTION
9
10 Sets up the watchdog timer (WDT). The WDT allows you to monitor
11 whether the device is still executing properly. If the watchdog
12 isn't 'fed' within a pre-determined delay, it will raise an interrupt
13 allowing you to decide if you want to reset the device, etc.
14
15 @code
16 #include "core/cpu/cpu.h"
17 #include "core/wdt/wdt.h"
18 ...
19 cpuInit();
20
21 // Initialise wdt with no reset on timeout
22 wdtInit(false);
23
24 // Pat the watchdog (to start the timer)
25 wdtFeed();
26
27 while (1)
28 {
29 // Keep the watchdog happy by regularly feeding it
30 wdtFeed();
31 }
32 @endcode
33
34 @section LICENSE
35
36 Software License Agreement (BSD License)
37
38 Copyright (c) 2010, microBuilder SARL
39 All rights reserved.
40
41 Redistribution and use in source and binary forms, with or without
42 modification, are permitted provided that the following conditions are met:
43 1. Redistributions of source code must retain the above copyright
44 notice, this list of conditions and the following disclaimer.
45 2. Redistributions in binary form must reproduce the above copyright
46 notice, this list of conditions and the following disclaimer in the
47 documentation and/or other materials provided with the distribution.
48 3. Neither the name of the copyright holders nor the
49 names of its contributors may be used to endorse or promote products
50 derived from this software without specific prior written permission.
51
52 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
53 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
54 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
55 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
56 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
57 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
58 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
59 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
60 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
61 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
62 */
63 /**************************************************************************/
64
65 #include "wdt.h"
66
67 #define WDT_FEED_VALUE (0x003FFFFF)
68
69 volatile uint32_t wdt_counter;
70
71 /**************************************************************************/
72 /*!
73 IRQ Handler when the watchdog times out. Any actions that you wish
74 to take when a timeout occurs should be called from here.
75 */
76 /**************************************************************************/
77 void WDT_IRQHandler(void)
78 {
79 /* Clear the time-out interrupt flag */
80 WDT_WDMOD &= ~WDT_WDMOD_WDTOF;
81 wdt_counter++;
82 }
83
84 /**************************************************************************/
85 /*!
86 Setup the clock for the watchdog timer. The default setting is 250kHz.
87 */
88 /**************************************************************************/
89 static void wdtClockSetup (void)
90 {
91 /* Watchdog Configuration */
92 /* Freq. = 0.5MHz, div = 2: WDT_OSC = 250kHz */
93 SCB_WDTOSCCTRL = SCB_WDTOSCCTRL_FREQSEL_0_5MHZ |
94 SCB_WDTOSCCTRL_DIVSEL_DIV2;
95
96 /* Set clock source (use WDT oscillator) */
97 SCB_WDTCLKSEL = SCB_WDTCLKSEL_SOURCE_WATCHDOGOSC;
98 SCB_WDTCLKUEN = SCB_WDTCLKUEN_UPDATE;
99 SCB_WDTCLKUEN = SCB_WDTCLKUEN_DISABLE;
100 SCB_WDTCLKUEN = SCB_WDTCLKUEN_UPDATE;
101
102 /* Wait until updated */
103 while (!(SCB_WDTCLKUEN & SCB_WDTCLKUEN_UPDATE));
104
105 /* Set divider */
106 SCB_WDTCLKDIV = SCB_WDTCLKDIV_DIV1;
107
108 /* Enable WDT clock */
109 SCB_PDRUNCFG &= ~(SCB_PDRUNCFG_WDTOSC);
110 }
111
112 /**************************************************************************/
113 /*!
114 Initialises the watchdog timer and sets up the interrupt.
115 */
116 /**************************************************************************/
117 void wdtInit (bool reset)
118 {
119 /* Setup the WDT clock */
120 wdtClockSetup();
121
122 /* Enable AHB clock to the WDT domain. */
123 SCB_SYSAHBCLKCTRL |= SCB_SYSAHBCLKCTRL_WDT;
124
125 wdt_counter = 0;
126
127 /* Enable the WDT interrupt */
128 NVIC_EnableIRQ(WDT_IRQn);
129
130 /* Set timeout value (must be at least 0x000000FF) */
131 WDT_WDTC = WDT_FEED_VALUE;
132
133 /* Enable the watchdog timer (without system reset) */
134 WDT_WDMOD = WDT_WDMOD_WDEN_ENABLED |
135 reset ? WDT_WDMOD_WDRESET_ENABLED : WDT_WDMOD_WDRESET_DISABLED ;
136 }
137
138 /**************************************************************************/
139 /*!
140 Feeds the watchdog to keep it from timing out. Interrupts will be
141 disabled while feeding the watchdog.
142 */
143 /**************************************************************************/
144 void wdtFeed (void)
145 {
146 /* Pet the watchdog */
147 __disable_irq();
148 WDT_WDFEED = WDT_WDFEED_FEED1;
149 WDT_WDFEED = WDT_WDFEED_FEED2;
150 __enable_irq();
151 }
152
This page took 0.065499 seconds and 5 git commands to generate.