bq24195_i2c/
lib.rs

1//! BQ24195 is a single cell charger intended for use in portable devices. The features of the charger are summarized as they pertain to this library below.
2//!
3//! # Functional Modes
4//!
5//! Chip mode is indicated by [`Fault::WATCHDOG_FAULT`](struct.Fault.html#associatedconstant.WATCHDOG_FAULT), 1 = Default Mode and 0 = Host Mode.
6//!
7//! ## Default Mode
8//!
9//! By default, the chip does not require host management and can be used as an autonomous charger. In this case, I2C can be used to just monitor the chip's status.
10//!
11//! ## Host Mode
12//!
13//! In host mode,
14//! The chip will transition to host mode upon writing to any chip register, resetting the watchdog timer.
15//! If the watchdog timer set in [`ChargeTerminationTimerControl::WATCHDOG[1:0]`](struct.ChargeTerminationTimerControl.html#associatedconstant.WATCHDOG_1) (default 40s) expires, the chip transitions back to default mode.
16//! To stay in host mode, either write 1 twice to [`PowerOnConfiguration::I2C_WATCHDOG_TIMER_RESET`](struct.PowerOnConfiguration.html#associatedconstant.I2C_WATCHDOG_TIMER_RESET) to reset the timer before it expires,
17//! or disable the timer entirely by setting [`ChargeTerminationTimerControl::WATCHDOG[1:0]`](struct.ChargeTerminationTimerControl.html#associatedconstant.WATCHDOG_1) to 00.
18//!
19//! # BATFET
20//!
21//! The battery field-effect transistor (BATFET) is used to control the flow of current to the battery.
22//! You can manually disable it by writing 1 to [`MiscOperationControl::BATFET_DISABLE`](struct.MiscOperationControl.html#associatedconstant.BATFET_DISABLE). This disconnects the battery, disabling both charging and discharging.
23//!
24//! # Power Path Management
25//! [Dynamic Power Management](https://www.ti.com/lit/ds/symlink/bq24195l.pdf#%5B%7B%22num%22%3A326%2C%22gen%22%3A0%7D%2C%7B%22name%22%3A%22XYZ%22%7D%2C0%2C202.4%2C0%5D) ensures compliance with the USB specification.
26//! It continuously monitors the input current and input voltage to maintain nominal system performance.
27//!
28//! ## Overloaded input source
29//! If input current exceeds [`InputSourceControl::IINLIM[2:0]`](struct.InputSourceControl.html#associatedconstant.IINLIM_2) or input voltage falls below 3.88V + [`InputSourceControl::VINDPM[3:0]`](struct.InputSourceControl.html#associatedconstant.VINDPM_3),
30//! then the input source is considered overloaded. [`SystemStatus::DPM_STATUS`](struct.SystemStatus.html#associatedconstant.DPM_STAT) will indicate these conditions.
31//! DPM will reduce charge current until it is no longer overloaded.
32//!
33//! For example, the default input voltage limit offset is set to 480 mV (3.88V + 480mV = 4.36V), which is the correct voltage for fully charging a Lithium-Ion cell.
34//!
35//! ## Supplement mode
36//!
37//! If the input source is still overloaded when the charge current is dropped to 0A, the chip enters supplement mode; the BATFET is turned on and the battery begins discharging to supplement the input source.
38//!
39//! # Battery Charging Management
40//!
41//! BQ24195 is designed to charge a single-cell Li-Ion high capacity battery (i.e. 18650).
42//!
43//! Although the default current limit [`InputSourceControl::IINLIM[2:0]`](struct.InputSourceControl.html#associatedconstant.IINLIM_2) is listed as 100 mA, the actual default value will depend on USB detection.
44//!
45//! ## USB D+/D- Detection
46//!
47//!  The charger detects the type of USB connection and sets the input current limit to comply with the USB specification:
48//!
49//! * Floating data lines after 500ms: 100mA (IINLIM[2:0] = 000)
50//! * Standard Down Stream Port (SDP) (connected to USB Host)
51//!     * OTG pin = 0 : 100 mA (IINLIM[2:0] = 000)
52//!     * OTG pin = 1 : 500 mA (IINLIM[2:0] = 010)
53//! * Charging Down Stream Port or Dedicated Charging Down Stream Port (CDP/DCP): 1.5A (IINLIM[2:0] = 101)
54//!
55//! ## HIZ
56//!
57//! When the chip is in high-impedance (HIZ) the buck converter is disabled and the system load is supplied by the battery. To comply with the USB battery charging specification, the chip enters HIZ if the input source is a 100mA USB host and the battery voltage is above VBATGD (3.55V).
58//!
59//! This can be manually controlled via [InputSourceControl::EN_HIZ](struct.InputSourceControl.html#associatedconstant.EN_HIZ).
60//!
61//! ## ILIM
62//!
63//! ILIM is a hardware pin for a limiting maximum input current. It is grounded with a resistor using the following formula: `ILIM = 1V / R_ILIM * 530`
64//!
65//! By changing [`InputSourceControl::IINLIM[2:0]`](struct.InputSourceControl.html#associatedconstant.IINLIM_2), you can [ONLY REDUCE the input current limit below ILIM](https://www.ti.com/lit/ds/symlink/bq24195l.pdf#%5B%7B%22num%22%3A436%2C%22gen%22%3A0%7D%2C%7B%22name%22%3A%22XYZ%22%7D%2C0%2C481.2%2C0%5D).
66//!
67//! ## Charging Profile
68//!
69//! To safely charge the battery and preserve its lifetime, charging is split into several phases (collectively referred to as the charging profile):
70//!
71//! * Almost Empty or Empty Cell: the battery voltage is below the battery short voltage (VBAT_SHORT = 2V) and is charged at 100mA, which cannot be changed
72//!     * [Lithium-Ion batteries should never be drained below 3V](https://electronics.stackexchange.com/questions/219222/is-draining-a-li-ion-to-2-5v-harmful-to-the-battery). If they are, battery life is significantly reduced.
73//! * Pre-charge: the battery voltage is 2V to 3V, and current limit is set to 128mA + [`PreChargeTerminationCurrentControl::IPRECHG[3:0]`](struct.PreChargeTerminationCurrentControl.html#associatedconstant.IPRECHG_3)
74//! * Fast Charge: the battery voltage is above [`ChargeVoltageControl::BATLOWV`](struct.ChargeVoltageControl.html#associatedconstant.BATLOWV) (2.8V/3V), and the current limit is set to 512mA + [`ChargeCurrentControl::ICHG[5:0]`](struct.ChargeCurrentControl.html#associatedconstant.ICHG_5)
75//! * Constant-Voltage: the battery voltage has reached the recharge threshold voltage (3.504V + [`ChargeVoltageControl::VREG[5:0]`](struct.ChargeVoltageControl.html#associatedconstant.VREG_5)),and charging current drops rapidly to 128mA + [`PreChargeTerminationCurrentControl::ITERM[3:0]`](struct.PreChargeTerminationCurrentControl.html#associatedconstant.ITERM_3) at which charging is terminated
76//!
77//! ## Battery Temperature
78//!
79//! An external thermistor is used to measure battery temperature. The reading must be between VLTF and VHTF, else the chip will suspend charging. The nature of the thermal fault will be indicated in [`Fault::NTC_FAULT[2:0]`](struct.Fault.html#associatedconstant.NTC_FAULT_2)
80//!
81//! In some cases, there is no therimstor present because the battery is external, in which case the chip may always report a normal battery temperature.
82//!
83//! ## Charging Termination
84//!
85//! BQ24195 will terminate charging when the battery voltage has reached the recharge threshold and the current has dropped below the termination threshold. [`SystemStatus::CHRG_STAT_1`](struct.SystemStatus.html#associatedconstant.CHRG_STAT_1) will become 11.
86//!
87//! Termination will be disabled if the device is in thermal regulation or input current/voltage regulation. It can also be disabled manually by writing 0 to [`ChargeTerminationTimerControl::EN_TERM`](struct.ChargeTerminationTimerControl.html#associatedconstant.EN_TERM)
88//!
89//! When [`ChargeCurrentControl::FORCE_20PCT`](struct.ChargeCurrentControl.html#associatedconstant.FORCE_20PCT) is set, make sure that the termination current [`PreChargeTerminationCurrentControl::ITERM[3:0]`](struct.PreChargeTerminationCurrentControl.html#associatedconstant.ITERM_3) is less than 20% of the charging current, otherwise charging will not terminate.
90//!
91//! Writing 1 to [`ChargeTerminationTimerControl::TERM_STAT`](struct.ChargeTerminationTimerControl.html#associatedconstant.TERM_STAT) will enable an early charge done indication on the STAT pin when charging current falls below 800 mA.
92//!
93//! ## Safety Timer
94//!
95//! A safety timer is used to stop charging if it is taking too long. When connected to a 100mA USB source, it is ALWAYS a maximum of 45 minutes. Otherwise, in device mode, it is 5 hours long. In host mode, it is 8 hours long but can be changed.
96//! If battery voltage is below [`ChargeVoltageControl::BATLOWV`](struct.ChargeVoltageControl.html#associatedconstant.BATLOWV), it is 1 hour.
97//! An expired safety timer will appear as [`Fault::CHRG_FAULT[1:0]`](struct.Fault.html#associatedconstant.CHRG_FAULT_1) equal to 11. The timer can be enabled/disabled by writing to [`ChargeTerminationTimerControl::EN_TIMER`](struct.ChargeTerminationTimerControl.html#associatedconstant.EN_TIMER).
98//!
99//! ### Restarting the timer
100//!
101//! The timer can be restarted by disabling and then re-enabling it. It is also restarted when [`PowerOnConfiguration::CHG_CONFIG[1:0]`](struct.PowerOnConfiguration.html#associatedconstant.CHG_CONFIG_1) is changed from disabled to any enabled mode.
102//!
103//! ### Changing the timer
104//!
105//! To change the timer, the datasheet recommends you first disable it, write the desired value to [`ChargeTerminationTimerControl::CHG_TIMER[2:1]`](struct.ChargeTerminationTimerControl.html#associatedconstant.CHG_TIMER_1), then re-enable it.
106//!
107//! ### Half clock rate
108//!
109//! The safety timer will count at half the normal clock rate when in thermal regulation, input voltage/current regulation, or [`ChargeCurrentControl::FORCE_20PCT`](struct.ChargeCurrentControl.html#associatedconstant.FORCE_20PCT) is set.
110//! A 5 hour safety timer would actually be 10 hours long.
111//!
112//! # Protections
113//!
114//! ## ILIM
115//!
116//! Already discussed above.
117//!
118//! ## Battery Over-Current Protection
119//!
120//! If the battery voltage is at least 4% above the regulation voltage, charging is immediately disabled and [`Fault::CHRG_FAULT_1`](struct.Fault.html#associatedconstant.CHRG_FAULT_1) goes high.
121//!
122//! ## Input Over-Voltage
123//!
124//! An input voltage of over 18V for VBUS will stop buck mode operation and [`Fault::CHRG_FAULT[1:0]`](struct.Fault.html#associatedconstant.CHRG_FAULT_1) will be set to 01.
125
126#![no_std]
127#![forbid(unsafe_code)]
128
129extern crate embedded_hal as hal;
130
131use hal::blocking::i2c::{Write, WriteRead};
132
133/// I2C Address of BQ24195
134pub const ADDRESS: u8 = 0x6B;
135
136macro_rules! registers {
137    ($(
138            $(#[$outer:meta])*
139            $registerName: ident ($registerAddress: pat) {
140                #[$bit7meta:meta]
141                $bit7: ident,
142                #[$bit6meta:meta]
143                $bit6: ident,
144                #[$bit5meta:meta]
145                $bit5: ident,
146                #[$bit4meta:meta]
147                $bit4: ident,
148                #[$bit3meta:meta]
149                $bit3: ident,
150                #[$bit2meta:meta]
151                $bit2: ident,
152                #[$bit1meta:meta]
153                $bit1: ident,
154                #[$bit0meta:meta]
155                $bit0: ident,
156                Default { $($default:ident),* }
157            }
158        ),*
159    ) => {
160        paste::item!{
161            /// BQ24195 state, as viewed from I2C
162            #[derive(Clone)]
163            pub struct ChargerState {
164                $(
165                    [<$registerName:snake:lower>]: $registerName,
166                )*
167            }
168        }
169
170        paste::item! {
171            impl ChargerState {
172                /// Create a new `ChargerState` struct by reading all registers over I2C
173                ///
174                /// `Default` is NOT implemented for `ChargerState` because some registers do not actually have a default
175                pub fn try_new<E, I2C: WriteRead<Error = E>>(i2c: &mut I2C) -> Result<Self, E> {
176                    let mut state = Self {
177                        $(
178                            [<$registerName:snake:lower>]: $registerName::default(),
179                        )*
180                    };
181                    state.read_all(i2c)?;
182                    Ok(state)
183                }
184
185                /// Read all registers to set the current state of BQ24195.
186                pub fn read_all<E, I2C: WriteRead<Error = E>>(&mut self, i2c: &mut I2C) -> Result<(), E> {
187                    let mut values = [0u8; NUM_REGISTERS];
188                    i2c.write_read(ADDRESS, &[0x00], &mut values)?;
189                    $(
190                        self.[<$registerName:snake:lower>] = values[$registerAddress].into();
191                    )*
192                    Ok(())
193                }
194
195                /// Write chip state to all registers. Useful for taking a preset chip state and applying it.
196                ///
197                /// [Relevant BQ24195 Datasheet Section](https://www.ti.com/lit/ds/symlink/bq24195l.pdf#%5B%7B%22num%22%3A98%2C%22gen%22%3A0%7D%2C%7B%22name%22%3A%22XYZ%22%7D%2C0%2C556.4%2C0%5D)
198                pub fn write_all<E, I2C: Write<Error = E>>(&self, i2c: &mut I2C) -> Result<(), E> {
199                    i2c.write(ADDRESS, &[0x00])?;
200                    let mut values = [0u8; NUM_REGISTERS];
201                    $(
202                        values[$registerAddress] = self.[<$registerName:snake:lower>].into();
203                    )*
204                    i2c.write(ADDRESS, &values[..=LAST_WRITABLE_REGISTER])?;
205                    Ok(())
206                }
207
208                $(
209                    /// Get a register state from the current chip state. Does NOT do an I2C call.
210                    pub fn [<get_$registerName:snake:lower>](&self) -> $registerName {
211                        self.[<$registerName:snake:lower>]
212                    }
213
214                    /// Read the state of a single register over I2C, updating the chip state.
215                    ///
216                    /// If an error occurs, the chip state remains the same.
217                    pub fn [<read_$registerName:snake:lower>]<E, I2C: WriteRead<Error = E>>(&mut self, i2c: &mut I2C) -> Result<(), E> {
218                        let mut value = [0u8; 1];
219                        i2c.write_read(ADDRESS, &[$registerAddress], &mut value)?;
220                        self.[<$registerName:snake:lower>] = value[0].into();
221                        Ok(())
222                    }
223
224                    /// Write the state of a single register over I2C, updating the chip state.
225                    ///
226                    /// If an error occurs, the chip state remains the same.
227                    pub fn [<write_$registerName:snake:lower>]<E, I2C: Write<Error = E>>(&mut self, i2c: &mut I2C, [<$registerName:snake:lower>]: $registerName) -> Result<(), E> {
228                        i2c.write(ADDRESS, &[$registerAddress])?;
229                        let value = [[<$registerName:snake:lower>].into(); 1];
230                        i2c.write(ADDRESS, &value)?;
231                        self.[<$registerName:snake:lower>] = [<$registerName:snake:lower>];
232                        Ok(())
233                    }
234                )*
235            }
236        }
237
238        $(
239            $(#[$outer])*
240            #[derive(Copy, Debug, PartialEq, Clone, Eq)]
241            pub struct $registerName {
242                bits: u8
243            }
244
245            impl $registerName {
246                #[$bit7meta]
247                pub const $bit7: Self = Self { bits: 1u8 << 7 };
248                #[$bit6meta]
249                pub const $bit6: Self = Self { bits: 1u8 << 6 };
250                #[$bit5meta]
251                pub const $bit5: Self = Self { bits: 1u8 << 5 };
252                #[$bit4meta]
253                pub const $bit4: Self = Self { bits: 1u8 << 4 };
254                #[$bit3meta]
255                pub const $bit3: Self = Self { bits: 1u8 << 3 };
256                #[$bit2meta]
257                pub const $bit2: Self = Self { bits: 1u8 << 2 };
258                #[$bit1meta]
259                pub const $bit1: Self = Self { bits: 1u8 << 1 };
260                #[$bit0meta]
261                pub const $bit0: Self = Self { bits: 1u8 << 0 };
262            }
263
264            impl core::ops::BitOr for $registerName {
265                type Output = Self;
266                fn bitor(self, rhs: Self) -> Self {
267                    Self { bits: self.bits | rhs.bits }
268                }
269            }
270
271            impl core::ops::BitOrAssign for $registerName {
272                fn bitor_assign(&mut self, rhs: Self) {
273                    self.bits |= rhs.bits;
274                }
275            }
276
277            impl core::ops::BitAnd for $registerName {
278                type Output = Self;
279                fn bitand(self, rhs: Self) -> Self {
280                    Self { bits: self.bits & rhs.bits }
281                }
282            }
283
284            impl core::ops::BitAndAssign for $registerName {
285                fn bitand_assign(&mut self, rhs: Self) {
286                    self.bits &= rhs.bits;
287                }
288            }
289
290            impl core::ops::BitXor for $registerName {
291                type Output = Self;
292                fn bitxor(self, rhs: Self) -> Self {
293                    Self { bits: self.bits ^ rhs.bits }
294                }
295            }
296
297            impl core::ops::BitXorAssign for $registerName {
298                fn bitxor_assign(&mut self, rhs: Self) {
299                    self.bits ^= rhs.bits;
300                }
301            }
302
303            impl Default for $registerName {
304                fn default() -> $registerName {
305                    $($registerName::$default |)* 0u8.into()
306                }
307            }
308
309            impl From<u8> for $registerName {
310                fn from(bits: u8) -> $registerName {
311                    $registerName {
312                        bits
313                    }
314                }
315            }
316
317            impl Into<u8> for $registerName {
318                fn into(self) -> u8 {
319                    self.bits
320                }
321            }
322        )*
323    };
324}
325
326const NUM_REGISTERS: usize = 11;
327const LAST_WRITABLE_REGISTER: usize = 7;
328
329registers!(
330    /// [Register 0x00](https://www.ti.com/lit/ds/symlink/bq24195l.pdf#%5B%7B%22num%22%3A578%2C%22gen%22%3A0%7D%2C%7B%22name%22%3A%22XYZ%22%7D%2C0%2C681.2%2C0%5D)
331    ///
332    /// VINDPM[3:0] is added to 3.88V
333    ///
334    /// IINLIM[2:0] is scaled in an odd manner:
335    /// ```
336    /// 000 = 100  mA
337    /// 001 = 150  mA
338    /// 010 = 500  mA
339    /// 011 = 900  mA
340    /// 100 = 1200 mA
341    /// 101 = 1500 mA
342    /// 110 = 2000 mA
343    /// 111 = 3000 mA
344    /// ```
345    InputSourceControl (0x00) {
346        /// Buck Converter Control (0 = Restart Buck Converter, 1 = Buck Converter Stops, system load supplied by battery)
347        EN_HIZ,
348        /// Input Voltage Limit Offset Bit 3: 640mV
349        VINDPM_3,
350        /// Input Voltage Limit Offset Bit 2: 320 mV
351        VINDPM_2,
352        /// Input Voltage Limit Offset Bit 1: 160 mV
353        VINDPM_1,
354        /// Input Voltage Limit Offset Bit 0: 80 mV
355        VINDPM_0,
356        /// Input Current Limit Bit 2
357        IINLIM_2,
358        /// Input Current Limit Bit 1
359        IINLIM_1,
360        /// Input Current Limit Bit 0
361        IINLIM_0,
362    Default { VINDPM_2, VINDPM_1 }},
363    /// [Register 0x01](https://www.ti.com/lit/ds/symlink/bq24195l.pdf#%5B%7B%22num%22%3A586%2C%22gen%22%3A0%7D%2C%7B%22name%22%3A%22XYZ%22%7D%2C0%2C720%2C0%5D)
364    ///
365    /// SYS_MIN[2:0] is added to 3.0V
366    PowerOnConfiguration (0x01) {
367        /// Resets this register upon writing this value, returns to 0 after reset
368        REGISTER_RESET,
369        /// Reset I2C watchdog timer, returns to 0 after reset
370        I2C_WATCHDOG_TIMER_RESET,
371        /// Charger Configuration Bit 1 (10/11 = OTG)
372        CHG_CONFIG_1,
373        /// Charger Configuration Bit 0 (00 = Charge Disable, 01 = Charge Battery)
374        CHG_CONFIG_0,
375        /// Minimum System Voltage Limit Offset Bit 2: 0.4V
376        SYS_MIN_2,
377        /// Minimum System Voltage Limit Offset Bit 2: 0.2V
378        SYS_MIN_1,
379        /// Minimum System Voltage Limit Offset Bit 2: 0.1V
380        SYS_MIN_0,
381        /// Reserved, must write 1
382        RESERVED,
383    Default {
384        CHG_CONFIG_0,
385        SYS_MIN_2,
386        SYS_MIN_0,
387        RESERVED
388    }},
389    /// [Register 0x02](https://www.ti.com/lit/ds/symlink/bq24195l.pdf#%5B%7B%22num%22%3A158%2C%22gen%22%3A0%7D%2C%7B%22name%22%3A%22XYZ%22%7D%2C0%2C720%2C0%5D)
390    ///
391    /// ICHG[5:0] is added to 512mA
392    ChargeCurrentControl (0x02) {
393        /// Fast Charge Current Limit Offset Bit 5: 2048 mA
394        ICHG_5,
395        /// Fast Charge Current Limit Offset Bit 4: 1024 mA
396        ICHG_4,
397        /// Fast Charge Current Limit Offset Bit 3: 512 mA
398        ICHG_3,
399        /// Fast Charge Current Limit Offset Bit 2: 256 mA
400        ICHG_2,
401        /// Fast Charge Current Limit Offset Bit 1: 128 mA
402        ICHG_1,
403        /// Fast Charge Current Limit Offset Bit 0: 64 mA
404        ICHG_0,
405        /// Reserved, must write 0
406        RESERVED,
407        /// Force 20% of fast-charge current limit and 50% of pre-charge current limit
408        FORCE_20PCT,
409    Default { ICHG_4, ICHG_3 }},
410    /// [Register 0x03](https://www.ti.com/lit/ds/symlink/bq24195l.pdf#%5B%7B%22num%22%3A158%2C%22gen%22%3A0%7D%2C%7B%22name%22%3A%22XYZ%22%7D%2C0%2C409.9%2C0%5D)
411    ///
412    /// IPRECHG[3:0] is added to 128mA
413    ///
414    /// ITERM[3:0] is added to 128mA
415    PreChargeTerminationCurrentControl (0x03) {
416        /// Pre-Charge Current Limit Offset Bit 3: 1024 mA
417        IPRECHG_3,
418        /// Pre-Charge Current Limit Offset Bit 2: 512 mA
419        IPRECHG_2,
420        /// Pre-Charge Current Limit Offset Bit 1: 256 mA
421        IPRECHG_1,
422        /// Pre-Charge Current Limit Offset Bit 0: 128 mA
423        IPRECHG_0,
424        /// Termination Current Limit Offset Bit 3: 1024 mA
425        ITERM_3,
426        /// Termination Current Limit Offset Bit 2: 512 mA
427        ITERM_2,
428        /// Termination Current Limit Offset Bit 1: 256 mA
429        ITERM_1,
430        /// Termination Current Limit Offset Bit 0: 128 mA
431        ITERM_0,
432    Default { IPRECHG_0, ITERM_0 }},
433    /// [Register 0x04](https://www.ti.com/lit/ds/symlink/bq24195l.pdf#%5B%7B%22num%22%3A601%2C%22gen%22%3A0%7D%2C%7B%22name%22%3A%22XYZ%22%7D%2C0%2C720%2C0%5D)
434    ///
435    /// VREG[5:0] is added to 3.504V
436    ChargeVoltageControl (0x04) {
437        /// Charger Voltage Limit Offset Bit 5: 512mV
438        VREG_5,
439        /// Charger Voltage Limit Offset Bit 4: 256mV
440        VREG_4,
441        /// Charger Voltage Limit Offset Bit 3: 128mV
442        VREG_3,
443        /// Charger Voltage Limit Offset Bit 2: 64mV
444        VREG_2,
445        /// Charger Voltage Limit Offset Bit 1: 32mV
446        VREG_1,
447        /// Charger Voltage Limit Offset Bit 0: 16mV
448        VREG_0,
449        /// Battery Precharge to Fast Charge Threshold: (0 = 2.8V, 1 = 3.0V)
450        BATLOWV,
451        /// Battery Recharge to Threshold (below battery regulation voltage) (0 = 100 mV, 1 = 300 mV)
452        VRECHG,
453    Default {
454        VREG_5,
455        VREG_3,
456        VREG_2,
457        BATLOWV
458    }},
459    /// [Register 0x05](https://www.ti.com/lit/ds/symlink/bq24195l.pdf#%5B%7B%22num%22%3A601%2C%22gen%22%3A0%7D%2C%7B%22name%22%3A%22XYZ%22%7D%2C0%2C437.5%2C0%5D)
460    ChargeTerminationTimerControl (0x05) {
461        /// Charging Termination Enable
462        EN_TERM,
463        /// Termination Indicator Threshold
464        TERM_STAT,
465        /// I2C Watchdog Timer Setting Bit 1: (10 = 80s, 11 = 160s)
466        WATCHDOG_1,
467        /// I2C Watchdog Timer Setting Bit 0: (00 = Disable Timer, 01 = 40s)
468        WATCHDOG_0,
469        /// Charging Safety Timer Enable
470        EN_TIMER,
471        /// Fast Charge Timer Setting Bit 1 (10 = 12h, 11 = 20h)
472        CHG_TIMER_1,
473        /// Fast Charge Timer Setting Bit 0 (00 = 5h, 01 = 8h)
474        CHG_TIMER_0,
475        /// Reserved, must write 0
476        RESERVED,
477    Default {
478        EN_TERM,
479        WATCHDOG_0,
480        EN_TIMER,
481        CHG_TIMER_0
482    }},
483    /// [Register 0x06](https://www.ti.com/lit/ds/symlink/bq24195l.pdf#%5B%7B%22num%22%3A609%2C%22gen%22%3A0%7D%2C%7B%22name%22%3A%22XYZ%22%7D%2C0%2C720%2C0%5D)
484    ThermalRegulationControl (0x06) {
485        /// Reserved, must write 0
486        RESERVED_7,
487        /// Reserved, must write 0
488        RESERVED_6,
489        /// Reserved, must write 0
490        RESERVED_5,
491        /// Reserved, must write 0
492        RESERVED_4,
493        /// Reserved, must write 0
494        RESERVED_3,
495        /// Reserved, must write 0
496        RESERVED_2,
497        /// Thermal Regulation Threshold Bit 1 (10 = 100C, 11 = 120C)
498        TREG_1,
499        /// Thermal Regulation Threshold Bit 0 (00 = 60C, 01 = 80C)
500        TREG_0,
501    Default { TREG_1, TREG_0 }},
502    /// [Register 0x07](https://www.ti.com/lit/ds/symlink/bq24195l.pdf#%5B%7B%22num%22%3A609%2C%22gen%22%3A0%7D%2C%7B%22name%22%3A%22XYZ%22%7D%2C0%2C463.9%2C0%5D)
503    MiscOperationControl (0x07) {
504        /// Force DPDM detection
505        DPDM_EN,
506        /// Safety Timer Setting during Input DPM and Thermal Regulation (1 = safety timer slowed by 2x, 0 = normal speed)
507        TMR2X_EN,
508        /// Force BATFET Off
509        BATFET_DISABLE,
510        /// Reserved, must write 0
511        RESERVED_4,
512        /// Reserved, must write 1
513        RESERVED_3,
514        /// Reserved, must write 0
515        RESERVED_2,
516        /// Interrupt Mask Bit 1 (1 = interrupt on CHRG_FAULT)
517        INT_MASK_1,
518        /// Interrupt Mask Bit 0 (0 = interrupt on BAT_FAULT)
519        INT_MASK_0,
520    Default {
521        TMR2X_EN,
522        RESERVED_3,
523        INT_MASK_1,
524        INT_MASK_0
525    }},
526    /// [Register 0x08](https://www.ti.com/lit/ds/symlink/bq24195l.pdf#%5B%7B%22num%22%3A618%2C%22gen%22%3A0%7D%2C%7B%22name%22%3A%22XYZ%22%7D%2C0%2C720%2C0%5D)
527    SystemStatus (0x08) {
528        /// VBUS Status Bit 1 (10 = Adapter port, 11 = OTG)
529        VBUS_STAT_1,
530        /// VBUS Status Bit 0 (00 = Unknown, 01 = USB host)
531        VBUS_STAT_0,
532        /// Charging Status Bit 1 (10 = Fast Charging, 11 = Charge Termination Done)
533        CHRG_STAT_1,
534        /// Charging Status Bit 0 (00 = Not Charging, 01 = Pre-Charge)
535        CHRG_STAT_0,
536        /// DPM Status (0 = Not DPM, 1 = VINDPM / IINDPM)
537        DPM_STAT,
538        /// Power Good Status (0 = not good, 1 = good)
539        PG_STAT,
540        /// Thermal Regulation Status (0 = normal, 1 = thermal regulation)
541        THERM_STAT,
542        /// VSYSMIN Regulation Status (0 = BAT > VSYSTMIN, 1 = BAT < VSYSMIN)
543        VSYS_STAT,
544    Default {}},
545    /// [Register 0x09](https://www.ti.com/lit/ds/symlink/bq24195l.pdf#%5B%7B%22num%22%3A618%2C%22gen%22%3A0%7D%2C%7B%22name%22%3A%22XYZ%22%7D%2C0%2C468.1%2C0%5D)
546    Fault (0x09) {
547        /// Watchdog Fault Status (0 = normal, 1 = watchdog timer expired)
548        WATCHDOG_FAULT,
549        /// Reserved, always 0
550        RESERVED,
551        /// Charging Fault Bit 1 (10 = Thermal shutdown, 11 = Charge Safety Timer Expiration)
552        CHRG_FAULT_1,
553        /// Charging Fault Bit 0 (00 = Normal, 01 = Input Fault (VBUS OVP or VBAT < VBUS < 3.8V))
554        CHRG_FAULT_0,
555        /// Battery Fault: (0 = Normal, 1 = BATOVP)
556        BAT_FAULT,
557        /// NTC Fault Bit 2 (110 = Hot, 101 = Cold)
558        NTC_FAULT_2,
559        /// NTC Fault Bit 1 (110 = Hot)
560        NTC_FAULT_1,
561        /// NTC Fault Bit 0 (000 = Normal, 101 = Cold)
562        NTC_FAULT_0,
563    Default { WATCHDOG_FAULT }},
564    /// [Register 0x0A](https://www.ti.com/lit/ds/symlink/bq24195l.pdf#%5B%7B%22num%22%3A626%2C%22gen%22%3A0%7D%2C%7B%22name%22%3A%22XYZ%22%7D%2C0%2C720%2C0%5D)
565    VendorPartRevisionStatus (0x0A) {
566        /// Reserved, always 0
567        RESERVED_7,
568        /// Reserved, always 0
569        RESERVED_6,
570        /// Always 1
571        PN_2,
572        /// Always 0
573        PN_1,
574        /// Always 0
575        PN_0,
576        /// 0 = Cold/Hot Window
577        TS_PROFILE,
578        /// Always 1 (note the inversed bit order here)
579        DEV_REG_0,
580        /// Always 1
581        DEV_REG_1,
582    Default {
583        PN_2,
584        DEV_REG_0,
585        DEV_REG_1
586    }}
587);