aboutsummaryrefslogtreecommitdiff
path: root/cores
diff options
context:
space:
mode:
authorMartino Facchin <m.facchin@arduino.cc>2015-03-02 13:33:50 +0100
committerMartino Facchin <m.facchin@arduino.cc>2015-05-29 15:01:37 +0200
commit6940c1d64454c4550d41d5dc14fea2ca5963c231 (patch)
tree6b14aaba46030286fd51a4fb72881dbd32a60d43 /cores
parent2bac15c63d519a4b7eeba4d8e6c0407056986a68 (diff)
pulseIn: modify function to use ASM implementation
Diffstat (limited to 'cores')
-rw-r--r--cores/arduino/wiring_private.h2
-rw-r--r--cores/arduino/wiring_pulse.c37
2 files changed, 12 insertions, 27 deletions
diff --git a/cores/arduino/wiring_private.h b/cores/arduino/wiring_private.h
index 5dc7d4b..3bd2900 100644
--- a/cores/arduino/wiring_private.h
+++ b/cores/arduino/wiring_private.h
@@ -43,6 +43,8 @@ extern "C"{
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif
+uint32_t countPulseASM(volatile uint8_t *port, uint8_t bit, uint8_t stateMask, unsigned long maxloops);
+
#define EXTERNAL_INT_0 0
#define EXTERNAL_INT_1 1
#define EXTERNAL_INT_2 2
diff --git a/cores/arduino/wiring_pulse.c b/cores/arduino/wiring_pulse.c
index 0d96886..2ac6988 100644
--- a/cores/arduino/wiring_pulse.c
+++ b/cores/arduino/wiring_pulse.c
@@ -28,7 +28,10 @@
/* Measures the length (in microseconds) of a pulse on the pin; state is HIGH
* or LOW, the type of pulse to measure. Works on pulses from 2-3 microseconds
* to 3 minutes in length, but must be called at least a few dozen microseconds
- * before the start of the pulse. */
+ * before the start of the pulse.
+ *
+ * This function performs better with short pulses in noInterrupt() context
+ */
unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout)
{
// cache the port and bit of the pin in order to speed up the
@@ -38,32 +41,12 @@ unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout)
uint8_t port = digitalPinToPort(pin);
uint8_t stateMask = (state ? bit : 0);
unsigned long width = 0; // keep initialization out of time critical area
-
+
// convert the timeout from microseconds to a number of times through
- // the initial loop; it takes 16 clock cycles per iteration.
+ // the initial loop; it takes approximately 16 clock cycles per iteration
unsigned long numloops = 0;
- unsigned long maxloops = microsecondsToClockCycles(timeout) / 16;
-
- // wait for any previous pulse to end
- while ((*portInputRegister(port) & bit) == stateMask)
- if (numloops++ == maxloops)
- return 0;
-
- // wait for the pulse to start
- while ((*portInputRegister(port) & bit) != stateMask)
- if (numloops++ == maxloops)
- return 0;
-
- // wait for the pulse to stop
- while ((*portInputRegister(port) & bit) == stateMask) {
- if (numloops++ == maxloops)
- return 0;
- width++;
- }
+ unsigned long maxloops = microsecondsToClockCycles(timeout)/16;
- // convert the reading to microseconds. The loop has been determined
- // to be 20 clock cycles long and have about 16 clocks between the edge
- // and the start of the loop. There will be some error introduced by
- // the interrupt handlers.
- return clockCyclesToMicroseconds(width * 21 + 16);
-}
+ width = countPulseASM(portInputRegister(port), bit, stateMask, maxloops);
+ return clockCyclesToMicroseconds(width * 16 + 16);
+} \ No newline at end of file