ina233/
lib.rs

1#![no_std]
2
3use embedded_hal::i2c::I2c;
4use error::Error;
5use registers::{
6    MfrCalibration, MfrId, MfrModel, MfrRevision, ReadIin, ReadVin, RestoreDefaultAll, TiMfrId,
7    TiMfrModel, TiMfrRevision,
8};
9use uom::si::f32::{ElectricCurrent, ElectricPotential, ElectricalResistance};
10
11pub mod error;
12
13mod bits;
14mod registers;
15
16/// A driver for a Texas Instruments INA233.
17///
18/// Generic over the device's I2C bus `S` and address `A`.
19pub struct Ina233<S: I2c, const A: u8> {
20    i2c: S,
21
22    current_lsb: ElectricCurrent,
23}
24
25impl<S: I2c, const A: u8> Ina233<S, A> {
26    /// Construct a new driver instance.
27    ///
28    /// Will error on a mismatch in any of the component identification
29    /// registers, unless the `no-verify` feature is active. Resets the device
30    /// before continuing.
31    ///
32    /// - `shunt_resistance`: The resistance of the current shunt.
33    /// - `maximum_current`: The maximum expected (measurable) current load.
34    pub fn new(
35        i2c: S,
36        shunt_resistance: ElectricalResistance,
37        maximum_current: ElectricCurrent,
38    ) -> Result<Self, Error<S>> {
39        let mut ina233 = Self {
40            i2c,
41            current_lsb: maximum_current / 0x8000 as f32,
42        };
43
44        #[cfg(not(feature = "no-verify"))]
45        {
46            let mfr_id = unsafe { ina233.read_register::<MfrId, 3>()? };
47            let mfr_model = unsafe { ina233.read_register::<MfrModel, 7>()? };
48            let mfr_revision = unsafe { ina233.read_register::<MfrRevision, 3>()? };
49            let ti_mfr_id = unsafe { ina233.read_register::<TiMfrId, 2>()? };
50            let ti_mfr_model = unsafe { ina233.read_register::<TiMfrModel, 2>()? };
51            let ti_mfr_revision = unsafe { ina233.read_register::<TiMfrRevision, 2>()? };
52
53            if mfr_id.id() != "TI"
54                || mfr_model.model() != "INA233"
55                || mfr_revision.revision() != "A1"
56                || ti_mfr_id.id() != "TI"
57                || ti_mfr_model.model() != "33"
58                || ti_mfr_revision.revision() != "A1"
59            {
60                return Err(Error::Verification);
61            }
62        }
63
64        unsafe { ina233.write_register(RestoreDefaultAll)? };
65
66        let mut mfr_calibration = MfrCalibration::default();
67        mfr_calibration.set_current_lsb(ina233.current_lsb, shunt_resistance);
68        unsafe { ina233.write_register(mfr_calibration)? };
69
70        Ok(ina233)
71    }
72
73    /// Read the latest voltage measurement.
74    pub fn voltage(&mut self) -> Result<ElectricPotential, Error<S>> {
75        Ok(unsafe { self.read_register::<ReadVin, 2>()? }.voltage())
76    }
77
78    /// Read the latest current measurement.
79    pub fn current(&mut self) -> Result<ElectricCurrent, Error<S>> {
80        Ok(unsafe { self.read_register::<ReadIin, 2>()? }.current(self.current_lsb))
81    }
82}