use crate::common::*;
use crate::Ms4525doError;
use embedded_hal::delay::DelayNs;
use embedded_hal::i2c::I2c;
#[cfg(feature = "defmt")]
use defmt::info;
pub struct Ms4525do<I2C> {
i2c: I2C,
address: u8,
}
impl<I2C> Ms4525do<I2C>
where
I2C: I2c,
{
pub fn new(i2c: I2C) -> Self {
Self {
i2c,
address: MS4525DO_ADDR,
}
}
pub fn new_with_address(i2c: I2C, address: u8) -> Self {
Self { i2c, address }
}
pub fn read_data<D: DelayNs>(&mut self, delay: &mut D) -> Result<(f32, f32), Ms4525doError> {
let cmd = [READ_MR];
self.i2c
.write(self.address, &cmd)
.map_err(|_| Ms4525doError::I2cError)?;
delay.delay_ms(2);
let mut data_1 = [0u8; DATA_SIZE];
let mut data_2 = [0u8; DATA_SIZE];
self.i2c
.read(self.address, &mut data_1)
.map_err(|_| Ms4525doError::I2cError)?;
self.i2c
.read(self.address, &mut data_2)
.map_err(|_| Ms4525doError::I2cError)?;
let status_1 = Status::from(data_1[0] >> 6);
let status_2 = Status::from(data_2[0] >> 6);
if status_1 == Status::FaultDetected || status_2 == Status::FaultDetected {
return Err(Ms4525doError::FaultDetected);
}
if status_1 != Status::NormalOperation || status_2 != Status::StaleData {
#[cfg(feature = "defmt")]
info!("Invalid status sequence: {:?} -> {:?}", status_1, status_2);
#[cfg(all(not(feature = "defmt"), feature = "log"))]
log::info!("Invalid status sequence: {:?} -> {:?}", status_1, status_2);
return Err(Ms4525doError::InvalidStatus(status_1));
}
let bridge_data_1 = extract_bridge_data(&data_1);
let bridge_data_2 = extract_bridge_data(&data_2);
let temperature_1 = read_temperature(&data_1);
let temperature_2 = read_temperature(&data_2);
if bridge_data_1 != bridge_data_2 || temperature_1 != temperature_2 {
#[cfg(feature = "defmt")]
info!(
"Data mismatch: pressure {} != {}, temp {} != {}",
bridge_data_1, bridge_data_2, temperature_1, temperature_2
);
#[cfg(all(not(feature = "defmt"), feature = "log"))]
log::info!(
"Data mismatch: pressure {} != {}, temp {} != {}",
bridge_data_1,
bridge_data_2,
temperature_1,
temperature_2
);
return Err(Ms4525doError::StaleDataMismatch);
}
let diff_press_pa = calculate_pressure_differential_pa(bridge_data_1);
let temp_c = calculate_temperature_deg_c(temperature_1);
Ok((diff_press_pa, temp_c))
}
pub fn release(self) -> I2C {
self.i2c
}
}