Looking at the mbed driver code, I do see some weirdness.
First of all, the code doesn’t properly handle periods smaller than about 10us, because doing that would require using a smaller count_top
constant (the value at which the PWM counter resets), which it isn’t smart enough to do. Additionally, with count_top
fixed to 1000, and a max clock divider of 256, the longest possible duty cycle is 1/(133MHz / 256 / 1000) = ~2ms.
It also has resolution problems – it doesn’t use the fractional part of the clock divider pwm_config_set_clkdiv_int_frac()
, so the frequency resolution is lower than it could be. Additionally, with count_top
locked to 1000, the duty cycle resolution is locked to 1/1000, when it could be 1/65536 (using the full 16 bit counter).
I think this code should be updated so that it dynamically determines count_top based on the frequency. It should use count_top = 65536 in most cases, but if the calculated clock divider would be less than 1, it should decrease count_top as needed so that the lower period can be accommodated. That should restore the full frequency range.