Skip to content

Commit d37ee89

Browse files
committed
ESP8266PWM: Fix phase shift glitches
In some cases it was possible for the computed phase shift to skip a cycle. Update the shift calculation logic to prevent this.
1 parent cb8dae1 commit d37ee89

File tree

1 file changed

+9
-9
lines changed

1 file changed

+9
-9
lines changed

lib/ESP8266PWM/src/core_esp8266_waveform_phase.cpp

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -324,7 +324,7 @@ static IRAM_ATTR void timer1Interrupt() {
324324
case WaveformMode::INIT:
325325
waveform.states &= ~waveform.toSetBits; // Clear the state of any just started
326326
if (waveform.alignPhase >= 0 && waveform.enabled & (1UL << waveform.alignPhase)) {
327-
wave.nextPeriodCcy = waveform.pins[waveform.alignPhase].nextPeriodCcy + wave.nextPeriodCcy;
327+
wave.nextPeriodCcy = waveform.pins[waveform.alignPhase].nextPeriodCcy + scaleCcys(waveform.phaseCcy, isCPU2X);
328328
}
329329
else {
330330
wave.nextPeriodCcy = waveform.nextEventCcy;
@@ -342,15 +342,15 @@ static IRAM_ATTR void timer1Interrupt() {
342342
// @willmmiles new feature
343343
case WaveformMode::UPDATEPHASE:
344344
// in WaveformMode::UPDATEPHASE, we recalculate the targets
345-
if (waveform.alignPhase >= 0 && waveform.enabled & (1UL << waveform.alignPhase)) {
345+
if ((waveform.alignPhase >= 0) && (waveform.enabled & (1UL << waveform.alignPhase))) {
346346
// Compute phase shift to realign with target
347-
auto& align_wave = waveform.pins[waveform.alignPhase];
348-
int32_t shift = static_cast<int32_t>(align_wave.nextPeriodCcy + scaleCcys(waveform.phaseCcy, isCPU2X) - wave.nextPeriodCcy);
349-
const int32_t periodCcys = scaleCcys(wave.periodCcys, isCPU2X);
350-
if (shift > periodCcys/2) shift -= periodCcys;
351-
else if (shift <= -periodCcys/2) shift += periodCcys;
352-
wave.nextPeriodCcy += shift;
353-
wave.endDutyCcy += shift;
347+
auto const newPeriodCcy = waveform.pins[waveform.alignPhase].nextPeriodCcy + scaleCcys(waveform.phaseCcy, isCPU2X);
348+
auto const period = scaleCcys(wave.periodCcys, isCPU2X);
349+
auto shift = ((static_cast<int32_t> (newPeriodCcy - wave.nextPeriodCcy) + period/2) % period) - (period/2);
350+
wave.nextPeriodCcy += static_cast<uint32_t>(shift);
351+
if (static_cast<int32_t>(wave.endDutyCcy - wave.nextPeriodCcy) > 0) {
352+
wave.endDutyCcy = wave.nextPeriodCcy;
353+
}
354354
}
355355
default:
356356
break;

0 commit comments

Comments
 (0)