1 /* This is from http://www.mtcnet.net/~henryvm/wdt/ */
8 Copyright (c) 2009, Curt Van Maanen
10 Permission to use, copy, modify, and/or distribute this software for any
11 purpose with or without fee is hereby granted, provided that the above
12 copyright notice and this permission notice appear in all copies.
14 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
15 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
16 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
17 ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
18 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
19 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
20 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
24 #include "wd.h" //if in same directory as project
25 #include <avr/wd.h> //if wd.h is in avr directory
27 set watchdog modes and prescale
30 WD_SET(mode,[timeout]); //prescale always set
34 WD_RST normal reset mode
35 WD_IRQ interrupt only mode (if supported)
36 WD_RST_IRQ interrupt+reset mode (if supported)
39 WDTO_15MS default if no timeout provided
47 WDTO_4S (if supported)
48 WDTO_8S (if supported)
51 WD_SET(WD_RST,WDTO_1S); //reset mode, 1s timeout
52 WD_SET(WD_OFF); //watchdog disabled (if not fused on)
53 WD_SET(WD_RST); //reset mode, 15ms (default timeout)
54 WD_SET(WD_IRQ,WDTO_120MS); //interrupt only mode, 120ms timeout
55 WD_SET(WD_RST_IRQ,WDTO_2S); //interrupt+reset mode, 2S timeout
58 for enhanced watchdogs, if the watchdog is not being used WDRF should be
59 cleared on every power up or reset, along with disabling the watchdog-
60 WD_DISABLE(); //clear WDRF, then turn off watchdog
64 //reset registers to the same name (MCUCSR)
69 //watchdog registers to the same name (WDTCSR)
74 //if enhanced watchdog, define irq values, create disable macro
77 #define WD_RST_IRQ 0xC8
78 #define WD_DISABLE() do{ \
79 MCUCSR &= ~(1<<WDRF); \
98 //prescale values for avrs with WDP3
105 #define WDR() __asm__ __volatile__("wdr")
107 //avr reset using watchdog
108 #define WD_AVR_RESET() do{ \
109 __asm__ __volatile__("cli"); \
110 WD_SET_UNSAFE(WD_RST); \
117 3. reset watchdog timer
118 4. enable watchdog change
119 5. write watchdog value
120 6. restore SREG (restoring irq status)
122 #define WD_SET(val,...) \
123 __asm__ __volatile__( \
124 "in __tmp_reg__,__SREG__" "\n\t" \
127 "sts %[wdreg],%[wden]" "\n\t" \
128 "sts %[wdreg],%[wdval]" "\n\t" \
129 "out __SREG__,__tmp_reg__" "\n\t" \
131 : [wdreg] "M" (&WDTCSR), \
132 [wden] "r" ((uint8_t)(0x18)), \
133 [wdval] "r" ((uint8_t)(val|(__VA_ARGS__+0))) \
137 /*set the watchdog when I bit in SREG known to be clear-
138 1. reset watchdog timer
139 2. enable watchdog change
140 5. write watchdog value
142 #define WD_SET_UNSAFE(val,...) \
143 __asm__ __volatile__( \
145 "sts %[wdreg],%[wden]" "\n\t" \
146 "sts %[wdreg],%[wdval]" "\n\t" \
148 : [wdreg] "M" (&WDTCSR), \
149 [wden] "r" ((uint8_t)(0x18)), \
150 [wdval] "r" ((uint8_t)(val|(__VA_ARGS__+0))) \
154 //for compatibility with avr/wdt.h
155 #define wdt_enable(val) WD_SET(WD_RST,val)
156 #define wdt_disable() WD_SET(WD_OFF)
159 #endif /* _AVR_WD_H_ */