source: rtems/cpukit/score/cpu/avr/avr/wdt.h @ 455bd4e

4.115
Last change on this file since 455bd4e was 455bd4e, checked in by Alex Ivanov <alexivanov97@…>, on 01/04/13 at 14:49:56

score: Doxygen Clean Up Task #9

  • Property mode set to 100644
File size: 12.4 KB
Line 
1/**
2 * @file
3 *
4 * @brief Watchdog Timer Handling
5 */
6/* Copyright (c) 2002, 2004 Marek Michalkiewicz
7   Copyright (c) 2005, 2006, 2007 Eric B. Weddington
8   All rights reserved.
9
10   Redistribution and use in source and binary forms, with or without
11   modification, are permitted provided that the following conditions are met:
12
13   * Redistributions of source code must retain the above copyright
14     notice, this list of conditions and the following disclaimer.
15
16   * Redistributions in binary form must reproduce the above copyright
17     notice, this list of conditions and the following disclaimer in
18     the documentation and/or other materials provided with the
19     distribution.
20
21   * Neither the name of the copyright holders nor the names of
22     contributors may be used to endorse or promote products derived
23     from this software without specific prior written permission.
24
25  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
26  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
29  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35  POSSIBILITY OF SUCH DAMAGE. */
36
37
38/*
39   avr/wdt.h - macros for AVR watchdog timer
40 */
41
42#ifndef _AVR_WDT_H_
43#define _AVR_WDT_H_
44
45#include <avr/io.h>
46#include <stdint.h>
47
48/**
49 * @defgroup avr_watchdog Watchdog Timer Handling
50 *
51 * This header file declares the interface to some inline macros
52 * handling the watchdog timer present in many AVR devices.  In order
53 * to prevent the watchdog timer configuration from being
54 * accidentally altered by a crashing application, a special timed
55 * equence is required in order to change it.  The macros within
56 * this header file handle the required sequence automatically
57 * before changing any value.  Interrupts will be disabled during
58 * the manipulation.
59 *
60 * Note: Depending on the fuse configuration of the particular
61 * device, further restrictions might apply, in particular it might
62 * be disallowed to turn off the watchdog timer.
63 *
64 * Note that for newer devices (ATmega88 and newer, effectively any
65 * AVR that has the option to also generate interrupts), the watchdog
66 * timer remains active even after a system reset (except a power-on
67 * condition), using the fastest prescaler value (approximately 15
68 * ms).  It is therefore required to turn off the watchdog early
69 * during program startup, the datasheet recommends a sequence like
70 * the following:
71 *
72 * @code{.c}
73 * #include <stdint.h>
74 * #include <avr/wdt.h>
75 *
76 * uint8_t mcusr_mirror __attribute__ ((section (".noinit")));
77 *
78 * void get_mcusr(void) \
79 *   __attribute__((naked)) \
80 *   __attribute__((section(".init3")));
81 * void get_mcusr(void)
82 * {
83 *   mcusr_mirror = MCUSR;
84 *   MCUSR = 0;
85 *   wdt_disable();
86 * }
87 * @endcode
88 *
89 * Saving the value of MCUSR in @c mcusr_mirror is only needed if the
90 * application later wants to examine the reset source, but in particular,
91 * clearing the watchdog reset flag before disabling the
92 * watchdog is required, according to the datasheet.
93 * @{
94*/
95
96/**
97 * @brief Watchdog Timer Reset
98 *
99 * Reset the watchdog timer.  When the watchdog timer is enabled,
100 * a call to this instruction is required before the timer expires,
101 * otherwise a watchdog-initiated device reset will occur.
102*/
103
104#define wdt_reset() __asm__ __volatile__ ("wdr")
105
106
107#if defined(WDP3)
108# define _WD_PS3_MASK       _BV(WDP3)
109#else
110# define _WD_PS3_MASK       0x00
111#endif
112
113#if defined(WDTCSR)
114#  define _WD_CONTROL_REG     WDTCSR
115#else
116#  define _WD_CONTROL_REG     WDTCR
117#endif
118
119#if defined(WDTOE)
120#define _WD_CHANGE_BIT      WDTOE
121#else
122#define _WD_CHANGE_BIT      WDCE
123#endif
124
125
126/**
127 * Enable the watchdog timer, configuring it for expiry after
128 * @c timeout (which is a combination of the @c WDP0 through
129 * @c WDP2 bits to write into the @c WDTCR register; For those devices
130 * that have a @c WDTCSR register, it uses the combination of the @c WDP0
131 * through @c WDP3 bits).
132 *
133 * See also the symbolic constants @c WDTO_15MS et al.
134*/
135
136
137#if defined(__AVR_ATxmega16A4__) \
138|| defined(__AVR_ATxmega16D4__) \
139|| defined(__AVR_ATxmega32A4__) \
140|| defined(__AVR_ATxmega32D4__) \
141|| defined(__AVR_ATxmega64A1__) \
142|| defined(__AVR_ATxmega64A3__) \
143|| defined(__AVR_ATxmega64D3__) \
144|| defined(__AVR_ATxmega128A1__) \
145|| defined(__AVR_ATxmega128A3__) \
146|| defined(__AVR_ATxmega128D3__) \
147|| defined(__AVR_ATxmega192A3__) \
148|| defined(__AVR_ATxmega192D3__) \
149|| defined(__AVR_ATxmega256A3__) \
150|| defined(__AVR_ATxmega256D3__) \
151|| defined(__AVR_ATxmega256A3B__)
152
153/*
154    wdt_enable(WDT_PER_8KCLK_gc);
155*/
156#define wdt_enable(value) \
157__asm__ __volatile__ ( \
158    "in __tmp_reg__, %0"  "\n\t" \
159    "out %1, %3"          "\n\t" \
160    "sts %2, %4"          "\n\t" \
161    "wdr"                 "\n\t" \
162    "out %0, __tmp_reg__" "\n\t" \
163    : \
164    : "M" (_SFR_MEM_ADDR(RAMPD)), \
165      "M" (_SFR_MEM_ADDR(CCP)), \
166      "M" (_SFR_MEM_ADDR(WDT_CTRL)), \
167      "r" ((uint8_t)0xD8), \
168      "r" ((uint8_t)(WDT_CEN_bm | WDT_ENABLE_bm | value)) \
169    : "r0" \
170)
171
172
173#elif defined(__AVR_AT90CAN32__) \
174|| defined(__AVR_AT90CAN64__) \
175|| defined(__AVR_AT90CAN128__) \
176|| defined(__AVR_AT90PWM1__) \
177|| defined(__AVR_AT90PWM2__) \
178|| defined(__AVR_AT90PWM216__) \
179|| defined(__AVR_AT90PWM2B__) \
180|| defined(__AVR_AT90PWM3__) \
181|| defined(__AVR_AT90PWM316__) \
182|| defined(__AVR_AT90PWM3B__) \
183|| defined(__AVR_AT90PWM81__) \
184|| defined(__AVR_AT90USB1286__) \
185|| defined(__AVR_AT90USB1287__) \
186|| defined(__AVR_AT90USB162__) \
187|| defined(__AVR_AT90USB646__) \
188|| defined(__AVR_AT90USB647__) \
189|| defined(__AVR_AT90USB82__) \
190|| defined(__AVR_ATmega1280__) \
191|| defined(__AVR_ATmega1281__) \
192|| defined(__AVR_ATmega1284P__) \
193|| defined(__AVR_ATmega128RFA1__) \
194|| defined(__AVR_ATmega164__) \
195|| defined(__AVR_ATmega164A__) \
196|| defined(__AVR_ATmega164P__) \
197|| defined(__AVR_ATmega165__) \
198|| defined(__AVR_ATmega165A__) \
199|| defined(__AVR_ATmega165P__) \
200|| defined(__AVR_ATmega168__) \
201|| defined(__AVR_ATmega168A__) \
202|| defined(__AVR_ATmega168P__) \
203|| defined(__AVR_ATmega169__) \
204|| defined(__AVR_ATmega169A__) \
205|| defined(__AVR_ATmega169P__) \
206|| defined(__AVR_ATmega169PA__) \
207|| defined(__AVR_ATmega16HVA__) \
208|| defined(__AVR_ATmega16HVA2__) \
209|| defined(__AVR_ATmega16HVB__) \
210|| defined(__AVR_ATmega16M1__) \
211|| defined(__AVR_ATmega16U2__) \
212|| defined(__AVR_ATmega16U4__) \
213|| defined(__AVR_ATmega2560__) \
214|| defined(__AVR_ATmega2561__) \
215|| defined(__AVR_ATmega324__) \
216|| defined(__AVR_ATmega324A__) \
217|| defined(__AVR_ATmega324P__) \
218|| defined(__AVR_ATmega324PA__) \
219|| defined(__AVR_ATmega325__) \
220|| defined(__AVR_ATmega3250__) \
221|| defined(__AVR_ATmega328__) \
222|| defined(__AVR_ATmega328P__) \
223|| defined(__AVR_ATmega329__) \
224|| defined(__AVR_ATmega329P__) \
225|| defined(__AVR_ATmega329PA__) \
226|| defined(__AVR_ATmega3290__) \
227|| defined(__AVR_ATmega3290P__) \
228|| defined(__AVR_ATmega32C1__) \
229|| defined(__AVR_ATmega32HVB__) \
230|| defined(__AVR_ATmega32M1__) \
231|| defined(__AVR_ATmega32U2__) \
232|| defined(__AVR_ATmega32U4__) \
233|| defined(__AVR_ATmega32U6__) \
234|| defined(__AVR_ATmega406__) \
235|| defined(__AVR_ATmega48__) \
236|| defined(__AVR_ATmega48A__) \
237|| defined(__AVR_ATmega48P__) \
238|| defined(__AVR_ATmega640__) \
239|| defined(__AVR_ATmega644__) \
240|| defined(__AVR_ATmega644A__) \
241|| defined(__AVR_ATmega644P__) \
242|| defined(__AVR_ATmega644PA__) \
243|| defined(__AVR_ATmega645__) \
244|| defined(__AVR_ATmega645A__) \
245|| defined(__AVR_ATmega645P__) \
246|| defined(__AVR_ATmega6450__) \
247|| defined(__AVR_ATmega6450A__) \
248|| defined(__AVR_ATmega6450P__) \
249|| defined(__AVR_ATmega649__) \
250|| defined(__AVR_ATmega649A__) \
251|| defined(__AVR_ATmega6490__) \
252|| defined(__AVR_ATmega6490A__) \
253|| defined(__AVR_ATmega6490P__) \
254|| defined(__AVR_ATmega649P__) \
255|| defined(__AVR_ATmega64C1__) \
256|| defined(__AVR_ATmega64HVE__) \
257|| defined(__AVR_ATmega64M1__) \
258|| defined(__AVR_ATmega88__) \
259|| defined(__AVR_ATmega88A__) \
260|| defined(__AVR_ATmega88P__) \
261|| defined(__AVR_ATmega88PA__) \
262|| defined(__AVR_ATmega8HVA__) \
263|| defined(__AVR_ATmega8U2__) \
264|| defined(__AVR_ATtiny48__) \
265|| defined(__AVR_ATtiny88__) \
266|| defined(__AVR_ATtiny87__) \
267|| defined(__AVR_ATtiny167__) \
268|| defined(__AVR_AT90SCR100__) \
269|| defined(__AVR_ATA6289__)
270
271/* Use STS instruction. */
272 
273#define wdt_enable(value)   \
274__asm__ __volatile__ (  \
275    "in __tmp_reg__,__SREG__" "\n\t"    \
276    "cli" "\n\t"    \
277    "wdr" "\n\t"    \
278    "sts %0,%1" "\n\t"  \
279    "out __SREG__,__tmp_reg__" "\n\t"   \
280    "sts %0,%2" "\n\t" \
281    : /* no outputs */  \
282    : "M" (_SFR_MEM_ADDR(_WD_CONTROL_REG)), \
283    "r" (_BV(_WD_CHANGE_BIT) | _BV(WDE)), \
284    "r" ((uint8_t) ((value & 0x08 ? _WD_PS3_MASK : 0x00) | \
285        _BV(WDE) | (value & 0x07)) ) \
286    : "r0"  \
287)
288
289#define wdt_disable() \
290__asm__ __volatile__ (  \
291    "in __tmp_reg__, __SREG__" "\n\t" \
292    "cli" "\n\t" \
293    "sts %0, %1" "\n\t" \
294    "sts %0, __zero_reg__" "\n\t" \
295    "out __SREG__,__tmp_reg__" "\n\t" \
296    : /* no outputs */ \
297    : "M" (_SFR_MEM_ADDR(_WD_CONTROL_REG)), \
298    "r" ((uint8_t)(_BV(_WD_CHANGE_BIT) | _BV(WDE))) \
299    : "r0" \
300)
301
302
303   
304#else 
305
306/* Use OUT instruction. */
307
308#define wdt_enable(value)   \
309    __asm__ __volatile__ (  \
310        "in __tmp_reg__,__SREG__" "\n\t"    \
311        "cli" "\n\t"    \
312        "wdr" "\n\t"    \
313        "out %0,%1" "\n\t"  \
314        "out __SREG__,__tmp_reg__" "\n\t"   \
315        "out %0,%2" \
316        : /* no outputs */  \
317        : "I" (_SFR_IO_ADDR(_WD_CONTROL_REG)), \
318        "r" (_BV(_WD_CHANGE_BIT) | _BV(WDE)),   \
319        "r" ((uint8_t) ((value & 0x08 ? _WD_PS3_MASK : 0x00) | \
320            _BV(WDE) | (value & 0x07)) ) \
321        : "r0"  \
322    )
323
324/**
325 *  Disable the watchdog timer, if possible.  This attempts to turn off the
326 *  Enable bit in the watchdog control register. See the datasheet for
327 *  details.
328*/
329#define wdt_disable() \
330__asm__ __volatile__ (  \
331    "in __tmp_reg__, __SREG__" "\n\t" \
332     "cli" "\n\t" \
333    "out %0, %1" "\n\t" \
334    "out %0, __zero_reg__" "\n\t" \
335    "out __SREG__,__tmp_reg__" "\n\t" \
336    : /* no outputs */ \
337    : "I" (_SFR_IO_ADDR(_WD_CONTROL_REG)), \
338    "r" ((uint8_t)(_BV(_WD_CHANGE_BIT) | _BV(WDE))) \
339    : "r0" \
340)
341
342#endif
343
344
345
346/**
347 *  Symbolic constants for the watchdog timeout.  Since the watchdog
348 *  timer is based on a free-running RC oscillator, the times are
349 *  approximate only and apply to a supply voltage of 5 V.  At lower
350 *  supply voltages, the times will increase.  For older devices, the
351 *  times will be as large as three times when operating at Vcc = 3 V,
352 *  while the newer devices (e. g. ATmega128, ATmega8) only experience
353 *  a negligible change.
354 *
355 *  Possible timeout values are: 15 ms, 30 ms, 60 ms, 120 ms, 250 ms,
356 *  500 ms, 1 s, 2 s.  (Some devices also allow for 4 s and 8 s.)
357 *  Symbolic constants are formed by the prefix
358 *  @c WDTO_, followed by the time.
359 *
360 *  Example that would select a watchdog timer expiry of approximately
361 *  500 ms:
362 *
363 *  @code{.c}
364 *  wdt_enable(WDTO_500MS);
365 *  @endcode
366*/
367#define WDTO_15MS   0
368
369/** @see WDT0_15MS */
370#define WDTO_30MS   1
371
372/** @see WDT0_15MS */
373#define WDTO_60MS   2
374
375/** @see WDT0_15MS */
376#define WDTO_120MS  3
377
378/** @see WDT0_15MS */
379#define WDTO_250MS  4
380
381/** @see WDT0_15MS */
382#define WDTO_500MS  5
383
384/** @see WDT0_15MS */
385#define WDTO_1S     6
386
387/** @see WDT0_15MS */
388#define WDTO_2S     7
389
390#if defined(__DOXYGEN__) || defined(WDP3)
391
392/**
393 * @see WDT0_15MS
394 *
395 * Note: This is only available on:
396 * ATtiny2313,
397 * ATtiny24, ATtiny44, ATtiny84,
398 * ATtiny25, ATtiny45, ATtiny85,
399 * ATtiny261, ATtiny461, ATtiny861,
400 * ATmega48, ATmega88, ATmega168,
401 * ATmega48P, ATmega88P, ATmega168P, ATmega328P,
402 * ATmega164P, ATmega324P, ATmega644P, ATmega644,
403 * ATmega640, ATmega1280, ATmega1281, ATmega2560, ATmega2561,
404 * ATmega8HVA, ATmega16HVA, ATmega32HVB,
405 * ATmega406, ATmega1284P,
406 * AT90PWM1, AT90PWM2, AT90PWM2B, AT90PWM3, AT90PWM3B, AT90PWM216, AT90PWM316,
407 * AT90PWM81,
408 * AT90USB82, AT90USB162,
409 * AT90USB646, AT90USB647, AT90USB1286, AT90USB1287,
410 * ATtiny48, ATtiny88.
411 */
412#define WDTO_4S     8
413
414/** @see WDTO_4S */
415#define WDTO_8S     9
416
417#endif  /* defined(__DOXYGEN__) || defined(WDP3) */
418/** @} */   
419
420#endif /* _AVR_WDT_H_ */
Note: See TracBrowser for help on using the repository browser.