@@ -246,6 +246,19 @@ int ICACHE_RAM_ATTR stopWaveform(uint8_t pin) {
246
246
// Speed critical bits
247
247
#pragma GCC optimize ("O2")
248
248
249
+ // For dynamic CPU clock frequency switch in loop the scaling logic would have to be adapted.
250
+ // Using constexpr makes sure that the CPU clock frequency is compile-time fixed.
251
+ static ICACHE_RAM_ATTR uint32_t __attribute__ ((noinline)) getScaledCcyCount(uint32_t ref) {
252
+ constexpr bool cpuFreq80MHz = clockCyclesPerMicrosecond () == 80 ;
253
+ const uint32_t elapsed = ESP.getCycleCount () - ref;
254
+ if (cpuFreq80MHz) {
255
+ return ref + ((CPU2X & 1 ) ? elapsed >> 1 : elapsed);
256
+ }
257
+ else {
258
+ return ref + ((CPU2X & 1 ) ? elapsed : elapsed << 1 );
259
+ }
260
+ }
261
+
249
262
static ICACHE_RAM_ATTR void timer1Interrupt () {
250
263
const uint32_t isrStartCcy = ESP.getCycleCount ();
251
264
const uint32_t toSetMask = waveform.toSet >= 0 ? 1UL << waveform.toSet : 0 ;
@@ -318,7 +331,7 @@ static ICACHE_RAM_ATTR void timer1Interrupt() {
318
331
while (busyPins) {
319
332
uint32_t now;
320
333
do {
321
- now = ESP. getCycleCount ( );
334
+ now = getScaledCcyCount (isrStartCcy );
322
335
} while (static_cast <int32_t >(isrNextEventCcy - now) > 0 );
323
336
isrNextEventCcy = isrTimeoutCcy;
324
337
do {
@@ -410,21 +423,21 @@ static ICACHE_RAM_ATTR void timer1Interrupt() {
410
423
isrNextEventCcy = wave.nextEventCcy ;
411
424
}
412
425
413
- now = ESP. getCycleCount ( );
426
+ now = getScaledCcyCount (isrStartCcy );
414
427
} while ((pin = (pin < waveform.endPin ) ? pin + 1 : waveform.startPin ) != stopPin);
415
428
}
416
429
417
430
int32_t nextTimerCcys;
418
431
if (waveform.timer1CB ) {
419
432
int32_t callbackCcys = microsecondsToClockCycles (waveform.timer1CB ());
420
433
// Account for unknown duration of timer1CB().
421
- nextTimerCcys = waveform.nextEventCcy - ESP. getCycleCount ( );
434
+ nextTimerCcys = waveform.nextEventCcy - getScaledCcyCount (isrStartCcy );
422
435
if (nextTimerCcys > callbackCcys) {
423
436
nextTimerCcys = callbackCcys;
424
437
}
425
438
}
426
439
else {
427
- nextTimerCcys = waveform.nextEventCcy - ESP. getCycleCount ( );
440
+ nextTimerCcys = waveform.nextEventCcy - getScaledCcyCount (isrStartCcy );
428
441
}
429
442
430
443
// Firing timer too soon, the NMI occurs before ISR has returned.
0 commit comments