-
Notifications
You must be signed in to change notification settings - Fork 62
PWM support #26
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
Comments
I'd be very interested to take a crack at doing some trait witchcraft in the hope of getting the flexibility of the second solution while maintaining compile time verification. I'll see what I can do, though im not certain how much free time I will have to look at it immediately. |
I think we should do the first variant. Being able to use multiple is also possible with variant one (by just configuring a pin to the af, without doing anything else with it), but that isn't the most used variant. I'd also propose adding an Implementing PWM this way would make using it the most common way (one pin per channel) really obvious and safe, while also allowing the other variants with obvious patterns in the code. As an aside: I think having a type safe interface is important, even though it is a lot of overhead. Maybe we could consolidate all the different bindings for gpios in the future in a bindings.rs file, with all the afs implemented in one spot, this would also make comparing it with the data sheet easier. |
I agree with everything @david-sawatzke said. I prefer the first approach because it gives us more compile time guarantees which is one of the main things I appreciate about doing embedded dev with Rust. I definitely like the idea of having an |
Unlike most other peripherals which are really only useful if they're actually connected to something this is not the case for the PWM (or other timer functions). While the But you're right we should have this for other peripherals... NB: We already have those filler types here https://github.com/stm32-rs/stm32f4xx-hal/ and could reuse that approach. |
This issue is not about about sacrificing compile time guarantees but about usability and flexibility. The |
It does support it by virtue of just being able to configure other pins to the right af. This is (afaict) also what you'd need to do in approach 2, so no usability is lost, and it does make the more unusual and more often wrong approach of driving multiple pins with the same pwm channel possible, but hard to do accidentally |
And how is that a safe interface?
No, the idea is a different one: You configure a channel and then you can assign the correct pins in the correct configuration to the appropriate channel, turning them into a
Sorry, I could not disagree more. It is very common to drive as many pins as possible with the least amount of timers (and potentially also use some extended features like safety mode) or to use complimentary PWM signals. This is a very important use case and should be just as safe and sane to use as the "fade this single LED" implementation. |
I don't see it. The basic api is
And the pins just implement the If @HarkonenBade implements a method to attach multiple pins, we should distinguish complimentary and normal channels anyway. I do agree that it would be nice if the additional pins where type-checked somewhere, but that's not what approach 2 is doing (afaict). |
Mmm, Also part of me feels like an appropriate thing to do would be to handle the AF selection internally. It feels like a more pleasing interface to just require say an |
Yeah, because it's not implemented yet and the main reason why I put it up for discussion (and possibly someone to come up with a clever implementation, cf. #26 (comment))
Seems you're quite the complexity junkie. 😏 |
Ah, sorry, forgot about that
I'd hate to have a long debugging session with the exact wrong values until i look in the data sheet and see that it's inverted, so i think that's somewhat necessary |
There're so many ways to mess up the setup. An inverted output will mostly likely be the very least of your problems and is easily corrected, too. |
Not sure there's a lot of benefit in that approach. Sounds like a ton of complexity (if possible to implement at all) with little benefit. If the interface is decent then rustc is quite good at pointing problems with wrong mode selections...
Maybe it would more sense to implement the |
Anything ever get decided on this? Would love to have PWM support integrated in to the HAL! |
@bentwire Nope. Slow going at the moment... |
I may be of assistance. I'm new to rust but could probably help with this at least some. :-) |
Is there any progress on this topic? If not, maybe I could help with the implementation of PWM support in this crate. As I am still new to rust, I would probably need some more extensive review. However I do have knowledge about embedded systems and ARM in particular. Also, I would have some hardware (nulceo-f042k6) and oscilloscope at hand to check if it works. I have checked the PWM implementations in other stm32f*xx-hal crates and wonder a bit, why each crate takes a different approach, since to my understanding ARM Cortex-M0 and M3 are not too different. Recently in the stm32f1xx-hal crate there was a PR merged regarding PWM support and I wonder if it could be ported to the stm32f0xx-hal crate. |
The different families have different generations and versions of peripherals. Some of the code might be portable with a bit of effort, other code is better written from scratch. Timers are especially tricky in this regard because even on the same model they're a usually a few different which makes coming up with a general approach even harder. |
Thanks for your explanation, I was not aware of this. I also see in stm32f1xx-hal the handling of the AF pins is done quite differently. |
I find myself really needing PWM all of a sudden. Did we have any general opinions about this stuff? |
Well, we do have implementations, e.g. in |
Are there any that mesh well with how GPIOs and similar are implemented in the f0-hal? |
I don't see why https://github.com/stm32-rs/stm32f4xx-hal/blob/master/src/pwm.rs wouldn't work for F0 in a pinch. I think the timers in the F4 are pretty much feature complete already so F0 should have mostly the same concepts and implementation. |
Any movement on this? PWM seems like a pretty critical feature. |
We're open for PRs 24/7. 😉 |
I've just started reading through the f4 pwm implementation - so I'll give it my best effort. I'm pretty new to Rust so it may be a bit over my head. |
I would also be happy to sponsor this feature. |
@kiranshila sorry, that I steal you the fun to implement it. I didn't saw your comment until I had it implemented. |
I'm glad you did! I got pretty overwhelmed with trying to figure out which variants had which timers. |
I started implementing PWM for this crate in two slightly different ways:
Approach one
https://github.com/stm32-rs/stm32f0xx-hal/tree/features/pwm
This uses the typical approach of initialising the PWM peripheral with the timer and pins to use for PWM. The code is loosely based on https://github.com/stm32-rs/stm32f1xx-hal/blob/master/src/pwm.rs and I can see a number of advantages and disadvantages with this.
Advantages:
Disadvantages:
Approach two
https://github.com/stm32-rs/stm32f0xx-hal/tree/features/pwm-alternate
This approach only binds the timer to provide 4 PWM channels without any association to a GPIO.
Advantages:
Disadvantages:
I'm a bit on the fence which variant we should go for. Approach one is rather limiting, especially if we want to support advanced uses of PWM (and maybe other nice timer features). It is also very complex to implement for all chips and all possible combinations at once. On the other hand it would be great to have a way of telling a user that some timer/channel/GPIO combination will not work or is incorrectly configured.
Ideas?
CC @zklapow
The text was updated successfully, but these errors were encountered: