1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
use crate::conversion::convert_temp_from_register;
use crate::{marker::mode, BitFlagsHigh, BitFlagsLow, Error, Register, Tmp1x2};
use embedded_hal::i2c;
impl<I2C, E> Tmp1x2<I2C, mode::Continuous>
where
I2C: i2c::I2c<Error = E>,
{
/// Read the temperature from the sensor.
pub fn read_temperature(&mut self) -> Result<f32, Error<E>> {
let mut data = [0; 2];
self.i2c
.write_read(self.address, &[Register::TEMPERATURE], &mut data)
.map_err(Error::I2C)?;
Ok(convert_temp_from_register(data[0], data[1]))
}
}
impl<I2C, E> Tmp1x2<I2C, mode::OneShot>
where
I2C: i2c::I2c<Error = E>,
{
/// Read whether the one-shot measurement result is ready.
fn one_shot_measurement_is_ready(&mut self) -> Result<bool, Error<E>> {
let mut data = [0; 2];
self.i2c
.write_read(self.address, &[Register::CONFIG], &mut data)
.map_err(Error::I2C)?;
Ok((data[1] & BitFlagsLow::ONE_SHOT) != 0)
}
/// Perform a one-shot temperature measurement.
///
/// This allows triggering a single temperature measurement when in
/// shutdown mode. The device returns to the shutdown state at the
/// completion of the temperature conversion. This reduces power
/// consumption when continuous temperature monitoring is not required.
///
/// If no temperature conversion was started yet, calling this method
/// will start one and return `nb::Error::WouldBlock`. Subsequent calls
/// will continue to return `nb::Error::WouldBlock` until the
/// temperature measurement is finished. Then it will return the
/// measured temperature.
pub fn read_temperature(&mut self) -> nb::Result<f32, Error<E>> {
if !self.a_temperature_conversion_was_started {
self.trigger_one_shot_measurement()
.map_err(nb::Error::Other)?;
self.a_temperature_conversion_was_started = true;
return Err(nb::Error::WouldBlock);
}
if !self
.one_shot_measurement_is_ready()
.map_err(nb::Error::Other)?
{
Err(nb::Error::WouldBlock)
} else {
let mut data = [0; 2];
self.i2c
.write_read(self.address, &[Register::TEMPERATURE], &mut data)
.map_err(Error::I2C)
.map_err(nb::Error::Other)?;
let temp = convert_temp_from_register(data[0], data[1]);
self.a_temperature_conversion_was_started = false;
Ok(temp)
}
}
}
impl<I2C, E, MODE> Tmp1x2<I2C, MODE>
where
I2C: i2c::I2c<Error = E>,
{
/// Read whether an alert is active as defined by the comparator mode.
///
/// *NOTE*: This ignores the thermostat mode setting and always corresponds
/// to the activation status as defined by the comparator mode.
///
/// This method takes into account the alert polarity selected.
///
/// See also: [ThermostatMode](enum.ThermostatMode.html),
/// [AlertPolarity](enum.AlertPolarity.html).
#[allow(clippy::wrong_self_convention)]
pub fn is_comparator_mode_alert_active(&mut self) -> Result<bool, Error<E>> {
let mut data = [0; 2];
self.i2c
.write_read(self.address, &[Register::CONFIG], &mut data)
.map_err(Error::I2C)?;
let is_alert_polarity_high = (data[1] & BitFlagsLow::ALERT_POLARITY) != 0;
let alert_status = (data[0] & BitFlagsHigh::ALERT) != 0;
Ok(is_alert_polarity_high == alert_status)
}
}