summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore5
-rw-r--r--delay.h264
-rw-r--r--project.h16
3 files changed, 270 insertions, 15 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..4282c5e
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,5 @@
+*.d
+*~
+*.o
+blinky
+blinky.hex
diff --git a/delay.h b/delay.h
new file mode 100644
index 0000000..6f351db
--- /dev/null
+++ b/delay.h
@@ -0,0 +1,264 @@
+/* Copyright (c) 2002, Marek Michalkiewicz
+ Copyright (c) 2004,2005,2007 Joerg Wunsch
+ Copyright (c) 2007 Florin-Viorel Petrov
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+
+ * Neither the name of the copyright holders nor the names of
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE. */
+
+/* $Id: delay.h.in 2251 2011-09-14 08:20:33Z joerg_wunsch $ */
+
+#ifndef _UTIL_DELAY_H_
+#define _UTIL_DELAY_H_ 1
+
+#ifndef __HAS_DELAY_CYCLES
+#define __HAS_DELAY_CYCLES 1
+#endif
+
+#include <inttypes.h>
+#include <util/delay_basic.h>
+#include <math.h>
+
+/** \file */
+/** \defgroup util_delay <util/delay.h>: Convenience functions for busy-wait delay loops
+ \code
+ #define F_CPU 1000000UL // 1 MHz
+ //#define F_CPU 14.7456E6
+ #include <util/delay.h>
+ \endcode
+
+ \note As an alternative method, it is possible to pass the
+ F_CPU macro down to the compiler from the Makefile.
+ Obviously, in that case, no \c \#define statement should be
+ used.
+
+ The functions in this header file are wrappers around the basic
+ busy-wait functions from <util/delay_basic.h>. They are meant as
+ convenience functions where actual time values can be specified
+ rather than a number of cycles to wait for. The idea behind is
+ that compile-time constant expressions will be eliminated by
+ compiler optimization so floating-point expressions can be used
+ to calculate the number of delay cycles needed based on the CPU
+ frequency passed by the macro F_CPU.
+
+ \note In order for these functions to work as intended, compiler
+ optimizations <em>must</em> be enabled, and the delay time
+ <em>must</em> be an expression that is a known constant at
+ compile-time. If these requirements are not met, the resulting
+ delay will be much longer (and basically unpredictable), and
+ applications that otherwise do not use floating-point calculations
+ will experience severe code bloat by the floating-point library
+ routines linked into the application.
+
+ The functions available allow the specification of microsecond, and
+ millisecond delays directly, using the application-supplied macro
+ F_CPU as the CPU clock frequency (in Hertz).
+
+*/
+
+#if !defined(__DOXYGEN__)
+static inline void _delay_us(double __us) __attribute__((always_inline));
+static inline void _delay_ms(double __ms) __attribute__((always_inline));
+#endif
+
+#ifndef F_CPU
+/* prevent compiler error by supplying a default */
+# warning "F_CPU not defined for <util/delay.h>"
+# define F_CPU 1000000UL
+#endif
+
+#ifndef __OPTIMIZE__
+# warning "Compiler optimizations disabled; functions from <util/delay.h> won't work as designed"
+#endif
+
+#if __HAS_DELAY_CYCLES && defined(__OPTIMIZE__) && \
+ !defined(__DELAY_BACKWARD_COMPATIBLE__) && \
+ __STDC_HOSTED__
+# include <math.h>
+#endif
+
+/**
+ \ingroup util_delay
+
+ Perform a delay of \c __ms milliseconds, using _delay_loop_2().
+
+ 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.
+
+ When the user request delay which exceed the maximum possible one,
+ _delay_ms() provides a decreased resolution functionality. In this
+ 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.
+ Also, the backward compatible
+ algorithm will be chosen if the code is compiled in a <em>freestanding
+ environment</em> (GCC option \c -ffreestanding), as the math functions
+ required for rounding are not available to the compiler then.
+
+ */
+static inline void
+_delay_ms(double __ms)
+{
+ double __tmp ;
+#if __HAS_DELAY_CYCLES && defined(__OPTIMIZE__) && \
+ !defined(__DELAY_BACKWARD_COMPATIBLE__) && \
+ __STDC_HOSTED__
+ uint32_t __ticks_dc;
+ extern void __builtin_avr_delay_cycles(unsigned long);
+ __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);
+
+#else
+ uint16_t __ticks;
+ __tmp = ((F_CPU) / 4e3) * __ms;
+ if (__tmp < 1.0)
+ __ticks = 1;
+ else if (__tmp > 65535)
+ {
+ // __ticks = requested delay in 1/10 ms
+ __ticks = (uint16_t) (__ms * 10.0);
+ while(__ticks)
+ {
+ // wait 1/10 ms
+ _delay_loop_2(((F_CPU) / 4e3) / 10);
+ __ticks --;
+ }
+ return;
+ }
+ else
+ __ticks = (uint16_t)__tmp;
+ _delay_loop_2(__ticks);
+#endif
+}
+
+/**
+ \ingroup util_delay
+
+ Perform a delay of \c __us microseconds, using _delay_loop_1().
+
+ 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.
+
+ 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.
+ Also, the backward compatible
+ algorithm will be chosen if the code is compiled in a <em>freestanding
+ environment</em> (GCC option \c -ffreestanding), as the math functions
+ required for rounding are not available to the compiler then.
+
+ */
+static inline void
+_delay_us(double __us)
+{
+ double __tmp ;
+#if __HAS_DELAY_CYCLES && defined(__OPTIMIZE__) && \
+ !defined(__DELAY_BACKWARD_COMPATIBLE__) && \
+ __STDC_HOSTED__
+ uint32_t __ticks_dc;
+ extern void __builtin_avr_delay_cycles(unsigned long);
+ __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);
+
+#else
+ uint8_t __ticks;
+ __tmp = ((F_CPU) / 3e6) * __us;
+ if (__tmp < 1.0)
+ __ticks = 1;
+ else if (__tmp > 255)
+ {
+ _delay_ms(__us / 1000.0);
+ return;
+ }
+ else
+ __ticks = (uint8_t)__tmp;
+ _delay_loop_1(__ticks);
+#endif
+}
+
+
+#endif /* _UTIL_DELAY_H_ */
diff --git a/project.h b/project.h
index 2d542fc..6f7d64b 100644
--- a/project.h
+++ b/project.h
@@ -17,21 +17,7 @@
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
-#ifdef PROTOTYPING
-#define _delay_ms static _delay_ms
-#define _delay_us static _delay_us
-#define _delay_loop_1 static _delay_loop_1
-#define _delay_loop_2 static _delay_loop_2
-#endif
-
-#include <util/delay.h>
-
-#ifdef PROTOTYPING
-#undef _delay_loop_2
-#undef _delay_loop_1
-#undef _delay_us
-#undef _delay_ms
-#endif
+#include "delay.h"
#include "uart.h"