pwm_pca9685/
config.rs

1//! Device configuration
2
3pub enum BitFlag {
4    Mode1(BitFlagMode1),
5    Mode2(BitFlagMode2),
6}
7
8pub enum BitFlagMode1 {
9    Restart = 0b1000_0000,
10    ExtClk = 0b0100_0000,
11    AutoInc = 0b0010_0000,
12    Sleep = 0b0001_0000,
13    Subaddr1 = 0b0000_1000,
14    Subaddr2 = 0b0000_0100,
15    Subaddr3 = 0b0000_0010,
16    AllCall = 0b0000_0001,
17}
18
19pub enum BitFlagMode2 {
20    Invrt = 0b0001_0000,
21    Och = 0b0000_1000,
22    OutDrv = 0b0000_0100,
23    OutNe1 = 0b0000_0010,
24    OutNe0 = 0b0000_0001,
25}
26
27impl From<BitFlagMode1> for BitFlag {
28    fn from(bf: BitFlagMode1) -> Self {
29        BitFlag::Mode1(bf)
30    }
31}
32
33impl From<BitFlagMode2> for BitFlag {
34    fn from(bf: BitFlagMode2) -> Self {
35        BitFlag::Mode2(bf)
36    }
37}
38
39#[derive(Debug, Clone, Copy)]
40pub struct Config {
41    pub mode1: u8,
42    pub mode2: u8,
43}
44
45impl Config {
46    pub fn is_high<BF: Into<BitFlag>>(self, bf: BF) -> bool {
47        match bf.into() {
48            BitFlag::Mode1(mask) => (self.mode1 & (mask as u8)) != 0,
49            BitFlag::Mode2(mask) => (self.mode2 & (mask as u8)) != 0,
50        }
51    }
52
53    pub fn is_low<BF: Into<BitFlag>>(self, bf: BF) -> bool {
54        !self.is_high(bf)
55    }
56
57    pub fn with_high<BF: Into<BitFlag>>(self, bf: BF) -> Self {
58        match bf.into() {
59            BitFlag::Mode1(mask) => Config {
60                mode1: self.mode1 | (mask as u8),
61                mode2: self.mode2,
62            },
63            BitFlag::Mode2(mask) => Config {
64                mode1: self.mode1,
65                mode2: self.mode2 | (mask as u8),
66            },
67        }
68    }
69    pub fn with_low<BF: Into<BitFlag>>(self, bf: BF) -> Self {
70        match bf.into() {
71            BitFlag::Mode1(mask) => Config {
72                mode1: self.mode1 & !(mask as u8),
73                mode2: self.mode2,
74            },
75            BitFlag::Mode2(mask) => Config {
76                mode1: self.mode1,
77                mode2: self.mode2 & !(mask as u8),
78            },
79        }
80    }
81}
82
83impl Default for Config {
84    fn default() -> Self {
85        Config {
86            mode1: (BitFlagMode1::Sleep as u8) | (BitFlagMode1::AllCall as u8),
87            mode2: BitFlagMode2::OutDrv as u8,
88        }
89    }
90}
91
92#[cfg(test)]
93mod tests {
94    use super::*;
95
96    #[test]
97    fn default_config_is_correct() {
98        assert_eq!(0b0001_0001, Config::default().mode1);
99        assert_eq!(0b0000_0100, Config::default().mode2);
100    }
101
102    #[test]
103    fn config_mode1_is_high() {
104        assert!(Config::default().is_high(BitFlagMode1::Sleep));
105    }
106    #[test]
107    fn config_mode1_is_not_high() {
108        assert!(!Config::default().is_high(BitFlagMode1::ExtClk));
109    }
110
111    #[test]
112    fn config_mode2_is_high() {
113        assert!(Config::default().is_high(BitFlagMode2::OutDrv));
114    }
115    #[test]
116    fn config_mode2_is_not_high() {
117        assert!(!Config::default().is_high(BitFlagMode2::Invrt));
118    }
119}