I noticed in your code, you are setting the duty cycle to 0%, so the signal would be low all the time. Try again setting the duty cycle to 50% for example.
I'll recommend you these two posts:
You might find them interesting. The first post is about setting the PWM to 48Hz, which means almost 20ms period. The other post is about something similar but the user attached a code that could be interesting to you. Have a nice day.
Hi Diego, thanks for your reply. The problem is not with the duty cycle. As I said, I can make it work correctly for low periods using bash or C, the problem is with periods over 8ms.
After a bit of research I realised the source of this issue. It relies on the capabilities of the Cypress CY8C9540A I/O expander. The default clock source of this chip is 32kHz. With an 8-bit resolution, it can be driven down to a minimum of 32000Hz / 256 = 125 Hz = 8ms. The OS knows there's an error setting a frequency lower than this one since the chip interrupts it whenever an erroneous frequency is set.
Anyhow, the PWM clock source for this chip can also be set to 367.6 Hz, which could be divided by 7 to obtain a frequency of 52.5 Hz. The PWM config register must be set accordingly to achieve this.
I'm working on a solution, I'll post it here if I succeed.
For 20 ms a divider value shall be 31250Hz / 50Hz = 625, but 625 > 255 = PWM_MAX_PERIOD. So, a clock source 32kHz is not a way.
As I see an usage of REG_PWM_CLK (or Config PWM 29h) to select clock source is not implemented in SD Card Linux v1.0.3
It is required to rewrite cy8c9540a_pwm_config procedure and add REG_PWM_CLK register support.
I've been making progress with this and now I'm able to set a 20ms period with some modifications to the CY8C9540A kernel module. The source clock for the Cypress chip is dynamically selected given an input period. There's still lots to do, though:
- Release a patch that can be applied to the galileo build.
- Test frequencies near the clock limits.
- Use the "previous PWM" clock setting of the Cypress chip.