Skip to content
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

Make digital pin traits fallible #97

Closed
wants to merge 17 commits into from
Closed
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,22 @@ and this project adheres to [Semantic Versioning](http://semver.org/).

## [Unreleased]

### Added

- A `FallibleOutputPin` trait has been added. It is a version of the `OutputPin` trait
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this needs to be updated to match the feature based approach, and we probably need to document that this release is opt-in and the next will be opt-out.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

where the methods return a `Result` type as setting an output pin could potentially fail.
The current `OutputPin` method signatures will become deprecated in a future version and
will be replaced by the ones defined in `FallibleOutputPin`.
After that, the `FallibleOutputPin` trait will be removed.
See [here](https://github.com/rust-embedded/embedded-hal/issues/95) for more info.

### Changed

- [breaking-change] The unproven `InputPin` trait methods are now fallible, as reading an input
could potentially fail. Similarly, the methods in the unproven `ToggleableOutputPin` trait
are now also fallible.
See [here](https://github.com/rust-embedded/embedded-hal/issues/95) for more info.

## [v0.2.1] - 2018-05-14

### Changed
Expand Down
59 changes: 45 additions & 14 deletions src/digital.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,25 @@ pub trait OutputPin {
fn set_high(&mut self);
}

/// Single digital push-pull output pin
/// (Fallible version. The OutputPin trait will adopt this interface in the future)
pub trait FallibleOutputPin {
/// Error type
type Error;

/// Drives the pin low
///
/// *NOTE* the actual electrical state of the pin may not actually be low, e.g. due to external
/// electrical sources
fn set_low(&mut self) -> Result<(), Self::Error>;

/// Drives the pin high
///
/// *NOTE* the actual electrical state of the pin may not actually be high, e.g. due to external
/// electrical sources
fn set_high(&mut self) -> Result<(), Self::Error>;
}

/// Push-pull output pin that can read its output state
///
/// *This trait is available if embedded-hal is built with the `"unproven"` feature.*
Expand All @@ -41,28 +60,35 @@ pub trait StatefulOutputPin {
/// implemented. Otherwise, implement this using hardware mechanisms.
#[cfg(feature = "unproven")]
pub trait ToggleableOutputPin {
/// Error type
type Error;

/// Toggle pin output.
fn toggle(&mut self);
fn toggle(&mut self) -> Result<(), Self::Error>;
}

/// If you can read **and** write the output state, a pin is
/// toggleable by software.
///
/// ```
/// use embedded_hal::digital::{OutputPin, StatefulOutputPin, ToggleableOutputPin};
/// use embedded_hal::digital::{FallibleOutputPin, StatefulOutputPin, ToggleableOutputPin};
/// use embedded_hal::digital::toggleable;
///
/// /// A virtual output pin that exists purely in software
/// struct MyPin {
/// state: bool
/// }
///
/// impl OutputPin for MyPin {
/// fn set_low(&mut self) {
/// impl FallibleOutputPin for MyPin {
/// type Error = void::Void;
///
/// fn set_low(&mut self) -> Result<(), Self::Error> {
/// self.state = false;
/// Ok(())
/// }
/// fn set_high(&mut self) {
/// fn set_high(&mut self) -> Result<(), Self::Error> {
/// self.state = true;
/// Ok(())
/// }
/// }
///
Expand All @@ -79,30 +105,32 @@ pub trait ToggleableOutputPin {
/// impl toggleable::Default for MyPin {}
///
/// let mut pin = MyPin { state: false };
/// pin.toggle();
/// pin.toggle().unwrap();
/// assert!(pin.is_set_high());
/// pin.toggle();
/// pin.toggle().unwrap();
/// assert!(pin.is_set_low());
/// ```
#[cfg(feature = "unproven")]
pub mod toggleable {
use super::{OutputPin, StatefulOutputPin, ToggleableOutputPin};
use super::{FallibleOutputPin, StatefulOutputPin, ToggleableOutputPin};

/// Software-driven `toggle()` implementation.
///
/// *This trait is available if embedded-hal is built with the `"unproven"` feature.*
pub trait Default: OutputPin + StatefulOutputPin {}
pub trait Default: FallibleOutputPin + StatefulOutputPin {}

impl<P> ToggleableOutputPin for P
where
P: Default,
{
type Error = P::Error;

/// Toggle pin output
fn toggle(&mut self) {
fn toggle(&mut self) -> Result<(), Self::Error> {
if self.is_set_low() {
self.set_high();
self.set_high()
} else {
self.set_low();
self.set_low()
}
}
}
Expand All @@ -113,9 +141,12 @@ pub mod toggleable {
/// *This trait is available if embedded-hal is built with the `"unproven"` feature.*
#[cfg(feature = "unproven")]
pub trait InputPin {
/// Error type
type Error;

/// Is the input pin high?
fn is_high(&self) -> bool;
fn is_high(&self) -> Result<bool, Self::Error>;

/// Is the input pin low?
fn is_low(&self) -> bool;
fn is_low(&self) -> Result<bool, Self::Error>;
}