AVR Libc Home Page AVRs AVR Libc Development Pages
Main Page User Manual Library Reference FAQ Alphabetical Index 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 
00102 #if defined(WDP3)
00103 # define _WD_PS3_MASK       _BV(WDP3)
00104 #else
00105 # define _WD_PS3_MASK       0x00
00106 #endif
00107 
00108 #if defined(WDTCSR)
00109 #  define _WD_CONTROL_REG     WDTCSR
00110 #elif defined(WDTCR)
00111 #  define _WD_CONTROL_REG     WDTCR
00112 #else
00113 #  define _WD_CONTROL_REG     WDT
00114 #endif
00115 
00116 #if defined(WDTOE)
00117 #define _WD_CHANGE_BIT      WDTOE
00118 #else
00119 #define _WD_CHANGE_BIT      WDCE
00120 #endif
00121 
00122 
00123 /**
00124    \ingroup avr_watchdog
00125    Enable the watchdog timer, configuring it for expiry after
00126    \c timeout (which is a combination of the \c WDP0 through
00127    \c WDP2 bits to write into the \c WDTCR register; For those devices 
00128    that have a \c WDTCSR register, it uses the combination of the \c WDP0 
00129    through \c WDP3 bits).
00130 
00131    See also the symbolic constants \c WDTO_15MS et al.
00132 */
00133 
00134 
00135 #if defined(__AVR_ATxmega16A4__) \
00136 || defined(__AVR_ATxmega16A4U__) \
00137 || defined(__AVR_ATxmega16C4__) \
00138 || defined(__AVR_ATxmega16D4__) \
00139 || defined(__AVR_ATxmega32A4__) \
00140 || defined(__AVR_ATxmega32A4U__) \
00141 || defined(__AVR_ATxmega32C3__) \
00142 || defined(__AVR_ATxmega32C4__) \
00143 || defined(__AVR_ATxmega32D3__) \
00144 || defined(__AVR_ATxmega32D4__) \
00145 || defined(__AVR_ATxmega8E5__) \
00146 || defined(__AVR_ATxmega16E5__) \
00147 || defined(__AVR_ATxmega32E5__) \
00148 || defined(__AVR_ATxmega64A1__) \
00149 || defined(__AVR_ATxmega64A1U__) \
00150 || defined(__AVR_ATxmega64A3__) \
00151 || defined(__AVR_ATxmega64A3U__) \
00152 || defined(__AVR_ATxmega64A4U__) \
00153 || defined(__AVR_ATxmega64B1__) \
00154 || defined(__AVR_ATxmega64B3__) \
00155 || defined(__AVR_ATxmega64C3__) \
00156 || defined(__AVR_ATxmega64D3__) \
00157 || defined(__AVR_ATxmega64D4__) \
00158 || defined(__AVR_ATxmega128A1__) \
00159 || defined(__AVR_ATxmega128A1U__) \
00160 || defined(__AVR_ATxmega128A3__) \
00161 || defined(__AVR_ATxmega128A3U__) \
00162 || defined(__AVR_ATxmega128A4U__) \
00163 || defined(__AVR_ATxmega128B1__) \
00164 || defined(__AVR_ATxmega128B3__) \
00165 || defined(__AVR_ATxmega128C3__) \
00166 || defined(__AVR_ATxmega128D3__) \
00167 || defined(__AVR_ATxmega128D4__) \
00168 || defined(__AVR_ATxmega192A3__) \
00169 || defined(__AVR_ATxmega192A3U__) \
00170 || defined(__AVR_ATxmega192C3__) \
00171 || defined(__AVR_ATxmega192D3__) \
00172 || defined(__AVR_ATxmega256A3__) \
00173 || defined(__AVR_ATxmega256A3U__) \
00174 || defined(__AVR_ATxmega256C3__) \
00175 || defined(__AVR_ATxmega256D3__) \
00176 || defined(__AVR_ATxmega256A3B__) \
00177 || defined(__AVR_ATxmega256A3BU__) \
00178 || defined(__AVR_ATxmega384C3__) \
00179 || defined(__AVR_ATxmega384D3__)
00180 
00181 /*
00182    wdt_enable(timeout) for xmega devices
00183 ** write signature (CCP_IOREG_gc) that enables change of protected I/O
00184    registers to the CCP register
00185 ** At the same time,
00186    1) set WDT change enable (WDT_CEN_bm)
00187    2) enable WDT (WDT_ENABLE_bm)
00188    3) set timeout (timeout)
00189 ** Synchronization starts when ENABLE bit of WDT is set. So, wait till it
00190    finishes (SYNCBUSY of STATUS register is automatically cleared after the
00191    sync is finished).
00192 */
00193 #define wdt_enable(timeout) \
00194 do { \
00195 uint8_t temp = 0; \
00196 __asm__ __volatile__ (         \
00197     "in __tmp_reg__, %[rampd]"              "\n\t" \
00198     "out %[rampd], __zero_reg__"            "\n\t" \
00199     "out %[ccp_reg], %[ioreg_cen_mask]"     "\n\t" \
00200     "sts %[wdt_reg], %[wdt_enable_timeout]" "\n\t" \
00201     "1:lds %[tmp], %[wdt_status_reg]"       "\n\t" \
00202     "sbrc  %[tmp], %[wdt_syncbusy_bit]"     "\n\t" \
00203     "rjmp 1b"                               "\n\t" \
00204     "out %[rampd], __tmp_reg__"             "\n\t" \
00205     : "=r" (temp) \
00206     : [rampd]              "M" (_SFR_MEM_ADDR(RAMPD)),      \
00207       [ccp_reg]            "I" (_SFR_MEM_ADDR(CCP)),        \
00208       [ioreg_cen_mask]     "r" ((uint8_t)CCP_IOREG_gc),     \
00209       [wdt_reg]            "M" (_SFR_MEM_ADDR(WDT_CTRL)),   \
00210       [wdt_enable_timeout] "r" ((uint8_t)(WDT_CEN_bm | WDT_ENABLE_bm | timeout)), \
00211       [wdt_status_reg]     "M" (_SFR_MEM_ADDR(WDT_STATUS)), \
00212       [wdt_syncbusy_bit]   "I" (WDT_SYNCBUSY_bm),           \
00213       [tmp]                "r" (temp)                       \
00214     : "r0" \
00215 ); \
00216 } while(0)
00217 
00218 #define wdt_disable() \
00219 __asm__ __volatile__ (  \
00220     "in __tmp_reg__, %[rampd]"          "\n\t" \
00221     "out %[rampd], __zero_reg__"        "\n\t" \
00222     "out %[ccp_reg], %[ioreg_cen_mask]" "\n\t" \
00223     "sts %[wdt_reg], %[disable_mask]"    "\n\t" \
00224     "out %[rampd], __tmp_reg__"         "\n\t" \
00225     : \
00226     : [rampd]             "M" (_SFR_MEM_ADDR(RAMPD)),    \
00227       [ccp_reg]           "I" (_SFR_MEM_ADDR(CCP)),      \
00228       [ioreg_cen_mask]    "r" ((uint8_t)CCP_IOREG_gc),   \
00229       [wdt_reg]           "M" (_SFR_MEM_ADDR(WDT_CTRL)), \
00230       [disable_mask]      "r" ((uint8_t)((~WDT_ENABLE_bm) | WDT_CEN_bm)) \
00231     : "r0" \
00232 );
00233 
00234 #elif defined(__AVR_AT90CAN32__) \
00235 || defined(__AVR_AT90CAN64__) \
00236 || defined(__AVR_AT90CAN128__) \
00237 || defined(__AVR_AT90PWM1__) \
00238 || defined(__AVR_AT90PWM2__) \
00239 || defined(__AVR_AT90PWM216__) \
00240 || defined(__AVR_AT90PWM2B__) \
00241 || defined(__AVR_AT90PWM3__) \
00242 || defined(__AVR_AT90PWM316__) \
00243 || defined(__AVR_AT90PWM3B__) \
00244 || defined(__AVR_AT90PWM161__) \
00245 || defined(__AVR_AT90PWM81__) \
00246 || defined(__AVR_AT90USB1286__) \
00247 || defined(__AVR_AT90USB1287__) \
00248 || defined(__AVR_AT90USB162__) \
00249 || defined(__AVR_AT90USB646__) \
00250 || defined(__AVR_AT90USB647__) \
00251 || defined(__AVR_AT90USB82__) \
00252 || defined(__AVR_ATmega128A__) \
00253 || defined(__AVR_ATmega1280__) \
00254 || defined(__AVR_ATmega1281__) \
00255 || defined(__AVR_ATmega1284__) \
00256 || defined(__AVR_ATmega1284P__) \
00257 || defined(__AVR_ATmega128RFA1__) \
00258 || defined(__AVR_ATmega128RFR2__) \
00259 || defined(__AVR_ATmega1284RFR2__) \
00260 || defined(__AVR_ATmega164__) \
00261 || defined(__AVR_ATmega164A__) \
00262 || defined(__AVR_ATmega164P__) \
00263 || defined(__AVR_ATmega164PA__) \
00264 || defined(__AVR_ATmega165__) \
00265 || defined(__AVR_ATmega165A__) \
00266 || defined(__AVR_ATmega165P__) \
00267 || defined(__AVR_ATmega165PA__) \
00268 || defined(__AVR_ATmega168__) \
00269 || defined(__AVR_ATmega168A__) \
00270 || defined(__AVR_ATmega168P__) \
00271 || defined(__AVR_ATmega168PA__) \
00272 || defined(__AVR_ATmega169__) \
00273 || defined(__AVR_ATmega169A__) \
00274 || defined(__AVR_ATmega169P__) \
00275 || defined(__AVR_ATmega169PA__) \
00276 || defined(__AVR_ATmega16HVA__) \
00277 || defined(__AVR_ATmega16HVA2__) \
00278 || defined(__AVR_ATmega16HVB__) \
00279 || defined(__AVR_ATmega16HVBrevB__) \
00280 || defined(__AVR_ATmega16M1__) \
00281 || defined(__AVR_ATmega16U2__) \
00282 || defined(__AVR_ATmega16U4__) \
00283 || defined(__AVR_ATmega2560__) \
00284 || defined(__AVR_ATmega2561__) \
00285 || defined(__AVR_ATmega256RFR2__) \
00286 || defined(__AVR_ATmega2564RFR2__) \
00287 || defined(__AVR_ATmega32A__) \
00288 || defined(__AVR_ATmega324__) \
00289 || defined(__AVR_ATmega324A__) \
00290 || defined(__AVR_ATmega324P__) \
00291 || defined(__AVR_ATmega324PA__) \
00292 || defined(__AVR_ATmega325__) \
00293 || defined(__AVR_ATmega325A__) \
00294 || defined(__AVR_ATmega325P__) \
00295 || defined(__AVR_ATmega325PA__) \
00296 || defined(__AVR_ATmega3250__) \
00297 || defined(__AVR_ATmega3250A__) \
00298 || defined(__AVR_ATmega3250P__) \
00299 || defined(__AVR_ATmega3250PA__) \
00300 || defined(__AVR_ATmega328__) \
00301 || defined(__AVR_ATmega328P__) \
00302 || defined(__AVR_ATmega329__) \
00303 || defined(__AVR_ATmega329A__) \
00304 || defined(__AVR_ATmega329P__) \
00305 || defined(__AVR_ATmega329PA__) \
00306 || defined(__AVR_ATmega3290__) \
00307 || defined(__AVR_ATmega3290A__) \
00308 || defined(__AVR_ATmega3290P__) \
00309 || defined(__AVR_ATmega3290PA__) \
00310 || defined(__AVR_ATmega32C1__) \
00311 || defined(__AVR_ATmega32HVB__) \
00312 || defined(__AVR_ATmega32HVBrevB__) \
00313 || defined(__AVR_ATmega32M1__) \
00314 || defined(__AVR_ATmega32U2__) \
00315 || defined(__AVR_ATmega32U4__) \
00316 || defined(__AVR_ATmega32U6__) \
00317 || defined(__AVR_ATmega406__) \
00318 || defined(__AVR_ATmega48__) \
00319 || defined(__AVR_ATmega48A__) \
00320 || defined(__AVR_ATmega48PA__) \
00321 || defined(__AVR_ATmega48P__) \
00322 || defined(__AVR_ATmega64A__) \
00323 || defined(__AVR_ATmega64RFR2__) \
00324 || defined(__AVR_ATmega644RFR2__) \
00325 || defined(__AVR_ATmega640__) \
00326 || defined(__AVR_ATmega644__) \
00327 || defined(__AVR_ATmega644A__) \
00328 || defined(__AVR_ATmega644P__) \
00329 || defined(__AVR_ATmega644PA__) \
00330 || defined(__AVR_ATmega645__) \
00331 || defined(__AVR_ATmega645A__) \
00332 || defined(__AVR_ATmega645P__) \
00333 || defined(__AVR_ATmega6450__) \
00334 || defined(__AVR_ATmega6450A__) \
00335 || defined(__AVR_ATmega6450P__) \
00336 || defined(__AVR_ATmega649__) \
00337 || defined(__AVR_ATmega649A__) \
00338 || defined(__AVR_ATmega6490__) \
00339 || defined(__AVR_ATmega6490A__) \
00340 || defined(__AVR_ATmega6490P__) \
00341 || defined(__AVR_ATmega649P__) \
00342 || defined(__AVR_ATmega64C1__) \
00343 || defined(__AVR_ATmega64HVE__) \
00344 || defined(__AVR_ATmega64HVE2__) \
00345 || defined(__AVR_ATmega64M1__) \
00346 || defined(__AVR_ATmega8A__) \
00347 || defined(__AVR_ATmega88__) \
00348 || defined(__AVR_ATmega88A__) \
00349 || defined(__AVR_ATmega88P__) \
00350 || defined(__AVR_ATmega88PA__) \
00351 || defined(__AVR_ATmega8HVA__) \
00352 || defined(__AVR_ATmega8U2__) \
00353 || defined(__AVR_ATtiny48__) \
00354 || defined(__AVR_ATtiny88__) \
00355 || defined(__AVR_ATtiny87__) \
00356 || defined(__AVR_ATtiny167__) \
00357 || defined(__AVR_AT90SCR100__) \
00358 || defined(__AVR_ATA6285__) \
00359 || defined(__AVR_ATA6286__) \
00360 || defined(__AVR_ATA6289__) \
00361 || defined(__AVR_ATA5272__) \
00362 || defined(__AVR_ATA5505__) \
00363 || defined(__AVR_ATA5790__) \
00364 || defined(__AVR_ATA5790N__) \
00365 || defined(__AVR_ATA5795__) \
00366 || defined(__AVR_ATA5782__) \
00367 || defined(__AVR_ATA5702M322__) \
00368 || defined(__AVR_ATA5831__) \
00369 || defined(__AVR_ATA6612C__) \
00370 || defined(__AVR_ATA6613C__) \
00371 || defined(__AVR_ATA6614Q__) \
00372 || defined(__AVR_ATA6616C__) \
00373 || defined(__AVR_ATA6617C__) \
00374 || defined(__AVR_ATA664251__) 
00375 
00376 /* Use STS instruction. */
00377  
00378 #define wdt_enable(value)   \
00379 __asm__ __volatile__ (  \
00380     "in __tmp_reg__,__SREG__" "\n\t"    \
00381     "cli" "\n\t"    \
00382     "wdr" "\n\t"    \
00383     "sts %0,%1" "\n\t"  \
00384     "out __SREG__,__tmp_reg__" "\n\t"   \
00385     "sts %0,%2" "\n\t" \
00386     : /* no outputs */  \
00387     : "M" (_SFR_MEM_ADDR(_WD_CONTROL_REG)), \
00388     "r" (_BV(_WD_CHANGE_BIT) | _BV(WDE)), \
00389     "r" ((uint8_t) ((value & 0x08 ? _WD_PS3_MASK : 0x00) | \
00390         _BV(WDE) | (value & 0x07)) ) \
00391     : "r0"  \
00392 )
00393 
00394 #define wdt_disable() \
00395 __asm__ __volatile__ (  \
00396     "in __tmp_reg__, __SREG__" "\n\t" \
00397     "cli" "\n\t" \
00398     "sts %0, %1" "\n\t" \
00399     "sts %0, __zero_reg__" "\n\t" \
00400     "out __SREG__,__tmp_reg__" "\n\t" \
00401     : /* no outputs */ \
00402     : "M" (_SFR_MEM_ADDR(_WD_CONTROL_REG)), \
00403     "r" ((uint8_t)(_BV(_WD_CHANGE_BIT) | _BV(WDE))) \
00404     : "r0" \
00405 )
00406 
00407 
00408 #elif defined(__AVR_ATtiny441__) \
00409 || defined(__AVR_ATtiny841__)
00410 
00411 /* Use STS instruction. */
00412 
00413 #define wdt_enable(value) \
00414 __asm__ __volatile__ ( \
00415     "in __tmp_reg__,__SREG__" "\n\t"  \
00416     "cli" "\n\t"  \
00417     "wdr" "\n\t"  \
00418     "sts %[CCPADDRESS],%[SIGNATURE]" "\n\t"  \
00419     "out %[WDTREG],%[WDVALUE]" "\n\t"  \
00420     "out __SREG__,__tmp_reg__" "\n\t"  \
00421     : /* no outputs */  \
00422     : [CCPADDRESS] "M" (_SFR_MEM_ADDR(CCP)),  \
00423       [SIGNATURE] "r" ((uint8_t)0xD8), \
00424       [WDTREG] "I" (_SFR_IO_ADDR(_WD_CONTROL_REG)), \
00425       [WDVALUE] "r" ((uint8_t)((value & 0x08 ? _WD_PS3_MASK : 0x00) \
00426       | _BV(WDE) | (value & 0x07) )) \
00427     : "r0" \
00428 )
00429 
00430 #define wdt_disable() \
00431 do { \
00432 uint8_t temp_wd; \
00433 __asm__ __volatile__ ( \
00434     "in __tmp_reg__,__SREG__" "\n\t"  \
00435     "cli" "\n\t"  \
00436     "wdr" "\n\t"  \
00437     "sts %[CCPADDRESS],%[SIGNATURE]" "\n\t"  \
00438     "in  %[TEMP_WD],%[WDTREG]" "\n\t" \
00439     "cbr %[TEMP_WD],%[WDVALUE]" "\n\t" \
00440     "out %[WDTREG],%[TEMP_WD]" "\n\t" \
00441     "out __SREG__,__tmp_reg__" "\n\t" \
00442     : /*no output */ \
00443     : [CCPADDRESS] "M" (_SFR_MEM_ADDR(CCP)), \
00444       [SIGNATURE] "r" ((uint8_t)0xD8), \
00445       [WDTREG] "I" (_SFR_IO_ADDR(_WD_CONTROL_REG)), \
00446       [TEMP_WD] "d" (temp_wd), \
00447       [WDVALUE] "I" (1 << WDE) \
00448     : "r0" \
00449 ); \
00450 }while(0)
00451 
00452 #elif defined(__AVR_ATtiny1634__) \
00453 || defined(__AVR_ATtiny828__)
00454 
00455 #define wdt_enable(value) \
00456 __asm__ __volatile__ ( \
00457     "in __tmp_reg__,__SREG__" "\n\t"  \
00458     "cli" "\n\t"  \
00459     "wdr" "\n\t"  \
00460     "sts %[CCPADDRESS],%[SIGNATURE]" "\n\t"  \
00461     "sts %[WDTREG],%[WDVALUE]" "\n\t"  \
00462     "out __SREG__,__tmp_reg__" "\n\t"  \
00463     : /* no outputs */  \
00464     : [CCPADDRESS] "M" (_SFR_MEM_ADDR(CCP)),  \
00465       [SIGNATURE] "r" ((uint8_t)0xD8), \
00466       [WDTREG] "M" (_SFR_MEM_ADDR(_WD_CONTROL_REG)), \
00467       [WDVALUE] "r" ((uint8_t)((value & 0x08 ? _WD_PS3_MASK : 0x00) \
00468       | _BV(WDE) | value)) \
00469     : "r0" \
00470 )
00471 
00472 #define wdt_disable() \
00473 do { \
00474 uint8_t temp_wd; \
00475 __asm__ __volatile__ ( \
00476     "in __tmp_reg__,__SREG__" "\n\t"  \
00477     "cli" "\n\t"  \
00478     "wdr" "\n\t"  \
00479     "out %[CCPADDRESS],%[SIGNATURE]" "\n\t"  \
00480     "in  %[TEMP_WD],%[WDTREG]" "\n\t" \
00481     "cbr %[TEMP_WD],%[WDVALUE]" "\n\t" \
00482     "out %[WDTREG],%[TEMP_WD]" "\n\t" \
00483     "out __SREG__,__tmp_reg__" "\n\t" \
00484     : /*no output */ \
00485     : [CCPADDRESS] "I" (_SFR_IO_ADDR(CCP)), \
00486       [SIGNATURE] "r" ((uint8_t)0xD8), \
00487       [WDTREG] "I" (_SFR_IO_ADDR(_WD_CONTROL_REG)), \
00488       [TEMP_WD] "d" (temp_wd), \
00489       [WDVALUE] "I" (1 << WDE) \
00490     : "r0" \
00491 ); \
00492 }while(0)
00493 
00494 #elif defined(__AVR_ATtiny4__) \
00495 || defined(__AVR_ATtiny5__) \
00496 || defined(__AVR_ATtiny9__) \
00497 || defined(__AVR_ATtiny10__) \
00498 || defined(__AVR_ATtiny20__) \
00499 || defined(__AVR_ATtiny40__) 
00500 
00501 #define wdt_enable(value) \
00502 __asm__ __volatile__ ( \
00503     "in __tmp_reg__,__SREG__" "\n\t"  \
00504     "cli" "\n\t"  \
00505     "wdr" "\n\t"  \
00506     "out %[CCPADDRESS],%[SIGNATURE]" "\n\t"  \
00507     "out %[WDTREG],%[WDVALUE]" "\n\t"  \
00508     "out __SREG__,__tmp_reg__" "\n\t"  \
00509     : /* no outputs */  \
00510     : [CCPADDRESS] "I" (_SFR_IO_ADDR(CCP)),  \
00511       [SIGNATURE] "r" ((uint8_t)0xD8), \
00512       [WDTREG] "I" (_SFR_IO_ADDR(_WD_CONTROL_REG)), \
00513       [WDVALUE] "r" ((uint8_t)((value & 0x08 ? _WD_PS3_MASK : 0x00) \
00514       | _BV(WDE) | value)) \
00515     : "r16" \
00516 )
00517 
00518 #define wdt_disable() \
00519 do { \
00520 uint8_t temp_wd; \
00521 __asm__ __volatile__ ( \
00522     "in __tmp_reg__,__SREG__" "\n\t"  \
00523     "cli" "\n\t"  \
00524     "wdr" "\n\t"  \
00525     "out %[CCPADDRESS],%[SIGNATURE]" "\n\t"  \
00526     "in  %[TEMP_WD],%[WDTREG]" "\n\t" \
00527     "cbr %[TEMP_WD],%[WDVALUE]" "\n\t" \
00528     "out %[WDTREG],%[TEMP_WD]" "\n\t" \
00529     "out __SREG__,__tmp_reg__" "\n\t" \
00530     : /*no output */ \
00531     : [CCPADDRESS] "I" (_SFR_IO_ADDR(CCP)), \
00532       [SIGNATURE] "r" ((uint8_t)0xD8), \
00533       [WDTREG] "I" (_SFR_IO_ADDR(_WD_CONTROL_REG)), \
00534       [TEMP_WD] "d" (temp_wd), \
00535       [WDVALUE] "I" (1 << WDE) \
00536     : "r16" \
00537 ); \
00538 }while(0)
00539 
00540 /**
00541 Undefining explicitly so that it produces an error.
00542  */
00543 #elif defined(__AVR_AT90C8534__) \
00544 || defined(__AVR_M3000__) 
00545     #undef wdt_enable
00546     #undef wdt_disale    
00547     
00548 #else  
00549 
00550 /* Use OUT instruction. */
00551 
00552 #define wdt_enable(value)   \
00553     __asm__ __volatile__ (  \
00554         "in __tmp_reg__,__SREG__" "\n\t"    \
00555         "cli" "\n\t"    \
00556         "wdr" "\n\t"    \
00557         "out %0,%1" "\n\t"  \
00558         "out __SREG__,__tmp_reg__" "\n\t"   \
00559         "out %0,%2" \
00560         : /* no outputs */  \
00561         : "I" (_SFR_IO_ADDR(_WD_CONTROL_REG)), \
00562         "r" (_BV(_WD_CHANGE_BIT) | _BV(WDE)),   \
00563         "r" ((uint8_t) ((value & 0x08 ? _WD_PS3_MASK : 0x00) | \
00564             _BV(WDE) | (value & 0x07)) ) \
00565         : "r0"  \
00566     )
00567 
00568 /**
00569    \ingroup avr_watchdog
00570    Disable the watchdog timer, if possible.  This attempts to turn off the 
00571    Enable bit in the watchdog control register. See the datasheet for 
00572    details.
00573 */
00574 #define wdt_disable() \
00575 __asm__ __volatile__ (  \
00576     "in __tmp_reg__, __SREG__" "\n\t" \
00577      "cli" "\n\t" \
00578     "out %0, %1" "\n\t" \
00579     "out %0, __zero_reg__" "\n\t" \
00580     "out __SREG__,__tmp_reg__" "\n\t" \
00581     : /* no outputs */ \
00582     : "I" (_SFR_IO_ADDR(_WD_CONTROL_REG)), \
00583     "r" ((uint8_t)(_BV(_WD_CHANGE_BIT) | _BV(WDE))) \
00584     : "r0" \
00585 )
00586 
00587 #endif
00588 
00589 
00590 
00591 /**
00592    \ingroup avr_watchdog
00593    Symbolic constants for the watchdog timeout.  Since the watchdog
00594    timer is based on a free-running RC oscillator, the times are
00595    approximate only and apply to a supply voltage of 5 V.  At lower
00596    supply voltages, the times will increase.  For older devices, the
00597    times will be as large as three times when operating at Vcc = 3 V,
00598    while the newer devices (e. g. ATmega128, ATmega8) only experience
00599    a negligible change.
00600 
00601    Possible timeout values are: 15 ms, 30 ms, 60 ms, 120 ms, 250 ms,
00602    500 ms, 1 s, 2 s.  (Some devices also allow for 4 s and 8 s.)
00603    Symbolic constants are formed by the prefix
00604    \c WDTO_, followed by the time.
00605 
00606    Example that would select a watchdog timer expiry of approximately
00607    500 ms:
00608    \code
00609    wdt_enable(WDTO_500MS);
00610    \endcode
00611 */
00612 #define WDTO_15MS   0
00613 
00614 /** \ingroup avr_watchdog
00615     See \c WDT0_15MS */
00616 #define WDTO_30MS   1
00617 
00618 /** \ingroup avr_watchdog See
00619     \c WDT0_15MS */
00620 #define WDTO_60MS   2
00621 
00622 /** \ingroup avr_watchdog
00623     See \c WDT0_15MS */
00624 #define WDTO_120MS  3
00625 
00626 /** \ingroup avr_watchdog
00627     See \c WDT0_15MS */
00628 #define WDTO_250MS  4
00629 
00630 /** \ingroup avr_watchdog
00631     See \c WDT0_15MS */
00632 #define WDTO_500MS  5
00633 
00634 /** \ingroup avr_watchdog
00635     See \c WDT0_15MS */
00636 #define WDTO_1S     6
00637 
00638 /** \ingroup avr_watchdog
00639     See \c WDT0_15MS */
00640 #define WDTO_2S     7
00641 
00642 #if defined(__DOXYGEN__) || defined(WDP3)
00643 
00644 /** \ingroup avr_watchdog
00645     See \c WDT0_15MS
00646     Note: This is only available on the 
00647     ATtiny2313, 
00648     ATtiny24, ATtiny44, ATtiny84, ATtiny84A,
00649     ATtiny25, ATtiny45, ATtiny85, 
00650     ATtiny261, ATtiny461, ATtiny861, 
00651     ATmega48, ATmega88, ATmega168,
00652     ATmega48P, ATmega88P, ATmega168P, ATmega328P,
00653     ATmega164P, ATmega324P, ATmega644P, ATmega644,
00654     ATmega640, ATmega1280, ATmega1281, ATmega2560, ATmega2561,
00655     ATmega8HVA, ATmega16HVA, ATmega32HVB,
00656     ATmega406, ATmega1284P,
00657     ATmega256RFR2, ATmega128RFR2, ATmega64RFR2,
00658     ATmega2564RFR2, ATmega1284RFR2, ATmega644RFR2,
00659     AT90PWM1, AT90PWM2, AT90PWM2B, AT90PWM3, AT90PWM3B, AT90PWM216, AT90PWM316,
00660     AT90PWM81, AT90PWM161,
00661     AT90USB82, AT90USB162,
00662     AT90USB646, AT90USB647, AT90USB1286, AT90USB1287,
00663     ATtiny48, ATtiny88.
00664     */
00665 #define WDTO_4S     8
00666 
00667 /** \ingroup avr_watchdog
00668     See \c WDT0_15MS
00669     Note: This is only available on the 
00670     ATtiny2313, 
00671     ATtiny24, ATtiny44, ATtiny84, ATtiny84A,
00672     ATtiny25, ATtiny45, ATtiny85, 
00673     ATtiny261, ATtiny461, ATtiny861, 
00674     ATmega48, ATmega48A, ATmega48PA, ATmega88, ATmega168,
00675     ATmega48P, ATmega88P, ATmega168P, ATmega328P,
00676     ATmega164P, ATmega324P, ATmega644P, ATmega644,
00677     ATmega640, ATmega1280, ATmega1281, ATmega2560, ATmega2561,
00678     ATmega8HVA, ATmega16HVA, ATmega32HVB,
00679     ATmega406, ATmega1284P,
00680     ATmega256RFR2, ATmega128RFR2, ATmega64RFR2,
00681     ATmega2564RFR2, ATmega1284RFR2, ATmega644RFR2,
00682     AT90PWM1, AT90PWM2, AT90PWM2B, AT90PWM3, AT90PWM3B, AT90PWM216, AT90PWM316,
00683     AT90PWM81, AT90PWM161,
00684     AT90USB82, AT90USB162,
00685     AT90USB646, AT90USB647, AT90USB1286, AT90USB1287,
00686     ATtiny48, ATtiny88,
00687     ATxmega16a4u, ATxmega32a4u,
00688     ATxmega16c4, ATxmega32c4,
00689     ATxmega128c3, ATxmega192c3, ATxmega256c3.
00690     */
00691 #define WDTO_8S     9
00692 
00693 #endif  /* defined(__DOXYGEN__) || defined(WDP3) */
00694    
00695 
00696 #endif /* _AVR_WDT_H_ */

Automatically generated by Doxygen 1.6.1 on 25 Apr 2014.