use crate::conversion::{convert_temp_to_register_extended, convert_temp_to_register_normal};
use crate::RegisterU16;
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;
#[cfg(not(feature = "async"))]
use embedded_hal::i2c::I2c;
#[cfg(feature = "async")]
use embedded_hal_async::i2c::I2c as AsyncI2c;
#[maybe_async_cfg::maybe(
sync(
cfg(not(feature = "async")),
self = "Tmp1x2",
idents(AsyncI2c(sync = "I2c"))
),
async(feature = "async", keep_self)
)]
impl<I2C, E> Tmp1x2<I2C, mode::Continuous>
where
I2C: AsyncI2c<Error = E>,
{
pub async fn into_one_shot(
mut self,
) -> Result<Tmp1x2<I2C, mode::OneShot>, ModeChangeError<E, Self>> {
if let Err(Error::I2C(e)) = self.config_one_shot().await {
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,
})
}
}
#[maybe_async_cfg::maybe(
sync(
cfg(not(feature = "async")),
self = "Tmp1x2",
idents(AsyncI2c(sync = "I2c"))
),
async(feature = "async", keep_self)
)]
impl<I2C, E> Tmp1x2<I2C, mode::OneShot>
where
I2C: AsyncI2c<Error = E>,
{
pub async fn into_continuous(
mut self,
) -> Result<Tmp1x2<I2C, mode::Continuous>, ModeChangeError<E, Self>> {
if let Err(Error::I2C(e)) = self.config_continuous().await {
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) async fn trigger_one_shot_measurement(&mut self) -> Result<(), Error<E>> {
self.write_register(Register::CONFIG, self.config.with_high_msb(BFH::ONE_SHOT))
.await
}
}
#[maybe_async_cfg::maybe(
sync(
cfg(not(feature = "async")),
self = "Tmp1x2",
idents(AsyncI2c(sync = "I2c"))
),
async(feature = "async", keep_self)
)]
impl<I2C, E, MODE> Tmp1x2<I2C, MODE>
where
I2C: AsyncI2c<Error = E>,
{
async fn config_continuous(&mut self) -> Result<(), Error<E>> {
self.write_config(self.config.with_low_msb(BFH::SHUTDOWN))
.await
}
async fn config_one_shot(&mut self) -> Result<(), Error<E>> {
self.write_config(self.config.with_high_msb(BFH::SHUTDOWN))
.await
}
pub async fn enable_extended_mode(&mut self) -> Result<(), Error<E>> {
self.write_config(self.config.with_high_lsb(BFL::EXTENDED_MODE))
.await
}
pub async fn disable_extended_mode(&mut self) -> Result<(), Error<E>> {
self.write_config(self.config.with_low_lsb(BFL::EXTENDED_MODE))
.await
}
pub async 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(Config {
lsb: lsb & !BFL::CONV_RATE1 & !BFL::CONV_RATE0,
msb,
})
.await
}
CR::_1Hz => {
self.write_config(Config {
lsb: lsb & !BFL::CONV_RATE1 | BFL::CONV_RATE0,
msb,
})
.await
}
CR::_4Hz => {
self.write_config(Config {
lsb: lsb | BFL::CONV_RATE1 & !BFL::CONV_RATE0,
msb,
})
.await
}
CR::_8Hz => {
self.write_config(Config {
lsb: lsb | BFL::CONV_RATE1 | BFL::CONV_RATE0,
msb,
})
.await
}
}
}
pub async fn set_high_temperature_threshold(
&mut self,
temperature: f32,
) -> Result<(), Error<E>> {
self.set_temperature_threshold(temperature, Register::T_HIGH)
.await
}
pub async fn set_low_temperature_threshold(
&mut self,
temperature: f32,
) -> Result<(), Error<E>> {
self.set_temperature_threshold(temperature, Register::T_LOW)
.await
}
async fn set_temperature_threshold(
&mut self,
temperature: f32,
register: u8,
) -> Result<(), Error<E>> {
if (self.config.lsb & BFL::EXTENDED_MODE) != 0 {
let (msb, lsb) = convert_temp_to_register_extended(temperature);
self.write_register(register, RegisterU16 { lsb, msb })
.await
} else {
let (msb, lsb) = convert_temp_to_register_normal(temperature);
self.write_register(register, RegisterU16 { lsb, msb })
.await
}
}
pub async fn set_fault_queue(&mut self, fq: FaultQueue) -> Result<(), Error<E>> {
let Config { lsb, msb } = self.config;
match fq {
FaultQueue::_1 => {
self.write_config(Config {
lsb,
msb: msb & !BFH::FAULT_QUEUE1 & !BFH::FAULT_QUEUE0,
})
.await
}
FaultQueue::_2 => {
self.write_config(Config {
lsb,
msb: msb & !BFH::FAULT_QUEUE1 | BFH::FAULT_QUEUE0,
})
.await
}
FaultQueue::_4 => {
self.write_config(Config {
lsb,
msb: msb | BFH::FAULT_QUEUE1 & !BFH::FAULT_QUEUE0,
})
.await
}
FaultQueue::_6 => {
self.write_config(Config {
lsb,
msb: msb | BFH::FAULT_QUEUE1 | BFH::FAULT_QUEUE0,
})
.await
}
}
}
pub async fn set_alert_polarity(&mut self, polarity: AlertPolarity) -> Result<(), Error<E>> {
match polarity {
AlertPolarity::ActiveLow => {
self.write_config(self.config.with_low_msb(BFH::ALERT_POLARITY))
.await
}
AlertPolarity::ActiveHigh => {
self.write_config(self.config.with_high_msb(BFH::ALERT_POLARITY))
.await
}
}
}
pub async fn set_thermostat_mode(&mut self, mode: ThermostatMode) -> Result<(), Error<E>> {
match mode {
ThermostatMode::Comparator => {
self.write_config(self.config.with_low_msb(BFH::THERMOSTAT))
.await
}
ThermostatMode::Interrupt => {
self.write_config(self.config.with_high_msb(BFH::THERMOSTAT))
.await
}
}
}
pub fn reset_internal_driver_state(&mut self) {
self.config = Config::default();
}
}