avr-libc-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[avr-libc-commit] [2189] Fix for bug30363


From: Anitha Boyapati
Subject: [avr-libc-commit] [2189] Fix for bug30363
Date: Wed, 13 Oct 2010 09:39:35 +0000

Revision: 2189
          http://svn.sv.gnu.org/viewvc/?view=rev&root=avr-libc&revision=2189
Author:   aboyapati
Date:     2010-10-13 09:39:34 +0000 (Wed, 13 Oct 2010)
Log Message:
-----------
Fix for bug30363

Modified Paths:
--------------
    trunk/avr-libc/ChangeLog
    trunk/avr-libc/NEWS
    trunk/avr-libc/include/util/delay.h.in

Modified: trunk/avr-libc/ChangeLog
===================================================================
--- trunk/avr-libc/ChangeLog    2010-09-28 12:10:10 UTC (rev 2188)
+++ trunk/avr-libc/ChangeLog    2010-10-13 09:39:34 UTC (rev 2189)
@@ -1,3 +1,13 @@
+2010-10-13  Anitha Boyapati  <address@hidden>
+
+       * include/util/delay.h.in: Functions _delay_ms and 
+       _delay_us are modified. They now calculate new _ticks
+       value when builtin_avr_delay_cycle() is used. Macros
+       __DELAY_ROUND_DOWN__, __DELAY_ROUND_CLOSEST__ control
+       round up/closest of _ticks. __DELAY_BACKWARD_COMPATIBLE__
+       macro enables backward compatibility. This macro will be
+       deprecated.
+
 2010-09-28  Anitha Boyapati  <address@hidden>
 
        * include/avr/iotn88.h: Fix RAMEND.

