$treeview $search $mathjax $extrastylesheet
avr-libc
2.0.0
$projectbrief
|
$projectbrief
|
$searchbox |
AVR Libc Home Page |
AVR Libc Development Pages |
||||
Main Page |
User Manual |
Library Reference |
FAQ |
Example Projects |
00001 /* Copyright (c) 2002, 2004 Theodore A. Roth 00002 Copyright (c) 2004, 2007, 2008 Eric B. Weddington 00003 Copyright (c) 2005, 2006, 2007 Joerg Wunsch 00004 All rights reserved. 00005 00006 Redistribution and use in source and binary forms, with or without 00007 modification, are permitted provided that the following conditions are met: 00008 00009 * Redistributions of source code must retain the above copyright 00010 notice, this list of conditions and the following disclaimer. 00011 00012 * Redistributions in binary form must reproduce the above copyright 00013 notice, this list of conditions and the following disclaimer in 00014 the documentation and/or other materials provided with the 00015 distribution. 00016 00017 * Neither the name of the copyright holders nor the names of 00018 contributors may be used to endorse or promote products derived 00019 from this software without specific prior written permission. 00020 00021 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00022 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00023 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00024 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 00025 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 00026 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 00027 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00028 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 00029 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 00030 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00031 POSSIBILITY OF SUCH DAMAGE. */ 00032 00033 /* $Id$ */ 00034 00035 #ifndef _AVR_SLEEP_H_ 00036 #define _AVR_SLEEP_H_ 1 00037 00038 #include <avr/io.h> 00039 #include <stdint.h> 00040 00041 00042 /** \file */ 00043 00044 /** \defgroup avr_sleep <avr/sleep.h>: Power Management and Sleep Modes 00045 00046 \code #include <avr/sleep.h>\endcode 00047 00048 Use of the \c SLEEP instruction can allow an application to reduce its 00049 power comsumption considerably. AVR devices can be put into different 00050 sleep modes. Refer to the datasheet for the details relating to the device 00051 you are using. 00052 00053 There are several macros provided in this header file to actually 00054 put the device into sleep mode. The simplest way is to optionally 00055 set the desired sleep mode using \c set_sleep_mode() (it usually 00056 defaults to idle mode where the CPU is put on sleep but all 00057 peripheral clocks are still running), and then call 00058 \c sleep_mode(). This macro automatically sets the sleep enable bit, goes 00059 to sleep, and clears the sleep enable bit. 00060 00061 Example: 00062 \code 00063 #include <avr/sleep.h> 00064 00065 ... 00066 set_sleep_mode(<mode>); 00067 sleep_mode(); 00068 \endcode 00069 00070 Note that unless your purpose is to completely lock the CPU (until a 00071 hardware reset), interrupts need to be enabled before going to sleep. 00072 00073 As the \c sleep_mode() macro might cause race conditions in some 00074 situations, the individual steps of manipulating the sleep enable 00075 (SE) bit, and actually issuing the \c SLEEP instruction, are provided 00076 in the macros \c sleep_enable(), \c sleep_disable(), and 00077 \c sleep_cpu(). This also allows for test-and-sleep scenarios that 00078 take care of not missing the interrupt that will awake the device 00079 from sleep. 00080 00081 Example: 00082 \code 00083 #include <avr/interrupt.h> 00084 #include <avr/sleep.h> 00085 00086 ... 00087 set_sleep_mode(<mode>); 00088 cli(); 00089 if (some_condition) 00090 { 00091 sleep_enable(); 00092 sei(); 00093 sleep_cpu(); 00094 sleep_disable(); 00095 } 00096 sei(); 00097 \endcode 00098 00099 This sequence ensures an atomic test of \c some_condition with 00100 interrupts being disabled. If the condition is met, sleep mode 00101 will be prepared, and the \c SLEEP instruction will be scheduled 00102 immediately after an \c SEI instruction. As the intruction right 00103 after the \c SEI is guaranteed to be executed before an interrupt 00104 could trigger, it is sure the device will really be put to sleep. 00105 00106 Some devices have the ability to disable the Brown Out Detector (BOD) before 00107 going to sleep. This will also reduce power while sleeping. If the 00108 specific AVR device has this ability then an additional macro is defined: 00109 \c sleep_bod_disable(). This macro generates inlined assembly code 00110 that will correctly implement the timed sequence for disabling the BOD 00111 before sleeping. However, there is a limited number of cycles after the 00112 BOD has been disabled that the device can be put into sleep mode, otherwise 00113 the BOD will not truly be disabled. Recommended practice is to disable 00114 the BOD (\c sleep_bod_disable()), set the interrupts (\c sei()), and then 00115 put the device to sleep (\c sleep_cpu()), like so: 00116 00117 \code 00118 #include <avr/interrupt.h> 00119 #include <avr/sleep.h> 00120 00121 ... 00122 set_sleep_mode(<mode>); 00123 cli(); 00124 if (some_condition) 00125 { 00126 sleep_enable(); 00127 sleep_bod_disable(); 00128 sei(); 00129 sleep_cpu(); 00130 sleep_disable(); 00131 } 00132 sei(); 00133 \endcode 00134 */ 00135 00136 00137 /* Define an internal sleep control register and an internal sleep enable bit mask. */ 00138 #if defined(SLEEP_CTRL) 00139 00140 /* XMEGA devices */ 00141 #define _SLEEP_CONTROL_REG SLEEP_CTRL 00142 #define _SLEEP_ENABLE_MASK SLEEP_SEN_bm 00143 #define _SLEEP_SMODE_GROUP_MASK SLEEP_SMODE_gm 00144 00145 #elif defined(SLPCTRL) 00146 00147 /* New xmega devices */ 00148 #define _SLEEP_CONTROL_REG SLPCTRL_CTRLA 00149 #define _SLEEP_ENABLE_MASK SLPCTRL_SEN_bm 00150 #define _SLEEP_SMODE_GROUP_MASK SLPCTRL_SMODE_gm 00151 00152 #elif defined(SMCR) 00153 00154 #define _SLEEP_CONTROL_REG SMCR 00155 #define _SLEEP_ENABLE_MASK _BV(SE) 00156 00157 #elif defined(__AVR_AT94K__) 00158 00159 #define _SLEEP_CONTROL_REG MCUR 00160 #define _SLEEP_ENABLE_MASK _BV(SE) 00161 00162 #elif !defined(__DOXYGEN__) 00163 00164 #define _SLEEP_CONTROL_REG MCUCR 00165 #define _SLEEP_ENABLE_MASK _BV(SE) 00166 00167 #endif 00168 00169 00170 /* Special casing these three devices - they are the 00171 only ones that need to write to more than one register. */ 00172 #if defined(__AVR_ATmega161__) 00173 00174 #define set_sleep_mode(mode) \ 00175 do { \ 00176 MCUCR = ((MCUCR & ~_BV(SM1)) | ((mode) == SLEEP_MODE_PWR_DOWN || (mode) == SLEEP_MODE_PWR_SAVE ? _BV(SM1) : 0)); \ 00177 EMCUCR = ((EMCUCR & ~_BV(SM0)) | ((mode) == SLEEP_MODE_PWR_SAVE ? _BV(SM0) : 0)); \ 00178 } while(0) 00179 00180 00181 #elif defined(__AVR_ATmega162__) \ 00182 || defined(__AVR_ATmega8515__) 00183 00184 #define set_sleep_mode(mode) \ 00185 do { \ 00186 MCUCR = ((MCUCR & ~_BV(SM1)) | ((mode) == SLEEP_MODE_IDLE ? 0 : _BV(SM1))); \ 00187 MCUCSR = ((MCUCSR & ~_BV(SM2)) | ((mode) == SLEEP_MODE_STANDBY || (mode) == SLEEP_MODE_EXT_STANDBY ? _BV(SM2) : 0)); \ 00188 EMCUCR = ((EMCUCR & ~_BV(SM0)) | ((mode) == SLEEP_MODE_PWR_SAVE || (mode) == SLEEP_MODE_EXT_STANDBY ? _BV(SM0) : 0)); \ 00189 } while(0) 00190 00191 /* For xmegas, check presence of SLEEP_SMODE<n>_bm and define set_sleep_mode accordingly. */ 00192 #elif defined(__AVR_XMEGA__) 00193 00194 #define set_sleep_mode(mode) \ 00195 do { \ 00196 _SLEEP_CONTROL_REG = ((_SLEEP_CONTROL_REG & ~(_SLEEP_SMODE_GROUP_MASK)) | (mode)); \ 00197 } while(0) 00198 00199 /* For everything else, check for presence of SM<n> and define set_sleep_mode accordingly. */ 00200 #else 00201 #if defined(SM2) 00202 00203 #define set_sleep_mode(mode) \ 00204 do { \ 00205 _SLEEP_CONTROL_REG = ((_SLEEP_CONTROL_REG & ~(_BV(SM0) | _BV(SM1) | _BV(SM2))) | (mode)); \ 00206 } while(0) 00207 00208 #elif defined(SM1) 00209 00210 #define set_sleep_mode(mode) \ 00211 do { \ 00212 _SLEEP_CONTROL_REG = ((_SLEEP_CONTROL_REG & ~(_BV(SM0) | _BV(SM1))) | (mode)); \ 00213 } while(0) 00214 00215 #elif defined(SM) 00216 00217 #define set_sleep_mode(mode) \ 00218 do { \ 00219 _SLEEP_CONTROL_REG = ((_SLEEP_CONTROL_REG & ~_BV(SM)) | (mode)); \ 00220 } while(0) 00221 00222 #else 00223 00224 #error "No SLEEP mode defined for this device." 00225 00226 #endif /* if defined(SM2) */ 00227 #endif /* #if defined(__AVR_ATmega161__) */ 00228 00229 00230 00231 /** \ingroup avr_sleep 00232 00233 Put the device in sleep mode. How the device is brought out of sleep mode 00234 depends on the specific mode selected with the set_sleep_mode() function. 00235 See the data sheet for your device for more details. */ 00236 00237 00238 #if defined(__DOXYGEN__) 00239 00240 /** \ingroup avr_sleep 00241 00242 Set the SE (sleep enable) bit. 00243 */ 00244 extern void sleep_enable (void); 00245 00246 #else 00247 00248 #define sleep_enable() \ 00249 do { \ 00250 _SLEEP_CONTROL_REG |= (uint8_t)_SLEEP_ENABLE_MASK; \ 00251 } while(0) 00252 00253 #endif 00254 00255 00256 #if defined(__DOXYGEN__) 00257 00258 /** \ingroup avr_sleep 00259 00260 Clear the SE (sleep enable) bit. 00261 */ 00262 extern void sleep_disable (void); 00263 00264 #else 00265 00266 #define sleep_disable() \ 00267 do { \ 00268 _SLEEP_CONTROL_REG &= (uint8_t)(~_SLEEP_ENABLE_MASK); \ 00269 } while(0) 00270 00271 #endif 00272 00273 00274 /** \ingroup avr_sleep 00275 00276 Put the device into sleep mode. The SE bit must be set 00277 beforehand, and it is recommended to clear it afterwards. 00278 */ 00279 #if defined(__DOXYGEN__) 00280 00281 extern void sleep_cpu (void); 00282 00283 #else 00284 00285 #define sleep_cpu() \ 00286 do { \ 00287 __asm__ __volatile__ ( "sleep" "\n\t" :: ); \ 00288 } while(0) 00289 00290 #endif 00291 00292 00293 #if defined(__DOXYGEN__) 00294 00295 /** \ingroup avr_sleep 00296 00297 Put the device into sleep mode, taking care of setting 00298 the SE bit before, and clearing it afterwards. */ 00299 extern void sleep_mode (void); 00300 00301 #else 00302 00303 #define sleep_mode() \ 00304 do { \ 00305 sleep_enable(); \ 00306 sleep_cpu(); \ 00307 sleep_disable(); \ 00308 } while (0) 00309 00310 #endif 00311 00312 00313 #if defined(__DOXYGEN__) 00314 00315 /** \ingroup avr_sleep 00316 00317 Disable BOD before going to sleep. 00318 Not available on all devices. 00319 */ 00320 extern void sleep_bod_disable (void); 00321 00322 #else 00323 00324 #if defined(BODS) && defined(BODSE) 00325 00326 #ifdef BODCR 00327 00328 #define BOD_CONTROL_REG BODCR 00329 00330 #else 00331 00332 #define BOD_CONTROL_REG MCUCR 00333 00334 #endif 00335 00336 #define sleep_bod_disable() \ 00337 do { \ 00338 uint8_t tempreg; \ 00339 __asm__ __volatile__("in %[tempreg], %[mcucr]" "\n\t" \ 00340 "ori %[tempreg], %[bods_bodse]" "\n\t" \ 00341 "out %[mcucr], %[tempreg]" "\n\t" \ 00342 "andi %[tempreg], %[not_bodse]" "\n\t" \ 00343 "out %[mcucr], %[tempreg]" \ 00344 : [tempreg] "=&d" (tempreg) \ 00345 : [mcucr] "I" _SFR_IO_ADDR(BOD_CONTROL_REG), \ 00346 [bods_bodse] "i" (_BV(BODS) | _BV(BODSE)), \ 00347 [not_bodse] "i" (~_BV(BODSE))); \ 00348 } while (0) 00349 00350 #endif 00351 00352 #endif 00353 00354 00355 /*@}*/ 00356 00357 #endif /* _AVR_SLEEP_H_ */