~ubuntu-branches/ubuntu/maverick/avr-libc/maverick

« back to all changes in this revision

Viewing changes to include/util/delay.h

  • Committer: Bazaar Package Importer
  • Author(s): Hakan Ardo
  • Date: 2007-08-09 11:28:01 UTC
  • mfrom: (1.1.4 upstream)
  • Revision ID: james.westby@ubuntu.com-20070809112801-ps7wognnynio9kz7
Tags: 1:1.4.6-1
New upstream release

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* Copyright (c) 2002, Marek Michalkiewicz
2
 
   Copyright (c) 2004,2005 Joerg Wunsch
 
2
   Copyright (c) 2004,2005,2007 Joerg Wunsch
3
3
   All rights reserved.
4
4
 
5
5
   Redistribution and use in source and binary forms, with or without
29
29
  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30
30
  POSSIBILITY OF SUCH DAMAGE. */
31
31
 
32
 
/* $Id: delay.h,v 1.1.2.1 2005/12/12 23:19:49 joerg_wunsch Exp $ */
 
32
/* $Id: delay.h,v 1.1.2.3 2007/05/13 21:26:06 joerg_wunsch Exp $ */
33
33
 
34
34
#ifndef _UTIL_DELAY_H_
35
35
#define _UTIL_DELAY_H_ 1
36
36
 
37
37
#include <inttypes.h>
 
38
#include <util/delay_basic.h>
38
39
 
39
 
/** \defgroup util_delay <util/delay.h>: Busy-wait delay loops
 
40
/** \file */
 
41
/** \defgroup util_delay <util/delay.h>: Convenience functions for busy-wait delay loops
40
42
    \code
41
43
    #define F_CPU 1000000UL  // 1 MHz
42
44
    //#define F_CPU 14.7456E6
48
50
    Obviously, in that case, no \c \#define statement should be
49
51
    used.
50
52
 
51
 
    The functions in this header file implement simple delay loops
52
 
    that perform a busy-waiting.  They are typically used to
53
 
    facilitate short delays in the program execution.  They are
54
 
    implemented as count-down loops with a well-known CPU cycle
55
 
    count per loop iteration.  As such, no other processing can
56
 
    occur simultaneously.  It should be kept in mind that the
57
 
    functions described here do not disable interrupts.
58
 
 
59
 
    In general, for long delays, the use of hardware timers is
60
 
    much preferrable, as they free the CPU, and allow for
61
 
    concurrent processing of other events while the timer is
62
 
    running.  However, in particular for very short delays, the
63
 
    overhead of setting up a hardware timer is too much compared
64
 
    to the overall delay time.
65
 
 
66
 
    Two inline functions are provided for the actual delay algorithms.
67
 
 
68
 
    Two wrapper functions allow the specification of microsecond, and
 
53
    The functions in this header file are wrappers around the basic
 
54
    busy-wait functions from <util/delay_basic.h>.  They are meant as
 
55
    convenience functions where actual time values can be specified
 
56
    rather than a number of cycles to wait for.  The idea behind is
 
57
    that compile-time constant expressions will be eliminated by
 
58
    compiler optimization so floating-point expressions can be used
 
59
    to calculate the number of delay cycles needed based on the CPU
 
60
    frequency passed by the macro F_CPU.
 
61
 
 
62
    \note In order for these functions to work as intended, compiler
 
63
    optimizations <em>must</em> be enabled, and the delay time
 
64
    <em>must</em> be an expression that is a known constant at
 
65
    compile-time.  If these requirements are not met, the resulting
 
66
    delay will be much longer (and basically unpredictable), and
 
67
    applications that otherwise do not use floating-point calculations
 
68
    will experience severe code bloat by the floating-point library
 
69
    routines linked into the application.
 
70
 
 
71
    The functions available allow the specification of microsecond, and
69
72
    millisecond delays directly, using the application-supplied macro
70
 
    F_CPU as the CPU clock frequency (in Hertz).  These functions
71
 
    operate on double typed arguments, however when optimization is
72
 
    turned on, the entire floating-point calculation will be done at
73
 
    compile-time.
 
73
    F_CPU as the CPU clock frequency (in Hertz).
74
74
 
75
 
    \note When using _delay_us() and _delay_ms(), the expressions
76
 
    passed as arguments to these functions shall be compile-time
77
 
    constants, otherwise the floating-point calculations to setup the
78
 
    loops will be done at run-time, thereby drastically increasing
79
 
    both the resulting code size, as well as the time required to
80
 
    setup the loops.
81
75
*/
82
76
 
83
77
#if !defined(__DOXYGEN__)
84
 
static inline void _delay_loop_1(uint8_t __count) __attribute__((always_inline));
85
 
static inline void _delay_loop_2(uint16_t __count) __attribute__((always_inline));
86
78
static inline void _delay_us(double __us) __attribute__((always_inline));
87
79
static inline void _delay_ms(double __ms) __attribute__((always_inline));
88
80
#endif
89
81
 
90
 
/** \ingroup util_delay
91
 
 
92
 
    Delay loop using an 8-bit counter \c __count, so up to 256
93
 
    iterations are possible.  (The value 256 would have to be passed
94
 
    as 0.)  The loop executes three CPU cycles per iteration, not
95
 
    including the overhead the compiler needs to setup the counter
96
 
    register.
97
 
 
98
 
    Thus, at a CPU speed of 1 MHz, delays of up to 768 microseconds
99
 
    can be achieved.
100
 
*/
101
 
void
102
 
_delay_loop_1(uint8_t __count)
103
 
{
104
 
        __asm__ volatile (
105
 
                "1: dec %0" "\n\t"
106
 
                "brne 1b"
107
 
                : "=r" (__count)
108
 
                : "0" (__count)
109
 
        );
110
 
}
111
 
 
112
 
/** \ingroup util_delay
113
 
 
114
 
    Delay loop using a 16-bit counter \c __count, so up to 65536
115
 
    iterations are possible.  (The value 65536 would have to be
116
 
    passed as 0.)  The loop executes four CPU cycles per iteration,
117
 
    not including the overhead the compiler requires to setup the
118
 
    counter register pair.
119
 
 
120
 
    Thus, at a CPU speed of 1 MHz, delays of up to about 262.1
121
 
    milliseconds can be achieved.
122
 
 */
123
 
void
124
 
_delay_loop_2(uint16_t __count)
125
 
{
126
 
        __asm__ volatile (
127
 
                "1: sbiw %0,1" "\n\t"
128
 
                "brne 1b"
129
 
                : "=w" (__count)
130
 
                : "0" (__count)
131
 
        );
132
 
}
133
 
 
134
82
#ifndef F_CPU
135
83
/* prevent compiler error by supplying a default */
136
84
# warning "F_CPU not defined for <util/delay.h>"
137
85
# define F_CPU 1000000UL
138
86
#endif
139
87
 
 
88
#ifndef __OPTIMIZE__
 
89
# warning "Compiler optimizations disabled; functions from <util/delay.h> won't work as designed"
 
90
#endif
 
91
 
140
92
/**
141
93
   \ingroup util_delay
142
94