use embedded_hal::i2c::I2c;
use embedded_hal::i2c::SevenBitAddress;
use uom::si::electric_potential::volt;
use uom::si::f32::ElectricPotential;
use crate::{
device::AFE4404,
errors::AfeError,
modes::{LedMode, ThreeLedsMode, TwoLedsMode},
};
pub use configuration::Readings;
mod configuration;
impl<I2C, MODE> AFE4404<I2C, MODE>
where
I2C: I2c<SevenBitAddress>,
MODE: LedMode,
{
#[allow(clippy::similar_names)]
fn get_raw_readings(&mut self) -> Result<[ElectricPotential; 8], AfeError<I2C::Error>> {
let r2ah_prev = self.registers.r2Ah.read()?;
let r2bh_prev = self.registers.r2Bh.read()?;
let r2ch_prev = self.registers.r2Ch.read()?;
let r2dh_prev = self.registers.r2Dh.read()?;
let quantisation: ElectricPotential = ElectricPotential::new::<volt>(1.2) / 2_097_151.0;
let mut values: [ElectricPotential; 8] = Default::default();
#[allow(clippy::cast_precision_loss, clippy::cast_possible_wrap)]
for (i, ®ister_value) in [
r2ch_prev.led1val(),
r2ah_prev.led2val(),
r2dh_prev.aled1val(),
r2bh_prev.aled2val_or_led3val(),
]
.iter()
.enumerate()
{
let sign_extension_bits = ((register_value & 0x00FF_FFFF) >> 21) as u8;
let signed_value = match sign_extension_bits {
0b000 => register_value as i32, 0b111 => (register_value | 0xFF00_0000) as i32, _ => return Err(AfeError::AdcReadingOutsideAllowedRange),
};
values[i] = signed_value as f32 * quantisation;
}
Ok(values)
}
}
impl<I2C> AFE4404<I2C, ThreeLedsMode>
where
I2C: I2c<SevenBitAddress>,
{
pub fn read(&mut self) -> Result<Readings<ThreeLedsMode>, AfeError<I2C::Error>> {
let values = self.get_raw_readings()?;
Ok(Readings::<ThreeLedsMode>::new(
values[0], values[1], values[3], values[2],
))
}
}
impl<I2C> AFE4404<I2C, TwoLedsMode>
where
I2C: I2c<SevenBitAddress>,
{
#[allow(clippy::similar_names)]
pub fn read(&mut self) -> Result<Readings<TwoLedsMode>, AfeError<I2C::Error>> {
let values = self.get_raw_readings()?;
Ok(Readings::<TwoLedsMode>::new(
values[0], values[1], values[2], values[3],
))
}
}