#![no_std]
#![warn(missing_docs)]
use byteorder::{ByteOrder, LittleEndian};
use embedded_hal_async::{delay::DelayNs, i2c::I2c};
use crate::{
error::{
Error::{InvalidId, NotReady, ReadError, WriteError},
Result,
},
osr::Oversampling,
register::{CHIP_ID, CMD, INT_STATUS, ODR_CONFIG, PRESS_DATA_XLSB, STATUS, TEMP_DATA_XLSB},
};
mod continuous;
pub mod error;
mod forced;
pub mod iir;
pub mod int;
pub mod normal;
pub mod oor;
pub mod osr;
mod register;
pub struct Bmp5xx<I2C, D> {
i2c: I2C,
delay: D,
addr: u8,
osr_t: Oversampling,
osr_p: Oversampling,
}
impl<I2C, D> Bmp5xx<I2C, D>
where
I2C: I2c,
D: DelayNs,
{
pub fn new(i2c: I2C, delay: D, addr: u8) -> Self {
Self {
i2c,
delay,
addr,
osr_t: Oversampling::X1,
osr_p: Oversampling::X1,
}
}
pub async fn reset(&mut self) -> Result<()> {
self.i2c
.write(self.addr, &[CMD, 0xB6])
.await
.map_err(|_| WriteError)?;
self.delay.delay_ms(2).await;
Ok(())
}
pub async fn init(&mut self) -> Result<()> {
let mut id_buf = [0u8; 1];
self.i2c
.write_read(self.addr, &[CHIP_ID], &mut id_buf)
.await
.map_err(|_| ReadError)?;
match id_buf[0] {
0x50 | 0x51 => (),
_ => return Err(InvalidId),
}
self.reset().await?;
let mut status_buf = [0u8; 1];
self.i2c
.write_read(self.addr, &[STATUS], &mut status_buf)
.await
.map_err(|_| ReadError)?;
if status_buf[0] & 0x02 == 0 || status_buf[0] & 0x04 != 0 {
return Err(NotReady);
}
let mut int_status_buf = [0u8; 1];
self.i2c
.write_read(self.addr, &[INT_STATUS], &mut int_status_buf)
.await
.map_err(|_| ReadError)?;
if int_status_buf[0] & 0x10 == 0 {
return Err(NotReady);
}
Ok(())
}
}
impl<I2C, D> Bmp5xx<I2C, D>
where
I2C: I2c,
D: DelayNs,
{
pub async fn read_temp(&mut self) -> Result<f32> {
let mut temp_buf = [0u8; 3];
self.i2c
.write_read(self.addr, &[TEMP_DATA_XLSB], &mut temp_buf)
.await
.map_err(|_| ReadError)?;
Ok(LittleEndian::read_i24(&temp_buf) as f32 / 65536.0)
}
pub async fn read_pres(&mut self) -> Result<f32> {
let mut pres_buf = [0u8; 3];
self.i2c
.write_read(self.addr, &[PRESS_DATA_XLSB], &mut pres_buf)
.await
.map_err(|_| ReadError)?;
Ok(LittleEndian::read_i24(&pres_buf) as f32 / 64.0 / 100.0)
}
pub async fn stop(&mut self) -> Result<()> {
self.i2c
.write(self.addr, &[ODR_CONFIG, 0x00])
.await
.map_err(|_| WriteError)
}
}