AVR-LibC  2.2.0
Standard C library for AVR-GCC
 

AVR-LibC Documentation

Logo

AVR-LibC Development Pages

Main Page

User Manual

Library Reference

FAQ

Example Projects

File List

Loading...
Searching...
No Matches
wdt.h
Go to the documentation of this file.
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$ */
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 __attribute__((used, unused, naked, section(".init3")))
76 static void get_mcusr (void);
77
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#ifndef __ATTR_ALWAYS_INLINE__
104#define __ATTR_ALWAYS_INLINE__ __inline__ __attribute__((__always_inline__))
105#endif
106
107#if defined(WDP3)
108# define _WD_PS3_MASK _BV(WDP3)
109#else
110# define _WD_PS3_MASK 0x00
111#endif
112
113#if defined(WDTCSR)
114# define _WD_CONTROL_REG WDTCSR
115#elif defined(WDTCR)
116# define _WD_CONTROL_REG WDTCR
117#else
118# define _WD_CONTROL_REG WDT
119#endif
120
121#if defined(WDTOE)
122#define _WD_CHANGE_BIT WDTOE
123#else
124#define _WD_CHANGE_BIT WDCE
125#endif
126
127#endif /* !__DOXYGEN__ */
128
129#ifdef __DOXYGEN__
130/**
131 \ingroup avr_watchdog
132 Enable the watchdog timer, configuring it for expiry after
133 \c timeout (which is a combination of the \c WDP0 through
134 \c WDP2 bits to write into the \c WDTCR register; For those devices
135 that have a \c WDTCSR register, it uses the combination of the \c WDP0
136 through \c WDP3 bits).
137
138 See also the symbolic constants \c WDTO_15MS et al.
139*/
140#define wdt_enable(timeout)
141#endif /* __DOXYGEN__ */
142
143
144#if defined(__AVR_XMEGA__)
145
146#if defined (WDT_CTRLA) && !defined(RAMPD)
147
148#define wdt_enable(timeout) \
149do { \
150uint8_t __temp; \
151__asm__ __volatile__ ( \
152 "wdr" "\n\t" \
153 "out %[ccp_reg], %[ioreg_cen_mask]" "\n\t" \
154 "lds %[tmp], %[wdt_reg]" "\n\t" \
155 "sbr %[tmp], %[wdt_enable_timeout]" "\n\t" \
156 "sts %[wdt_reg], %[tmp]" "\n\t" \
157 "1:lds %[tmp], %[wdt_status_reg]" "\n\t" \
158 "sbrc %[tmp], %[wdt_syncbusy_bit]" "\n\t" \
159 "rjmp 1b" \
160 : [tmp] "=d" (__temp) \
161 : [ccp_reg] "I" (_SFR_IO_ADDR(CCP)), \
162 [ioreg_cen_mask] "r" ((uint8_t)CCP_IOREG_gc), \
163 [wdt_reg] "n" (_SFR_MEM_ADDR(WDT_CTRLA)), \
164 [wdt_enable_timeout] "M" (timeout), \
165 [wdt_status_reg] "n" (_SFR_MEM_ADDR(WDT_STATUS)), \
166 [wdt_syncbusy_bit] "I" (WDT_SYNCBUSY_bm) \
167); \
168} while(0)
169
170#define wdt_disable() \
171do { \
172uint8_t __temp; \
173__asm__ __volatile__ ( \
174 "wdr" "\n\t" \
175 "out %[ccp_reg], %[ioreg_cen_mask]" "\n\t" \
176 "lds %[tmp], %[wdt_reg]" "\n\t" \
177 "cbr %[tmp], %[timeout_mask]" "\n\t" \
178 "sts %[wdt_reg], %[tmp]" \
179 : [tmp] "=d" (__temp) \
180 : [ccp_reg] "I" (_SFR_IO_ADDR(CCP)), \
181 [ioreg_cen_mask] "r" ((uint8_t)CCP_IOREG_gc), \
182 [wdt_reg] "n" (_SFR_MEM_ADDR(WDT_CTRLA)),\
183 [timeout_mask] "I" (WDT_PERIOD_gm) \
184); \
185} while(0)
186
187#else // defined (WDT_CTRLA) && !defined(RAMPD)
188
189/*
190 wdt_enable(timeout) for xmega devices
191** write signature (CCP_IOREG_gc) that enables change of protected I/O
192 registers to the CCP register
193** At the same time,
194 1) set WDT change enable (WDT_CEN_bm)
195 2) enable WDT (WDT_ENABLE_bm)
196 3) set timeout (timeout)
197** Synchronization starts when ENABLE bit of WDT is set. So, wait till it
198 finishes (SYNCBUSY of STATUS register is automatically cleared after the
199 sync is finished).
200*/
201#define wdt_enable(timeout) \
202do { \
203uint8_t __temp; \
204__asm__ __volatile__ ( \
205 "in __tmp_reg__, %[rampd]" "\n\t" \
206 "out %[rampd], __zero_reg__" "\n\t" \
207 "out %[ccp_reg], %[ioreg_cen_mask]" "\n\t" \
208 "sts %[wdt_reg], %[wdt_enable_timeout]" "\n\t" \
209 "1:lds %[tmp], %[wdt_status_reg]" "\n\t" \
210 "sbrc %[tmp], %[wdt_syncbusy_bit]" "\n\t" \
211 "rjmp 1b" "\n\t" \
212 "out %[rampd], __tmp_reg__" \
213 : [tmp] "=r" (__temp) \
214 : [rampd] "I" (_SFR_IO_ADDR(RAMPD)), \
215 [ccp_reg] "I" (_SFR_IO_ADDR(CCP)), \
216 [ioreg_cen_mask] "r" ((uint8_t)CCP_IOREG_gc), \
217 [wdt_reg] "n" (_SFR_MEM_ADDR(WDT_CTRL)), \
218 [wdt_enable_timeout] "r" ((uint8_t)(WDT_CEN_bm | WDT_ENABLE_bm | timeout)), \
219 [wdt_status_reg] "n" (_SFR_MEM_ADDR(WDT_STATUS)), \
220 [wdt_syncbusy_bit] "I" (WDT_SYNCBUSY_bm) \
221 : "r0" \
222); \
223} while(0)
224
225#define wdt_disable() \
226__asm__ __volatile__ ( \
227 "in __tmp_reg__, %[rampd]" "\n\t" \
228 "out %[rampd], __zero_reg__" "\n\t" \
229 "out %[ccp_reg], %[ioreg_cen_mask]" "\n\t" \
230 "sts %[wdt_reg], %[disable_mask]" "\n\t" \
231 "out %[rampd], __tmp_reg__" \
232 : /* no outputs */ \
233 : [rampd] "I" (_SFR_IO_ADDR(RAMPD)), \
234 [ccp_reg] "I" (_SFR_IO_ADDR(CCP)), \
235 [ioreg_cen_mask] "r" ((uint8_t)CCP_IOREG_gc), \
236 [wdt_reg] "n" (_SFR_MEM_ADDR(WDT_CTRL)), \
237 [disable_mask] "r" ((uint8_t)((~WDT_ENABLE_bm) | WDT_CEN_bm)) \
238 : "r0" \
239)
240
241#endif // defined (WDT_CTRLA) && !defined(RAMPD)
242
243#elif defined(__AVR_TINY__)
244
245#define wdt_enable(value) \
246__asm__ __volatile__ ( \
247 "in __tmp_reg__,__SREG__" "\n\t" \
248 "cli" "\n\t" \
249 "wdr" "\n\t" \
250 "out %[CCPADDRESS],%[SIGNATURE]" "\n\t" \
251 "out %[WDTREG],%[WDVALUE]" "\n\t" \
252 "out __SREG__,__tmp_reg__" \
253 : /* no outputs */ \
254 : [CCPADDRESS] "I" (_SFR_IO_ADDR(CCP)), \
255 [SIGNATURE] "r" ((uint8_t)0xD8), \
256 [WDTREG] "I" (_SFR_IO_ADDR(_WD_CONTROL_REG)), \
257 [WDVALUE] "r" ((uint8_t)((value & 0x08 ? _WD_PS3_MASK : 0x00) \
258 | _BV(WDE) | (value & 0x07) )) \
259 : "r16" \
260)
261
262#define wdt_disable() \
263do { \
264uint8_t __temp_wd; \
265__asm__ __volatile__ ( \
266 "in __tmp_reg__,__SREG__" "\n\t" \
267 "cli" "\n\t" \
268 "wdr" "\n\t" \
269 "out %[CCPADDRESS],%[SIGNATURE]" "\n\t" \
270 "in %[TEMP_WD],%[WDTREG]" "\n\t" \
271 "cbr %[TEMP_WD],%[WDVALUE]" "\n\t" \
272 "out %[WDTREG],%[TEMP_WD]" "\n\t" \
273 "out __SREG__,__tmp_reg__" \
274 : [TEMP_WD] "=d" (__temp_wd) \
275 : [CCPADDRESS] "I" (_SFR_IO_ADDR(CCP)), \
276 [SIGNATURE] "r" ((uint8_t)0xD8), \
277 [WDTREG] "I" (_SFR_IO_ADDR(_WD_CONTROL_REG)), \
278 [WDVALUE] "n" (1 << WDE) \
279 : "r16" \
280); \
281} while(0)
282
283#elif defined(CCP)
284
285static __ATTR_ALWAYS_INLINE__
286void wdt_enable (const uint8_t value)
287{
288 if (!_SFR_IO_REG_P (CCP) && !_SFR_IO_REG_P (_WD_CONTROL_REG))
289 {
290 __asm__ __volatile__ (
291 "in __tmp_reg__,__SREG__" "\n\t"
292 "cli" "\n\t"
293 "wdr" "\n\t"
294 "sts %[CCPADDRESS],%[SIGNATURE]" "\n\t"
295 "sts %[WDTREG],%[WDVALUE]" "\n\t"
296 "out __SREG__,__tmp_reg__"
297 : /* no outputs */
298 : [CCPADDRESS] "n" (_SFR_MEM_ADDR(CCP)),
299 [SIGNATURE] "r" ((uint8_t)0xD8),
300 [WDTREG] "n" (_SFR_MEM_ADDR(_WD_CONTROL_REG)),
301 [WDVALUE] "r" ((uint8_t)((value & 0x08 ? _WD_PS3_MASK : 0x00)
302 | _BV(WDE) | (value & 0x07) ))
303 : "r0"
304 );
305 }
306 else if (!_SFR_IO_REG_P (CCP) && _SFR_IO_REG_P (_WD_CONTROL_REG))
307 {
308 __asm__ __volatile__ (
309 "in __tmp_reg__,__SREG__" "\n\t"
310 "cli" "\n\t"
311 "wdr" "\n\t"
312 "sts %[CCPADDRESS],%[SIGNATURE]" "\n\t"
313 "out %[WDTREG],%[WDVALUE]" "\n\t"
314 "out __SREG__,__tmp_reg__"
315 : /* no outputs */
316 : [CCPADDRESS] "n" (_SFR_MEM_ADDR(CCP)),
317 [SIGNATURE] "r" ((uint8_t)0xD8),
318 [WDTREG] "I" (_SFR_IO_ADDR(_WD_CONTROL_REG)),
319 [WDVALUE] "r" ((uint8_t)((value & 0x08 ? _WD_PS3_MASK : 0x00)
320 | _BV(WDE) | (value & 0x07) ))
321 : "r0"
322 );
323 }
324 else if (_SFR_IO_REG_P (CCP) && !_SFR_IO_REG_P (_WD_CONTROL_REG))
325 {
326 __asm__ __volatile__ (
327 "in __tmp_reg__,__SREG__" "\n\t"
328 "cli" "\n\t"
329 "wdr" "\n\t"
330 "out %[CCPADDRESS],%[SIGNATURE]" "\n\t"
331 "sts %[WDTREG],%[WDVALUE]" "\n\t"
332 "out __SREG__,__tmp_reg__"
333 : /* no outputs */
334 : [CCPADDRESS] "I" (_SFR_IO_ADDR(CCP)),
335 [SIGNATURE] "r" ((uint8_t)0xD8),
336 [WDTREG] "n" (_SFR_MEM_ADDR(_WD_CONTROL_REG)),
337 [WDVALUE] "r" ((uint8_t)((value & 0x08 ? _WD_PS3_MASK : 0x00)
338 | _BV(WDE) | (value & 0x07) ))
339 : "r0"
340 );
341 }
342 else
343 {
344 __asm__ __volatile__ (
345 "in __tmp_reg__,__SREG__" "\n\t"
346 "cli" "\n\t"
347 "wdr" "\n\t"
348 "out %[CCPADDRESS],%[SIGNATURE]" "\n\t"
349 "out %[WDTREG],%[WDVALUE]" "\n\t"
350 "out __SREG__,__tmp_reg__"
351 : /* no outputs */
352 : [CCPADDRESS] "I" (_SFR_IO_ADDR(CCP)),
353 [SIGNATURE] "r" ((uint8_t)0xD8),
354 [WDTREG] "I" (_SFR_IO_ADDR(_WD_CONTROL_REG)),
355 [WDVALUE] "r" ((uint8_t)((value & 0x08 ? _WD_PS3_MASK : 0x00)
356 | _BV(WDE) | (value & 0x07) ))
357 : "r0"
358 );
359 }
360}
361
362static __ATTR_ALWAYS_INLINE__
363void wdt_disable (void)
364{
365 if (!_SFR_IO_REG_P (CCP) && !_SFR_IO_REG_P(_WD_CONTROL_REG))
366 {
367 uint8_t __temp_wd;
368 __asm__ __volatile__ (
369 "in __tmp_reg__,__SREG__" "\n\t"
370 "cli" "\n\t"
371 "wdr" "\n\t"
372 "sts %[CCPADDRESS],%[SIGNATURE]" "\n\t"
373 "lds %[TEMP_WD],%[WDTREG]" "\n\t"
374 "cbr %[TEMP_WD],%[WDVALUE]" "\n\t"
375 "sts %[WDTREG],%[TEMP_WD]" "\n\t"
376 "out __SREG__,__tmp_reg__"
377 : [TEMP_WD] "=d" (__temp_wd)
378 : [CCPADDRESS] "n" (_SFR_MEM_ADDR(CCP)),
379 [SIGNATURE] "r" ((uint8_t)0xD8),
380 [WDTREG] "n" (_SFR_MEM_ADDR(_WD_CONTROL_REG)),
381 [WDVALUE] "n" (1 << WDE)
382 : "r0"
383 );
384 }
385 else if (!_SFR_IO_REG_P (CCP) && _SFR_IO_REG_P(_WD_CONTROL_REG))
386 {
387 uint8_t __temp_wd;
388 __asm__ __volatile__ (
389 "in __tmp_reg__,__SREG__" "\n\t"
390 "cli" "\n\t"
391 "wdr" "\n\t"
392 "sts %[CCPADDRESS],%[SIGNATURE]" "\n\t"
393 "in %[TEMP_WD],%[WDTREG]" "\n\t"
394 "cbr %[TEMP_WD],%[WDVALUE]" "\n\t"
395 "out %[WDTREG],%[TEMP_WD]" "\n\t"
396 "out __SREG__,__tmp_reg__"
397 : [TEMP_WD] "=d" (__temp_wd)
398 : [CCPADDRESS] "n" (_SFR_MEM_ADDR(CCP)),
399 [SIGNATURE] "r" ((uint8_t)0xD8),
400 [WDTREG] "I" (_SFR_IO_ADDR(_WD_CONTROL_REG)),
401 [WDVALUE] "n" (1 << WDE)
402 : "r0"
403 );
404 }
405 else if (_SFR_IO_REG_P (CCP) && !_SFR_IO_REG_P(_WD_CONTROL_REG))
406 {
407 uint8_t __temp_wd;
408 __asm__ __volatile__ (
409 "in __tmp_reg__,__SREG__" "\n\t"
410 "cli" "\n\t"
411 "wdr" "\n\t"
412 "out %[CCPADDRESS],%[SIGNATURE]" "\n\t"
413 "lds %[TEMP_WD],%[WDTREG]" "\n\t"
414 "cbr %[TEMP_WD],%[WDVALUE]" "\n\t"
415 "sts %[WDTREG],%[TEMP_WD]" "\n\t"
416 "out __SREG__,__tmp_reg__"
417 : [TEMP_WD] "=d" (__temp_wd)
418 : [CCPADDRESS] "I" (_SFR_IO_ADDR(CCP)),
419 [SIGNATURE] "r" ((uint8_t)0xD8),
420 [WDTREG] "n" (_SFR_MEM_ADDR(_WD_CONTROL_REG)),
421 [WDVALUE] "n" (1 << WDE)
422 : "r0"
423 );
424 }
425 else
426 {
427 uint8_t __temp_wd;
428 __asm__ __volatile__ (
429 "in __tmp_reg__,__SREG__" "\n\t"
430 "cli" "\n\t"
431 "wdr" "\n\t"
432 "out %[CCPADDRESS],%[SIGNATURE]" "\n\t"
433 "in %[TEMP_WD],%[WDTREG]" "\n\t"
434 "cbr %[TEMP_WD],%[WDVALUE]" "\n\t"
435 "out %[WDTREG],%[TEMP_WD]" "\n\t"
436 "out __SREG__,__tmp_reg__"
437 : [TEMP_WD] "=d" (__temp_wd)
438 : [CCPADDRESS] "I" (_SFR_IO_ADDR(CCP)),
439 [SIGNATURE] "r" ((uint8_t)0xD8),
440 [WDTREG] "I" (_SFR_IO_ADDR(_WD_CONTROL_REG)),
441 [WDVALUE] "n" (1 << WDE)
442 : "r0"
443 );
444 }
445}
446
447#else
448
449static __ATTR_ALWAYS_INLINE__
450void wdt_enable (const uint8_t value)
451{
452 if (_SFR_IO_REG_P (_WD_CONTROL_REG))
453 {
454 __asm__ __volatile__ (
455 "in __tmp_reg__,__SREG__" "\n\t"
456 "cli" "\n\t"
457 "wdr" "\n\t"
458 "out %0, %1" "\n\t"
459 "out __SREG__,__tmp_reg__" "\n\t"
460 "out %0, %2"
461 : /* no outputs */
462 : "I" (_SFR_IO_ADDR(_WD_CONTROL_REG)),
463 "r" ((uint8_t)(_BV(_WD_CHANGE_BIT) | _BV(WDE))),
464 "r" ((uint8_t) ((value & 0x08 ? _WD_PS3_MASK : 0x00) |
465 _BV(WDE) | (value & 0x07)) )
466 : "r0"
467 );
468 }
469 else
470 {
471 __asm__ __volatile__ (
472 "in __tmp_reg__,__SREG__" "\n\t"
473 "cli" "\n\t"
474 "wdr" "\n\t"
475 "sts %0, %1" "\n\t"
476 "out __SREG__,__tmp_reg__" "\n\t"
477 "sts %0, %2"
478 : /* no outputs */
479 : "n" (_SFR_MEM_ADDR(_WD_CONTROL_REG)),
480 "r" ((uint8_t)(_BV(_WD_CHANGE_BIT) | _BV(WDE))),
481 "r" ((uint8_t) ((value & 0x08 ? _WD_PS3_MASK : 0x00) |
482 _BV(WDE) | (value & 0x07)) )
483 : "r0"
484 );
485 }
486}
487
488static __ATTR_ALWAYS_INLINE__
489void wdt_disable (void)
490{
491 if (_SFR_IO_REG_P (_WD_CONTROL_REG))
492 {
493 uint8_t __temp_reg;
494 __asm__ __volatile__ (
495 "in __tmp_reg__,__SREG__" "\n\t"
496 "cli" "\n\t"
497 "wdr" "\n\t"
498 "in %[TEMPREG],%[WDTREG]" "\n\t"
499 "ori %[TEMPREG],%[WDCE_WDE]" "\n\t"
500 "out %[WDTREG],%[TEMPREG]" "\n\t"
501 "out %[WDTREG],__zero_reg__" "\n\t"
502 "out __SREG__,__tmp_reg__"
503 : [TEMPREG] "=d" (__temp_reg)
504 : [WDTREG] "I" (_SFR_IO_ADDR(_WD_CONTROL_REG)),
505 [WDCE_WDE] "n" ((uint8_t)(_BV(_WD_CHANGE_BIT) | _BV(WDE)))
506 : "r0"
507 );
508 }
509 else
510 {
511 uint8_t __temp_reg;
512 __asm__ __volatile__ (
513 "in __tmp_reg__,__SREG__" "\n\t"
514 "cli" "\n\t"
515 "wdr" "\n\t"
516 "lds %[TEMPREG],%[WDTREG]" "\n\t"
517 "ori %[TEMPREG],%[WDCE_WDE]" "\n\t"
518 "sts %[WDTREG],%[TEMPREG]" "\n\t"
519 "sts %[WDTREG],__zero_reg__" "\n\t"
520 "out __SREG__,__tmp_reg__"
521 : [TEMPREG] "=d" (__temp_reg)
522 : [WDTREG] "n" (_SFR_MEM_ADDR(_WD_CONTROL_REG)),
523 [WDCE_WDE] "n" ((uint8_t)(_BV(_WD_CHANGE_BIT) | _BV(WDE)))
524 : "r0"
525 );
526 }
527}
528
529#endif
530
531
532/**
533 \ingroup avr_watchdog
534 Symbolic constants for the watchdog timeout. Since the watchdog
535 timer is based on a free-running RC oscillator, the times are
536 approximate only and apply to a supply voltage of 5 V. At lower
537 supply voltages, the times will increase. For older devices, the
538 times will be as large as three times when operating at Vcc = 3 V,
539 while the newer devices (e. g. ATmega128, ATmega8) only experience
540 a negligible change.
541
542 Possible timeout values are: 15 ms, 30 ms, 60 ms, 120 ms, 250 ms,
543 500 ms, 1 s, 2 s. (Some devices also allow for 4 s and 8 s.)
544 Symbolic constants are formed by the prefix
545 \c WDTO_, followed by the time.
546
547 Example that would select a watchdog timer expiry of approximately
548 500 ms:
549 \code
550 wdt_enable(WDTO_500MS);
551 \endcode
552*/
553#define WDTO_15MS 0
554
555/** \ingroup avr_watchdog
556 See \c WDTO_15MS */
557#define WDTO_30MS 1
558
559/** \ingroup avr_watchdog
560 See \c WDTO_15MS */
561#define WDTO_60MS 2
562
563/** \ingroup avr_watchdog
564 See \c WDTO_15MS */
565#define WDTO_120MS 3
566
567/** \ingroup avr_watchdog
568 See \c WDTO_15MS */
569#define WDTO_250MS 4
570
571/** \ingroup avr_watchdog
572 See \c WDTO_15MS */
573#define WDTO_500MS 5
574
575/** \ingroup avr_watchdog
576 See \c WDTO_15MS */
577#define WDTO_1S 6
578
579/** \ingroup avr_watchdog
580 See \c WDTO_15MS */
581#define WDTO_2S 7
582
583#if defined(__DOXYGEN__) || defined(WDP3)
584
585/** \ingroup avr_watchdog
586 See \c WDTO_15MS
587 Note: This is only available on the
588 ATtiny2313,
589 ATtiny24, ATtiny44, ATtiny84, ATtiny84A,
590 ATtiny25, ATtiny45, ATtiny85,
591 ATtiny261, ATtiny461, ATtiny861,
592 ATmega48*, ATmega88*, ATmega168*, ATmega328*,
593 ATmega164P, ATmega324P, ATmega324PB, ATmega644P, ATmega644,
594 ATmega640, ATmega1280, ATmega1281, ATmega2560, ATmega2561,
595 ATmega8HVA, ATmega16HVA, ATmega32HVB,
596 ATmega406, ATmega1284P,
597 AT90PWM1, AT90PWM2, AT90PWM2B, AT90PWM3, AT90PWM3B, AT90PWM216, AT90PWM316,
598 AT90PWM81, AT90PWM161,
599 AT90USB82, AT90USB162,
600 AT90USB646, AT90USB647, AT90USB1286, AT90USB1287,
601 ATtiny48, ATtiny88.
602
603 Note: This value does <em>not</em> match the bit pattern of the
604 respective control register. It is solely meant to be used together
605 with wdt_enable().
606 */
607#define WDTO_4S 8
608
609/** \ingroup avr_watchdog
610 See \c WDTO_15MS
611 Note: This is only available on the
612 ATtiny2313,
613 ATtiny24, ATtiny44, ATtiny84, ATtiny84A,
614 ATtiny25, ATtiny45, ATtiny85,
615 ATtiny261, ATtiny461, ATtiny861,
616 ATmega48*, ATmega88*, ATmega168*, ATmega328*,
617 ATmega164P, ATmega324P, ATmega324PB, ATmega644P, ATmega644,
618 ATmega640, ATmega1280, ATmega1281, ATmega2560, ATmega2561,
619 ATmega8HVA, ATmega16HVA, ATmega32HVB,
620 ATmega406, ATmega1284P,
621 ATmega2564RFR2, ATmega256RFR2, ATmega1284RFR2, ATmega128RFR2, ATmega644RFR2, ATmega64RFR2
622 AT90PWM1, AT90PWM2, AT90PWM2B, AT90PWM3, AT90PWM3B, AT90PWM216, AT90PWM316,
623 AT90PWM81, AT90PWM161,
624 AT90USB82, AT90USB162,
625 AT90USB646, AT90USB647, AT90USB1286, AT90USB1287,
626 ATtiny48, ATtiny88,
627 ATxmega16a4u, ATxmega32a4u,
628 ATxmega16c4, ATxmega32c4,
629 ATxmega128c3, ATxmega192c3, ATxmega256c3.
630
631 Note: This value does <em>not</em> match the bit pattern of the
632 respective control register. It is solely meant to be used together
633 with wdt_enable().
634 */
635#define WDTO_8S 9
636
637#endif /* defined(__DOXYGEN__) || defined(WDP3) */
638
639
640#endif /* _AVR_WDT_H_ */
#define _BV(bit)
Definition: sfr_defs.h:208
unsigned char uint8_t
Definition: stdint.h:83
#define wdt_enable(timeout)
Definition: wdt.h:140