Modified: trunk/avr-libc/NEWS
===================================================================
--- trunk/avr-libc/NEWS 2010-09-28 12:10:10 UTC (rev 2188)
+++ trunk/avr-libc/NEWS 2010-10-13 09:39:34 UTC (rev 2189)
@@ -147,6 +147,7 @@
   [#30669] Improve comment in stdiodemo
   [#30735] bug in example twitest
   [#31086] ATTINY88 RAMEND value not set to correct value in iotn88.h
+  [#30363] _delay_xx() functions in <util/delay.h> are broken
 
 * Other changes:
 

Modified: trunk/avr-libc/include/util/delay.h.in
===================================================================
--- trunk/avr-libc/include/util/delay.h.in      2010-09-28 12:10:10 UTC (rev 
2188)
+++ trunk/avr-libc/include/util/delay.h.in      2010-10-13 09:39:34 UTC (rev 
2189)
@@ -109,16 +109,50 @@
    mode _delay_ms() will work with a resolution of 1/10 ms, providing
    delays up to 6.5535 seconds (independent from CPU frequency).  The
    user will not be informed about decreased resolution.
+
+   If the avr-gcc toolchain has __builtin_avr_delay_cycles(unsigned long)
+   support, maximal possible delay is 4294967.295 ms/ F_CPU in MHz. For
+   values greater than the maximal possible delay, overflows results in
+   no delay i.e., 0ms.
+
+   Conversion of __us into clock cycles may not always result in integer.
+   By default, the clock cycles rounded up to next integer. This ensures that
+   the user gets atleast __us microseconds of delay.
+
+   Alternatively, user can define __DELAY_ROUND_DOWN__ and 
__DELAY_ROUND_CLOSEST__
+   to round down and round to closest integer.
+
+   Note: The new implementation of _delay_ms(double __ms) with 
+    __builtin_avr_delay_cycles(unsigned long) support is not backward 
compatible. 
+   User can define __DELAY_BACKWARD_COMPATIBLE__ to get a backward compatible 
delay
+   although this will be deprecated in future.
+
  */
 void
 _delay_ms(double __ms)
 {
        uint16_t __ticks;
-       double __tmp = ((F_CPU) / 4e3) * __ms;
-#if __HAS_DELAY_CYCLES && defined(__OPTIMIZE__)
+       double __tmp ; 
+#if __HAS_DELAY_CYCLES && defined(__OPTIMIZE__) && 
!defined(__DELAY_BACKWARD_COMPATIBLE__)
+       uint32_t __ticks_dc;
        extern void __builtin_avr_delay_cycles(unsigned long);
-       __builtin_avr_delay_cycles(__tmp);
-#else
+       __tmp = ((F_CPU) / 1e3) * __ms;
+
+       #if defined(__DELAY_ROUND_DOWN__)
+               __ticks_dc = (uint32_t)fabs(__tmp);
+
+       #elif defined(__DELAY_ROUND_CLOSEST__)
+               __ticks_dc = (uint32_t)(fabs(__tmp)+0.5);
+
+       #else
+               //round up by default
+               __ticks_dc = (uint32_t)(ceil(fabs(__tmp)));
+       #endif
+
+       __builtin_avr_delay_cycles(__ticks_dc);
+
+#elif !__HAS_DELAY_CYCLES || (__HAS_DELAY_CYCLES && !defined(__OPTIMIZE__)) || 
defined (__DELAY_BACKWARD_COMPATIBLE__)
+       __tmp = ((F_CPU) / 4e3) * __ms;
        if (__tmp < 1.0)
                __ticks = 1;
        else if (__tmp > 65535)
@@ -152,16 +186,50 @@
    If the user requests a delay greater than the maximal possible one,
    _delay_us() will automatically call _delay_ms() instead.  The user
    will not be informed about this case.
+
+   If the avr-gcc toolchain has __builtin_avr_delay_cycles(unsigned long)
+   support, maximal possible delay is 4294967.295 us/ F_CPU in MHz. For
+   values greater than the maximal possible delay, overflow results in
+   no delay i.e., 0us.
+  
+   Conversion of __us into clock cycles may not always result in integer.
+   By default, the clock cycles rounded up to next integer. This ensures that
+   the user gets atleast __us microseconds of delay.
+
+   Alternatively, user can define __DELAY_ROUND_DOWN__ and 
__DELAY_ROUND_CLOSEST__
+   to round down and round to closest integer.
+ 
+   Note: The new implementation of _delay_us(double __us) with 
+    __builtin_avr_delay_cycles(unsigned long) support is not backward 
compatible.
+   User can define __DELAY_BACKWARD_COMPATIBLE__ to get a backward compatible 
delay
+   although this will be deprecated in future.
+
  */
 void
 _delay_us(double __us)
 {
        uint8_t __ticks;
-       double __tmp = ((F_CPU) / 3e6) * __us;
-#if __HAS_DELAY_CYCLES && defined(__OPTIMIZE__)
+       double __tmp ; 
+#if __HAS_DELAY_CYCLES && defined(__OPTIMIZE__) && 
!defined(__DELAY_BACKWARD_COMPATIBLE__)
+       uint32_t __ticks_dc;
        extern void __builtin_avr_delay_cycles(unsigned long);
-       __builtin_avr_delay_cycles(__tmp);
-#else
+       __tmp = ((F_CPU) / 1e6) * __us;
+
+       #if defined(__DELAY_ROUND_DOWN__)
+               __ticks_dc = (uint32_t)fabs(__tmp);
+
+       #elif defined(__DELAY_ROUND_CLOSEST__)
+               __ticks_dc = (uint32_t)(fabs(__tmp)+0.5);
+
+       #else
+               //round up by default
+               __ticks_dc = (uint32_t)(ceil(fabs(__tmp)));
+       #endif
+
+       __builtin_avr_delay_cycles(__ticks_dc);
+
+#elif !__HAS_DELAY_CYCLES || (__HAS_DELAY_CYCLES && !defined(__OPTIMIZE__)) || 
defined (__DELAY_BACKWARD_COMPATIBLE__)
+       __tmp = ((F_CPU) / 3e6) * __us;
        if (__tmp < 1.0)
                __ticks = 1;
        else if (__tmp > 255)




reply via email to

[Prev in Thread] Current Thread [Next in Thread]