AVR-LibC  2.3.0git
Standard C library for AVR-GCC
 

AVR-LibC Documen­tation

AVR-LibC Development Pages

Main Page

User Manual

Library Refe­rence

FAQ

Example Projects

File List

Index

Loading...
Searching...
No Matches
delay.h
Go to the documentation of this file.
1/* Copyright (c) 2002, Marek Michalkiewicz
2 Copyright (c) 2004,2005,2007 Joerg Wunsch
3 Copyright (c) 2007 Florin-Viorel Petrov
4 All rights reserved.
5
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions are met:
8
9 * Redistributions of source code must retain the above copyright
10 notice, this list of conditions and the following disclaimer.
11
12 * Redistributions in binary form must reproduce the above copyright
13 notice, this list of conditions and the following disclaimer in
14 the documentation and/or other materials provided with the
15 distribution.
16
17 * Neither the name of the copyright holders nor the names of
18 contributors may be used to endorse or promote products derived
19 from this software without specific prior written permission.
20
21 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
25 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 POSSIBILITY OF SUCH DAMAGE. */
32
33/* include/util/delay.h. Generated from delay.h.in by configure. */
34
35#ifndef _UTIL_DELAY_H_
36#define _UTIL_DELAY_H_ 1
37
38#ifndef __DOXYGEN__
39# ifndef __HAS_DELAY_CYCLES
40# define __HAS_DELAY_CYCLES 1
41# endif
42
43#endif /* __DOXYGEN__ */
44
45#include <stdint.h>
46#include <util/delay_basic.h>
47#include <bits/attribs.h>
48
49/** \file */
50/** \defgroup util_delay <util/delay.h>: Convenience functions for busy-wait delay loops
51 \code
52 #define F_CPU 1000000UL // 1 MHz
53 //#define F_CPU 14.7456e6
54 #include <util/delay.h>
55 \endcode
56
57 \note As an alternative method, it is possible to pass the
58 F_CPU macro down to the compiler from the Makefile.
59 Obviously, in that case, no \c \#define statement should be
60 used.
61
62 The functions in this header file are wrappers around the basic
63 busy-wait functions from <tt><util/delay_basic.h></tt>. They are meant as
64 convenience functions where actual time values can be specified
65 rather than a number of cycles to wait for. The idea behind is
66 that compile-time constant expressions will be eliminated by
67 compiler optimization so floating-point expressions can be used
68 to calculate the number of delay cycles needed based on the CPU
69 frequency passed by the macro F_CPU.
70
71 \note In order for these functions to work as intended, compiler
72 optimizations <em>must</em> be enabled, and the delay time
73 <em>must</em> be an expression that is a known constant at
74 compile-time. If these requirements are not met, the resulting
75 delay will be much longer (and basically unpredictable), and
76 applications that otherwise do not use floating-point calculations
77 will experience severe code bloat by the floating-point library
78 routines linked into the application.
79
80 The functions available allow the specification of microsecond, and
81 millisecond delays directly, using the application-supplied macro
82 F_CPU as the CPU clock frequency (in Hertz).
83*/
84
85
86#ifndef F_CPU
87/* prevent compiler error by supplying a default */
88# warning "F_CPU not defined for <util/delay.h>"
89/** \ingroup util_delay
90 \def F_CPU
91 \brief CPU frequency in Hz
92
93 The macro F_CPU specifies the CPU frequency to be considered by
94 the delay macros. This macro is normally supplied by the
95 environment (e.g. from within a project header, or the project's
96 Makefile). The value 1 MHz here is only provided as a "vanilla"
97 fallback if no such user-provided definition could be found.
98
99 In terms of the delay functions, the CPU frequency can be given as
100 a floating-point constant (e.g. 3.6864e6 for 3.6864 MHz).
101 However, the macros in <util/setbaud.h> require it to be an
102 integer value.
103 */
104# define F_CPU 1000000UL
105#endif
106
107#ifndef __OPTIMIZE__
108# warning "Compiler optimizations disabled; functions from <util/delay.h> won't work as designed"
109#endif
110
111/**
112 \ingroup util_delay
113
114 Perform a delay of \c __ms milliseconds, using _delay_loop_2().
115
116 The macro #F_CPU is supposed to be defined to a
117 constant defining the CPU clock frequency (in Hertz).
118
119 The maximal possible delay is 262.14 ms / F_CPU in MHz.
120
121 When the user request delay which exceed the maximum possible one,
122 _delay_ms() provides a decreased resolution functionality. In this
123 mode _delay_ms() will work with a resolution of 1/10&nbsp;ms, providing
124 delays up to 6.5535 seconds (independent from CPU frequency). The
125 user will not be informed about decreased resolution.
126
127 If the avr-gcc toolchain has \c __builtin_avr_delay_cycles()
128 support, maximal possible delay is 4294967.295 ms/ F_CPU in MHz. For
129 values greater than the maximal possible delay, overflow may result in
130 no delay i.e., 0&nbsp;ms.
131
132 Conversion of \c __ms into clock cycles may not always result in
133 an integral value. By default, the clock cycles are rounded up to the next
134 integer. This ensures that the user gets at least \c __ms
135 microseconds of delay.
136
137 Alternatively, by defining the macro \c __DELAY_ROUND_DOWN__, or
138 \c __DELAY_ROUND_CLOSEST__, before including this header file, the
139 algorithm can be made to round down, or round to closest integer,
140 respectively.
141
142 \note The implementation of _delay_ms() based on
143 \c __builtin_avr_delay_cycles() is not backward compatible with older
144 implementations. In order to get functionality backward compatible
145 with previous versions, the macro \c __DELAY_BACKWARD_COMPATIBLE__
146 must be defined before including this header file.
147 */
148static __ATTR_ALWAYS_INLINE__ void _delay_ms(double __ms);
149
150void
151_delay_ms(double __ms)
152{
153 double __tmp ;
154#if __HAS_DELAY_CYCLES && defined(__OPTIMIZE__) \
155 && !defined(__DELAY_BACKWARD_COMPATIBLE__)
156 uint32_t __ticks_dc;
157 __tmp = ((F_CPU) / 1e3) * __ms;
158
159 #if defined(__DELAY_ROUND_DOWN__)
160 __ticks_dc = (uint32_t)__builtin_fabs(__tmp);
161
162 #elif defined(__DELAY_ROUND_CLOSEST__)
163 __ticks_dc = (uint32_t)(__builtin_fabs(__tmp)+0.5);
164
165 #else
166 //round up by default
167 __ticks_dc = (uint32_t)(__builtin_ceil(__builtin_fabs(__tmp)));
168 #endif
169
170 __builtin_avr_delay_cycles(__ticks_dc);
171
172#else
173 uint16_t __ticks;
174 __tmp = ((F_CPU) / 4e3) * __ms;
175 if (__tmp < 1.0)
176 __ticks = 1;
177 else if (__tmp > 65535)
178 {
179 // __ticks = requested delay in 1/10 ms
180 __ticks = (uint16_t) (__ms * 10.0);
181 while(__ticks)
182 {
183 // wait 1/10 ms
184 _delay_loop_2(((F_CPU) / 4e3) / 10);
185 __ticks --;
186 }
187 return;
188 }
189 else
190 __ticks = (uint16_t)__tmp;
191 _delay_loop_2(__ticks);
192#endif
193}
194
195/**
196 \ingroup util_delay
197
198 Perform a delay of \c __us microseconds, using _delay_loop_1().
199
200 The macro #F_CPU is supposed to be defined to a
201 constant defining the CPU clock frequency (in Hertz).
202
203 The maximal possible delay is 768 &mu;s / F_CPU in MHz.
204
205 If the user requests a delay greater than the maximal possible one,
206 _delay_us() will automatically call _delay_ms() instead. The user
207 will not be informed about this case.
208
209 If the avr-gcc toolchain has __builtin_avr_delay_cycles()
210 support, maximal possible delay is 4294967.295 &mu;s/ F_CPU in MHz. For
211 values greater than the maximal possible delay, overflow may result in
212 no delay i.e., 0&nbsp;&mu;s.
213
214 Conversion of \c __us into clock cycles may not always result in
215 integer. By default, the clock cycles are rounded up to next
216 integer. This ensures that the user gets at least \c __us
217 microseconds of delay.
218
219 Alternatively, by defining the macro \c __DELAY_ROUND_DOWN__, or
220 \c __DELAY_ROUND_CLOSEST__, before including this header file, the
221 algorithm can be made to round down, or round to closest integer,
222 respectively.
223
224 \note The implementation of _delay_us() based on
225 \c __builtin_avr_delay_cycles() is not backward compatible with older
226 implementations. In order to get functionality backward compatible
227 with previous versions, the macro \c __DELAY_BACKWARD_COMPATIBLE__
228 must be defined before including this header file.
229 */
230static __ATTR_ALWAYS_INLINE__ void _delay_us(double __us);
231
232void
233_delay_us(double __us)
234{
235 double __tmp ;
236#if __HAS_DELAY_CYCLES && defined(__OPTIMIZE__) \
237 && !defined(__DELAY_BACKWARD_COMPATIBLE__)
238 uint32_t __ticks_dc;
239 __tmp = ((F_CPU) / 1e6) * __us;
240
241 #if defined(__DELAY_ROUND_DOWN__)
242 __ticks_dc = (uint32_t)__builtin_fabs(__tmp);
243
244 #elif defined(__DELAY_ROUND_CLOSEST__)
245 __ticks_dc = (uint32_t)(__builtin_fabs(__tmp)+0.5);
246
247 #else
248 //round up by default
249 __ticks_dc = (uint32_t)(__builtin_ceil(__builtin_fabs(__tmp)));
250 #endif
251
252 __builtin_avr_delay_cycles(__ticks_dc);
253
254#else
255 uint8_t __ticks;
256 double __tmp2 ;
257 __tmp = ((F_CPU) / 3e6) * __us;
258 __tmp2 = ((F_CPU) / 4e6) * __us;
259 if (__tmp < 1.0)
260 __ticks = 1;
261 else if (__tmp2 > 65535)
262 {
263 _delay_ms(__us / 1000.0);
264 return;
265 }
266 else if (__tmp > 255)
267 {
268 uint16_t __ticks=(uint16_t)__tmp2;
269 _delay_loop_2(__ticks);
270 return;
271 }
272 else
273 __ticks = (uint8_t)__tmp;
274 _delay_loop_1(__ticks);
275#endif
276}
277
278
279#endif /* _UTIL_DELAY_H_ */
unsigned int uint16_t
Definition: stdint.h:91
unsigned long int uint32_t
Definition: stdint.h:101
unsigned char uint8_t
Definition: stdint.h:81
void _delay_loop_1(uint8_t __count)
Definition: delay_basic.h:79
void _delay_loop_2(uint16_t __count)
Definition: delay_basic.h:101
#define F_CPU
CPU frequency in Hz.
Definition: delay.h:104
static void _delay_us(double __us)
Definition: delay.h:233
static void _delay_ms(double __ms)
Definition: delay.h:151