From f220317a6e04937302c84de65ad75393953922a0 Mon Sep 17 00:00:00 2001 From: Diego Barrios Romero Date: Thu, 12 Mar 2020 07:45:39 +0100 Subject: [PATCH 01/22] Keep only v2 digital traits --- src/{digital/v2.rs => digital.rs} | 6 +- src/digital/mod.rs | 27 --- src/digital/v1.rs | 142 --------------- src/digital/v1_compat.rs | 286 ------------------------------ src/digital/v2_compat.rs | 226 ----------------------- 5 files changed, 2 insertions(+), 685 deletions(-) rename src/{digital/v2.rs => digital.rs} (94%) delete mode 100644 src/digital/mod.rs delete mode 100644 src/digital/v1.rs delete mode 100644 src/digital/v1_compat.rs delete mode 100644 src/digital/v2_compat.rs diff --git a/src/digital/v2.rs b/src/digital.rs similarity index 94% rename from src/digital/v2.rs rename to src/digital.rs index 0de0a877c..f86f54b2c 100644 --- a/src/digital/v2.rs +++ b/src/digital.rs @@ -1,6 +1,4 @@ //! Digital I/O -//! -//! Version 2 / fallible traits. Infallible implementations should set Error to `!`. /// Single digital push-pull output pin pub trait OutputPin { @@ -57,8 +55,8 @@ pub trait ToggleableOutputPin { /// toggleable by software. /// /// ``` -/// use embedded_hal::digital::v2::{OutputPin, StatefulOutputPin, ToggleableOutputPin}; -/// use embedded_hal::digital::v2::toggleable; +/// use embedded_hal::digital::{OutputPin, StatefulOutputPin, ToggleableOutputPin}; +/// use embedded_hal::digital::toggleable; /// use std::convert::Infallible; /// /// /// A virtual output pin that exists purely in software diff --git a/src/digital/mod.rs b/src/digital/mod.rs deleted file mode 100644 index 7b5b57025..000000000 --- a/src/digital/mod.rs +++ /dev/null @@ -1,27 +0,0 @@ -//! Digital I/O -//! -//! -//! - -// Deprecated / infallible traits -#[deprecated( - since = "0.2.2", - note = "Deprecated because the methods cannot return errors. \ - Users should use the traits in digital::v2." -)] -pub mod v1; - -// New / fallible traits -pub mod v2; - -// v2 -> v1 compatibility wrappers -// These require explicit casts from v2 -> v1 -pub mod v1_compat; - -// v1 -> v2 compatibility shims -// These are implicit over v1 implementations -pub mod v2_compat; - -// Re-export old traits so this isn't a breaking change -#[allow(deprecated)] -pub use self::v1::*; diff --git a/src/digital/v1.rs b/src/digital/v1.rs deleted file mode 100644 index 9c0678b10..000000000 --- a/src/digital/v1.rs +++ /dev/null @@ -1,142 +0,0 @@ -//! Digital I/O -//! -//! The traits in this module are now deprecated. Please use the new versions included -//! in `digital::v2`. - -#![allow(deprecated)] - -/// Single digital push-pull output pin -/// -/// *This version of the trait is now deprecated. Please use the new `OutputPin` trait in -/// `digital::v2::OutputPin`*. - -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`*. -#[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. -#[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()); -/// ``` -#[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 version of the trait is now deprecated. Please use the new `InputPin` trait in -/// `digital::v2::InputPin`*. -pub trait InputPin { - /// Is the input pin high? - fn is_high(&self) -> bool; - - /// Is the input pin low? - fn is_low(&self) -> bool; -} diff --git a/src/digital/v1_compat.rs b/src/digital/v1_compat.rs deleted file mode 100644 index 856cbb9fc..000000000 --- a/src/digital/v1_compat.rs +++ /dev/null @@ -1,286 +0,0 @@ -//! v1 compatibility wrappers -//! -//! This module provides wrappers to support use of v2 implementations with -//! v1 consumers. v2 traits must be explicitly cast to the v1 version using -//! `.into()`, and will panic on internal errors -//! -//! ``` -//! extern crate embedded_hal; -//! use embedded_hal::digital::{v1, v2, v1_compat::OldOutputPin}; -//! -//! struct NewOutputPinImpl {} -//! -//! impl v2::OutputPin for NewOutputPinImpl { -//! type Error = (); -//! fn set_low(&mut self) -> Result<(), Self::Error> { Ok(()) } -//! fn set_high(&mut self) -> Result<(), Self::Error>{ Ok(()) } -//! } -//! -//! struct OldOutputPinConsumer { -//! _pin: T, -//! } -//! -//! impl OldOutputPinConsumer -//! where T: v1::OutputPin { -//! pub fn new(pin: T) -> OldOutputPinConsumer { -//! OldOutputPinConsumer{ _pin: pin } -//! } -//! } -//! -//! fn main() { -//! let pin = NewOutputPinImpl{}; -//! let _consumer: OldOutputPinConsumer> = OldOutputPinConsumer::new(pin.into()); -//! } -//! ``` -//! - -#[allow(deprecated)] -use super::v1; -use super::v2; - -/// Wrapper to allow fallible `v2::OutputPin` traits to be converted to `v1::OutputPin` traits -pub struct OldOutputPin { - pin: T, -} - -impl OldOutputPin -where - T: v2::OutputPin, - E: core::fmt::Debug, -{ - /// Create a new OldOutputPin wrapper around a `v2::OutputPin` - pub fn new(pin: T) -> Self { - Self { pin } - } - - /// Fetch a reference to the inner `v2::OutputPin` impl - #[cfg(test)] - fn inner(&self) -> &T { - &self.pin - } -} - -impl From for OldOutputPin -where - T: v2::OutputPin, - E: core::fmt::Debug, -{ - fn from(pin: T) -> Self { - OldOutputPin { pin } - } -} - -/// Implementation of `v1::OutputPin` trait for fallible `v2::OutputPin` output pins -/// where errors will panic. -#[allow(deprecated)] -impl v1::OutputPin for OldOutputPin -where - T: v2::OutputPin, - E: core::fmt::Debug, -{ - fn set_low(&mut self) { - self.pin.set_low().unwrap() - } - - fn set_high(&mut self) { - self.pin.set_high().unwrap() - } -} - -/// Implementation of `v1::StatefulOutputPin` trait for `v2::StatefulOutputPin` fallible pins -/// where errors will panic. -#[cfg(feature = "unproven")] -#[allow(deprecated)] -impl v1::StatefulOutputPin for OldOutputPin -where - T: v2::StatefulOutputPin, - E: core::fmt::Debug, -{ - fn is_set_low(&self) -> bool { - self.pin.is_set_low().unwrap() - } - - fn is_set_high(&self) -> bool { - self.pin.is_set_high().unwrap() - } -} - -/// Wrapper to allow fallible `v2::InputPin` traits to be converted to `v1::InputPin` traits -/// where errors will panic. -pub struct OldInputPin { - pin: T, -} - -impl OldInputPin -where - T: v2::OutputPin, - E: core::fmt::Debug, -{ - /// Create an `OldInputPin` wrapper around a `v2::InputPin`. - pub fn new(pin: T) -> Self { - Self { pin } - } -} - -impl From for OldInputPin -where - T: v2::InputPin, - E: core::fmt::Debug, -{ - fn from(pin: T) -> Self { - OldInputPin { pin } - } -} - -/// Implementation of `v1::InputPin` trait for `v2::InputPin` fallible pins -/// where errors will panic. -#[allow(deprecated)] -impl v1::InputPin for OldInputPin -where - T: v2::InputPin, - E: core::fmt::Debug, -{ - fn is_low(&self) -> bool { - self.pin.is_low().unwrap() - } - - fn is_high(&self) -> bool { - self.pin.is_high().unwrap() - } -} - -#[cfg(test)] -#[allow(deprecated)] -mod tests { - use super::*; - - #[allow(deprecated)] - use crate::digital::v1; - use crate::digital::v2; - - use crate::digital::v1::OutputPin; - - #[derive(Clone)] - struct NewOutputPinImpl { - state: bool, - res: Result<(), ()>, - } - - impl v2::OutputPin for NewOutputPinImpl { - type Error = (); - - fn set_low(&mut self) -> Result<(), Self::Error> { - self.state = false; - self.res - } - fn set_high(&mut self) -> Result<(), Self::Error> { - self.state = true; - self.res - } - } - - #[allow(deprecated)] - struct OldOutputPinConsumer { - _pin: T, - } - - #[allow(deprecated)] - impl OldOutputPinConsumer - where - T: v1::OutputPin, - { - pub fn new(pin: T) -> OldOutputPinConsumer { - OldOutputPinConsumer { _pin: pin } - } - } - - #[test] - fn v1_v2_output_explicit() { - let i = NewOutputPinImpl { - state: false, - res: Ok(()), - }; - let _c: OldOutputPinConsumer> = OldOutputPinConsumer::new(i.into()); - } - - #[test] - fn v1_v2_output_state() { - let mut o: OldOutputPin<_> = NewOutputPinImpl { - state: false, - res: Ok(()), - } - .into(); - - o.set_high(); - assert_eq!(o.inner().state, true); - - o.set_low(); - assert_eq!(o.inner().state, false); - } - - #[test] - #[should_panic] - fn v1_v2_output_panic() { - let mut o: OldOutputPin<_> = NewOutputPinImpl { - state: false, - res: Err(()), - } - .into(); - - o.set_high(); - } - - use crate::digital::v1::InputPin; - - struct NewInputPinImpl { - state: Result, - } - - impl v2::InputPin for NewInputPinImpl { - type Error = (); - - fn is_low(&self) -> Result { - self.state.map(|v| v == false) - } - fn is_high(&self) -> Result { - self.state.map(|v| v == true) - } - } - - #[allow(deprecated)] - struct OldInputPinConsumer { - _pin: T, - } - - #[allow(deprecated)] - impl OldInputPinConsumer - where - T: v1::InputPin, - { - pub fn new(pin: T) -> OldInputPinConsumer { - OldInputPinConsumer { _pin: pin } - } - } - - #[test] - fn v1_v2_input_explicit() { - let i = NewInputPinImpl { state: Ok(false) }; - let _c: OldInputPinConsumer> = OldInputPinConsumer::new(i.into()); - } - - #[test] - fn v1_v2_input_state() { - let i: OldInputPin<_> = NewInputPinImpl { state: Ok(false) }.into(); - - assert_eq!(i.is_low(), true); - assert_eq!(i.is_high(), false); - } - - #[test] - #[should_panic] - fn v1_v2_input_panic() { - let i: OldInputPin<_> = NewInputPinImpl { state: Err(()) }.into(); - - i.is_low(); - } -} diff --git a/src/digital/v2_compat.rs b/src/digital/v2_compat.rs deleted file mode 100644 index 4b6b4c805..000000000 --- a/src/digital/v2_compat.rs +++ /dev/null @@ -1,226 +0,0 @@ -//! v2 compatibility shims -//! -//! This module adds implicit forward support to v1 digital traits, -//! allowing v1 implementations to be directly used with v2 consumers. -//! -//! ``` -//! extern crate embedded_hal; -//! use embedded_hal::digital::{v1, v2}; -//! -//! struct OldOutputPinImpl { } -//! -//! impl v1::OutputPin for OldOutputPinImpl { -//! fn set_low(&mut self) { } -//! fn set_high(&mut self) { } -//! } -//! -//! struct NewOutputPinConsumer { -//! _pin: T, -//! } -//! -//! impl NewOutputPinConsumer -//! where T: v2::OutputPin { -//! pub fn new(pin: T) -> NewOutputPinConsumer { -//! NewOutputPinConsumer{ _pin: pin } -//! } -//! } -//! -//! fn main() { -//! let pin = OldOutputPinImpl{}; -//! let _consumer = NewOutputPinConsumer::new(pin); -//! } -//! ``` -//! - -use core::convert::Infallible; - -#[allow(deprecated)] -use super::v1; -use super::v2; - -/// Implementation of fallible `v2::OutputPin` for `v1::OutputPin` traits -#[allow(deprecated)] -impl v2::OutputPin for T -where - T: v1::OutputPin, -{ - type Error = Infallible; - - fn set_low(&mut self) -> Result<(), Self::Error> { - Ok(self.set_low()) - } - - fn set_high(&mut self) -> Result<(), Self::Error> { - Ok(self.set_high()) - } -} - -/// Implementation of fallible `v2::StatefulOutputPin` for `v1::StatefulOutputPin` digital traits -#[cfg(feature = "unproven")] -#[allow(deprecated)] -impl v2::StatefulOutputPin for T -where - T: v1::StatefulOutputPin + v1::OutputPin, -{ - fn is_set_low(&self) -> Result { - Ok(self.is_set_low()) - } - - fn is_set_high(&self) -> Result { - Ok(self.is_set_high()) - } -} - -#[cfg(feature = "unproven")] -#[allow(deprecated)] -impl v2::toggleable::Default for T where T: v1::toggleable::Default {} - -/// Implementation of fallible `v2::InputPin` for `v1::InputPin` digital traits -#[allow(deprecated)] -impl v2::InputPin for T -where - T: v1::InputPin, -{ - type Error = Infallible; - - fn is_low(&self) -> Result { - Ok(self.is_low()) - } - - fn is_high(&self) -> Result { - Ok(self.is_high()) - } -} - -#[cfg(test)] -mod tests { - - #[allow(deprecated)] - use crate::digital::v1; - use crate::digital::v2; - - #[allow(deprecated)] - struct OldOutputPinImpl { - state: bool, - } - - #[allow(deprecated)] - impl v1::OutputPin for OldOutputPinImpl { - fn set_low(&mut self) { - self.state = false; - } - fn set_high(&mut self) { - self.state = true; - } - } - - #[cfg(feature = "unproven")] - #[allow(deprecated)] - impl v1::StatefulOutputPin for OldOutputPinImpl { - fn is_set_low(&self) -> bool { - self.state == false - } - - fn is_set_high(&self) -> bool { - self.state == true - } - } - - #[cfg(feature = "unproven")] - #[allow(deprecated)] - impl v1::toggleable::Default for OldOutputPinImpl {} - - struct NewOutputPinConsumer { - _pin: T, - } - - impl NewOutputPinConsumer - where - T: v2::OutputPin, - { - pub fn new(pin: T) -> NewOutputPinConsumer { - NewOutputPinConsumer { _pin: pin } - } - } - - #[cfg(feature = "unproven")] - struct NewToggleablePinConsumer { - _pin: T, - } - - #[cfg(feature = "unproven")] - impl NewToggleablePinConsumer - where - T: v2::ToggleableOutputPin, - { - pub fn new(pin: T) -> NewToggleablePinConsumer { - NewToggleablePinConsumer { _pin: pin } - } - } - - #[cfg(feature = "unproven")] - #[test] - fn v2_v1_toggleable_implicit() { - let i = OldOutputPinImpl { state: false }; - let _c = NewToggleablePinConsumer::new(i); - } - - #[test] - fn v2_v1_output_implicit() { - let i = OldOutputPinImpl { state: false }; - let _c = NewOutputPinConsumer::new(i); - } - - #[test] - fn v2_v1_output_state() { - let mut o = OldOutputPinImpl { state: false }; - - v2::OutputPin::set_high(&mut o).unwrap(); - assert_eq!(o.state, true); - - v2::OutputPin::set_low(&mut o).unwrap(); - assert_eq!(o.state, false); - } - - #[allow(deprecated)] - struct OldInputPinImpl { - state: bool, - } - - #[allow(deprecated)] - impl v1::InputPin for OldInputPinImpl { - fn is_low(&self) -> bool { - !self.state - } - fn is_high(&self) -> bool { - self.state - } - } - - struct NewInputPinConsumer { - _pin: T, - } - - impl NewInputPinConsumer - where - T: v2::InputPin, - { - pub fn new(pin: T) -> NewInputPinConsumer { - NewInputPinConsumer { _pin: pin } - } - } - - #[test] - fn v2_v1_input_implicit() { - let i = OldInputPinImpl { state: false }; - let _c = NewInputPinConsumer::new(i); - } - - #[test] - fn v2_v1_input_state() { - let mut i = OldInputPinImpl { state: false }; - - assert_eq!(v2::InputPin::is_high(&mut i).unwrap(), false); - assert_eq!(v2::InputPin::is_low(&mut i).unwrap(), true); - } -} From 91892596d1217e8e1b8f77f2f25337cbf6fcb143 Mon Sep 17 00:00:00 2001 From: Diego Barrios Romero Date: Thu, 12 Mar 2020 07:58:36 +0100 Subject: [PATCH 02/22] Make Capture trait fallible --- src/lib.rs | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 13c0d8bd7..37d76386d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -721,32 +721,33 @@ pub mod watchdog; /// # Capture1 /// }; /// -/// capture.set_resolution(1.ms()); +/// capture.try_set_resolution(1.ms()).unwrap(); /// -/// let before = block!(capture.capture(Channel::_1)).unwrap(); -/// let after = block!(capture.capture(Channel::_1)).unwrap(); +/// let before = block!(capture.try_capture(Channel::_1)).unwrap(); +/// let after = block!(capture.try_capture(Channel::_1)).unwrap(); /// /// let period = after.wrapping_sub(before); /// /// println!("Period: {} ms", period); /// } /// -/// # use std::convert::Infallible; +/// # use core::convert::Infallible; /// # struct MilliSeconds(u32); /// # trait U32Ext { fn ms(self) -> MilliSeconds; } /// # impl U32Ext for u32 { fn ms(self) -> MilliSeconds { MilliSeconds(self) } } /// # struct Capture1; /// # enum Channel { _1 } /// # impl hal::Capture for Capture1 { +/// # type Error = Infallible; /// # type Capture = u16; /// # type Channel = Channel; /// # type Error = Infallible; /// # type Time = MilliSeconds; -/// # fn capture(&mut self, _: Channel) -> ::nb::Result { Ok(0) } -/// # fn disable(&mut self, _: Channel) { unimplemented!() } -/// # fn enable(&mut self, _: Channel) { unimplemented!() } -/// # fn get_resolution(&self) -> MilliSeconds { unimplemented!() } -/// # fn set_resolution(&mut self, _: T) where T: Into {} +/// # fn try_capture(&mut self, _: Channel) -> ::nb::Result { Ok(0) } +/// # fn try_disable(&mut self, _: Channel) -> Result<(), Self::Error> { unimplemented!() } +/// # fn try_enable(&mut self, _: Channel) -> Result<(), Self::Error> { unimplemented!() } +/// # fn try_get_resolution(&self) -> Result { unimplemented!() } +/// # fn try_set_resolution(&mut self, _: T) -> Result<(), Self::Error> where T: Into {} /// # } /// ``` #[cfg(feature = "unproven")] @@ -778,19 +779,19 @@ pub trait Capture { /// /// NOTE that you must multiply the returned value by the *resolution* of /// this `Capture` interface to get a human time unit (e.g. seconds) - fn capture(&mut self, channel: Self::Channel) -> nb::Result; + fn try_capture(&mut self, channel: Self::Channel) -> nb::Result; /// Disables a capture `channel` - fn disable(&mut self, channel: Self::Channel); + fn try_disable(&mut self, channel: Self::Channel) -> Result<(), Self::Error>; /// Enables a capture `channel` - fn enable(&mut self, channel: Self::Channel); + fn try_enable(&mut self, channel: Self::Channel) -> Result<(), Self::Error>; /// Returns the current resolution - fn get_resolution(&self) -> Self::Time; + fn try_get_resolution(&self) -> Result; /// Sets the resolution of the capture timer - fn set_resolution(&mut self, resolution: R) + fn try_set_resolution(&mut self, resolution: R) -> Result<(), Self::Error> where R: Into; } From a4fb672fc7ced22ff0468c74da4166b615bc21bd Mon Sep 17 00:00:00 2001 From: Diego Barrios Romero Date: Thu, 12 Mar 2020 08:01:39 +0100 Subject: [PATCH 03/22] Make Pwm trait fallible --- src/lib.rs | 42 ++++++++++++++++++++++++------------------ 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 37d76386d..b3c2f0a9c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -815,39 +815,44 @@ pub trait Capture { /// # Pwm1 /// }; /// -/// pwm.set_period(1.khz()); +/// pwm.try_set_period(1.khz()).unwrap(); /// -/// let max_duty = pwm.get_max_duty(); +/// let max_duty = pwm.try_get_max_duty().unwrap(); /// /// // brightest LED -/// pwm.set_duty(Channel::_1, max_duty); +/// pwm.try_set_duty(Channel::_1, max_duty).unwrap(); /// /// // dimmer LED -/// pwm.set_duty(Channel::_2, max_duty / 4); +/// pwm.try_set_duty(Channel::_2, max_duty / 4).unwrap(); /// } /// +/// # use core::convert::Infallible; /// # struct KiloHertz(u32); /// # trait U32Ext { fn khz(self) -> KiloHertz; } /// # impl U32Ext for u32 { fn khz(self) -> KiloHertz { KiloHertz(self) } } /// # enum Channel { _1, _2 } /// # struct Pwm1; /// # impl hal::Pwm for Pwm1 { +/// # type Error = Infallible; /// # type Channel = Channel; /// # type Time = KiloHertz; /// # type Duty = u16; -/// # fn disable(&mut self, _: Channel) { unimplemented!() } -/// # fn enable(&mut self, _: Channel) { unimplemented!() } -/// # fn get_duty(&self, _: Channel) -> u16 { unimplemented!() } -/// # fn get_max_duty(&self) -> u16 { 0 } -/// # fn set_duty(&mut self, _: Channel, _: u16) {} -/// # fn get_period(&self) -> KiloHertz { unimplemented!() } -/// # fn set_period(&mut self, _: T) where T: Into {} +/// # fn try_disable(&mut self, _: Channel) -> Result<(), Self::Error> { unimplemented!() } +/// # fn try_enable(&mut self, _: Channel) -> Result<(), Self::Error> { unimplemented!() } +/// # fn try_get_duty(&self, _: Channel) -> Result { unimplemented!() } +/// # fn try_get_max_duty(&self) -> Result { 0 } +/// # fn try_set_duty(&mut self, _: Channel, _: u16) -> Result<(), Self::Error> {} +/// # fn try_get_period(&self) -> Result { unimplemented!() } +/// # fn try_set_period(&mut self, _: T) -> Result<(), Self::Error> where T: Into {} /// # } /// ``` #[cfg(feature = "unproven")] // reason: pre-singletons API. The `PwmPin` trait seems more useful because it models independent // PWM channels. Here a certain number of channels are multiplexed in a single implementer. pub trait Pwm { + /// Enumeration of `Pwm` errors + type Error; + /// Enumeration of channels that can be used with this `Pwm` interface /// /// If your `Pwm` interface has no channels you can use the type `()` @@ -864,25 +869,26 @@ pub trait Pwm { type Duty; /// Disables a PWM `channel` - fn disable(&mut self, channel: Self::Channel); + fn try_disable(&mut self, channel: Self::Channel) -> Result<(), Self::Error>; /// Enables a PWM `channel` - fn enable(&mut self, channel: Self::Channel); + fn try_enable(&mut self, channel: Self::Channel) -> Result<(), Self::Error>; /// Returns the current PWM period - fn get_period(&self) -> Self::Time; + fn try_get_period(&self) -> Result; /// Returns the current duty cycle - fn get_duty(&self, channel: Self::Channel) -> Self::Duty; + fn try_get_duty(&self, channel: Self::Channel) -> Result; /// Returns the maximum duty cycle value - fn get_max_duty(&self) -> Self::Duty; + fn try_get_max_duty(&self) -> Result; /// Sets a new duty cycle - fn set_duty(&mut self, channel: Self::Channel, duty: Self::Duty); + fn try_set_duty(&mut self, channel: Self::Channel, duty: Self::Duty) + -> Result<(), Self::Error>; /// Sets a new PWM period - fn set_period

