1use crate::{BitFlagsLow, Error, Register, SensorData, Tmp006};
2use embedded_hal::i2c;
3
4impl<I2C, E> Tmp006<I2C>
5where
6 I2C: i2c::I2c<Error = E>,
7{
8 pub fn read_object_temperature(
19 &mut self,
20 calibration_factor: f64,
21 ) -> nb::Result<f64, Error<E>> {
22 let data = self.read_sensor_data()?;
23 let temp = self.calculate_object_temperature(data, calibration_factor);
24 Ok(temp)
25 }
26
27 pub fn calculate_object_temperature(&self, data: SensorData, calibration_factor: f64) -> f64 {
37 const A1: f64 = 1.75e-3;
38 const A2: f64 = -1.678e-5;
39 const B0: f64 = -2.94e-5;
40 const B1: f64 = -5.7e-7;
41 const B2: f64 = 4.63e-9;
42 const C2: f64 = 13.4;
43 const T_REF: f64 = 298.15;
44 const V_LSB_SIZE: f64 = 156.25e-9;
45
46 let v_obj = f64::from(data.object_voltage) * V_LSB_SIZE;
47 let t_die_k = f64::from(data.ambient_temperature) / 128.0 + 273.15;
48
49 let t_diff = t_die_k - T_REF;
50 let t_diff_sq = t_diff * t_diff;
51 let v_os = B0 + B1 * t_diff + B2 * t_diff_sq;
52 let v_diff = v_obj - v_os;
53 let fv_obj = v_diff + C2 * v_diff * v_diff;
54 let s0 = calibration_factor;
55 let s = s0 * (1.0 + A1 * t_diff + A2 * t_diff_sq);
56 libm::pow(libm::pow(t_die_k, 4.0) + fv_obj / s, 0.25)
57 }
58
59 pub fn read_sensor_data(&mut self) -> nb::Result<SensorData, Error<E>> {
66 let ready = self.is_data_ready().map_err(nb::Error::Other)?;
67 if !ready {
68 return Err(nb::Error::WouldBlock);
69 }
70 let v = self
71 .read_register(Register::V_OBJECT)
72 .map_err(nb::Error::Other)?;
73 let temp = self
74 .read_register(Register::TEMP_AMBIENT)
75 .map_err(nb::Error::Other)?;
76 let data = SensorData {
77 object_voltage: v as i16,
78 ambient_temperature: temp as i16 / 4,
79 };
80 Ok(data)
81 }
82
83 #[allow(clippy::wrong_self_convention)]
87 pub fn is_data_ready(&mut self) -> Result<bool, Error<E>> {
88 let config = self.read_register(Register::CONFIG)?;
89 Ok((config & u16::from(BitFlagsLow::DRDY)) != 0)
90 }
91
92 pub fn read_manufacturer_id(&mut self) -> Result<u16, Error<E>> {
96 self.read_register(Register::MANUFAC_ID)
97 }
98
99 pub fn read_device_id(&mut self) -> Result<u16, Error<E>> {
103 self.read_register(Register::DEVICE_ID)
104 }
105
106 fn read_register(&mut self, register: u8) -> Result<u16, Error<E>> {
107 let mut data = [0; 2];
108 self.i2c
109 .write_read(self.address, &[register], &mut data)
110 .map_err(Error::I2C)?;
111 Ok((u16::from(data[0]) << 8) | u16::from(data[1]))
112 }
113}