Skip to main content

async_ltc681x/driver/registers/
cfga.rs

1use super::base::{BitPos, RegisterBlock};
2/// Struct representing the Configuration Register Group A of the chip
3///
4/// For now only the minimum necessary access functions for Conf Group A are provided:
5/// ADCOPT => Defines conversion rate settings
6/// REFON => brings chip into Reference On State
7/// GPIO1..5 => Configuration of the GPIO Pins 1 to 5
8#[derive(Debug, Clone, Copy)]
9pub struct CfgA {
10    reg: RegisterBlock,
11}
12/// Enumeration of all GPIOs in [`CfgA`] which can be [`pulled down`](CfgA::pulldown_gpio) or [`released`](CfgA::release_gpio) (This is a Open Drain GPIO!)
13#[derive(Debug, Copy, Clone, PartialEq)]
14pub enum Gpio {
15    Gpio1 = 3,
16    Gpio2 = 4,
17    Gpio3 = 5,
18    Gpio4 = 6,
19    Gpio5 = 7,
20}
21impl From<Gpio> for BitPos {
22    fn from(value: Gpio) -> Self {
23        match value {
24            Gpio::Gpio1 => BitPos::Pos3,
25            Gpio::Gpio2 => BitPos::Pos4,
26            Gpio::Gpio3 => BitPos::Pos5,
27            Gpio::Gpio4 => BitPos::Pos6,
28            Gpio::Gpio5 => BitPos::Pos7,
29        }
30    }
31}
32impl From<RegisterBlock> for CfgA {
33    fn from(value: RegisterBlock) -> Self {
34        Self { reg: value }
35    }
36}
37impl From<CfgA> for RegisterBlock {
38    fn from(value: CfgA) -> Self {
39        value.reg
40    }
41}
42
43/// Enumeration of all Cell Balance Switches in [`CfgA`] which can be [`activated`](CfgA::activate_single_switch) or [`deactivated`](CfgA::deactivate_single_switch)
44#[derive(Debug, Copy, Clone, PartialEq)]
45pub enum BalancingSwitch {
46    SwitchCell1,
47    SwitchCell2,
48    SwitchCell3,
49    SwitchCell4,
50    SwitchCell5,
51    SwitchCell6,
52    SwitchCell7,
53    SwitchCell8,
54    SwitchCell9,
55    SwitchCell10,
56    SwitchCell11,
57    SwitchCell12,
58}
59impl From<BalancingSwitch> for BitPos {
60    fn from(value: BalancingSwitch) -> Self {
61        match value {
62            BalancingSwitch::SwitchCell1 => BitPos::Pos0,
63            BalancingSwitch::SwitchCell2 => BitPos::Pos1,
64            BalancingSwitch::SwitchCell3 => BitPos::Pos2,
65            BalancingSwitch::SwitchCell4 => BitPos::Pos3,
66            BalancingSwitch::SwitchCell5 => BitPos::Pos4,
67            BalancingSwitch::SwitchCell6 => BitPos::Pos5,
68            BalancingSwitch::SwitchCell7 => BitPos::Pos6,
69            BalancingSwitch::SwitchCell8 => BitPos::Pos7,
70            BalancingSwitch::SwitchCell9 => BitPos::Pos8,
71            BalancingSwitch::SwitchCell10 => BitPos::Pos9,
72            BalancingSwitch::SwitchCell11 => BitPos::Pos10,
73            BalancingSwitch::SwitchCell12 => BitPos::Pos11,
74        }
75    }
76}
77/// Creates a `CfgA` Structure with the default values of the chip. This does not read back the actual
78/// `CfgA` Register value from the chip. Default value is only guaranteed to be inline with the actual register value
79/// of the chip after power up.
80impl Default for CfgA {
81    fn default() -> Self {
82        let reg = Self {
83            reg: RegisterBlock::default(),
84        };
85        // Default Settings of the Chip
86        reg.reset_adcopt() // ADCOPT = 0
87            .reset_ref_on() // REF_ON = 0
88            .release_gpio(Gpio::Gpio1) // GPIO_1 = 1 (Open Drain: Not pulled down)
89            .release_gpio(Gpio::Gpio2) // GPIO_2 = 1 (Open Drain: Not pulled down)
90            .release_gpio(Gpio::Gpio3) // GPIO_3 = 1 (Open Drain: Not pulled down)
91            .release_gpio(Gpio::Gpio4) // GPIO_4 = 1 (Open Drain: Not pulled down)
92            .release_gpio(Gpio::Gpio5) // GPIO_5 = 1 (Open Drain: Not pulled down)
93    }
94}
95impl CfgA {
96    /// Activate the open drain pulldown of the given GPIO
97    #[must_use]
98    pub fn pulldown_gpio(mut self, io: Gpio) -> Self {
99        self.reg.reset_bits_reg1(0b1, io.into());
100        self
101    }
102    /// Deactivate the open drain pulldown of the given GPIO (Floating Input)
103    ///
104    /// If the GPIOs are used as an ADC input, the pulldown must be deactivted for this GPIO.
105    #[must_use]
106    pub fn release_gpio(mut self, io: Gpio) -> Self {
107        self.reg.set_bits_reg1(0b1, io.into());
108        self
109    }
110    /// Sets the `REF_ON` Bit
111    ///
112    /// Powers Up the Reference and stays active until the Watchdog Timer shutsdown the chip
113    #[must_use]
114    pub fn set_ref_on(mut self) -> Self {
115        self.reg.set_bits_reg1(0b1, BitPos::Pos2);
116        self
117    }
118    /// Resets the `REF_ON` Bit
119    ///
120    /// Reference is powered down. Reference is powered up for conversion and goes back to shutdown
121    /// after conversion
122    #[must_use]
123    pub fn reset_ref_on(mut self) -> Self {
124        self.reg.reset_bits_reg1(0b1, BitPos::Pos2);
125        self
126    }
127    /// Sets the ADCOPT Bit
128    ///
129    /// Conversion Rates for ADCOPT Bit set are
130    /// ADCOPT = 1
131    ///
132    /// MD Bits [0, 0]: Conversion Rate 1kHz
133    ///
134    /// MD Bits [0, 1]: Conversion Rate 14kHz
135    ///
136    /// MD Bits [1, 0]: Conversion Rate 3kHz
137    ///
138    /// MD Bits [1, 1]: Conversion Rate 2kHz
139    ///
140    #[must_use]
141    pub fn set_adcopt(mut self) -> Self {
142        self.reg.set_bits_reg1(0b01, BitPos::Pos0);
143        self
144    }
145    /// Resets the ADCOPT Bit
146    ///
147    /// Conversion Rates for ADCOPT Bit not set are
148    ///
149    /// ADCOPT = 0
150    ///
151    /// MD Bits [0, 0]: Conversion Rate 422Hz
152    ///
153    /// MD Bits [0, 1]: Conversion Rate 27kHz
154    ///
155    /// MD Bits [1, 0]: Conversion Rate 7kHz
156    ///
157    /// MD Bits [1, 1]: Conversion Rate 26Hz
158    ///
159    #[must_use]
160    pub fn reset_adcopt(mut self) -> Self {
161        self.reg.reset_bits_reg1(0b1, BitPos::Pos0);
162        self
163    }
164
165    /// Activates the given Balancing Switch
166    #[must_use]
167    pub fn activate_single_switch(mut self, switch_nr: BalancingSwitch) -> Self {
168        self.reg.set_bits_reg3(0b1, switch_nr.into());
169        self
170    }
171    /// Deactivates the given Balancing Switch
172    #[must_use]
173    pub fn deactivate_single_switch(mut self, switch_nr: BalancingSwitch) -> Self {
174        self.reg.reset_bits_reg3(0b1, switch_nr.into());
175        self
176    }
177}
178
179#[cfg(test)]
180mod tests {
181    use super::*;
182    #[test]
183    fn some_test() {
184        let cfga = CfgA::default();
185        assert_eq!(cfga.reg.reg_1, 0b0000_0000_1111_1000);
186
187        let cfga = cfga.pulldown_gpio(Gpio::Gpio2).pulldown_gpio(Gpio::Gpio5);
188        assert_eq!(cfga.reg.reg_1, 0b0000_0000_0110_1000);
189
190        let cfga = cfga.release_gpio(Gpio::Gpio2);
191        assert_eq!(cfga.reg.reg_1, 0b0000_0000_0111_1000);
192
193        let cfga = cfga.set_ref_on();
194        assert_eq!(cfga.reg.reg_1, 0b0000_0000_0111_1100);
195        let cfga = cfga.reset_ref_on().release_gpio(Gpio::Gpio5);
196        assert_eq!(cfga.reg.reg_1, 0b0000_0000_1111_1000);
197
198        let cfga = cfga
199            .set_ref_on()
200            .pulldown_gpio(Gpio::Gpio5)
201            .set_adcopt()
202            .pulldown_gpio(Gpio::Gpio3);
203        assert_eq!(cfga.reg.reg_1, 0b0000_0000_0101_1101);
204
205        assert_eq!(
206            CfgA::from(RegisterBlock::default()).reg,
207            RegisterBlock::default()
208        );
209        assert_eq!(RegisterBlock::from(CfgA::default()).reg_1, 248);
210    }
211}