Skip to content

Commit d7be300

Browse files
committed
Add fallible version of the digital traits and deprecate the current ones
1 parent 0ee24e4 commit d7be300

File tree

4 files changed

+181
-0
lines changed

4 files changed

+181
-0
lines changed

CHANGELOG.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,19 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
77

88
## [Unreleased]
99

10+
### Added
11+
- A new version of the digital `OutputPin`, `StatefulOutputPin`, `ToggleableOutputPin`
12+
and `InputPin` traits has been added under `digital::v2`. These traits are now
13+
fallible and their methods now return a `Result` type as setting an output pin
14+
and reading an input pin could potentially fail.
15+
See [here](https://github.com/rust-embedded/embedded-hal/issues/95) for more info.
16+
17+
### Changed
18+
- The current versions of the `OutputPin`, `StatefulOutputPin`, `ToggleableOutputPin`
19+
and `InputPin` traits have been marked as deprecated. Please use the new versions
20+
included in `digital::v2`.
21+
See [here](https://github.com/rust-embedded/embedded-hal/issues/95) for more info.
22+
1023
## [v0.2.1] - 2018-05-14
1124

1225
### Changed

src/digital.rs renamed to src/digital/mod.rs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
11
//! Digital I/O
2+
//!
3+
//! The traits in this module are now deprecated. Please use the new versions included
4+
//! in `digital::v2`.
25
36
/// Single digital push-pull output pin
7+
///
8+
/// *This version of the trait is now deprecated. Please use the new `OutputPin` trait in
9+
/// `digital::v2::OutputPin`*.
10+
#[deprecated]
411
pub trait OutputPin {
512
/// Drives the pin low
613
///
@@ -18,6 +25,10 @@ pub trait OutputPin {
1825
/// Push-pull output pin that can read its output state
1926
///
2027
/// *This trait is available if embedded-hal is built with the `"unproven"` feature.*
28+
///
29+
/// *This version of the trait is now deprecated. Please use the new `StatefulOutputPin` trait in
30+
/// `digital::v2::StatefulOutputPin`*.
31+
#[deprecated]
2132
#[cfg(feature = "unproven")]
2233
pub trait StatefulOutputPin {
2334
/// Is the pin in drive high mode?
@@ -35,10 +46,14 @@ pub trait StatefulOutputPin {
3546
///
3647
/// *This trait is available if embedded-hal is built with the `"unproven"` feature.*
3748
///
49+
/// *This version of the trait is now deprecated. Please use the new `ToggleableOutputPin`
50+
/// trait in `digital::v2::ToggleableOutputPin`*.
51+
///
3852
/// See [toggleable](toggleable) to use a software implementation if
3953
/// both [OutputPin](trait.OutputPin.html) and
4054
/// [StatefulOutputPin](trait.StatefulOutputPin.html) are
4155
/// implemented. Otherwise, implement this using hardware mechanisms.
56+
#[deprecated]
4257
#[cfg(feature = "unproven")]
4358
pub trait ToggleableOutputPin {
4459
/// Toggle pin output.
@@ -48,6 +63,9 @@ pub trait ToggleableOutputPin {
4863
/// If you can read **and** write the output state, a pin is
4964
/// toggleable by software.
5065
///
66+
/// *This version of the module is now deprecated. Please use the new `toggleable` module in
67+
/// `digital::v2::toggleable`*.
68+
///
5169
/// ```
5270
/// use embedded_hal::digital::{OutputPin, StatefulOutputPin, ToggleableOutputPin};
5371
/// use embedded_hal::digital::toggleable;
@@ -84,15 +102,19 @@ pub trait ToggleableOutputPin {
84102
/// pin.toggle();
85103
/// assert!(pin.is_set_low());
86104
/// ```
105+
#[deprecated]
87106
#[cfg(feature = "unproven")]
88107
pub mod toggleable {
108+
#[allow(deprecated)]
89109
use super::{OutputPin, StatefulOutputPin, ToggleableOutputPin};
90110

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

117+
#[allow(deprecated)]
96118
impl<P> ToggleableOutputPin for P
97119
where
98120
P: Default,
@@ -111,6 +133,10 @@ pub mod toggleable {
111133
/// Single digital input pin
112134
///
113135
/// *This trait is available if embedded-hal is built with the `"unproven"` feature.*
136+
///
137+
/// *This version of the trait is now deprecated. Please use the new `InputPin` trait in
138+
/// `digital::v2::InputPin`*.
139+
#[deprecated]
114140
#[cfg(feature = "unproven")]
115141
pub trait InputPin {
116142
/// Is the input pin high?
@@ -119,3 +145,6 @@ pub trait InputPin {
119145
/// Is the input pin low?
120146
fn is_low(&self) -> bool;
121147
}
148+
149+
/// Improved version of the digital traits where the methods can also return an error.
150+
pub mod v2;

src/digital/v2.rs

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
/// Digital I/O
2+
3+
/// Single digital push-pull output pin
4+
pub trait OutputPin {
5+
/// Error type
6+
type Error;
7+
8+
/// Drives the pin low
9+
///
10+
/// *NOTE* the actual electrical state of the pin may not actually be low, e.g. due to external
11+
/// electrical sources
12+
fn set_low(&mut self) -> Result<(), Self::Error>;
13+
14+
/// Drives the pin high
15+
///
16+
/// *NOTE* the actual electrical state of the pin may not actually be high, e.g. due to external
17+
/// electrical sources
18+
fn set_high(&mut self) -> Result<(), Self::Error>;
19+
}
20+
21+
/// Push-pull output pin that can read its output state
22+
///
23+
/// *This trait is available if embedded-hal is built with the `"unproven"` feature.*
24+
#[cfg(feature = "unproven")]
25+
pub trait StatefulOutputPin : OutputPin {
26+
/// Is the pin in drive high mode?
27+
///
28+
/// *NOTE* this does *not* read the electrical state of the pin
29+
fn is_set_high(&self) -> Result<bool, Self::Error>;
30+
31+
/// Is the pin in drive low mode?
32+
///
33+
/// *NOTE* this does *not* read the electrical state of the pin
34+
fn is_set_low(&self) -> Result<bool, Self::Error>;
35+
}
36+
37+
/// Output pin that can be toggled
38+
///
39+
/// *This trait is available if embedded-hal is built with the `"unproven"` feature.*
40+
///
41+
/// See [toggleable](toggleable) to use a software implementation if
42+
/// both [OutputPin](trait.OutputPin.html) and
43+
/// [StatefulOutputPin](trait.StatefulOutputPin.html) are
44+
/// implemented. Otherwise, implement this using hardware mechanisms.
45+
#[cfg(feature = "unproven")]
46+
pub trait ToggleableOutputPin {
47+
/// Error type
48+
type Error;
49+
50+
/// Toggle pin output.
51+
fn toggle(&mut self) -> Result<(), Self::Error>;
52+
}
53+
54+
/// If you can read **and** write the output state, a pin is
55+
/// toggleable by software.
56+
///
57+
/// ```
58+
/// use embedded_hal::digital::v2::{OutputPin, StatefulOutputPin, ToggleableOutputPin};
59+
/// use embedded_hal::digital::v2::toggleable;
60+
///
61+
/// /// A virtual output pin that exists purely in software
62+
/// struct MyPin {
63+
/// state: bool
64+
/// }
65+
///
66+
/// impl OutputPin for MyPin {
67+
/// type Error = void::Void;
68+
///
69+
/// fn set_low(&mut self) -> Result<(), Self::Error> {
70+
/// self.state = false;
71+
/// Ok(())
72+
/// }
73+
/// fn set_high(&mut self) -> Result<(), Self::Error> {
74+
/// self.state = true;
75+
/// Ok(())
76+
/// }
77+
/// }
78+
///
79+
/// impl StatefulOutputPin for MyPin {
80+
/// fn is_set_low(&self) -> Result<bool, Self::Error> {
81+
/// Ok(!self.state)
82+
/// }
83+
/// fn is_set_high(&self) -> Result<bool, Self::Error> {
84+
/// Ok(self.state)
85+
/// }
86+
/// }
87+
///
88+
/// /// Opt-in to the software implementation.
89+
/// impl toggleable::Default for MyPin {}
90+
///
91+
/// let mut pin = MyPin { state: false };
92+
/// pin.toggle().unwrap();
93+
/// assert!(pin.is_set_high().unwrap());
94+
/// pin.toggle().unwrap();
95+
/// assert!(pin.is_set_low().unwrap());
96+
/// ```
97+
#[cfg(feature = "unproven")]
98+
pub mod toggleable {
99+
use super::{OutputPin, StatefulOutputPin, ToggleableOutputPin};
100+
101+
/// Software-driven `toggle()` implementation.
102+
///
103+
/// *This trait is available if embedded-hal is built with the `"unproven"` feature.*
104+
pub trait Default: OutputPin + StatefulOutputPin {}
105+
106+
impl<P> ToggleableOutputPin for P
107+
where
108+
P: Default,
109+
{
110+
type Error = P::Error;
111+
112+
/// Toggle pin output
113+
fn toggle(&mut self) -> Result<(), Self::Error> {
114+
if self.is_set_low()? {
115+
self.set_high()
116+
} else {
117+
self.set_low()
118+
}
119+
}
120+
}
121+
}
122+
123+
/// Single digital input pin
124+
///
125+
/// *This trait is available if embedded-hal is built with the `"unproven"` feature.*
126+
#[cfg(feature = "unproven")]
127+
pub trait InputPin {
128+
/// Error type
129+
type Error;
130+
131+
/// Is the input pin high?
132+
fn is_high(&self) -> Result<bool, Self::Error>;
133+
134+
/// Is the input pin low?
135+
fn is_low(&self) -> Result<bool, Self::Error>;
136+
}

src/prelude.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,13 @@ pub use blocking::serial::Write as _embedded_hal_blocking_serial_Write;
1515
pub use blocking::spi::{
1616
Transfer as _embedded_hal_blocking_spi_Transfer, Write as _embedded_hal_blocking_spi_Write,
1717
};
18+
#[allow(deprecated)]
1819
#[cfg(feature = "unproven")]
1920
pub use digital::InputPin as _embedded_hal_digital_InputPin;
21+
#[allow(deprecated)]
2022
pub use digital::OutputPin as _embedded_hal_digital_OutputPin;
2123
#[cfg(feature = "unproven")]
24+
#[allow(deprecated)]
2225
pub use digital::ToggleableOutputPin as _embedded_hal_digital_ToggleableOutputPin;
2326
pub use serial::Read as _embedded_hal_serial_Read;
2427
pub use serial::Write as _embedded_hal_serial_Write;

0 commit comments

Comments
 (0)