use core::marker::PhantomData;
use embassy_time::Delay;
pub use oxstack_drivers::axes::{Axis, AxisMap};
use oxstack_drivers::bmi270::{self, ADDRESS_SDO_HIGH, Bmi270};
pub use oxstack_drivers::bmi270::{AccelRange, Config, DataRate, GyroRange, RawSample, Sample};
use crate::i2c::{SysI2cBus, SysI2cDevice, device};
pub type Chip = Bmi270<SysI2cDevice>;
pub type Error =
bmi270::Error<embassy_embedded_hal::shared_bus::I2cDeviceError<esp_hal::i2c::master::Error>>;
pub const BOARD_AXES: AxisMap = AxisMap {
x: Axis::PosX,
y: Axis::PosY,
z: Axis::PosZ,
};
pub struct ImuResources {
pub(crate) _private: (),
}
impl ImuResources {
pub async fn init(
&mut self,
bus: &'static SysI2cBus,
config: Config,
) -> Result<Imu<'_>, Error> {
let mut chip = Bmi270::new(device(bus), ADDRESS_SDO_HIGH);
chip.init(config, &mut Delay).await?;
Ok(Imu {
chip,
axes: BOARD_AXES,
_token: PhantomData,
})
}
}
pub struct Imu<'d> {
chip: Chip,
axes: AxisMap,
_token: PhantomData<&'d mut ()>,
}
impl Imu<'_> {
pub async fn read(&mut self) -> Result<Sample, Error> {
let s = self.read_chip().await?;
Ok(Sample {
accel: self.axes.apply(s.accel),
gyro: self.axes.apply(s.gyro),
})
}
pub async fn read_chip(&mut self) -> Result<Sample, Error> {
self.chip.read().await.map_err(Error::I2c)
}
pub async fn read_raw(&mut self) -> Result<RawSample, Error> {
self.chip.read_raw().await.map_err(Error::I2c)
}
pub async fn temperature(&mut self) -> Result<Option<f32>, Error> {
self.chip.temperature().await.map_err(Error::I2c)
}
pub async fn configure(&mut self, config: Config) -> Result<(), Error> {
self.chip.configure(config).await
}
pub fn axes(&self) -> AxisMap {
self.axes
}
pub fn set_axes(&mut self, axes: AxisMap) {
self.axes = axes;
}
pub fn chip(&mut self) -> &mut Chip {
&mut self.chip
}
}