diff --git a/CHANGELOG.md b/CHANGELOG.md index 4d3c4a147..d2d33c64d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ### Added - 10-bit addressing mode for I2C traits. +- Dummy GPIO pin (no-op, zero cost) struct `DummyPin`, useful when dealing + with optional pins. ### Changed diff --git a/src/digital.rs b/src/digital.rs index 05897fc84..a38857f78 100644 --- a/src/digital.rs +++ b/src/digital.rs @@ -123,3 +123,83 @@ pub trait InputPin { /// Is the input pin low? fn try_is_low(&self) -> Result; } + +/// Dummy GPIO pin +/// +/// These structures are useful when using optional pins, for example +/// when using some SPI devices. +pub mod dummy { + use super::{InputPin, OutputPin}; + use core::{convert::Infallible, marker::PhantomData}; + + /// Pin level marker types for usage of `DummyPin` as an `InputPin`. + pub mod level { + /// `DummyPin` will always behave as being high when checked. + pub struct High; + /// `DummyPin` will always behave as being low when checked. + pub struct Low; + } + + /// Dummy (no-op, zero-cost) pin + /// + /// The implementation will discard any value written to it. When read, + /// it will always behave according to the value provided at construction + /// time (high or low). + pub struct DummyPin { + _l: PhantomData, + } + + impl DummyPin { + /// Create new instance + /// + /// When read it will always behave as being low. + pub fn new_low() -> Self { + DummyPin { _l: PhantomData } + } + } + + impl DummyPin { + /// Create new instance + /// + /// When read it will always behave as being high. + pub fn new_high() -> Self { + DummyPin { _l: PhantomData } + } + } + + impl OutputPin for DummyPin { + type Error = Infallible; + + fn try_set_high(&mut self) -> Result<(), Self::Error> { + Ok(()) + } + + fn try_set_low(&mut self) -> Result<(), Self::Error> { + Ok(()) + } + } + + impl InputPin for DummyPin { + type Error = Infallible; + + fn try_is_high(&self) -> Result { + Ok(false) + } + + fn try_is_low(&self) -> Result { + Ok(true) + } + } + + impl InputPin for DummyPin { + type Error = Infallible; + + fn try_is_high(&self) -> Result { + Ok(true) + } + + fn try_is_low(&self) -> Result { + Ok(false) + } + } +}