Skip to content

Fix pulseIn #1768

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 30, 2016
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 30 additions & 11 deletions cores/esp8266/core_esp8266_wiring_pulse.c
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
/*
/*
pulse.c - wiring pulseIn implementation for esp8266

Copyright (c) 2015 Hristo Gochkov. All rights reserved.
This file is part of the esp8266 core for Arduino environment.

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
Expand All @@ -18,19 +18,38 @@
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <limits.h>
#include "wiring_private.h"
#include "pins_arduino.h"

unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout) {
pinMode(pin, INPUT);
uint32_t start = micros();
while(digitalRead(pin) == state && (micros() - start) < timeout);
while(digitalRead(pin) != state && (micros() - start) < timeout);
start = micros();
while(digitalRead(pin) == state && (micros() - start) < timeout);
return micros() - start;

extern uint32_t xthal_get_ccount();

#define WAIT_FOR_PIN_STATE(state) \
while (digitalRead(pin) != (state)) { \
if (xthal_get_ccount() - start_cycle_count > timeout_cycles) { \
return 0; \
} \
optimistic_yield(5000); \
}

// max timeout is 27 seconds at 160MHz clock and 54 seconds at 80MHz clock
unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout)
{
const uint32_t max_timeout_us = clockCyclesToMicroseconds(UINT_MAX);
if (timeout > max_timeout_us) {
timeout = max_timeout_us;
}
const uint32_t timeout_cycles = microsecondsToClockCycles(timeout);
const uint32_t start_cycle_count = xthal_get_ccount();
WAIT_FOR_PIN_STATE(!state);
WAIT_FOR_PIN_STATE(state);
const uint32_t pulse_start_cycle_count = xthal_get_ccount();
WAIT_FOR_PIN_STATE(!state);
return clockCyclesToMicroseconds(xthal_get_ccount() - pulse_start_cycle_count);
}

unsigned long pulseInLong(uint8_t pin, uint8_t state, unsigned long timeout) {
unsigned long pulseInLong(uint8_t pin, uint8_t state, unsigned long timeout)
{
return pulseIn(pin, state, timeout);
}