-
Notifications
You must be signed in to change notification settings - Fork 237
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
Missing impls for Pin<_, DynFunction, _> #756
Comments
(I saved some experimental code to https://github.com/jannic/rp-hal/commits/issue-756/) |
Any more progress on this? As it stands I'm not quite sure what the proper way is of implementing something like bitbanged SWD (or bitbanged I2C or anything with a bidirectional pin) without maybe (haven't thought it through) doing a bunch of unsafe things? The |
I didn't work on it because nobody came up with an actual use case. If it helps you to implement SWD I can update the branch and make it a merge request. What do you think about the implementation in the |
Sounds good -- let me play with it a bit to get a feel for it. At first look though I'm not a fan of having the function-check branch on every get/set. One thought I had was to have the API work more like borrowing -- where you could "borrow" a specific-functioned pin from a DynFunction pin. The borrow operation would set the pin's function, and the drop would make it available for borrowing with a possibly-different function again. I can try to implement this if that sounds interesting. |
I'm thinking something like this -- untested yet, and needs separate impls for when you do have a non-dynamic pull type (or probably not necessary, you probably want a dynamic pull type if you want a dynamic function). But the idea is to use the borrow checker to allow borrowing the pin as a specific typed pin, relying on
|
Hmm, this looks quite complicated. Is it really worth the effort and the unsafe code? I made a few experiments, and it looks like rustc is able to optimize the repeated function-check branch on every get/set away. At least in easy cases like calling the same function multiple times in a row. But then, I agree that your approach can potentially provide a better API to the user. And having some unsafe code inside the HAL might be a sensible tradeoff if it really simplifies application code. |
Yeah, the code can be even simplified, I don't think I need the separate explicit functions.. it just seemed cleaner. But I'm still working on making it work. Will report! |
Ok, here's a take at this: main...vvuk:rp-hal:dyn-pins There's one serious but I think fixable issue -- I wanted to point it out first in case there are better ideas. Because
the different One fix would be to define the concrete functions to have a field of the dynamic enum, i.e.:
which would give it the same size as This is annoying, because I really like the ergonomic API (see the gpio example). But I don't think it's acceptable to suddenly require passing around a ref to useless data to use fully statically-defined pins. So the idea... always have |
Actually, this won't work. This approach or even the original approach wouldn't let you dynamically reconfigure a pin as a Whether for SWD or bitbanged I2C or whatever, what we're really talking about is using a pin for both input and output SIO. So let's just implement That struct itself could store some state, and allow you to e.g. configure the state of pullups differently for when it's in input or output mode, and give you an easy way to toggle between the two modes. I think |
Bitbanged I2C already has a type in the hal (InOutPin). The more I think about it, the more it seems to me that a newtype relying on the overrides would be much simpler and cleaner than trying to shoehorn a solution with unsafe :S |
Hm do you mean But I think in order to implement that, we need a |
I mean https://docs.rs/rp2040-hal/latest/rp2040_hal/gpio/struct.InOutPin.html It differs from what you need for SWD in that it switches between driven low and "floating". |
There are currently not many useful functions implemented for
Pin<_, DynFunction, _>
. Therefore, pins configured that way can not be used without converting them to a pin with a statically defined function first. That defeats the idea of having aDynFunction
in the first place.One could, for example, implement
OutputPin
like this:It may be useful to first describe use cases for
DynFunction
where it's not feasible to just use a statically defined function.The text was updated successfully, but these errors were encountered: