mirror of
https://github.com/wled/WLED.git
synced 2025-07-25 19:56:32 +00:00
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.
This commit is contained in:
parent
cb8dae1ddb
commit
d37ee89e84
@ -324,7 +324,7 @@ static IRAM_ATTR void timer1Interrupt() {
|
|||||||
case WaveformMode::INIT:
|
case WaveformMode::INIT:
|
||||||
waveform.states &= ~waveform.toSetBits; // Clear the state of any just started
|
waveform.states &= ~waveform.toSetBits; // Clear the state of any just started
|
||||||
if (waveform.alignPhase >= 0 && waveform.enabled & (1UL << waveform.alignPhase)) {
|
if (waveform.alignPhase >= 0 && waveform.enabled & (1UL << waveform.alignPhase)) {
|
||||||
wave.nextPeriodCcy = waveform.pins[waveform.alignPhase].nextPeriodCcy + wave.nextPeriodCcy;
|
wave.nextPeriodCcy = waveform.pins[waveform.alignPhase].nextPeriodCcy + scaleCcys(waveform.phaseCcy, isCPU2X);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
wave.nextPeriodCcy = waveform.nextEventCcy;
|
wave.nextPeriodCcy = waveform.nextEventCcy;
|
||||||
@ -342,15 +342,15 @@ static IRAM_ATTR void timer1Interrupt() {
|
|||||||
// @willmmiles new feature
|
// @willmmiles new feature
|
||||||
case WaveformMode::UPDATEPHASE:
|
case WaveformMode::UPDATEPHASE:
|
||||||
// in WaveformMode::UPDATEPHASE, we recalculate the targets
|
// in WaveformMode::UPDATEPHASE, we recalculate the targets
|
||||||
if (waveform.alignPhase >= 0 && waveform.enabled & (1UL << waveform.alignPhase)) {
|
if ((waveform.alignPhase >= 0) && (waveform.enabled & (1UL << waveform.alignPhase))) {
|
||||||
// Compute phase shift to realign with target
|
// Compute phase shift to realign with target
|
||||||
auto& align_wave = waveform.pins[waveform.alignPhase];
|
auto const newPeriodCcy = waveform.pins[waveform.alignPhase].nextPeriodCcy + scaleCcys(waveform.phaseCcy, isCPU2X);
|
||||||
int32_t shift = static_cast<int32_t>(align_wave.nextPeriodCcy + scaleCcys(waveform.phaseCcy, isCPU2X) - wave.nextPeriodCcy);
|
auto const period = scaleCcys(wave.periodCcys, isCPU2X);
|
||||||
const int32_t periodCcys = scaleCcys(wave.periodCcys, isCPU2X);
|
auto shift = ((static_cast<int32_t> (newPeriodCcy - wave.nextPeriodCcy) + period/2) % period) - (period/2);
|
||||||
if (shift > periodCcys/2) shift -= periodCcys;
|
wave.nextPeriodCcy += static_cast<uint32_t>(shift);
|
||||||
else if (shift <= -periodCcys/2) shift += periodCcys;
|
if (static_cast<int32_t>(wave.endDutyCcy - wave.nextPeriodCcy) > 0) {
|
||||||
wave.nextPeriodCcy += shift;
|
wave.endDutyCcy = wave.nextPeriodCcy;
|
||||||
wave.endDutyCcy += shift;
|
}
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user