AVR Libc Home Page | ![]() |
AVR Libc Development Pages | |||
Main Page | User Manual | Library Reference | FAQ | Alphabetical Index | Example Projects |
00001 /* Copyright (c) 2002, Marek Michalkiewicz 00002 Copyright (c) 2004,2005,2007 Joerg Wunsch 00003 Copyright (c) 2007 Florin-Viorel Petrov 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: delay.h.in 2103 2010-03-17 05:16:10Z joerg_wunsch $ */ 00034 00035 #ifndef _UTIL_DELAY_H_ 00036 #define _UTIL_DELAY_H_ 1 00037 00038 #ifndef __HAS_DELAY_CYCLES 00039 #define __HAS_DELAY_CYCLES 0 00040 #endif 00041 00042 #include <inttypes.h> 00043 #include <util/delay_basic.h> 00044 00045 /** \file */ 00046 /** \defgroup util_delay <util/delay.h>: Convenience functions for busy-wait delay loops 00047 \code 00048 #define F_CPU 1000000UL // 1 MHz 00049 //#define F_CPU 14.7456E6 00050 #include <util/delay.h> 00051 \endcode 00052 00053 \note As an alternative method, it is possible to pass the 00054 F_CPU macro down to the compiler from the Makefile. 00055 Obviously, in that case, no \c \#define statement should be 00056 used. 00057 00058 The functions in this header file are wrappers around the basic 00059 busy-wait functions from <util/delay_basic.h>. They are meant as 00060 convenience functions where actual time values can be specified 00061 rather than a number of cycles to wait for. The idea behind is 00062 that compile-time constant expressions will be eliminated by 00063 compiler optimization so floating-point expressions can be used 00064 to calculate the number of delay cycles needed based on the CPU 00065 frequency passed by the macro F_CPU. 00066 00067 \note In order for these functions to work as intended, compiler 00068 optimizations <em>must</em> be enabled, and the delay time 00069 <em>must</em> be an expression that is a known constant at 00070 compile-time. If these requirements are not met, the resulting 00071 delay will be much longer (and basically unpredictable), and 00072 applications that otherwise do not use floating-point calculations 00073 will experience severe code bloat by the floating-point library 00074 routines linked into the application. 00075 00076 The functions available allow the specification of microsecond, and 00077 millisecond delays directly, using the application-supplied macro 00078 F_CPU as the CPU clock frequency (in Hertz). 00079 00080 */ 00081 00082 #if !defined(__DOXYGEN__) 00083 static inline void _delay_us(double __us) __attribute__((always_inline)); 00084 static inline void _delay_ms(double __ms) __attribute__((always_inline)); 00085 #endif 00086 00087 #ifndef F_CPU 00088 /* prevent compiler error by supplying a default */ 00089 # warning "F_CPU not defined for <util/delay.h>" 00090 # define F_CPU 1000000UL 00091 #endif 00092 00093 #ifndef __OPTIMIZE__ 00094 # warning "Compiler optimizations disabled; functions from <util/delay.h> won't work as designed" 00095 #endif 00096 00097 /** 00098 \ingroup util_delay 00099 00100 Perform a delay of \c __ms milliseconds, using _delay_loop_2(). 00101 00102 The macro F_CPU is supposed to be defined to a 00103 constant defining the CPU clock frequency (in Hertz). 00104 00105 The maximal possible delay is 262.14 ms / F_CPU in MHz. 00106 00107 When the user request delay which exceed the maximum possible one, 00108 _delay_ms() provides a decreased resolution functionality. In this 00109 mode _delay_ms() will work with a resolution of 1/10 ms, providing 00110 delays up to 6.5535 seconds (independent from CPU frequency). The 00111 user will not be informed about decreased resolution. 00112 */ 00113 void 00114 _delay_ms(double __ms) 00115 { 00116 uint16_t __ticks; 00117 double __tmp = ((F_CPU) / 4e3) * __ms; 00118 #if __HAS_DELAY_CYCLES && defined(__OPTIMIZE__) 00119 extern void __builtin_avr_delay_cycles(unsigned long); 00120 __builtin_avr_delay_cycles(__tmp); 00121 #else 00122 if (__tmp < 1.0) 00123 __ticks = 1; 00124 else if (__tmp > 65535) 00125 { 00126 // __ticks = requested delay in 1/10 ms 00127 __ticks = (uint16_t) (__ms * 10.0); 00128 while(__ticks) 00129 { 00130 // wait 1/10 ms 00131 _delay_loop_2(((F_CPU) / 4e3) / 10); 00132 __ticks --; 00133 } 00134 return; 00135 } 00136 else 00137 __ticks = (uint16_t)__tmp; 00138 _delay_loop_2(__ticks); 00139 #endif 00140 } 00141 00142 /** 00143 \ingroup util_delay 00144 00145 Perform a delay of \c __us microseconds, using _delay_loop_1(). 00146 00147 The macro F_CPU is supposed to be defined to a 00148 constant defining the CPU clock frequency (in Hertz). 00149 00150 The maximal possible delay is 768 us / F_CPU in MHz. 00151 00152 If the user requests a delay greater than the maximal possible one, 00153 _delay_us() will automatically call _delay_ms() instead. The user 00154 will not be informed about this case. 00155 */ 00156 void 00157 _delay_us(double __us) 00158 { 00159 uint8_t __ticks; 00160 double __tmp = ((F_CPU) / 3e6) * __us; 00161 #if __HAS_DELAY_CYCLES && defined(__OPTIMIZE__) 00162 extern void __builtin_avr_delay_cycles(unsigned long); 00163 __builtin_avr_delay_cycles(__tmp); 00164 #else 00165 if (__tmp < 1.0) 00166 __ticks = 1; 00167 else if (__tmp > 255) 00168 { 00169 _delay_ms(__us / 1000.0); 00170 return; 00171 } 00172 else 00173 __ticks = (uint8_t)__tmp; 00174 _delay_loop_1(__ticks); 00175 #endif 00176 } 00177 00178 00179 #endif /* _UTIL_DELAY_H_ */