From 9bc4f628f6d4103465d02cc7ba88e61c072e4010 Mon Sep 17 00:00:00 2001 From: Tim Date: Tue, 2 Jul 2024 17:15:15 -0700 Subject: [PATCH 1/3] fix off-by-one in PWM frequency setting --- ports/raspberrypi/common-hal/pwmio/PWMOut.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ports/raspberrypi/common-hal/pwmio/PWMOut.c b/ports/raspberrypi/common-hal/pwmio/PWMOut.c index 07591012c587..40b006d083a3 100644 --- a/ports/raspberrypi/common-hal/pwmio/PWMOut.c +++ b/ports/raspberrypi/common-hal/pwmio/PWMOut.c @@ -218,8 +218,8 @@ void common_hal_pwmio_pwmout_set_frequency(pwmio_pwmout_obj_t *self, uint32_t fr pwm_set_clkdiv_int_frac(self->slice, div16 / 16, div16 % 16); pwm_set_wrap(self->slice, self->top); } else { - uint32_t top = common_hal_mcu_processor_get_frequency() / frequency; - self->actual_frequency = common_hal_mcu_processor_get_frequency() / top; + uint32_t top = common_hal_mcu_processor_get_frequency() / frequency - 1; + self->actual_frequency = common_hal_mcu_processor_get_frequency() / (top + 1); self->top = MIN(MAX_TOP, top); pwm_set_clkdiv_int_frac(self->slice, 1, 0); // Set TOP register. For 100% duty cycle, CC must be set to TOP+1. From 8a1b3e7cfc283124779ba407c33f0a87582a735f Mon Sep 17 00:00:00 2001 From: Tim Date: Wed, 3 Jul 2024 09:37:55 -0700 Subject: [PATCH 2/3] disallow duty cycle rounding to 0 --- ports/raspberrypi/common-hal/pwmio/PWMOut.c | 4 + .../pwmio/code_extremes.py | 87 +++++++++++++++++++ 2 files changed, 91 insertions(+) create mode 100644 tests/circuitpython-manual/pwmio/code_extremes.py diff --git a/ports/raspberrypi/common-hal/pwmio/PWMOut.c b/ports/raspberrypi/common-hal/pwmio/PWMOut.c index 40b006d083a3..e0572eccd9e4 100644 --- a/ports/raspberrypi/common-hal/pwmio/PWMOut.c +++ b/ports/raspberrypi/common-hal/pwmio/PWMOut.c @@ -176,6 +176,10 @@ extern void common_hal_pwmio_pwmout_set_duty_cycle(pwmio_pwmout_obj_t *self, uin } else { compare_count = ((uint32_t)duty * self->top + MAX_TOP / 2) / MAX_TOP; } + // do not allow count to be 0 (due to rounding) unless duty 0 was requested + if (compare_count == 0 && duty != 0) { + compare_count = 1; + } // compare_count is the CC register value, which should be TOP+1 for 100% duty cycle. pwm_set_chan_level(self->slice, self->ab_channel, compare_count); } diff --git a/tests/circuitpython-manual/pwmio/code_extremes.py b/tests/circuitpython-manual/pwmio/code_extremes.py new file mode 100644 index 000000000000..13dd5c90ad1a --- /dev/null +++ b/tests/circuitpython-manual/pwmio/code_extremes.py @@ -0,0 +1,87 @@ +import board +import pwmio +import random +import time +import microcontroller +import os +import sys +import random + +exponents = [ + 2, + 3, + 4, + 5, + 6, + 7, +] + +freqs = [int(10**f) for f in exponents] + +top = 65536 +den = 10 +duties = [32767, 65535, 1, 65534, 0, 0] +freq_duration = 1.2 +duty_duration = 0.2 + +print("\n\n") +board_name = sys.implementation[2] + +pins = { + "Feather RP2040": (("D4", ""),), + "RP2040-Zero": (("GP15", ""),), + "Grand Central": (("D51", "TCC"), ("A15", "TC")), + "Metro M0": (("A2", "TC"), ("A3", "TCC")), + "ESP32-S3-DevKit": (("IO6", ""),), # marked D5 on board for XIAO-ESP32-s3 + "Feather ESP32-S2": (("D9", ""),), + "XIAO nRF52840": (("D9", ""),), +} + +for board_key in pins: + if board_key in board_name: + pins_to_use = pins[board_key] + break + +while True: + for pin_name, pin_type in pins_to_use: + pin = getattr(board, pin_name) + print('title="', end="") + print(f"{board_name} at {microcontroller.cpu.frequency} Hz, pin {pin_name}", end="") + if len(pin_type) > 0: + print(f" ({pin_type})", end="") + print('",') + print(f'subtitle="{freq_duration:0.1f}s per frequency",') + print(f'version="{sys.version}",') + print("freq_calls=", end="") + pwm = pwmio.PWMOut(pin, variable_frequency=True) + t0 = time.monotonic() + duty_time = t0 + duty_duration + print("(", end="") + offset = 0 + increment = 1 + for freq in freqs: + i = 0 + try: + pwm.frequency = freq + except ValueError: + break + freq_time = t0 + freq_duration + duty_time = t0 + duty_duration + j = 0 + while time.monotonic() < freq_time: + duty = duties[j] + pwm.duty_cycle = duty + while time.monotonic() < duty_time and time.monotonic() < freq_time: + pass + j += 1 + j = min(j, len(duties) - 1) + duty_time += duty_duration + i += 1 + if time.monotonic() > freq_time: + break + t0 = freq_time + print(f"({freq}, {i/freq_duration:.0f}), ", end="") + print(")") + print("done.") + pwm.deinit() + time.sleep(5) From 6c1227efdd19d77833f1945b2a19265b3ddbca1a Mon Sep 17 00:00:00 2001 From: Tim Date: Wed, 3 Jul 2024 10:21:34 -0700 Subject: [PATCH 3/3] add tests of pwm extremes --- tests/circuitpython-manual/pwmio/README.md | 8 +++++++- .../pwmio/{code.py => code_ramps.py} | 1 + .../pwmio/pwm_extremes_explainer.png | Bin 0 -> 32557 bytes 3 files changed, 8 insertions(+), 1 deletion(-) rename tests/circuitpython-manual/pwmio/{code.py => code_ramps.py} (98%) create mode 100644 tests/circuitpython-manual/pwmio/pwm_extremes_explainer.png diff --git a/tests/circuitpython-manual/pwmio/README.md b/tests/circuitpython-manual/pwmio/README.md index 11bcd4de6651..511424c8f6c6 100644 --- a/tests/circuitpython-manual/pwmio/README.md +++ b/tests/circuitpython-manual/pwmio/README.md @@ -2,7 +2,7 @@ This directory contains tools for testing CircuitPython's PWM API. Running the tests involves three steps: -1. [CircuitPython PWM test code `code.py`](code.py) is run on the board to be tested. +1. [CircuitPython PWM test code `code_ramps.py`](code_ramps.py) is run on the board to be tested. 2. As the code runs, the state of the PWM signal is logged by a logic analyzer (I used a Saleae Logic Pro 8). 3. Data collected by the logic analyzer is analyzed and plotted into a PNG image by [CPython code `duty.py`](duty.py). @@ -37,3 +37,9 @@ These tests can be used to assess how well the PWM API delivers expected behavio The plot at the top of this page depicts data PWM gathered from a device with an API that displays all of the expected behavior listed above. The plots below show how the tools reveal flaws in the behavior of PWM APIs that are not as complete. + +## Testing always-off and always-on PWM extremes + +The procedure described above does not test item 2 above, i.e. the ability of the API to support duty cycles of 0% and 100%. A different code file, (code_extremes.py) provides for this. This code cycles through PWM duty cycles of 32767, 65535, 1, 65534, and 0, repeating the sequence at six frequencies from 100 Hz to 10MHz. When viewed on a logic analyzer, the PWM output should look like the figure below. 100% and 0% PWM result from duty cycle settings of 65535 and 0, (and only from those settings, in accordance with item 3 above.) + + diff --git a/tests/circuitpython-manual/pwmio/code.py b/tests/circuitpython-manual/pwmio/code_ramps.py similarity index 98% rename from tests/circuitpython-manual/pwmio/code.py rename to tests/circuitpython-manual/pwmio/code_ramps.py index b7f10670e8be..6a06e4eff6bb 100644 --- a/tests/circuitpython-manual/pwmio/code.py +++ b/tests/circuitpython-manual/pwmio/code_ramps.py @@ -39,6 +39,7 @@ board_name = sys.implementation[2] pins = { + "Feather RP2040": (("D4", ""),), "RP2040-Zero": (("GP15", ""),), "Grand Central": (("D51", "TCC"), ("A15", "TC")), "Metro M0": (("A2", "TC"), ("A3", "TCC")), diff --git a/tests/circuitpython-manual/pwmio/pwm_extremes_explainer.png b/tests/circuitpython-manual/pwmio/pwm_extremes_explainer.png new file mode 100644 index 0000000000000000000000000000000000000000..25f30251976dde9641e7a0e3fb675547eef4eeb3 GIT binary patch literal 32557 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%0A8J zI=Wa09X0x4DbPCOD=1^7?_lGb1rk0$l4_j#;tYS^Bmr8SbueRsg6q_O>-0SsQH8;IScg$2Vat>UZRe9ezJMy{v!nmH~D{61tKh*K<7i(28p_(d=|v@MTkfo8x||1;2?5mX@k z-t;<>wOCA