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

delay.h

Go to the documentation of this file.
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_ */

Automatically generated by Doxygen 1.6.2-20100208 on 11 Jul 2010.