@@ -170,6 +170,13 @@ static inline ICACHE_RAM_ATTR uint32_t min_u32(uint32_t a, uint32_t b) {
170
170
return b;
171
171
}
172
172
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
+
173
180
// Stops a waveform on a pin
174
181
int ICACHE_RAM_ATTR stopWaveform (uint8_t pin) {
175
182
// Can't possibly need to stop anything if there is no timer active
@@ -261,23 +268,30 @@ static ICACHE_RAM_ATTR void timer1Interrupt() {
261
268
// Check for toggles
262
269
int32_t cyclesToGo = wave->nextServiceCycle - now;
263
270
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)};
264
278
waveformState ^= mask;
265
279
if (waveformState & mask) {
266
280
if (i == 16 ) {
267
281
GP16O |= 1 ; // GPIO16 write slow as it's RMW
268
282
} else {
269
283
SetGPIO (mask);
270
284
}
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 ) ));
273
287
} else {
274
288
if (i == 16 ) {
275
289
GP16O &= ~1 ; // GPIO16 write slow as it's RMW
276
290
} else {
277
291
ClearGPIO (mask);
278
292
}
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 ) ));
281
295
}
282
296
} else {
283
297
uint32_t deltaCycles = wave->nextServiceCycle - now;
0 commit comments