@@ -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
174181int 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