AVR-LibC  2.3.0git
Standard C library for AVR-GCC
 

AVR-LibC Documen­tation

AVR-LibC Development Pages

Main Page

User Manual

Library Refe­rence

FAQ

Example Projects

File List

Index

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/*
33 avr/wdt.h - macros for AVR watchdog timer
34 */
35
36#ifndef _AVR_WDT_H_
37#define _AVR_WDT_H_
38
39#include <avr/io.h>
40#include <stdint.h>
41
42/** \file */
43/** \defgroup avr_watchdog <avr/wdt.h>: Watchdog timer handling
44 \code #include <avr/wdt.h> \endcode
45
46 This header file declares the interface to some inline macros
47 handling the watchdog timer present in many AVR devices. In order
48 to prevent the watchdog timer configuration from being
49 accidentally altered by a crashing application, a special timed
50 sequence is required in order to change it. The macros within
51 this header file handle the required sequence automatically
52 before changing any value. Interrupts will be disabled during
53 the manipulation.
54
55 \note Depending on the fuse configuration of the particular
56 device, further restrictions might apply, in particular it might
57 be disallowed to turn off the watchdog timer.
58
59 Note that for newer devices (ATmega88 and newer, effectively any
60 AVR that has the option to also generate interrupts), the watchdog
61 timer remains active even after a system reset (except a power-on
62 condition), using the fastest prescaler value (approximately 15
63 ms). It is therefore required to turn off the watchdog early
64 during program startup, the datasheet recommends a sequence like
65 the following:
66
67 \code
68 #include <stdint.h>
69 #include <avr/wdt.h>
70
71 uint8_t mcusr_mirror __attribute__ ((section (".noinit")));
72
73 __attribute__((used, unused, naked, section(".init3")))
74 static void get_mcusr (void);
75
76 void get_mcusr (void)
77 {
78 mcusr_mirror = MCUSR;
79 MCUSR = 0;
80 wdt_disable();
81 }
82 \endcode
83
84 Saving the value of MCUSR in \c mcusr_mirror is only needed if the
85 application later wants to examine the reset source, but in particular,
86 clearing the watchdog reset flag before disabling the
87 watchdog is required, according to the datasheet.
88*/
89
90/**
91 \ingroup avr_watchdog
92 Reset the watchdog timer. When the watchdog timer is enabled,
93 a call to this instruction is required before the timer expires,
94 otherwise a watchdog-initiated device reset will occur.
95*/
96
97#define wdt_reset() __asm__ __volatile__ ("wdr")
98
99#ifndef __DOXYGEN__
100
101#include <bits/attribs.h>
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#ifdef __DOXYGEN__
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#define wdt_enable(timeout)
137#endif /* __DOXYGEN__ */
138
139
140#if defined(__AVR_XMEGA__)
141
142#if defined (WDT_CTRLA) && !defined(RAMPD)
143
144#define wdt_enable(timeout) \
145do { \
146uint8_t __temp; \
147__asm__ __volatile__ ( \
148 "wdr" "\n\t" \
149 "out %[ccp_reg], %[ioreg_cen_mask]" "\n\t" \
150 "lds %[tmp], %[wdt_reg]" "\n\t" \
151 "sbr %[tmp], %[wdt_enable_timeout]" "\n\t" \
152 "sts %[wdt_reg], %[tmp]" "\n\t" \
153 "1:lds %[tmp], %[wdt_status_reg]" "\n\t" \
154 "sbrc %[tmp], %[wdt_syncbusy_bit]" "\n\t" \
155 "rjmp 1b" \
156 : [tmp] "=d" (__temp) \
157 : [ccp_reg] "I" (_SFR_IO_ADDR(CCP)), \
158 [ioreg_cen_mask] "r" ((uint8_t)CCP_IOREG_gc), \
159 [wdt_reg] "n" (_SFR_MEM_ADDR(WDT_CTRLA)), \
160 [wdt_enable_timeout] "M" (timeout), \
161 [wdt_status_reg] "n" (_SFR_MEM_ADDR(WDT_STATUS)), \
162 [wdt_syncbusy_bit] "I" (WDT_SYNCBUSY_bm) \
163); \
164} while(0)
165
166#define wdt_disable() \
167do { \
168uint8_t __temp; \
169__asm__ __volatile__ ( \
170 "wdr" "\n\t" \
171 "out %[ccp_reg], %[ioreg_cen_mask]" "\n\t" \
172 "lds %[tmp], %[wdt_reg]" "\n\t" \
173 "cbr %[tmp], %[timeout_mask]" "\n\t" \
174 "sts %[wdt_reg], %[tmp]" \
175 : [tmp] "=d" (__temp) \
176 : [ccp_reg] "I" (_SFR_IO_ADDR(CCP)), \
177 [ioreg_cen_mask] "r" ((uint8_t)CCP_IOREG_gc), \
178 [wdt_reg] "n" (_SFR_MEM_ADDR(WDT_CTRLA)),\
179 [timeout_mask] "I" (WDT_PERIOD_gm) \
180); \
181} while(0)
182
183#else // defined (WDT_CTRLA) && !defined(RAMPD)
184
185/*
186 wdt_enable(timeout) for xmega devices
187** write signature (CCP_IOREG_gc) that enables change of protected I/O
188 registers to the CCP register
189** At the same time,
190 1) set WDT change enable (WDT_CEN_bm)
191 2) enable WDT (WDT_ENABLE_bm)
192 3) set timeout (timeout)
193** Synchronization starts when ENABLE bit of WDT is set. So, wait till it
194 finishes (SYNCBUSY of STATUS register is automatically cleared after the
195 sync is finished).
196*/
197#define wdt_enable(timeout) \
198do { \
199uint8_t __temp; \
200__asm__ __volatile__ ( \
201 "in __tmp_reg__, %[rampd]" "\n\t" \
202 "out %[rampd], __zero_reg__" "\n\t" \
203 "out %[ccp_reg], %[ioreg_cen_mask]" "\n\t" \
204 "sts %[wdt_reg], %[wdt_enable_timeout]" "\n\t" \
205 "1:lds %[tmp], %[wdt_status_reg]" "\n\t" \
206 "sbrc %[tmp], %[wdt_syncbusy_bit]" "\n\t" \
207 "rjmp 1b" "\n\t" \
208 "out %[rampd], __tmp_reg__" \
209 : [tmp] "=r" (__temp) \
210 : [rampd] "I" (_SFR_IO_ADDR(RAMPD)), \
211 [ccp_reg] "I" (_SFR_IO_ADDR(CCP)), \
212 [ioreg_cen_mask] "r" ((uint8_t)CCP_IOREG_gc), \
213 [wdt_reg] "n" (_SFR_MEM_ADDR(WDT_CTRL)), \
214 [wdt_enable_timeout] "r" ((uint8_t)(WDT_CEN_bm | WDT_ENABLE_bm | ((timeout + 1) << 2))), \
215 [wdt_status_reg] "n" (_SFR_MEM_ADDR(WDT_STATUS)), \
216 [wdt_syncbusy_bit] "I" (WDT_SYNCBUSY_bm) \
217 : "r0" \
218); \
219} while(0)
220
221#define wdt_disable() \
222__asm__ __volatile__ ( \
223 "in __tmp_reg__, %[rampd]" "\n\t" \
224 "out %[rampd], __zero_reg__" "\n\t" \
225 "out %[ccp_reg], %[ioreg_cen_mask]" "\n\t" \
226 "sts %[wdt_reg], %[disable_mask]" "\n\t" \
227 "out %[rampd], __tmp_reg__" \
228 : /* no outputs */ \
229 : [rampd] "I" (_SFR_IO_ADDR(RAMPD)), \
230 [ccp_reg] "I" (_SFR_IO_ADDR(CCP)), \
231 [ioreg_cen_mask] "r" ((uint8_t)CCP_IOREG_gc), \
232 [wdt_reg] "n" (_SFR_MEM_ADDR(WDT_CTRL)), \
233 [disable_mask] "r" ((uint8_t)((~WDT_ENABLE_bm) | WDT_CEN_bm)) \
234 : "r0" \
235)
236
237#endif // defined (WDT_CTRLA) && !defined(RAMPD)
238
239#elif defined(__AVR_TINY__)
240
241#define wdt_enable(value) \
242__asm__ __volatile__ ( \
243 "in __tmp_reg__,__SREG__" "\n\t" \
244 "cli" "\n\t" \
245 "wdr" "\n\t" \
246 "out %[CCPADDRESS],%[SIGNATURE]" "\n\t" \
247 "out %[WDTREG],%[WDVALUE]" "\n\t" \
248 "out __SREG__,__tmp_reg__" \
249 : /* no outputs */ \
250 : [CCPADDRESS] "I" (_SFR_IO_ADDR(CCP)), \
251 [SIGNATURE] "r" ((uint8_t)0xD8), \
252 [WDTREG] "I" (_SFR_IO_ADDR(_WD_CONTROL_REG)), \
253 [WDVALUE] "r" ((uint8_t)((value & 0x08 ? _WD_PS3_MASK : 0x00) \
254 | _BV(WDE) | (value & 0x07) )) \
255 : "r16" \
256)
257
258#define wdt_disable() \
259do { \
260uint8_t __temp_wd; \
261__asm__ __volatile__ ( \
262 "in __tmp_reg__,__SREG__" "\n\t" \
263 "cli" "\n\t" \
264 "wdr" "\n\t" \
265 "out %[CCPADDRESS],%[SIGNATURE]" "\n\t" \
266 "in %[TEMP_WD],%[WDTREG]" "\n\t" \
267 "cbr %[TEMP_WD],%[WDVALUE]" "\n\t" \
268 "out %[WDTREG],%[TEMP_WD]" "\n\t" \
269 "out __SREG__,__tmp_reg__" \
270 : [TEMP_WD] "=d" (__temp_wd) \
271 : [CCPADDRESS] "I" (_SFR_IO_ADDR(CCP)), \
272 [SIGNATURE] "r" ((uint8_t)0xD8), \
273 [WDTREG] "I" (_SFR_IO_ADDR(_WD_CONTROL_REG)), \
274 [WDVALUE] "n" (1 << WDE) \
275 : "r16" \
276); \
277} while(0)
278
279#elif defined(CCP)
280
281static __ATTR_ALWAYS_INLINE__
282void wdt_enable (const uint8_t value)
283{
284 if (!_SFR_IO_REG_P (CCP) && !_SFR_IO_REG_P (_WD_CONTROL_REG))
285 {
286 __asm__ __volatile__ (
287 "in __tmp_reg__,__SREG__" "\n\t"
288 "cli" "\n\t"
289 "wdr" "\n\t"
290 "sts %[CCPADDRESS],%[SIGNATURE]" "\n\t"
291 "sts %[WDTREG],%[WDVALUE]" "\n\t"
292 "out __SREG__,__tmp_reg__"
293 : /* no outputs */
294 : [CCPADDRESS] "n" (_SFR_MEM_ADDR(CCP)),
295 [SIGNATURE] "r" ((uint8_t)0xD8),
296 [WDTREG] "n" (_SFR_MEM_ADDR(_WD_CONTROL_REG)),
297 [WDVALUE] "r" ((uint8_t)((value & 0x08 ? _WD_PS3_MASK : 0x00)
298 | _BV(WDE) | (value & 0x07) ))
299 : "r0"
300 );
301 }
302 else if (!_SFR_IO_REG_P (CCP) && _SFR_IO_REG_P (_WD_CONTROL_REG))
303 {
304 __asm__ __volatile__ (
305 "in __tmp_reg__,__SREG__" "\n\t"
306 "cli" "\n\t"
307 "wdr" "\n\t"
308 "sts %[CCPADDRESS],%[SIGNATURE]" "\n\t"
309 "out %[WDTREG],%[WDVALUE]" "\n\t"
310 "out __SREG__,__tmp_reg__"
311 : /* no outputs */
312 : [CCPADDRESS] "n" (_SFR_MEM_ADDR(CCP)),
313 [SIGNATURE] "r" ((uint8_t)0xD8),
314 [WDTREG] "I" (_SFR_IO_ADDR(_WD_CONTROL_REG)),
315 [WDVALUE] "r" ((uint8_t)((value & 0x08 ? _WD_PS3_MASK : 0x00)
316 | _BV(WDE) | (value & 0x07) ))
317 : "r0"
318 );
319 }
320 else if (_SFR_IO_REG_P (CCP) && !_SFR_IO_REG_P (_WD_CONTROL_REG))
321 {
322 __asm__ __volatile__ (
323 "in __tmp_reg__,__SREG__" "\n\t"
324 "cli" "\n\t"
325 "wdr" "\n\t"
326 "out %[CCPADDRESS],%[SIGNATURE]" "\n\t"
327 "sts %[WDTREG],%[WDVALUE]" "\n\t"
328 "out __SREG__,__tmp_reg__"
329 : /* no outputs */
330 : [CCPADDRESS] "I" (_SFR_IO_ADDR(CCP)),
331 [SIGNATURE] "r" ((uint8_t)0xD8),
332 [WDTREG] "n" (_SFR_MEM_ADDR(_WD_CONTROL_REG)),
333 [WDVALUE] "r" ((uint8_t)((value & 0x08 ? _WD_PS3_MASK : 0x00)
334 | _BV(WDE) | (value & 0x07) ))
335 : "r0"
336 );
337 }
338 else
339 {
340 __asm__ __volatile__ (
341 "in __tmp_reg__,__SREG__" "\n\t"
342 "cli" "\n\t"
343 "wdr" "\n\t"
344 "out %[CCPADDRESS],%[SIGNATURE]" "\n\t"
345 "out %[WDTREG],%[WDVALUE]" "\n\t"
346 "out __SREG__,__tmp_reg__"
347 : /* no outputs */
348 : [CCPADDRESS] "I" (_SFR_IO_ADDR(CCP)),
349 [SIGNATURE] "r" ((uint8_t)0xD8),
350 [WDTREG] "I" (_SFR_IO_ADDR(_WD_CONTROL_REG)),
351 [WDVALUE] "r" ((uint8_t)((value & 0x08 ? _WD_PS3_MASK : 0x00)
352 | _BV(WDE) | (value & 0x07) ))
353 : "r0"
354 );
355 }
356}
357
358static __ATTR_ALWAYS_INLINE__
359void wdt_disable (void)
360{
361 if (!_SFR_IO_REG_P (CCP) && !_SFR_IO_REG_P(_WD_CONTROL_REG))
362 {
363 uint8_t __temp_wd;
364 __asm__ __volatile__ (
365 "in __tmp_reg__,__SREG__" "\n\t"
366 "cli" "\n\t"
367 "wdr" "\n\t"
368 "sts %[CCPADDRESS],%[SIGNATURE]" "\n\t"
369 "lds %[TEMP_WD],%[WDTREG]" "\n\t"
370 "cbr %[TEMP_WD],%[WDVALUE]" "\n\t"
371 "sts %[WDTREG],%[TEMP_WD]" "\n\t"
372 "out __SREG__,__tmp_reg__"
373 : [TEMP_WD] "=d" (__temp_wd)
374 : [CCPADDRESS] "n" (_SFR_MEM_ADDR(CCP)),
375 [SIGNATURE] "r" ((uint8_t)0xD8),
376 [WDTREG] "n" (_SFR_MEM_ADDR(_WD_CONTROL_REG)),
377 [WDVALUE] "n" (1 << WDE)
378 : "r0"
379 );
380 }
381 else if (!_SFR_IO_REG_P (CCP) && _SFR_IO_REG_P(_WD_CONTROL_REG))
382 {
383 uint8_t __temp_wd;
384 __asm__ __volatile__ (
385 "in __tmp_reg__,__SREG__" "\n\t"
386 "cli" "\n\t"
387 "wdr" "\n\t"
388 "sts %[CCPADDRESS],%[SIGNATURE]" "\n\t"
389 "in %[TEMP_WD],%[WDTREG]" "\n\t"
390 "cbr %[TEMP_WD],%[WDVALUE]" "\n\t"
391 "out %[WDTREG],%[TEMP_WD]" "\n\t"
392 "out __SREG__,__tmp_reg__"
393 : [TEMP_WD] "=d" (__temp_wd)
394 : [CCPADDRESS] "n" (_SFR_MEM_ADDR(CCP)),
395 [SIGNATURE] "r" ((uint8_t)0xD8),
396 [WDTREG] "I" (_SFR_IO_ADDR(_WD_CONTROL_REG)),
397 [WDVALUE] "n" (1 << WDE)
398 : "r0"
399 );
400 }
401 else if (_SFR_IO_REG_P (CCP) && !_SFR_IO_REG_P(_WD_CONTROL_REG))
402 {
403 uint8_t __temp_wd;
404 __asm__ __volatile__ (
405 "in __tmp_reg__,__SREG__" "\n\t"
406 "cli" "\n\t"
407 "wdr" "\n\t"
408 "out %[CCPADDRESS],%[SIGNATURE]" "\n\t"
409 "lds %[TEMP_WD],%[WDTREG]" "\n\t"
410 "cbr %[TEMP_WD],%[WDVALUE]" "\n\t"
411 "sts %[WDTREG],%[TEMP_WD]" "\n\t"
412 "out __SREG__,__tmp_reg__"
413 : [TEMP_WD] "=d" (__temp_wd)
414 : [CCPADDRESS] "I" (_SFR_IO_ADDR(CCP)),
415 [SIGNATURE] "r" ((uint8_t)0xD8),
416 [WDTREG] "n" (_SFR_MEM_ADDR(_WD_CONTROL_REG)),
417 [WDVALUE] "n" (1 << WDE)
418 : "r0"
419 );
420 }
421 else
422 {
423 uint8_t __temp_wd;
424 __asm__ __volatile__ (
425 "in __tmp_reg__,__SREG__" "\n\t"
426 "cli" "\n\t"
427 "wdr" "\n\t"
428 "out %[CCPADDRESS],%[SIGNATURE]" "\n\t"
429 "in %[TEMP_WD],%[WDTREG]" "\n\t"
430 "cbr %[TEMP_WD],%[WDVALUE]" "\n\t"
431 "out %[WDTREG],%[TEMP_WD]" "\n\t"
432 "out __SREG__,__tmp_reg__"
433 : [TEMP_WD] "=d" (__temp_wd)
434 : [CCPADDRESS] "I" (_SFR_IO_ADDR(CCP)),
435 [SIGNATURE] "r" ((uint8_t)0xD8),
436 [WDTREG] "I" (_SFR_IO_ADDR(_WD_CONTROL_REG)),
437 [WDVALUE] "n" (1 << WDE)
438 : "r0"
439 );
440 }
441}
442
443#else
444
445static __ATTR_ALWAYS_INLINE__
446void wdt_enable (const uint8_t value)
447{
448 if (_SFR_IO_REG_P (_WD_CONTROL_REG))
449 {
450 __asm__ __volatile__ (
451 "in __tmp_reg__,__SREG__" "\n\t"
452 "cli" "\n\t"
453 "wdr" "\n\t"
454 "out %0, %1" "\n\t"
455 "out __SREG__,__tmp_reg__" "\n\t"
456 "out %0, %2"
457 : /* no outputs */
458 : "I" (_SFR_IO_ADDR(_WD_CONTROL_REG)),
459 "r" ((uint8_t)(_BV(_WD_CHANGE_BIT) | _BV(WDE))),
460 "r" ((uint8_t) ((value & 0x08 ? _WD_PS3_MASK : 0x00) |
461 _BV(WDE) | (value & 0x07)) )
462 : "r0"
463 );
464 }
465 else
466 {
467 __asm__ __volatile__ (
468 "in __tmp_reg__,__SREG__" "\n\t"
469 "cli" "\n\t"
470 "wdr" "\n\t"
471 "sts %0, %1" "\n\t"
472 "out __SREG__,__tmp_reg__" "\n\t"
473 "sts %0, %2"
474 : /* no outputs */
475 : "n" (_SFR_MEM_ADDR(_WD_CONTROL_REG)),
476 "r" ((uint8_t)(_BV(_WD_CHANGE_BIT) | _BV(WDE))),
477 "r" ((uint8_t) ((value & 0x08 ? _WD_PS3_MASK : 0x00) |
478 _BV(WDE) | (value & 0x07)) )
479 : "r0"
480 );
481 }
482}
483
484static __ATTR_ALWAYS_INLINE__
485void wdt_disable (void)
486{
487 if (_SFR_IO_REG_P (_WD_CONTROL_REG))
488 {
489 uint8_t __temp_reg;
490 __asm__ __volatile__ (
491 "in __tmp_reg__,__SREG__" "\n\t"
492 "cli" "\n\t"
493 "wdr" "\n\t"
494 "in %[TEMPREG],%[WDTREG]" "\n\t"
495 "ori %[TEMPREG],%[WDCE_WDE]" "\n\t"
496 "out %[WDTREG],%[TEMPREG]" "\n\t"
497 "out %[WDTREG],__zero_reg__" "\n\t"
498 "out __SREG__,__tmp_reg__"
499 : [TEMPREG] "=d" (__temp_reg)
500 : [WDTREG] "I" (_SFR_IO_ADDR(_WD_CONTROL_REG)),
501 [WDCE_WDE] "n" ((uint8_t)(_BV(_WD_CHANGE_BIT) | _BV(WDE)))
502 : "r0"
503 );
504 }
505 else
506 {
507 uint8_t __temp_reg;
508 __asm__ __volatile__ (
509 "in __tmp_reg__,__SREG__" "\n\t"
510 "cli" "\n\t"
511 "wdr" "\n\t"
512 "lds %[TEMPREG],%[WDTREG]" "\n\t"
513 "ori %[TEMPREG],%[WDCE_WDE]" "\n\t"
514 "sts %[WDTREG],%[TEMPREG]" "\n\t"
515 "sts %[WDTREG],__zero_reg__" "\n\t"
516 "out __SREG__,__tmp_reg__"
517 : [TEMPREG] "=d" (__temp_reg)
518 : [WDTREG] "n" (_SFR_MEM_ADDR(_WD_CONTROL_REG)),
519 [WDCE_WDE] "n" ((uint8_t)(_BV(_WD_CHANGE_BIT) | _BV(WDE)))
520 : "r0"
521 );
522 }
523}
524
525#endif
526
527
528/**
529 \ingroup avr_watchdog
530 Symbolic constants for the watchdog timeout. Since the watchdog
531 timer is based on a free-running RC oscillator, the times are
532 approximate only and apply to a supply voltage of 5 V. At lower
533 supply voltages, the times will increase. For older devices, the
534 times will be as large as three times when operating at Vcc = 3 V,
535 while the newer devices (e. g. ATmega128, ATmega8) only experience
536 a negligible change.
537
538 Possible timeout values are: 15 ms, 30 ms, 60 ms, 120 ms, 250 ms,
539 500 ms, 1 s, 2 s. (Some devices also allow for 4 s and 8 s.)
540 Symbolic constants are formed by the prefix
541 \c WDTO_, followed by the time.
542
543 Example that would select a watchdog timer expiry of approximately
544 500 ms:
545 \code
546 wdt_enable(WDTO_500MS);
547 \endcode
548*/
549#if defined(__DOXYGEN__) || defined(__AVR_XMEGA__)
550#define WDTO_8MS -1
551#endif
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) || defined(__AVR_XMEGA__)
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#endif /* _AVR_WDT_H_ */
#define _BV(bit)
Definition: sfr_defs.h:206
unsigned char uint8_t
Definition: stdint.h:81
#define wdt_enable(timeout)
Definition: wdt.h:136