@@ -246,6 +246,19 @@ int ICACHE_RAM_ATTR stopWaveform(uint8_t pin) {
246246// Speed critical bits
247247#pragma GCC optimize ("O2")
248248
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+
249262static ICACHE_RAM_ATTR void timer1Interrupt () {
250263 const uint32_t isrStartCcy = ESP.getCycleCount ();
251264 const uint32_t toSetMask = waveform.toSet >= 0 ? 1UL << waveform.toSet : 0 ;
@@ -318,7 +331,7 @@ static ICACHE_RAM_ATTR void timer1Interrupt() {
318331 while (busyPins) {
319332 uint32_t now;
320333 do {
321- now = ESP. getCycleCount ( );
334+ now = getScaledCcyCount (isrStartCcy );
322335 } while (static_cast <int32_t >(isrNextEventCcy - now) > 0 );
323336 isrNextEventCcy = isrTimeoutCcy;
324337 do {
@@ -410,21 +423,21 @@ static ICACHE_RAM_ATTR void timer1Interrupt() {
410423 isrNextEventCcy = wave.nextEventCcy ;
411424 }
412425
413- now = ESP. getCycleCount ( );
426+ now = getScaledCcyCount (isrStartCcy );
414427 } while ((pin = (pin < waveform.endPin ) ? pin + 1 : waveform.startPin ) != stopPin);
415428 }
416429
417430 int32_t nextTimerCcys;
418431 if (waveform.timer1CB ) {
419432 int32_t callbackCcys = microsecondsToClockCycles (waveform.timer1CB ());
420433 // Account for unknown duration of timer1CB().
421- nextTimerCcys = waveform.nextEventCcy - ESP. getCycleCount ( );
434+ nextTimerCcys = waveform.nextEventCcy - getScaledCcyCount (isrStartCcy );
422435 if (nextTimerCcys > callbackCcys) {
423436 nextTimerCcys = callbackCcys;
424437 }
425438 }
426439 else {
427- nextTimerCcys = waveform.nextEventCcy - ESP. getCycleCount ( );
440+ nextTimerCcys = waveform.nextEventCcy - getScaledCcyCount (isrStartCcy );
428441 }
429442
430443 // Firing timer too soon, the NMI occurs before ISR has returned.
0 commit comments