aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid A. Mellis <d.mellis@arduino.cc>2011-12-02 17:04:20 -0500
committerDavid A. Mellis <d.mellis@arduino.cc>2011-12-02 17:04:20 -0500
commitaae9972a2b3fa47b12a99d5c7fea7fd49f51ce4f (patch)
tree6d757ecd642b5bd9dc6a5a2a8390e3088724364a
parent59a3690eb47640767277021e2832a06c2579175e (diff)
Fixing delayMicroseconds() timing for 20 MHz clocks. (Erdem U. Altinyurt)
http://code.google.com/p/arduino/issues/detail?id=306
-rwxr-xr-xcores/arduino/wiring.c20
1 files changed, 19 insertions, 1 deletions
diff --git a/cores/arduino/wiring.c b/cores/arduino/wiring.c
index bc01949..e7f7cde 100755
--- a/cores/arduino/wiring.c
+++ b/cores/arduino/wiring.c
@@ -124,8 +124,26 @@ void delayMicroseconds(unsigned int us)
// calling avrlib's delay_us() function with low values (e.g. 1 or
// 2 microseconds) gives delays longer than desired.
//delay_us(us);
+#if F_CPU >= 20000000L
+ // for the 20 MHz clock on rare Arduino boards
-#if F_CPU >= 16000000L
+ // for a one-microsecond delay, simply wait 2 cycle and return. The overhead
+ // of the function call yields a delay of exactly a one microsecond.
+ __asm__ __volatile__ (
+ "nop" "\n\t"
+ "nop"); //just waiting 2 cycle
+ if (--us == 0)
+ return;
+
+ // the following loop takes a 1/5 of a microsecond (4 cycles)
+ // per iteration, so execute it five times for each microsecond of
+ // delay requested.
+ us = (us<<2) + us; // x5 us
+
+ // account for the time taken in the preceeding commands.
+ us -= 2;
+
+#elif F_CPU >= 16000000L
// for the 16 MHz clock on most Arduino boards
// for a one-microsecond delay, simply return. the overhead