2004-12-20 Joerg Wunsch
* include/avr/delay.h: Move _delay_ms and _delay_us to double.
Index: include/avr/delay.h
===================================================================
RCS file: /cvsroot/avr-libc/avr-libc/include/avr/delay.h,v
retrieving revision 1.6
diff -u -u -r1.6 delay.h
--- include/avr/delay.h 19 Dec 2004 22:43:38 -0000 1.6
+++ include/avr/delay.h 21 Dec 2004 22:55:26 -0000
@@ -1,4 +1,5 @@
/* Copyright (c) 2002, Marek Michalkiewicz
+ Copyright (c) 2004, Joerg Wunsch
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -44,7 +45,7 @@
#include
\endcode
- The macros in this header file implement simple delay loops
+ The functions in this header file implement simple delay loops
that perform a busy-waiting. They are typically used to
facilitate short delays in the program execution. They are
implemented as count-down loops with a well-known CPU cycle
@@ -59,17 +60,14 @@
overhead of setting up a hardware timer is too much compared
to the overall delay time.
- Two inline functions are provided for the actual delay
- algorithms. Two wrapper macros allow the specification of
- microsecond, and millisecond delays directly, using the
- application-supplied macro F_CPU as the CPU clock frequency
- (in Hertz).
-
- \note While these macros perform all calculation at compile-time
- using the C preprocessor, so no run-time overhead results, care
- should be taken to not overflow the argument domain range, as the
- macros cannot detect such an overflow but would rather truncate
- the loop count, yielding unintented delay values.
+ Two inline functions are provided for the actual delay algorithms.
+
+ Two wrapper functions allow the specification of microsecond, and
+ millisecond delays directly, using the application-supplied macro
+ F_CPU as the CPU clock frequency (in Hertz). These functions
+ operate on double typed arguments, however when optimization is
+ turned on, the entire floating-point calculation will be done at
+ compile-time.
*/
/** \ingroup avr_delay
@@ -86,7 +84,7 @@
static __inline__ void
_delay_loop_1(uint8_t __count)
{
- asm volatile (
+ __asm__ volatile (
"1: dec %0" "\n\t"
"brne 1b"
: "=r" (__count)
@@ -108,7 +106,7 @@
static __inline__ void
_delay_loop_2(uint16_t __count)
{
- asm volatile (
+ __asm__ volatile (
"1: sbiw %0,1" "\n\t"
"brne 1b"
: "=w" (__count)
@@ -116,33 +114,53 @@
);
}
-
/**
\ingroup avr_delay
- \def _delay_us
- Perform a delay of \c count microseconds, using _delay_loop_1().
+ Perform a delay of \c __us microseconds, using _delay_loop_1().
- The macro F_CPU is supposed to be defined to an unsigned long
- integer constant defining the CPU clock frequency (in Hertz).
+ The macro F_CPU is supposed to be defined to a
+ constant defining the CPU clock frequency (in Hertz).
The maximal possible delay is 768 us / F_CPU in MHz.
*/
-#define _delay_us(count) \
-_delay_loop_1((uint8_t)(((unsigned long)(F_CPU) * (count)) / 3000000UL))
+static __inline__ void
+_delay_us(double __us)
+{
+ uint8_t __ticks;
+ double __tmp = ((F_CPU) / 3e6) * __us;
+ if (__tmp < 1.0)
+ __ticks = 1;
+ else if (__tmp > 255)
+ __ticks = 0; /* i.e. 256 */
+ else
+ __ticks = (uint8_t)__tmp;
+ _delay_loop_1(__ticks);
+}
+
/**
\ingroup avr_delay
- \def _delay_ms
- Perform a delay of \c count milliseconds, using _delay_loop_2().
+ Perform a delay of \c __ms milliseconds, using _delay_loop_2().
- The macro F_CPU is supposed to be defined to an unsigned long
- integer constant defining the CPU clock frequency (in Hertz).
+ The macro F_CPU is supposed to be defined to a
+ constant defining the CPU clock frequency (in Hertz).
The maximal possible delay is 262.14 ms / F_CPU in MHz.
*/
-#define _delay_ms(count) \
-_delay_loop_2((uint16_t)(((unsigned long)(F_CPU) * (count)) / 4000UL))
+static __inline__ void
+_delay_ms(double __ms)
+{
+ uint16_t __ticks;
+ double __tmp = ((F_CPU) / 4e3) * __ms;
+ if (__tmp < 1.0)
+ __ticks = 1;
+ else if (__tmp > 65535)
+ __ticks = 0; /* i.e. 65536 */
+ else
+ __ticks = (uint16_t)__tmp;
+ _delay_loop_2(__ticks);
+}
#endif /* _AVR_DELAY_H_ */