AVR Libc Home Page
AVR Libc Development Pages
Main Page
User Manual
Library Reference
FAQ
Alphabetical Index
Example Projects
include
avr
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_ */
io.h
stdint.h
Automatically generated by Doxygen 1.8.9.1 on Thu May 7 2015.