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