8000 Simplify calculations, fix non-autoPwm for servo use, where exact dut… · dok-net/arduino-esp8266@0b707cd · GitHub
[go: up one dir, main page]

Skip to content

Commit 0b707cd

Browse files
committed
Simplify calculations, fix non-autoPwm for servo use, where exact duty is needed, idle is elastic.
1 parent 08e8675 commit 0b707cd

File tree

1 file changed

+21
-18
lines changed

1 file changed

+21
-18
lines changed

cores/esp8266/core_esp8266_waveform.cpp

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ constexpr uint32_t ISRTIMEOUTCCYS = microsecondsToClockCycles(14);
5454
// decrement the next IRQ's timer value by a bit so we can actually catch the
5555
// real CPU cycle count we want for the waveforms.
5656
constexpr int32_t DELTAIRQ = clockCyclesPerMicrosecond() == 160 ?
57-
microsecondsToClockCycles(3) >> 1 : microsecondsToClockCycles(3);
57+
microsecondsToClockCycles(4) >> 1 : microsecondsToClockCycles(4);
5858
// The latency between in-ISR rearming of the timer and the earliest firing
5959
constexpr int32_t IRQLATENCY = clockCyclesPerMicrosecond() == 160 ?
6060
microsecondsToClockCycles(3) >> 1 : microsecondsToClockCycles(3);
@@ -306,18 +306,16 @@ static ICACHE_RAM_ATTR void timer1Interrupt() {
306306
waveform.enabled ^= 1UL << pin;
307307
}
308308
else {
309+
const uint32_t idleCcys = wave.periodCcys - wave.dutyCcys;
309310
// get true accumulated overshoot
310311
overshootCcys = now - ((waveform.states & (1UL << pin)) ? wave.endDutyCcy : wave.nextPeriodCcy);
311-
const uint32_t idleCcys = wave.periodCcys - wave.dutyCcys;
312312
uint32_t fwdPeriods = static_cast<uint32_t>(overshootCcys) >= idleCcys ?
313313
((overshootCcys + wave.dutyCcys) / wave.periodCcys) : 0;
314-
if (fwdPeriods && !wave.autoPwm) {
315-
// for best effort hard timings - allow only limited duty cycle floating
316-
fwdPeriods = 0;
317-
overshootCcys = 0;
318-
}
319314
uint32_t nextEdgeCcy;
320315
if (waveform.states & (1UL << pin)) {
316+
if (!wave.autoPwm) {
317+
overshootCcys = 0;
318+
}
321319
// up to and including this period 100% duty
322320
const bool endOfPeriod = wave.nextPeriodCcy == wave.endDutyCcy;
323321
// active configuration and forward 100% duty
@@ -328,7 +326,12 @@ static ICACHE_RAM_ATTR void timer1Interrupt() {
328326
}
329327
else if (endOfPeriod) {
330328
// preceeding period had zero idle cycle, continue direct into new duty cycle
331-
wave.nextPeriodCcy += fwdPeriods * wave.periodCcys;
329+
if (fwdPeriods) {
330+
wave.nextPeriodCcy += fwdPeriods * wave.periodCcys;
331+
// adapt expiry such that it occurs during intended cycle
332+
if (WaveformMode::EXPIRES == wave.mode)
333+
wave.expiryCcy += fwdPeriods * wave.periodCcys;
334+
}
332335
wave.endDutyCcy = wave.nextPeriodCcy + wave.dutyCcys;
333336
wave.nextPeriodCcy += wave.periodCcys;
334337
nextEdgeCcy = wave.endDutyCcy;
@@ -352,18 +355,18 @@ static ICACHE_RAM_ATTR void timer1Interrupt() {
352355
}
353356
else {
354357
waveform.states ^= 1UL << pin;
358+
wave.endDutyCcy = now + wave.dutyCcys;
359+
wave.nextPeriodCcy += wave.periodCcys;
355360
if (fwdPeriods)
356361
{
357-
// maintain phase, maintain duty/idle ratio, temporarily reduce frequency by fwdPeriods
358-
wave.endDutyCcy =
359-
wave.nextPeriodCcy + (fwdPeriods + 1) * wave.dutyCcys +
360-
(overshootCcys + wave.dutyCcys - fwdPeriods * wave.periodCcys);
361-
wave.nextPeriodCcy += (fwdPeriods + 1) * wave.periodCcys;
362-
}
363-
else
364-
{
365-
wave.endDutyCcy = wave.nextPeriodCcy + wave.dutyCcys + overshootCcys;
366-
wave.nextPeriodCcy += wave.periodCcys;
362+
if (wave.autoPwm) {
363+
// maintain phase, maintain duty/idle ratio, temporarily reduce frequency by fwdPeriods
364+
wave.endDutyCcy += (fwdPeriods + 1) * wave.dutyCcys - fwdPeriods * wave.periodCcys;
365+
}
366+
wave.nextPeriodCcy += fwdPeriods * wave.periodCcys;
367+
// adapt expiry such that it occurs during intended cycle
368+
if (WaveformMode::EXPIRES == wave.mode)
369+
wave.expiryCcy += fwdPeriods * wave.periodCcys;
367370
}
368371
if (pin == 16) {
369372
GP16O |= 1; // GPIO16 write slow as it's RMW

0 commit comments

Comments
 (0)
0