Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"Phase Locked" Waveform: fix significant jitter, that stresses servos and is clearly audible in Tone output #7022

Merged
merged 153 commits into from
Nov 19, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
153 commits
Select commit Hold shift + click to select a range
3f36f6f
Allow 100% high or low periods.
dok-net Jan 6, 2020
ee3ca86
Fix serious jitter issues in previous versions.
dok-net Jan 7, 2020
233e5f1
Use ESP.getCycleCount() just like everyone else.
dok-net Jan 7, 2020
c462fe0
Highest timer rate at which this runs stable appears to be 2µs (500kHz).
dok-net Jan 7, 2020
a97f247
Guard for zero period length undefined waveforms.
dok-net Jan 7, 2020
a2c7125
Cycle precision for expiry instead of special treatment for 0 value.
dok-net Jan 8, 2020
b2e9ad7
Give expiry proper precedence over updating a waveform
dok-net Jan 8, 2020
6eb28d3
Important comment
dok-net Feb 6, 2020
da049c1
Refactored, identical behavior.
dok-net Feb 6, 2020
1178268
Use plural for bit arrays.
dok-net Feb 6, 2020
3fbaaa8
Fix for completely duty or all off cycle period case.
dok-net Feb 7, 2020
01c5f7a
Expiration is explicitly relative to service time.
dok-net Feb 7, 2020
b255655
Comment updated, here it's about cycles not usecs.
dok-net Feb 8, 2020
7b99b85
Revert misconception of how waveformToEnable/Disable communicates wit…
dok-net Feb 9, 2020
22556f0
Rewrite to keep phase in sync if period remains same during duty cycl…
dok-net Feb 9, 2020
0f4486b
Rather iterate even if full-duty or no-duty cycle in period, than too…
dok-net Feb 11, 2020
37b0685
Must fire timer early to reach waveform deadlines, otherwise under so…
dok-net Feb 11, 2020
0a2415d
Schedule expiry explicitly, too.
dok-net Feb 11, 2020
b595e49
Quick change lets analogWrite keep phase for any duty cycle (includin…
dok-net Feb 15, 2020
e0d9a48
Set duration to multiple of period, so tone stops on LOW pin output.
dok-net Feb 20, 2020
bb04a02
Improve phase timing
dok-net Feb 26, 2020
8c646f3
Eror causing next Timer IRQ to fail busy-to-off cycle transitions.
dok-net Mar 1, 2020
8ab9975
Regression fix, don't reset timer if pending shortly.
dok-net Mar 2, 2020
acd0dcd
Rather reschedule ISR instead of busy looping during permitted maximu…
dok-net Mar 2, 2020
87b71c2
Lead time improved for ISR
dok-net Mar 2, 2020
2bae205
Reduce number of cycle calculations.
dok-net Mar 2, 2020
deaf2ec
Reactive the gcc optimize pragmas.
dok-net Mar 2, 2020
d8e330e
Simplify calculation.
dok-net Mar 6, 2020
da933fd
handles overshoot where an updated period is shorter than the previou…
dok-net Mar 6, 2020
6c7346a
Misleading code, there must ever be only one bit set at a time, start…
dok-net Mar 7, 2020
f6fbf80
Prevent missing a duty cycle unless it is overshot already.
dok-net Mar 8, 2020
745c1b2
Continuously remove distant pending waveform edges from the loop, con…
dok-net Mar 9, 2020
b877047
Replace volatile for one-way exchange into ISR with memory fence.
dok-net Mar 9, 2020
42983a9
Remove redundant stack object.
dok-net Mar 9, 2020
6aea9d6
Revert pending waveform removal from loop - corrupts continuous next …
dok-net Mar 9, 2020
9245e19
Reduce if/do ... while to while
dok-net Mar 22, 2020
42a065d
Convert relative timings to absolute.
dok-net Mar 23, 2020
02e5233
Relax waveform start to possibly cluster phases into same IRQ interval.
dok-net Mar 23, 2020
b68d3cb
max 12us in ISR seems to work best for servo/fan/led/tone combo test.
dok-net Mar 23, 2020
2bc599f
Restructured code in ISR for expiration, this saves 36 byte IRAM, and…
dok-net Mar 29, 2020
aab4a49
Simplified overshot detection and 0% / 100% duty cycle.
dok-net Mar 29, 2020
5a91f9f
Leave ISR early if rescheduling is more promising than busy-waiting u…
dok-net Mar 30, 2020
6395373
Stabilized timings.
dok-net Mar 31, 2020
4984f49
Prevent WDT under load.
dok-net Apr 2, 2020
eb28b27
Use clock cycle resolution instead of us for analogWrite.
dok-net Apr 6, 2020
3155888
Reduce idle calculations in ISR.
dok-net Apr 7, 2020
6c43c0d
Optimize in-ISR time.
dok-net Apr 7, 2020
14444a9
Support starting new waveform in phase with another running waveform.
dok-net Apr 8, 2020
48f6d85
Align phase for analogWrite PWMs.
dok-net Apr 8, 2020
ac832a7
Tune preshoot, add lost period fast forward.
dok-net Apr 8, 2020
94626e8
Adapt phase sync code from analogWrite to Servo
dok-net Apr 9, 2020
ef5fdd0
Fix for going off 100% duty cycle period.
dok-net Apr 9, 2020
59d788b
Eschew obfuscation.
dok-net Apr 10, 2020
1057256
Fixed logic for zero duty cycle.
dok-net Apr 10, 2020
3d99249
Determine generator quantum during same IRQ - this is better than tim…
dok-net Apr 11, 2020
d92a737
Tune timings, fix write barriers and overshoot logic.
dok-net Apr 12, 2020
560cca7
Migrate Tone to waveform with CPU cycle precision
dok-net Apr 13, 2020
c75d1bd
Can do 60kHz PWM.
dok-net Apr 14, 2020
a2222e8
Recalibrated timings after performance optimizations.
dok-net Apr 15, 2020
6ab789c
Fix regression for waveform runtime.
dok-net Apr 15, 2020
ac21bca
Test cycle duration values for signed arithmetic safety.
dok-net Apr 16, 2020
7a4bb61
Performance tuning.
dok-net Apr 16, 2020
ba47d27
Performance tweak, in-ISR quantum is now 1.12µs.
dok-net Apr 16, 2020
1c4de11
Round up duration instead of down - possibly to zero, which means for…
dok-net Apr 17, 2020
a9565b2
Extend phase alignment with optional phase offset.
dok-net Apr 19, 2020
a3c0dfe
Slightly better in-ISR quantum approximation for steadier increments.
dok-net Apr 19, 2020
bd0fea0
Waveform stopped by runtime limit in iSR doesn't deinit the timer, bu…
dok-net Apr 19, 2020
9f5743c
Improved quantum correction code.
dok-net Apr 20, 2020
9d29fc2
Fix broken multi-wave generation.
dok-net Apr 20, 2020
244153e
Aggregate GPIO output across inner loop. True phase sync, and now bet…
dok-net Apr 21, 2020
e149284
IRQ latency can be reduced from 2 to 1 us now, no WDT etc.
dok-net Apr 21, 2020
ab70633
Improved handling of complete idle cycle miss, progress directly into…
dok-net Apr 21, 2020
4ba59dc
Recalibrated after latest changes and reverts.
dok-net Apr 22, 2020
a3bf761
Overshoot compensation for duty cycle results in PWM milestone.
dok-net Apr 22, 2020
e2fe477
Adjustments to duty/idle cycle to mitigate effects of floating duty c…
dok-net Apr 22, 2020
3286bf7
Remove implicit condition from loop guard and fix timer restart duration
dok-net Apr 22, 2020
237bdfd
Host all static globals in an anonymous static struct.
dok-net Apr 22, 2020
6e352ea
Busy wait directly for next pending event and go to that pin.
dok-net Apr 22, 2020
5b6be8b
Record nextEventCcy in waveform struct to save a few cycles.
dok-net Apr 22, 2020
25dbff5
Adapt duty cycle modification to only fix full duty and all idle cases.
dok-net Apr 22, 2020
9f79f43
Remember next pin to operate between IRQs.
dok-net Apr 23, 2020
936985e
Don't set pinMode each time on already running PWM or Tone.
dok-net Apr 23, 2020
5fc33d0
Remove quantum, correct irq latency from testing,reuse isr timeout fr…
dok-net Apr 23, 2020
a235066
Move updating "now" out of inner loop, prevents float between pins th…
dok-net Apr 23, 2020
b0bf144
Merge init loop with action loop again.
dok-net Apr 23, 2020
948601c
Adaptive PWM frequency and floating duty cycle.
dok-net Apr 23, 2020
9445755
Predictive static frequency scaling.
dok-net Apr 24, 2020
0ec53e4
Dynamic frequency down-scaling
dok-net Apr 24, 2020
1d0f914
Frequency scaling is only for PWM-like applications, anything needing…
dok-net Apr 24, 2020
f8e07f5
Conserve IRAM cache, resort to best effort.
dok-net Apr 24, 2020
ea01c25
Directly scale frequency for all duty/all idle waves to reasonable ma…
dok-net Apr 24, 2020
d17a7b9
Getting the math right beats permanently reducing PWM frequency.
dok-net Apr 25, 2020
2ff07a1
Rename identifier to help think about the problem.
dok-net Apr 25, 2020
a07f12c
AutoPwm correction moved to correct location - after overshoot recalc…
dok-net Apr 26, 2020
d0a79d6
Finish overshoot math fixes.
dok-net Apr 26, 2020
2360dfe
First set pin mode, then digital write.
dok-net Apr 28, 2020
9d6130c
Simplify calculations, fix non-autoPwm for servo use, where exact dut…
dok-net Apr 28, 2020
c8f300f
Move wave initialization and modification outside the inner loop.
dok-net Apr 29, 2020
7565dc2
Some optimizing.
dok-net Apr 29, 2020
e0fbc99
Updating "now" in the inner loop should lessen interference
dok-net Apr 29, 2020
742199f
Finally get rid of volatile and use atomic thread fence memory barrie…
dok-net Apr 29, 2020
ee69ab9
Improved idle cycle overshoot mitigation.
dok-net Apr 30, 2020
e8d25b0
Improved duty cycle overshoot mitigation.
dok-net May 1, 2020
916db2e
Move startPin etc. into common static struct
dok-net May 2, 2020
864a2bf
Persist next event cycle across ISR invocations, like initPin was bef…
dok-net May 2, 2020
b0682a9
Recalibrated DELTAIRQ and IRQLATENCY. Tested @ 3x 40kHz PWM + 440Hz Tone
dok-net May 2, 2020
4af8505
CPU clock to Timer1 ccy correction must be dynamic even when BSP is c…
dok-net May 3, 2020
b861742
Corrected use of Timer1 registers and add rationale to Timer1 use in …
dok-net May 3, 2020
04ab1e0
Let duty cycle overshoot correction depend on relative impact compare…
dok-net May 4, 2020
60a09e4
80MHz/160MHz specific code can be compile-time selected in general, o…
dok-net May 5, 2020
4e50fbc
Seems that removing the redudant resetting of edge interrupt mode sha…
dok-net May 5, 2020
9d86859
Recalibrated delta irq ccys.
dok-net May 5, 2020
6fe4732
Off-by-one in 100% duty overshoot correction.
dok-net May 6, 2020
6885337
Simple register writes.
dok-net May 6, 2020
41f6bb5
Memory fences checked and joining events into same loop iteration tha…
dok-net May 6, 2020
89dd855
Shorten progression when going off 100% duty.
dok-net May 6, 2020
86afd50
Code simplifications.
dok-net May 7, 2020
b707020
Dynamically map pins out from in-ISR handling based on next event tim…
dok-net May 8, 2020
e71d86f
Reverting maximum IRQ period to 10ms. This sets the wave reprogrammin…
dok-net May 8, 2020
6855ad1
Revert recent change that is the most likely cause of reported PWM fr…
dok-net May 9, 2020
ddecf8a
Much simplified overshoot mitigation code.
dok-net May 9, 2020
111583b
Fixing overshoot mitigation, 3x 880Hz, 256 states now.
dok-net May 9, 2020
aa18a70
Increase resolution by keeping reference time moving forward earlier.
dok-net May 10, 2020
b43d4b0
Mitigation logic for ESP8266 SDK boosting to 160MHz during some WiFi …
dok-net May 10, 2020
e978ac4
Event timestamps are all recorded for compile-time CPU frequency, the…
dok-net May 11, 2020
3b18d51
Expired pins must not be checked for next event.
dok-net May 12, 2020
b45a2d2
Recalibrate after latest changes.
dok-net May 11, 2020
784692b
Save a few bytes code.
dok-net May 12, 2020
2d591eb
Guards are in place, so xor rather than and bitwise not.
dok-net May 14, 2020
dd10064
Reduce memory use.
dok-net May 15, 2020
557f356
SDK boost to 160MHz may last across multiple ISR invocations, therefo…
dok-net May 17, 2020
2e1ecc7
Overshoot mitigation w/o PWM frequency change.
dok-net May 20, 2020
b7f1b95
New PWM overshoot mitigation code keeps frequency. Averages duty betw…
dok-net May 21, 2020
05307a1
Small refactoring, remove code path that is never taken even at 3x25k…
dok-net May 22, 2020
83c6b67
Don't ever skip off duty, no matter if late or infinitely short.
dok-net May 22, 2020
5165ba2
Shed speed-up code that didn't speed up things.
dok-net May 23, 2020
12e4755
Must always recompute new waveform.nextEventCcy if there is any busy …
dok-net May 23, 2020
16956e9
Break out of ISR if timespan to next event allows, instead of busy wa…
dok-net May 24, 2020
7646984
Minor code simplification.
dok-net May 26, 2020
ab1b4c1
Improve code efficiency.
dok-net May 27, 2020
3d8865d
Improved performance of loop.
dok-net May 27, 2020
60bfa92
Recalibrated.
dok-net May 28, 2020
b78329b
No positive effect of lead time inclusion was found during testing, r…
dok-net May 28, 2020
f2dc71b
Fix WDT when at 160MHz CPU clock the Timer1 is set below 1µs.
dok-net May 30, 2020
7e247c2
Consolidate 160MHz constexpr check, finish 1µs minimum for Timer1 fix.
dok-net May 30, 2020
440c444
Test for non-zero before subtract should improve performance.
dok-net May 31, 2020
610fe5a
Reviewers/tested noted they were seeing WDT, and this change appeared…
dok-net Jun 7, 2020
0f1c423
More expressive use of parentheses and alias CPU2X for reduced code s…
dok-net Jun 7, 2020
59d3143
Bug fix: at 160MHz compiled, don't force minimum Timer1 latency to 2µs.
dok-net Jun 7, 2020
bc7d279
Alternate CPU frequency scaling mitigation.
dok-net Jun 8, 2020
12a4c65
Handle time-of-flight in the right spot.
dok-net Jun 9, 2020
e4892fa
Remove _toneMap from Tone.cpp
dok-net Nov 4, 2020
31ebfa7
Merge branch 'master' into waveform
d-a-v Nov 19, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 1 addition & 8 deletions cores/esp8266/Tone.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,6 @@
#include "core_esp8266_waveform.h"
#include "user_interface.h"

// Which pins have a tone running on them?
static uint32_t _toneMap = 0;


static void _startTone(uint8_t _pin, uint32_t high, uint32_t low, uint32_t duration) {
if (_pin > 16) {
return;
Expand All @@ -42,9 +38,7 @@ static void _startTone(uint8_t _pin, uint32_t high, uint32_t low, uint32_t durat
duration = microsecondsToClockCycles(duration * 1000UL);
duration += high + low - 1;
duration -= duration % (high + low);
if (startWaveformClockCycles(_pin, high, low, duration)) {
_toneMap |= 1 << _pin;
}
startWaveformClockCycles(_pin, high, low, duration);
}


Expand Down Expand Up @@ -86,6 +80,5 @@ void noTone(uint8_t _pin) {
return;
}
stopWaveform(_pin);
_toneMap &= ~(1 << _pin);
digitalWrite(_pin, 0);
}
Loading