8000 Getting the math right beats permanently reducing PWM frequency. · dok-net/arduino-esp8266@b1dece5 · GitHub
[go: up one dir, main page]

Skip to content

Commit b1dece5

Browse files
committed
Getting the math right beats permanently reducing PWM frequency.
1 parent be7d91a commit b1dece5

File tree

1 file changed

+11
-15
lines changed

1 file changed

+11
-15
lines changed

cores/esp8266/core_esp8266_waveform.cpp

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -310,31 +310,31 @@ static ICACHE_RAM_ATTR void timer1Interrupt() {
310310
waveform.enabled ^= 1UL << pin;
311311
}
312312
else {
313+
// get true accumulated overshoot
314+
overshootCcys = now - ((waveform.states & (1UL << pin)) ? wave.nextOffCcy : wave.nextPhaseCcy);
313315
const uint32_t idleCcys = wave.periodCcys - wave.dutyCcys;
314-
const uint32_t fwdPeriods = static_cast<uint32_t>(overshootCcys) >= idleCcys ?
316+
uint32_t fwdPeriods = static_cast<uint32_t>(overshootCcys) >= idleCcys ?
315317
((overshootCcys + wave.dutyCcys) / wave.periodCcys) : 0;
316318
uint32_t nextEdgeCcy;
317319
if (waveform.states & (1UL << pin)) {
318320
const bool endOfPeriod = wave.nextPhaseCcy == wave.nextOffCcy;
319-
if (fwdPeriods) {
320-
wave.nextPhaseCcy += fwdPeriods * wave.periodCcys;
321-
}
322321
if (!idleCcys) {
322+
wave.nextPhaseCcy += (fwdPeriods + 1) * wave.periodCcys;
323323
wave.nextOffCcy = wave.nextPhaseCcy;
324324
nextEdgeCcy = wave.nextPhaseCcy;
325325
}
326326
else if (endOfPeriod) {
327327
// preceeding period had zero idle cycle, continue direct into new duty cycle
328+
wave.nextPhaseCcy += fwdPeriods * wave.periodCcys;
328329
wave.nextOffCcy = wave.nextPhaseCcy + wave.dutyCcys;
329330
wave.nextPhaseCcy += wave.periodCcys;
330331
nextEdgeCcy = wave.nextOffCcy;
331332
}
332333
else if (fwdPeriods) {
333334
// maintain phase, maintain duty/idle ratio, temporarily reduce frequency by skipPeriods
334-
// plus dynamically scale frequency
335-
wave.nextOffCcy = wave.nextPhaseCcy - (fwdPeriods + 1) * idleCcys;
336-
wave.dutyCcys *= 2;
337-
wave.periodCcys *= 2;
335+
fwdPeriods = (now + wave.periodCcys - wave.nextOffCcy) / wave.dutyCcys;
336+
wave.nextOffCcy += fwdPeriods * wave.dutyCcys;
337+
wave.nextPhaseCcy += fwdPeriods * wave.periodCcys;
338338
nextEdgeCcy = wave.nextOffCcy;
339339
}
340340
else {
@@ -350,21 +350,17 @@ static ICACHE_RAM_ATTR void timer1Interrupt() {
350350
}
351351
else {
352352
if (!wave.dutyCcys) {
353-
wave.nextPhaseCcy += wave.periodCcys + fwdPeriods * wave.periodCcys;
353+
wave.nextPhaseCcy += (fwdPeriods + 1) * wave.periodCcys;
354354
wave.nextOffCcy = wave.nextPhaseCcy;
355355
}
356356
else {
357357
waveform.states ^= 1UL << pin;
358358
if (fwdPeriods)
359359
{
360-
const uint32_t fwdPeriodsCcys = fwdPeriods * wave.periodCcys;
361360
// maintain phase, maintain duty/idle ratio, temporarily reduce frequency by skipPeriods
362-
// plus dynamically scale frequency
363361
wave.nextOffCcy =
364-
wave.nextPhaseCcy + fwdPeriods * wave.dutyCcys + (overshootCcys + wave.dutyCcys - fwdPeriodsCcys);
365-
wave.nextPhaseCcy += fwdPeriodsCcys;
366-
wave.dutyCcys *= 2;
367-
wave.periodCcys *= 2;
362+
wave.nextPhaseCcy + (1 * fwdPeriods + 1) * wave.dutyCcys + (overshootCcys + wave.dutyCcys - fwdPeriods * wave.periodCcys);
363+
wave.nextPhaseCcy += (1 * fwdPeriods + 1) * wave.periodCcys;
368364
}
369365
else
370366
{

0 commit comments

Comments
 (0)
0