AVR Libc Home Page AVRs AVR Libc Development Pages
Main Page User Manual Reference FAQ Example Projects

sleep.h

Go to the documentation of this file.
01	1 Copyright (c) 2002, 2004 Theodore A. Roth
022Copyright (c) 2004, 2007, 2008 Eric B. Weddington 033Copyright (c) 2005, 2006, 2007 Joerg Wunsch 044All rights reserved. 055 066Redistribution and use in source and binary forms, with or without 077modification, are permitted provided that the following conditions are met: 088 099* Redistributions of source code must retain the above copyright 1010notice, this list of conditions and the following disclaimer. 1111 1212* Redistributions in binary form must reproduce the above copyright 1313notice, this list of conditions and the following disclaimer in 1414the documentation and/or other materials provided with the 1515distribution. 1616 1717* Neither the name of the copyright holders nor the names of 1818contributors may be used to endorse or promote products derived 1919from this software without specific prior written permission. 2020 2121THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 2222AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2323IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2424ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 2525LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 2626CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 2727SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 2828INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 2929CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 3030ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 3131POSSIBILITY OF SUCH DAMAGE. */ 3232 3333/* $Id: sleep.h 2503 2016-02-07 22:59:47Z joerg_wunsch $ */ 3434 3535#ifndef _AVR_SLEEP_H_ 3636#define _AVR_SLEEP_H_ 1 3737 3838#include <avr/io.h> 3939#include <stdint.h> 4040 4141 4242/** \file */ 4343 4444/** \defgroup avr_sleep <avr/sleep.h>: Power Management and Sleep Modes 4545 4646\code #include <avr/sleep.h>\endcode 4747 4848Use of the \c SLEEP instruction can allow an application to reduce its 4949power comsumption considerably. AVR devices can be put into different 5050sleep modes. Refer to the datasheet for the details relating to the device 5151you are using. 5252 5353There are several macros provided in this header file to actually 5454put the device into sleep mode. The simplest way is to optionally 5555set the desired sleep mode using \c set_sleep_mode() (it usually 5656defaults to idle mode where the CPU is put on sleep but all 5757peripheral clocks are still running), and then call 5858\c sleep_mode(). This macro automatically sets the sleep enable bit, goes 5959to sleep, and clears the sleep enable bit. 60606161Example: 6262\code 6363#include <avr/sleep.h> 6464 6565... 6666set_sleep_mode(<mode>); 6767sleep_mode(); 6868\endcode 69697070Note that unless your purpose is to completely lock the CPU (until a 7171hardware reset), interrupts need to be enabled before going to sleep. 7272 7373As the \c sleep_mode() macro might cause race conditions in some 7474situations, the individual steps of manipulating the sleep enable 7575(SE) bit, and actually issuing the \c SLEEP instruction, are provided 7676in the macros \c sleep_enable(), \c sleep_disable(), and 7777\c sleep_cpu(). This also allows for test-and-sleep scenarios that 7878take care of not missing the interrupt that will awake the device 7979from sleep. 8080 8181Example: 8282\code 8383#include <avr/interrupt.h> 8484#include <avr/sleep.h> 8585 8686... 8787set_sleep_mode(<mode>); 8888cli(); 8989if (some_condition) 9090{ 9191sleep_enable(); 9292sei(); 9393sleep_cpu(); 9494sleep_disable(); 9595} 9696sei(); 9797\endcode 9898 9999This sequence ensures an atomic test of \c some_condition with 100100interrupts being disabled. If the condition is met, sleep mode 101101will be prepared, and the \c SLEEP instruction will be scheduled 102102immediately after an \c SEI instruction. As the intruction right 103103after the \c SEI is guaranteed to be executed before an interrupt 104104could trigger, it is sure the device will really be put to sleep. 105105 106106Some devices have the ability to disable the Brown Out Detector (BOD) before 107107going to sleep. This will also reduce power while sleeping. If the 108108specific AVR device has this ability then an additional macro is defined: 109109\c sleep_bod_disable(). This macro generates inlined assembly code 110110that will correctly implement the timed sequence for disabling the BOD 111111before sleeping. However, there is a limited number of cycles after the 112112BOD has been disabled that the device can be put into sleep mode, otherwise 113113the BOD will not truly be disabled. Recommended practice is to disable 114114the BOD (\c sleep_bod_disable()), set the interrupts (\c sei()), and then 115115put the device to sleep (\c sleep_cpu()), like so: 116116 117117\code 118118#include <avr/interrupt.h> 119119#include <avr/sleep.h> 120120 121121... 122122set_sleep_mode(<mode>); 123123cli(); 124124if (some_condition) 125125{ 126126sleep_enable(); 127127sleep_bod_disable(); 128128sei(); 129129sleep_cpu(); 130130sleep_disable(); 131131} 132132sei(); 133133\endcode 134134*/ 135135 136136 137137/* Define an internal sleep control register and an internal sleep enable bit mask. */ 138138#if defined(SLEEP_CTRL) 139139 140140/* XMEGA devices */ 141141#define _SLEEP_CONTROL_REG SLEEP_CTRL 142142#define _SLEEP_ENABLE_MASK SLEEP_SEN_bm 143143 144144#elif defined(SMCR) 145145 146146#define _SLEEP_CONTROL_REG SMCR 147147#define _SLEEP_ENABLE_MASK _BV(SE) 148148 149149#elif defined(__AVR_AT94K__) 150150 151151#define _SLEEP_CONTROL_REG MCUR 152152#define _SLEEP_ENABLE_MASK _BV(SE) 153153 154154#elif !defined(__DOXYGEN__) 155155 156156#define _SLEEP_CONTROL_REG MCUCR 157157#define _SLEEP_ENABLE_MASK _BV(SE) 158158 159159#endif 160160 161161 162162/* Special casing these three devices - they are the 163163only ones that need to write to more than one register. */ 164164#if defined(__AVR_ATmega161__) 165165 166166#define set_sleep_mode(mode) \ 167167do { \ 168168MCUCR = ((MCUCR & ~_BV(SM1)) | ((mode) == SLEEP_MODE_PWR_DOWN || (mode) == SLEEP_MODE_PWR_SAVE ? _BV(SM1) : 0)); \ 169169EMCUCR = ((EMCUCR & ~_BV(SM0)) | ((mode) == SLEEP_MODE_PWR_SAVE ? _BV(SM0) : 0)); \ 170170} while(0) 171171 172172 173173#elif defined(__AVR_ATmega162__) \ 174174|| defined(__AVR_ATmega8515__) 175175 176176#define set_sleep_mode(mode) \ 177177do { \ 178178MCUCR = ((MCUCR & ~_BV(SM1)) | ((mode) == SLEEP_MODE_IDLE ? 0 : _BV(SM1))); \ 179179MCUCSR = ((MCUCSR & ~_BV(SM2)) | ((mode) == SLEEP_MODE_STANDBY || (mode) == SLEEP_MODE_EXT_STANDBY ? _BV(SM2) : 0)); \ 180180EMCUCR = ((EMCUCR & ~_BV(SM0)) | ((mode) == SLEEP_MODE_PWR_SAVE || (mode) == SLEEP_MODE_EXT_STANDBY ? _BV(SM0) : 0)); \ 181181} while(0) 182182 183183/* For xmegas, check presence of SLEEP_SMODE<n>_bm and define set_sleep_mode accordingly. */ 184184#elif defined(__AVR_XMEGA__) 185185#if defined(SLEEP_SMODE2_bm) 186186 187187#define set_sleep_mode(mode) \ 188188do { \ 189189_SLEEP_CONTROL_REG = ((_SLEEP_CONTROL_REG & ~(SLEEP_SMODE2_bm | SLEEP_SMODE1_bm | SLEEP_SMODE0_bm)) | (mode)); \ 190190} while(0) 191191 192192#elif defined(SLEEP_SMODE1_bm) 193193 194194#define set_sleep_mode(mode) \ 195195do { \ 196196_SLEEP_CONTROL_REG = ((_SLEEP_CONTROL_REG & ~(SLEEP_SMODE1_bm | SLEEP_SMODE0_bm)) | (mode)); \ 197197} while(0) 198198 199199#else 200200 201201#define set_sleep_mode(mode) \ 202202do { \ 203203_SLEEP_CONTROL_REG = ((_SLEEP_CONTROL_REG & ~( SLEEP_SMODE0_bm)) | (mode)); \ 204204} while(0) 205205 206206 207207#endif /* #if defined(SLEEP_SMODE2_bm) */ 208208 209209/* For everything else, check for presence of SM<n> and define set_sleep_mode accordingly. */ 210210#else 211211#if defined(SM2) 212212 213213#define set_sleep_mode(mode) \ 214214do { \ 215215_SLEEP_CONTROL_REG = ((_SLEEP_CONTROL_REG & ~(_BV(SM0) | _BV(SM1) | _BV(SM2))) | (mode)); \ 216216} while(0) 217217 218218#elif defined(SM1) 219219 220220#define set_sleep_mode(mode) \ 221221do { \ 222222_SLEEP_CONTROL_REG = ((_SLEEP_CONTROL_REG & ~(_BV(SM0) | _BV(SM1))) | (mode)); \ 223223} while(0) 224224 225225#elif defined(SM) 226226 227227#define set_sleep_mode(mode) \ 228228do { \ 229229_SLEEP_CONTROL_REG = ((_SLEEP_CONTROL_REG & ~_BV(SM)) | (mode)); \ 230230} while(0) 231231 232232#else 233233 234234#error "No SLEEP mode defined for this device." 235235 236236#endif /* if defined(SM2) */ 237237#endif /* #if defined(__AVR_ATmega161__) */ 238238 239239 240240 241241/** \ingroup avr_sleep 242242 243243Put the device in sleep mode. How the device is brought out of sleep mode 244244depends on the specific mode selected with the set_sleep_mode() function. 245245See the data sheet for your device for more details. */ 246246 247247 248248#if defined(__DOXYGEN__) 249249 250250/** \ingroup avr_sleep 251251 252252Set the SE (sleep enable) bit. 253253*/ 254254extern void sleep_enable (void); 255255 256256#else 257257 258258#define sleep_enable() \ 259259 do { \ 260260_SLEEP_CONTROL_REG |= (uint8_t)_SLEEP_ENABLE_MASK; \ 261261} while(0) 262262 263263#endif 264264 265265 266266#if defined(__DOXYGEN__) 267267 268268/** \ingroup avr_sleep 269269 270270Clear the SE (sleep enable) bit. 271271*/ 272272extern void sleep_disable (void); 273273 274274#else 275275 276276#define sleep_disable() \ 277277 do { \ 278278_SLEEP_CONTROL_REG &= (uint8_t)(~_SLEEP_ENABLE_MASK); \ 279279} while(0) 280280 281281#endif 282282 283283 284284/** \ingroup avr_sleep 285285 286286Put the device into sleep mode. The SE bit must be set 287287beforehand, and it is recommended to clear it afterwards. 288288*/ 289289#if defined(__DOXYGEN__) 290290 291291extern void sleep_cpu (void); 292292 293293#else 294294 295295#define sleep_cpu() \ 296296 do { \ 297297__asm__ __volatile__ ( "sleep" "\n\t" :: ); \ 298298} while(0) 299299 300300#endif 301301 302302 303303#if defined(__DOXYGEN__) 304304 305305/** \ingroup avr_sleep 306306 307307Put the device into sleep mode, taking care of setting 308308the SE bit before, and clearing it afterwards. */ 309309extern void sleep_mode (void); 310310 311311#else 312312 313313#define sleep_mode() \ 314314 do { \ 315315sleep_enable(); \ 316316sleep_cpu(); \ 317317sleep_disable(); \ 318318} while (0) 319319 320320#endif 321321 322322 323323#if defined(__DOXYGEN__) 324324 325325/** \ingroup avr_sleep 326326 327327Disable BOD before going to sleep. 328328Not available on all devices. 329329*/ 330330extern void sleep_bod_disable (void); 331331 332332#else 333333 334334#if defined(BODS) && defined(BODSE) 335335 336336#ifdef BODCR 337337 338338#define BOD_CONTROL_REG BODCR 339339 340340#else 341341 342342#define BOD_CONTROL_REG MCUCR 343343 344344#endif 345345 346346#define sleep_bod_disable() \ 347347 do { \ 348348uint8_t tempreg; \ 349349__asm__ __volatile__("in %[tempreg], %[mcucr]" "\n\t" \ 350350"ori %[tempreg], %[bods_bodse]" "\n\t" \ 351351"out %[mcucr], %[tempreg]" "\n\t" \ 352352"andi %[tempreg], %[not_bodse]" "\n\t" \ 353353"out %[mcucr], %[tempreg]" \ 354354: [tempreg] "=&d" (tempreg) \ 355355: [mcucr] "I" _SFR_IO_ADDR(BOD_CONTROL_REG), \ 356356[bods_bodse] "i" (_BV(BODS) | _BV(BODSE)), \ 357357[not_bodse] "i" (~_BV(BODSE))); \ 358358} while (0) 359359 360360#endif 361361 362362#endif 363363 364364 365365/*@}*/ 366366 367367#endif /* _AVR_SLEEP_H_ */

sleep_mode void sleep_mode(void)

sleep_cpu void sleep_cpu(void)

sleep_enable void sleep_enable(void)

io.h

sleep_disable void sleep_disable(void)

sleep_bod_disable void sleep_bod_disable(void)

stdint.h