AVR-LibC  2.3.0
Standard C library for AVR-GCC
 

AVR-LibC Manual

AVR-LibC Sources

Main Page

User Manual

Lib­rary Refe­rence

FAQ

Exam­ple Pro­jects

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 mcusr_mirror = MCUSR;
77 MCUSR = 0;
78 wdt_disable();
79 }
80 \endcode
81
82 Saving the value of MCUSR in \c mcusr_mirror is only needed if the
83 application later wants to examine the reset source, but in particular,
84 clearing the watchdog reset flag before disabling the
85 watchdog is required, according to the datasheet.
86*/
87
88/**
89 \ingroup avr_watchdog
90 Reset the watchdog timer. When the watchdog timer is enabled,
91 a call to this instruction is required before the timer expires,
92 otherwise a watchdog-initiated device reset will occur. */
93#define wdt_reset() __asm__ __volatile__ ("wdr")
94
95#ifndef __DOXYGEN__
96
97#include <bits/attribs.h>
98
99#if defined(WDP3)
100# define _WD_PS3_MASK _BV(WDP3)
101#else
102# define _WD_PS3_MASK 0x00
103#endif
104
105#if defined(WDTCSR)
106# define _WD_CONTROL_REG WDTCSR
107#elif defined(WDTCR)
108# define _WD_CONTROL_REG WDTCR
109#else
110# define _WD_CONTROL_REG WDT
111#endif
112
113#if defined(WDTOE)
114#define _WD_CHANGE_BIT WDTOE
115#else
116#define _WD_CHANGE_BIT WDCE
117#endif
118
119#endif /* !__DOXYGEN__ */
120
121#ifdef __DOXYGEN__
122/**
123 \ingroup avr_watchdog
124 Enable the watchdog timer, configuring it for expiry after
125 \c timeout (which is a combination of the \c WDP0 through
126 \c WDP2 bits to write into the \c WDTCR register; For those devices
127 that have a \c WDTCSR register, it uses the combination of the \c WDP0
128 through \c WDP3 bits).
129
130 See also the symbolic constants \c WDTO_15MS et al. */
131#define wdt_enable(timeout)
132#endif /* __DOXYGEN__ */
133
134
135#if defined(__AVR_XMEGA__)
136
137#if defined (WDT_CTRLA) && !defined(RAMPD)
138
139#define wdt_enable(timeout) \
140 do { \
141 __asm__ __volatile__ ( \
142 "wdr" "\n\t" \
143 "1: lds __tmp_reg__, %[wdt_status_reg]" "\n\t" \
144 "sbrc __tmp_reg__, %[wdt_syncbusy_bit]" "\n\t" \
145 "rjmp 1b" "\n\t" \
146 "out %i[ccp_reg], %[ioreg_cen_mask]" "\n\t" \
147 "sts %[wdt_reg], %[wdt_enable_timeout]" "\n\t" \
148 "2: lds __tmp_reg__, %[wdt_status_reg]" "\n\t" \
149 "sbrc __tmp_reg__, %[wdt_syncbusy_bit]" "\n\t" \
150 "rjmp 2b" \
151 : /* no outputs */ \
152 : [ccp_reg] "n" (& CCP), \
153 [ioreg_cen_mask] "r" ((uint8_t)CCP_IOREG_gc), \
154 [wdt_reg] "n" (& WDT_CTRLA), \
155 [wdt_enable_timeout] "r" ((uint8_t)(timeout)), \
156 [wdt_status_reg] "n" (& WDT_STATUS), \
157 [wdt_syncbusy_bit] "I" (WDT_SYNCBUSY_bp) \
158 : "r0", "memory"); \
159 } while(0)
160
161static __ATTR_ALWAYS_INLINE__
162void wdt_disable (void)
163{
164 __asm__ __volatile__ (
165 "wdr" "\n\t"
166 "1: lds __tmp_reg__, %[wdt_status_reg]" "\n\t"
167 "sbrc __tmp_reg__, %[wdt_syncbusy_bit]" "\n\t"
168 "rjmp 1b" "\n\t"
169 "out %i[ccp_reg], %[ioreg_cen_mask]" "\n\t"
170 "sts %[wdt_reg], %[wdt_off]"
171 : /* no outputs */
172 : [ccp_reg] "n" (& CCP),
173 [ioreg_cen_mask] "r" ((uint8_t)CCP_IOREG_gc),
174 [wdt_reg] "n" (& WDT_CTRLA),
175 [wdt_off] "r" ((uint8_t)WDT_PERIOD_OFF_gc),
176 [wdt_status_reg] "n" (& WDT_STATUS),
177 [wdt_syncbusy_bit] "I" (WDT_SYNCBUSY_bp)
178 : "r0", "memory");
179}
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#define wdt_enable(timeout) \
195 do { \
196 uint8_t __temp; \
197 __asm__ __volatile__ ( \
198 "in __tmp_reg__, %i[rampd]" "\n\t" \
199 "out %i[rampd], __zero_reg__" "\n\t" \
200 "out %i[ccp_reg], %[ioreg_cen_mask]" "\n\t" \
201 "sts %[wdt_reg], %[wdt_enable_timeout]" "\n\t" \
202 "1:lds %[tmp], %[wdt_status_reg]" "\n\t" \
203 "sbrc %[tmp], %[wdt_syncbusy_bit]" "\n\t" \
204 "rjmp 1b" "\n\t" \
205 "out %i[rampd], __tmp_reg__" \
206 : [tmp] "=r" (__temp) \
207 : [rampd] "n" (& RAMPD), \
208 [ccp_reg] "n" (& CCP), \
209 [ioreg_cen_mask] "r" ((uint8_t)CCP_IOREG_gc), \
210 [wdt_reg] "n" (& WDT_CTRL), \
211 [wdt_enable_timeout] "r" ((uint8_t)(WDT_CEN_bm \
212 | WDT_ENABLE_bm \
213 | ((timeout + 1) << 2))), \
214 [wdt_status_reg] "n" (& WDT_STATUS), \
215 [wdt_syncbusy_bit] "I" (WDT_SYNCBUSY_bp) \
216 : "memory"); \
217 } while(0)
218
219static __ATTR_ALWAYS_INLINE__
220void wdt_disable (void)
221{
222 __asm__ __volatile__ (
223 "in __tmp_reg__, %i[rampd]" "\n\t"
224 "out %i[rampd], __zero_reg__" "\n\t"
225 "out %i[ccp_reg], %[ioreg_cen_mask]" "\n\t"
226 "sts %[wdt_reg], %[disable_mask]" "\n\t"
227 "out %i[rampd], __tmp_reg__"
228 : /* no outputs */
229 : [rampd] "n" (& RAMPD),
230 [ccp_reg] "n" (& CCP),
231 [ioreg_cen_mask] "r" ((uint8_t)CCP_IOREG_gc),
232 [wdt_reg] "n" (& WDT_CTRL),
233 [disable_mask] "r" ((uint8_t)((~WDT_ENABLE_bm) | WDT_CEN_bm))
234 : "memory");
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 %i[CCPADDRESS],%[SIGNATURE]" "\n\t" \
247 "out %i[WDTREG],%[WDVALUE]" "\n\t" \
248 "out __SREG__,__tmp_reg__" \
249 : /* no outputs */ \
250 : [CCPADDRESS] "n" (& CCP), \
251 [SIGNATURE] "r" ((uint8_t)0xD8), \
252 [WDTREG] "n" (& _WD_CONTROL_REG), \
253 [WDVALUE] "r" ((uint8_t)((value & 0x08 ? _WD_PS3_MASK : 0x00) \
254 | _BV(WDE) | (value & 0x07) )) \
255 : "memory")
256
257static __ATTR_ALWAYS_INLINE__
258void wdt_disable (void)
259{
260 uint8_t __temp_wd;
261 __asm__ __volatile__ (
262 "in __tmp_reg__,__SREG__" "\n\t"
263 "cli" "\n\t"
264 "wdr" "\n\t"
265 "out %i[CCPADDRESS],%[SIGNATURE]" "\n\t"
266 "in %[TEMP_WD],%i[WDTREG]" "\n\t"
267 "cbr %[TEMP_WD],%[WDVALUE]" "\n\t"
268 "out %i[WDTREG],%[TEMP_WD]" "\n\t"
269 "out __SREG__,__tmp_reg__"
270 : [TEMP_WD] "=d" (__temp_wd)
271 : [CCPADDRESS] "n" (& CCP),
272 [SIGNATURE] "r" ((uint8_t)0xD8),
273 [WDTREG] "n" (& _WD_CONTROL_REG),
274 [WDVALUE] "n" (1 << WDE)
275 : "memory");
276}
277
278#elif defined(CCP)
279
280static __ATTR_ALWAYS_INLINE__
281void wdt_enable (const uint8_t value)
282{
283 if (!_SFR_IO_REG_P (CCP) && !_SFR_IO_REG_P (_WD_CONTROL_REG))
284 {
285 __asm__ __volatile__ (
286 "in __tmp_reg__,__SREG__" "\n\t"
287 "cli" "\n\t"
288 "wdr" "\n\t"
289 "sts %[CCPADDRESS],%[SIGNATURE]" "\n\t"
290 "sts %[WDTREG],%[WDVALUE]" "\n\t"
291 "out __SREG__,__tmp_reg__"
292 : /* no outputs */
293 : [CCPADDRESS] "n" (& CCP),
294 [SIGNATURE] "r" ((uint8_t)0xD8),
295 [WDTREG] "n" (& _WD_CONTROL_REG),
296 [WDVALUE] "r" ((uint8_t)((value & 0x08 ? _WD_PS3_MASK : 0x00)
297 | _BV(WDE) | (value & 0x07) ))
298 : "memory");
299 }
300 else if (!_SFR_IO_REG_P (CCP) && _SFR_IO_REG_P (_WD_CONTROL_REG))
301 {
302 __asm__ __volatile__ (
303 "in __tmp_reg__,__SREG__" "\n\t"
304 "cli" "\n\t"
305 "wdr" "\n\t"
306 "sts %[CCPADDRESS],%[SIGNATURE]" "\n\t"
307 "out %i[WDTREG],%[WDVALUE]" "\n\t"
308 "out __SREG__,__tmp_reg__"
309 : /* no outputs */
310 : [CCPADDRESS] "n" (& CCP),
311 [SIGNATURE] "r" ((uint8_t)0xD8),
312 [WDTREG] "n" (& _WD_CONTROL_REG),
313 [WDVALUE] "r" ((uint8_t)((value & 0x08 ? _WD_PS3_MASK : 0x00)
314 | _BV(WDE) | (value & 0x07) ))
315 : "memory");
316 }
317 else if (_SFR_IO_REG_P (CCP) && !_SFR_IO_REG_P (_WD_CONTROL_REG))
318 {
319 __asm__ __volatile__ (
320 "in __tmp_reg__,__SREG__" "\n\t"
321 "cli" "\n\t"
322 "wdr" "\n\t"
323 "out %i[CCPADDRESS],%[SIGNATURE]" "\n\t"
324 "sts %[WDTREG],%[WDVALUE]" "\n\t"
325 "out __SREG__,__tmp_reg__"
326 : /* no outputs */
327 : [CCPADDRESS] "n" (& CCP),
328 [SIGNATURE] "r" ((uint8_t)0xD8),
329 [WDTREG] "n" (& _WD_CONTROL_REG),
330 [WDVALUE] "r" ((uint8_t)((value & 0x08 ? _WD_PS3_MASK : 0x00)
331 | _BV(WDE) | (value & 0x07) ))
332 : "memory");
333 }
334 else
335 {
336 __asm__ __volatile__ (
337 "in __tmp_reg__,__SREG__" "\n\t"
338 "cli" "\n\t"
339 "wdr" "\n\t"
340 "out %i[CCPADDRESS],%[SIGNATURE]" "\n\t"
341 "out %i[WDTREG],%[WDVALUE]" "\n\t"
342 "out __SREG__,__tmp_reg__"
343 : /* no outputs */
344 : [CCPADDRESS] "n" (& CCP),
345 [SIGNATURE] "r" ((uint8_t)0xD8),
346 [WDTREG] "n" (& _WD_CONTROL_REG),
347 [WDVALUE] "r" ((uint8_t)((value & 0x08 ? _WD_PS3_MASK : 0x00)
348 | _BV(WDE) | (value & 0x07) ))
349 : "memory");
350 }
351}
352
353static __ATTR_ALWAYS_INLINE__
354void wdt_disable (void)
355{
356 if (!_SFR_IO_REG_P (CCP) && !_SFR_IO_REG_P(_WD_CONTROL_REG))
357 {
358 uint8_t __temp_wd;
359 __asm__ __volatile__ (
360 "in __tmp_reg__,__SREG__" "\n\t"
361 "cli" "\n\t"
362 "wdr" "\n\t"
363 "sts %[CCPADDRESS],%[SIGNATURE]" "\n\t"
364 "lds %[TEMP_WD],%[WDTREG]" "\n\t"
365 "cbr %[TEMP_WD],%[WDVALUE]" "\n\t"
366 "sts %[WDTREG],%[TEMP_WD]" "\n\t"
367 "out __SREG__,__tmp_reg__"
368 : [TEMP_WD] "=d" (__temp_wd)
369 : [CCPADDRESS] "n" (& CCP),
370 [SIGNATURE] "r" ((uint8_t)0xD8),
371 [WDTREG] "n" (& _WD_CONTROL_REG),
372 [WDVALUE] "n" (1 << WDE)
373 : "memory");
374 }
375 else if (!_SFR_IO_REG_P (CCP) && _SFR_IO_REG_P(_WD_CONTROL_REG))
376 {
377 uint8_t __temp_wd;
378 __asm__ __volatile__ (
379 "in __tmp_reg__,__SREG__" "\n\t"
380 "cli" "\n\t"
381 "wdr" "\n\t"
382 "sts %[CCPADDRESS],%[SIGNATURE]" "\n\t"
383 "in %[TEMP_WD],%i[WDTREG]" "\n\t"
384 "cbr %[TEMP_WD],%[WDVALUE]" "\n\t"
385 "out %i[WDTREG],%[TEMP_WD]" "\n\t"
386 "out __SREG__,__tmp_reg__"
387 : [TEMP_WD] "=d" (__temp_wd)
388 : [CCPADDRESS] "n" (& CCP),
389 [SIGNATURE] "r" ((uint8_t)0xD8),
390 [WDTREG] "n" (& _WD_CONTROL_REG),
391 [WDVALUE] "n" (1 << WDE)
392 : "memory");
393 }
394 else if (_SFR_IO_REG_P (CCP) && !_SFR_IO_REG_P(_WD_CONTROL_REG))
395 {
396 uint8_t __temp_wd;
397 __asm__ __volatile__ (
398 "in __tmp_reg__,__SREG__" "\n\t"
399 "cli" "\n\t"
400 "wdr" "\n\t"
401 "out %i[CCPADDRESS],%[SIGNATURE]" "\n\t"
402 "lds %[TEMP_WD],%[WDTREG]" "\n\t"
403 "cbr %[TEMP_WD],%[WDVALUE]" "\n\t"
404 "sts %[WDTREG],%[TEMP_WD]" "\n\t"
405 "out __SREG__,__tmp_reg__"
406 : [TEMP_WD] "=d" (__temp_wd)
407 : [CCPADDRESS] "n" (& CCP),
408 [SIGNATURE] "r" ((uint8_t)0xD8),
409 [WDTREG] "n" (& _WD_CONTROL_REG),
410 [WDVALUE] "n" (1 << WDE)
411 : "memory");
412 }
413 else
414 {
415 uint8_t __temp_wd;
416 __asm__ __volatile__ (
417 "in __tmp_reg__,__SREG__" "\n\t"
418 "cli" "\n\t"
419 "wdr" "\n\t"
420 "out %i[CCPADDRESS],%[SIGNATURE]" "\n\t"
421 "in %[TEMP_WD],%i[WDTREG]" "\n\t"
422 "cbr %[TEMP_WD],%[WDVALUE]" "\n\t"
423 "out %i[WDTREG],%[TEMP_WD]" "\n\t"
424 "out __SREG__,__tmp_reg__"
425 : [TEMP_WD] "=d" (__temp_wd)
426 : [CCPADDRESS] "n" (& CCP),
427 [SIGNATURE] "r" ((uint8_t)0xD8),
428 [WDTREG] "n" (& _WD_CONTROL_REG),
429 [WDVALUE] "n" (1 << WDE)
430 : "memory");
431 }
432}
433
434#else
435
436/** \ingroup avr_watchdog
437 Enable the watchdog timer, configuring it for expiry after
438 \c timeout (which is a combination of the \c WDP0 through
439 \c WDP2 bits to write into the \c WDTCR register; For those devices
440 that have a \c WDTCSR register, it uses the combination of the \c WDP0
441 through \c WDP3 bits).
442
443 See also the symbolic constants \c WDTO_15MS et al. */
444static __ATTR_ALWAYS_INLINE__
445void wdt_enable(const uint8_t value)
446{
447 if (_SFR_IO_REG_P (_WD_CONTROL_REG))
448 {
449 __asm__ __volatile__ (
450 "in __tmp_reg__,__SREG__" "\n\t"
451 "cli" "\n\t"
452 "wdr" "\n\t"
453 "out %i0, %1" "\n\t"
454 "out __SREG__,__tmp_reg__" "\n\t"
455 "out %i0, %2"
456 : /* no outputs */
457 : "n" (& _WD_CONTROL_REG),
458 "r" ((uint8_t)(_BV(_WD_CHANGE_BIT) | _BV(WDE))),
459 "r" ((uint8_t) ((value & 0x08 ? _WD_PS3_MASK : 0x00)
460 | _BV(WDE) | (value & 0x07)) )
461 : "memory");
462 }
463 else
464 {
465 __asm__ __volatile__ (
466 "in __tmp_reg__,__SREG__" "\n\t"
467 "cli" "\n\t"
468 "wdr" "\n\t"
469 "sts %0, %1" "\n\t"
470 "out __SREG__,__tmp_reg__" "\n\t"
471 "sts %0, %2"
472 : /* no outputs */
473 : "n" (& _WD_CONTROL_REG),
474 "r" ((uint8_t)(_BV(_WD_CHANGE_BIT) | _BV(WDE))),
475 "r" ((uint8_t) ((value & 0x08 ? _WD_PS3_MASK : 0x00)
476 | _BV(WDE) | (value & 0x07)) )
477 : "memory");
478 }
479}
480
481/** \ingroup avr_watchdog
482 Disable the watchdog timer.
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],%i[WDTREG]" "\n\t"
495 "ori %[TEMPREG],%[WDCE_WDE]" "\n\t"
496 "out %i[WDTREG],%[TEMPREG]" "\n\t"
497 "out %i[WDTREG],__zero_reg__" "\n\t"
498 "out __SREG__,__tmp_reg__"
499 : [TEMPREG] "=d" (__temp_reg)
500 : [WDTREG] "n" (& _WD_CONTROL_REG),
501 [WDCE_WDE] "n" ((uint8_t)(_BV(_WD_CHANGE_BIT) | _BV(WDE)))
502 : "memory");
503 }
504 else
505 {
506 uint8_t __temp_reg;
507 __asm__ __volatile__ (
508 "in __tmp_reg__,__SREG__" "\n\t"
509 "cli" "\n\t"
510 "wdr" "\n\t"
511 "lds %[TEMPREG],%[WDTREG]" "\n\t"
512 "ori %[TEMPREG],%[WDCE_WDE]" "\n\t"
513 "sts %[WDTREG],%[TEMPREG]" "\n\t"
514 "sts %[WDTREG],__zero_reg__" "\n\t"
515 "out __SREG__,__tmp_reg__"
516 : [TEMPREG] "=d" (__temp_reg)
517 : [WDTREG] "n" (& _WD_CONTROL_REG),
518 [WDCE_WDE] "n" ((uint8_t)(_BV(_WD_CHANGE_BIT) | _BV(WDE)))
519 : "memory");
520 }
521}
522
523#endif
524
525
526/**
527 \ingroup avr_watchdog
528 Symbolic constants for the watchdog timeout. Since the watchdog
529 timer is based on a free-running RC oscillator, the times are
530 approximate only and apply to a supply voltage of 5 V. At lower
531 supply voltages, the times will increase. For older devices, the
532 times will be as large as three times when operating at Vcc = 3 V,
533 while the newer devices (e. g. ATmega128, ATmega8) only experience
534 a negligible change.
535
536 Possible timeout values are: 15 ms, 30 ms, 60 ms, 120 ms, 250 ms,
537 500 ms, 1 s, 2 s. (Some devices also allow for 4 s and 8 s.)
538 Symbolic constants are formed by the prefix
539 \c WDTO_, followed by the time.
540
541 Example that would select a watchdog timer expiry of approximately
542 500 ms:
543 \code
544 wdt_enable(WDTO_500MS);
545 \endcode
546*/
547#if defined(__DOXYGEN__) || defined(__AVR_XMEGA__)
548#define WDTO_8MS -1
549#endif
550
551/** \ingroup avr_watchdog
552 A value to be passed to wdt_enable() for the specified watchdog
553 timeout duration. */
554#define WDTO_15MS 0
555
556/** \ingroup avr_watchdog
557 See \c #WDTO_15MS */
558#define WDTO_30MS 1
559
560/** \ingroup avr_watchdog
561 See \c #WDTO_15MS */
562#define WDTO_60MS 2
563
564/** \ingroup avr_watchdog
565 See \c #WDTO_15MS */
566#define WDTO_120MS 3
567
568/** \ingroup avr_watchdog
569 See \c #WDTO_15MS */
570#define WDTO_250MS 4
571
572/** \ingroup avr_watchdog
573 See \c #WDTO_15MS */
574#define WDTO_500MS 5
575
576/** \ingroup avr_watchdog
577 See \c #WDTO_15MS */
578#define WDTO_1S 6
579
580/** \ingroup avr_watchdog
581 See \c #WDTO_15MS */
582#define WDTO_2S 7
583
584#if defined(__DOXYGEN__) || defined(WDP3) || defined(__AVR_XMEGA__)
585
586/** \ingroup avr_watchdog
587 See \c WDTO_15MS
588 Note: This is only available on the
589 ATtiny2313,
590 ATtiny24, ATtiny44, ATtiny84, ATtiny84A,
591 ATtiny25, ATtiny45, ATtiny85,
592 ATtiny261, ATtiny461, ATtiny861,
593 ATmega48*, ATmega88*, ATmega168*, ATmega328*,
594 ATmega164P, ATmega324P, ATmega324PB, ATmega644P, ATmega644,
595 ATmega640, ATmega1280, ATmega1281, ATmega2560, ATmega2561,
596 ATmega8HVA, ATmega16HVA, ATmega32HVB,
597 ATmega406, ATmega1284P,
598 AT90PWM1, AT90PWM2, AT90PWM2B, AT90PWM3, AT90PWM3B, AT90PWM216, AT90PWM316,
599 AT90PWM81, AT90PWM161,
600 AT90USB82, AT90USB162,
601 AT90USB646, AT90USB647, AT90USB1286, AT90USB1287,
602 ATtiny48, ATtiny88.
603
604 Note: This value does <em>not</em> match the bit pattern of the
605 respective control register. It is solely meant to be used together
606 with wdt_enable().
607*/
608#define WDTO_4S 8
609
610/** \ingroup avr_watchdog
611 See \c WDTO_15MS
612 Note: This is only available on the
613 ATtiny2313,
614 ATtiny24, ATtiny44, ATtiny84, ATtiny84A,
615 ATtiny25, ATtiny45, ATtiny85,
616 ATtiny261, ATtiny461, ATtiny861,
617 ATmega48*, ATmega88*, ATmega168*, ATmega328*,
618 ATmega164P, ATmega324P, ATmega324PB, 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 Note: This value does <em>not</em> match the bit pattern of the
633 respective control register. It is solely meant to be used together
634 with wdt_enable().
635*/
636#define WDTO_8S 9
637
638#endif /* defined(__DOXYGEN__) || defined(WDP3) */
639
640#if defined(WDT_CTRLA) && !defined(RAMPD)
641/* Modern AVR Watchdog Timer (WDT.CTRLA): On these parts, wdt_enable()
642 writes the argument directly into the PERIOD bit field, so the WDTO_*
643 constants must equal the WDT.CTRLA PERIOD group codes - not the
644 classic WDTCSR WDP indices defined above (those land in the wrong
645 PERIOD slots, giving ~1/4 of the requested time, and WDTO_15MS even
646 selects PERIOD=OFF). Redefine them to the group codes here.
647 The new-WDT hardware also supports 4 s and 8 s (PERIOD 0xA / 0xB),
648 so define those on this branch too. 15 ms has no exact match and uses
649 the nearest period of 16 CLK (~15.6 ms). */
650#undef WDTO_8MS
651#define WDTO_8MS WDT_PERIOD_8CLK_gc
652#undef WDTO_15MS
653#define WDTO_15MS WDT_PERIOD_16CLK_gc
654#undef WDTO_30MS
655#define WDTO_30MS WDT_PERIOD_32CLK_gc
656#undef WDTO_60MS
657#define WDTO_60MS WDT_PERIOD_64CLK_gc
658#undef WDTO_120MS
659#define WDTO_120MS WDT_PERIOD_128CLK_gc
660#undef WDTO_250MS
661#define WDTO_250MS WDT_PERIOD_256CLK_gc
662#undef WDTO_500MS
663#define WDTO_500MS WDT_PERIOD_512CLK_gc
664#undef WDTO_1S
665#define WDTO_1S WDT_PERIOD_1KCLK_gc
666#undef WDTO_2S
667#define WDTO_2S WDT_PERIOD_2KCLK_gc
668#undef WDTO_4S
669#define WDTO_4S WDT_PERIOD_4KCLK_gc
670#undef WDTO_8S
671#define WDTO_8S WDT_PERIOD_8KCLK_gc
672#endif /* defined(WDT_CTRLA) && !defined(RAMPD) */
673
674#endif /* _AVR_WDT_H_ */
#define _BV(bit)
Definition: sfr_defs.h:206
unsigned char uint8_t
Definition: stdint.h:88
static void wdt_disable(void)
Definition: wdt.h:485
#define wdt_enable(timeout)
Definition: wdt.h:131