Skip to content

Commit 32c6176

Browse files
committed
Fix pulseIn (#1072, #1149)
- fix return value on timeout - add optimistic_yield to allow WiFi/network tasks to run - use ccount instead of micros (which causes an integer division on every call)
1 parent 652703e commit 32c6176

File tree

1 file changed

+30
-11
lines changed

1 file changed

+30
-11
lines changed
+30-11
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
/*
1+
/*
22
pulse.c - wiring pulseIn implementation for esp8266
33
44
Copyright (c) 2015 Hristo Gochkov. All rights reserved.
55
This file is part of the esp8266 core for Arduino environment.
6-
6+
77
This library is free software; you can redistribute it and/or
88
modify it under the terms of the GNU Lesser General Public
99
License as published by the Free Software Foundation; either
@@ -18,19 +18,38 @@
1818
License along with this library; if not, write to the Free Software
1919
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
2020
*/
21+
#include <limits.h>
2122
#include "wiring_private.h"
2223
#include "pins_arduino.h"
2324

24-
unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout) {
25-
pinMode(pin, INPUT);
26-
uint32_t start = micros();
27-
while(digitalRead(pin) == state && (micros() - start) < timeout);
28-
while(digitalRead(pin) != state && (micros() - start) < timeout);
29-
start = micros();
30-
while(digitalRead(pin) == state && (micros() - start) < timeout);
31-
return micros() - start;
25+
26+
extern uint32_t xthal_get_ccount();
27+
28+
#define WAIT_FOR_PIN_STATE(state) \
29+
while (digitalRead(pin) != (state)) { \
30+
if (xthal_get_ccount() - start_cycle_count > timeout_cycles) { \
31+
return 0; \
32+
} \
33+
optimistic_yield(5000); \
34+
}
35+
36+
// max timeout is 27 seconds at 160MHz clock and 54 seconds at 80MHz clock
37+
unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout)
38+
{
39+
const uint32_t max_timeout_us = clockCyclesToMicroseconds(UINT_MAX);
40+
if (timeout > max_timeout_us) {
41+
timeout = max_timeout_us;
42+
}
43+
const uint32_t timeout_cycles = microsecondsToClockCycles(timeout);
44+
const uint32_t start_cycle_count = xthal_get_ccount();
45+
WAIT_FOR_PIN_STATE(!state);
46+
WAIT_FOR_PIN_STATE(state);
47+
const uint32_t pulse_start_cycle_count = xthal_get_ccount();
48+
WAIT_FOR_PIN_STATE(!state);
49+
return clockCyclesToMicroseconds(xthal_get_ccount() - pulse_start_cycle_count);
3250
}
3351

34-
unsigned long pulseInLong(uint8_t pin, uint8_t state, unsigned long timeout) {
52+
unsigned long pulseInLong(uint8_t pin, uint8_t state, unsigned long timeout)
53+
{
3554
return pulseIn(pin, state, timeout);
3655
}

0 commit comments

Comments
 (0)