1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
//! This provides dummy implementations of the input/output pin [`embedded-hal`] traits.
//! This is useful when dealing with setups where a certain pin is handled by hardware in a way
//! that the software does not need to know about, for example.
//!
//! In addition to the no-op, zero-cost `DummyPin`, this crate provides an implementation of `LastStateDummyPin`,
//! which stores the last state set at runtime and returns it when read.
//!
//! [`embedded-hal`]: https://github.com/rust-embedded/embedded-hal
//!
//! ## Usage examples
//!
//! ### `DummyPin` interaction
//! A `DummyPin` does nothing and always returns the creation level when read.
//!
//! ```
//! # use embedded_hal::digital::v2::{InputPin, OutputPin, StatefulOutputPin, ToggleableOutputPin};
//! use dummy_pin::DummyPin;
//!
//! // This pin will always read low.
//! let mut pin = DummyPin::new_low();
//!
//! // Using pin as `OutpuPin` does nothing and returns `Ok(())`
//! pin.set_high().unwrap();
//!
//! // Using pin as `InputPin` always returns the creation level.
//! assert!( pin.is_low().unwrap() );
//! assert!( !pin.is_high().unwrap() );
//!
//! // Using pin as `ToggleableOutputPin` does nothing and returns `Ok(())`
//! pin.toggle().unwrap();
//!
//! // Using pin as `StatefulOutputPin` always returns the creation level.
//! assert!( pin.is_set_low().unwrap() );
//! assert!( !pin.is_set_high().unwrap() );
//! ```
//!
//! ### Pass dummy output pin to irrelevant driver output
//!
//! ```no_run
//! use dummy_pin::DummyPin;
//! use embedded_hal::digital::v2::OutputPin;
//! use linux_embedded_hal::Pin;
//!
//! struct Driver<P> {
//!     output: P,
//! }
//!
//! impl<P, E> Driver<P>
//! where
//!     P: OutputPin<Error = E>,
//! {
//!     fn new(pin: P) -> Self {
//!         Driver { output: pin }
//!     }
//!
//!     fn do_something(&mut self) -> Result<(), E> {
//!         // ...
//!         self.output.set_high()
//!     }
//! }
//!
//! // The same driver can operate with either a real or a dummy pin.
//! let real_pin = Pin::new(25);
//! let mut driver_with_real_pin = Driver::new(real_pin);
//! driver_with_real_pin.do_something().unwrap();
//!
//! let dummy_pin = DummyPin::new_low();
//! let mut driver_with_dummy_pin = Driver::new(dummy_pin);
//! driver_with_dummy_pin.do_something().unwrap();
//! ```
//!
//! ### `LastStateDummyPin` interaction
//! A `LastStateDummyPin` stores the last level set and returns it when read.
//!
//! ```
//! # use embedded_hal::digital::v2::{InputPin, OutputPin, StatefulOutputPin, ToggleableOutputPin};
//! use dummy_pin::LastStateDummyPin;
//!
//! // Initially this pin reads low.
//! let mut pin = LastStateDummyPin::new_low();
//!
//! assert!( pin.is_low().unwrap() );
//!
//! // Using pin as `OutpuPin` stores the level set
//! pin.set_high().unwrap();
//!
//! // Using pin as `InputPin` returns the last level.
//! assert!( pin.is_high().unwrap() );
//!
//! // Using pin as `ToggleableOutputPin` toggles the internal state
//! pin.toggle().unwrap();
//!
//! assert!( pin.is_low().unwrap() );
//!
//! // Using pin as `StatefulOutputPin` returns the last level.
//! assert!( pin.is_set_low().unwrap() );
//! assert!( !pin.is_set_high().unwrap() );
//! ```
//!

#![doc(html_root_url = "https://docs.rs/dummy-pin/0.1.0")]
#![deny(unsafe_code, missing_docs)]
#![no_std]

mod dummy;
pub use crate::dummy::level;
pub use crate::dummy::DummyPin;

mod last;
pub use crate::last::LastStateDummyPin;