use crate::conversion::{convert_temp_to_register_extended, convert_temp_to_register_normal};
use crate::{
marker::mode, AlertPolarity, BitFlagsHigh as BFH, BitFlagsLow as BFL, Config,
ConversionRate as CR, Error, FaultQueue, ModeChangeError, Register, ThermostatMode, Tmp1x2,
};
use core::marker::PhantomData;
use embedded_hal::i2c;
impl<I2C, E> Tmp1x2<I2C, mode::Continuous>
where
I2C: i2c::I2c<Error = E>,
{
pub fn into_one_shot(mut self) -> Result<Tmp1x2<I2C, mode::OneShot>, ModeChangeError<E, Self>> {
if let Err(Error::I2C(e)) = self.config_one_shot() {
return Err(ModeChangeError::I2C(e, self));
}
Ok(Tmp1x2 {
i2c: self.i2c,
address: self.address,
config: self.config,
a_temperature_conversion_was_started: false,
_mode: PhantomData,
})
}
}
impl<I2C, E> Tmp1x2<I2C, mode::OneShot>
where
I2C: i2c::I2c<Error = E>,
{
pub fn into_continuous(
mut self,
) -> Result<Tmp1x2<I2C, mode::Continuous>, ModeChangeError<E, Self>> {
if let Err(Error::I2C(e)) = self.config_continuous() {
return Err(ModeChangeError::I2C(e, self));
}
Ok(Tmp1x2 {
i2c: self.i2c,
address: self.address,
config: self.config,
a_temperature_conversion_was_started: false,
_mode: PhantomData,
})
}
pub(crate) fn trigger_one_shot_measurement(&mut self) -> Result<(), Error<E>> {
self.i2c
.write(
self.address,
&[
Register::CONFIG,
self.config.msb,
self.config.lsb | BFL::ONE_SHOT,
],
)
.map_err(Error::I2C)
}
}
impl<I2C, E, MODE> Tmp1x2<I2C, MODE>
where
I2C: i2c::I2c<Error = E>,
{
fn config_continuous(&mut self) -> Result<(), Error<E>> {
let Config { lsb, msb } = self.config;
self.write_config(lsb & !BFL::SHUTDOWN, msb)
}
fn config_one_shot(&mut self) -> Result<(), Error<E>> {
let Config { lsb, msb } = self.config;
self.write_config(lsb | BFL::SHUTDOWN, msb)
}
pub fn enable_extended_mode(&mut self) -> Result<(), Error<E>> {
let Config { lsb, msb } = self.config;
self.write_config(lsb, msb | BFH::EXTENDED_MODE)
}
pub fn disable_extended_mode(&mut self) -> Result<(), Error<E>> {
let Config { lsb, msb } = self.config;
self.write_config(lsb, msb & !BFH::EXTENDED_MODE)
}
pub fn set_conversion_rate(&mut self, rate: CR) -> Result<(), Error<E>> {
let Config { lsb, msb } = self.config;
match rate {
CR::_0_25Hz => self.write_config(lsb, msb & !BFH::CONV_RATE1 & !BFH::CONV_RATE0),
CR::_1Hz => self.write_config(lsb, msb & !BFH::CONV_RATE1 | BFH::CONV_RATE0),
CR::_4Hz => self.write_config(lsb, msb | BFH::CONV_RATE1 & !BFH::CONV_RATE0),
CR::_8Hz => self.write_config(lsb, msb | BFH::CONV_RATE1 | BFH::CONV_RATE0),
}
}
pub fn set_high_temperature_threshold(&mut self, temperature: f32) -> Result<(), Error<E>> {
self.set_temperature_threshold(temperature, Register::T_HIGH)
}
pub fn set_low_temperature_threshold(&mut self, temperature: f32) -> Result<(), Error<E>> {
self.set_temperature_threshold(temperature, Register::T_LOW)
}
fn set_temperature_threshold(
&mut self,
temperature: f32,
register: u8,
) -> Result<(), Error<E>> {
if (self.config.msb & BFH::EXTENDED_MODE) != 0 {
let (msb, lsb) = convert_temp_to_register_extended(temperature);
self.write_register(register, lsb, msb)
} else {
let (msb, lsb) = convert_temp_to_register_normal(temperature);
self.write_register(register, lsb, msb)
}
}
pub fn set_fault_queue(&mut self, fq: FaultQueue) -> Result<(), Error<E>> {
let Config { lsb, msb } = self.config;
match fq {
FaultQueue::_1 => self.write_config(lsb & !BFL::FAULT_QUEUE1 & !BFL::FAULT_QUEUE0, msb),
FaultQueue::_2 => self.write_config(lsb & !BFL::FAULT_QUEUE1 | BFL::FAULT_QUEUE0, msb),
FaultQueue::_4 => self.write_config(lsb | BFL::FAULT_QUEUE1 & !BFL::FAULT_QUEUE0, msb),
FaultQueue::_6 => self.write_config(lsb | BFL::FAULT_QUEUE1 | BFL::FAULT_QUEUE0, msb),
}
}
pub fn set_alert_polarity(&mut self, polarity: AlertPolarity) -> Result<(), Error<E>> {
let Config { lsb, msb } = self.config;
match polarity {
AlertPolarity::ActiveLow => self.write_config(lsb & !BFL::ALERT_POLARITY, msb),
AlertPolarity::ActiveHigh => self.write_config(lsb | BFL::ALERT_POLARITY, msb),
}
}
pub fn set_thermostat_mode(&mut self, mode: ThermostatMode) -> Result<(), Error<E>> {
let Config { lsb, msb } = self.config;
match mode {
ThermostatMode::Comparator => self.write_config(lsb & !BFL::THERMOSTAT, msb),
ThermostatMode::Interrupt => self.write_config(lsb | BFL::THERMOSTAT, msb),
}
}
pub fn reset_internal_driver_state(&mut self) {
self.config = Config::default();
}
fn write_config(&mut self, lsb: u8, msb: u8) -> Result<(), Error<E>> {
self.write_register(Register::CONFIG, lsb, msb)?;
self.config = Config { lsb, msb };
Ok(())
}
fn write_register(&mut self, register: u8, lsb: u8, msb: u8) -> Result<(), Error<E>> {
self.i2c
.write(self.address, &[register, msb, lsb])
.map_err(Error::I2C)
}
}