diff --git a/readme.md b/readme.md index bcb8080..5c3c724 100644 --- a/readme.md +++ b/readme.md @@ -1,11 +1,10 @@ # `adis1647x` -no_std driver for the Analog Devices [adis1647](https://www.mouser.com/new/analog-devices/adi-adis1647-imus/) family of IMUs. Currently only the adis16475 is implemented. - +no_std driver for the Analog Devices [adis1647](https://www.mouser.com/new/analog-devices/adi-adis1647-imus/) family of IMUs. Currently only the adis16475 is supported ### Usage -You need an embedded_hal_async spi driver +You need an embedded_hal_async spi driver and delay implementation ```rust @@ -14,8 +13,9 @@ use adis1647x::delta::*; async fn main() -> Result<(), SomeSpiError> { let bus = some_spi(); + let delay = some_delay(); - let imu = ADIS1647X::new(bus).await?; + let imu = ADIS1647X::new(bus, delay).await?; let mut angle: DeltaAngle = Default::default(); @@ -28,4 +28,5 @@ async fn main() -> Result<(), SomeSpiError> { println!("yaw: {} degrees", angle.angles().y); } +} ``` diff --git a/src/lib.rs b/src/lib.rs index c3bd3cb..dcaa958 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,6 +1,6 @@ #![no_std] use delta::{DeltaAngle, DeltaVelocity}; -use embedded_hal_async::spi::SpiDevice; +use embedded_hal_async::{delay::DelayNs, spi::SpiDevice}; use nalgebra::Vector3; use registers::*; @@ -45,38 +45,44 @@ impl Model { } } -pub struct ADIS1647X where T: SpiDevice { +/// microseconds between requests +const STALL_TIME: u32 = 16; + +pub struct ADIS1647X where T: SpiDevice, D: DelayNs { bus: T, - model: Model + model: Model, + delay: D, } -impl ADIS1647X { - pub async fn new(bus: T) -> Result { +impl ADIS1647X { + pub async fn new(bus: T, delay: D) -> Result { //let bus = BlockingAsync::new(bus); - let mut query_imu = Self { bus, model: Model::ADIS16475_1 }; + let mut query_imu = Self { bus, model: Model::ADIS16475_1, delay }; let range = query_imu.read_u16(RANG_MDL).await?; let model = Model::detect(range); - Ok(Self::with_model(query_imu.take_bus(), model)) - } - - fn take_bus(self) -> T { - self.bus + Ok(Self::with_model(query_imu.bus, model, query_imu.delay)) } /// use a known model instead of detecting it - pub fn with_model(bus: T, model: Model) -> Self { + pub fn with_model(bus: T, model: Model, delay: D) -> Self { //let bus = BlockingAsync::new(bus); - Self { bus, model } + Self { bus, model, delay } + } + + async fn stall(&mut self) { + self.delay.delay_us(STALL_TIME).await; } pub async fn read_u16(&mut self, addr: u8) -> Result { let request = [addr & 0x7F, 0]; self.bus.write(&request).await?; + self.stall().await; let mut dat = [0;2]; self.bus.read(&mut dat).await?; + self.stall().await; Ok(u16::from_be_bytes(dat)) } @@ -84,6 +90,7 @@ impl ADIS1647X { pub async fn write_u8(&mut self, addr: u8, data: u8) -> Result<(), T::Error> { let request = [addr | 0x80, data]; self.bus.write(&request).await?; + self.stall().await; Ok(()) } @@ -108,6 +115,7 @@ impl ADIS1647X { // first address self.bus.write(&read(addr[0])).await?; + self.stall().await; let mut responses = [0; N]; @@ -119,6 +127,7 @@ impl ADIS1647X { for i in 1..(addr.len()*2) { let addr = addr[i/2] + (i as u8 % 2) * 2; self.bus.transfer(&mut buf, &read(addr)).await?; + self.stall().await; partial[partial_idx] = i16::from_be_bytes(buf); partial_idx += 1; @@ -132,6 +141,7 @@ impl ADIS1647X { // last address self.bus.read(&mut buf).await.unwrap(); + self.stall().await; responses[addr.len() - 1] = partial[0] as i32 + (i16::from_be_bytes(buf) as i32) << 16; Ok(responses)