8000 Optimise `machine.time_pulse_us` implementation for code size, and switch esp8266 port to use it by dpgeorge · Pull Request #17346 · micropython/micropython · GitHub
[go: up one dir, main page]

Skip to content

Optimise machine.time_pulse_us implementation for code size, and switch esp8266 port to use it #17346

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

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

dpgeorge
Copy link
Member

Summary

The esp8266 has a custom implementation of machine.time_pulse_us(), which is needed so it can feed the WDT during long waits for a pin change. It doesn't need to have a separate implementation, instead we can use the common one with an optional hook for a port to do work during the busy wait loops.

This PR:

  1. Reworks the common implementation of machine.time_pulse_us() to be more like the esp8266 version. That cuts down code size a little, and improves accuracy a little.
  2. Switches esp8266 to use this common implementation.

Also, motivation comes from #16160: this PR should make that PR much simpler (and lower cost) to implement.

Testing

Tested with a range of square waves from 125Hz to 4kHz on:

  • PYBD_SF2: this has a very accurate measurement and accuracy is unchanged with this PR
  • RPI_PICO2_W: same as PYBD_SF2, very accurate and unchanged with this PR
  • ESP8266: for the frequencies it can handle (up to about 1kHz) this PR is slightly more accurate than before: for example a pulse that is 1000us long, it would measure between 998 and 1000us with an average of 999us. Now it measures between 999us and 1001us with an average of 1000us.

Also tested the timeout argument, a value of 5000000 still takes 5s and doesn't lead to a WDT timeout on esp8266.

Trade-offs and Alternatives

This is an optimisation. There is no change in the API. As tested above, the accuracy is at least the same if not better due to better sampling of ticks and pin at the same point in the code.

Copy link

Code size report:

   bare-arm:    +0 +0.000% 
minimal x86:    +0 +0.000% 
   unix x64:   +16 +0.002% standard
      stm32:   -16 -0.004% PYBV10
     mimxrt:   -16 -0.004% TEENSY40
        rp2:    -8 -0.001% RPI_PICO_W
       samd:   -16 -0.006% ADAFRUIT_ITSYBITSY_M4_EXPRESS
  qemu rv32:    +0 +0.000% VIRT_RV32

@dpgeorge
Copy link
Member Author

It's really hard to pass CI these days 😅

@dpgeorge dpgeorge force-pushed the extmod-machine-time-pulse-optimise branch from e6464be to 04226d0 Compare May 23, 2025 03:37
Copy link
codecov bot commented May 23, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 98.54%. Comparing base (49f81d5) to head (c21708b).

Additional details and impacted files
@@           Coverage Diff           @@
##           master   #17346   +/-   ##
=======================================
  Coverage   98.54%   98.54%           
=======================================
  Files         169      169           
  Lines       21898    21903    +5     
=======================================
+ Hits        21579    21584    +5     
  Misses        319      319           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

dpgeorge added 2 commits May 23, 2025 14:38
This implementation is based on the esp8266 custom implementation, and
further optimised for size and accuracy.

Testing on PYBD_SF2 and RPI_PICO2_W shows that it is at least as good as
the original implementation in performance.

Signed-off-by: Damien George <damien@micropython.org>
Testing shows that for frequencies which the esp8266 can handle -- up to
about 1kHz -- `machine.time_pulse_us()` now gives more accurate results.

Prior to this commit it would measure on average about 1us lower, but now
the average is much closer to the true value.  For example a pulse that is
1000us long, it would measure between 998 and 1000us.  Now it measures
between 999us and 1001us.

Signed-off-by: Damien George <damien@micropython.org>
@dpgeorge dpgeorge force-pushed the extmod-machine-time-pulse-optimise branch from 04226d0 to c21708b Compare May 23, 2025 04:39
@dpgeorge
Copy link
Member Author

@robert-hh regarding your comment that I think you deleted: it should be possible to allow nchanges to be any value, but the initial pulse_value would need to be twiddled like: pulse_value ^= nchanges & 1. Ie if there are an odd number of changes, toggle the initial value.

@robert-hh
Copy link
Contributor

Yes, I delete it because at second though it was wrong. The nchanges counter can not underrun.
Tests with a SAMD21 also returned improved accuracy. A 1000µs pulse showed most values being either 999 or 1002, and an average over 100 samples of 1000 +/- 0.15.

@projectgus projectgus self-requested a review May 29, 2025 03:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
extmod Relates to extmod/ directory in source port-esp8266
Projects
None yet
0