Skip to content

Commit b43d4b0

Browse files
committed
Mitigation logic for ESP8266 SDK boosting to 160MHz during some WiFi ops.
1 parent aa18a70 commit b43d4b0

File tree

1 file changed

+17
-4
lines changed

1 file changed

+17
-4
lines changed

cores/esp8266/core_esp8266_waveform.cpp

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
249262
static 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

Comments
 (0)