Open CedarGroveStudios opened 1 year ago
This must be related to SYNCBUSY:
I think we do want the value to be copied on reload but that shouldn't prevent us from writing the buffered value multiple times in the interim. We just changed this on rp2: #7299
Also suspect that the delay leads to DC motor "rattling" when establishing a new motor speed at low PWM frequencies since the two PWM control pins aren't changed simultaneously.
Also suspect that the delay leads to DC motor "rattling" when establishing a new motor speed at low PWM frequencies since the two PWM control pins aren't changed simultaneously.
Confirmed. At low PWM frequencies in slow decay mode, the delay causes a DC motor to noticeably shudder when switching between velocity zero and coasting (velocity = None) and back. Don't have a setup to test stepping motors, but would expect a similar issue.
I have been doing some benchmarking and the slowness of PWM setting immediately popped out. Looks like it is a known issue which still need to be fixed? And is there any background on if/how the SAMD PWM peripheral is different from e.g. the RP2040's, which requires setting it to be handled differently?
I have been doing some benchmarking and the slowness of PWM setting immediately popped out. Looks like it is a known issue which still need to be fixed? And is there any background on if/how the SAMD PWM peripheral is different from e.g. the RP2040's, which requires setting it to be handled differently?
I don't think it needs to be different. It just hasn't been updated. See https://github.com/adafruit/circuitpython/issues/7653#issuecomment-1447322516
Wondering why is double-buffering disabled here? https://github.com/adafruit/circuitpython/blob/2854dbe37f52dc9ebf48035dfc82bba83c8f9cac/ports/atmel-samd/common-hal/pwmio/PWMOut.c#L278-L286
and why is it necessary to wait for sync? https://github.com/adafruit/circuitpython/blob/2854dbe37f52dc9ebf48035dfc82bba83c8f9cac/ports/atmel-samd/common-hal/pwmio/PWMOut.c#L275-L276 Thanks!
and why is it necessary to wait for sync?
I don't think it is necessary. It was just a choice we made during the original implementation.
Wondering why is double-buffering disabled here?
No idea. Its been years since this code was added.
Ok! I'm going to be looking at this and #7747
CircuitPython version
Code/REPL
Behavior
100 iterations with a PWM frequency of 5000 Hz:
100 iterations with a PWM frequency of 50 Hz:
Description
The delay is approximately equal to the period of the PWM frequency. The delay is noticeable at lower frequencies such as those used for servo and DC motor control.
Although not confirmed (somewhat beyond my skill set), it might be that the SAMD51 timer used for PWM is not being operated in its double-buffered CC (Compare Channel) register mode. Instead it may be waiting to load the CC register when the timer count is at its ZERO value rather than loading the CC buffer register and returning to the calling module. (reference: Microchip SAM D5x/E5x Family Data Sheet , DS60001507E, pp 1719-1721)
If possible, the desired operation would be to load the new PWM duty_cycle value and immediately return to the calling code, allowing the SAMD51's timer hardware to self-synchronize rather than cause a blocking delay condition.
Changing to a double-buffered approach may also benefit
asyncio
-based code.Additional information