Skip to content

Commit fcf2ac5

Browse files
Optimize waveform stop routines (#4920)
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.
1 parent 60b21ef commit fcf2ac5

File tree

2 files changed

+13
-6
lines changed

2 files changed

+13
-6
lines changed

cores/esp8266/core_esp8266_waveform.c

+13-5
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,8 @@
6363
typedef struct {
6464
uint32_t nextServiceCycle; // ESP cycle timer when a transition required
6565
uint32_t timeLeftCycles; // For time-limited waveform, how many ESP cycles left
66-
uint16_t gpioMask; // Mask instead of value to speed IRQ loop
67-
uint16_t gpio16Mask; // Mask instead of value to speed IRQ loop
66+
const uint16_t gpioMask; // Mask instead of value to speed IRQ loop
67+
const uint16_t gpio16Mask; // Mask instead of value to speed IRQ loop
6868
unsigned state : 1; // Current state of this pin
6969
unsigned nextTimeHighCycles : 31; // Copy over low->high to keep smooth waveform
7070
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
204204

205205
// Stops a waveform on a pin
206206
int stopWaveform(uint8_t pin) {
207+
// Can't possibly need to stop anything if there is no timer active
208+
if (!timerRunning) {
209+
return false;
210+
}
211+
207212
for (size_t i = 0; i < countof(waveform); i++) {
208-
if ((((pin == 16) && waveform[i].gpio16Mask) || ((pin != 16) && (waveform[i].gpioMask == 1<<pin))) && waveform[i].enabled) {
213+
if (!waveform[i].enabled) {
214+
continue; // Skip fast to next one, can't need to stop this one since it's not running
215+
}
216+
if (((pin == 16) && waveform[i].gpio16Mask) || ((pin != 16) && (waveform[i].gpioMask == 1<<pin))) {
209217
// Note that there is no interrupt unsafety here. The IRQ can only ever change .enabled from 1->0
210218
// We're also doing that, so even if an IRQ occurred it would still stay as 0.
211219
waveform[i].enabled = 0;
212-
int cnt = timer1CB?1:0;
213-
for (size_t i = 0; i < countof(waveform); i++) {
220+
int cnt = timer1CB ? 1 : 0;
221+
for (size_t i = 0; (cnt == 0) && (i < countof(waveform)); i++) {
214222
cnt += waveform[i].enabled ? 1 : 0;
215223
}
216224
if (!cnt) {

cores/esp8266/core_esp8266_wiring_digital.c

-1
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,6 @@ extern void ICACHE_RAM_ATTR __digitalWrite(uint8_t pin, uint8_t val) {
8989
}
9090

9191
extern int ICACHE_RAM_ATTR __digitalRead(uint8_t pin) {
92-
stopWaveform(pin);
9392
if(pin < 16){
9493
return GPIP(pin);
9594
} else if(pin == 16){

0 commit comments

Comments
 (0)