(&mut self, period: P) + fn try_set_period

(&mut self, period: P) -> Result<(), Self::Error> where P: Into; } From d2135c48bd6c02a9807fff8a572050f98677e656 Mon Sep 17 00:00:00 2001 From: Diego Barrios Romero Date: Thu, 12 Mar 2020 08:02:17 +0100 Subject: [PATCH 04/22] Make PwmPin trait fallible --- src/lib.rs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index b3c2f0a9c..5c76ce589 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -897,6 +897,9 @@ pub trait Pwm { /// /// See `Pwm` for details pub trait PwmPin { + /// Enumeration of `PwmPin` errors + type Error; + /// Type for the `duty` methods /// /// The implementer is free to choose a float / percentage representation @@ -904,19 +907,19 @@ pub trait PwmPin { type Duty; /// Disables a PWM `channel` - fn disable(&mut self); + fn try_disable(&mut self) -> Result<(), Self::Error>; /// Enables a PWM `channel` - fn enable(&mut self); + fn try_enable(&mut self) -> Result<(), Self::Error>; /// Returns the current duty cycle - fn get_duty(&self) -> Self::Duty; + fn try_get_duty(&self) -> Result; /// Returns the maximum duty cycle value - fn get_max_duty(&self) -> Self::Duty; + fn try_get_max_duty(&self) -> Result; /// Sets a new duty cycle - fn set_duty(&mut self, duty: Self::Duty); + fn try_set_duty(&mut self, duty: Self::Duty) -> Result<(), Self::Error>; } /// Quadrature encoder interface From 0036746da37ca2995af70a9e825c4705424d1761 Mon Sep 17 00:00:00 2001 From: Diego Barrios Romero Date: Thu, 12 Mar 2020 08:04:31 +0100 Subject: [PATCH 05/22] Make Qei trait fallible --- src/lib.rs | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 5c76ce589..b7df553d5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -948,24 +948,25 @@ pub trait PwmPin { /// }; /// /// -/// let before = qei.count(); +/// let before = qei.try_count().unwrap(); /// timer.start(1.s()); /// block!(timer.wait()); -/// let after = qei.count(); +/// let after = qei.try_count().unwrap(); /// /// let speed = after.wrapping_sub(before); /// println!("Speed: {} pulses per second", speed); /// } /// -/// # use std::convert::Infallible; +/// # use core::convert::Infallible; /// # struct Seconds(u32); /// # trait U32Ext { fn s(self) -> Seconds; } /// # impl U32Ext for u32 { fn s(self) -> Seconds { Seconds(self) } } /// # struct Qei1; /// # impl hal::Qei for Qei1 { +/// # type Error = Infallible; /// # type Count = u16; -/// # fn count(&self) -> u16 { 0 } -/// # fn direction(&self) -> ::hal::Direction { unimplemented!() } +/// # fn try_count(&self) -> Result { 0 } +/// # fn try_direction(&self) -> Result<::hal::Direction, Self::Error> { unimplemented!() } /// # } /// # struct Timer6; /// # impl hal::timer::CountDown for Timer6 { @@ -978,14 +979,17 @@ pub trait PwmPin { // reason: needs to be re-evaluated in the new singletons world. At the very least this needs a // reference implementation pub trait Qei { + /// Enumeration of `Qei` errors + type Error; + /// The type of the value returned by `count` type Count; /// Returns the current pulse count of the encoder - fn count(&self) -> Self::Count; + fn try_count(&self) -> Result; /// Returns the count direction - fn direction(&self) -> Direction; + fn try_direction(&self) -> Result; } /// Count direction From 3fc79338d87ab904534be260f2353de4d2b022bb Mon Sep 17 00:00:00 2001 From: Diego Barrios Romero Date: Thu, 12 Mar 2020 08:05:17 +0100 Subject: [PATCH 06/22] Make delay traits fallible --- src/blocking/delay.rs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/blocking/delay.rs b/src/blocking/delay.rs index 177c29ccd..9db0c9e8d 100644 --- a/src/blocking/delay.rs +++ b/src/blocking/delay.rs @@ -12,8 +12,11 @@ /// `UXX` denotes the range type of the delay time. `UXX` can be `u8`, `u16`, etc. A single type can /// implement this trait for different types of `UXX`. pub trait DelayMs { + /// Enumeration of `DelayMs` errors + type Error; + /// Pauses execution for `ms` milliseconds - fn delay_ms(&mut self, ms: UXX); + fn try_delay_ms(&mut self, ms: UXX) -> Result<(), Self::Error>; } /// Microsecond delay @@ -21,6 +24,9 @@ pub trait DelayMs { /// `UXX` denotes the range type of the delay time. `UXX` can be `u8`, `u16`, etc. A single type can /// implement this trait for different types of `UXX`. pub trait DelayUs { + /// Enumeration of `DelayMs` errors + type Error; + /// Pauses execution for `us` microseconds - fn delay_us(&mut self, us: UXX); + fn try_delay_us(&mut self, us: UXX) -> Result<(), Self::Error>; } From 3c705616dc01faf2219d31a6e854831478e1a39b Mon Sep 17 00:00:00 2001 From: Diego Barrios Romero Date: Thu, 12 Mar 2020 08:05:49 +0100 Subject: [PATCH 07/22] Rename rng::Read trait method try_read --- src/blocking/rng.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/blocking/rng.rs b/src/blocking/rng.rs index cd8a543b6..8e1c13ee6 100644 --- a/src/blocking/rng.rs +++ b/src/blocking/rng.rs @@ -15,5 +15,5 @@ pub trait Read { /// /// If this function returns an error, it is unspecified how many bytes it has read, but it /// will never read more than would be necessary to completely fill the buffer. - fn read(&mut self, buffer: &mut [u8]) -> Result<(), Self::Error>; + fn try_read(&mut self, buffer: &mut [u8]) -> Result<(), Self::Error>; } From 50869c279785ecce1e1a42f2b1132b0150071e0f Mon Sep 17 00:00:00 2001 From: Diego Barrios Romero Date: Thu, 12 Mar 2020 08:07:17 +0100 Subject: [PATCH 08/22] Rename blocking serial trait methods try_* --- src/blocking/serial.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/blocking/serial.rs b/src/blocking/serial.rs index b3110e3c6..cfc7ff591 100644 --- a/src/blocking/serial.rs +++ b/src/blocking/serial.rs @@ -10,13 +10,13 @@ pub trait Write { /// An implementation can choose to buffer the write, returning `Ok(())` /// after the complete slice has been written to a buffer, but before all /// words have been sent via the serial interface. To make sure that - /// everything has been sent, call [`bflush`] after this function returns. + /// everything has been sent, call [`try_bflush`] after this function returns. /// - /// [`bflush`]: #tymethod.bflush - fn bwrite_all(&mut self, buffer: &[Word]) -> Result<(), Self::Error>; + /// [`try_bflush`]: #tymethod.bflush + fn try_bwrite_all(&mut self, buffer: &[Word]) -> Result<(), Self::Error>; /// Block until the serial interface has sent all buffered words - fn bflush(&mut self) -> Result<(), Self::Error>; + fn try_bflush(&mut self) -> Result<(), Self::Error>; } /// Blocking serial write @@ -38,7 +38,7 @@ pub mod write { { type Error = S::Error; - fn bwrite_all(&mut self, buffer: &[Word]) -> Result<(), Self::Error> { + fn try_bwrite_all(&mut self, buffer: &[Word]) -> Result<(), Self::Error> { for word in buffer { block!(self.write(word.clone()))?; } @@ -46,7 +46,7 @@ pub mod write { Ok(()) } - fn bflush(&mut self) -> Result<(), Self::Error> { + fn try_bflush(&mut self) -> Result<(), Self::Error> { block!(self.flush())?; Ok(()) } From 436908e7a1fae13b3082365e60b50f396f1b9123 Mon Sep 17 00:00:00 2001 From: Diego Barrios Romero Date: Thu, 12 Mar 2020 08:08:48 +0100 Subject: [PATCH 09/22] Rename I2C trait methods try_* --- src/blocking/i2c.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/blocking/i2c.rs b/src/blocking/i2c.rs index 57192cac8..d8fd13f03 100644 --- a/src/blocking/i2c.rs +++ b/src/blocking/i2c.rs @@ -28,7 +28,7 @@ pub trait Read { /// - `MAK` = master acknowledge /// - `NMAK` = master no acknowledge /// - `SP` = stop condition - fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Self::Error>; + fn try_read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Self::Error>; } /// Blocking write @@ -52,7 +52,7 @@ pub trait Write { /// - `SAK` = slave acknowledge /// - `Bi` = ith byte of data /// - `SP` = stop condition - fn write(&mut self, addr: u8, bytes: &[u8]) -> Result<(), Self::Error>; + fn try_write(&mut self, addr: u8, bytes: &[u8]) -> Result<(), Self::Error>; } /// Blocking write (iterator version) @@ -66,7 +66,7 @@ pub trait WriteIter { /// # I2C Events (contract) /// /// Same as `Write` - fn write(&mut self, addr: u8, bytes: B) -> Result<(), Self::Error> + fn try_write(&mut self, addr: u8, bytes: B) -> Result<(), Self::Error> where B: IntoIterator; } @@ -98,7 +98,7 @@ pub trait WriteRead { /// - `MAK` = master acknowledge /// - `NMAK` = master no acknowledge /// - `SP` = stop condition - fn write_read( + fn try_write_read( &mut self, address: u8, bytes: &[u8], @@ -118,7 +118,7 @@ pub trait WriteIterRead { /// # I2C Events (contract) /// /// Same as the `WriteRead` trait - fn write_iter_read( + fn try_write_iter_read( &mut self, address: u8, bytes: B, From 8e83e4bbe451c33363619bc9dff2070708464e7c Mon Sep 17 00:00:00 2001 From: Diego Barrios Romero Date: Thu, 12 Mar 2020 08:10:04 +0100 Subject: [PATCH 10/22] Rename blocking SPI trait methods try_* --- src/blocking/spi.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/blocking/spi.rs b/src/blocking/spi.rs index 90dc27afb..77ca3e525 100644 --- a/src/blocking/spi.rs +++ b/src/blocking/spi.rs @@ -6,7 +6,7 @@ pub trait Transfer { type Error; /// Sends `words` to the slave. Returns the `words` received from the slave - fn transfer<'w>(&mut self, words: &'w mut [W]) -> Result<&'w [W], Self::Error>; + fn try_transfer<'w>(&mut self, words: &'w mut [W]) -> Result<&'w [W], Self::Error>; } /// Blocking write @@ -15,7 +15,7 @@ pub trait Write { type Error; /// Sends `words` to the slave, ignoring all the incoming words - fn write(&mut self, words: &[W]) -> Result<(), Self::Error>; + fn try_write(&mut self, words: &[W]) -> Result<(), Self::Error>; } /// Blocking write (iterator version) @@ -25,7 +25,7 @@ pub trait WriteIter { type Error; /// Sends `words` to the slave, ignoring all the incoming words - fn write_iter(&mut self, words: WI) -> Result<(), Self::Error> + fn try_write_iter(&mut self, words: WI) -> Result<(), Self::Error> where WI: IntoIterator; } @@ -43,7 +43,7 @@ pub mod transfer { { type Error = S::Error; - fn transfer<'w>(&mut self, words: &'w mut [W]) -> Result<&'w [W], S::Error> { + fn try_transfer<'w>(&mut self, words: &'w mut [W]) -> Result<&'w [W], S::Error> { for word in words.iter_mut() { block!(self.send(word.clone()))?; *word = block!(self.read())?; @@ -66,7 +66,7 @@ pub mod write { { type Error = S::Error; - fn write(&mut self, words: &[W]) -> Result<(), S::Error> { + fn try_write(&mut self, words: &[W]) -> Result<(), S::Error> { for word in words { block!(self.send(word.clone()))?; block!(self.read())?; @@ -91,7 +91,7 @@ pub mod write_iter { { type Error = S::Error; - fn write_iter(&mut self, words: WI) -> Result<(), S::Error> + fn try_write_iter(&mut self, words: WI) -> Result<(), S::Error> where WI: IntoIterator, { From fc622436b0d7cf1bdda8d2f670c9fc950d71b9a1 Mon Sep 17 00:00:00 2001 From: Diego Barrios Romero Date: Thu, 12 Mar 2020 08:19:21 +0100 Subject: [PATCH 11/22] Rename adc::OneShot::try_read method --- src/adc.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/adc.rs b/src/adc.rs index cb7d7363f..ba7655efa 100644 --- a/src/adc.rs +++ b/src/adc.rs @@ -76,7 +76,7 @@ pub trait Channel { /// { /// type Error = (); /// -/// fn read(&mut self, _pin: &mut PIN) -> nb::Result { +/// fn try_read(&mut self, _pin: &mut PIN) -> nb::Result { /// let chan = 1 << PIN::channel(); /// self.power_up(); /// let result = self.do_conversion(chan); @@ -94,5 +94,5 @@ pub trait OneShot> { /// /// This method takes a `Pin` reference, as it is expected that the ADC will be able to sample /// whatever channel underlies the pin. - fn read(&mut self, pin: &mut Pin) -> nb::Result; + fn try_read(&mut self, pin: &mut Pin) -> nb::Result; } From ac1673e75192510cdf8428c561b7a492418003f3 Mon Sep 17 00:00:00 2001 From: Diego Barrios Romero Date: Thu, 12 Mar 2020 08:23:09 +0100 Subject: [PATCH 12/22] Rename digital trait methods try_* --- src/digital.rs | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/src/digital.rs b/src/digital.rs index f86f54b2c..37b05bf8c 100644 --- a/src/digital.rs +++ b/src/digital.rs @@ -9,13 +9,13 @@ pub trait OutputPin { /// /// *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>; + fn try_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>; + fn try_set_high(&mut self) -> Result<(), Self::Error>; } /// Push-pull output pin that can read its output state @@ -26,12 +26,12 @@ 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; + fn try_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; + fn try_is_set_low(&self) -> Result; } /// Output pin that can be toggled @@ -48,7 +48,7 @@ pub trait ToggleableOutputPin { type Error; /// Toggle pin output. - fn toggle(&mut self) -> Result<(), Self::Error>; + fn try_toggle(&mut self) -> Result<(), Self::Error>; } /// If you can read **and** write the output state, a pin is @@ -57,7 +57,7 @@ pub trait ToggleableOutputPin { /// ``` /// use embedded_hal::digital::{OutputPin, StatefulOutputPin, ToggleableOutputPin}; /// use embedded_hal::digital::toggleable; -/// use std::convert::Infallible; +/// use core::convert::Infallible; /// /// /// A virtual output pin that exists purely in software /// struct MyPin { @@ -67,21 +67,21 @@ pub trait ToggleableOutputPin { /// impl OutputPin for MyPin { /// type Error = Infallible; /// -/// fn set_low(&mut self) -> Result<(), Self::Error> { +/// fn try_set_low(&mut self) -> Result<(), Self::Error> { /// self.state = false; /// Ok(()) /// } -/// fn set_high(&mut self) -> Result<(), Self::Error> { +/// fn try_set_high(&mut self) -> Result<(), Self::Error> { /// self.state = true; /// Ok(()) /// } /// } /// /// impl StatefulOutputPin for MyPin { -/// fn is_set_low(&self) -> Result { +/// fn try_is_set_low(&self) -> Result { /// Ok(!self.state) /// } -/// fn is_set_high(&self) -> Result { +/// fn try_is_set_high(&self) -> Result { /// Ok(self.state) /// } /// } @@ -90,10 +90,10 @@ pub trait ToggleableOutputPin { /// 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()); +/// pin.try_toggle().unwrap(); +/// assert!(pin.try_is_set_high().unwrap()); +/// pin.try_toggle().unwrap(); +/// assert!(pin.try_is_set_low().unwrap()); /// ``` #[cfg(feature = "unproven")] pub mod toggleable { @@ -111,11 +111,11 @@ pub mod toggleable { type Error = P::Error; /// Toggle pin output - fn toggle(&mut self) -> Result<(), Self::Error> { - if self.is_set_low()? { - self.set_high() + fn try_toggle(&mut self) -> Result<(), Self::Error> { + if self.try_is_set_low()? { + self.try_set_high() } else { - self.set_low() + self.try_set_low() } } } @@ -127,8 +127,8 @@ pub trait InputPin { type Error; /// Is the input pin high? - fn is_high(&self) -> Result; + fn try_is_high(&self) -> Result; /// Is the input pin low? - fn is_low(&self) -> Result; + fn try_is_low(&self) -> Result; } From 0969b74338bcda6f9d91ae085597826f79ced875 Mon Sep 17 00:00:00 2001 From: Diego Barrios Romero Date: Thu, 12 Mar 2020 08:24:37 +0100 Subject: [PATCH 13/22] Rename rng::Read trait method try_read --- src/rng.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rng.rs b/src/rng.rs index d662ff545..de8586c39 100644 --- a/src/rng.rs +++ b/src/rng.rs @@ -13,5 +13,5 @@ pub trait Read { type Error; /// Get a number of bytes from the RNG. - fn read(&mut self, buf: &mut [u8]) -> nb::Result; + fn try_read(&mut self, buf: &mut [u8]) -> nb::Result; } From ab070b4f88d0ddb08b22a307f858b7d36269c3d1 Mon Sep 17 00:00:00 2001 From: Diego Barrios Romero Date: Thu, 12 Mar 2020 08:29:06 +0100 Subject: [PATCH 14/22] Make Watchdog trait methods fallible --- src/watchdog.rs | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/src/watchdog.rs b/src/watchdog.rs index 41e76f6ba..8009cc792 100644 --- a/src/watchdog.rs +++ b/src/watchdog.rs @@ -4,20 +4,31 @@ /// commonly referred to as "kicking" or "refreshing". #[cfg(feature = "unproven")] pub trait Watchdog { + /// An enumeration of `Watchdog` errors. + /// + /// For infallible implementations, will be `Infallible` + type Error; + /// Triggers the watchdog. This must be done once the watchdog is started /// to prevent the processor being reset. - fn feed(&mut self); + fn try_feed(&mut self) -> Result<(), Self::Error>; } /// Enables A watchdog timer to reset the processor if software is frozen or /// stalled. #[cfg(feature = "unproven")] pub trait WatchdogEnable { + /// An enumeration of `WatchdogEnable` errors. + /// + /// For infallible implementations, will be `Infallible` + type Error; + /// Unit of time used by the watchdog type Time; + /// Starts the watchdog with a given period, typically once this is done /// the watchdog needs to be kicked periodically or the processor is reset. - fn start(&mut self, period: T) + fn try_start(&mut self, period: T) -> Result<(), Self::Error> where T: Into; } @@ -25,6 +36,11 @@ pub trait WatchdogEnable { /// Disables a running watchdog timer so the processor won't be reset. #[cfg(feature = "unproven")] pub trait WatchdogDisable { + /// An enumeration of `WatchdogDisable` errors. + /// + /// For infallible implementations, will be `Infallible` + type Error; + /// Disables the watchdog - fn disable(&mut self); + fn try_disable(&mut self) -> Result<(), Self::Error>; } From 114534b395adb4d80a1ac98284b52e1fc05c0c14 Mon Sep 17 00:00:00 2001 From: Diego Barrios Romero Date: Thu, 12 Mar 2020 08:31:55 +0100 Subject: [PATCH 15/22] Make timer traits fallible --- src/lib.rs | 41 +++++++++++++++++++++-------------------- src/timer.rs | 30 ++++++++++++++++-------------- 2 files changed, 37 insertions(+), 34 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index b7df553d5..ee396d22b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -103,7 +103,7 @@ //! // .. //! //! /// "waits" until the count down is over -//! fn wait(&mut self) -> nb::Result<(), Infallible>; +//! fn try_wait(&mut self) -> nb::Result<(), Infallible>; //! } //! //! # fn main() {} @@ -257,7 +257,7 @@ //! use stm32f30x_hal::{Led, Serial1, Timer6}; //! use std::convert::Infallible; //! -//! /// `futures` version of `CountDown.wait` +//! /// `futures` version of `CountDown.try_wait` //! /// //! /// This returns a future that must be polled to completion //! fn wait(mut timer: T) -> impl Future @@ -266,7 +266,7 @@ //! { //! let mut timer = Some(timer); //! future::poll_fn(move || { -//! try_nb!(timer.as_mut().unwrap().wait()); +//! try_nb!(timer.as_mut().unwrap().try_wait()); //! //! Ok(Async::Ready(timer.take().unwrap())) //! }) @@ -349,13 +349,13 @@ //! } //! //! # mod stm32f30x_hal { -//! # use std::convert::Infallible; +//! # use core::convert::Infallible; //! # pub struct Timer6; //! # impl ::hal::timer::CountDown for Timer6 { //! # type Time = (); //! # -//! # fn start(&mut self, _: T) where T: Into<()> {} -//! # fn wait(&mut self) -> ::nb::Result<(), Infallible> { Err(::nb::Error::WouldBlock) } +//! # fn try_start(&mut self, _: T) -> Result<(), Infallible> where T: Into<()> {} +//! # fn try_wait(&mut self) -> ::nb::Result<(), Infallible> { Err(::nb::Error::WouldBlock) } //! # } //! # //! # pub struct Serial1; @@ -509,22 +509,23 @@ //! //! use hal::prelude::*; //! -//! enum Error { +//! enum Error { //! /// Serial interface error -//! Serial(E), -//! TimedOut, +//! Serial(SE), +//! /// Timeout error +//! TimedOut(TE), //! } //! //! fn read_with_timeout( //! serial: &mut S, //! timer: &mut T, //! timeout: T::Time, -//! ) -> Result> +//! ) -> Result> //! where -//! T: hal::timer::CountDown, +//! T: hal::timer::CountDown, //! S: hal::serial::Read, //! { -//! timer.start(timeout); +//! timer.try_start(timeout).map_err(Error::TimedOut)?; //! //! loop { //! match serial.read() { @@ -536,16 +537,16 @@ //! Ok(byte) => return Ok(byte), //! } //! -//! match timer.wait() { +//! match timer.try_wait() { //! Err(nb::Error::Other(e)) => { -//! // The error type specified by `timer.wait()` is `!`, which +//! // The error type specified by `timer.try_wait()` is `!`, which //! // means no error can actually occur. The Rust compiler //! // still forces us to provide this match arm, though. //! unreachable!() //! }, //! // no timeout yet, try again //! Err(nb::Error::WouldBlock) => continue, -//! Ok(()) => return Err(Error::TimedOut), +//! Ok(()) => return Err(Error::TimedOut(())), //! } //! } //! } @@ -949,8 +950,8 @@ pub trait PwmPin { /// /// /// let before = qei.try_count().unwrap(); -/// timer.start(1.s()); -/// block!(timer.wait()); +/// timer.try_start(1.s()).unwrap(); +/// block!(timer.try_wait()); /// let after = qei.try_count().unwrap(); /// /// let speed = after.wrapping_sub(before); @@ -965,14 +966,14 @@ pub trait PwmPin { /// # impl hal::Qei for Qei1 { /// # type Error = Infallible; /// # type Count = u16; -/// # fn try_count(&self) -> Result { 0 } +/// # fn try_count(&self) -> Result { Ok(0) } /// # fn try_direction(&self) -> Result<::hal::Direction, Self::Error> { unimplemented!() } /// # } /// # struct Timer6; /// # impl hal::timer::CountDown for Timer6 { /// # type Time = Seconds; -/// # fn start(&mut self, _: T) where T: Into {} -/// # fn wait(&mut self) -> ::nb::Result<(), Infallible> { Ok(()) } +/// # fn try_start(&mut self, _: T) -> Result<(), Infallible> where T: Into { Ok(()) } +/// # fn try_wait(&mut self) -> ::nb::Result<(), Infallible> { Ok(()) } /// # } /// ``` #[cfg(feature = "unproven")] diff --git a/src/timer.rs b/src/timer.rs index cdde65398..518717316 100644 --- a/src/timer.rs +++ b/src/timer.rs @@ -1,13 +1,12 @@ //! Timers -use core::convert::Infallible; use nb; /// A count down timer /// /// # Contract /// -/// - `self.start(count); block!(self.wait());` MUST block for AT LEAST the time specified by +/// - `self.start(count); block!(self.try_wait());` MUST block for AT LEAST the time specified by /// `count`. /// /// *Note* that the implementer doesn't necessarily have to be a *downcounting* timer; it could also @@ -35,12 +34,12 @@ use nb; /// }; /// /// Led.on(); -/// timer.start(1.s()); -/// block!(timer.wait()); // blocks for 1 second +/// timer.try_start(1.s()).unwrap(); +/// block!(timer.try_wait()); // blocks for 1 second /// Led.off(); /// } /// -/// # use std::convert::Infallible; +/// # use core::convert::Infallible; /// # struct Seconds(u32); /// # trait U32Ext { fn s(self) -> Seconds; } /// # impl U32Ext for u32 { fn s(self) -> Seconds { Seconds(self) } } @@ -51,17 +50,23 @@ use nb; /// # } /// # struct Timer6; /// # impl hal::timer::CountDown for Timer6 { +/// # type Error = Infallible; /// # type Time = Seconds; -/// # fn start(&mut self, _: T) where T: Into {} -/// # fn wait(&mut self) -> ::nb::Result<(), Infallible> { Ok(()) } +/// # fn try_start(&mut self, _: T) -> Result<(), Self::Error> where T: Into { Ok(()) } +/// # fn try_wait(&mut self) -> ::nb::Result<(), Infallible> { Ok(()) } /// # } /// ``` pub trait CountDown { + /// An enumeration of `CountDown` errors. + /// + /// For infallible implementations, will be `Infallible` + type Error; + /// The unit of time used by this timer type Time; /// Starts a new count down - fn start(&mut self, count: T) + fn try_start(&mut self, count: T) -> Result<(), Self::Error> where T: Into; @@ -71,9 +76,9 @@ pub trait CountDown { /// /// - If `Self: Periodic`, the timer will start a new count down right after the last one /// finishes. - /// - Otherwise the behavior of calling `wait` after the last call returned `Ok` is UNSPECIFIED. + /// - Otherwise the behavior of calling `try_wait` after the last call returned `Ok` is UNSPECIFIED. /// Implementers are suggested to panic on this scenario to signal a programmer error. - fn wait(&mut self) -> nb::Result<(), Infallible>; + fn try_wait(&mut self) -> nb::Result<(), Self::Error>; } /// Marker trait that indicates that a timer is periodic @@ -81,14 +86,11 @@ pub trait Periodic {} /// Trait for cancelable countdowns. pub trait Cancel: CountDown { - /// Error returned when a countdown can't be canceled. - type Error; - /// Tries to cancel this countdown. /// /// # Errors /// /// An error will be returned if the countdown has already been canceled or was never started. /// An error is also returned if the countdown is not `Periodic` and has already expired. - fn cancel(&mut self) -> Result<(), Self::Error>; + fn try_cancel(&mut self) -> Result<(), Self::Error>; } From b5ad852ac8a31c488087472758bc0e547e2c5c06 Mon Sep 17 00:00:00 2001 From: Diego Barrios Romero Date: Thu, 12 Mar 2020 08:35:02 +0100 Subject: [PATCH 16/22] Rename SPI trait methods try_* --- src/blocking/spi.rs | 12 ++++++------ src/lib.rs | 4 ++-- src/spi.rs | 4 ++-- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/blocking/spi.rs b/src/blocking/spi.rs index 77ca3e525..bb31dec52 100644 --- a/src/blocking/spi.rs +++ b/src/blocking/spi.rs @@ -45,8 +45,8 @@ pub mod transfer { fn try_transfer<'w>(&mut self, words: &'w mut [W]) -> Result<&'w [W], S::Error> { for word in words.iter_mut() { - block!(self.send(word.clone()))?; - *word = block!(self.read())?; + block!(self.try_send(word.clone()))?; + *word = block!(self.try_read())?; } Ok(words) @@ -68,8 +68,8 @@ pub mod write { fn try_write(&mut self, words: &[W]) -> Result<(), S::Error> { for word in words { - block!(self.send(word.clone()))?; - block!(self.read())?; + block!(self.try_send(word.clone()))?; + block!(self.try_read())?; } Ok(()) @@ -96,8 +96,8 @@ pub mod write_iter { WI: IntoIterator, { for word in words.into_iter() { - block!(self.send(word.clone()))?; - block!(self.read())?; + block!(self.try_send(word.clone()))?; + block!(self.try_read())?; } Ok(()) diff --git a/src/lib.rs b/src/lib.rs index ee396d22b..1e1361c8f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -581,8 +581,8 @@ //! move || { //! let n = buffer.len(); //! for i in 0..n { -//! nb::r#await!(spi.send(buffer[i]))?; -//! buffer[i] = nb::r#await!(spi.read())?; +//! nb::r#await!(spi.try_send(buffer[i]))?; +//! buffer[i] = nb::r#await!(spi.try_read())?; //! } //! //! Ok((spi, buffer)) diff --git a/src/spi.rs b/src/spi.rs index 20d8538cd..d2c8a15e4 100644 --- a/src/spi.rs +++ b/src/spi.rs @@ -20,10 +20,10 @@ pub trait FullDuplex { /// /// **NOTE** A word must be sent to the slave before attempting to call this /// method. - fn read(&mut self) -> nb::Result; + fn try_read(&mut self) -> nb::Result; /// Sends a word to the slave - fn send(&mut self, word: Word) -> nb::Result<(), Self::Error>; + fn try_send(&mut self, word: Word) -> nb::Result<(), Self::Error>; } /// Clock polarity From da83c024bec36ace3c25759e0476f73b98d18b1f Mon Sep 17 00:00:00 2001 From: Diego Barrios Romero Date: Thu, 12 Mar 2020 08:41:42 +0100 Subject: [PATCH 17/22] Rename serial trait methods try_* --- src/blocking/serial.rs | 4 ++-- src/fmt.rs | 2 +- src/lib.rs | 34 +++++++++++++++++----------------- src/serial.rs | 6 +++--- 4 files changed, 23 insertions(+), 23 deletions(-) diff --git a/src/blocking/serial.rs b/src/blocking/serial.rs index cfc7ff591..e90767419 100644 --- a/src/blocking/serial.rs +++ b/src/blocking/serial.rs @@ -40,14 +40,14 @@ pub mod write { fn try_bwrite_all(&mut self, buffer: &[Word]) -> Result<(), Self::Error> { for word in buffer { - block!(self.write(word.clone()))?; + block!(self.try_write(word.clone()))?; } Ok(()) } fn try_bflush(&mut self) -> Result<(), Self::Error> { - block!(self.flush())?; + block!(self.try_flush())?; Ok(()) } } diff --git a/src/fmt.rs b/src/fmt.rs index 03c09363d..706d53d38 100644 --- a/src/fmt.rs +++ b/src/fmt.rs @@ -11,7 +11,7 @@ where let _ = s .as_bytes() .into_iter() - .map(|c| block!(self.write(Word::from(*c)))) + .map(|c| block!(self.try_write(Word::from(*c)))) .last(); Ok(()) } diff --git a/src/lib.rs b/src/lib.rs index 1e1361c8f..af4120942 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -75,10 +75,10 @@ //! type Error; //! //! /// Reads a single byte -//! fn read(&mut self) -> nb::Result; +//! fn try_read(&mut self) -> nb::Result; //! //! /// Writes a single byte -//! fn write(&mut self, byte: u8) -> nb::Result<(), Self::Error>; +//! fn try_write(&mut self, byte: u8) -> nb::Result<(), Self::Error>; //! } //! ``` //! @@ -150,7 +150,7 @@ //! impl hal::serial::Read for Serial { //! type Error = Error; //! -//! fn read(&mut self) -> nb::Result { +//! fn try_read(&mut self) -> nb::Result { //! // read the status register //! let isr = self.usart.isr.read(); //! @@ -172,13 +172,13 @@ //! impl hal::serial::Write for Serial { //! type Error = Error; //! -//! fn write(&mut self, byte: u8) -> nb::Result<(), Error> { -//! // Similar to the `read` implementation +//! fn try_write(&mut self, byte: u8) -> nb::Result<(), Error> { +//! // Similar to the `try_read` implementation //! # Ok(()) //! } //! -//! fn flush(&mut self) -> nb::Result<(), Error> { -//! // Similar to the `read` implementation +//! fn try_flush(&mut self) -> nb::Result<(), Error> { +//! // Similar to the `try_read` implementation //! # Ok(()) //! } //! } @@ -281,7 +281,7 @@ //! { //! let mut serial = Some(serial); //! future::poll_fn(move || { -//! let byte = try_nb!(serial.as_mut().unwrap().read()); +//! let byte = try_nb!(serial.as_mut().unwrap().try_read()); //! //! Ok(Async::Ready((serial.take().unwrap(), byte))) //! }) @@ -296,7 +296,7 @@ //! { //! let mut serial = Some(serial); //! future::poll_fn(move || { -//! try_nb!(serial.as_mut().unwrap().write(byte)); +//! try_nb!(serial.as_mut().unwrap().try_write(byte)); //! //! Ok(Async::Ready(serial.take().unwrap())) //! }) @@ -361,12 +361,12 @@ //! # pub struct Serial1; //! # impl ::hal::serial::Read for Serial1 { //! # type Error = Infallible; -//! # fn read(&mut self) -> ::nb::Result { Err(::nb::Error::WouldBlock) } +//! # fn try_read(&mut self) -> ::nb::Result { Err(::nb::Error::WouldBlock) } //! # } //! # impl ::hal::serial::Write for Serial1 { //! # type Error = Infallible; -//! # fn flush(&mut self) -> ::nb::Result<(), Infallible> { Err(::nb::Error::WouldBlock) } -//! # fn write(&mut self, _: u8) -> ::nb::Result<(), Infallible> { Err(::nb::Error::WouldBlock) } +//! # fn try_flush(&mut self) -> ::nb::Result<(), Infallible> { Err(::nb::Error::WouldBlock) } +//! # fn try_write(&mut self, _: u8) -> ::nb::Result<(), Infallible> { Err(::nb::Error::WouldBlock) } //! # } //! # //! # pub struct Led; @@ -492,7 +492,7 @@ //! S: hal::serial::Write //! { //! for &byte in buffer { -//! block!(serial.write(byte))?; +//! block!(serial.try_write(byte))?; //! } //! //! Ok(()) @@ -528,7 +528,7 @@ //! timer.try_start(timeout).map_err(Error::TimedOut)?; //! //! loop { -//! match serial.read() { +//! match serial.try_read() { //! // raise error //! Err(nb::Error::Other(e)) => return Err(Error::Serial(e)), //! Err(nb::Error::WouldBlock) => { @@ -608,7 +608,7 @@ //! { //! loop { //! if let Some(byte) = cb.peek() { -//! match serial.write(*byte) { +//! match serial.try_write(*byte) { //! Err(nb::Error::Other(_)) => unreachable!(), //! Err(nb::Error::WouldBlock) => return, //! Ok(()) => {}, // keep flushing data @@ -670,8 +670,8 @@ //! # struct Serial1; //! # impl ::hal::serial::Write for Serial1 { //! # type Error = Infallible; -//! # fn write(&mut self, _: u8) -> nb::Result<(), Infallible> { Err(::nb::Error::WouldBlock) } -//! # fn flush(&mut self) -> nb::Result<(), Infallible> { Err(::nb::Error::WouldBlock) } +//! # fn try_write(&mut self, _: u8) -> nb::Result<(), Infallible> { Err(::nb::Error::WouldBlock) } +//! # fn try_flush(&mut self) -> nb::Result<(), Infallible> { Err(::nb::Error::WouldBlock) } //! # } //! # struct CircularBuffer; //! # impl CircularBuffer { diff --git a/src/serial.rs b/src/serial.rs index 484bb2967..ea36b7818 100644 --- a/src/serial.rs +++ b/src/serial.rs @@ -11,7 +11,7 @@ pub trait Read { type Error; /// Reads a single word from the serial interface - fn read(&mut self) -> nb::Result; + fn try_read(&mut self) -> nb::Result; } /// Write half of a serial interface @@ -20,8 +20,8 @@ pub trait Write { type Error; /// Writes a single word to the serial interface - fn write(&mut self, word: Word) -> nb::Result<(), Self::Error>; + fn try_write(&mut self, word: Word) -> nb::Result<(), Self::Error>; /// Ensures that none of the previously written words are still buffered - fn flush(&mut self) -> nb::Result<(), Self::Error>; + fn try_flush(&mut self) -> nb::Result<(), Self::Error>; } From 750f0be0c4504f057b512ce8ab41c6dbe58b6610 Mon Sep 17 00:00:00 2001 From: Diego Barrios Romero Date: Thu, 12 Mar 2020 08:44:19 +0100 Subject: [PATCH 18/22] Rename methods try_* for consistency --- src/lib.rs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index af4120942..c3e84d9cc 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -216,9 +216,9 @@ //! }; //! //! for byte in b"Hello, world!" { -//! // NOTE `block!` blocks until `serial.write()` completes and returns +//! // NOTE `block!` blocks until `serial.try_write()` completes and returns //! // `Result<(), Error>` -//! block!(serial.write(*byte)).unwrap(); +//! block!(serial.try_write(*byte)).unwrap(); //! } //! # } //! @@ -226,7 +226,7 @@ //! # use std::convert::Infallible; //! # pub struct Serial1; //! # impl Serial1 { -//! # pub fn write(&mut self, _: u8) -> ::nb::Result<(), Infallible> { +//! # pub fn try_write(&mut self, _: u8) -> ::nb::Result<(), Infallible> { //! # Ok(()) //! # } //! # } @@ -419,7 +419,7 @@ //! loop { //! // `await!` means "suspend / yield here" instead of "block until //! // completion" -//! nb::r#await!(timer.wait()).unwrap(); // NOTE(unwrap) E = Infallible +//! nb::r#await!(timer.try_wait()).unwrap(); // NOTE(unwrap) E = Infallible //! //! state = !state; //! @@ -433,8 +433,8 @@ //! //! let mut loopback = (move || { //! loop { -//! let byte = nb::r#await!(serial.read()).unwrap(); -//! nb::r#await!(serial.write(byte)).unwrap(); +//! let byte = nb::r#await!(serial.try_read()).unwrap(); +//! nb::r#await!(serial.try_write(byte)).unwrap(); //! } //! }); //! @@ -450,12 +450,12 @@ //! # use std::convert::Infallible; //! # pub struct Serial1; //! # impl Serial1 { -//! # pub fn read(&mut self) -> ::nb::Result { Err(::nb::Error::WouldBlock) } -//! # pub fn write(&mut self, _: u8) -> ::nb::Result<(), Infallible> { Err(::nb::Error::WouldBlock) } +//! # pub fn try_read(&mut self) -> ::nb::Result { Err(::nb::Error::WouldBlock) } +//! # pub fn try_write(&mut self, _: u8) -> ::nb::Result<(), Infallible> { Err(::nb::Error::WouldBlock) } //! # } //! # pub struct Timer6; //! # impl Timer6 { -//! # pub fn wait(&mut self) -> ::nb::Result<(), Infallible> { Err(::nb::Error::WouldBlock) } +//! # pub fn try_wait(&mut self) -> ::nb::Result<(), Infallible> { Err(::nb::Error::WouldBlock) } //! # } //! # pub struct Led; //! # impl Led { From 4a4ff0c923794731d5029bcc92a94bb3a829bd1b Mon Sep 17 00:00:00 2001 From: Diego Barrios Romero Date: Thu, 12 Mar 2020 08:47:30 +0100 Subject: [PATCH 19/22] use core instead of std --- src/adc.rs | 2 +- src/lib.rs | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/adc.rs b/src/adc.rs index ba7655efa..488de3050 100644 --- a/src/adc.rs +++ b/src/adc.rs @@ -10,7 +10,7 @@ use nb; /// between the physical interface and the ADC sampling buffer. /// /// ``` -/// # use std::marker::PhantomData; +/// # use core::marker::PhantomData; /// # use embedded_hal::adc::Channel; /// /// struct Adc1; // Example ADC with single bank of 8 channels diff --git a/src/lib.rs b/src/lib.rs index c3e84d9cc..9a26e98ad 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -223,7 +223,7 @@ //! # } //! //! # mod stm32f30x_hal { -//! # use std::convert::Infallible; +//! # use core::convert::Infallible; //! # pub struct Serial1; //! # impl Serial1 { //! # pub fn try_write(&mut self, _: u8) -> ::nb::Result<(), Infallible> { @@ -255,7 +255,7 @@ //! }; //! use futures::future::Loop; //! use stm32f30x_hal::{Led, Serial1, Timer6}; -//! use std::convert::Infallible; +//! use core::convert::Infallible; //! //! /// `futures` version of `CountDown.try_wait` //! /// @@ -392,8 +392,8 @@ //! #[macro_use(r#await)] //! extern crate nb; //! -//! use std::ops::Generator; -//! use std::pin::Pin; +//! use core::ops::Generator; +//! use core::pin::Pin; //! //! use hal::prelude::*; //! use stm32f30x_hal::{Led, Serial1, Timer6}; @@ -447,7 +447,7 @@ //! } //! //! # mod stm32f30x_hal { -//! # use std::convert::Infallible; +//! # use core::convert::Infallible; //! # pub struct Serial1; //! # impl Serial1 { //! # pub fn try_read(&mut self) -> ::nb::Result { Err(::nb::Error::WouldBlock) } @@ -565,7 +565,7 @@ //! #[macro_use(r#await)] //! extern crate nb; //! -//! use std::ops::Generator; +//! use core::ops::Generator; //! //! /// Transfers a byte buffer of size N //! /// @@ -660,11 +660,11 @@ //! # fn lock(&self) -> RefMut { unimplemented!() } //! # } //! # struct RefMut<'a, T>(&'a mut T) where T: 'a; -//! # impl<'a, T> ::std::ops::Deref for RefMut<'a, T> { +//! # impl<'a, T> ::core::ops::Deref for RefMut<'a, T> { //! # type Target = T; //! # fn deref(&self) -> &T { self.0 } //! # } -//! # impl<'a, T> ::std::ops::DerefMut for RefMut<'a, T> { +//! # impl<'a, T> ::core::ops::DerefMut for RefMut<'a, T> { //! # fn deref_mut(&mut self) -> &mut T { self.0 } //! # } //! # struct Serial1; From 90c3c3e92247400780970060628ebdc0955aa75a Mon Sep 17 00:00:00 2001 From: Diego Barrios Romero Date: Thu, 12 Mar 2020 08:54:22 +0100 Subject: [PATCH 20/22] Remove unproven feature --- Cargo.toml | 9 ++------- ci/script.sh | 3 +-- src/adc.rs | 3 --- src/blocking/i2c.rs | 2 -- src/blocking/rng.rs | 3 --- src/blocking/spi.rs | 2 -- src/digital.rs | 9 --------- src/lib.rs | 34 +++++++++------------------------- src/prelude.rs | 14 -------------- src/rng.rs | 3 --- src/watchdog.rs | 3 --- 11 files changed, 12 insertions(+), 73 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 0fc6ab3f7..66cef8cb4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,15 +14,10 @@ readme = "README.md" repository = "https://github.com/rust-embedded/embedded-hal" version = "0.2.3" -[dependencies.nb] -version = "0.1.1" +[dependencies] +nb = { version = "0.1.1", features = ["unstable"] } [dev-dependencies] stm32f3 = { version = "0.8", features = ["stm32f303", "rt"] } futures = "0.1.17" -[features] -unproven = ["nb/unstable"] - -[package.metadata.docs.rs] -features = ["unproven"] diff --git a/ci/script.sh b/ci/script.sh index d0a23d200..600263659 100644 --- a/ci/script.sh +++ b/ci/script.sh @@ -2,11 +2,10 @@ set -euxo pipefail main() { cargo check --target $TARGET - cargo check --target $TARGET --features unproven cargo fmt -- --check if [ $TRAVIS_RUST_VERSION = nightly ]; then - cargo test --target $TARGET --features unproven + cargo test --target $TARGET fi } diff --git a/src/adc.rs b/src/adc.rs index 488de3050..c39379565 100644 --- a/src/adc.rs +++ b/src/adc.rs @@ -1,6 +1,5 @@ //! Analog-digital conversion traits -#[cfg(feature = "unproven")] use nb; /// A marker trait to identify MCU pins that can be used as inputs to an ADC channel. @@ -35,7 +34,6 @@ use nb; /// fn channel() -> (u8, u8) { (0, 3) } // bank 0 channel 3 /// } /// ``` -#[cfg(feature = "unproven")] pub trait Channel { /// Channel ID type /// @@ -85,7 +83,6 @@ pub trait Channel { /// } /// } /// ``` -#[cfg(feature = "unproven")] pub trait OneShot> { /// Error type returned by ADC methods type Error; diff --git a/src/blocking/i2c.rs b/src/blocking/i2c.rs index d8fd13f03..02844da2b 100644 --- a/src/blocking/i2c.rs +++ b/src/blocking/i2c.rs @@ -56,7 +56,6 @@ pub trait Write { } /// Blocking write (iterator version) -#[cfg(feature = "unproven")] pub trait WriteIter { /// Error type type Error; @@ -107,7 +106,6 @@ pub trait WriteRead { } /// Blocking write (iterator version) + read -#[cfg(feature = "unproven")] pub trait WriteIterRead { /// Error type type Error; diff --git a/src/blocking/rng.rs b/src/blocking/rng.rs index 8e1c13ee6..3be055fe2 100644 --- a/src/blocking/rng.rs +++ b/src/blocking/rng.rs @@ -1,9 +1,6 @@ //! Blocking hardware random number generator /// Blocking read -/// -/// *This trait is available if embedded-hal is built with the `"unproven"` feature.* -#[cfg(feature = "unproven")] pub trait Read { /// Error type type Error; diff --git a/src/blocking/spi.rs b/src/blocking/spi.rs index bb31dec52..b1e81bb8a 100644 --- a/src/blocking/spi.rs +++ b/src/blocking/spi.rs @@ -19,7 +19,6 @@ pub trait Write { } /// Blocking write (iterator version) -#[cfg(feature = "unproven")] pub trait WriteIter { /// Error type type Error; @@ -78,7 +77,6 @@ pub mod write { } /// Blocking write (iterator version) -#[cfg(feature = "unproven")] pub mod write_iter { /// Default implementation of `blocking::spi::WriteIter` for implementers of /// `spi::FullDuplex` diff --git a/src/digital.rs b/src/digital.rs index 37b05bf8c..05897fc84 100644 --- a/src/digital.rs +++ b/src/digital.rs @@ -19,9 +19,6 @@ 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.* -#[cfg(feature = "unproven")] pub trait StatefulOutputPin: OutputPin { /// Is the pin in drive high mode? /// @@ -36,13 +33,10 @@ pub trait StatefulOutputPin: OutputPin { /// 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; @@ -95,13 +89,10 @@ pub trait ToggleableOutputPin { /// pin.try_toggle().unwrap(); /// assert!(pin.try_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 diff --git a/src/lib.rs b/src/lib.rs index 9a26e98ad..8429767f5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2,10 +2,7 @@ //! //! **NOTE** This HAL is still is active development. Expect the traits presented here to be //! tweaked, split or be replaced wholesale before being stabilized, i.e. before hitting the 1.0.0 -//! release. That being said there's a part of the HAL that's currently considered unproven and is -//! hidden behind an "unproven" Cargo feature. This API is even more volatile and it's exempt from -//! semver rules: it can change in a non-backward compatible fashion or even disappear in between -//! patch releases. +//! release. //! //! # Design goals //! @@ -702,8 +699,6 @@ pub mod watchdog; /// Input capture /// -/// *This trait is available if embedded-hal is built with the `"unproven"` feature.* -/// /// # Examples /// /// You can use this interface to measure the period of (quasi) periodic signals @@ -742,17 +737,15 @@ pub mod watchdog; /// # type Error = Infallible; /// # type Capture = u16; /// # type Channel = Channel; -/// # type Error = Infallible; /// # type Time = MilliSeconds; /// # fn try_capture(&mut self, _: Channel) -> ::nb::Result { Ok(0) } /// # fn try_disable(&mut self, _: Channel) -> Result<(), Self::Error> { unimplemented!() } /// # fn try_enable(&mut self, _: Channel) -> Result<(), Self::Error> { unimplemented!() } /// # fn try_get_resolution(&self) -> Result { unimplemented!() } -/// # fn try_set_resolution(&mut self, _: T) -> Result<(), Self::Error> where T: Into {} +/// # fn try_set_resolution(&mut self, _: T) -> Result<(), Self::Error> where T: Into { Ok(()) } /// # } /// ``` -#[cfg(feature = "unproven")] -// reason: pre-singletons API. With singletons a `CapturePin` (cf. `PwmPin`) trait seems more +// unproven reason: pre-singletons API. With singletons a `CapturePin` (cf. `PwmPin`) trait seems more // appropriate pub trait Capture { /// Enumeration of `Capture` errors @@ -799,8 +792,6 @@ pub trait Capture { /// Pulse Width Modulation /// -/// *This trait is available if embedded-hal is built with the `"unproven"` feature.* -/// /// # Examples /// /// Use this interface to control the power output of some actuator @@ -841,14 +832,13 @@ pub trait Capture { /// # fn try_disable(&mut self, _: Channel) -> Result<(), Self::Error> { unimplemented!() } /// # fn try_enable(&mut self, _: Channel) -> Result<(), Self::Error> { unimplemented!() } /// # fn try_get_duty(&self, _: Channel) -> Result { unimplemented!() } -/// # fn try_get_max_duty(&self) -> Result { 0 } -/// # fn try_set_duty(&mut self, _: Channel, _: u16) -> Result<(), Self::Error> {} +/// # fn try_get_max_duty(&self) -> Result { Ok(0) } +/// # fn try_set_duty(&mut self, _: Channel, _: u16) -> Result<(), Self::Error> { Ok(()) } /// # fn try_get_period(&self) -> Result { unimplemented!() } -/// # fn try_set_period(&mut self, _: T) -> Result<(), Self::Error> where T: Into {} +/// # fn try_set_period(&mut self, _: T) -> Result<(), Self::Error> where T: Into { Ok(()) } /// # } /// ``` -#[cfg(feature = "unproven")] -// reason: pre-singletons API. The `PwmPin` trait seems more useful because it models independent +// unproven reason: pre-singletons API. The `PwmPin` trait seems more useful because it models independent // PWM channels. Here a certain number of channels are multiplexed in a single implementer. pub trait Pwm { /// Enumeration of `Pwm` errors @@ -925,8 +915,6 @@ pub trait PwmPin { /// Quadrature encoder interface /// -/// *This trait is available if embedded-hal is built with the `"unproven"` feature.* -/// /// # Examples /// /// You can use this interface to measure the speed of a motor @@ -971,13 +959,13 @@ pub trait PwmPin { /// # } /// # struct Timer6; /// # impl hal::timer::CountDown for Timer6 { +/// # type Error = Infallible; /// # type Time = Seconds; /// # fn try_start(&mut self, _: T) -> Result<(), Infallible> where T: Into { Ok(()) } /// # fn try_wait(&mut self) -> ::nb::Result<(), Infallible> { Ok(()) } /// # } /// ``` -#[cfg(feature = "unproven")] -// reason: needs to be re-evaluated in the new singletons world. At the very least this needs a +// unproven reason: needs to be re-evaluated in the new singletons world. At the very least this needs a // reference implementation pub trait Qei { /// Enumeration of `Qei` errors @@ -994,11 +982,7 @@ pub trait Qei { } /// Count direction -/// -/// *This enumeration is available if embedded-hal is built with the `"unproven"` feature.* #[derive(Clone, Copy, Debug, Eq, PartialEq)] -#[cfg(feature = "unproven")] -// reason: part of the unproven `Qei` interface pub enum Direction { /// 3, 2, 1 Downcounting, diff --git a/src/prelude.rs b/src/prelude.rs index 60f32b3d3..8205aef20 100644 --- a/src/prelude.rs +++ b/src/prelude.rs @@ -3,7 +3,6 @@ //! The traits have been renamed to avoid collisions with other items when //! performing a glob import. -#[cfg(feature = "unproven")] pub use crate::adc::OneShot as _embedded_hal_adc_OneShot; pub use crate::blocking::delay::DelayMs as _embedded_hal_blocking_delay_DelayMs; pub use crate::blocking::delay::DelayUs as _embedded_hal_blocking_delay_DelayUs; @@ -11,36 +10,23 @@ pub use crate::blocking::i2c::{ Read as _embedded_hal_blocking_i2c_Read, Write as _embedded_hal_blocking_i2c_Write, WriteRead as _embedded_hal_blocking_i2c_WriteRead, }; -#[cfg(feature = "unproven")] pub use crate::blocking::rng::Read as _embedded_hal_blocking_rng_Read; pub use crate::blocking::serial::Write as _embedded_hal_blocking_serial_Write; pub use crate::blocking::spi::{ Transfer as _embedded_hal_blocking_spi_Transfer, Write as _embedded_hal_blocking_spi_Write, }; -#[allow(deprecated)] -#[cfg(feature = "unproven")] pub use crate::digital::InputPin as _embedded_hal_digital_InputPin; -#[allow(deprecated)] pub use crate::digital::OutputPin as _embedded_hal_digital_OutputPin; -#[cfg(feature = "unproven")] -#[allow(deprecated)] pub use crate::digital::ToggleableOutputPin as _embedded_hal_digital_ToggleableOutputPin; -#[cfg(feature = "unproven")] pub use crate::rng::Read as _embedded_hal_rng_Read; pub use crate::serial::Read as _embedded_hal_serial_Read; pub use crate::serial::Write as _embedded_hal_serial_Write; pub use crate::spi::FullDuplex as _embedded_hal_spi_FullDuplex; pub use crate::timer::CountDown as _embedded_hal_timer_CountDown; -#[cfg(feature = "unproven")] pub use crate::watchdog::Watchdog as _embedded_hal_watchdog_Watchdog; -#[cfg(feature = "unproven")] pub use crate::watchdog::WatchdogDisable as _embedded_hal_watchdog_WatchdogDisable; -#[cfg(feature = "unproven")] pub use crate::watchdog::WatchdogEnable as _embedded_hal_watchdog_WatchdogEnable; -#[cfg(feature = "unproven")] pub use crate::Capture as _embedded_hal_Capture; -#[cfg(feature = "unproven")] pub use crate::Pwm as _embedded_hal_Pwm; pub use crate::PwmPin as _embedded_hal_PwmPin; -#[cfg(feature = "unproven")] pub use crate::Qei as _embedded_hal_Qei; diff --git a/src/rng.rs b/src/rng.rs index de8586c39..9afa0d0ea 100644 --- a/src/rng.rs +++ b/src/rng.rs @@ -1,11 +1,8 @@ //! Random Number Generator Interface -#[cfg(feature = "unproven")] use nb; /// Nonblocking stream of random bytes. -#[cfg(feature = "unproven")] -// reason: No implementation or users yet pub trait Read { /// An enumeration of RNG errors. /// diff --git a/src/watchdog.rs b/src/watchdog.rs index 8009cc792..b0a2efabf 100644 --- a/src/watchdog.rs +++ b/src/watchdog.rs @@ -2,7 +2,6 @@ /// Feeds an existing watchdog to ensure the processor isn't reset. Sometimes /// commonly referred to as "kicking" or "refreshing". -#[cfg(feature = "unproven")] pub trait Watchdog { /// An enumeration of `Watchdog` errors. /// @@ -16,7 +15,6 @@ pub trait Watchdog { /// Enables A watchdog timer to reset the processor if software is frozen or /// stalled. -#[cfg(feature = "unproven")] pub trait WatchdogEnable { /// An enumeration of `WatchdogEnable` errors. /// @@ -34,7 +32,6 @@ pub trait WatchdogEnable { } /// Disables a running watchdog timer so the processor won't be reset. -#[cfg(feature = "unproven")] pub trait WatchdogDisable { /// An enumeration of `WatchdogDisable` errors. /// From 5bc0f0c85db201e5b366bb54d8a549399fca9f47 Mon Sep 17 00:00:00 2001 From: Diego Barrios Romero Date: Thu, 12 Mar 2020 08:57:07 +0100 Subject: [PATCH 21/22] Update changelog --- CHANGELOG.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ca0ead6de..f33f4031c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,8 +11,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - A nonblocking trait for interfacing with random number generation hardware. ### Changed -- The current versions of `InputPin` have been proven. These are `digital::v1::InputPin` - and `digital::v2::InputPin`. +- All traits have been marked as proven (`unproven` feature has been removed). +- All trait methods have been made fallible. +- All trait methods have been renamed `try_*` (i.e. `try_send`) for consistency. ## [v0.2.3] - 2019-05-09 From ee56d1e736e7587f5ba3cd496e5f4f6eac02c894 Mon Sep 17 00:00:00 2001 From: Diego Barrios Romero Date: Sat, 14 Mar 2020 11:23:50 +0100 Subject: [PATCH 22/22] Make ADC Channel::channel() a constant and update MSRV to 1.35 --- CHANGELOG.md | 1 + src/adc.rs | 13 ++++--------- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f33f4031c..2858be9a7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - All traits have been marked as proven (`unproven` feature has been removed). - All trait methods have been made fallible. - All trait methods have been renamed `try_*` (i.e. `try_send`) for consistency. +- The minimum supported Rust version is 1.35 due to [this issue](https://github.com/rust-lang/rust/issues/54973). ## [v0.2.3] - 2019-05-09 diff --git a/src/adc.rs b/src/adc.rs index c39379565..293ad4d94 100644 --- a/src/adc.rs +++ b/src/adc.rs @@ -20,7 +20,7 @@ use nb; /// impl Channel for Gpio1Pin1 { /// type ID = u8; // ADC channels are identified numerically /// -/// fn channel() -> u8 { 7_u8 } // GPIO pin 1 is connected to ADC channel 7 +/// const CHANNEL: u8 = 7_u8; // GPIO pin 1 is connected to ADC channel 7 /// } /// /// struct Adc2; // ADC with two banks of 16 channels @@ -31,7 +31,7 @@ use nb; /// impl Channel for Gpio2PinA { /// type ID = (u8, u8); // ADC channels are identified by bank number and channel number /// -/// fn channel() -> (u8, u8) { (0, 3) } // bank 0 channel 3 +/// const CHANNEL: (u8, u8) = (0, 3); // bank 0 channel 3 /// } /// ``` pub trait Channel { @@ -44,12 +44,7 @@ pub trait Channel { /// Get the specific ID that identifies this channel, for example `0_u8` for the first ADC /// channel, if Self::ID is u8. - fn channel() -> Self::ID; - - // `channel` is a function due to [this reported - // issue](https://github.com/rust-lang/rust/issues/54973). Something about blanket impls - // combined with `type ID; const CHANNEL: Self::ID;` causes problems. - //const CHANNEL: Self::ID; + const CHANNEL: Self::ID; } /// ADCs that sample on single channels per request, and do so at the time of the request. @@ -75,7 +70,7 @@ pub trait Channel { /// type Error = (); /// /// fn try_read(&mut self, _pin: &mut PIN) -> nb::Result { -/// let chan = 1 << PIN::channel(); +/// let chan = 1 << PIN::CHANNEL; /// self.power_up(); /// let result = self.do_conversion(chan); /// self.power_down();