From 233224d8643fa5b48e874c3320718d157348bdeb Mon Sep 17 00:00:00 2001 From: "Earle F. Philhower, III" Date: Wed, 11 Jul 2018 19:31:08 -0700 Subject: [PATCH] Optimize waveform stop routines Thanks to ideas from @shimarin for offering ideas to speed up the stopWaveform calls which may help things like SoftwareSerial run better. Optimize the stopWaveform routine to abort fast and early whenever possible. Remove the stopWaveform call from digitalRead(). If you're running a waveform on a pin and try to read it, that is a logic error and you'll end up reading the waveform and not the outside world's view of the pin. --- cores/esp8266/core_esp8266_waveform.c | 18 +++++++++++++----- cores/esp8266/core_esp8266_wiring_digital.c | 1 - 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/cores/esp8266/core_esp8266_waveform.c b/cores/esp8266/core_esp8266_waveform.c index 1d703515d7..360730bbdf 100644 --- a/cores/esp8266/core_esp8266_waveform.c +++ b/cores/esp8266/core_esp8266_waveform.c @@ -63,8 +63,8 @@ typedef struct { uint32_t nextServiceCycle; // ESP cycle timer when a transition required uint32_t timeLeftCycles; // For time-limited waveform, how many ESP cycles left - uint16_t gpioMask; // Mask instead of value to speed IRQ loop - uint16_t gpio16Mask; // Mask instead of value to speed IRQ loop + const uint16_t gpioMask; // Mask instead of value to speed IRQ loop + const uint16_t gpio16Mask; // Mask instead of value to speed IRQ loop unsigned state : 1; // Current state of this pin unsigned nextTimeHighCycles : 31; // Copy over low->high to keep smooth waveform unsigned enabled : 1; // Is this GPIO generating a waveform? @@ -204,13 +204,21 @@ int startWaveform(uint8_t pin, uint32_t timeHighUS, uint32_t timeLowUS, uint32_t // Stops a waveform on a pin int stopWaveform(uint8_t pin) { + // Can't possibly need to stop anything if there is no timer active + if (!timerRunning) { + return false; + } + for (size_t i = 0; i < countof(waveform); i++) { - if ((((pin == 16) && waveform[i].gpio16Mask) || ((pin != 16) && (waveform[i].gpioMask == 1<0 // We're also doing that, so even if an IRQ occurred it would still stay as 0. waveform[i].enabled = 0; - int cnt = timer1CB?1:0; - for (size_t i = 0; i < countof(waveform); i++) { + int cnt = timer1CB ? 1 : 0; + for (size_t i = 0; (cnt == 0) && (i < countof(waveform)); i++) { cnt += waveform[i].enabled ? 1 : 0; } if (!cnt) { diff --git a/cores/esp8266/core_esp8266_wiring_digital.c b/cores/esp8266/core_esp8266_wiring_digital.c index b15d481f96..1954b3a1a2 100644 --- a/cores/esp8266/core_esp8266_wiring_digital.c +++ b/cores/esp8266/core_esp8266_wiring_digital.c @@ -89,7 +89,6 @@ extern void ICACHE_RAM_ATTR __digitalWrite(uint8_t pin, uint8_t val) { } extern int ICACHE_RAM_ATTR __digitalRead(uint8_t pin) { - stopWaveform(pin); if(pin < 16){ return GPIP(pin); } else if(pin == 16){