-
Notifications
You must be signed in to change notification settings - Fork 242
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
Reconfigure Spi new functions for better type inference #706
Conversation
Seems to be a good tradeoff. In many cases, the word size will be 8 bits anyway, so calling the new API gets simpler. And for other word sizes, the change to |
rp2040-hal/src/spi.rs
Outdated
/// | ||
/// Initialize it with [`.init`][Self::init] | ||
/// or [`.init_slave`][Self::init_slave]. | ||
pub fn new_with_data_size<const DS: u8>(device: D, pins: P) -> Spi<Disabled, D, P, DS> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if this method should be moved down to the impl<D: SpiDevice, P: ValidSpiPinout<D>, const DS: u8> Spi<Disabled, D, P, DS>
block? It's a little bit strange to have the constructor for the bit-generic version in the 8-bit impl.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done. The only awkward thing is that now there is already DS
const generic from the impl block in scope, so I had to rename it on the function level parameter. But not that big of a deal.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see any update on the branch on github. Did you perhaps forget to push it?
Regarding the function level parameter: I think you don't need it at all, you can use the parameter from the impl block:
impl<D: SpiDevice, P: ValidSpiPinout<D>, const DS: u8> Spi<Disabled, D, P, DS> {
[...]
pub fn new_with_data_size(device: D, pins: P) -> Spi<Disabled, D, P, DS> {
[...]
}
[...]
}
Which makes me wonder: Is the new_with_data_size
name confusing, if it's often possible to call it without specifying the data size at the call location? It's enough if the compiler can somehow infer the correct value for DS, eg. if you later store the value in some struct where the type is specified.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
True, but I feel like storing this in a wider struct or somewhere it could be inferred would be relatively uncommon? Maybe I'm mistaken though.
663bf77
to
d18bc27
Compare
/// or [`.init_slave`][Self::init_slave]. | ||
/// | ||
/// Valid pin sets are in the form of `(Tx, Sck)` or `(Tx, Rx, Sck)` | ||
/// | ||
/// If you pins are dynamically identified (`Pin<DynPinId, _, _>`) they will first need to pass | ||
/// validation using their corresponding [`ValidatedPinXX`](ValidatedPinTx). | ||
pub fn new(device: D, pins: P) -> Spi<Disabled, D, P, DS> { | ||
pub fn new(device: D, pins: P) -> Spi<Disabled, D, P, 8> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems to me that choosing 8bits for the fn new
a bit arbitrary.
I understand 8 bits were used as the default for the type before, but I don't think it makes it more correct 😛
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To be fair I don't have that much embedded experience, but it seems like 8 bits as word size is extremely common in general and would at least not be particularly surprising
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That was my assumption as well, but to be honest my experience with embedded peripherals is also quite limited.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had a look at embassy-rp to see how they handle the word width. They don't. It's hard coded to 8 bits. 😄
https://github.com/embassy-rs/embassy/blob/main/embassy-rp/src/spi.rs#L87
I need to try a few thing, to make sure I'm not missing some inference subtleties. EDIT: I made this: ithinuel@90c6c82 Let me know your thoughts. |
I'm not convinced. This is not really getting better with I wonder if we could remove the |
Another option could be to make DS a conventional generic parameter, with different types for the available bit sizes. This would have the additional advantage that it would become impossible to set invalid bit sizes. The current API would allow to configure a device with a bit size of 0 or more than 16 bits. (That device would be unusable though, as the read and write methods are only defined for valid bit sizes.) |
I'm not too attached to that parameter TBH. On a setup with multiple spi peripheral with the rp2040 as one controller on the bus, you may need to change the word size between different peripheral and this generic parameter does not allow for an easy implementation of that usecase. |
I will close this for now, it may still be relevant but not so much work to revive or redo if we want it... |
Does what it says on the tin :) unfortunately a breaking change but it means we can get rid of the
Spi::<_, _, _, 8>::
paradigm.