AVR Libc Home Page AVRs AVR Libc Development Pages
Main Page User Manual Library Reference FAQ Alphabetical Index 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 
102 #if defined(WDP3)
103 # define _WD_PS3_MASK _BV(WDP3)
104 #else
105 # define _WD_PS3_MASK 0x00
106 #endif
107 
108 #if defined(WDTCSR)
109 # define _WD_CONTROL_REG WDTCSR
110 #elif defined(WDTCR)
111 # define _WD_CONTROL_REG WDTCR
112 #else
113 # define _WD_CONTROL_REG WDT
114 #endif
115 
116 #if defined(WDTOE)
117 #define _WD_CHANGE_BIT WDTOE
118 #else
119 #define _WD_CHANGE_BIT WDCE
120 #endif
121 
122 
123 /**
124  \ingroup avr_watchdog
125  Enable the watchdog timer, configuring it for expiry after
126  \c timeout (which is a combination of the \c WDP0 through
127  \c WDP2 bits to write into the \c WDTCR register; For those devices
128  that have a \c WDTCSR register, it uses the combination of the \c WDP0
129  through \c WDP3 bits).
130 
131  See also the symbolic constants \c WDTO_15MS et al.
132 */
133 
134 
135 #if defined(__AVR_ATxmega16A4__) \
136 || defined(__AVR_ATxmega16A4U__) \
137 || defined(__AVR_ATxmega16C4__) \
138 || defined(__AVR_ATxmega16D4__) \
139 || defined(__AVR_ATxmega32A4__) \
140 || defined(__AVR_ATxmega32A4U__) \
141 || defined(__AVR_ATxmega32C3__) \
142 || defined(__AVR_ATxmega32C4__) \
143 || defined(__AVR_ATxmega32D3__) \
144 || defined(__AVR_ATxmega32D4__) \
145 || defined(__AVR_ATxmega8E5__) \
146 || defined(__AVR_ATxmega16E5__) \
147 || defined(__AVR_ATxmega32E5__) \
148 || defined(__AVR_ATxmega64A1__) \
149 || defined(__AVR_ATxmega64A1U__) \
150 || defined(__AVR_ATxmega64A3__) \
151 || defined(__AVR_ATxmega64A3U__) \
152 || defined(__AVR_ATxmega64A4U__) \
153 || defined(__AVR_ATxmega64B1__) \
154 || defined(__AVR_ATxmega64B3__) \
155 || defined(__AVR_ATxmega64C3__) \
156 || defined(__AVR_ATxmega64D3__) \
157 || defined(__AVR_ATxmega64D4__) \
158 || defined(__AVR_ATxmega128A1__) \
159 || defined(__AVR_ATxmega128A1U__) \
160 || defined(__AVR_ATxmega128A3__) \
161 || defined(__AVR_ATxmega128A3U__) \
162 || defined(__AVR_ATxmega128A4U__) \
163 || defined(__AVR_ATxmega128B1__) \
164 || defined(__AVR_ATxmega128B3__) \
165 || defined(__AVR_ATxmega128C3__) \
166 || defined(__AVR_ATxmega128D3__) \
167 || defined(__AVR_ATxmega128D4__) \
168 || defined(__AVR_ATxmega192A3__) \
169 || defined(__AVR_ATxmega192A3U__) \
170 || defined(__AVR_ATxmega192C3__) \
171 || defined(__AVR_ATxmega192D3__) \
172 || defined(__AVR_ATxmega256A3__) \
173 || defined(__AVR_ATxmega256A3U__) \
174 || defined(__AVR_ATxmega256C3__) \
175 || defined(__AVR_ATxmega256D3__) \
176 || defined(__AVR_ATxmega256A3B__) \
177 || defined(__AVR_ATxmega256A3BU__) \
178 || defined(__AVR_ATxmega384C3__) \
179 || defined(__AVR_ATxmega384D3__)
180 
181 /*
182  wdt_enable(timeout) for xmega devices
183 ** write signature (CCP_IOREG_gc) that enables change of protected I/O
184  registers to the CCP register
185 ** At the same time,
186  1) set WDT change enable (WDT_CEN_bm)
187  2) enable WDT (WDT_ENABLE_bm)
188  3) set timeout (timeout)
189 ** Synchronization starts when ENABLE bit of WDT is set. So, wait till it
190  finishes (SYNCBUSY of STATUS register is automatically cleared after the
191  sync is finished).
192 */
193 #define wdt_enable(timeout) \
194 do { \
195 uint8_t temp = 0; \
196 __asm__ __volatile__ ( \
197  "in __tmp_reg__, %[rampd]" "\n\t" \
198  "out %[rampd], __zero_reg__" "\n\t" \
199  "out %[ccp_reg], %[ioreg_cen_mask]" "\n\t" \
200  "sts %[wdt_reg], %[wdt_enable_timeout]" "\n\t" \
201  "1:lds %[tmp], %[wdt_status_reg]" "\n\t" \
202  "sbrc %[tmp], %[wdt_syncbusy_bit]" "\n\t" \
203  "rjmp 1b" "\n\t" \
204  "out %[rampd], __tmp_reg__" "\n\t" \
205  : "=r" (temp) \
206  : [rampd] "M" (_SFR_MEM_ADDR(RAMPD)), \
207  [ccp_reg] "I" (_SFR_MEM_ADDR(CCP)), \
208  [ioreg_cen_mask] "r" ((uint8_t)CCP_IOREG_gc), \
209  [wdt_reg] "M" (_SFR_MEM_ADDR(WDT_CTRL)), \
210  [wdt_enable_timeout] "r" ((uint8_t)(WDT_CEN_bm | WDT_ENABLE_bm | timeout)), \
211  [wdt_status_reg] "M" (_SFR_MEM_ADDR(WDT_STATUS)), \
212  [wdt_syncbusy_bit] "I" (WDT_SYNCBUSY_bm), \
213  [tmp] "r" (temp) \
214  : "r0" \
215 ); \
216 } while(0)
217 
218 #define wdt_disable() \
219 __asm__ __volatile__ ( \
220  "in __tmp_reg__, %[rampd]" "\n\t" \
221  "out %[rampd], __zero_reg__" "\n\t" \
222  "out %[ccp_reg], %[ioreg_cen_mask]" "\n\t" \
223  "sts %[wdt_reg], %[disable_mask]" "\n\t" \
224  "out %[rampd], __tmp_reg__" "\n\t" \
225  : \
226  : [rampd] "M" (_SFR_MEM_ADDR(RAMPD)), \
227  [ccp_reg] "I" (_SFR_MEM_ADDR(CCP)), \
228  [ioreg_cen_mask] "r" ((uint8_t)CCP_IOREG_gc), \
229  [wdt_reg] "M" (_SFR_MEM_ADDR(WDT_CTRL)), \
230  [disable_mask] "r" ((uint8_t)((~WDT_ENABLE_bm) | WDT_CEN_bm)) \
231  : "r0" \
232 );
233 
234 #elif defined(__AVR_AT90CAN32__) \
235 || defined(__AVR_AT90CAN64__) \
236 || defined(__AVR_AT90CAN128__) \
237 || defined(__AVR_AT90PWM1__) \
238 || defined(__AVR_AT90PWM2__) \
239 || defined(__AVR_AT90PWM216__) \
240 || defined(__AVR_AT90PWM2B__) \
241 || defined(__AVR_AT90PWM3__) \
242 || defined(__AVR_AT90PWM316__) \
243 || defined(__AVR_AT90PWM3B__) \
244 || defined(__AVR_AT90PWM161__) \
245 || defined(__AVR_AT90PWM81__) \
246 || defined(__AVR_AT90USB1286__) \
247 || defined(__AVR_AT90USB1287__) \
248 || defined(__AVR_AT90USB162__) \
249 || defined(__AVR_AT90USB646__) \
250 || defined(__AVR_AT90USB647__) \
251 || defined(__AVR_AT90USB82__) \
252 || defined(__AVR_ATmega128A__) \
253 || defined(__AVR_ATmega1280__) \
254 || defined(__AVR_ATmega1281__) \
255 || defined(__AVR_ATmega1284__) \
256 || defined(__AVR_ATmega1284P__) \
257 || defined(__AVR_ATmega128RFA1__) \
258 || defined(__AVR_ATmega128RFR2__) \
259 || defined(__AVR_ATmega1284RFR2__) \
260 || defined(__AVR_ATmega164__) \
261 || defined(__AVR_ATmega164A__) \
262 || defined(__AVR_ATmega164P__) \
263 || defined(__AVR_ATmega164PA__) \
264 || defined(__AVR_ATmega165__) \
265 || defined(__AVR_ATmega165A__) \
266 || defined(__AVR_ATmega165P__) \
267 || defined(__AVR_ATmega165PA__) \
268 || defined(__AVR_ATmega168__) \
269 || defined(__AVR_ATmega168A__) \
270 || defined(__AVR_ATmega168P__) \
271 || defined(__AVR_ATmega168PA__) \
272 || defined(__AVR_ATmega168PB__) \
273 || defined(__AVR_ATmega169__) \
274 || defined(__AVR_ATmega169A__) \
275 || defined(__AVR_ATmega169P__) \
276 || defined(__AVR_ATmega169PA__) \
277 || defined(__AVR_ATmega16HVA__) \
278 || defined(__AVR_ATmega16HVA2__) \
279 || defined(__AVR_ATmega16HVB__) \
280 || defined(__AVR_ATmega16HVBREVB__) \
281 || defined(__AVR_ATmega16M1__) \
282 || defined(__AVR_ATmega16U2__) \
283 || defined(__AVR_ATmega16U4__) \
284 || defined(__AVR_ATmega2560__) \
285 || defined(__AVR_ATmega2561__) \
286 || defined(__AVR_ATmega256RFR2__) \
287 || defined(__AVR_ATmega2564RFR2__) \
288 || defined(__AVR_ATmega32A__) \
289 || defined(__AVR_ATmega324__) \
290 || defined(__AVR_ATmega324A__) \
291 || defined(__AVR_ATmega324P__) \
292 || defined(__AVR_ATmega324PA__) \
293 || defined(__AVR_ATmega325__) \
294 || defined(__AVR_ATmega325A__) \
295 || defined(__AVR_ATmega325P__) \
296 || defined(__AVR_ATmega325PA__) \
297 || defined(__AVR_ATmega3250__) \
298 || defined(__AVR_ATmega3250A__) \
299 || defined(__AVR_ATmega3250P__) \
300 || defined(__AVR_ATmega3250PA__) \
301 || defined(__AVR_ATmega328__) \
302 || defined(__AVR_ATmega328P__) \
303 || defined(__AVR_ATmega329__) \
304 || defined(__AVR_ATmega329A__) \
305 || defined(__AVR_ATmega329P__) \
306 || defined(__AVR_ATmega329PA__) \
307 || defined(__AVR_ATmega3290__) \
308 || defined(__AVR_ATmega3290A__) \
309 || defined(__AVR_ATmega3290P__) \
310 || defined(__AVR_ATmega3290PA__) \
311 || defined(__AVR_ATmega32C1__) \
312 || defined(__AVR_ATmega32HVB__) \
313 || defined(__AVR_ATmega32HVBREVB__) \
314 || defined(__AVR_ATmega32M1__) \
315 || defined(__AVR_ATmega32U2__) \
316 || defined(__AVR_ATmega32U4__) \
317 || defined(__AVR_ATmega32U6__) \
318 || defined(__AVR_ATmega406__) \
319 || defined(__AVR_ATmega48__) \
320 || defined(__AVR_ATmega48A__) \
321 || defined(__AVR_ATmega48PA__) \
322 || defined(__AVR_ATmega48PB__) \
323 || defined(__AVR_ATmega48P__) \
324 || defined(__AVR_ATmega64A__) \
325 || defined(__AVR_ATmega64RFR2__) \
326 || defined(__AVR_ATmega644RFR2__) \
327 || defined(__AVR_ATmega640__) \
328 || defined(__AVR_ATmega644__) \
329 || defined(__AVR_ATmega644A__) \
330 || defined(__AVR_ATmega644P__) \
331 || defined(__AVR_ATmega644PA__) \
332 || defined(__AVR_ATmega645__) \
333 || defined(__AVR_ATmega645A__) \
334 || defined(__AVR_ATmega645P__) \
335 || defined(__AVR_ATmega6450__) \
336 || defined(__AVR_ATmega6450A__) \
337 || defined(__AVR_ATmega6450P__) \
338 || defined(__AVR_ATmega649__) \
339 || defined(__AVR_ATmega649A__) \
340 || defined(__AVR_ATmega6490__) \
341 || defined(__AVR_ATmega6490A__) \
342 || defined(__AVR_ATmega6490P__) \
343 || defined(__AVR_ATmega649P__) \
344 || defined(__AVR_ATmega64C1__) \
345 || defined(__AVR_ATmega64HVE__) \
346 || defined(__AVR_ATmega64HVE2__) \
347 || defined(__AVR_ATmega64M1__) \
348 || defined(__AVR_ATmega8A__) \
349 || defined(__AVR_ATmega88__) \
350 || defined(__AVR_ATmega88A__) \
351 || defined(__AVR_ATmega88P__) \
352 || defined(__AVR_ATmega88PA__) \
353 || defined(__AVR_ATmega88PB__) \
354 || defined(__AVR_ATmega8HVA__) \
355 || defined(__AVR_ATmega8U2__) \
356 || defined(__AVR_ATtiny48__) \
357 || defined(__AVR_ATtiny88__) \
358 || defined(__AVR_ATtiny87__) \
359 || defined(__AVR_ATtiny167__) \
360 || defined(__AVR_AT90SCR100__) \
361 || defined(__AVR_ATA6285__) \
362 || defined(__AVR_ATA6286__) \
363 || defined(__AVR_ATA6289__) \
364 || defined(__AVR_ATA5272__) \
365 || defined(__AVR_ATA5505__) \
366 || defined(__AVR_ATA5790__) \
367 || defined(__AVR_ATA5790N__) \
368 || defined(__AVR_ATA5795__) \
369 || defined(__AVR_ATA5782__) \
370 || defined(__AVR_ATA5702M322__) \
371 || defined(__AVR_ATA5831__) \
372 || defined(__AVR_ATA6612C__) \
373 || defined(__AVR_ATA6613C__) \
374 || defined(__AVR_ATA6614Q__) \
375 || defined(__AVR_ATA6616C__) \
376 || defined(__AVR_ATA6617C__) \
377 || defined(__AVR_ATA664251__)
378 
379 /* Use STS instruction. */
380 
381 #define wdt_enable(value) \
382 __asm__ __volatile__ ( \
383  "in __tmp_reg__,__SREG__" "\n\t" \
384  "cli" "\n\t" \
385  "wdr" "\n\t" \
386  "sts %0,%1" "\n\t" \
387  "out __SREG__,__tmp_reg__" "\n\t" \
388  "sts %0,%2" "\n\t" \
389  : /* no outputs */ \
390  : "M" (_SFR_MEM_ADDR(_WD_CONTROL_REG)), \
391  "r" (_BV(_WD_CHANGE_BIT) | _BV(WDE)), \
392  "r" ((uint8_t) ((value & 0x08 ? _WD_PS3_MASK : 0x00) | \
393  _BV(WDE) | (value & 0x07)) ) \
394  : "r0" \
395 )
396 
397 #define wdt_disable() \
398 __asm__ __volatile__ ( \
399  "in __tmp_reg__, __SREG__" "\n\t" \
400  "cli" "\n\t" \
401  "sts %0, %1" "\n\t" \
402  "sts %0, __zero_reg__" "\n\t" \
403  "out __SREG__,__tmp_reg__" "\n\t" \
404  : /* no outputs */ \
405  : "M" (_SFR_MEM_ADDR(_WD_CONTROL_REG)), \
406  "r" ((uint8_t)(_BV(_WD_CHANGE_BIT) | _BV(WDE))) \
407  : "r0" \
408 )
409 
410 
411 #elif defined(__AVR_ATtiny441__) \
412 || defined(__AVR_ATtiny841__)
413 
414 /* Use STS instruction. */
415 
416 #define wdt_enable(value) \
417 __asm__ __volatile__ ( \
418  "in __tmp_reg__,__SREG__" "\n\t" \
419  "cli" "\n\t" \
420  "wdr" "\n\t" \
421  "sts %[CCPADDRESS],%[SIGNATURE]" "\n\t" \
422  "out %[WDTREG],%[WDVALUE]" "\n\t" \
423  "out __SREG__,__tmp_reg__" "\n\t" \
424  : /* no outputs */ \
425  : [CCPADDRESS] "M" (_SFR_MEM_ADDR(CCP)), \
426  [SIGNATURE] "r" ((uint8_t)0xD8), \
427  [WDTREG] "I" (_SFR_IO_ADDR(_WD_CONTROL_REG)), \
428  [WDVALUE] "r" ((uint8_t)((value & 0x08 ? _WD_PS3_MASK : 0x00) \
429  | _BV(WDE) | (value & 0x07) )) \
430  : "r0" \
431 )
432 
433 #define wdt_disable() \
434 do { \
435 uint8_t temp_wd; \
436 __asm__ __volatile__ ( \
437  "in __tmp_reg__,__SREG__" "\n\t" \
438  "cli" "\n\t" \
439  "wdr" "\n\t" \
440  "sts %[CCPADDRESS],%[SIGNATURE]" "\n\t" \
441  "in %[TEMP_WD],%[WDTREG]" "\n\t" \
442  "cbr %[TEMP_WD],%[WDVALUE]" "\n\t" \
443  "out %[WDTREG],%[TEMP_WD]" "\n\t" \
444  "out __SREG__,__tmp_reg__" "\n\t" \
445  : /*no output */ \
446  : [CCPADDRESS] "M" (_SFR_MEM_ADDR(CCP)), \
447  [SIGNATURE] "r" ((uint8_t)0xD8), \
448  [WDTREG] "I" (_SFR_IO_ADDR(_WD_CONTROL_REG)), \
449  [TEMP_WD] "d" (temp_wd), \
450  [WDVALUE] "I" (1 << WDE) \
451  : "r0" \
452 ); \
453 }while(0)
454 
455 #elif defined(__AVR_ATtiny1634__) \
456 || defined(__AVR_ATtiny828__)
457 
458 #define wdt_enable(value) \
459 __asm__ __volatile__ ( \
460  "in __tmp_reg__,__SREG__" "\n\t" \
461  "cli" "\n\t" \
462  "wdr" "\n\t" \
463  "sts %[CCPADDRESS],%[SIGNATURE]" "\n\t" \
464  "sts %[WDTREG],%[WDVALUE]" "\n\t" \
465  "out __SREG__,__tmp_reg__" "\n\t" \
466  : /* no outputs */ \
467  : [CCPADDRESS] "M" (_SFR_MEM_ADDR(CCP)), \
468  [SIGNATURE] "r" ((uint8_t)0xD8), \
469  [WDTREG] "M" (_SFR_MEM_ADDR(_WD_CONTROL_REG)), \
470  [WDVALUE] "r" ((uint8_t)((value & 0x08 ? _WD_PS3_MASK : 0x00) \
471  | _BV(WDE) | value)) \
472  : "r0" \
473 )
474 
475 #define wdt_disable() \
476 do { \
477 uint8_t temp_wd; \
478 __asm__ __volatile__ ( \
479  "in __tmp_reg__,__SREG__" "\n\t" \
480  "cli" "\n\t" \
481  "wdr" "\n\t" \
482  "out %[CCPADDRESS],%[SIGNATURE]" "\n\t" \
483  "in %[TEMP_WD],%[WDTREG]" "\n\t" \
484  "cbr %[TEMP_WD],%[WDVALUE]" "\n\t" \
485  "out %[WDTREG],%[TEMP_WD]" "\n\t" \
486  "out __SREG__,__tmp_reg__" "\n\t" \
487  : /*no output */ \
488  : [CCPADDRESS] "I" (_SFR_IO_ADDR(CCP)), \
489  [SIGNATURE] "r" ((uint8_t)0xD8), \
490  [WDTREG] "I" (_SFR_IO_ADDR(_WD_CONTROL_REG)), \
491  [TEMP_WD] "d" (temp_wd), \
492  [WDVALUE] "I" (1 << WDE) \
493  : "r0" \
494 ); \
495 }while(0)
496 
497 #elif defined(__AVR_ATtiny4__) \
498 || defined(__AVR_ATtiny5__) \
499 || defined(__AVR_ATtiny9__) \
500 || defined(__AVR_ATtiny10__) \
501 || defined(__AVR_ATtiny20__) \
502 || defined(__AVR_ATtiny40__)
503 
504 #define wdt_enable(value) \
505 __asm__ __volatile__ ( \
506  "in __tmp_reg__,__SREG__" "\n\t" \
507  "cli" "\n\t" \
508  "wdr" "\n\t" \
509  "out %[CCPADDRESS],%[SIGNATURE]" "\n\t" \
510  "out %[WDTREG],%[WDVALUE]" "\n\t" \
511  "out __SREG__,__tmp_reg__" "\n\t" \
512  : /* no outputs */ \
513  : [CCPADDRESS] "I" (_SFR_IO_ADDR(CCP)), \
514  [SIGNATURE] "r" ((uint8_t)0xD8), \
515  [WDTREG] "I" (_SFR_IO_ADDR(_WD_CONTROL_REG)), \
516  [WDVALUE] "r" ((uint8_t)((value & 0x08 ? _WD_PS3_MASK : 0x00) \
517  | _BV(WDE) | value)) \
518  : "r16" \
519 )
520 
521 #define wdt_disable() \
522 do { \
523 uint8_t temp_wd; \
524 __asm__ __volatile__ ( \
525  "in __tmp_reg__,__SREG__" "\n\t" \
526  "cli" "\n\t" \
527  "wdr" "\n\t" \
528  "out %[CCPADDRESS],%[SIGNATURE]" "\n\t" \
529  "in %[TEMP_WD],%[WDTREG]" "\n\t" \
530  "cbr %[TEMP_WD],%[WDVALUE]" "\n\t" \
531  "out %[WDTREG],%[TEMP_WD]" "\n\t" \
532  "out __SREG__,__tmp_reg__" "\n\t" \
533  : /*no output */ \
534  : [CCPADDRESS] "I" (_SFR_IO_ADDR(CCP)), \
535  [SIGNATURE] "r" ((uint8_t)0xD8), \
536  [WDTREG] "I" (_SFR_IO_ADDR(_WD_CONTROL_REG)), \
537  [TEMP_WD] "d" (temp_wd), \
538  [WDVALUE] "I" (1 << WDE) \
539  : "r16" \
540 ); \
541 }while(0)
542 
543 /**
544 Undefining explicitly so that it produces an error.
545  */
546 #elif defined(__AVR_AT90C8534__) \
547 || defined(__AVR_M3000__)
548  #undef wdt_enable
549  #undef wdt_disale
550 
551 #else
552 
553 /* Use OUT instruction. */
554 
555 #define wdt_enable(value) \
556  __asm__ __volatile__ ( \
557  "in __tmp_reg__,__SREG__" "\n\t" \
558  "cli" "\n\t" \
559  "wdr" "\n\t" \
560  "out %0,%1" "\n\t" \
561  "out __SREG__,__tmp_reg__" "\n\t" \
562  "out %0,%2" \
563  : /* no outputs */ \
564  : "I" (_SFR_IO_ADDR(_WD_CONTROL_REG)), \
565  "r" (_BV(_WD_CHANGE_BIT) | _BV(WDE)), \
566  "r" ((uint8_t) ((value & 0x08 ? _WD_PS3_MASK : 0x00) | \
567  _BV(WDE) | (value & 0x07)) ) \
568  : "r0" \
569  )
570 
571 /**
572  \ingroup avr_watchdog
573  Disable the watchdog timer, if possible. This attempts to turn off the
574  Enable bit in the watchdog control register. See the datasheet for
575  details.
576 */
577 #define wdt_disable() \
578 __asm__ __volatile__ ( \
579  "in __tmp_reg__, __SREG__" "\n\t" \
580  "cli" "\n\t" \
581  "out %0, %1" "\n\t" \
582  "out %0, __zero_reg__" "\n\t" \
583  "out __SREG__,__tmp_reg__" "\n\t" \
584  : /* no outputs */ \
585  : "I" (_SFR_IO_ADDR(_WD_CONTROL_REG)), \
586  "r" ((uint8_t)(_BV(_WD_CHANGE_BIT) | _BV(WDE))) \
587  : "r0" \
588 )
589 
590 #endif
591 
592 
593 
594 /**
595  \ingroup avr_watchdog
596  Symbolic constants for the watchdog timeout. Since the watchdog
597  timer is based on a free-running RC oscillator, the times are
598  approximate only and apply to a supply voltage of 5 V. At lower
599  supply voltages, the times will increase. For older devices, the
600  times will be as large as three times when operating at Vcc = 3 V,
601  while the newer devices (e. g. ATmega128, ATmega8) only experience
602  a negligible change.
603 
604  Possible timeout values are: 15 ms, 30 ms, 60 ms, 120 ms, 250 ms,
605  500 ms, 1 s, 2 s. (Some devices also allow for 4 s and 8 s.)
606  Symbolic constants are formed by the prefix
607  \c WDTO_, followed by the time.
608 
609  Example that would select a watchdog timer expiry of approximately
610  500 ms:
611  \code
612  wdt_enable(WDTO_500MS);
613  \endcode
614 */
615 #define WDTO_15MS 0
616 
617 /** \ingroup avr_watchdog
618  See \c WDT0_15MS */
619 #define WDTO_30MS 1
620 
621 /** \ingroup avr_watchdog See
622  \c WDT0_15MS */
623 #define WDTO_60MS 2
624 
625 /** \ingroup avr_watchdog
626  See \c WDT0_15MS */
627 #define WDTO_120MS 3
628 
629 /** \ingroup avr_watchdog
630  See \c WDT0_15MS */
631 #define WDTO_250MS 4
632 
633 /** \ingroup avr_watchdog
634  See \c WDT0_15MS */
635 #define WDTO_500MS 5
636 
637 /** \ingroup avr_watchdog
638  See \c WDT0_15MS */
639 #define WDTO_1S 6
640 
641 /** \ingroup avr_watchdog
642  See \c WDT0_15MS */
643 #define WDTO_2S 7
644 
645 #if defined(__DOXYGEN__) || defined(WDP3)
646 
647 /** \ingroup avr_watchdog
648  See \c WDT0_15MS
649  Note: This is only available on the
650  ATtiny2313,
651  ATtiny24, ATtiny44, ATtiny84, ATtiny84A,
652  ATtiny25, ATtiny45, ATtiny85,
653  ATtiny261, ATtiny461, ATtiny861,
654  ATmega48, ATmega88, ATmega168,
655  ATmega48P, ATmega88P, ATmega168P, ATmega328P,
656  ATmega164P, ATmega324P, ATmega644P, ATmega644,
657  ATmega640, ATmega1280, ATmega1281, ATmega2560, ATmega2561,
658  ATmega8HVA, ATmega16HVA, ATmega32HVB,
659  ATmega406, ATmega1284P,
660  ATmega256RFR2, ATmega128RFR2, ATmega64RFR2,
661  ATmega2564RFR2, ATmega1284RFR2, ATmega644RFR2,
662  AT90PWM1, AT90PWM2, AT90PWM2B, AT90PWM3, AT90PWM3B, AT90PWM216, AT90PWM316,
663  AT90PWM81, AT90PWM161,
664  AT90USB82, AT90USB162,
665  AT90USB646, AT90USB647, AT90USB1286, AT90USB1287,
666  ATtiny48, ATtiny88.
667  */
668 #define WDTO_4S 8
669 
670 /** \ingroup avr_watchdog
671  See \c WDT0_15MS
672  Note: This is only available on the
673  ATtiny2313,
674  ATtiny24, ATtiny44, ATtiny84, ATtiny84A,
675  ATtiny25, ATtiny45, ATtiny85,
676  ATtiny261, ATtiny461, ATtiny861,
677  ATmega48, ATmega48A, ATmega48PA, ATmega88, ATmega168,
678  ATmega48P, ATmega88P, ATmega168P, ATmega328P,
679  ATmega164P, ATmega324P, ATmega644P, ATmega644,
680  ATmega640, ATmega1280, ATmega1281, ATmega2560, ATmega2561,
681  ATmega8HVA, ATmega16HVA, ATmega32HVB,
682  ATmega406, ATmega1284P,
683  ATmega256RFR2, ATmega128RFR2, ATmega64RFR2,
684  ATmega2564RFR2, ATmega1284RFR2, ATmega644RFR2,
685  AT90PWM1, AT90PWM2, AT90PWM2B, AT90PWM3, AT90PWM3B, AT90PWM216, AT90PWM316,
686  AT90PWM81, AT90PWM161,
687  AT90USB82, AT90USB162,
688  AT90USB646, AT90USB647, AT90USB1286, AT90USB1287,
689  ATtiny48, ATtiny88,
690  ATxmega16a4u, ATxmega32a4u,
691  ATxmega16c4, ATxmega32c4,
692  ATxmega128c3, ATxmega192c3, ATxmega256c3.
693  */
694 #define WDTO_8S 9
695 
696 #endif /* defined(__DOXYGEN__) || defined(WDP3) */
697 
698 
699 #endif /* _AVR_WDT_H_ */

Automatically generated by Doxygen 1.8.8 on Thu Apr 2 2015.