summaryrefslogtreecommitdiffstats
path: root/cpukit/score/cpu/avr/avr/sleep.h
diff options
context:
space:
mode:
Diffstat (limited to 'cpukit/score/cpu/avr/avr/sleep.h')
-rw-r--r--cpukit/score/cpu/avr/avr/sleep.h588
1 files changed, 588 insertions, 0 deletions
diff --git a/cpukit/score/cpu/avr/avr/sleep.h b/cpukit/score/cpu/avr/avr/sleep.h
new file mode 100644
index 0000000000..718e671512
--- /dev/null
+++ b/cpukit/score/cpu/avr/avr/sleep.h
@@ -0,0 +1,588 @@
+/* Copyright (c) 2002, 2004 Theodore A. Roth
+ Copyright (c) 2004, 2007, 2008 Eric B. Weddington
+ Copyright (c) 2005, 2006, 2007 Joerg Wunsch
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+
+ * Neither the name of the copyright holders nor the names of
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE. */
+
+/* $Id$ */
+
+#ifndef _AVR_SLEEP_H_
+#define _AVR_SLEEP_H_ 1
+
+#include <avr/io.h>
+#include <stdint.h>
+
+
+/** \file */
+
+/** \defgroup avr_sleep <avr/sleep.h>: Power Management and Sleep Modes
+
+ \code #include <avr/sleep.h>\endcode
+
+ Use of the \c SLEEP instruction can allow an application to reduce its
+ power comsumption considerably. AVR devices can be put into different
+ sleep modes. Refer to the datasheet for the details relating to the device
+ you are using.
+
+ There are several macros provided in this header file to actually
+ put the device into sleep mode. The simplest way is to optionally
+ set the desired sleep mode using \c set_sleep_mode() (it usually
+ defaults to idle mode where the CPU is put on sleep but all
+ peripheral clocks are still running), and then call
+ \c sleep_mode(). This macro automatically sets the sleep enable bit, goes
+ to sleep, and clears the sleep enable bit.
+
+ Example:
+ \code
+ #include <avr/sleep.h>
+
+ ...
+ set_sleep_mode(<mode>);
+ sleep_mode();
+ \endcode
+
+ Note that unless your purpose is to completely lock the CPU (until a
+ hardware reset), interrupts need to be enabled before going to sleep.
+
+ As the \c sleep_mode() macro might cause race conditions in some
+ situations, the individual steps of manipulating the sleep enable
+ (SE) bit, and actually issuing the \c SLEEP instruction, are provided
+ in the macros \c sleep_enable(), \c sleep_disable(), and
+ \c sleep_cpu(). This also allows for test-and-sleep scenarios that
+ take care of not missing the interrupt that will awake the device
+ from sleep.
+
+ Example:
+ \code
+ #include <avr/interrupt.h>
+ #include <avr/sleep.h>
+
+ ...
+ set_sleep_mode(<mode>);
+ cli();
+ if (some_condition)
+ {
+ sleep_enable();
+ sei();
+ sleep_cpu();
+ sleep_disable();
+ }
+ sei();
+ \endcode
+
+ This sequence ensures an atomic test of \c some_condition with
+ interrupts being disabled. If the condition is met, sleep mode
+ will be prepared, and the \c SLEEP instruction will be scheduled
+ immediately after an \c SEI instruction. As the intruction right
+ after the \c SEI is guaranteed to be executed before an interrupt
+ could trigger, it is sure the device will really be put to sleep.
+
+ Some devices have the ability to disable the Brown Out Detector (BOD) before
+ going to sleep. This will also reduce power while sleeping. If the
+ specific AVR device has this ability then an additional macro is defined:
+ \c sleep_bod_disable(). This macro generates inlined assembly code
+ that will correctly implement the timed sequence for disabling the BOD
+ before sleeping. However, there is a limited number of cycles after the
+ BOD has been disabled that the device can be put into sleep mode, otherwise
+ the BOD will not truly be disabled. Recommended practice is to disable
+ the BOD (\c sleep_bod_disable()), set the interrupts (\c sei()), and then
+ put the device to sleep (\c sleep_cpu()), like so:
+
+ \code
+ #include <avr/interrupt.h>
+ #include <avr/sleep.h>
+
+ ...
+ set_sleep_mode(<mode>);
+ cli();
+ if (some_condition)
+ {
+ sleep_enable();
+ sleep_bod_disable();
+ sei();
+ sleep_cpu();
+ sleep_disable();
+ }
+ sei();
+ \endcode
+*/
+
+
+/* Define an internal sleep control register and an internal sleep enable bit mask. */
+#if defined(SLEEP_CTRL)
+
+ /* XMEGA devices */
+ #define _SLEEP_CONTROL_REG SLEEP_CTRL
+ #define _SLEEP_ENABLE_MASK SLEEP_SEN_bm
+
+#elif defined(SMCR)
+
+ #define _SLEEP_CONTROL_REG SMCR
+ #define _SLEEP_ENABLE_MASK _BV(SE)
+
+#elif defined(__AVR_AT94K__)
+
+ #define _SLEEP_CONTROL_REG MCUR
+ #define _SLEEP_ENABLE_MASK _BV(SE)
+
+#else
+
+ #define _SLEEP_CONTROL_REG MCUCR
+ #define _SLEEP_ENABLE_MASK _BV(SE)
+
+#endif
+
+
+/* Define set_sleep_mode() and sleep mode values per device. */
+#if defined(__AVR_ATmega161__)
+
+ #define SLEEP_MODE_IDLE 0
+ #define SLEEP_MODE_PWR_DOWN 1
+ #define SLEEP_MODE_PWR_SAVE 2
+
+ #define set_sleep_mode(mode) \
+ do { \
+ MCUCR = ((MCUCR & ~_BV(SM1)) | ((mode) == SLEEP_MODE_PWR_DOWN || (mode) == SLEEP_MODE_PWR_SAVE ? _BV(SM1) : 0)); \
+ EMCUCR = ((EMCUCR & ~_BV(SM0)) | ((mode) == SLEEP_MODE_PWR_SAVE ? _BV(SM0) : 0)); \
+ } while(0)
+
+
+#elif defined(__AVR_ATmega162__) \
+|| defined(__AVR_ATmega8515__)
+
+ #define SLEEP_MODE_IDLE 0
+ #define SLEEP_MODE_PWR_DOWN 1
+ #define SLEEP_MODE_PWR_SAVE 2
+ #define SLEEP_MODE_ADC 3
+ #define SLEEP_MODE_STANDBY 4
+ #define SLEEP_MODE_EXT_STANDBY 5
+
+ #define set_sleep_mode(mode) \
+ do { \
+ MCUCR = ((MCUCR & ~_BV(SM1)) | ((mode) == SLEEP_MODE_IDLE ? 0 : _BV(SM1))); \
+ MCUCSR = ((MCUCSR & ~_BV(SM2)) | ((mode) == SLEEP_MODE_STANDBY || (mode) == SLEEP_MODE_EXT_STANDBY ? _BV(SM2) : 0)); \
+ EMCUCR = ((EMCUCR & ~_BV(SM0)) | ((mode) == SLEEP_MODE_PWR_SAVE || (mode) == SLEEP_MODE_EXT_STANDBY ? _BV(SM0) : 0)); \
+ } while(0)
+
+#elif defined(__AVR_AT90S2313__) \
+|| defined(__AVR_AT90S2323__) \
+|| defined(__AVR_AT90S2333__) \
+|| defined(__AVR_AT90S2343__) \
+|| defined(__AVR_AT43USB320__) \
+|| defined(__AVR_AT43USB355__) \
+|| defined(__AVR_AT90S4414__) \
+|| defined(__AVR_AT90S4433__) \
+|| defined(__AVR_AT90S8515__) \
+|| defined(__AVR_ATtiny22__)
+
+ #define SLEEP_MODE_IDLE 0
+ #define SLEEP_MODE_PWR_DOWN _BV(SM)
+
+ #define set_sleep_mode(mode) \
+ do { \
+ _SLEEP_CONTROL_REG = ((_SLEEP_CONTROL_REG & ~__BV(SM)) | (mode)); \
+ } while(0)
+
+#elif defined(__AVR_ATtiny167__) \
+|| defined(__AVR_ATtiny87__)
+
+ #define SLEEP_MODE_IDLE 0
+ #define SLEEP_MODE_ADC _BV(SM0)
+ #define SLEEP_MODE_PWR_DOWN _BV(SM1)
+
+ #define set_sleep_mode(mode) \
+ do { \
+ _SLEEP_CONTROL_REG = ((_SLEEP_CONTROL_REG & ~(_BV(SM0) | _BV(SM1))) | (mode)); \
+ } while(0)
+
+#elif defined(__AVR_AT90S4434__) \
+|| defined(__AVR_AT76C711__) \
+|| defined(__AVR_AT90S8535__) \
+|| defined(__AVR_ATmega103__) \
+|| defined(__AVR_ATmega161__) \
+|| defined(__AVR_ATmega163__) \
+|| defined(__AVR_ATtiny13__) \
+|| defined(__AVR_ATtiny13A__) \
+|| defined(__AVR_ATtiny15__) \
+|| defined(__AVR_ATtiny24__) \
+|| defined(__AVR_ATtiny24A__) \
+|| defined(__AVR_ATtiny44__) \
+|| defined(__AVR_ATtiny44A__) \
+|| defined(__AVR_ATtiny84__) \
+|| defined(__AVR_ATtiny25__) \
+|| defined(__AVR_ATtiny45__) \
+|| defined(__AVR_ATtiny48__) \
+|| defined(__AVR_ATtiny85__) \
+|| defined(__AVR_ATtiny261__) \
+|| defined(__AVR_ATtiny261A__) \
+|| defined(__AVR_ATtiny461__) \
+|| defined(__AVR_ATtiny461A__) \
+|| defined(__AVR_ATtiny861__) \
+|| defined(__AVR_ATtiny861A__) \
+|| defined(__AVR_ATtiny88__)
+
+ #define SLEEP_MODE_IDLE 0
+ #define SLEEP_MODE_ADC _BV(SM0)
+ #define SLEEP_MODE_PWR_DOWN _BV(SM1)
+ #define SLEEP_MODE_PWR_SAVE (_BV(SM0) | _BV(SM1))
+
+ #define set_sleep_mode(mode) \
+ do { \
+ _SLEEP_CONTROL_REG = ((_SLEEP_CONTROL_REG & ~(_BV(SM0) | _BV(SM1))) | (mode)); \
+ } while(0)
+
+#elif defined(__AVR_ATtiny2313__) \
+|| defined(__AVR_ATtiny2313A__) \
+|| defined(__AVR_ATtiny4313__)
+
+ #define SLEEP_MODE_IDLE 0
+ #define SLEEP_MODE_PWR_DOWN (_BV(SM0) | _BV(SM1))
+ #define SLEEP_MODE_STANDBY _BV(SM1)
+
+ #define set_sleep_mode(mode) \
+ do { \
+ _SLEEP_CONTROL_REG = ((_SLEEP_CONTROL_REG & ~(_BV(SM0) | _BV(SM1))) | (mode)); \
+ } while(0)
+
+#elif defined(__AVR_AT94K__)
+
+ #define SLEEP_MODE_IDLE 0
+ #define SLEEP_MODE_PWR_DOWN _BV(SM1)
+ #define SLEEP_MODE_PWR_SAVE (_BV(SM0) | _BV(SM1))
+
+ #define set_sleep_mode(mode) \
+ do { \
+ _SLEEP_CONTROL_REG = ((_SLEEP_CONTROL_REG & ~(_BV(SM0) | _BV(SM1))) | (mode)); \
+ } while(0)
+
+#elif defined(__AVR_ATtiny26__) \
+|| defined(__AVR_ATtiny43U__)
+
+ #define SLEEP_MODE_IDLE 0
+ #define SLEEP_MODE_ADC _BV(SM0)
+ #define SLEEP_MODE_PWR_DOWN _BV(SM1)
+ #define SLEEP_MODE_STANDBY (_BV(SM0) | _BV(SM1))
+
+ #define set_sleep_mode(mode) \
+ do { \
+ _SLEEP_CONTROL_REG = ((_SLEEP_CONTROL_REG & ~(_BV(SM0) | _BV(SM1))) | (mode)); \
+ } while(0)
+
+#elif defined(__AVR_AT90PWM216__) \
+|| defined(__AVR_AT90PWM316__) \
+|| defined(__AVR_AT90PWM81__)
+
+ #define SLEEP_MODE_IDLE 0
+ #define SLEEP_MODE_ADC _BV(SM0)
+ #define SLEEP_MODE_PWR_DOWN _BV(SM1)
+ #define SLEEP_MODE_STANDBY (_BV(SM1) | _BV(SM2))
+
+ #define set_sleep_mode(mode) \
+ do { \
+ _SLEEP_CONTROL_REG = ((_SLEEP_CONTROL_REG & ~(_BV(SM0) | _BV(SM1) | _BV(SM2))) | (mode)); \
+ } while(0)
+
+#elif defined(__AVR_AT90CAN128__) \
+|| defined(__AVR_AT90CAN32__) \
+|| defined(__AVR_AT90CAN64__) \
+|| defined(__AVR_AT90PWM1__) \
+|| defined(__AVR_AT90PWM2__) \
+|| defined(__AVR_AT90PWM2B__) \
+|| defined(__AVR_AT90PWM3__) \
+|| defined(__AVR_AT90PWM3B__) \
+|| defined(__AVR_AT90USB162__) \
+|| defined(__AVR_AT90USB82__) \
+|| defined(__AVR_AT90USB1286__) \
+|| defined(__AVR_AT90USB1287__) \
+|| defined(__AVR_AT90USB646__) \
+|| defined(__AVR_AT90USB647__) \
+|| defined(__AVR_ATmega128__) \
+|| defined(__AVR_ATmega1280__) \
+|| defined(__AVR_ATmega1281__) \
+|| defined(__AVR_ATmega1284P__) \
+|| defined(__AVR_ATmega128RFA1__) \
+|| defined(__AVR_ATmega16__) \
+|| defined(__AVR_ATmega16A__) \
+|| defined(__AVR_ATmega162__) \
+|| defined(__AVR_ATmega164A__) \
+|| defined(__AVR_ATmega164P__) \
+|| defined(__AVR_ATmega165__) \
+|| defined(__AVR_ATmega165A__) \
+|| defined(__AVR_ATmega165P__) \
+|| defined(__AVR_ATmega168__) \
+|| defined(__AVR_ATmega168A__) \
+|| defined(__AVR_ATmega168P__) \
+|| defined(__AVR_ATmega169__) \
+|| defined(__AVR_ATmega169A__) \
+|| defined(__AVR_ATmega169P__) \
+|| defined(__AVR_ATmega169PA__) \
+|| defined(__AVR_ATmega16HVA__) \
+|| defined(__AVR_ATmega16HVA2__) \
+|| defined(__AVR_ATmega16HVB__) \
+|| defined(__AVR_ATmega16M1__) \
+|| defined(__AVR_ATmega16U2__) \
+|| defined(__AVR_ATmega16U4__) \
+|| defined(__AVR_ATmega2560__) \
+|| defined(__AVR_ATmega2561__) \
+|| defined(__AVR_ATmega32__) \
+|| defined(__AVR_ATmega323__) \
+|| defined(__AVR_ATmega324A__) \
+|| defined(__AVR_ATmega324P__) \
+|| defined(__AVR_ATmega324PA__) \
+|| defined(__AVR_ATmega325__) \
+|| defined(__AVR_ATmega3250__) \
+|| defined(__AVR_ATmega328__) \
+|| defined(__AVR_ATmega328P__) \
+|| defined(__AVR_ATmega329__) \
+|| defined(__AVR_ATmega329P__) \
+|| defined(__AVR_ATmega329PA__) \
+|| defined(__AVR_ATmega3290__) \
+|| defined(__AVR_ATmega3290P__) \
+|| defined(__AVR_ATmega32C1__) \
+|| defined(__AVR_ATmega32HVB__) \
+|| defined(__AVR_ATmega32M1__) \
+|| defined(__AVR_ATmega32U2__) \
+|| defined(__AVR_ATmega32U4__) \
+|| defined(__AVR_ATmega32U6__) \
+|| defined(__AVR_ATmega406__) \
+|| defined(__AVR_ATmega48__) \
+|| defined(__AVR_ATmega48A__) \
+|| defined(__AVR_ATmega48P__) \
+|| defined(__AVR_ATmega64__) \
+|| defined(__AVR_ATmega640__) \
+|| defined(__AVR_ATmega644__) \
+|| defined(__AVR_ATmega644A__) \
+|| defined(__AVR_ATmega644P__) \
+|| defined(__AVR_ATmega644PA__) \
+|| defined(__AVR_ATmega645__) \
+|| defined(__AVR_ATmega645A__) \
+|| defined(__AVR_ATmega645P__) \
+|| defined(__AVR_ATmega6450__) \
+|| defined(__AVR_ATmega6450A__) \
+|| defined(__AVR_ATmega6450P__) \
+|| defined(__AVR_ATmega649__) \
+|| defined(__AVR_ATmega649A__) \
+|| defined(__AVR_ATmega6490__) \
+|| defined(__AVR_ATmega6490A__) \
+|| defined(__AVR_ATmega6490P__) \
+|| defined(__AVR_ATmega649P__) \
+|| defined(__AVR_ATmega64C1__) \
+|| defined(__AVR_ATmega64HVE__) \
+|| defined(__AVR_ATmega64M1__) \
+|| defined(__AVR_ATmega8__) \
+|| defined(__AVR_ATmega8515__) \
+|| defined(__AVR_ATmega8535__) \
+|| defined(__AVR_ATmega88__) \
+|| defined(__AVR_ATmega88A__) \
+|| defined(__AVR_ATmega88P__) \
+|| defined(__AVR_ATmega88PA__) \
+|| defined(__AVR_ATmega8HVA__) \
+|| defined(__AVR_ATmega8U2__)
+
+
+ #define SLEEP_MODE_IDLE (0)
+ #define SLEEP_MODE_ADC _BV(SM0)
+ #define SLEEP_MODE_PWR_DOWN _BV(SM1)
+ #define SLEEP_MODE_PWR_SAVE (_BV(SM0) | _BV(SM1))
+ #define SLEEP_MODE_STANDBY (_BV(SM1) | _BV(SM2))
+ #define SLEEP_MODE_EXT_STANDBY (_BV(SM0) | _BV(SM1) | _BV(SM2))
+
+
+ #define set_sleep_mode(mode) \
+ do { \
+ _SLEEP_CONTROL_REG = ((_SLEEP_CONTROL_REG & ~(_BV(SM0) | _BV(SM1) | _BV(SM2))) | (mode)); \
+ } while(0)
+
+#elif defined(__AVR_ATxmega16A4__) \
+|| defined(__AVR_ATxmega16D4__) \
+|| defined(__AVR_ATxmega32A4__) \
+|| defined(__AVR_ATxmega32D4__) \
+|| defined(__AVR_ATxmega64A1__) \
+|| defined(__AVR_ATxmega64A3__) \
+|| defined(__AVR_ATxmega64D3__) \
+|| defined(__AVR_ATxmega128A1__) \
+|| defined(__AVR_ATxmega128A3__) \
+|| defined(__AVR_ATxmega128D3__) \
+|| defined(__AVR_ATxmega192A3__) \
+|| defined(__AVR_ATxmega192D3__) \
+|| defined(__AVR_ATxmega256A3__) \
+|| defined(__AVR_ATxmega256D3__) \
+|| defined(__AVR_ATxmega256A3B__)
+
+ #define SLEEP_MODE_IDLE (0)
+ #define SLEEP_MODE_PWR_DOWN (SLEEP_SMODE1_bm)
+ #define SLEEP_MODE_PWR_SAVE (SLEEP_SMODE1_bm | SLEEP_SMODE0_bm)
+ #define SLEEP_MODE_STANDBY (SLEEP_SMODE2_bm | SLEEP_SMODE1_bm)
+ #define SLEEP_MODE_EXT_STANDBY (SLEEP_SMODE2_bm | SLEEP_SMODE1_bm | SLEEP_SMODE0_bm)
+
+ #define set_sleep_mode(mode) \
+ do { \
+ _SLEEP_CONTROL_REG = ((_SLEEP_CONTROL_REG & ~(SLEEP_SMODE2_bm | SLEEP_SMODE1_bm | SLEEP_SMODE0_bm)) | (mode)); \
+ } while(0)
+
+#elif defined(__AVR_AT90SCR100__)
+
+ #define SLEEP_MODE_IDLE (0)
+ #define SLEEP_MODE_PWR_DOWN _BV(SM1)
+ #define SLEEP_MODE_PWR_SAVE (_BV(SM0) | _BV(SM1))
+ #define SLEEP_MODE_STANDBY (_BV(SM1) | _BV(SM2))
+ #define SLEEP_MODE_EXT_STANDBY (_BV(SM0) | _BV(SM1) | _BV(SM2))
+
+ #define set_sleep_mode(mode) \
+ do { \
+ _SLEEP_CONTROL_REG = ((_SLEEP_CONTROL_REG & ~(_BV(SM0) | _BV(SM1) | _BV(SM2))) | (mode)); \
+ } while(0)
+
+#elif defined(__AVR_ATA6289__)
+
+ #define SLEEP_MODE_IDLE (0)
+ #define SLEEP_MODE_SENSOR_NOISE_REDUCTION (_BV(SM0))
+ #define SLEEP_MODE_PWR_DOWN (_BV(SM1))
+
+ #define set_sleep_mode(mode) \
+ do { \
+ _SLEEP_CONTROL_REG = ((_SLEEP_CONTROL_REG & ~(_BV(SM0) | _BV(SM1) | _BV(SM2))) | (mode)); \
+ } while(0)
+
+#else
+
+ #error "No SLEEP mode defined for this device."
+
+#endif
+
+
+
+/** \ingroup avr_sleep
+
+ Put the device in sleep mode. How the device is brought out of sleep mode
+ depends on the specific mode selected with the set_sleep_mode() function.
+ See the data sheet for your device for more details. */
+
+
+#if defined(__DOXYGEN__)
+
+/** \ingroup avr_sleep
+
+ Set the SE (sleep enable) bit.
+*/
+extern void sleep_enable (void);
+
+#else
+
+#define sleep_enable() \
+do { \
+ _SLEEP_CONTROL_REG |= (uint8_t)_SLEEP_ENABLE_MASK; \
+} while(0)
+
+#endif
+
+
+#if defined(__DOXYGEN__)
+
+/** \ingroup avr_sleep
+
+ Clear the SE (sleep enable) bit.
+*/
+extern void sleep_disable (void);
+
+#else
+
+#define sleep_disable() \
+do { \
+ _SLEEP_CONTROL_REG &= (uint8_t)(~_SLEEP_ENABLE_MASK); \
+} while(0)
+
+#endif
+
+
+/** \ingroup avr_sleep
+
+ Put the device into sleep mode. The SE bit must be set
+ beforehand, and it is recommended to clear it afterwards.
+*/
+#if defined(__DOXYGEN__)
+
+extern void sleep_cpu (void);
+
+#else
+
+#define sleep_cpu() \
+do { \
+ __asm__ __volatile__ ( "sleep" "\n\t" :: ); \
+} while(0)
+
+#endif
+
+
+#if defined(__DOXYGEN__)
+
+extern void sleep_mode (void);
+
+#else
+
+#define sleep_mode() \
+do { \
+ sleep_enable(); \
+ sleep_cpu(); \
+ sleep_disable(); \
+} while (0)
+
+#endif
+
+
+#if defined(__DOXYGEN__)
+
+extern void sleep_bod_disable (void);
+
+#else
+
+#if defined(BODS) && defined(BODSE)
+
+#define sleep_bod_disable() \
+do { \
+ uint8_t tempreg; \
+ __asm__ __volatile__("in %[tempreg], %[mcucr]" "\n\t" \
+ "ori %[tempreg], %[bods_bodse]" "\n\t" \
+ "out %[mcucr], %[tempreg]" "\n\t" \
+ "andi %[tempreg], %[not_bodse]" "\n\t" \
+ "out %[mcucr], %[tempreg]" \
+ : [tempreg] "=&d" (tempreg) \
+ : [mcucr] "I" _SFR_IO_ADDR(MCUCR), \
+ [bods_bodse] "i" (_BV(BODS) | _BV(BODSE)), \
+ [not_bodse] "i" (~_BV(BODSE))); \
+} while (0)
+
+#endif
+
+#endif
+
+
+/*@}*/
+
+#endif /* _AVR_SLEEP_H_ */