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}