$treeview $search $mathjax $extrastylesheet
avr-libc  2.0.0
$projectbrief
$projectbrief
$searchbox

AVR Libc Home Page

AVRs

AVR Libc Development Pages

Main Page

User Manual

Library Reference

FAQ

Example Projects

wdt.h

Go to the documentation of this file.
00001 /* Copyright (c) 2002, 2004 Marek Michalkiewicz
00002    Copyright (c) 2005, 2006, 2007 Eric B. Weddington
00003    All rights reserved.
00004 
00005    Redistribution and use in source and binary forms, with or without
00006    modification, are permitted provided that the following conditions are met:
00007 
00008    * Redistributions of source code must retain the above copyright
00009      notice, this list of conditions and the following disclaimer.
00010 
00011    * Redistributions in binary form must reproduce the above copyright
00012      notice, this list of conditions and the following disclaimer in
00013      the documentation and/or other materials provided with the
00014      distribution.
00015 
00016    * Neither the name of the copyright holders nor the names of
00017      contributors may be used to endorse or promote products derived
00018      from this software without specific prior written permission.
00019 
00020   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00021   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00022   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00023   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00024   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00025   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00026   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00027   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00028   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00029   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00030   POSSIBILITY OF SUCH DAMAGE. */
00031 
00032 /* $Id$ */
00033 
00034 /*
00035    avr/wdt.h - macros for AVR watchdog timer
00036  */
00037 
00038 #ifndef _AVR_WDT_H_
00039 #define _AVR_WDT_H_
00040 
00041 #include <avr/io.h>
00042 #include <stdint.h>
00043 
00044 /** \file */
00045 /** \defgroup avr_watchdog <avr/wdt.h>: Watchdog timer handling
00046     \code #include <avr/wdt.h> \endcode
00047 
00048     This header file declares the interface to some inline macros
00049     handling the watchdog timer present in many AVR devices.  In order
00050     to prevent the watchdog timer configuration from being
00051     accidentally altered by a crashing application, a special timed
00052     sequence is required in order to change it.  The macros within
00053     this header file handle the required sequence automatically
00054     before changing any value.  Interrupts will be disabled during
00055     the manipulation.
00056 
00057     \note Depending on the fuse configuration of the particular
00058     device, further restrictions might apply, in particular it might
00059     be disallowed to turn off the watchdog timer.
00060 
00061     Note that for newer devices (ATmega88 and newer, effectively any
00062     AVR that has the option to also generate interrupts), the watchdog
00063     timer remains active even after a system reset (except a power-on
00064     condition), using the fastest prescaler value (approximately 15
00065     ms).  It is therefore required to turn off the watchdog early
00066     during program startup, the datasheet recommends a sequence like
00067     the following:
00068 
00069     \code
00070     #include <stdint.h>
00071     #include <avr/wdt.h>
00072 
00073     uint8_t mcusr_mirror __attribute__ ((section (".noinit")));
00074 
00075     void get_mcusr(void) \
00076       __attribute__((naked)) \
00077       __attribute__((section(".init3")));
00078     void get_mcusr(void)
00079     {
00080       mcusr_mirror = MCUSR;
00081       MCUSR = 0;
00082       wdt_disable();
00083     }
00084     \endcode
00085 
00086     Saving the value of MCUSR in \c mcusr_mirror is only needed if the
00087     application later wants to examine the reset source, but in particular, 
00088     clearing the watchdog reset flag before disabling the
00089     watchdog is required, according to the datasheet.
00090 */
00091 
00092 /**
00093    \ingroup avr_watchdog
00094    Reset the watchdog timer.  When the watchdog timer is enabled,
00095    a call to this instruction is required before the timer expires,
00096    otherwise a watchdog-initiated device reset will occur. 
00097 */
00098 
00099 #define wdt_reset() __asm__ __volatile__ ("wdr")
00100 
00101 #ifndef __DOXYGEN__
00102 
00103 #if defined(WDP3)
00104 # define _WD_PS3_MASK       _BV(WDP3)
00105 #else
00106 # define _WD_PS3_MASK       0x00
00107 #endif
00108 
00109 #if defined(WDTCSR)
00110 #  define _WD_CONTROL_REG     WDTCSR
00111 #elif defined(WDTCR)
00112 #  define _WD_CONTROL_REG     WDTCR
00113 #else
00114 #  define _WD_CONTROL_REG     WDT
00115 #endif
00116 
00117 #if defined(WDTOE)
00118 #define _WD_CHANGE_BIT      WDTOE
00119 #else
00120 #define _WD_CHANGE_BIT      WDCE
00121 #endif
00122 
00123 #endif  /* !__DOXYGEN__ */
00124 
00125 
00126 /**
00127    \ingroup avr_watchdog
00128    Enable the watchdog timer, configuring it for expiry after
00129    \c timeout (which is a combination of the \c WDP0 through
00130    \c WDP2 bits to write into the \c WDTCR register; For those devices 
00131    that have a \c WDTCSR register, it uses the combination of the \c WDP0 
00132    through \c WDP3 bits).
00133 
00134    See also the symbolic constants \c WDTO_15MS et al.
00135 */
00136 
00137 
00138 #if defined(__AVR_XMEGA__)
00139 
00140 #if defined (WDT_CTRLA) && !defined(RAMPD)
00141 
00142 #define wdt_enable(timeout) \
00143 do { \
00144 uint8_t temp; \
00145 __asm__ __volatile__ ( \
00146     "wdr"                                   "\n\t" \
00147     "out %[ccp_reg], %[ioreg_cen_mask]"     "\n\t" \
00148     "lds %[tmp], %[wdt_reg]"                "\n\t" \
00149     "sbr %[tmp], %[wdt_enable_timeout]"     "\n\t" \
00150     "sts %[wdt_reg], %[tmp]"                "\n\t" \
00151     "1:lds %[tmp], %[wdt_status_reg]"       "\n\t" \
00152     "sbrc %[tmp], %[wdt_syncbusy_bit]"      "\n\t" \
00153     "rjmp 1b"                               "\n\t" \
00154     : [tmp]                 "=r" (temp) \
00155     : [ccp_reg]             "I"  (_SFR_IO_ADDR(CCP)), \
00156       [ioreg_cen_mask]      "r"  ((uint8_t)CCP_IOREG_gc), \
00157       [wdt_reg]             "n"  (_SFR_MEM_ADDR(WDT_CTRLA)), \
00158       [wdt_enable_timeout]  "M"  (timeout), \
00159       [wdt_status_reg]      "n"  (_SFR_MEM_ADDR(WDT_STATUS)), \
00160       [wdt_syncbusy_bit]    "I"  (WDT_SYNCBUSY_bm) \
00161 ); \
00162 } while(0)
00163 
00164 #define wdt_disable() \
00165 do { \
00166 uint8_t temp; \
00167 __asm__ __volatile__ (  \
00168     "wdr"                               "\n\t" \
00169     "out %[ccp_reg], %[ioreg_cen_mask]" "\n\t" \
00170     "lds %[tmp], %[wdt_reg]"            "\n\t" \
00171     "cbr %[tmp], %[timeout_mask]"       "\n\t" \
00172     "sts %[wdt_reg], %[tmp]"            "\n\t" \
00173     : [tmp]            "=r" (temp) \
00174     : [ccp_reg]        "I" (_SFR_IO_ADDR(CCP)),       \
00175       [ioreg_cen_mask] "r" ((uint8_t)CCP_IOREG_gc),   \
00176       [wdt_reg]        "n" (_SFR_MEM_ADDR(WDT_CTRLA)),\
00177       [timeout_mask]   "I" (WDT_PERIOD_gm) \
00178 ); \
00179 } while(0)
00180 
00181 #else // defined (WDT_CTRLA) && !defined(RAMPD)
00182 
00183 /*
00184    wdt_enable(timeout) for xmega devices
00185 ** write signature (CCP_IOREG_gc) that enables change of protected I/O
00186    registers to the CCP register
00187 ** At the same time,
00188    1) set WDT change enable (WDT_CEN_bm)
00189    2) enable WDT (WDT_ENABLE_bm)
00190    3) set timeout (timeout)
00191 ** Synchronization starts when ENABLE bit of WDT is set. So, wait till it
00192    finishes (SYNCBUSY of STATUS register is automatically cleared after the
00193    sync is finished).
00194 */
00195 #define wdt_enable(timeout) \
00196 do { \
00197 uint8_t temp; \
00198 __asm__ __volatile__ (         \
00199     "in __tmp_reg__, %[rampd]"              "\n\t" \
00200     "out %[rampd], __zero_reg__"            "\n\t" \
00201     "out %[ccp_reg], %[ioreg_cen_mask]"     "\n\t" \
00202     "sts %[wdt_reg], %[wdt_enable_timeout]" "\n\t" \
00203     "1:lds %[tmp], %[wdt_status_reg]"       "\n\t" \
00204     "sbrc %[tmp], %[wdt_syncbusy_bit]"      "\n\t" \
00205     "rjmp 1b"                               "\n\t" \
00206     "out %[rampd], __tmp_reg__"             "\n\t" \
00207     : [tmp]                "=r" (temp) \
00208     : [rampd]              "I" (_SFR_IO_ADDR(RAMPD)),      \
00209       [ccp_reg]            "I" (_SFR_IO_ADDR(CCP)),        \
00210       [ioreg_cen_mask]     "r" ((uint8_t)CCP_IOREG_gc),     \
00211       [wdt_reg]            "n" (_SFR_MEM_ADDR(WDT_CTRL)),   \
00212       [wdt_enable_timeout] "r" ((uint8_t)(WDT_CEN_bm | WDT_ENABLE_bm | timeout)), \
00213       [wdt_status_reg]     "n" (_SFR_MEM_ADDR(WDT_STATUS)), \
00214       [wdt_syncbusy_bit]   "I" (WDT_SYNCBUSY_bm)            \
00215     : "r0" \
00216 ); \
00217 } while(0)
00218 
00219 #define wdt_disable() \
00220 __asm__ __volatile__ (  \
00221     "in __tmp_reg__, %[rampd]"          "\n\t" \
00222     "out %[rampd], __zero_reg__"        "\n\t" \
00223     "out %[ccp_reg], %[ioreg_cen_mask]" "\n\t" \
00224     "sts %[wdt_reg], %[disable_mask]"   "\n\t" \
00225     "out %[rampd], __tmp_reg__"         "\n\t" \
00226     : \
00227     : [rampd]             "I" (_SFR_IO_ADDR(RAMPD)),    \
00228       [ccp_reg]           "I" (_SFR_IO_ADDR(CCP)),      \
00229       [ioreg_cen_mask]    "r" ((uint8_t)CCP_IOREG_gc),   \
00230       [wdt_reg]           "n" (_SFR_MEM_ADDR(WDT_CTRL)), \
00231       [disable_mask]      "r" ((uint8_t)((~WDT_ENABLE_bm) | WDT_CEN_bm)) \
00232     : "r0" \
00233 );
00234 
00235 #endif // defined (WDT_CTRLA) && !defined(RAMPD)
00236 
00237 #elif defined(__AVR_TINY__)
00238 
00239 #define wdt_enable(value) \
00240 __asm__ __volatile__ ( \
00241     "in __tmp_reg__,__SREG__" "\n\t"  \
00242     "cli" "\n\t"  \
00243     "wdr" "\n\t"  \
00244     "out %[CCPADDRESS],%[SIGNATURE]" "\n\t"  \
00245     "out %[WDTREG],%[WDVALUE]" "\n\t"  \
00246     "out __SREG__,__tmp_reg__" "\n\t"  \
00247     : /* no outputs */  \
00248     : [CCPADDRESS] "I" (_SFR_IO_ADDR(CCP)),  \
00249       [SIGNATURE] "r" ((uint8_t)0xD8), \
00250       [WDTREG] "I" (_SFR_IO_ADDR(_WD_CONTROL_REG)), \
00251       [WDVALUE] "r" ((uint8_t)((value & 0x08 ? _WD_PS3_MASK : 0x00) \
00252       | _BV(WDE) | (value & 0x07) )) \
00253     : "r16" \
00254 )
00255 
00256 #define wdt_disable() \
00257 do { \
00258 uint8_t temp_wd; \
00259 __asm__ __volatile__ ( \
00260     "in __tmp_reg__,__SREG__" "\n\t"  \
00261     "cli" "\n\t"  \
00262     "wdr" "\n\t"  \
00263     "out %[CCPADDRESS],%[SIGNATURE]" "\n\t"  \
00264     "in  %[TEMP_WD],%[WDTREG]" "\n\t" \
00265     "cbr %[TEMP_WD],%[WDVALUE]" "\n\t" \
00266     "out %[WDTREG],%[TEMP_WD]" "\n\t" \
00267     "out __SREG__,__tmp_reg__" "\n\t" \
00268     : /*no output */ \
00269     : [CCPADDRESS] "I" (_SFR_IO_ADDR(CCP)), \
00270       [SIGNATURE] "r" ((uint8_t)0xD8), \
00271       [WDTREG] "I" (_SFR_IO_ADDR(_WD_CONTROL_REG)), \
00272       [TEMP_WD] "d" (temp_wd), \
00273       [WDVALUE] "n" (1 << WDE) \
00274     : "r16" \
00275 ); \
00276 }while(0)
00277 
00278 #elif defined(CCP)
00279 
00280 static __inline__
00281 __attribute__ ((__always_inline__))
00282 void wdt_enable (const uint8_t value)
00283 {
00284     if (!_SFR_IO_REG_P (CCP) && !_SFR_IO_REG_P (_WD_CONTROL_REG))
00285     {
00286         __asm__ __volatile__ (
00287             "in __tmp_reg__,__SREG__" "\n\t"
00288             "cli" "\n\t"
00289             "wdr" "\n\t"
00290             "sts %[CCPADDRESS],%[SIGNATURE]" "\n\t"
00291             "sts %[WDTREG],%[WDVALUE]" "\n\t"
00292             "out __SREG__,__tmp_reg__" "\n\t"
00293             : /* no outputs */
00294             : [CCPADDRESS] "n" (_SFR_MEM_ADDR(CCP)),
00295             [SIGNATURE] "r" ((uint8_t)0xD8),
00296             [WDTREG] "n" (_SFR_MEM_ADDR(_WD_CONTROL_REG)),
00297             [WDVALUE] "r" ((uint8_t)((value & 0x08 ? _WD_PS3_MASK : 0x00)
00298                 | _BV(WDE) | (value & 0x07) ))
00299             : "r0"
00300             );
00301     }
00302     else if (!_SFR_IO_REG_P (CCP) && _SFR_IO_REG_P (_WD_CONTROL_REG))
00303     {
00304         __asm__ __volatile__ (
00305             "in __tmp_reg__,__SREG__" "\n\t"
00306             "cli" "\n\t"
00307             "wdr" "\n\t"
00308             "sts %[CCPADDRESS],%[SIGNATURE]" "\n\t"
00309             "out %[WDTREG],%[WDVALUE]" "\n\t"
00310             "out __SREG__,__tmp_reg__" "\n\t"
00311             : /* no outputs */
00312             : [CCPADDRESS] "n" (_SFR_MEM_ADDR(CCP)),
00313             [SIGNATURE] "r" ((uint8_t)0xD8),
00314             [WDTREG] "I" (_SFR_IO_ADDR(_WD_CONTROL_REG)),
00315             [WDVALUE] "r" ((uint8_t)((value & 0x08 ? _WD_PS3_MASK : 0x00)
00316                 | _BV(WDE) | (value & 0x07) ))
00317             : "r0"
00318             );
00319     }
00320     else if (_SFR_IO_REG_P (CCP) && !_SFR_IO_REG_P (_WD_CONTROL_REG))
00321     {
00322         __asm__ __volatile__ (
00323             "in __tmp_reg__,__SREG__" "\n\t"
00324             "cli" "\n\t"
00325             "wdr" "\n\t"
00326             "out %[CCPADDRESS],%[SIGNATURE]" "\n\t"
00327             "sts %[WDTREG],%[WDVALUE]" "\n\t"
00328             "out __SREG__,__tmp_reg__" "\n\t"
00329             : /* no outputs */
00330             : [CCPADDRESS] "I" (_SFR_IO_ADDR(CCP)),
00331             [SIGNATURE] "r" ((uint8_t)0xD8),
00332             [WDTREG] "n" (_SFR_MEM_ADDR(_WD_CONTROL_REG)),
00333             [WDVALUE] "r" ((uint8_t)((value & 0x08 ? _WD_PS3_MASK : 0x00)
00334                 | _BV(WDE) | (value & 0x07) ))
00335             : "r0"
00336             );
00337     }
00338     else
00339     {
00340         __asm__ __volatile__ (
00341             "in __tmp_reg__,__SREG__" "\n\t"
00342             "cli" "\n\t"
00343             "wdr" "\n\t"
00344             "out %[CCPADDRESS],%[SIGNATURE]" "\n\t"
00345             "out %[WDTREG],%[WDVALUE]" "\n\t"
00346             "out __SREG__,__tmp_reg__" "\n\t"
00347             : /* no outputs */
00348             : [CCPADDRESS] "I" (_SFR_IO_ADDR(CCP)),
00349             [SIGNATURE] "r" ((uint8_t)0xD8),
00350             [WDTREG] "I" (_SFR_IO_ADDR(_WD_CONTROL_REG)),
00351             [WDVALUE] "r" ((uint8_t)((value & 0x08 ? _WD_PS3_MASK : 0x00)
00352                 | _BV(WDE) | (value & 0x07) ))
00353             : "r0"
00354             );
00355     }
00356 }
00357 
00358 static __inline__
00359 __attribute__ ((__always_inline__))
00360 void wdt_disable (void)
00361 {
00362     if (!_SFR_IO_REG_P (CCP) && !_SFR_IO_REG_P(_WD_CONTROL_REG))
00363     {
00364         uint8_t temp_wd;
00365         __asm__ __volatile__ (
00366                 "in __tmp_reg__,__SREG__" "\n\t"
00367                 "cli" "\n\t"
00368                 "wdr" "\n\t"
00369                 "sts %[CCPADDRESS],%[SIGNATURE]" "\n\t"
00370                 "lds %[TEMP_WD],%[WDTREG]" "\n\t"
00371                 "cbr %[TEMP_WD],%[WDVALUE]" "\n\t"
00372                 "sts %[WDTREG],%[TEMP_WD]" "\n\t"
00373                 "out __SREG__,__tmp_reg__" "\n\t"
00374                 : /*no output */
00375                 : [CCPADDRESS] "n" (_SFR_MEM_ADDR(CCP)),
00376                 [SIGNATURE] "r" ((uint8_t)0xD8),
00377                 [WDTREG] "n" (_SFR_MEM_ADDR(_WD_CONTROL_REG)),
00378                 [TEMP_WD] "d" (temp_wd),
00379                 [WDVALUE] "n" (1 << WDE)
00380                 : "r0"
00381                 );
00382     }
00383     else if (!_SFR_IO_REG_P (CCP) && _SFR_IO_REG_P(_WD_CONTROL_REG))
00384     {
00385         uint8_t temp_wd;
00386         __asm__ __volatile__ (
00387                 "in __tmp_reg__,__SREG__" "\n\t"
00388                 "cli" "\n\t"
00389                 "wdr" "\n\t"
00390                 "sts %[CCPADDRESS],%[SIGNATURE]" "\n\t"
00391                 "in %[TEMP_WD],%[WDTREG]" "\n\t"
00392                 "cbr %[TEMP_WD],%[WDVALUE]" "\n\t"
00393                 "out %[WDTREG],%[TEMP_WD]" "\n\t"
00394                 "out __SREG__,__tmp_reg__" "\n\t"
00395                 : /*no output */
00396                 : [CCPADDRESS] "n" (_SFR_MEM_ADDR(CCP)),
00397                 [SIGNATURE] "r" ((uint8_t)0xD8),
00398                 [WDTREG] "I" (_SFR_IO_ADDR(_WD_CONTROL_REG)),
00399                 [TEMP_WD] "d" (temp_wd),
00400                 [WDVALUE] "n" (1 << WDE)
00401                 : "r0"
00402                 );
00403     }
00404     else if (_SFR_IO_REG_P (CCP) && !_SFR_IO_REG_P(_WD_CONTROL_REG))
00405     {
00406         uint8_t temp_wd;
00407         __asm__ __volatile__ (
00408                 "in __tmp_reg__,__SREG__" "\n\t"
00409                 "cli" "\n\t"
00410                 "wdr" "\n\t"
00411                 "out %[CCPADDRESS],%[SIGNATURE]" "\n\t"
00412                 "lds %[TEMP_WD],%[WDTREG]" "\n\t"
00413                 "cbr %[TEMP_WD],%[WDVALUE]" "\n\t"
00414                 "sts %[WDTREG],%[TEMP_WD]" "\n\t"
00415                 "out __SREG__,__tmp_reg__" "\n\t"
00416                 : /*no output */
00417                 : [CCPADDRESS] "I" (_SFR_IO_ADDR(CCP)),
00418                 [SIGNATURE] "r" ((uint8_t)0xD8),
00419                 [WDTREG] "n" (_SFR_MEM_ADDR(_WD_CONTROL_REG)),
00420                 [TEMP_WD] "d" (temp_wd),
00421                 [WDVALUE] "n" (1 << WDE)
00422                 : "r0"
00423                 );
00424     }
00425     else
00426     {
00427         uint8_t temp_wd;
00428         __asm__ __volatile__ (
00429                 "in __tmp_reg__,__SREG__" "\n\t"
00430                 "cli" "\n\t"
00431                 "wdr" "\n\t"
00432                 "out %[CCPADDRESS],%[SIGNATURE]" "\n\t"
00433                 "in %[TEMP_WD],%[WDTREG]" "\n\t"
00434                 "cbr %[TEMP_WD],%[WDVALUE]" "\n\t"
00435                 "out %[WDTREG],%[TEMP_WD]" "\n\t"
00436                 "out __SREG__,__tmp_reg__" "\n\t"
00437                 : /*no output */
00438                 : [CCPADDRESS] "I" (_SFR_IO_ADDR(CCP)),
00439                 [SIGNATURE] "r" ((uint8_t)0xD8),
00440                 [WDTREG] "I" (_SFR_IO_ADDR(_WD_CONTROL_REG)),
00441                 [TEMP_WD] "d" (temp_wd),
00442                 [WDVALUE] "n" (1 << WDE)
00443                 : "r0"
00444                 );
00445     }
00446 }
00447 
00448 #else
00449 
00450 static __inline__
00451 __attribute__ ((__always_inline__))
00452 void wdt_enable (const uint8_t value)
00453 {
00454     if (_SFR_IO_REG_P (_WD_CONTROL_REG))
00455     {
00456         __asm__ __volatile__ (
00457                 "in __tmp_reg__,__SREG__" "\n\t"
00458                 "cli" "\n\t"
00459                 "wdr" "\n\t"
00460                 "out %0, %1" "\n\t"
00461                 "out __SREG__,__tmp_reg__" "\n\t"
00462                 "out %0, %2" "\n \t"
00463                 : /* no outputs */
00464                 : "I" (_SFR_IO_ADDR(_WD_CONTROL_REG)),
00465                 "r" ((uint8_t)(_BV(_WD_CHANGE_BIT) | _BV(WDE))),
00466                 "r" ((uint8_t) ((value & 0x08 ? _WD_PS3_MASK : 0x00) |
00467                         _BV(WDE) | (value & 0x07)) )
00468                 : "r0"
00469         );
00470     }
00471     else
00472     {
00473         __asm__ __volatile__ (
00474                 "in __tmp_reg__,__SREG__" "\n\t"
00475                 "cli" "\n\t"
00476                 "wdr" "\n\t"
00477                 "sts %0, %1" "\n\t"
00478                 "out __SREG__,__tmp_reg__" "\n\t"
00479                 "sts %0, %2" "\n \t"
00480                 : /* no outputs */
00481                 : "n" (_SFR_MEM_ADDR(_WD_CONTROL_REG)),
00482                 "r" ((uint8_t)(_BV(_WD_CHANGE_BIT) | _BV(WDE))),
00483                 "r" ((uint8_t) ((value & 0x08 ? _WD_PS3_MASK : 0x00) |
00484                         _BV(WDE) | (value & 0x07)) )
00485                 : "r0"
00486         );
00487     }
00488 }
00489 
00490 static __inline__
00491 __attribute__ ((__always_inline__))
00492 void wdt_disable (void)
00493 {
00494     if (_SFR_IO_REG_P (_WD_CONTROL_REG))
00495     {
00496         uint8_t register temp_reg;
00497         __asm__ __volatile__ (
00498                 "in __tmp_reg__,__SREG__"    "\n\t"
00499                 "cli"                        "\n\t"
00500                 "wdr"                        "\n\t"
00501                 "in  %[TEMPREG],%[WDTREG]"   "\n\t"
00502                 "ori %[TEMPREG],%[WDCE_WDE]" "\n\t"
00503                 "out %[WDTREG],%[TEMPREG]"   "\n\t"
00504                 "out %[WDTREG],__zero_reg__" "\n\t"
00505                 "out __SREG__,__tmp_reg__"   "\n\t"
00506                 : [TEMPREG] "=d" (temp_reg)
00507                 : [WDTREG]  "I"  (_SFR_IO_ADDR(_WD_CONTROL_REG)),
00508                 [WDCE_WDE]  "n"  ((uint8_t)(_BV(_WD_CHANGE_BIT) | _BV(WDE)))
00509                 : "r0"
00510         );
00511     }
00512     else
00513     {
00514         uint8_t register temp_reg;
00515         __asm__ __volatile__ (
00516                 "in __tmp_reg__,__SREG__"    "\n\t"
00517                 "cli"                        "\n\t"
00518                 "wdr"                        "\n\t"
00519                 "lds %[TEMPREG],%[WDTREG]"   "\n\t"
00520                 "ori %[TEMPREG],%[WDCE_WDE]" "\n\t"
00521                 "sts %[WDTREG],%[TEMPREG]"   "\n\t"
00522                 "sts %[WDTREG],__zero_reg__" "\n\t"
00523                 "out __SREG__,__tmp_reg__"   "\n\t"
00524                 : [TEMPREG] "=d" (temp_reg)
00525                 : [WDTREG]  "n"  (_SFR_MEM_ADDR(_WD_CONTROL_REG)),
00526                 [WDCE_WDE]  "n"  ((uint8_t)(_BV(_WD_CHANGE_BIT) | _BV(WDE)))
00527                 : "r0"
00528         );
00529     }
00530 }
00531 
00532 #endif
00533 
00534 
00535 /**
00536    \ingroup avr_watchdog
00537    Symbolic constants for the watchdog timeout.  Since the watchdog
00538    timer is based on a free-running RC oscillator, the times are
00539    approximate only and apply to a supply voltage of 5 V.  At lower
00540    supply voltages, the times will increase.  For older devices, the
00541    times will be as large as three times when operating at Vcc = 3 V,
00542    while the newer devices (e. g. ATmega128, ATmega8) only experience
00543    a negligible change.
00544 
00545    Possible timeout values are: 15 ms, 30 ms, 60 ms, 120 ms, 250 ms,
00546    500 ms, 1 s, 2 s.  (Some devices also allow for 4 s and 8 s.)
00547    Symbolic constants are formed by the prefix
00548    \c WDTO_, followed by the time.
00549 
00550    Example that would select a watchdog timer expiry of approximately
00551    500 ms:
00552    \code
00553    wdt_enable(WDTO_500MS);
00554    \endcode
00555 */
00556 #define WDTO_15MS   0
00557 
00558 /** \ingroup avr_watchdog
00559     See \c WDTO_15MS */
00560 #define WDTO_30MS   1
00561 
00562 /** \ingroup avr_watchdog
00563     See \c WDTO_15MS */
00564 #define WDTO_60MS   2
00565 
00566 /** \ingroup avr_watchdog
00567     See \c WDTO_15MS */
00568 #define WDTO_120MS  3
00569 
00570 /** \ingroup avr_watchdog
00571     See \c WDTO_15MS */
00572 #define WDTO_250MS  4
00573 
00574 /** \ingroup avr_watchdog
00575     See \c WDTO_15MS */
00576 #define WDTO_500MS  5
00577 
00578 /** \ingroup avr_watchdog
00579     See \c WDTO_15MS */
00580 #define WDTO_1S     6
00581 
00582 /** \ingroup avr_watchdog
00583     See \c WDTO_15MS */
00584 #define WDTO_2S     7
00585 
00586 #if defined(__DOXYGEN__) || defined(WDP3)
00587 
00588 /** \ingroup avr_watchdog
00589     See \c WDTO_15MS
00590     Note: This is only available on the 
00591     ATtiny2313, 
00592     ATtiny24, ATtiny44, ATtiny84, ATtiny84A,
00593     ATtiny25, ATtiny45, ATtiny85, 
00594     ATtiny261, ATtiny461, ATtiny861, 
00595     ATmega48, ATmega88, ATmega168,
00596     ATmega48P, ATmega88P, ATmega168P, ATmega328P,
00597     ATmega164P, ATmega324P, ATmega644P, ATmega644,
00598     ATmega640, ATmega1280, ATmega1281, ATmega2560, ATmega2561,
00599     ATmega8HVA, ATmega16HVA, ATmega32HVB,
00600     ATmega406, ATmega1284P,
00601     AT90PWM1, AT90PWM2, AT90PWM2B, AT90PWM3, AT90PWM3B, AT90PWM216, AT90PWM316,
00602     AT90PWM81, AT90PWM161,
00603     AT90USB82, AT90USB162,
00604     AT90USB646, AT90USB647, AT90USB1286, AT90USB1287,
00605     ATtiny48, ATtiny88.
00606 
00607     Note: This value does <em>not</em> match the bit pattern of the
00608     respective control register.  It is solely meant to be used together
00609     with wdt_enable().
00610     */
00611 #define WDTO_4S     8
00612 
00613 /** \ingroup avr_watchdog
00614     See \c WDTO_15MS
00615     Note: This is only available on the 
00616     ATtiny2313, 
00617     ATtiny24, ATtiny44, ATtiny84, ATtiny84A,
00618     ATtiny25, ATtiny45, ATtiny85, 
00619     ATtiny261, ATtiny461, ATtiny861, 
00620     ATmega48, ATmega48A, ATmega48PA, ATmega88, ATmega168,
00621     ATmega48P, ATmega88P, ATmega168P, ATmega328P,
00622     ATmega164P, ATmega324P, ATmega644P, ATmega644,
00623     ATmega640, ATmega1280, ATmega1281, ATmega2560, ATmega2561,
00624     ATmega8HVA, ATmega16HVA, ATmega32HVB,
00625     ATmega406, ATmega1284P,
00626     ATmega2564RFR2, ATmega256RFR2, ATmega1284RFR2, ATmega128RFR2, ATmega644RFR2, ATmega64RFR2
00627     AT90PWM1, AT90PWM2, AT90PWM2B, AT90PWM3, AT90PWM3B, AT90PWM216, AT90PWM316,
00628     AT90PWM81, AT90PWM161,
00629     AT90USB82, AT90USB162,
00630     AT90USB646, AT90USB647, AT90USB1286, AT90USB1287,
00631     ATtiny48, ATtiny88,
00632     ATxmega16a4u, ATxmega32a4u,
00633     ATxmega16c4, ATxmega32c4,
00634     ATxmega128c3, ATxmega192c3, ATxmega256c3.
00635 
00636     Note: This value does <em>not</em> match the bit pattern of the
00637     respective control register.  It is solely meant to be used together
00638     with wdt_enable().
00639     */
00640 #define WDTO_8S     9
00641 
00642 #endif  /* defined(__DOXYGEN__) || defined(WDP3) */
00643    
00644 
00645 #endif /* _AVR_WDT_H_ */
 All Data Structures Files Functions Variables Typedefs Enumerations Defines