use crate::conf::Configuration; use crate::eeprom::EEPROM; use crate::id::Identity; use crate::reg::Registers; use embedded_hal::{delay::DelayNs, i2c::I2c}; pub struct TMP117 { addr: u8, i2c: I2C, delay: Delay, } impl TMP117 { const CELSIUS_PER_LSB: f32 = 7.8125e-3; pub fn new(addr: u8, i2c: I2C, delay: Delay) -> Self { Self { addr, i2c, delay } } pub fn configure(&mut self, configuration: u16) -> Result<(), I2C::Error> { let bytes = configuration.to_be_bytes(); self.i2c.write( self.addr, &[Registers::Configuration as u8, bytes[0], bytes[1]], ) } pub fn configure_typed(&mut self, configuration: Configuration) -> Result<(), I2C::Error> { let configuration = u16::from(&configuration); self.configure(configuration) } pub fn get_configuration(&mut self) -> Result { let mut bytes = [0u8; 2]; self.i2c .write_read(self.addr, &[Registers::Configuration as u8], &mut bytes)?; let configuration = u16::from_be_bytes(bytes); Ok(configuration) } pub fn get_configuration_typed(&mut self) -> Result { let configuration = self.get_configuration()?; let configuration = Configuration::from(configuration); Ok(configuration) } pub fn configure_low_limit(&mut self, limit: i16) -> Result<(), I2C::Error> { let bytes = limit.to_be_bytes(); self.i2c .write(self.addr, &[Registers::LowLimit as u8, bytes[0], bytes[1]]) } pub fn configure_low_limit_celsius(&mut self, limit: f32) -> Result<(), I2C::Error> { let limit = limit / Self::CELSIUS_PER_LSB; let limit = limit.round() as i16; self.configure_low_limit(limit) } pub fn get_low_limit(&mut self) -> Result { let mut limit = [0u8; 2]; self.i2c .write_read(self.addr, &[Registers::LowLimit as u8], &mut limit)?; let limit = i16::from_be_bytes(limit); Ok(limit) } pub fn get_low_limit_celsius(&mut self) -> Result { let limit = self.get_low_limit()?; let limit = limit as f32 * Self::CELSIUS_PER_LSB; Ok(limit) } pub fn configure_high_limit(&mut self, limit: i16) -> Result<(), I2C::Error> { let limit = limit.to_be_bytes(); self.i2c .write(self.addr, &[Registers::HighLimit as u8, limit[0], limit[1]]) } pub fn configure_high_limit_celsius(&mut self, limit: f32) -> Result<(), I2C::Error> { let limit = limit / Self::CELSIUS_PER_LSB; let limit = limit.round() as i16; self.configure_high_limit(limit) } pub fn get_high_limit(&mut self) -> Result { let mut limit = [0u8; 2]; self.i2c .write_read(self.addr, &[Registers::HighLimit as u8], &mut limit)?; let limit = i16::from_be_bytes(limit); Ok(limit) } pub fn get_high_limit_celsius(&mut self) -> Result { let high_limit = self.get_high_limit()?; let high_limit = high_limit as f32 * Self::CELSIUS_PER_LSB; Ok(high_limit) } pub fn configure_offset_temperature(&mut self, offset: i16) -> Result<(), I2C::Error> { let offset = offset.to_be_bytes(); self.i2c.write( self.addr, &[Registers::TemperatureOffset as u8, offset[0], offset[1]], ) } pub fn configure_offset_temperature_celsius(&mut self, offset: f32) -> Result<(), I2C::Error> { let offset = offset / Self::CELSIUS_PER_LSB; let offset = offset.round() as i16; self.configure_offset_temperature(offset) } pub fn get_offset_temperature(&mut self) -> Result { let mut offset = [0u8; 2]; self.i2c.write_read( self.addr, &[Registers::TemperatureOffset as u8], &mut offset, )?; let offset = i16::from_be_bytes(offset); Ok(offset) } pub fn get_offset_temperature_celsius(&mut self) -> Result { let offset = self.get_offset_temperature()?; let offset = offset as f32 * Self::CELSIUS_PER_LSB; Ok(offset) } pub fn get_eeprom_1(&mut self) -> Result { let mut eeprom = [0u8; 2]; self.i2c .write_read(self.addr, &[Registers::Eeprom1 as u8], &mut eeprom)?; let eeprom = u16::from_be_bytes(eeprom); Ok(eeprom) } pub fn get_eeprom_2(&mut self) -> Result { let mut eeprom = [0u8; 2]; self.i2c .write_read(self.addr, &[Registers::Eeprom2 as u8], &mut eeprom)?; let eeprom = u16::from_be_bytes(eeprom); Ok(eeprom) } pub fn get_eeprom_3(&mut self) -> Result { let mut eeprom = [0u8; 2]; self.i2c .write_read(self.addr, &[Registers::Eeprom3 as u8], &mut eeprom)?; let eeprom = u16::from_be_bytes(eeprom); Ok(eeprom) } pub fn get_eeprom_all(&mut self) -> Result { let eeprom1 = self.get_eeprom_1()?; let eeprom2 = self.get_eeprom_2()?; let eeprom3 = self.get_eeprom_3()?; let eeprom = EEPROM { eeprom1, eeprom2, eeprom3, }; Ok(eeprom) } pub fn get_identity(&mut self) -> Result { let mut identity = [0u8; 2]; self.i2c .write_read(self.addr, &[Registers::DeviceId as u8], &mut identity)?; let identity = u16::from_be_bytes(identity); let identity = Identity::from(identity); Ok(identity) } pub fn get_temperature(&mut self) -> Result { let mut temperature = [0u8; 2]; self.i2c .write_read(self.addr, &[Registers::Temperature as u8], &mut temperature)?; let temperature = i16::from_be_bytes(temperature); Ok(temperature) } pub fn get_temperature_celsius(&mut self) -> Result { let temperature = self.get_temperature()?; let temperature = temperature as f32 * Self::CELSIUS_PER_LSB; Ok(temperature) } pub fn software_reset(&mut self) -> Result<(), I2C::Error> { let mask: u16 = 0x0002; let mask = mask.to_be_bytes(); self.i2c.write( self.addr, &[Registers::Configuration as u8, mask[0], mask[1]], )?; self.delay.delay_ms(2); Ok(()) } }