1
Fork 0

delay between requests as per datasheet

This commit is contained in:
Andy Killorin 2025-03-14 23:24:23 -04:00
parent d30012746c
commit 24023f6e29
Signed by: ank
GPG key ID: 23F9463ECB67FE8C
2 changed files with 28 additions and 17 deletions

View file

@ -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);
}
}
```

View file

@ -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<T> where T: SpiDevice {
/// microseconds between requests
const STALL_TIME: u32 = 16;
pub struct ADIS1647X<T, D> where T: SpiDevice, D: DelayNs {
bus: T,
model: Model
model: Model,
delay: D,
}
impl<T: SpiDevice> ADIS1647X<T> {
pub async fn new(bus: T) -> Result<Self, T::Error> {
impl<T: SpiDevice, D: DelayNs> ADIS1647X<T, D> {
pub async fn new(bus: T, delay: D) -> Result<Self, T::Error> {
//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<u16, T::Error> {
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<T: SpiDevice> ADIS1647X<T> {
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<T: SpiDevice> ADIS1647X<T> {
// first address
self.bus.write(&read(addr[0])).await?;
self.stall().await;
let mut responses = [0; N];
@ -119,6 +127,7 @@ impl<T: SpiDevice> ADIS1647X<T> {
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<T: SpiDevice> ADIS1647X<T> {
// 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)