use embedded_hal::delay;
use crate::{interface::{I2cAddr, I2cInterface, ReadData, WriteData, SpiInterface}, registers::Registers, types::{Error, Odr, PowerMode, IntConfig, IntSource, IntStatus, Status, OsrConfig, DeepDis, OdrConfig}};
pub struct Bmp581<I> {
interface: I,
}
impl<I2C> Bmp581<I2cInterface<I2C>>
{
pub fn new_i2c(i2c: I2C, address: I2cAddr) -> Self {
Bmp581 {
interface: I2cInterface {
i2c,
address: address.addr(),
},
}
}
pub fn release(self) -> I2C {
self.interface.i2c
}
}
impl<SPI> Bmp581<SpiInterface<SPI>>
{
pub fn new_spi(spi: SPI) -> Self {
Bmp581 {
interface: SpiInterface {
spi,
},
}
}
pub fn release(self) -> SPI {
self.interface.spi
}
}
impl<I, CommE> Bmp581<I>
where
I: ReadData<Error = Error<CommE>> + WriteData<Error = Error<CommE>>,
{
pub fn init<D>(&mut self, delay: &mut D) -> Result<(), Error<CommE>>
where
D: delay::DelayNs,
{
self.soft_reset()?;
delay.delay_us(2000);
let chip_id = self.get_chip_id()?;
if chip_id != 0x50 {
return Err(Error::InvalidChipId(chip_id));
}
let _status = self.get_status()?;
let _int_status = self.get_int_status()?;
let mut odr_config = self.get_odr_config()?;
odr_config.deep_dis = DeepDis::Disabled;
self.set_odr_config(odr_config)?;
Ok(())
}
pub fn get_chip_id(&mut self) -> Result<u8, Error<CommE>> {
self.interface.read_reg(Registers::CHIP_ID)
}
pub fn set_pressure_enabled(&mut self, enable: bool) -> Result<(), Error<CommE>> {
let mut current = self.interface.read_reg(Registers::OSR_CONFIG)?;
if enable {
current |= 1 << 6; } else {
current &= !(1 << 6); }
self.interface.write_reg(Registers::OSR_CONFIG, current)
}
pub fn soft_reset(&mut self) -> Result<(), Error<CommE>> {
self.interface.write_reg(Registers::CMD, 0xB6)
}
pub fn get_odr_config(&mut self) -> Result<OdrConfig, Error<CommE>> {
let register = self.interface.read_reg(Registers::ODR_CONFIG)?;
Ok(OdrConfig::from_reg(register))
}
pub fn set_power_mode(&mut self, mode: PowerMode) -> Result<(), Error<CommE>> {
let mut current = self.interface.read_reg(Registers::ODR_CONFIG)?;
current &= !0x03;
current |= mode as u8 & 0x03;
current |= 0b1 << 7;
self.interface.write_reg(Registers::ODR_CONFIG, current)
}
pub fn set_odr(&mut self, odr: Odr) -> Result<(), Error<CommE>> {
let mut current = self.interface.read_reg(Registers::ODR_CONFIG)?;
current &= !(0x1F << 2);
current |= (odr as u8) << 2;
self.interface.write_reg(Registers::ODR_CONFIG, current)
}
pub fn set_osr_config(&mut self, config: OsrConfig) -> Result<(), Error<CommE>> {
self.interface.write_reg(Registers::OSR_CONFIG, config.to_reg())
}
pub fn set_odr_config(&mut self, config: OdrConfig) -> Result<(), Error<CommE>> {
self.interface.write_reg(Registers::ODR_CONFIG, config.to_reg())
}
pub fn get_osr_config(&mut self) -> Result<OsrConfig, Error<CommE>> {
let reg = self.interface.read_reg(Registers::OSR_CONFIG)?;
Ok(OsrConfig::from_reg(reg))
}
pub fn get_status(&mut self) -> Result<Status, Error<CommE>> {
let status = self.interface.read_reg(Registers::STATUS)?;
Ok(Status::from_reg(status))
}
pub fn get_int_status(&mut self) -> Result<IntStatus, Error<CommE>> {
let status = self.interface.read_reg(Registers::INT_STATUS)?;
Ok(IntStatus::from_reg(status))
}
pub fn set_int_source(&mut self, source: IntSource) -> Result<(), Error<CommE>> {
self.interface.write_reg(Registers::INT_SOURCE, source.to_reg())
}
pub fn get_int_source(&mut self) -> Result<IntSource, Error<CommE>> {
let status = self.interface.read_reg(Registers::INT_SOURCE)?;
Ok(IntSource::from_reg(status))
}
pub fn get_int_config(&mut self) -> Result<IntConfig, Error<CommE>> {
let status = self.interface.read_reg(Registers::INT_CONFIG)?;
Ok(IntConfig::from_reg(status))
}
pub fn get_fifo_config(&mut self) -> Result<u8, Error<CommE>> {
self.interface.read_reg(Registers::FIFO_CONFIG)
}
pub fn get_fifo_sel_config(&mut self) -> Result<u8, Error<CommE>> {
self.interface.read_reg(Registers::FIFO_SEL)
}
pub fn set_int_config(&mut self, config: IntConfig) -> Result<(), Error<CommE>> {
self.interface.write_reg(Registers::INT_CONFIG, config.to_reg())
}
pub fn get_dsp_config(&mut self) -> Result<u8, Error<CommE>> {
self.interface.read_reg(Registers::DSP_CONFIG)
}
pub fn get_dsp_iir(&mut self) -> Result<u8, Error<CommE>> {
self.interface.read_reg(Registers::DSP_IIR)
}
pub fn read_temperature(&mut self) -> Result<f32, Error<CommE>> {
let mut buffer = [Registers::TEMP_DATA_XLSB, 0, 0, 0];
self.interface.read(&mut buffer)?;
let raw_temp = ((buffer[3] as u32) << 16) | ((buffer[2] as u32) << 8) | (buffer[1] as u32);
Ok((raw_temp as f32) / 65536.0)
}
pub fn read_pressure(&mut self) -> Result<f32, Error<CommE>> {
let xlsb = self.interface.read_reg(Registers::PRESS_DATA_XLSB)?;
let lsb = self.interface.read_reg(Registers::PRESS_DATA_LSB)?;
let msb = self.interface.read_reg(Registers::PRESS_DATA_MSB)?;
let raw_press = u32::from_be_bytes([0, msb, lsb, xlsb]);
#[cfg(feature = "defmt")]
defmt::debug!("Pressure: {}, {}, {}", msb, lsb, xlsb);
Ok((raw_press as f32) / 64.0)
}
}