-
-
Notifications
You must be signed in to change notification settings - Fork 8.2k
ports/machine_pwm: Set the PWM duty_u16() back to 65535. #16153
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
Conversation
Code size report:
|
@@ -36,15 +36,15 @@ void PWM_UpdatePwmDutycycle_u16( | |||
|
|||
// Setup the PWM dutycycle of channel A or B | |||
if (pwmSignal == kPWM_PwmA) { | |||
if (dutyCycle >= 65536) { | |||
if (dutyCycle >= PWM_FULL_SCALE) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This constant is still defined as 65536 in pwm_backport.h
. Does it need changing there?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Of course.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated. Behavior still fine. At duty_u16(32768) the difference between low and high phases with a Teensy 4.x are 700ps (flexpwm) and 400ps (QTMR).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can the hardware have even better symmetry with 50% duty cycle, if you choose the right upper limit for the counter? If so, it may be possible to get this working with machine.PWM
by using 65536 for the hardware full scale, but 65535 for the duty_u16
max, and then scaling it via x * 65536 / 65535
. I think this is how the rp2 port works.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The difference between the high/low phase is 10% of the PWM clock or about 50% of the CPU clock. It hardly can get much better.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right... picoseconds are very small! Great work testing it to that degree.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks good to me, thanks @robert-hh
099562a
to
b48cc26
Compare
Thanks for taking care of all of these important details folks! |
Running the PWM test on this updated MIMXRT/Teensy 4.x, I made a few "observations". The MIMXRT port has three different mechanisms for PWM, which I call : FLEXPWM_AB, FLEXPWM_X and QTMR. All work fine with usual PWM signal, but with duty_u16(0) and duty_u16(65535) there are some problems. QTMR: No problem. FLEXPWM_X: duty_u16(0) is implemented by switching the output off. Otherwise there are still pulses at the output. If the FLEX_PWM_AB: There are problems of switching from duty_u16(65535) to duty_u16(0). It takes longer than a full frequency period. If there is a different duty value enabled between duty_u16(65535) and duty_u16(0), then the transition is fast. I do not know yet what the reason is. Simple test programs seem to work. In any case switching the PWM settings require a full previous period to expire. Edit: fixed The pins used by the machine_pwm.py test are D0 and D1. D0 has a FLEXPWM_X type PWM. Enabling PULL_DOWN on |
Edit: The reason for issue with the FLEX_PWM_AB channels is double loading of PWM parameters within one PWM cycle. The second load is ignored. Fixed by clearing a pending load before loading new paramerts. |
c92dbd1
to
1e26fda
Compare
The issues with the FLEXPM channels and duty_u16(0) are fixed. The changes are pushed. Tested with MIMXRT 1011, -1015, -1020, -1052, -1062 (Teensy 4.x) and -1176. |
Excellent work @robert-hh ! We should probably make more of these hardware tests, they are really teasing out the bugs.
I think we should make the PWM test test all three of these mechanisms (for mimxrt boards). Can you suggest three pairs of pins that can be used for this? Maybe one pair can also have MISO/MOSI to test loopback SPI. |
Sure. With Teensy 4.x: |
The following ports used 65536 as the upper value (100% duty cycle) and are changed in this commit to use 65535: esp8266, mimxrt, nrf, samd. Tested that output is high at `duty_u16(65535)` and low at `duty_u16(0)`. Also verified that at `duty_u16(32768)` the high and low pulse have the same length. Partially reverts micropython#10850, commits 9c7ad68 and 2ac643c. Signed-off-by: robert-hh <robert@hammelrath.com>
Changes in this commit: - When setting PWM parameters of a FLEXPWM AB channel twice within a PWM cycle, the second setting was ignored. Now the second setting persists. - With `duty_u16(0)` a FLEXPWM X channel was set to high impedance. Now it is set to low impedance with value 0 for `invert=False`, and 1 for `invert=True`. - The align parameter requires a duty rate and frequency to be set. Align will now be ignored if freq or duty are missing. Signed-off-by: robert-hh <robert@hammelrath.com>
1e26fda
to
e2532e0
Compare
Merged. Thanks again @robert-hh for your efforts here. |
Thank you for setting up the test, which proves to be very useful. |
Tested that output is high at duty_u16(65565) and low at duty_u16(0). Also verified that at duty_u16(32768) the high and low pulse have the same length.
Tested with ESP8266, MIMXRT, NRF and SAMD, which are affected by this change. Other ports did not require a change.
Partially reverting PR #10850.