Skip to content

Commit 3a2a3cd

Browse files
author
Hadinger
committed
1 parent 25c2a6f commit 3a2a3cd

File tree

1 file changed

+18
-4
lines changed

1 file changed

+18
-4
lines changed

tasmota/core_esp8266_waveform.cpp

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,13 @@ static inline ICACHE_RAM_ATTR uint32_t min_u32(uint32_t a, uint32_t b) {
170170
return b;
171171
}
172172

173+
static inline ICACHE_RAM_ATTR int32_t max_32(int32_t a, int32_t b) {
174+
if (a < b) {
175+
return b;
176+
}
177+
return a;
178+
}
179+
173180
// Stops a waveform on a pin
174181
int ICACHE_RAM_ATTR stopWaveform(uint8_t pin) {
175182
// Can't possibly need to stop anything if there is no timer active
@@ -261,23 +268,30 @@ static ICACHE_RAM_ATTR void timer1Interrupt() {
261268
// Check for toggles
262269
int32_t cyclesToGo = wave->nextServiceCycle - now;
263270
if (cyclesToGo < 0) {
271+
// See #7057
272+
// The following is a no-op unless we have overshot by an entire waveform cycle.
273+
// As modulus is an expensive operation, this code is removed for now:
274+
// cyclesToGo = -((-cyclesToGo) % (wave->nextTimeHighCycles + wave->nextTimeLowCycles));
275+
//
276+
// Alternative version with lower CPU impact:
277+
// while (-cyclesToGo > wave->nextTimeHighCycles + wave->nextTimeLowCycles) { cyclesToGo += wave->nextTimeHighCycles + wave->nextTimeLowCycles)};
264278
waveformState ^= mask;
265279
if (waveformState & mask) {
266280
if (i == 16) {
267281
GP16O |= 1; // GPIO16 write slow as it's RMW
268282
} else {
269283
SetGPIO(mask);
270284
}
271-
wave->nextServiceCycle = now + wave->nextTimeHighCycles + cyclesToGo;
272-
nextEventCycles = min_u32(nextEventCycles, min_u32(wave->nextTimeHighCycles + cyclesToGo, 1));
285+
wave->nextServiceCycle += wave->nextTimeHighCycles;
286+
nextEventCycles = min_u32(nextEventCycles, max_32(wave->nextTimeHighCycles + cyclesToGo, microsecondsToClockCycles(1)));
273287
} else {
274288
if (i == 16) {
275289
GP16O &= ~1; // GPIO16 write slow as it's RMW
276290
} else {
277291
ClearGPIO(mask);
278292
}
279-
wave->nextServiceCycle = now + wave->nextTimeLowCycles + cyclesToGo;
280-
nextEventCycles = min_u32(nextEventCycles, min_u32(wave->nextTimeLowCycles + cyclesToGo, 1));
293+
wave->nextServiceCycle += wave->nextTimeLowCycles;
294+
nextEventCycles = min_u32(nextEventCycles, max_32(wave->nextTimeLowCycles + cyclesToGo, microsecondsToClockCycles(1)));
281295
}
282296
} else {
283297
uint32_t deltaCycles = wave->nextServiceCycle - now;

0 commit comments

Comments
 (0)