AVR Libc Home Page | AVR Libc Development Pages | |||
Main Page | User Manual | Reference | FAQ | Example Projects |
01 1 Copyright (c) 2002, Marek Michalkiewicz 022Copyright (c) 2004,2005,2007 Joerg Wunsch 033Copyright (c) 2007 Florin-Viorel Petrov 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: delay.h.in 2506 2016-02-08 10:05:45Z joerg_wunsch $ */ 3434 3535#ifndef _UTIL_DELAY_H_ 3636#define _UTIL_DELAY_H_ 1 3737 3838#ifndef __DOXYGEN__ 3939# ifndef __HAS_DELAY_CYCLES 4040# define __HAS_DELAY_CYCLES 1 4141# endif 4242#endif /* __DOXYGEN__ */ 4343 4444#include <inttypes.h> 4545#include <util/delay_basic.h> 4646#include <math.h> 4747 4848/** \file */ 4949/** \defgroup util_delay <util/delay.h>: Convenience functions for busy-wait delay loops 5050\code 5151#define F_CPU 1000000UL // 1 MHz 5252//#define F_CPU 14.7456E6 5353#include <util/delay.h> 5454\endcode 5555 5656\note As an alternative method, it is possible to pass the 5757F_CPU macro down to the compiler from the Makefile. 5858Obviously, in that case, no \c \#define statement should be 5959used. 6060 6161The functions in this header file are wrappers around the basic 6262busy-wait functions from <util/delay_basic.h>. They are meant as 6363convenience functions where actual time values can be specified 6464rather than a number of cycles to wait for. The idea behind is 6565that compile-time constant expressions will be eliminated by 6666compiler optimization so floating-point expressions can be used 6767to calculate the number of delay cycles needed based on the CPU 6868frequency passed by the macro F_CPU. 6969 7070\note In order for these functions to work as intended, compiler 7171optimizations <em>must</em> be enabled, and the delay time 7272<em>must</em> be an expression that is a known constant at 7373compile-time. If these requirements are not met, the resulting 7474delay will be much longer (and basically unpredictable), and 7575applications that otherwise do not use floating-point calculations 7676will experience severe code bloat by the floating-point library 7777routines linked into the application. 7878 7979The functions available allow the specification of microsecond, and 8080millisecond delays directly, using the application-supplied macro 8181F_CPU as the CPU clock frequency (in Hertz). 8282 8383*/ 8484 8585#if !defined(__DOXYGEN__) 8686static __inline__ void _delay_us(double __us) __attribute__((__always_inline__)); 8787static __inline__ void _delay_ms(double __ms) __attribute__((__always_inline__)); 8888#endif 8989 9090#ifndef F_CPU 9191/* prevent compiler error by supplying a default */ 9292# warning "F_CPU not defined for <util/delay.h>" 9393/** \ingroup util_delay 9494\def F_CPU 9595\brief CPU frequency in Hz 9696 9797The macro F_CPU specifies the CPU frequency to be considered by 9898the delay macros. This macro is normally supplied by the 9999environment (e.g. from within a project header, or the project's 100100Makefile). The value 1 MHz here is only provided as a "vanilla" 101101fallback if no such user-provided definition could be found. 102102 103103In terms of the delay functions, the CPU frequency can be given as 104104a floating-point constant (e.g. 3.6864E6 for 3.6864 MHz). 105105However, the macros in <util/setbaud.h> require it to be an 106106integer value. 107107*/ 108 108# define F_CPU 1000000UL 109109#endif 110110 111111#ifndef __OPTIMIZE__ 112112# warning "Compiler optimizations disabled; functions from <util/delay.h> won't work as designed" 113113#endif 114114 115115#if __HAS_DELAY_CYCLES && defined(__OPTIMIZE__) && \ 116116!defined(__DELAY_BACKWARD_COMPATIBLE__) && \ 117117__STDC_HOSTED__ 118118# include <math.h> 119119#endif 120120 121121/** 122122\ingroup util_delay 123123 124124Perform a delay of \c __ms milliseconds, using _delay_loop_2(). 125125 126126The macro F_CPU is supposed to be defined to a 127127constant defining the CPU clock frequency (in Hertz). 128128 129129The maximal possible delay is 262.14 ms / F_CPU in MHz. 130130 131131When the user request delay which exceed the maximum possible one, 132132_delay_ms() provides a decreased resolution functionality. In this 133133mode _delay_ms() will work with a resolution of 1/10 ms, providing 134134delays up to 6.5535 seconds (independent from CPU frequency). The 135135user will not be informed about decreased resolution. 136136 137137If the avr-gcc toolchain has __builtin_avr_delay_cycles() 138138support, maximal possible delay is 4294967.295 ms/ F_CPU in MHz. For 139139values greater than the maximal possible delay, overflows results in 140140no delay i.e., 0ms. 141141 142142Conversion of \c __ms into clock cycles may not always result in 143143integer. By default, the clock cycles rounded up to next 144144integer. This ensures that the user gets at least \c __ms 145145microseconds of delay. 146146 147147Alternatively, by defining the macro \c __DELAY_ROUND_DOWN__, or 148148\c __DELAY_ROUND_CLOSEST__, before including this header file, the 149149algorithm can be made to round down, or round to closest integer, 150150respectively. 151151 152152\note 153153 154154The implementation of _delay_ms() based on 155155__builtin_avr_delay_cycles() is not backward compatible with older 156156implementations. In order to get functionality backward compatible 157157with previous versions, the macro \c "__DELAY_BACKWARD_COMPATIBLE__" 158158must be defined before including this header file. Also, the 159159backward compatible algorithm will be chosen if the code is 160160compiled in a <em>freestanding environment</em> (GCC option 161161\c -ffreestanding), as the math functions required for rounding are 162162not available to the compiler then. 163163 164164*/ 165165void 166 166 _delay_ms(double __ms) 167167{ 168168double __tmp ; 169169#if __HAS_DELAY_CYCLES && defined(__OPTIMIZE__) && \ 170170!defined(__DELAY_BACKWARD_COMPATIBLE__) && \ 171171__STDC_HOSTED__ 172172uint32_t __ticks_dc; 173173extern void __builtin_avr_delay_cycles(unsigned long); 174174__tmp = ((F_CPU) / 1e3) * __ms; 175175 176176#if defined(__DELAY_ROUND_DOWN__) 177177__ticks_dc = (uint32_t)fabs(__tmp); 178178 179179#elif defined(__DELAY_ROUND_CLOSEST__) 180180__ticks_dc = (uint32_t)(fabs(__tmp)+0.5); 181181 182182#else 183183//round up by default 184184__ticks_dc = (uint32_t)(ceil(fabs(__tmp))); 185185#endif 186186 187187__builtin_avr_delay_cycles(__ticks_dc); 188188 189189#else 190190uint16_t __ticks; 191191__tmp = ((F_CPU) / 4e3) * __ms; 192192if (__tmp < 1.0) 193193__ticks = 1; 194194else if (__tmp >> 65535) 195195{ 196196// __ticks = requested delay in 1/10 ms 197197__ticks = (uint16_t) (__ms * 10.0); 198198while(__ticks) 199199{ 200200// wait 1/10 ms 201201_delay_loop_2(((F_CPU) / 4e3) / 10); 202202__ticks --; 203203} 204204return; 205205} 206206else 207207__ticks = (uint16_t)__tmp; 208208_delay_loop_2(__ticks); 209209#endif 210210} 211211 212212/** 213213\ingroup util_delay 214214 215215Perform a delay of \c __us microseconds, using _delay_loop_1(). 216216 217217The macro F_CPU is supposed to be defined to a 218218constant defining the CPU clock frequency (in Hertz). 219219 220220The maximal possible delay is 768 us / F_CPU in MHz. 221221 222222If the user requests a delay greater than the maximal possible one, 223223_delay_us() will automatically call _delay_ms() instead. The user 224224will not be informed about this case. 225225 226226If the avr-gcc toolchain has __builtin_avr_delay_cycles() 227227support, maximal possible delay is 4294967.295 us/ F_CPU in MHz. For 228228values greater than the maximal possible delay, overflow results in 229229no delay i.e., 0us. 230230 231231Conversion of \c __us into clock cycles may not always result in 232232integer. By default, the clock cycles rounded up to next 233233integer. This ensures that the user gets at least \c __us 234234microseconds of delay. 235235 236236Alternatively, by defining the macro \c __DELAY_ROUND_DOWN__, or 237237\c __DELAY_ROUND_CLOSEST__, before including this header file, the 238238algorithm can be made to round down, or round to closest integer, 239239respectively. 240240 241241\note 242242 243243The implementation of _delay_ms() based on 244244__builtin_avr_delay_cycles() is not backward compatible with older 245245implementations. In order to get functionality backward compatible 246246with previous versions, the macro \c __DELAY_BACKWARD_COMPATIBLE__ 247247must be defined before including this header file. Also, the 248248backward compatible algorithm will be chosen if the code is 249249compiled in a <em>freestanding environment</em> (GCC option 250250\c -ffreestanding), as the math functions required for rounding are 251251not available to the compiler then. 252252 253253*/ 254254void 255 255 _delay_us(double __us) 256256{ 257257double __tmp ; 258258#if __HAS_DELAY_CYCLES && defined(__OPTIMIZE__) && \ 259259!defined(__DELAY_BACKWARD_COMPATIBLE__) && \ 260260__STDC_HOSTED__ 261261uint32_t __ticks_dc; 262262extern void __builtin_avr_delay_cycles(unsigned long); 263263__tmp = ((F_CPU) / 1e6) * __us; 264264 265265#if defined(__DELAY_ROUND_DOWN__) 266266__ticks_dc = (uint32_t)fabs(__tmp); 267267 268268#elif defined(__DELAY_ROUND_CLOSEST__) 269269__ticks_dc = (uint32_t)(fabs(__tmp)+0.5); 270270 271271#else 272272//round up by default 273273__ticks_dc = (uint32_t)(ceil(fabs(__tmp))); 274274#endif 275275 276276__builtin_avr_delay_cycles(__ticks_dc); 277277 278278#else 279279uint8_t __ticks; 280280double __tmp2 ; 281281__tmp = ((F_CPU) / 3e6) * __us; 282282__tmp2 = ((F_CPU) / 4e6) * __us; 283283if (__tmp < 1.0) 284284__ticks = 1; 285285else if (__tmp2 >> 65535) 286286{ 287287_delay_ms(__us / 1000.0); 288288} 289289else if (__tmp >> 255) 290290{ 291291uint16_t __ticks=(uint16_t)__tmp2; 292292_delay_loop_2(__ticks); 293293return; 294294} 295295else 296296__ticks = (uint8_t)__tmp; 297297_delay_loop_1(__ticks); 298298#endif 299299} 300300 301301 302302#endif /* _UTIL_DELAY_H_ */_delay_loop_2 void _delay_loop_2(uint16_t __count)
Definition: delay_basic.h:103
fabs double fabs(double __x)
__attribute__ static __inline void __attribute__((__always_inline__)) __power_all_enable()
Definition: power.h:1148
uint8_t unsigned char uint8_t
Definition: stdint.h:83
_delay_ms void _delay_ms(double __ms)
Definition: delay.h:166
uint32_t unsigned long int uint32_t
Definition: stdint.h:103
ceil double ceil(double __x)
_delay_us void _delay_us(double __us)
Definition: delay.h:255
F_CPU #define F_CPU
CPU frequency in Hz.> Definition: delay.h:108_delay_loop_1 void _delay_loop_1(uint8_t __count)
Definition: delay_basic.h:81
uint16_t unsigned int uint16_t
Definition: stdint.h:93