diff --git a/CHANGELOG.md b/CHANGELOG.md index 0863ecebb..bfa9671e4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 @@ -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 diff --git a/src/digital/mod.rs b/src/digital/mod.rs new file mode 100644 index 000000000..5784f0fbe --- /dev/null +++ b/src/digital/mod.rs @@ -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

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; diff --git a/src/digital.rs b/src/digital/v2.rs similarity index 64% rename from src/digital.rs rename to src/digital/v2.rs index 8f49da3d9..460005eb0 100644 --- a/src/digital.rs +++ b/src/digital/v2.rs @@ -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; /// 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; } /// Output pin that can be toggled @@ -41,16 +44,19 @@ 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 { @@ -58,20 +64,24 @@ pub trait ToggleableOutputPin { /// } /// /// 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 { +/// Ok(!self.state) /// } -/// fn is_set_high(&self) -> bool { -/// self.state +/// fn is_set_high(&self) -> Result { +/// Ok(self.state) /// } /// } /// @@ -79,10 +89,10 @@ pub trait ToggleableOutputPin { /// 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 { @@ -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() } } } @@ -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; /// Is the input pin low? - fn is_low(&self) -> bool; + 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;