1 /* Copyright (c) 2002, 2004 Marek Michalkiewicz
2    Copyright (c) 2005, 2006, 2007 Eric B. Weddington
3    All rights reserved.
4 
5    Redistribution and use in source and binary forms, with or without
6    modification, are permitted provided that the following conditions are met:
7 
8    * Redistributions of source code must retain the above copyright
9      notice, this list of conditions and the following disclaimer.
10 
11    * Redistributions in binary form must reproduce the above copyright
12      notice, this list of conditions and the following disclaimer in
13      the documentation and/or other materials provided with the
14      distribution.
15 
16    * Neither the name of the copyright holders nor the names of
17      contributors may be used to endorse or promote products derived
18      from this software without specific prior written permission.
19 
20   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30   POSSIBILITY OF SUCH DAMAGE. */
31 
32 /* $Id: wdt.h 2503 2016-02-07 22:59:47Z joerg_wunsch $ */
33 
34 /*
35    avr/wdt.h - macros for AVR watchdog timer
36  */
37 
38 #ifndef _AVR_WDT_H_
39 #define _AVR_WDT_H_
40 
41 #include <avr/io.h>
42 #include <stdint.h>
43 
44 /** \file */
45 /** \defgroup avr_watchdog <avr/wdt.h>: Watchdog timer handling
46     \code #include <avr/wdt.h> \endcode
47 
48     This header file declares the interface to some inline macros
49     handling the watchdog timer present in many AVR devices.  In order
50     to prevent the watchdog timer configuration from being
51     accidentally altered by a crashing application, a special timed
52     sequence is required in order to change it.  The macros within
53     this header file handle the required sequence automatically
54     before changing any value.  Interrupts will be disabled during
55     the manipulation.
56 
57     \note Depending on the fuse configuration of the particular
58     device, further restrictions might apply, in particular it might
59     be disallowed to turn off the watchdog timer.
60 
61     Note that for newer devices (ATmega88 and newer, effectively any
62     AVR that has the option to also generate interrupts), the watchdog
63     timer remains active even after a system reset (except a power-on
64     condition), using the fastest prescaler value (approximately 15
65     ms).  It is therefore required to turn off the watchdog early
66     during program startup, the datasheet recommends a sequence like
67     the following:
68 
69     \code
70     #include <stdint.h>
71     #include <avr/wdt.h>
72 
73     uint8_t mcusr_mirror __attribute__ ((section (".noinit")));
74 
75     void get_mcusr(void) \
76       __attribute__((naked)) \
77       __attribute__((section(".init3")));
78     void get_mcusr(void)
79     {
80       mcusr_mirror = MCUSR;
81       MCUSR = 0;
82       wdt_disable();
83     }
84     \endcode
85 
86     Saving the value of MCUSR in \c mcusr_mirror is only needed if the
87     application later wants to examine the reset source, but in particular,
88     clearing the watchdog reset flag before disabling the
89     watchdog is required, according to the datasheet.
90 */
91 
92 /**
93    \ingroup avr_watchdog
94    Reset the watchdog timer.  When the watchdog timer is enabled,
95    a call to this instruction is required before the timer expires,
96    otherwise a watchdog-initiated device reset will occur.
97 */
98 
99 #define wdt_reset() __asm__ __volatile__ ("wdr")
100 
101 #ifndef __DOXYGEN__
102 
103 #if defined(WDP3)
104 # define _WD_PS3_MASK       _BV(WDP3)
105 #else
106 # define _WD_PS3_MASK       0x00
107 #endif
108 
109 #if defined(WDTCSR)
110 #  define _WD_CONTROL_REG     WDTCSR
111 #elif defined(WDTCR)
112 #  define _WD_CONTROL_REG     WDTCR
113 #else
114 #  define _WD_CONTROL_REG     WDT
115 #endif
116 
117 #if defined(WDTOE)
118 #define _WD_CHANGE_BIT      WDTOE
119 #else
120 #define _WD_CHANGE_BIT      WDCE
121 #endif
122 
123 #endif	/* !__DOXYGEN__ */
124 
125 
126 /**
127    \ingroup avr_watchdog
128    Enable the watchdog timer, configuring it for expiry after
129    \c timeout (which is a combination of the \c WDP0 through
130    \c WDP2 bits to write into the \c WDTCR register; For those devices
131    that have a \c WDTCSR register, it uses the combination of the \c WDP0
132    through \c WDP3 bits).
133 
134    See also the symbolic constants \c WDTO_15MS et al.
135 */
136 
137 
138 #if defined(__AVR_XMEGA__)
139 
140 /*
141    wdt_enable(timeout) for xmega devices
142 ** write signature (CCP_IOREG_gc) that enables change of protected I/O
143    registers to the CCP register
144 ** At the same time,
145    1) set WDT change enable (WDT_CEN_bm)
146    2) enable WDT (WDT_ENABLE_bm)
147    3) set timeout (timeout)
148 ** Synchronization starts when ENABLE bit of WDT is set. So, wait till it
149    finishes (SYNCBUSY of STATUS register is automatically cleared after the
150    sync is finished).
151 */
152 #define wdt_enable(timeout) \
153 do { \
154 uint8_t temp; \
155 __asm__ __volatile__ (         \
156     "in __tmp_reg__, %[rampd]"              "\n\t" \
157     "out %[rampd], __zero_reg__"            "\n\t" \
158     "out %[ccp_reg], %[ioreg_cen_mask]"     "\n\t" \
159     "sts %[wdt_reg], %[wdt_enable_timeout]" "\n\t" \
160     "1:lds %[tmp], %[wdt_status_reg]"       "\n\t" \
161     "sbrc %[tmp], %[wdt_syncbusy_bit]"      "\n\t" \
162     "rjmp 1b"                               "\n\t" \
163     "out %[rampd], __tmp_reg__"             "\n\t" \
164     : [tmp]                "=r" (temp) \
165     : [rampd]              "I" (_SFR_IO_ADDR(RAMPD)),      \
166       [ccp_reg]            "I" (_SFR_IO_ADDR(CCP)),        \
167       [ioreg_cen_mask]     "r" ((uint8_t)CCP_IOREG_gc),     \
168       [wdt_reg]            "n" (_SFR_MEM_ADDR(WDT_CTRL)),   \
169       [wdt_enable_timeout] "r" ((uint8_t)(WDT_CEN_bm | WDT_ENABLE_bm | timeout)), \
170       [wdt_status_reg]     "n" (_SFR_MEM_ADDR(WDT_STATUS)), \
171       [wdt_syncbusy_bit]   "I" (WDT_SYNCBUSY_bm)            \
172     : "r0" \
173 ); \
174 } while(0)
175 
176 #define wdt_disable() \
177 __asm__ __volatile__ (  \
178     "in __tmp_reg__, %[rampd]"          "\n\t" \
179     "out %[rampd], __zero_reg__"        "\n\t" \
180     "out %[ccp_reg], %[ioreg_cen_mask]" "\n\t" \
181     "sts %[wdt_reg], %[disable_mask]"   "\n\t" \
182     "out %[rampd], __tmp_reg__"         "\n\t" \
183     : \
184     : [rampd]             "I" (_SFR_IO_ADDR(RAMPD)),    \
185       [ccp_reg]           "I" (_SFR_IO_ADDR(CCP)),      \
186       [ioreg_cen_mask]    "r" ((uint8_t)CCP_IOREG_gc),   \
187       [wdt_reg]           "n" (_SFR_MEM_ADDR(WDT_CTRL)), \
188       [disable_mask]      "r" ((uint8_t)((~WDT_ENABLE_bm) | WDT_CEN_bm)) \
189     : "r0" \
190 );
191 
192 #elif defined(__AVR_TINY__)
193 
194 #define wdt_enable(value) \
195 __asm__ __volatile__ ( \
196     "in __tmp_reg__,__SREG__" "\n\t"  \
197     "cli" "\n\t"  \
198     "wdr" "\n\t"  \
199     "out %[CCPADDRESS],%[SIGNATURE]" "\n\t"  \
200     "out %[WDTREG],%[WDVALUE]" "\n\t"  \
201     "out __SREG__,__tmp_reg__" "\n\t"  \
202     : /* no outputs */  \
203     : [CCPADDRESS] "I" (_SFR_IO_ADDR(CCP)),  \
204       [SIGNATURE] "r" ((uint8_t)0xD8), \
205       [WDTREG] "I" (_SFR_IO_ADDR(_WD_CONTROL_REG)), \
206       [WDVALUE] "r" ((uint8_t)((value & 0x08 ? _WD_PS3_MASK : 0x00) \
207       | _BV(WDE) | (value & 0x07) )) \
208     : "r16" \
209 )
210 
211 #define wdt_disable() \
212 do { \
213 uint8_t temp_wd; \
214 __asm__ __volatile__ ( \
215     "in __tmp_reg__,__SREG__" "\n\t"  \
216     "cli" "\n\t"  \
217     "wdr" "\n\t"  \
218     "out %[CCPADDRESS],%[SIGNATURE]" "\n\t"  \
219     "in  %[TEMP_WD],%[WDTREG]" "\n\t" \
220     "cbr %[TEMP_WD],%[WDVALUE]" "\n\t" \
221     "out %[WDTREG],%[TEMP_WD]" "\n\t" \
222     "out __SREG__,__tmp_reg__" "\n\t" \
223     : /*no output */ \
224     : [CCPADDRESS] "I" (_SFR_IO_ADDR(CCP)), \
225       [SIGNATURE] "r" ((uint8_t)0xD8), \
226       [WDTREG] "I" (_SFR_IO_ADDR(_WD_CONTROL_REG)), \
227       [TEMP_WD] "d" (temp_wd), \
228       [WDVALUE] "n" (1 << WDE) \
229     : "r16" \
230 ); \
231 }while(0)
232 
233 #elif defined(CCP)
234 
235 static __inline__
236 __attribute__ ((__always_inline__))
wdt_enable(const uint8_t value)237 void wdt_enable (const uint8_t value)
238 {
239 	if (!_SFR_IO_REG_P (CCP) && !_SFR_IO_REG_P (_WD_CONTROL_REG))
240 	{
241 		__asm__ __volatile__ (
242 			"in __tmp_reg__,__SREG__" "\n\t"
243 			"cli" "\n\t"
244 			"wdr" "\n\t"
245 			"sts %[CCPADDRESS],%[SIGNATURE]" "\n\t"
246 			"sts %[WDTREG],%[WDVALUE]" "\n\t"
247 			"out __SREG__,__tmp_reg__" "\n\t"
248 			: /* no outputs */
249 			: [CCPADDRESS] "n" (_SFR_MEM_ADDR(CCP)),
250 			[SIGNATURE] "r" ((uint8_t)0xD8),
251 			[WDTREG] "n" (_SFR_MEM_ADDR(_WD_CONTROL_REG)),
252 			[WDVALUE] "r" ((uint8_t)((value & 0x08 ? _WD_PS3_MASK : 0x00)
253 				| _BV(WDE) | (value & 0x07) ))
254 			: "r0"
255 			);
256 	}
257 	else if (!_SFR_IO_REG_P (CCP) && _SFR_IO_REG_P (_WD_CONTROL_REG))
258 	{
259 		__asm__ __volatile__ (
260 			"in __tmp_reg__,__SREG__" "\n\t"
261 			"cli" "\n\t"
262 			"wdr" "\n\t"
263 			"sts %[CCPADDRESS],%[SIGNATURE]" "\n\t"
264 			"out %[WDTREG],%[WDVALUE]" "\n\t"
265 			"out __SREG__,__tmp_reg__" "\n\t"
266 			: /* no outputs */
267 			: [CCPADDRESS] "n" (_SFR_MEM_ADDR(CCP)),
268 			[SIGNATURE] "r" ((uint8_t)0xD8),
269 			[WDTREG] "I" (_SFR_IO_ADDR(_WD_CONTROL_REG)),
270 			[WDVALUE] "r" ((uint8_t)((value & 0x08 ? _WD_PS3_MASK : 0x00)
271 				| _BV(WDE) | (value & 0x07) ))
272 			: "r0"
273 			);
274 	}
275 	else if (_SFR_IO_REG_P (CCP) && !_SFR_IO_REG_P (_WD_CONTROL_REG))
276 	{
277 		__asm__ __volatile__ (
278 			"in __tmp_reg__,__SREG__" "\n\t"
279 			"cli" "\n\t"
280 			"wdr" "\n\t"
281 			"out %[CCPADDRESS],%[SIGNATURE]" "\n\t"
282 			"sts %[WDTREG],%[WDVALUE]" "\n\t"
283 			"out __SREG__,__tmp_reg__" "\n\t"
284 			: /* no outputs */
285 			: [CCPADDRESS] "I" (_SFR_IO_ADDR(CCP)),
286 			[SIGNATURE] "r" ((uint8_t)0xD8),
287 			[WDTREG] "n" (_SFR_MEM_ADDR(_WD_CONTROL_REG)),
288 			[WDVALUE] "r" ((uint8_t)((value & 0x08 ? _WD_PS3_MASK : 0x00)
289 				| _BV(WDE) | (value & 0x07) ))
290 			: "r0"
291 			);
292 	}
293 	else
294  	{
295 		__asm__ __volatile__ (
296 			"in __tmp_reg__,__SREG__" "\n\t"
297 			"cli" "\n\t"
298 			"wdr" "\n\t"
299 			"out %[CCPADDRESS],%[SIGNATURE]" "\n\t"
300 			"out %[WDTREG],%[WDVALUE]" "\n\t"
301 			"out __SREG__,__tmp_reg__" "\n\t"
302 			: /* no outputs */
303 			: [CCPADDRESS] "I" (_SFR_IO_ADDR(CCP)),
304 			[SIGNATURE] "r" ((uint8_t)0xD8),
305 			[WDTREG] "I" (_SFR_IO_ADDR(_WD_CONTROL_REG)),
306 			[WDVALUE] "r" ((uint8_t)((value & 0x08 ? _WD_PS3_MASK : 0x00)
307 				| _BV(WDE) | (value & 0x07) ))
308 			: "r0"
309 			);
310 	}
311 }
312 
313 static __inline__
314 __attribute__ ((__always_inline__))
wdt_disable(void)315 void wdt_disable (void)
316 {
317 	if (!_SFR_IO_REG_P (CCP) && !_SFR_IO_REG_P(_WD_CONTROL_REG))
318 	{
319         uint8_t temp_wd;
320         __asm__ __volatile__ (
321 				"in __tmp_reg__,__SREG__" "\n\t"
322 				"cli" "\n\t"
323 				"wdr" "\n\t"
324 				"sts %[CCPADDRESS],%[SIGNATURE]" "\n\t"
325 				"lds %[TEMP_WD],%[WDTREG]" "\n\t"
326 				"cbr %[TEMP_WD],%[WDVALUE]" "\n\t"
327 				"sts %[WDTREG],%[TEMP_WD]" "\n\t"
328 				"out __SREG__,__tmp_reg__" "\n\t"
329 				: /*no output */
330 				: [CCPADDRESS] "n" (_SFR_MEM_ADDR(CCP)),
331 				[SIGNATURE] "r" ((uint8_t)0xD8),
332 				[WDTREG] "n" (_SFR_MEM_ADDR(_WD_CONTROL_REG)),
333 				[TEMP_WD] "d" (temp_wd),
334 				[WDVALUE] "n" (1 << WDE)
335 				: "r0"
336 				);
337 	}
338 	else if (!_SFR_IO_REG_P (CCP) && _SFR_IO_REG_P(_WD_CONTROL_REG))
339 	{
340         uint8_t temp_wd;
341         __asm__ __volatile__ (
342 				"in __tmp_reg__,__SREG__" "\n\t"
343 				"cli" "\n\t"
344 				"wdr" "\n\t"
345 				"sts %[CCPADDRESS],%[SIGNATURE]" "\n\t"
346 				"in %[TEMP_WD],%[WDTREG]" "\n\t"
347 				"cbr %[TEMP_WD],%[WDVALUE]" "\n\t"
348 				"out %[WDTREG],%[TEMP_WD]" "\n\t"
349 				"out __SREG__,__tmp_reg__" "\n\t"
350 				: /*no output */
351 				: [CCPADDRESS] "n" (_SFR_MEM_ADDR(CCP)),
352 				[SIGNATURE] "r" ((uint8_t)0xD8),
353 				[WDTREG] "I" (_SFR_IO_ADDR(_WD_CONTROL_REG)),
354 				[TEMP_WD] "d" (temp_wd),
355 				[WDVALUE] "n" (1 << WDE)
356 				: "r0"
357 				);
358 	}
359 	else if (_SFR_IO_REG_P (CCP) && !_SFR_IO_REG_P(_WD_CONTROL_REG))
360 	{
361         uint8_t temp_wd;
362         __asm__ __volatile__ (
363 				"in __tmp_reg__,__SREG__" "\n\t"
364 				"cli" "\n\t"
365 				"wdr" "\n\t"
366 				"out %[CCPADDRESS],%[SIGNATURE]" "\n\t"
367 				"lds %[TEMP_WD],%[WDTREG]" "\n\t"
368 				"cbr %[TEMP_WD],%[WDVALUE]" "\n\t"
369 				"sts %[WDTREG],%[TEMP_WD]" "\n\t"
370 				"out __SREG__,__tmp_reg__" "\n\t"
371 				: /*no output */
372 				: [CCPADDRESS] "I" (_SFR_IO_ADDR(CCP)),
373 				[SIGNATURE] "r" ((uint8_t)0xD8),
374 				[WDTREG] "n" (_SFR_MEM_ADDR(_WD_CONTROL_REG)),
375 				[TEMP_WD] "d" (temp_wd),
376 				[WDVALUE] "n" (1 << WDE)
377 				: "r0"
378 				);
379 	}
380 	else
381 	{
382         uint8_t temp_wd;
383         __asm__ __volatile__ (
384 				"in __tmp_reg__,__SREG__" "\n\t"
385 				"cli" "\n\t"
386 				"wdr" "\n\t"
387 				"out %[CCPADDRESS],%[SIGNATURE]" "\n\t"
388 				"in %[TEMP_WD],%[WDTREG]" "\n\t"
389 				"cbr %[TEMP_WD],%[WDVALUE]" "\n\t"
390 				"out %[WDTREG],%[TEMP_WD]" "\n\t"
391 				"out __SREG__,__tmp_reg__" "\n\t"
392 				: /*no output */
393 				: [CCPADDRESS] "I" (_SFR_IO_ADDR(CCP)),
394 				[SIGNATURE] "r" ((uint8_t)0xD8),
395 				[WDTREG] "I" (_SFR_IO_ADDR(_WD_CONTROL_REG)),
396 				[TEMP_WD] "d" (temp_wd),
397 				[WDVALUE] "n" (1 << WDE)
398 				: "r0"
399 				);
400 	}
401 }
402 
403 #else
404 
405 static __inline__
406 __attribute__ ((__always_inline__))
wdt_enable(const uint8_t value)407 void wdt_enable (const uint8_t value)
408 {
409 	if (_SFR_IO_REG_P (_WD_CONTROL_REG))
410 	{
411 		__asm__ __volatile__ (
412 				"in __tmp_reg__,__SREG__" "\n\t"
413 				"cli" "\n\t"
414 				"wdr" "\n\t"
415 				"out %0, %1" "\n\t"
416 				"out __SREG__,__tmp_reg__" "\n\t"
417 				"out %0, %2" "\n \t"
418 				: /* no outputs */
419 				: "I" (_SFR_IO_ADDR(_WD_CONTROL_REG)),
420 				"r" ((uint8_t)(_BV(_WD_CHANGE_BIT) | _BV(WDE))),
421 				"r" ((uint8_t) ((value & 0x08 ? _WD_PS3_MASK : 0x00) |
422 						_BV(WDE) | (value & 0x07)) )
423 				: "r0"
424 		);
425 	}
426 	else
427 	{
428 		__asm__ __volatile__ (
429 				"in __tmp_reg__,__SREG__" "\n\t"
430 				"cli" "\n\t"
431 				"wdr" "\n\t"
432 				"sts %0, %1" "\n\t"
433 				"out __SREG__,__tmp_reg__" "\n\t"
434 				"sts %0, %2" "\n \t"
435 				: /* no outputs */
436 				: "n" (_SFR_MEM_ADDR(_WD_CONTROL_REG)),
437 				"r" ((uint8_t)(_BV(_WD_CHANGE_BIT) | _BV(WDE))),
438 				"r" ((uint8_t) ((value & 0x08 ? _WD_PS3_MASK : 0x00) |
439 						_BV(WDE) | (value & 0x07)) )
440 				: "r0"
441 		);
442 	}
443 }
444 
445 static __inline__
446 __attribute__ ((__always_inline__))
wdt_disable(void)447 void wdt_disable (void)
448 {
449 	if (_SFR_IO_REG_P (_WD_CONTROL_REG))
450 	{
451         uint8_t register temp_reg;
452 		__asm__ __volatile__ (
453 				"in __tmp_reg__,__SREG__"    "\n\t"
454 				"cli"                        "\n\t"
455 				"wdr"                        "\n\t"
456 				"in  %[TEMPREG],%[WDTREG]"   "\n\t"
457 				"ori %[TEMPREG],%[WDCE_WDE]" "\n\t"
458 				"out %[WDTREG],%[TEMPREG]"   "\n\t"
459 				"out %[WDTREG],__zero_reg__" "\n\t"
460 				"out __SREG__,__tmp_reg__"   "\n\t"
461 				: [TEMPREG] "=d" (temp_reg)
462 				: [WDTREG]  "I"  (_SFR_IO_ADDR(_WD_CONTROL_REG)),
463 				[WDCE_WDE]  "n"  ((uint8_t)(_BV(_WD_CHANGE_BIT) | _BV(WDE)))
464 				: "r0"
465 		);
466 	}
467 	else
468 	{
469         uint8_t register temp_reg;
470 		__asm__ __volatile__ (
471 				"in __tmp_reg__,__SREG__"    "\n\t"
472 				"cli"                        "\n\t"
473 				"wdr"                        "\n\t"
474 				"lds %[TEMPREG],%[WDTREG]"   "\n\t"
475 				"ori %[TEMPREG],%[WDCE_WDE]" "\n\t"
476 				"sts %[WDTREG],%[TEMPREG]"   "\n\t"
477 				"sts %[WDTREG],__zero_reg__" "\n\t"
478 				"out __SREG__,__tmp_reg__"   "\n\t"
479 				: [TEMPREG] "=d" (temp_reg)
480 				: [WDTREG]  "n"  (_SFR_MEM_ADDR(_WD_CONTROL_REG)),
481 				[WDCE_WDE]  "n"  ((uint8_t)(_BV(_WD_CHANGE_BIT) | _BV(WDE)))
482 				: "r0"
483 		);
484 	}
485 }
486 
487 #endif
488 
489 
490 /**
491    \ingroup avr_watchdog
492    Symbolic constants for the watchdog timeout.  Since the watchdog
493    timer is based on a free-running RC oscillator, the times are
494    approximate only and apply to a supply voltage of 5 V.  At lower
495    supply voltages, the times will increase.  For older devices, the
496    times will be as large as three times when operating at Vcc = 3 V,
497    while the newer devices (e. g. ATmega128, ATmega8) only experience
498    a negligible change.
499 
500    Possible timeout values are: 15 ms, 30 ms, 60 ms, 120 ms, 250 ms,
501    500 ms, 1 s, 2 s.  (Some devices also allow for 4 s and 8 s.)
502    Symbolic constants are formed by the prefix
503    \c WDTO_, followed by the time.
504 
505    Example that would select a watchdog timer expiry of approximately
506    500 ms:
507    \code
508    wdt_enable(WDTO_500MS);
509    \endcode
510 */
511 #define WDTO_15MS   0
512 
513 /** \ingroup avr_watchdog
514     See \c WDTO_15MS */
515 #define WDTO_30MS   1
516 
517 /** \ingroup avr_watchdog
518     See \c WDTO_15MS */
519 #define WDTO_60MS   2
520 
521 /** \ingroup avr_watchdog
522     See \c WDTO_15MS */
523 #define WDTO_120MS  3
524 
525 /** \ingroup avr_watchdog
526     See \c WDTO_15MS */
527 #define WDTO_250MS  4
528 
529 /** \ingroup avr_watchdog
530     See \c WDTO_15MS */
531 #define WDTO_500MS  5
532 
533 /** \ingroup avr_watchdog
534     See \c WDTO_15MS */
535 #define WDTO_1S     6
536 
537 /** \ingroup avr_watchdog
538     See \c WDTO_15MS */
539 #define WDTO_2S     7
540 
541 #if defined(__DOXYGEN__) || defined(WDP3)
542 
543 /** \ingroup avr_watchdog
544     See \c WDTO_15MS
545     Note: This is only available on the
546     ATtiny2313,
547     ATtiny24, ATtiny44, ATtiny84, ATtiny84A,
548     ATtiny25, ATtiny45, ATtiny85,
549     ATtiny261, ATtiny461, ATtiny861,
550     ATmega48, ATmega88, ATmega168,
551     ATmega48P, ATmega88P, ATmega168P, ATmega328P,
552     ATmega164P, ATmega324P, ATmega644P, ATmega644,
553     ATmega640, ATmega1280, ATmega1281, ATmega2560, ATmega2561,
554     ATmega8HVA, ATmega16HVA, ATmega32HVB,
555     ATmega406, ATmega1284P,
556     AT90PWM1, AT90PWM2, AT90PWM2B, AT90PWM3, AT90PWM3B, AT90PWM216, AT90PWM316,
557     AT90PWM81, AT90PWM161,
558     AT90USB82, AT90USB162,
559     AT90USB646, AT90USB647, AT90USB1286, AT90USB1287,
560     ATtiny48, ATtiny88.
561     */
562 #define WDTO_4S     8
563 
564 /** \ingroup avr_watchdog
565     See \c WDTO_15MS
566     Note: This is only available on the
567     ATtiny2313,
568     ATtiny24, ATtiny44, ATtiny84, ATtiny84A,
569     ATtiny25, ATtiny45, ATtiny85,
570     ATtiny261, ATtiny461, ATtiny861,
571     ATmega48, ATmega48A, ATmega48PA, ATmega88, ATmega168,
572     ATmega48P, ATmega88P, ATmega168P, ATmega328P,
573     ATmega164P, ATmega324P, ATmega644P, ATmega644,
574     ATmega640, ATmega1280, ATmega1281, ATmega2560, ATmega2561,
575     ATmega8HVA, ATmega16HVA, ATmega32HVB,
576     ATmega406, ATmega1284P,
577     ATmega2564RFR2, ATmega256RFR2, ATmega1284RFR2, ATmega128RFR2, ATmega644RFR2, ATmega64RFR2
578     AT90PWM1, AT90PWM2, AT90PWM2B, AT90PWM3, AT90PWM3B, AT90PWM216, AT90PWM316,
579     AT90PWM81, AT90PWM161,
580     AT90USB82, AT90USB162,
581     AT90USB646, AT90USB647, AT90USB1286, AT90USB1287,
582     ATtiny48, ATtiny88,
583     ATxmega16a4u, ATxmega32a4u,
584     ATxmega16c4, ATxmega32c4,
585     ATxmega128c3, ATxmega192c3, ATxmega256c3.
586     */
587 #define WDTO_8S     9
588 
589 #endif  /* defined(__DOXYGEN__) || defined(WDP3) */
590 
591 
592 #endif /* _AVR_WDT_H_ */
593