source: rtems/cpukit/score/cpu/avr/avr/wdt.h @ 04a62dce

4.104.11
Last change on this file since 04a62dce was 04a62dce, checked in by Joel Sherrill <joel.sherrill@…>, on Aug 6, 2009 at 2:52:07 PM

2009-08-05 Josh Switnicki <josh.switnicki@…>

  • Makefile.am: added AVR specific Header files to score/cpu/avr/avr. These are from avr-libc 1.6 and assumed to exist by AVR applications.
  • preinstall.am: Regenerated.
  • Property mode set to 100644
File size: 12.2 KB
Line 
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#else
111#  define _WD_CONTROL_REG     WDTCR
112#endif
113
114#if defined(WDTOE)
115#define _WD_CHANGE_BIT      WDTOE
116#else
117#define _WD_CHANGE_BIT      WDCE
118#endif
119
120
121/**
122   \ingroup avr_watchdog
123   Enable the watchdog timer, configuring it for expiry after
124   \c timeout (which is a combination of the \c WDP0 through
125   \c WDP2 bits to write into the \c WDTCR register; For those devices
126   that have a \c WDTCSR register, it uses the combination of the \c WDP0
127   through \c WDP3 bits).
128
129   See also the symbolic constants \c WDTO_15MS et al.
130*/
131
132
133#if defined(__AVR_ATxmega16A4__) \
134|| defined(__AVR_ATxmega16D4__) \
135|| defined(__AVR_ATxmega32A4__) \
136|| defined(__AVR_ATxmega32D4__) \
137|| defined(__AVR_ATxmega64A1__) \
138|| defined(__AVR_ATxmega64A3__) \
139|| defined(__AVR_ATxmega128A1__) \
140|| defined(__AVR_ATxmega128A3__) \
141|| defined(__AVR_ATxmega256A3__) \
142|| defined(__AVR_ATxmega256A3B__)
143
144/*
145    wdt_enable(WDT_PER_8KCLK_gc);
146*/
147#define wdt_enable(value) \
148__asm__ __volatile__ ( \
149    "in __tmp_reg__, %0"  "\n\t" \
150    "out %1, %3"          "\n\t" \
151    "sts %2, %4"          "\n\t" \
152    "wdr"                 "\n\t" \
153    "out %0, __tmp_reg__" "\n\t" \
154    : \
155    : "M" (_SFR_MEM_ADDR(RAMPD)), \
156      "M" (_SFR_MEM_ADDR(CCP)), \
157      "M" (_SFR_MEM_ADDR(WDT_CTRL)), \
158      "r" ((uint8_t)0xD8), \
159      "r" ((uint8_t)(WDT_CEN_bm | WDT_ENABLE_bm | value)) \
160    : "r0" \
161)
162
163
164#elif defined(__AVR_AT90CAN32__) \
165|| defined(__AVR_AT90CAN64__) \
166|| defined(__AVR_AT90CAN128__) \
167|| defined(__AVR_AT90PWM1__) \
168|| defined(__AVR_AT90PWM2__) \
169|| defined(__AVR_AT90PWM216__) \
170|| defined(__AVR_AT90PWM2B__) \
171|| defined(__AVR_AT90PWM3__) \
172|| defined(__AVR_AT90PWM316__) \
173|| defined(__AVR_AT90PWM3B__) \
174|| defined(__AVR_AT90PWM81__) \
175|| defined(__AVR_AT90USB1286__) \
176|| defined(__AVR_AT90USB1287__) \
177|| defined(__AVR_AT90USB162__) \
178|| defined(__AVR_AT90USB646__) \
179|| defined(__AVR_AT90USB647__) \
180|| defined(__AVR_AT90USB82__) \
181|| defined(__AVR_ATmega1280__) \
182|| defined(__AVR_ATmega1281__) \
183|| defined(__AVR_ATmega1284P__) \
184|| defined(__AVR_ATmega128RFA1__) \
185|| defined(__AVR_ATmega164__) \
186|| defined(__AVR_ATmega164P__) \
187|| defined(__AVR_ATmega165__) \
188|| defined(__AVR_ATmega165P__) \
189|| defined(__AVR_ATmega168__) \
190|| defined(__AVR_ATmega168P__) \
191|| defined(__AVR_ATmega169__) \
192|| defined(__AVR_ATmega169P__) \
193|| defined(__AVR_ATmega16HVA__) \
194|| defined(__AVR_ATmega16M1__) \
195|| defined(__AVR_ATmega16U4__) \
196|| defined(__AVR_ATmega2560__) \
197|| defined(__AVR_ATmega2561__) \
198|| defined(__AVR_ATmega324__) \
199|| defined(__AVR_ATmega324P__) \
200|| defined(__AVR_ATmega325__) \
201|| defined(__AVR_ATmega3250__) \
202|| defined(__AVR_ATmega328P__) \
203|| defined(__AVR_ATmega329__) \
204|| defined(__AVR_ATmega329P__) \
205|| defined(__AVR_ATmega3290__) \
206|| defined(__AVR_ATmega3290P__) \
207|| defined(__AVR_ATmega32C1__) \
208|| defined(__AVR_ATmega32HVB__) \
209|| defined(__AVR_ATmega32M1__) \
210|| defined(__AVR_ATmega32U4__) \
211|| defined(__AVR_ATmega32U6__) \
212|| defined(__AVR_ATmega406__) \
213|| defined(__AVR_ATmega48__) \
214|| defined(__AVR_ATmega48P__) \
215|| defined(__AVR_ATmega640__) \
216|| defined(__AVR_ATmega644__) \
217|| defined(__AVR_ATmega644P__) \
218|| defined(__AVR_ATmega645__) \
219|| defined(__AVR_ATmega6450__) \
220|| defined(__AVR_ATmega649__) \
221|| defined(__AVR_ATmega6490__) \
222|| defined(__AVR_ATmega64C1__) \
223|| defined(__AVR_ATmega64M1__) \
224|| defined(__AVR_ATmega8HVA__) \
225|| defined(__AVR_ATmega88__) \
226|| defined(__AVR_ATmega88P__) \
227|| defined(__AVR_ATtiny48__) \
228|| defined(__AVR_ATtiny88__) \
229|| defined(__AVR_ATtiny87__) \
230|| defined(__AVR_ATtiny167__) \
231|| defined(__AVR_AT90SCR100__) \
232|| defined(__AVR_ATA6289__)
233
234/* Use STS instruction. */
235 
236#define wdt_enable(value)   \
237__asm__ __volatile__ (  \
238    "in __tmp_reg__,__SREG__" "\n\t"    \
239    "cli" "\n\t"    \
240    "wdr" "\n\t"    \
241    "sts %0,%1" "\n\t"  \
242    "out __SREG__,__tmp_reg__" "\n\t"   \
243    "sts %0,%2" "\n\t" \
244    : /* no outputs */  \
245    : "M" (_SFR_MEM_ADDR(_WD_CONTROL_REG)), \
246    "r" (_BV(_WD_CHANGE_BIT) | _BV(WDE)), \
247    "r" ((uint8_t) ((value & 0x08 ? _WD_PS3_MASK : 0x00) | \
248        _BV(WDE) | (value & 0x07)) ) \
249    : "r0"  \
250)
251
252#define wdt_disable() \
253__asm__ __volatile__ (  \
254    "in __tmp_reg__, __SREG__" "\n\t" \
255    "cli" "\n\t" \
256    "sts %0, %1" "\n\t" \
257    "sts %0, __zero_reg__" "\n\t" \
258    "out __SREG__,__tmp_reg__" "\n\t" \
259    : /* no outputs */ \
260    : "M" (_SFR_MEM_ADDR(_WD_CONTROL_REG)), \
261    "r" ((uint8_t)(_BV(_WD_CHANGE_BIT) | _BV(WDE))) \
262    : "r0" \
263)
264
265
266   
267#else 
268
269/* Use OUT instruction. */
270
271#define wdt_enable(value)   \
272    __asm__ __volatile__ (  \
273        "in __tmp_reg__,__SREG__" "\n\t"    \
274        "cli" "\n\t"    \
275        "wdr" "\n\t"    \
276        "out %0,%1" "\n\t"  \
277        "out __SREG__,__tmp_reg__" "\n\t"   \
278        "out %0,%2" \
279        : /* no outputs */  \
280        : "I" (_SFR_IO_ADDR(_WD_CONTROL_REG)), \
281        "r" (_BV(_WD_CHANGE_BIT) | _BV(WDE)),   \
282        "r" ((uint8_t) ((value & 0x08 ? _WD_PS3_MASK : 0x00) | \
283            _BV(WDE) | (value & 0x07)) ) \
284        : "r0"  \
285    )
286
287/**
288   \ingroup avr_watchdog
289   Disable the watchdog timer, if possible.  This attempts to turn off the
290   Enable bit in the watchdog control register. See the datasheet for
291   details.
292*/
293#define wdt_disable() \
294__asm__ __volatile__ (  \
295    "in __tmp_reg__, __SREG__" "\n\t" \
296     "cli" "\n\t" \
297    "out %0, %1" "\n\t" \
298    "out %0, __zero_reg__" "\n\t" \
299    "out __SREG__,__tmp_reg__" "\n\t" \
300    : /* no outputs */ \
301    : "I" (_SFR_IO_ADDR(_WD_CONTROL_REG)), \
302    "r" ((uint8_t)(_BV(_WD_CHANGE_BIT) | _BV(WDE))) \
303    : "r0" \
304)
305
306#endif
307
308
309
310/**
311   \ingroup avr_watchdog
312   Symbolic constants for the watchdog timeout.  Since the watchdog
313   timer is based on a free-running RC oscillator, the times are
314   approximate only and apply to a supply voltage of 5 V.  At lower
315   supply voltages, the times will increase.  For older devices, the
316   times will be as large as three times when operating at Vcc = 3 V,
317   while the newer devices (e. g. ATmega128, ATmega8) only experience
318   a negligible change.
319
320   Possible timeout values are: 15 ms, 30 ms, 60 ms, 120 ms, 250 ms,
321   500 ms, 1 s, 2 s.  (Some devices also allow for 4 s and 8 s.)
322   Symbolic constants are formed by the prefix
323   \c WDTO_, followed by the time.
324
325   Example that would select a watchdog timer expiry of approximately
326   500 ms:
327   \code
328   wdt_enable(WDTO_500MS);
329   \endcode
330*/
331#define WDTO_15MS   0
332
333/** \ingroup avr_watchdog
334    See \c WDT0_15MS */
335#define WDTO_30MS   1
336
337/** \ingroup avr_watchdog See
338    \c WDT0_15MS */
339#define WDTO_60MS   2
340
341/** \ingroup avr_watchdog
342    See \c WDT0_15MS */
343#define WDTO_120MS  3
344
345/** \ingroup avr_watchdog
346    See \c WDT0_15MS */
347#define WDTO_250MS  4
348
349/** \ingroup avr_watchdog
350    See \c WDT0_15MS */
351#define WDTO_500MS  5
352
353/** \ingroup avr_watchdog
354    See \c WDT0_15MS */
355#define WDTO_1S     6
356
357/** \ingroup avr_watchdog
358    See \c WDT0_15MS */
359#define WDTO_2S     7
360
361#if defined(__DOXYGEN__) || defined(WDP3)
362
363/** \ingroup avr_watchdog
364    See \c WDT0_15MS
365    Note: This is only available on the
366    ATtiny2313,
367    ATtiny24, ATtiny44, ATtiny84,
368    ATtiny25, ATtiny45, ATtiny85,
369    ATtiny261, ATtiny461, ATtiny861,
370    ATmega48, ATmega88, ATmega168,
371    ATmega48P, ATmega88P, ATmega168P, ATmega328P,
372    ATmega164P, ATmega324P, ATmega644P, ATmega644,
373    ATmega640, ATmega1280, ATmega1281, ATmega2560, ATmega2561,
374    ATmega8HVA, ATmega16HVA, ATmega32HVB,
375    ATmega406, ATmega1284P,
376    AT90PWM1, AT90PWM2, AT90PWM2B, AT90PWM3, AT90PWM3B, AT90PWM216, AT90PWM316,
377    AT90PWM81,
378    AT90USB82, AT90USB162,
379    AT90USB646, AT90USB647, AT90USB1286, AT90USB1287,
380    ATtiny48, ATtiny88.
381    */
382#define WDTO_4S     8
383
384/** \ingroup avr_watchdog
385    See \c WDT0_15MS
386    Note: This is only available on the
387    ATtiny2313,
388    ATtiny24, ATtiny44, ATtiny84,
389    ATtiny25, ATtiny45, ATtiny85,
390    ATtiny261, ATtiny461, ATtiny861,
391    ATmega48, ATmega88, ATmega168,
392    ATmega48P, ATmega88P, ATmega168P, ATmega328P,
393    ATmega164P, ATmega324P, ATmega644P, ATmega644,
394    ATmega640, ATmega1280, ATmega1281, ATmega2560, ATmega2561,
395    ATmega8HVA, ATmega16HVA, ATmega32HVB,
396    ATmega406, ATmega1284P,
397    AT90PWM1, AT90PWM2, AT90PWM2B, AT90PWM3, AT90PWM3B, AT90PWM216, AT90PWM316,
398    AT90PWM81,
399    AT90USB82, AT90USB162,
400    AT90USB646, AT90USB647, AT90USB1286, AT90USB1287,
401    ATtiny48, ATtiny88.
402    */
403#define WDTO_8S     9
404
405#endif  /* defined(__DOXYGEN__) || defined(WDP3) */
406   
407
408#endif /* _AVR_WDT_H_ */
Note: See TracBrowser for help on using the repository browser.