avr-libc  2.0.0
Standard C library for AVR-GCC
 

AVR Libc Home Page

AVRs

AVR Libc Development Pages

Main Page

User Manual

Library Reference

FAQ

Example Projects

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 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#if defined (WDT_CTRLA) && !defined(RAMPD)
141
142#define wdt_enable(timeout) \
143do { \
144uint8_t temp; \
145__asm__ __volatile__ ( \
146 "wdr" "\n\t" \
147 "out %[ccp_reg], %[ioreg_cen_mask]" "\n\t" \
148 "lds %[tmp], %[wdt_reg]" "\n\t" \
149 "sbr %[tmp], %[wdt_enable_timeout]" "\n\t" \
150 "sts %[wdt_reg], %[tmp]" "\n\t" \
151 "1:lds %[tmp], %[wdt_status_reg]" "\n\t" \
152 "sbrc %[tmp], %[wdt_syncbusy_bit]" "\n\t" \
153 "rjmp 1b" "\n\t" \
154 : [tmp] "=r" (temp) \
155 : [ccp_reg] "I" (_SFR_IO_ADDR(CCP)), \
156 [ioreg_cen_mask] "r" ((uint8_t)CCP_IOREG_gc), \
157 [wdt_reg] "n" (_SFR_MEM_ADDR(WDT_CTRLA)), \
158 [wdt_enable_timeout] "M" (timeout), \
159 [wdt_status_reg] "n" (_SFR_MEM_ADDR(WDT_STATUS)), \
160 [wdt_syncbusy_bit] "I" (WDT_SYNCBUSY_bm) \
161); \
162} while(0)
163
164#define wdt_disable() \
165do { \
166uint8_t temp; \
167__asm__ __volatile__ ( \
168 "wdr" "\n\t" \
169 "out %[ccp_reg], %[ioreg_cen_mask]" "\n\t" \
170 "lds %[tmp], %[wdt_reg]" "\n\t" \
171 "cbr %[tmp], %[timeout_mask]" "\n\t" \
172 "sts %[wdt_reg], %[tmp]" "\n\t" \
173 : [tmp] "=r" (temp) \
174 : [ccp_reg] "I" (_SFR_IO_ADDR(CCP)), \
175 [ioreg_cen_mask] "r" ((uint8_t)CCP_IOREG_gc), \
176 [wdt_reg] "n" (_SFR_MEM_ADDR(WDT_CTRLA)),\
177 [timeout_mask] "I" (WDT_PERIOD_gm) \
178); \
179} while(0)
180
181#else // defined (WDT_CTRLA) && !defined(RAMPD)
182
183/*
184 wdt_enable(timeout) for xmega devices
185** write signature (CCP_IOREG_gc) that enables change of protected I/O
186 registers to the CCP register
187** At the same time,
188 1) set WDT change enable (WDT_CEN_bm)
189 2) enable WDT (WDT_ENABLE_bm)
190 3) set timeout (timeout)
191** Synchronization starts when ENABLE bit of WDT is set. So, wait till it
192 finishes (SYNCBUSY of STATUS register is automatically cleared after the
193 sync is finished).
194*/
195#define wdt_enable(timeout) \
196do { \
197uint8_t temp; \
198__asm__ __volatile__ ( \
199 "in __tmp_reg__, %[rampd]" "\n\t" \
200 "out %[rampd], __zero_reg__" "\n\t" \
201 "out %[ccp_reg], %[ioreg_cen_mask]" "\n\t" \
202 "sts %[wdt_reg], %[wdt_enable_timeout]" "\n\t" \
203 "1:lds %[tmp], %[wdt_status_reg]" "\n\t" \
204 "sbrc %[tmp], %[wdt_syncbusy_bit]" "\n\t" \
205 "rjmp 1b" "\n\t" \
206 "out %[rampd], __tmp_reg__" "\n\t" \
207 : [tmp] "=r" (temp) \
208 : [rampd] "I" (_SFR_IO_ADDR(RAMPD)), \
209 [ccp_reg] "I" (_SFR_IO_ADDR(CCP)), \
210 [ioreg_cen_mask] "r" ((uint8_t)CCP_IOREG_gc), \
211 [wdt_reg] "n" (_SFR_MEM_ADDR(WDT_CTRL)), \
212 [wdt_enable_timeout] "r" ((uint8_t)(WDT_CEN_bm | WDT_ENABLE_bm | timeout)), \
213 [wdt_status_reg] "n" (_SFR_MEM_ADDR(WDT_STATUS)), \
214 [wdt_syncbusy_bit] "I" (WDT_SYNCBUSY_bm) \
215 : "r0" \
216); \
217} while(0)
218
219#define wdt_disable() \
220__asm__ __volatile__ ( \
221 "in __tmp_reg__, %[rampd]" "\n\t" \
222 "out %[rampd], __zero_reg__" "\n\t" \
223 "out %[ccp_reg], %[ioreg_cen_mask]" "\n\t" \
224 "sts %[wdt_reg], %[disable_mask]" "\n\t" \
225 "out %[rampd], __tmp_reg__" "\n\t" \
226 : \
227 : [rampd] "I" (_SFR_IO_ADDR(RAMPD)), \
228 [ccp_reg] "I" (_SFR_IO_ADDR(CCP)), \
229 [ioreg_cen_mask] "r" ((uint8_t)CCP_IOREG_gc), \
230 [wdt_reg] "n" (_SFR_MEM_ADDR(WDT_CTRL)), \
231 [disable_mask] "r" ((uint8_t)((~WDT_ENABLE_bm) | WDT_CEN_bm)) \
232 : "r0" \
233);
234
235#endif // defined (WDT_CTRLA) && !defined(RAMPD)
236
237#elif defined(__AVR_TINY__)
238
239#define wdt_enable(value) \
240__asm__ __volatile__ ( \
241 "in __tmp_reg__,__SREG__" "\n\t" \
242 "cli" "\n\t" \
243 "wdr" "\n\t" \
244 "out %[CCPADDRESS],%[SIGNATURE]" "\n\t" \
245 "out %[WDTREG],%[WDVALUE]" "\n\t" \
246 "out __SREG__,__tmp_reg__" "\n\t" \
247 : /* no outputs */ \
248 : [CCPADDRESS] "I" (_SFR_IO_ADDR(CCP)), \
249 [SIGNATURE] "r" ((uint8_t)0xD8), \
250 [WDTREG] "I" (_SFR_IO_ADDR(_WD_CONTROL_REG)), \
251 [WDVALUE] "r" ((uint8_t)((value & 0x08 ? _WD_PS3_MASK : 0x00) \
252 | _BV(WDE) | (value & 0x07) )) \
253 : "r16" \
254)
255
256#define wdt_disable() \
257do { \
258uint8_t temp_wd; \
259__asm__ __volatile__ ( \
260 "in __tmp_reg__,__SREG__" "\n\t" \
261 "cli" "\n\t" \
262 "wdr" "\n\t" \
263 "out %[CCPADDRESS],%[SIGNATURE]" "\n\t" \
264 "in %[TEMP_WD],%[WDTREG]" "\n\t" \
265 "cbr %[TEMP_WD],%[WDVALUE]" "\n\t" \
266 "out %[WDTREG],%[TEMP_WD]" "\n\t" \
267 "out __SREG__,__tmp_reg__" "\n\t" \
268 : /*no output */ \
269 : [CCPADDRESS] "I" (_SFR_IO_ADDR(CCP)), \
270 [SIGNATURE] "r" ((uint8_t)0xD8), \
271 [WDTREG] "I" (_SFR_IO_ADDR(_WD_CONTROL_REG)), \
272 [TEMP_WD] "d" (temp_wd), \
273 [WDVALUE] "n" (1 << WDE) \
274 : "r16" \
275); \
276}while(0)
277
278#elif defined(CCP)
279
280static __inline__
281__attribute__ ((__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__" "\n\t"
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__" "\n\t"
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__" "\n\t"
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__" "\n\t"
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 __inline__
359__attribute__ ((__always_inline__))
360void wdt_disable (void)
361{
362 if (!_SFR_IO_REG_P (CCP) && !_SFR_IO_REG_P(_WD_CONTROL_REG))
363 {
364 uint8_t temp_wd;
365 __asm__ __volatile__ (
366 "in __tmp_reg__,__SREG__" "\n\t"
367 "cli" "\n\t"
368 "wdr" "\n\t"
369 "sts %[CCPADDRESS],%[SIGNATURE]" "\n\t"
370 "lds %[TEMP_WD],%[WDTREG]" "\n\t"
371 "cbr %[TEMP_WD],%[WDVALUE]" "\n\t"
372 "sts %[WDTREG],%[TEMP_WD]" "\n\t"
373 "out __SREG__,__tmp_reg__" "\n\t"
374 : /*no output */
375 : [CCPADDRESS] "n" (_SFR_MEM_ADDR(CCP)),
376 [SIGNATURE] "r" ((uint8_t)0xD8),
377 [WDTREG] "n" (_SFR_MEM_ADDR(_WD_CONTROL_REG)),
378 [TEMP_WD] "d" (temp_wd),
379 [WDVALUE] "n" (1 << WDE)
380 : "r0"
381 );
382 }
383 else if (!_SFR_IO_REG_P (CCP) && _SFR_IO_REG_P(_WD_CONTROL_REG))
384 {
385 uint8_t temp_wd;
386 __asm__ __volatile__ (
387 "in __tmp_reg__,__SREG__" "\n\t"
388 "cli" "\n\t"
389 "wdr" "\n\t"
390 "sts %[CCPADDRESS],%[SIGNATURE]" "\n\t"
391 "in %[TEMP_WD],%[WDTREG]" "\n\t"
392 "cbr %[TEMP_WD],%[WDVALUE]" "\n\t"
393 "out %[WDTREG],%[TEMP_WD]" "\n\t"
394 "out __SREG__,__tmp_reg__" "\n\t"
395 : /*no output */
396 : [CCPADDRESS] "n" (_SFR_MEM_ADDR(CCP)),
397 [SIGNATURE] "r" ((uint8_t)0xD8),
398 [WDTREG] "I" (_SFR_IO_ADDR(_WD_CONTROL_REG)),
399 [TEMP_WD] "d" (temp_wd),
400 [WDVALUE] "n" (1 << WDE)
401 : "r0"
402 );
403 }
404 else if (_SFR_IO_REG_P (CCP) && !_SFR_IO_REG_P(_WD_CONTROL_REG))
405 {
406 uint8_t temp_wd;
407 __asm__ __volatile__ (
408 "in __tmp_reg__,__SREG__" "\n\t"
409 "cli" "\n\t"
410 "wdr" "\n\t"
411 "out %[CCPADDRESS],%[SIGNATURE]" "\n\t"
412 "lds %[TEMP_WD],%[WDTREG]" "\n\t"
413 "cbr %[TEMP_WD],%[WDVALUE]" "\n\t"
414 "sts %[WDTREG],%[TEMP_WD]" "\n\t"
415 "out __SREG__,__tmp_reg__" "\n\t"
416 : /*no output */
417 : [CCPADDRESS] "I" (_SFR_IO_ADDR(CCP)),
418 [SIGNATURE] "r" ((uint8_t)0xD8),
419 [WDTREG] "n" (_SFR_MEM_ADDR(_WD_CONTROL_REG)),
420 [TEMP_WD] "d" (temp_wd),
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__" "\n\t"
437 : /*no output */
438 : [CCPADDRESS] "I" (_SFR_IO_ADDR(CCP)),
439 [SIGNATURE] "r" ((uint8_t)0xD8),
440 [WDTREG] "I" (_SFR_IO_ADDR(_WD_CONTROL_REG)),
441 [TEMP_WD] "d" (temp_wd),
442 [WDVALUE] "n" (1 << WDE)
443 : "r0"
444 );
445 }
446}
447
448#else
449
450static __inline__
451__attribute__ ((__always_inline__))
452void wdt_enable (const uint8_t value)
453{
454 if (_SFR_IO_REG_P (_WD_CONTROL_REG))
455 {
456 __asm__ __volatile__ (
457 "in __tmp_reg__,__SREG__" "\n\t"
458 "cli" "\n\t"
459 "wdr" "\n\t"
460 "out %0, %1" "\n\t"
461 "out __SREG__,__tmp_reg__" "\n\t"
462 "out %0, %2" "\n \t"
463 : /* no outputs */
464 : "I" (_SFR_IO_ADDR(_WD_CONTROL_REG)),
465 "r" ((uint8_t)(_BV(_WD_CHANGE_BIT) | _BV(WDE))),
466 "r" ((uint8_t) ((value & 0x08 ? _WD_PS3_MASK : 0x00) |
467 _BV(WDE) | (value & 0x07)) )
468 : "r0"
469 );
470 }
471 else
472 {
473 __asm__ __volatile__ (
474 "in __tmp_reg__,__SREG__" "\n\t"
475 "cli" "\n\t"
476 "wdr" "\n\t"
477 "sts %0, %1" "\n\t"
478 "out __SREG__,__tmp_reg__" "\n\t"
479 "sts %0, %2" "\n \t"
480 : /* no outputs */
481 : "n" (_SFR_MEM_ADDR(_WD_CONTROL_REG)),
482 "r" ((uint8_t)(_BV(_WD_CHANGE_BIT) | _BV(WDE))),
483 "r" ((uint8_t) ((value & 0x08 ? _WD_PS3_MASK : 0x00) |
484 _BV(WDE) | (value & 0x07)) )
485 : "r0"
486 );
487 }
488}
489
490static __inline__
491__attribute__ ((__always_inline__))
492void wdt_disable (void)
493{
494 if (_SFR_IO_REG_P (_WD_CONTROL_REG))
495 {
496 uint8_t register temp_reg;
497 __asm__ __volatile__ (
498 "in __tmp_reg__,__SREG__" "\n\t"
499 "cli" "\n\t"
500 "wdr" "\n\t"
501 "in %[TEMPREG],%[WDTREG]" "\n\t"
502 "ori %[TEMPREG],%[WDCE_WDE]" "\n\t"
503 "out %[WDTREG],%[TEMPREG]" "\n\t"
504 "out %[WDTREG],__zero_reg__" "\n\t"
505 "out __SREG__,__tmp_reg__" "\n\t"
506 : [TEMPREG] "=d" (temp_reg)
507 : [WDTREG] "I" (_SFR_IO_ADDR(_WD_CONTROL_REG)),
508 [WDCE_WDE] "n" ((uint8_t)(_BV(_WD_CHANGE_BIT) | _BV(WDE)))
509 : "r0"
510 );
511 }
512 else
513 {
514 uint8_t register temp_reg;
515 __asm__ __volatile__ (
516 "in __tmp_reg__,__SREG__" "\n\t"
517 "cli" "\n\t"
518 "wdr" "\n\t"
519 "lds %[TEMPREG],%[WDTREG]" "\n\t"
520 "ori %[TEMPREG],%[WDCE_WDE]" "\n\t"
521 "sts %[WDTREG],%[TEMPREG]" "\n\t"
522 "sts %[WDTREG],__zero_reg__" "\n\t"
523 "out __SREG__,__tmp_reg__" "\n\t"
524 : [TEMPREG] "=d" (temp_reg)
525 : [WDTREG] "n" (_SFR_MEM_ADDR(_WD_CONTROL_REG)),
526 [WDCE_WDE] "n" ((uint8_t)(_BV(_WD_CHANGE_BIT) | _BV(WDE)))
527 : "r0"
528 );
529 }
530}
531
532#endif
533
534
535/**
536 \ingroup avr_watchdog
537 Symbolic constants for the watchdog timeout. Since the watchdog
538 timer is based on a free-running RC oscillator, the times are
539 approximate only and apply to a supply voltage of 5 V. At lower
540 supply voltages, the times will increase. For older devices, the
541 times will be as large as three times when operating at Vcc = 3 V,
542 while the newer devices (e. g. ATmega128, ATmega8) only experience
543 a negligible change.
544
545 Possible timeout values are: 15 ms, 30 ms, 60 ms, 120 ms, 250 ms,
546 500 ms, 1 s, 2 s. (Some devices also allow for 4 s and 8 s.)
547 Symbolic constants are formed by the prefix
548 \c WDTO_, followed by the time.
549
550 Example that would select a watchdog timer expiry of approximately
551 500 ms:
552 \code
553 wdt_enable(WDTO_500MS);
554 \endcode
555*/
556#define WDTO_15MS 0
557
558/** \ingroup avr_watchdog
559 See \c WDTO_15MS */
560#define WDTO_30MS 1
561
562/** \ingroup avr_watchdog
563 See \c WDTO_15MS */
564#define WDTO_60MS 2
565
566/** \ingroup avr_watchdog
567 See \c WDTO_15MS */
568#define WDTO_120MS 3
569
570/** \ingroup avr_watchdog
571 See \c WDTO_15MS */
572#define WDTO_250MS 4
573
574/** \ingroup avr_watchdog
575 See \c WDTO_15MS */
576#define WDTO_500MS 5
577
578/** \ingroup avr_watchdog
579 See \c WDTO_15MS */
580#define WDTO_1S 6
581
582/** \ingroup avr_watchdog
583 See \c WDTO_15MS */
584#define WDTO_2S 7
585
586#if defined(__DOXYGEN__) || defined(WDP3)
587
588/** \ingroup avr_watchdog
589 See \c WDTO_15MS
590 Note: This is only available on the
591 ATtiny2313,
592 ATtiny24, ATtiny44, ATtiny84, ATtiny84A,
593 ATtiny25, ATtiny45, ATtiny85,
594 ATtiny261, ATtiny461, ATtiny861,
595 ATmega48, ATmega88, ATmega168,
596 ATmega48P, ATmega88P, ATmega168P, ATmega328P,
597 ATmega164P, ATmega324P, ATmega644P, ATmega644,
598 ATmega640, ATmega1280, ATmega1281, ATmega2560, ATmega2561,
599 ATmega8HVA, ATmega16HVA, ATmega32HVB,
600 ATmega406, ATmega1284P,
601 AT90PWM1, AT90PWM2, AT90PWM2B, AT90PWM3, AT90PWM3B, AT90PWM216, AT90PWM316,
602 AT90PWM81, AT90PWM161,
603 AT90USB82, AT90USB162,
604 AT90USB646, AT90USB647, AT90USB1286, AT90USB1287,
605 ATtiny48, ATtiny88.
606
607 Note: This value does <em>not</em> match the bit pattern of the
608 respective control register. It is solely meant to be used together
609 with wdt_enable().
610 */
611#define WDTO_4S 8
612
613/** \ingroup avr_watchdog
614 See \c WDTO_15MS
615 Note: This is only available on the
616 ATtiny2313,
617 ATtiny24, ATtiny44, ATtiny84, ATtiny84A,
618 ATtiny25, ATtiny45, ATtiny85,
619 ATtiny261, ATtiny461, ATtiny861,
620 ATmega48, ATmega48A, ATmega48PA, ATmega88, ATmega168,
621 ATmega48P, ATmega88P, ATmega168P, ATmega328P,
622 ATmega164P, ATmega324P, ATmega644P, ATmega644,
623 ATmega640, ATmega1280, ATmega1281, ATmega2560, ATmega2561,
624 ATmega8HVA, ATmega16HVA, ATmega32HVB,
625 ATmega406, ATmega1284P,
626 ATmega2564RFR2, ATmega256RFR2, ATmega1284RFR2, ATmega128RFR2, ATmega644RFR2, ATmega64RFR2
627 AT90PWM1, AT90PWM2, AT90PWM2B, AT90PWM3, AT90PWM3B, AT90PWM216, AT90PWM316,
628 AT90PWM81, AT90PWM161,
629 AT90USB82, AT90USB162,
630 AT90USB646, AT90USB647, AT90USB1286, AT90USB1287,
631 ATtiny48, ATtiny88,
632 ATxmega16a4u, ATxmega32a4u,
633 ATxmega16c4, ATxmega32c4,
634 ATxmega128c3, ATxmega192c3, ATxmega256c3.
635
636 Note: This value does <em>not</em> match the bit pattern of the
637 respective control register. It is solely meant to be used together
638 with wdt_enable().
639 */
640#define WDTO_8S 9
641
642#endif /* defined(__DOXYGEN__) || defined(WDP3) */
643
644
645#endif /* _AVR_WDT_H_ */
#define _BV(bit)
Definition sfr_defs.h:208
unsigned char uint8_t
Definition stdint.h:83
static __inline__ __attribute__((__always_inline__)) void wdt_enable(const uint8_t value)
Definition wdt.h:451