-
Notifications
You must be signed in to change notification settings - Fork 202
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
Move reading functions from OutputPin trait to StatefulOutputPin #72
Conversation
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'm very much in favour of this change but I'd like a second opinion about how we're going to do this.
Also are you planning to follow up with the additional traits?
See #73. |
Please refresh your browser, I edited my comment several times. :) Sorry! I think this and #73 are separate problems. You can implement |
Err, yes, my bad, the comment was really meant for #73. Let me move it there. |
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.
Looks good to me! Thank you, @astro.
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'd prefer having the composable traits instead of a composed trait but it is better than what we have now so I'm good with it.
The only problem I see is that this might potentially break existing implementations?
As I stated before elsewhere, I don't think we should be losing sleep over backwards-compatibility at this point. Yes, breaking implementations sucks, but I'm more concerned about whether embedded-hal is going to look good a few years from now. |
@hannobraun That's fine with me, too. Just wanted to raise the concern others might have to feel whether there's consensus on that topic. |
FWIW, I'm totally of @hannobraun's opinion. Break things early, if they're to break at all |
src/digital.rs
Outdated
/// Is the pin set to low? | ||
fn is_set_low(&self) -> bool; | ||
|
||
/// Toggle pin output |
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.
Sorry if I am late to the party. Can you override a method in a trait? On some cores toggle is exposed as a separate register / no read state is required.
I'd propose having the toggle as a separate trait that you can implement on StatefulOutputPin if toggle function is not available.
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.
As discussed in #31 (et al) I also think that different capabilities should be modelled in different composable (and mode dependent) traits instead of being munged together into a few traits that do a lot of things at once. Something like is_set_low()
on a StatefulOutputPin
is not clear what it actually means, i.e. is that supposed to be the electrical or the logical state of the pin? For toggle()
it has to be the latter, not the former, in other cases you might want to have the electrical state, though and cannot have this. Also (as you said) there are implementations allowing an efficient toggle without reading the logical state from a pin. There might even be implementations which do not allow you to read back the logical state, although I don't recall any from the top of my head.
I only agreed to moving it out of OutputPin
because it belongs there even less and this change turns into into an unproven
functionality so if it doesn't provide the hoped for benefit (as I suspect it will not) then we can replace it by something better.
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.
Sounds reasonable. I'll remove it in favour of adding ToggleableOutputPin
later.
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.
Can you override a method in a trait?
I have moved Also, I removed the |
99b9937
to
81f3408
Compare
… impl for StatefulOutputPin
81f3408
to
ac965a3
Compare
src/digital.rs
Outdated
/// toggleable by software. You may override the `toggle()` method | ||
/// with a hardware implementation. | ||
#[cfg(feature = "unproven")] | ||
impl<PIN: OutputPin + StatefulOutputPin> ToggleableOutputPin for PIN { |
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.
Would it be good to add an empty DefaultToggle
trait here, and thus make this implementation opt-in rather than opt-out?
It would match the way the blocking SPI traits are handled. On the other hand, this is a simpler implementation.
I'm not particularly attached to one way or the other, but I do think consistency throughout the embedded-hal
will be valuable.
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.
Thanks for the suggestion. I added that now by copying the style of the opt-in default traits in spi
and serial
. I hope that the doc example is helpful.
b47006d
to
2fd1a3a
Compare
2fd1a3a
to
6549d73
Compare
Is there anything I can do to help this move forward? |
/// Sets the pin low | ||
fn set_low(&mut self); | ||
|
||
/// Sets the pin high | ||
fn set_high(&mut self); | ||
} | ||
|
||
/// Output pin that can read its output state |
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.
As I've mentioned before there's a distinction between a logical state and an electrical state. It should be made clear that this is meant to represent the logical (or register) state of a pin and not the electrical state.
/// Output pin that can read its output state | ||
#[cfg(feature = "unproven")] | ||
pub trait StatefulOutputPin { | ||
/// Is the pin set to high? |
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.
A pin could also be logically floating so either it needs to be made clear that a tri-stated pin may not implement this trait or that the implicit assumption p.is_set_high() == !p.is_set_low()
does not necessarily hold and should not be assumed.
This seems OK to me but it should be explicitly noted that these traits should be implemented only for push pull output pins and that low / high are referring to the electrical output of the pin. That was missing in the original trait as well. @hannobraun just for the record: releasing a new minor version doesn't "just breaks implementations"; it fragments the ecosystem. Once a HAL implementation moves from e.g. v0.1.x to v0.2.x it can no longer be used with driver crates that depend on embedded hal v0.1.x. This happens even if the trait that the driver crate uses as a bound has not changed at all between the two minor releases. This situation increases the maintenance work of driver authors which now have to publish a new minor version of their crate that supports the new embedded-hal and probably will also have to maintain the v0.1.x version until all / most-of the existing / active / maintained HAL implementations move to v0.2.x. So bumping the minor version shouldn't be done often / lightly; as the embedded-hal ecosystem grows we'll have to allow more "settling time" between each new minor version release. That being said we have to make a new minor version release beacuse of #80 so let's include this PR which also contains breaking changes in v0.2.0. @astro could you update the docs? |
I disagree. We can not make any assumption of the electrical state of a pin, only the logical state. Even if you drive it low on a push/pull pin there might be a stronger source keeping it high and vice versa. |
@therealprof point taken I'll merge this PR as it is and adjust the docs locally before releasing v0.2.0. Thanks for the PR, @astro! bors r+ |
👎 Rejected by code reviews |
bors r+ |
👎 Rejected by code reviews |
docs will be updated in a follow up commit
bors r+ |
72: Move reading functions from OutputPin trait to StatefulOutputPin r=japaric a=astro As it has come up in #29, here is a proposal for removing the burden of caching the state on implementations that cannot read it from an output pin. Co-authored-by: Astro <[email protected]>
Build succeeded |
Good point, thanks for the explanation. While that doesn't change my stance about breaking changes in general, it's good to keep in mind that we need to release them strategically. |
As it has come up in #29, here is a proposal for removing the burden of caching the state on implementations that cannot read it from an output pin.