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

delay.8h

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

math.h

_delay_loop_2 void _delay_loop_2(uint16_t __count)

Definition: delay_basic.h:103

fabs double fabs(double __x)

delay_basic.h

__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

inttypes.h

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