Skip to content

Commit

Permalink
Merge #108
Browse files Browse the repository at this point in the history
108: Add fallible version of the digital traits and deprecate the current ones r=ryankurte a=eldruin

There seems to be an agreement in [#100](#100 (comment)) on how to proceed with the fallible traits.
This adds the fallible traits under `digital::v2` and marks the current ones as deprecated.

Co-authored-by: Diego Barrios Romero <eldruin@gmail.com>
Co-authored-by: Ryan <ryankurte@users.noreply.github.com>
  • Loading branch information
3 people committed Nov 28, 2018
2 parents 98a6fb8 + 14cac99 commit 63a553c
Show file tree
Hide file tree
Showing 4 changed files with 213 additions and 25 deletions.
15 changes: 15 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,20 @@ and this project adheres to [Semantic Versioning](http://semver.org/).

## [Unreleased]

### Added
- A new version of the digital `OutputPin`, `StatefulOutputPin`, `ToggleableOutputPin`
and `InputPin` traits has been added under `digital::v2`. These traits are now
fallible and their methods now return a `Result` type as setting an output pin
and reading an input pin could potentially fail.
See [here](https://github.com/rust-embedded/embedded-hal/issues/95) for more info.

### Changed
- The current versions of the `OutputPin`, `StatefulOutputPin`, `ToggleableOutputPin`
and `InputPin` traits have been marked as deprecated. Please use the new versions
included in `digital::v2`.
See [here](https://github.com/rust-embedded/embedded-hal/issues/95) for more info.


## [v0.2.2] - 2018-11-03

### Added
Expand All @@ -21,6 +35,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
### Changed
- Updated docs to clarify I2C address bit widths and expectations.


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

### Changed
Expand Down
155 changes: 155 additions & 0 deletions src/digital/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
//! Digital I/O
//!
//! The traits in this module are now deprecated. Please use the new versions included
//! in `digital::v2`.
/// Single digital push-pull output pin
///
/// *This version of the trait is now deprecated. Please use the new `OutputPin` trait in
/// `digital::v2::OutputPin`*.
#[deprecated(since = "0.2.2", note = "Deprecated because the methods cannot return errors. \
Users should use the traits in digital::v2.")]
pub trait OutputPin {
/// 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);

/// 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);
}

/// Push-pull output pin that can read its output state
///
/// *This trait is available if embedded-hal is built with the `"unproven"` feature.*
///
/// *This version of the trait is now deprecated. Please use the new `StatefulOutputPin` trait in
/// `digital::v2::StatefulOutputPin`*.
#[deprecated(since = "0.2.2", note = "Deprecated because the methods cannot return errors. \
Users should use the traits in digital::v2.")]
#[cfg(feature = "unproven")]
pub trait StatefulOutputPin {
/// Is the pin in drive high mode?
///
/// *NOTE* this does *not* read the electrical state of the pin
fn is_set_high(&self) -> bool;

/// Is the pin in drive low mode?
///
/// *NOTE* this does *not* read the electrical state of the pin
fn is_set_low(&self) -> bool;
}

/// Output pin that can be toggled
///
/// *This trait is available if embedded-hal is built with the `"unproven"` feature.*
///
/// *This version of the trait is now deprecated. Please use the new `ToggleableOutputPin`
/// trait in `digital::v2::ToggleableOutputPin`*.
///
/// See [toggleable](toggleable) to use a software implementation if
/// both [OutputPin](trait.OutputPin.html) and
/// [StatefulOutputPin](trait.StatefulOutputPin.html) are
/// implemented. Otherwise, implement this using hardware mechanisms.
#[deprecated(since = "0.2.2", note = "Deprecated because the methods cannot return errors. \
Users should use the traits in digital::v2.")]
#[cfg(feature = "unproven")]
pub trait ToggleableOutputPin {
/// Toggle pin output.
fn toggle(&mut self);
}

/// If you can read **and** write the output state, a pin is
/// toggleable by software.
///
/// *This version of the module is now deprecated. Please use the new `toggleable` module in
/// `digital::v2::toggleable`*.
///
/// ```
/// use embedded_hal::digital::{OutputPin, 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) {
/// self.state = false;
/// }
/// fn set_high(&mut self) {
/// self.state = true;
/// }
/// }
///
/// impl StatefulOutputPin for MyPin {
/// fn is_set_low(&self) -> bool {
/// !self.state
/// }
/// fn is_set_high(&self) -> bool {
/// self.state
/// }
/// }
///
/// /// Opt-in to the software implementation.
/// impl toggleable::Default for MyPin {}
///
/// let mut pin = MyPin { state: false };
/// pin.toggle();
/// assert!(pin.is_set_high());
/// pin.toggle();
/// assert!(pin.is_set_low());
/// ```
#[deprecated(since = "0.2.2", note = "Deprecated because the methods cannot return errors. \
Users should use the traits in digital::v2.")]
#[cfg(feature = "unproven")]
pub mod toggleable {
#[allow(deprecated)]
use super::{OutputPin, StatefulOutputPin, ToggleableOutputPin};

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

#[allow(deprecated)]
impl<P> ToggleableOutputPin for P
where
P: Default,
{
/// Toggle pin output
fn toggle(&mut self) {
if self.is_set_low() {
self.set_high();
} else {
self.set_low();
}
}
}
}

/// Single digital input pin
///
/// *This trait is available if embedded-hal is built with the `"unproven"` feature.*
///
/// *This version of the trait is now deprecated. Please use the new `InputPin` trait in
/// `digital::v2::InputPin`*.
#[deprecated(since = "0.2.2", note = "Deprecated because the methods cannot return errors. \
Users should use the traits in digital::v2.")]
#[cfg(feature = "unproven")]
pub trait InputPin {
/// Is the input pin high?
fn is_high(&self) -> bool;

/// Is the input pin low?
fn is_low(&self) -> bool;
}

/// Improved version of the digital traits where the methods can also return an error.
pub mod v2;
65 changes: 40 additions & 25 deletions src/digital.rs → src/digital/v2.rs
Original file line number Diff line number Diff line change
@@ -1,34 +1,37 @@
//! Digital I/O
/// Digital I/O
/// Single digital push-pull output pin
pub trait OutputPin {
/// 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);
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);
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.*
#[cfg(feature = "unproven")]
pub trait StatefulOutputPin {
pub trait StatefulOutputPin : OutputPin {
/// Is the pin in drive high mode?
///
/// *NOTE* this does *not* read the electrical state of the pin
fn is_set_high(&self) -> bool;
fn is_set_high(&self) -> Result<bool, Self::Error>;

/// Is the pin in drive low mode?
///
/// *NOTE* this does *not* read the electrical state of the pin
fn is_set_low(&self) -> bool;
fn is_set_low(&self) -> Result<bool, Self::Error>;
}

/// Output pin that can be toggled
Expand All @@ -41,48 +44,55 @@ 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::toggleable;
/// use embedded_hal::digital::v2::{OutputPin, StatefulOutputPin, ToggleableOutputPin};
/// use embedded_hal::digital::v2::toggleable;
///
/// /// A virtual output pin that exists purely in software
/// struct MyPin {
/// state: bool
/// }
///
/// impl OutputPin for MyPin {
/// fn set_low(&mut self) {
/// 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(())
/// }
/// }
///
/// impl StatefulOutputPin for MyPin {
/// fn is_set_low(&self) -> bool {
/// !self.state
/// fn is_set_low(&self) -> Result<bool, Self::Error> {
/// Ok(!self.state)
/// }
/// fn is_set_high(&self) -> bool {
/// self.state
/// fn is_set_high(&self) -> Result<bool, Self::Error> {
/// Ok(self.state)
/// }
/// }
///
/// /// Opt-in to the software implementation.
/// impl toggleable::Default for MyPin {}
///
/// let mut pin = MyPin { state: false };
/// pin.toggle();
/// assert!(pin.is_set_high());
/// pin.toggle();
/// assert!(pin.is_set_low());
/// pin.toggle().unwrap();
/// assert!(pin.is_set_high().unwrap());
/// pin.toggle().unwrap();
/// assert!(pin.is_set_low().unwrap());
/// ```
#[cfg(feature = "unproven")]
pub mod toggleable {
Expand All @@ -97,12 +107,14 @@ pub mod toggleable {
where
P: Default,
{
type Error = P::Error;

/// Toggle pin output
fn toggle(&mut self) {
if self.is_set_low() {
self.set_high();
fn toggle(&mut self) -> Result<(), Self::Error> {
if self.is_set_low()? {
self.set_high()
} else {
self.set_low();
self.set_low()
}
}
}
Expand All @@ -113,9 +125,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>;
}
3 changes: 3 additions & 0 deletions src/prelude.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,13 @@ pub use blocking::serial::Write as _embedded_hal_blocking_serial_Write;
pub use blocking::spi::{
Transfer as _embedded_hal_blocking_spi_Transfer, Write as _embedded_hal_blocking_spi_Write,
};
#[allow(deprecated)]
#[cfg(feature = "unproven")]
pub use digital::InputPin as _embedded_hal_digital_InputPin;
#[allow(deprecated)]
pub use digital::OutputPin as _embedded_hal_digital_OutputPin;
#[cfg(feature = "unproven")]
#[allow(deprecated)]
pub use digital::ToggleableOutputPin as _embedded_hal_digital_ToggleableOutputPin;
pub use serial::Read as _embedded_hal_serial_Read;
pub use serial::Write as _embedded_hal_serial_Write;
Expand Down

0 comments on commit 63a553c

Please sign in to comment.