cpu/fe310: add pwm peripheral driver#12953
Conversation
f81822b to
b8c1e78
Compare
b8c1e78 to
e543a05
Compare
e543a05 to
7890b7d
Compare
|
rebased |
fjmolinas
left a comment
There was a problem hiding this comment.
Looks good, one minor comment. Will test on monday.
| * @{ | ||
| */ | ||
| #define PWM_NUMOF (3) | ||
| static const pwm_conf_t pwm_config[] = { |
There was a problem hiding this comment.
Seems like hifive1 and hhifive1b can share the config.
| uint8_t scale = 0; | ||
| while ((scale < (PWM_CMPWIDTH - 1)) && | ||
| (freq * res) > (uint32_t)(1 << (scale + PWM_CMPWIDTH))) { | ||
| scale++; | ||
| } |
There was a problem hiding this comment.
This calculation seems very bad to me, how can you get a good approximation of freq without taking the cpu_freq into account? It results in very weird frequency settings that do not make much sense.
If you want full resolution for example that means you can only scale the register. But if you wan't only lets say 8 bits of resolution then you have 8 more to tune the desired frequency. For me the calculation should take into account:
- bits left over by desired resolution:
res/2^16 cpu_freq
We are basically trying to resolve:
min CPU_FREQ * (2^x)/(2^(16-scale)) - freq, where x = 1...2^rembits and scale = 0...(PWM_CMPWIDTH - 1). I don't know efficient algorithms to find this, would have to think about it more. But one way would be find a scale which gives you a PWM_FREQ higher than freq and then trim the value with the remaining resolution bits. Another option is for every scale find the best match and then compare them all.
For the first suggestion.
- In pseudo code: find scaling that fives you a
PWM_FREQ > freq:
uint8_t scale = (PWM_CMPWIDTH - 1);
while ((scale > 0) &&
cpu_freq() / (uint32_t)(1 << (scale + PWM_CMPWIDTH)) << freq) {
scale--;
}
- Use the leftover bits for the required resolution to trim
PWM_FREQas close tofreqas possible
Then those leftover bits or rem_res give you more wiggle room to set the a freq closest to the desired one.
7890b7d to
11ec164
Compare
|
I removed the Murdock label to get this one out of the queue. |
|
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. If you want me to ignore this issue, please mark it with the "State: don't stale" label. Thank you for your contributions. |
|
Needs a rebase |
|
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. If you want me to ignore this issue, please mark it with the "State: don't stale" label. Thank you for your contributions. |
Contribution description
This PR implements the PWM driver for RISC-V FE310 CPU and adds a basic configuration for Sifive HiFive1 and HiFive1b boards.
Since a valid core clock value is required, this PR is based on #12519.
Testing procedure
tests/periph_pwmapplication on a Hifive1/b board:oscishell commandYou should see the on-board leds oscillate synchronously (they are connected to an RGD led, so the led oscillates in white). You can also plug a led on the other configured pins (Arduino D4, D16, D17) and watch them oscillate as well.
Issues/PRs references
Based on #12934