port_expander/
common.rs

1pub trait PortDriver {
2    type Error;
3
4    /// Set all pins in `mask_high` to HIGH and all pins in `mask_low` to LOW.
5    ///
6    /// The driver should implements this such that all pins change state at the same time.
7    fn set(&mut self, mask_high: u32, mask_low: u32) -> Result<(), Self::Error>;
8
9    /// Check whether pins in `mask_high` were set HIGH and pins in `mask_low` were set LOW.
10    ///
11    /// For each pin in either of the masks, the returned `u32` should have a 1 if they meet the
12    /// expected state and a 0 otherwise.  All other bits MUST always stay 0.
13    ///
14    /// If a bit is set in both `mask_high` and `mask_low`, the resulting bit must be 1.
15    fn is_set(&mut self, mask_high: u32, mask_low: u32) -> Result<u32, Self::Error>;
16
17    /// Check whether pins in `mask_high` are driven HIGH and pins in `mask_low` are driven LOW.
18    ///
19    /// For each pin in either of the masks, the returned `u32` should have a 1 if they meet the
20    /// expected state and a 0 otherwise.  All other bits MUST always stay 0.
21    ///
22    /// If a bit is set in both `mask_high` and `mask_low`, the resulting bit must be 1.
23    fn get(&mut self, mask_high: u32, mask_low: u32) -> Result<u32, Self::Error>;
24
25    fn toggle(&mut self, mask: u32) -> Result<(), Self::Error> {
26        // for all pins which are currently low, make them high.
27        let mask_high = self.is_set(0, mask)?;
28        // for all pins which are currently high, make them low.
29        let mask_low = self.is_set(mask, 0)?;
30        self.set(mask_high, mask_low)
31    }
32}
33
34pub trait PortDriverTotemPole: PortDriver {
35    /// Set the direction for all pins in `mask` to direction `dir`.
36    ///
37    /// To prevent electrical glitches, when making pins outputs, the `state` can be either `true`
38    /// or `false` to immediately put the pin HIGH or LOW upon switching.
39    fn set_direction(&mut self, mask: u32, dir: Direction, state: bool) -> Result<(), Self::Error>;
40}
41
42#[derive(Debug, Clone, Copy, PartialEq, Eq)]
43pub enum Direction {
44    Input,
45    Output,
46}
47
48pub trait PortDriverPolarity: PortDriver {
49    /// Set the polarity of all pins in `mask` either `inverted` or not.
50    fn set_polarity(&mut self, mask: u32, inverted: bool) -> Result<(), Self::Error>;
51}
52
53pub trait PortDriverPullDown: PortDriver {
54    /// Enable pull-downs for pins in mask or set the pin to floating if enable is false.
55    fn set_pull_down(&mut self, mask: u32, enable: bool) -> Result<(), Self::Error>;
56}
57
58pub trait PortDriverPullUp: PortDriver {
59    /// Enable pull-ups for pins in mask or set the pin to floating if enable is false.
60    fn set_pull_up(&mut self, mask: u32, enable: bool) -> Result<(), Self::Error>;
61}
62
63/// Pin Modes
64pub mod mode {
65    /// Trait for pin-modes which can be used to set a logic level.
66    pub trait HasOutput {}
67    /// Trait for pin-modes which can be used to read a logic level.
68    pub trait HasInput {}
69
70    /// Pin configured as an input.
71    pub struct Input;
72    impl HasInput for Input {}
73
74    /// Pin configured as an output.
75    pub struct Output;
76    impl HasOutput for Output {}
77
78    /// Pin configured as a quasi-bidirectional input/output.
79    pub struct QuasiBidirectional;
80    impl HasInput for QuasiBidirectional {}
81    impl HasOutput for QuasiBidirectional {}
82}