Skip to content

Improve optimistic_yield intervals for performance gain in sketches #7952

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

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
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
31 changes: 22 additions & 9 deletions cores/esp8266/core_esp8266_wiring_pulse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,20 @@ extern "C" {

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); \
namespace {
inline __attribute__((always_inline)) bool waitForPinState(
const uint8_t pin, const uint8_t state,
const uint32_t timeout_cycles, const uint32_t start_cycle_count)
{
while (digitalRead(pin) != state) {
if (xthal_get_ccount() - start_cycle_count > timeout_cycles) {
return false;
}
optimistic_yield(1000);
}
return true;
}
}

// 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)
Expand All @@ -43,10 +50,16 @@ unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout)
}
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);
if (!waitForPinState(pin, !state, timeout_cycles, start_cycle_count)) {
return 0;
}
if (!waitForPinState(pin, state, timeout_cycles, start_cycle_count)) {
return 0;
}
const uint32_t pulse_start_cycle_count = xthal_get_ccount();
WAIT_FOR_PIN_STATE(!state);
if (!waitForPinState(pin, !state, timeout_cycles, start_cycle_count)) {
return 0;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is wrong per my reading of the (not so hot docs) https://www.arduino.cc/reference/en/language/functions/advanced-io/pulsein/?setlang=it

Return 0 on no pulse beginning edge detected. OTW, it should return the full timeout as the pulse width (i.e. get rid of the return 0 and just fallthru tho the return below).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@earlephilhower I thought I had answered a long time before. IIRC I researched and besides this refactoring not changing how the return works before, my reading of the docs etc was that returning 0 was and is correct. Hm.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@earlephilhower Can you agree this year; the change is just same effective execution path as with the macros before?

}
return clockCyclesToMicroseconds(xthal_get_ccount() - pulse_start_cycle_count);
}

Expand Down
6 changes: 4 additions & 2 deletions cores/esp8266/uart.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -510,7 +510,10 @@ uart_tx_fifo_full(const int uart_nr)
static void
uart_do_write_char(const int uart_nr, char c)
{
while(uart_tx_fifo_full(uart_nr));
while(uart_tx_fifo_full(uart_nr))
{
optimistic_yield(10000UL);
}

USF(uart_nr) = c;
}
Expand Down Expand Up @@ -544,7 +547,6 @@ uart_write(uart_t* uart, const char* buf, size_t size)
const int uart_nr = uart->uart_nr;
while (size--) {
uart_do_write_char(uart_nr, pgm_read_byte(buf++));
optimistic_yield(10000UL);
}

return ret;
Expand Down
4 changes: 2 additions & 2 deletions libraries/ESP8266WiFi/src/WiFiUdp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ int WiFiUDP::available() {
if (!result) {
// yielding here will not make more data "available",
// but it will prevent the system from going into WDT reset
optimistic_yield(1000);
optimistic_yield(100UL);
}

return result;
Expand Down Expand Up @@ -194,7 +194,7 @@ int WiFiUDP::parsePacket()
return 0;

if (!_ctx->next()) {
optimistic_yield(100);
optimistic_yield(100UL);
return 0;
}

Expand Down
2 changes: 1 addition & 1 deletion libraries/Wire/Wire.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ int TwoWire::available(void)
{
// yielding here will not make more data "available",
// but it will prevent the system from going into WDT reset
optimistic_yield(1000);
optimistic_yield(100UL);
}

return result;
Expand Down