From d7be300e86d4288c2c145f00abd933f18619440b Mon Sep 17 00:00:00 2001 From: Diego Barrios Romero Date: Sun, 28 Oct 2018 08:41:22 +0100 Subject: [PATCH 1/2] Add fallible version of the digital traits and deprecate the current ones --- CHANGELOG.md | 13 +++ src/{digital.rs => digital/mod.rs} | 29 ++++++ src/digital/v2.rs | 136 +++++++++++++++++++++++++++++ src/prelude.rs | 3 + 4 files changed, 181 insertions(+) rename src/{digital.rs => digital/mod.rs} (76%) create mode 100644 src/digital/v2.rs diff --git a/CHANGELOG.md b/CHANGELOG.md index 2d7abb561..585048a0b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,19 @@ 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.1] - 2018-05-14 ### Changed diff --git a/src/digital.rs b/src/digital/mod.rs similarity index 76% rename from src/digital.rs rename to src/digital/mod.rs index 8f49da3d9..05a8e7c9a 100644 --- a/src/digital.rs +++ b/src/digital/mod.rs @@ -1,6 +1,13 @@ //! 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] pub trait OutputPin { /// Drives the pin low /// @@ -18,6 +25,10 @@ pub trait OutputPin { /// 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] #[cfg(feature = "unproven")] pub trait StatefulOutputPin { /// Is the pin in drive high mode? @@ -35,10 +46,14 @@ pub trait StatefulOutputPin { /// /// *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] #[cfg(feature = "unproven")] pub trait ToggleableOutputPin { /// Toggle pin output. @@ -48,6 +63,9 @@ pub trait ToggleableOutputPin { /// 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; @@ -84,15 +102,19 @@ pub trait ToggleableOutputPin { /// pin.toggle(); /// assert!(pin.is_set_low()); /// ``` +#[deprecated] #[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

ToggleableOutputPin for P where P: Default, @@ -111,6 +133,10 @@ pub mod toggleable { /// 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] #[cfg(feature = "unproven")] pub trait InputPin { /// Is the input pin high? @@ -119,3 +145,6 @@ pub trait InputPin { /// 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; diff --git a/src/digital/v2.rs b/src/digital/v2.rs new file mode 100644 index 000000000..460005eb0 --- /dev/null +++ b/src/digital/v2.rs @@ -0,0 +1,136 @@ +/// 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) -> 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.* +#[cfg(feature = "unproven")] +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) -> Result; + + /// Is the pin in drive low mode? + /// + /// *NOTE* this does *not* read the electrical state of the pin + fn is_set_low(&self) -> Result; +} + +/// Output pin that can be toggled +/// +/// *This trait is available if embedded-hal is built with the `"unproven"` feature.* +/// +/// 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. +#[cfg(feature = "unproven")] +pub trait ToggleableOutputPin { + /// Error type + type Error; + + /// Toggle pin output. + 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::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 { +/// type Error = void::Void; +/// +/// fn set_low(&mut self) -> Result<(), Self::Error> { +/// self.state = false; +/// Ok(()) +/// } +/// fn set_high(&mut self) -> Result<(), Self::Error> { +/// self.state = true; +/// Ok(()) +/// } +/// } +/// +/// impl StatefulOutputPin for MyPin { +/// fn is_set_low(&self) -> Result { +/// Ok(!self.state) +/// } +/// fn is_set_high(&self) -> Result { +/// Ok(self.state) +/// } +/// } +/// +/// /// Opt-in to the software implementation. +/// impl toggleable::Default for MyPin {} +/// +/// let mut pin = MyPin { state: false }; +/// pin.toggle().unwrap(); +/// assert!(pin.is_set_high().unwrap()); +/// pin.toggle().unwrap(); +/// assert!(pin.is_set_low().unwrap()); +/// ``` +#[cfg(feature = "unproven")] +pub mod toggleable { + use super::{OutputPin, StatefulOutputPin, ToggleableOutputPin}; + + /// Software-driven `toggle()` implementation. + /// + /// *This trait is available if embedded-hal is built with the `"unproven"` feature.* + pub trait Default: OutputPin + StatefulOutputPin {} + + impl

ToggleableOutputPin for P + where + P: Default, + { + type Error = P::Error; + + /// Toggle pin output + fn toggle(&mut self) -> Result<(), Self::Error> { + 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.* +#[cfg(feature = "unproven")] +pub trait InputPin { + /// Error type + type Error; + + /// Is the input pin high? + fn is_high(&self) -> Result; + + /// Is the input pin low? + fn is_low(&self) -> Result; +} diff --git a/src/prelude.rs b/src/prelude.rs index ce1a5e18a..1ec4cd9ec 100644 --- a/src/prelude.rs +++ b/src/prelude.rs @@ -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; From 421d11bdd590111f26931d68271b18681c72a862 Mon Sep 17 00:00:00 2001 From: Diego Barrios Romero Date: Sun, 28 Oct 2018 16:30:04 +0100 Subject: [PATCH 2/2] Add deprecation version and note --- src/digital/mod.rs | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/digital/mod.rs b/src/digital/mod.rs index 05a8e7c9a..5784f0fbe 100644 --- a/src/digital/mod.rs +++ b/src/digital/mod.rs @@ -7,7 +7,8 @@ /// /// *This version of the trait is now deprecated. Please use the new `OutputPin` trait in /// `digital::v2::OutputPin`*. -#[deprecated] +#[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 /// @@ -28,7 +29,8 @@ pub trait OutputPin { /// /// *This version of the trait is now deprecated. Please use the new `StatefulOutputPin` trait in /// `digital::v2::StatefulOutputPin`*. -#[deprecated] +#[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? @@ -53,7 +55,8 @@ pub trait StatefulOutputPin { /// both [OutputPin](trait.OutputPin.html) and /// [StatefulOutputPin](trait.StatefulOutputPin.html) are /// implemented. Otherwise, implement this using hardware mechanisms. -#[deprecated] +#[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. @@ -102,7 +105,8 @@ pub trait ToggleableOutputPin { /// pin.toggle(); /// assert!(pin.is_set_low()); /// ``` -#[deprecated] +#[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)] @@ -136,7 +140,8 @@ pub mod toggleable { /// /// *This version of the trait is now deprecated. Please use the new `InputPin` trait in /// `digital::v2::InputPin`*. -#[deprecated] +#[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?