Skip to content
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

expand pwm max value to 16 bit for avrs #3612

Closed

Conversation

Cirromulus
Copy link
Contributor

This enables AVR-Chips to use the full PWM resolution if available on the pin

@KevinOConnor
Copy link
Collaborator

Unless I'm missing something, all of the cycle_time calculations in gpio_pwm_setup() are based on PWM_MAX=255. And (unless I'm missing something) it's not easy to increase PWM_MAX there because doing so would reduce the maximum available hard pwm frequency.

-Kevin

@Cirromulus Cirromulus marked this pull request as draft December 8, 2020 14:56
@Cirromulus
Copy link
Contributor Author

I will check this soon, thanks for the fast comments

@Cirromulus
Copy link
Contributor Author

As I understand, the AVR-Code currently picks the closest PWM frequency to the requested cycle_time.
While it is possible to hit the (more or less) exact cycle_time, this would reduce the resolution. This is unacceptable at only 8 Bit.

My suggestion is to have a different behavior for 8bit and 16bit PWM:

  • keep 8 bit as is (but scaled to 65535)
  • 16 bit also calculates TOP counter (Configure MAX Val in ICRn) at the expense of reduced resolution

Unless choosing very fast PWM-Frequencies, the resolution decrease would max out at half (so 15 bit).
With fast PWM-Frequencies (cycle_time < (2^8)*mcu_frequency), the resolution would decrease below 8-bit at the benefit of enabling even faster, previously impossible, frequencies.

What are your thoughts about this, @KevinOConnor? "Implicit" behaviour of resolution changes may confuse the power-user, but would not break currently running systems (as long as they did not use a 16bit hard-pwm pin with a cycle time near zero)

Signed-off-by: Pascal Pieper <[email protected]>
@KevinOConnor
Copy link
Collaborator

I'm not sure I understand. Are you proposing that we be able to hit higher frequency cycle times by using less bits in the "on duration" setting? And similarly, obtain lower frequency cycle times by going up to 16 bits?

If so, I suppose it could be done, but I'm not sure what the use case is. Currently, Klipper's hard pwm feature is mostly used as a "poor man's DAC". That is, it's mostly used to approximate an analog voltage level (via resistor/capacitance circuit) for applications that need that. In particular, stepper motor driver reference voltage lines. I've also seen it used to try and provide a lower voltage level to some fans. For these applications I haven't seen a need for more precision or faster switching rates.

How do you intend to use the hardware pwm feature and what precision / switching rate do you need to obtain?

-Kevin

@Cirromulus
Copy link
Contributor Author

Are you proposing that we be able to hit higher frequency cycle times by using less bits in the "on duration" setting?
And similarly, obtain lower frequency cycle times by going up to 16 bits?

Correct. The timers can be resetted when hitting a specific value, effectively increasing the frequency at the expense of resolution, so using a 16-bit timer will not reduce the maximum PWM frequency but even increase it.
And the 16-Bit timers can count further, enabling lower cycle_times.

How do you intend to use the hardware pwm feature and what precision / switching rate do you need to obtain?

I want to use a higher resolution with the laser-extension (laser_fork, #133).
I've extended the printer to easily exchange the printer-head with a laser-head, which works quite nicely.
For raster engraving, the bit-depth of a hard-PWM limits the number of available shades, which is a limitation with materials that require less laser power (e.g. 50% max power -> half of the resolution gone).
I have quite good results with a PWM frequency of 1kHz, wich is well in the range of both the current 8-Bit implementation and a possible 16-Bit implementation.

@KevinOConnor
Copy link
Collaborator

Okay, I understand.

I have quite good results with a PWM frequency of 1kHz, wich is well in the range of both the current 8-Bit implementation and a possible 16-Bit implementation.

FYI, a 1ms cycle_time is well within the range of the software pwm implementation. And the software pwm code will provide excellent precision. The software pwm code can have some scheduling jitter, but I'd guess it would be less than 20us for at least 99.9% of updates on AVR (and likely <5us for ARM chips). I don't know if that kind of jitter is acceptable for your application though.

If you do feel it's necessary to use hard pwm, my suggestion would be to not attempt to increase the frequency. (Thus always having at least 8bits of precision, and not make notable changes to the 8-bit timers.) For the 16bit timers, though, I don't see any harm in bit shifting to obtain similar cycle times with higher precision.

-Kevin

@KevinOConnor
Copy link
Collaborator

I'd also mention that bit shifting an arbitrary amount (eg, x>>y) is painfully slow on AVR. The compiler will actually translate it into something like while (y--) x>>=1;. So, if you do want to update hard pwm on AVR, you might want to consider only supporting something like "no shift", "shift by 4", or "shift by 8". (Shifting by static multiples of 4 is fine on AVR.)

-Kevin

@Cirromulus
Copy link
Contributor Author

FYI, a 1ms cycle_time is well within the range of the software pwm implementation. And the software pwm code will provide excellent precision.

I did not expect it to be, but that would be great. Then I would not need the 16-bit HW-PWM resolution.
I feared that soft-pwm would increase the load on the MCU. Currently, 400-500 PWM updates per second are reliably doable.

I don't know if that kind of jitter is acceptable for your application though.

I will test that. 20µs at 1ms cycle time is 2%, thats probably unnoticable.

@Cirromulus
Copy link
Contributor Author

I tested the soft-pwm with good results.
The jitter is bigger than hard-PWM, but only noticeable with my Oscilloscope. In 1000 pulses, it jitters around 10 microseconds.
This is enough for me to not pursue the 16-bit hard-PWM.
Thanks!

@Cirromulus Cirromulus closed this Dec 14, 2020
@github-actions github-actions bot locked and limited conversation to collaborators Oct 18, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants