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

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) \
143 do { \
144 uint8_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() \
165 do { \
166 uint8_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) \
196 do { \
197 uint8_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() \
257 do { \
258 uint8_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 
280 static __inline__
281 __attribute__ ((__always_inline__))
282 void 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 
358 static __inline__
359 __attribute__ ((__always_inline__))
360 void 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 
450 static __inline__
451 __attribute__ ((__always_inline__))
452 void 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 
490 static __inline__
491 __attribute__ ((__always_inline__))
492 void 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 #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, ATmega48A, ATmega48PA, ATmega88, ATmega168,
617  ATmega48P, ATmega88P, ATmega168P, ATmega328P,
618  ATmega164P, ATmega324P, ATmega644P, ATmega644,
619  ATmega640, ATmega1280, ATmega1281, ATmega2560, ATmega2561,
620  ATmega8HVA, ATmega16HVA, ATmega32HVB,
621  ATmega406, ATmega1284P,
622  ATmega2564RFR2, ATmega256RFR2, ATmega1284RFR2, ATmega128RFR2, ATmega644RFR2, ATmega64RFR2
623  AT90PWM1, AT90PWM2, AT90PWM2B, AT90PWM3, AT90PWM3B, AT90PWM216, AT90PWM316,
624  AT90PWM81, AT90PWM161,
625  AT90USB82, AT90USB162,
626  AT90USB646, AT90USB647, AT90USB1286, AT90USB1287,
627  ATtiny48, ATtiny88,
628  ATxmega16a4u, ATxmega32a4u,
629  ATxmega16c4, ATxmega32c4,
630  ATxmega128c3, ATxmega192c3, ATxmega256c3.
631  */
632 #define WDTO_8S 9
633 
634 #endif /* defined(__DOXYGEN__) || defined(WDP3) */
635 
636 
637 #endif /* _AVR_WDT_H_ */
unsigned char uint8_t
Definition: stdint.h:83
#define _BV(bit)
Definition: sfr_defs.h:208
static __inline__ __attribute__((__always_inline__)) void wdt_enable(const uint8_t value)
Definition: wdt.h:451