* Allow 100% high or low periods.
Let output remain at current level on stopping instead of always turning to low.
* Fix serious jitter issues in previous versions.
* Use ESP.getCycleCount() just like everyone else.
* Highest timer rate at which this runs stable appears to be 2µs (500kHz).
* Guard for zero period length undefined waveforms.
Fix for zero duty or off cycles and expiring from them.
* Cycle precision for expiry instead of special treatment for 0 value.
* Give expiry proper precedence over updating a waveform
* Important comment
* Refactored, identical behavior.
* Use plural for bit arrays.
* Fix for completely duty or all off cycle period case.
* Expiration is explicitly relative to service time.
* Comment updated, here it's about cycles not usecs.
* Revert misconception of how waveformToEnable/Disable communicates with the NMI handler.
* Rewrite to keep phase in sync if period remains same during duty cycle change.
Refactor identifies to distinguish CPU clock cycle from waveform cycle.
* Rather iterate even if full-duty or no-duty cycle in period, than too many calculations in NMI handler.
* Must fire timer early to reach waveform deadlines, otherwise under some load aggressive jitter occurs.
* Schedule expiry explicitly, too.
Needed to keep track of next timer ccy in each iteration, not just when changing level.
* Quick change lets analogWrite keep phase for any duty cycle (including 0% and 100%).
* Set duration to multiple of period, so tone stops on LOW pin output.
* Improve phase timing
* Eror causing next Timer IRQ to fail busy-to-off cycle transitions.
* Regression fix, don't reset timer if pending shortly.
* Rather reschedule ISR instead of busy looping during permitted maximum time.
* Lead time improved for ISR
* Reduce number of cycle calculations.
* Reactive the gcc optimize pragmas.
* Simplify calculation.
* handles overshoot where an updated period is shorter than the previous duty cycle
* Misleading code, there must ever be only one bit set at a time, start and stop block until the ISR has handled and reset the token.
* Prevent missing a duty cycle unless it is overshot already.
* Continuously remove distant pending waveform edges from the loop, continuously update now.
* Replace volatile for one-way exchange into ISR with memory fence.
* Remove redundant stack object.
* Revert pending waveform removal from loop - corrupts continuous next event computation.
* Reduce if/do ... while to while
* Convert relative timings to absolute.
* Relax waveform start to possibly cluster phases into same IRQ interval.
* max 12us in ISR seems to work best for servo/fan/led/tone combo test.
* Restructured code in ISR for expiration, this saves 36 byte IRAM, and improves PWM resolution.
* Simplified overshot detection and 0% / 100% duty cycle.
* Leave ISR early if rescheduling is more promising than busy-waiting until next edge.
* Stabilized timings.
* Prevent WDT under load.
* Use clock cycle resolution instead of us for analogWrite.
* Reduce idle calculations in ISR.
* Optimize in-ISR time.
* Support starting new waveform in phase with another running waveform.
* Align phase for analogWrite PWMs.
* Tune preshoot, add lost period fast forward.
* Adapt phase sync code from analogWrite to Servo
* Fix for going off 100% duty cycle period.
* Eschew obfuscation.
* Fixed logic for zero duty cycle.
* Determine generator quantum during same IRQ - this is better than timer resolution, but non-zero.
* Tune timings, fix write barriers and overshoot logic.
* Migrate Tone to waveform with CPU cycle precision
* Can do 60kHz PWM.
* Recalibrated timings after performance optimizations.
Initialize GPIO if needed.
* Fix regression for waveform runtime.
* Test cycle duration values for signed arithmetic safety.
* Performance tuning.
* Performance tweak, in-ISR quantum is now 1.12µs.
* Round up duration instead of down - possibly to zero, which means forever.
* Extend phase alignment with optional phase offset.
* Slightly better in-ISR quantum approximation for steadier increments.
* Waveform stopped by runtime limit in iSR doesn't deinit the timer, but stopWaveform refuses
to do anything if the waveform was stopped by runtime, either.
* Improved quantum correction code.
* Fix broken multi-wave generation.
* Aggregate GPIO output across inner loop. True phase sync, and now better performance.
* IRQ latency can be reduced from 2 to 1 us now, no WDT etc.
* Improved handling of complete idle cycle miss, progress directly into duty cycle.
* Recalibrated after latest changes and reverts.
* Overshoot compensation for duty cycle results in PWM milestone.
* Adjustments to duty/idle cycle to mitigate effects of floating duty cycle logic.
* Remove implicit condition from loop guard and fix timer restart duration
* Host all static globals in an anonymous static struct.
* Busy wait directly for next pending event and go to that pin.
* Record nextEventCcy in waveform struct to save a few cycles.
* Adapt duty cycle modification to only fix full duty and all idle cases.
* Remember next pin to operate between IRQs.
* Don't set pinMode each time on already running PWM or Tone.
* Remove quantum, correct irq latency from testing,reuse isr timeout from master et al
* Move updating "now" out of inner loop, prevents float between pins that are in phase lock.
* Merge init loop with action loop again.
* Adaptive PWM frequency and floating duty cycle.
* Predictive static frequency scaling.
* Dynamic frequency down-scaling
* Frequency scaling is only for PWM-like applications, anything needing real time duty cycles or frequency must be able to fail on overload.
* Conserve IRAM cache, resort to best effort.
* Directly scale frequency for all duty/all idle waves to reasonable maximum, reduces thrashing.
* Getting the math right beats permanently reducing PWM frequency.
* Rename identifier to help think about the problem.
* AutoPwm correction moved to correct location - after overshoot recalc - and allow limited duty floating
* Finish overshoot math fixes.
* First set pin mode, then digital write.
* Simplify calculations, fix non-autoPwm for servo use, where exact duty is needed, idle is elastic.
* Move wave initialization and modification outside the inner loop.
* Some optimizing.
* Updating "now" in the inner loop should lessen interference
* Finally get rid of volatile and use atomic thread fence memory barriers, great for ISR performance.
* Improved idle cycle overshoot mitigation.
* Improved duty cycle overshoot mitigation.
Case for investigation: 3% (shl 5) vs. 1.5% (shl 6), either less fuzz, but a few marked stray spots, or more fuzz, but no bumps in counter-PWM travel test.
* Move startPin etc. into common static struct
* Persist next event cycle across ISR invocations, like initPin was before.
* Recalibrated DELTAIRQ and IRQLATENCY. Tested @ 3x 40kHz PWM + 440Hz Tone
* CPU clock to Timer1 ccy correction must be dynamic even when BSP is compiled for fixed CPU clock.
* Corrected use of Timer1 registers and add rationale to Timer1 use in comment.
Recalibrate for improved frequence downscaling @ 80MHz and 160MHz.
* Let duty cycle overshoot correction depend on relative impact compareed to both period and duty.
* 80MHz/160MHz specific code can be compile-time selected in general, only NMI is affected by
apparent CPU frequency scaling in SDK code.
* Seems that removing the redudant resetting of edge interrupt mode shaves 0.5us off rearm latency.
* Recalibrated delta irq ccys.
* Off-by-one in 100% duty overshoot correction.
* Simple register writes.
* Memory fences checked and joining events into same loop iteration that are close to one another.
* Shorten progression when going off 100% duty.
* Code simplifications.
* Dynamically map pins out from in-ISR handling based on next event timing.
Major performance boost.
* Reverting maximum IRQ period to 10ms. This sets the wave reprogramming rate to 100Hz max.
* Revert recent change that is the most likely cause of reported PWM frequency drop regression.
* Much simplified overshoot mitigation code.
* Fixing overshoot mitigation, 3x 880Hz, 256 states now.
* Increase resolution by keeping reference time moving forward earlier.
* Mitigation logic for ESP8266 SDK boosting to 160MHz during some WiFi ops.
* Event timestamps are all recorded for compile-time CPU frequency, the timer ticks conversion
must be set at compile-time also. The SDK WiFi 160MHz boost mitigation temporarily handles
the CPU clock running twice as fast.
* Expired pins must not be checked for next event.
* Recalibrate after latest changes.
* Save a few bytes code.
* Guards are in place, so xor rather than and bitwise not.
* Reduce memory use.
* SDK boost to 160MHz may last across multiple ISR invocations, therefore adjust target ccy instead of ccount.
* Overshoot mitigation w/o PWM frequency change.
* New PWM overshoot mitigation code keeps frequency. Averages duty between consecutive periods.
* Small refactoring, remove code path that is never taken even at 3x25kHz/1023 PWM.
* Don't ever skip off duty, no matter if late or infinitely short.
* Shed speed-up code that didn't speed up things.
* Must always recompute new waveform.nextEventCcy if there is any busy pin.
* Break out of ISR if timespan to next event allows, instead of busy waiting and stealing CPU cycles from userland.
* Minor code simplification.
* Improve code efficiency.
* Improved performance of loop.
* Recalibrated.
* No positive effect of lead time inclusion was found during testing, remove this code.
Maximum period duration limit is implicit to timer, consider it documented constraint, don't runtime
check in ISR.
* Fix WDT when at 160MHz CPU clock the Timer1 is set below 1µs.
* Consolidate 160MHz constexpr check, finish 1µs minimum for Timer1 fix.
* Test for non-zero before subtract should improve performance.
* Reviewers/tested noted they were seeing WDT, and this change appeared to fix that.
* More expressive use of parentheses and alias CPU2X for reduced code size.
* Bug fix: at 160MHz compiled, don't force minimum Timer1 latency to 2µs.
* Alternate CPU frequency scaling mitigation.
* Handle time-of-flight in the right spot.
* Remove _toneMap from Tone.cpp
Co-authored-by: david gauchard <gauchard@laas.fr>
* WString: Optimize a bit
* move bodies of dtor, `init()` and `charAt()` to .h (implicitly inlined)
* unify descriptions of the initialization into one: `init()` (literally), that is called from each ctors, `invalidate()` and `move()`
* invert the SSO state logic in order to make init state zeroed (as a result, each inlined `init()` saves 1 insn)
* detab and trim
* remove `inline` from .h
* cosmetics
* optimize the non-SSO -> SSO transition part of `changeBuffer()`
* remove duped body of `operator =(StringSumHelper &&rval)`
* remove common subexpressions from `lastIndexOf()` and `substring()`
* eliminate `strlen(buf)` after calling `sprintf(buf, ...)` that returns # of chars written
* eliminate `len()` after calling `setLen(newlen)`
* make ctor`(char c)` inlineable
* optimize `setLen()`
* replace constant-forwarding overload functions with default argument ones
* optimize `concat(char c)`
* * optimize `init()` more
* TZ: help newlib parser
Timezones coded with numeric abbreviations <±nn>±nn<±nn>[±nn][,...] are incorrectly parsed
by newlib's TZ parser.
Replacing <±nn> occurences by UNK allows newlib's TZ parser to nicely interpret all timezones.
Detailed explanation in https://github.com/earlephilhower/newlib-xtensa/issues/12
* Add Print::availableForWrite method
Adds an availableForWrite() method to the Print class, matching current
ArduinoCore-API commit 398e70f188e2b861c10d9ffe5e2bfcb6a4a4f489 .
Hook availableForWrite into the SDFS filesystem (other FSes don't have
this capability built-in).
Fixes#7650
* WiFiClient::availableForWrite proto matching Print
* Fix Netdump signedness warning
* Clean up Serial availableForWrite
This is evidently a breaking change due to the type difference.
Arduino's `availableForWrite` returns an `int`, while the
(multiply-implemented, non-virtual) core `availableForWrite` returned
`size_t`.
* Do not write more data than requested on PUYA flashes
* Always align flash reads/writes to 4 bytes
* fixup! Always align flash reads/writes to 4 bytes
This commit simplifies the code a bit and fixes a bug that caused wrong number of bytes to be
written
* fixup! Always align flash reads/writes to 4 bytes
* fixup! Always align flash reads/writes to 4 bytes
* Check for result before additional read/write
* Add overloads for unaligned reads/writes
* fixup! Add overloads for unaligned reads/writes
* fixup! Add overloads for unaligned reads/writes
* fixup! Add overloads for unaligned reads/writes
* fixup! Add overloads for unaligned reads/writes
* fixup! Add overloads for unaligned reads/writes
* fixup! Add overloads for unaligned reads/writes
* fixup! Add overloads for unaligned reads/writes
* Add tests for flashRead/flashWrite
* fixup! Add overloads for unaligned reads/writes
* fixup! Add tests for flashRead/flashWrite
* fixup! Add tests for flashRead/flashWrite
* fixup! Add overloads for unaligned reads/writes
* Allow test framework to use cores/esp8266/Arduino.h directly
* fix wps debugging
* some more missing debug.h
* Hunt down debug.h and roll-back
TODO: rename it to something else... it is an internal header
* Move abs+round checks to test/device/test_sw
* Restore macros for C code
* fixup! Move abs+round checks to test/device/test_sw
* Fix bad c/p, actually try round with ints
* tweak c macros per review
* fix gcc-10 missing cerrno include
* (test) WString: c_str() returns null pointer
target = std::move(source) does not reset buffer pointer back to the sso
* wstring: correctly do move invalidation & copy
based on the #7553 without isSSO -> isHeap rename and inline optimizations
additionally, remove useless pre-c++11 preprocessor checks
Co-authored-by: Takayuki 'January June' Suwa <jjsuwa@sys3175.com>
The last 4 bytes of a GZIP file is the decompressed file length, and
are used in eboot to do sanity checks and know when decompression is
done.
Updater was incorrectly telling eboot to look at
"end-of-bin + sizeof(signing)", and when eboot did so it got an
incorrect value causing either the update to be skipped or for only a
portion of update to be completed.
Fix by adjusting the size back to the end of binary.
Fixes#7570
Although GCC seems to be able to grok it, it looks weird
in my editor. this is the only place in the code base where
this combination is used, so I hope its okay to remove it.
Converting floats to doubles is very expensive on esp8266, so prefer
calculations or comparisons as float. This saves 10% (20 bytes) of the
String::parseFloat() code size and probably quite a bit of runtime
overhead.
The ROM routine __divsi3 is called by code whenever a division is needed,
because there is no divide unit on the ESP8266 core. When the divide
routine in ROM hits a div-by-zero case, it jumpt to an ILL(egal instruction)
at a fixed address which causes a HW exception 0 (IllegalInsnException).
In the postmortem dump, when an ILL exception is detected at this address
in ROM, convert it to a DivByZeroException for printout (6).
Divde by zero errors now print as follows:
````
--------------- CUT HERE FOR EXCEPTION DECODER ---------------
Exception (6):
epc1=0x4000dce5 epc2=0x00000000 epc3=0x00000000 excvaddr=0x00000000 depc=0x00000000
>>>stack>>>
...
<<<stack<<<
--------------- CUT HERE FOR EXCEPTION DECODER ---------------
````
And will decode as follows:
````
Exception 6: IntegerDivideByZero: QUOS, QUOU, REMS, or REMU divisor operand is zero
PC: 0x4000dce5
EXCVADDR: 0x00000000
Decoding stack results
...
````
* Add SerialEvent() callback to loop processing
Match the AVR SerialEvent implicit callback. Callback is executed
in normal user mode, not IRQ, so standard processing can be uses.
Fixes#752 after 5 years. :)
* Fix style
Parameters that are only used in an assert() statement are unused when
the NoAssert-NDEBUG option is used. This causes the following unused
parameter warnings while building:
````
/home/earle/Arduino/hardware/esp8266com/esp8266/cores/esp8266/Crypto.cpp: In function 'String {anonymous}::createBearsslHmac(const br_hash_class*, uint8_t, const String&, const void*, size_t, size_t)':
/home/earle/Arduino/hardware/esp8266com/esp8266/cores/esp8266/Crypto.cpp:101:71: warning: unused parameter 'hashTypeNaturalLength' [-Wunused-parameter]
101 | String createBearsslHmac(const br_hash_class *hashType, const uint8_t hashTypeNaturalLength, const String &message, const void *hashKey, const size_t hashKeyLength, const size_t hmacLength)
| ~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~
/home/earle/Arduino/hardware/esp8266com/esp8266/cores/esp8266/Crypto.cpp: In function 'String {anonymous}::createBearsslHmacCT(const br_hash_class*, uint8_t, const String&, const void*, size_t, size_t)':
/home/earle/Arduino/hardware/esp8266com/esp8266/cores/esp8266/Crypto.cpp:153:73: warning: unused parameter 'hashTypeNaturalLength' [-Wunused-parameter]
153 | String createBearsslHmacCT(const br_hash_class *hashType, const uint8_t hashTypeNaturalLength, const String &message, const void *hashKey, const size_t hashKeyLength, const size_t hmacLength)
| ~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~
````
Mark them unused in the code to avoid the error. The assert() still
works.
Matching standard Arduino cores, make the default analogWrite() take
values from 0...255. Users can always use the analogWriteRange() call
to change to a different setup.
Add a `analogWriteResolution` which takes a number of bits and sets
the range from 0...(1<<bits)-1, part of the standard Arduino API.
Remove the PWMRANGE define. It's non-standard and not generally valid
(i.e. it's fixed at 1024 of 256, but the real range varies depending on
what you last set).
Also add note about the change and how to fix pre 3.0 applications.
Fixes#2895
* webhook api
* simplify webserver debug printouts, move text to flash
* Hook examples in HelloServer example
* print executable code address in example
* simplify example per @mcspr suggestion
* Initialize _ledPin
_ledPin should be initialized to -1 in the constructor to avoid setting a random pin when calling Updater::end without having called Updater::begin before. This happens, for example, in the Homie software
* Fix field sequence