Compare commits
2 commits
d30012746c
...
82105eecb9
Author | SHA1 | Date | |
---|---|---|---|
82105eecb9 | |||
24023f6e29 |
4 changed files with 155 additions and 23 deletions
97
Cargo.lock
generated
97
Cargo.lock
generated
|
@ -9,6 +9,7 @@ dependencies = [
|
||||||
"embassy-embedded-hal",
|
"embassy-embedded-hal",
|
||||||
"embedded-hal 1.0.0",
|
"embedded-hal 1.0.0",
|
||||||
"embedded-hal-async",
|
"embedded-hal-async",
|
||||||
|
"maybe-async-cfg",
|
||||||
"nalgebra",
|
"nalgebra",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -27,6 +28,12 @@ version = "1.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
|
checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bitflags"
|
||||||
|
version = "2.9.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bytemuck"
|
name = "bytemuck"
|
||||||
version = "1.22.0"
|
version = "1.22.0"
|
||||||
|
@ -227,6 +234,30 @@ version = "0.4.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b4ce301924b7887e9d637144fdade93f9dfff9b60981d4ac161db09720d39aa5"
|
checksum = "b4ce301924b7887e9d637144fdade93f9dfff9b60981d4ac161db09720d39aa5"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "manyhow"
|
||||||
|
version = "0.11.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b33efb3ca6d3b07393750d4030418d594ab1139cee518f0dc88db70fec873587"
|
||||||
|
dependencies = [
|
||||||
|
"manyhow-macros",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 1.0.109",
|
||||||
|
"syn 2.0.100",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "manyhow-macros"
|
||||||
|
version = "0.11.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "46fce34d199b78b6e6073abf984c9cf5fd3e9330145a93ee0738a7443e371495"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro-utils",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "matrixmultiply"
|
name = "matrixmultiply"
|
||||||
version = "0.3.9"
|
version = "0.3.9"
|
||||||
|
@ -237,6 +268,25 @@ dependencies = [
|
||||||
"rawpointer",
|
"rawpointer",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "maybe-async-cfg"
|
||||||
|
version = "0.2.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8dbfaa67a76e2623580df07d6bb5e7956c0a4bae4b418314083a9c619bd66627"
|
||||||
|
dependencies = [
|
||||||
|
"manyhow",
|
||||||
|
"proc-macro2",
|
||||||
|
"pulldown-cmark",
|
||||||
|
"quote",
|
||||||
|
"syn 1.0.109",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "memchr"
|
||||||
|
version = "2.7.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nalgebra"
|
name = "nalgebra"
|
||||||
version = "0.31.4"
|
version = "0.31.4"
|
||||||
|
@ -261,7 +311,7 @@ checksum = "01fcc0b8149b4632adc89ac3b7b31a12fb6099a0317a4eb2ebff574ef7de7218"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn",
|
"syn 1.0.109",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -334,6 +384,17 @@ version = "0.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
|
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-macro-utils"
|
||||||
|
version = "0.10.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "eeaf08a13de400bc215877b5bdc088f241b12eb42f0a548d3390dc1c56bb7071"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"smallvec",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "proc-macro2"
|
||||||
version = "1.0.94"
|
version = "1.0.94"
|
||||||
|
@ -343,6 +404,17 @@ dependencies = [
|
||||||
"unicode-ident",
|
"unicode-ident",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pulldown-cmark"
|
||||||
|
version = "0.11.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "679341d22c78c6c649893cbd6c3278dcbe9fc4faa62fea3a9296ae2b50c14625"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags",
|
||||||
|
"memchr",
|
||||||
|
"unicase",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "quote"
|
name = "quote"
|
||||||
version = "1.0.39"
|
version = "1.0.39"
|
||||||
|
@ -380,6 +452,12 @@ dependencies = [
|
||||||
"wide",
|
"wide",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "smallvec"
|
||||||
|
version = "1.14.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7fcf8323ef1faaee30a44a340193b1ac6814fd9b7b4e88e9d4519a3e4abe1cfd"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "stable_deref_trait"
|
name = "stable_deref_trait"
|
||||||
version = "1.2.0"
|
version = "1.2.0"
|
||||||
|
@ -397,12 +475,29 @@ dependencies = [
|
||||||
"unicode-ident",
|
"unicode-ident",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "syn"
|
||||||
|
version = "2.0.100"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "typenum"
|
name = "typenum"
|
||||||
version = "1.18.0"
|
version = "1.18.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f"
|
checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicase"
|
||||||
|
version = "2.8.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "75b844d17643ee918803943289730bec8aac480150456169e647ed0b576ba539"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-ident"
|
name = "unicode-ident"
|
||||||
version = "1.0.18"
|
version = "1.0.18"
|
||||||
|
|
|
@ -8,3 +8,9 @@ embedded-hal = "1.0.0"
|
||||||
embedded-hal-async = "1.0.0"
|
embedded-hal-async = "1.0.0"
|
||||||
embassy-embedded-hal = {version = "0.3.0", git="https://github.com/embassy-rs/embassy", rev = "c39076724f052fed6781b056bb79c9fa576b87a3"}
|
embassy-embedded-hal = {version = "0.3.0", git="https://github.com/embassy-rs/embassy", rev = "c39076724f052fed6781b056bb79c9fa576b87a3"}
|
||||||
nalgebra = "0.31.4"
|
nalgebra = "0.31.4"
|
||||||
|
maybe-async-cfg = "0.2"
|
||||||
|
|
||||||
|
[features]
|
||||||
|
default = ["sync"]
|
||||||
|
sync = []
|
||||||
|
async = []
|
||||||
|
|
19
readme.md
19
readme.md
|
@ -1,21 +1,29 @@
|
||||||
# `adis1647x`
|
# `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
|
### Usage
|
||||||
|
|
||||||
You need an embedded_hal_async spi driver
|
You need an embedded_hal or embedded_hal_async spi driver and delay implementation
|
||||||
|
|
||||||
|
```toml
|
||||||
|
# async
|
||||||
|
adis1647x = { git = "https://git.ank.dev/ank/adis1647x", default-features = false, features = ["async"]
|
||||||
|
|
||||||
|
# sync
|
||||||
|
adis1647x = { git = "https://git.ank.dev/ank/adis1647x" }
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
|
|
||||||
use adis1647x::*;
|
use adis1647x::*;
|
||||||
use adis1647x::delta::*;
|
use adis1647x::delta::*;
|
||||||
|
|
||||||
async fn main() -> Result<(), SomeSpiError> {
|
async fn main() -> Result<(), SomeSpiError> {
|
||||||
let bus = some_spi();
|
let bus = some_spi();
|
||||||
|
let delay = some_delay();
|
||||||
|
|
||||||
let imu = ADIS1647X::new(bus).await?;
|
let imu = ADIS1647Async::new(bus, delay).await?;
|
||||||
|
|
||||||
let mut angle: DeltaAngle = Default::default();
|
let mut angle: DeltaAngle = Default::default();
|
||||||
|
|
||||||
|
@ -28,4 +36,5 @@ async fn main() -> Result<(), SomeSpiError> {
|
||||||
|
|
||||||
println!("yaw: {} degrees", angle.angles().y);
|
println!("yaw: {} degrees", angle.angles().y);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
56
src/lib.rs
56
src/lib.rs
|
@ -1,6 +1,12 @@
|
||||||
#![no_std]
|
#![no_std]
|
||||||
use delta::{DeltaAngle, DeltaVelocity};
|
use delta::{DeltaAngle, DeltaVelocity};
|
||||||
use embedded_hal_async::spi::SpiDevice;
|
|
||||||
|
#[cfg(feature = "async")]
|
||||||
|
use embedded_hal_async::{delay::DelayNs as DelayNsAsync, spi::SpiDevice as SpiDeviceAsync};
|
||||||
|
|
||||||
|
#[cfg(feature = "sync")]
|
||||||
|
use embedded_hal::{delay::DelayNs as DelayNsSync, spi::SpiDevice as SpiDeviceSync};
|
||||||
|
|
||||||
use nalgebra::Vector3;
|
use nalgebra::Vector3;
|
||||||
use registers::*;
|
use registers::*;
|
||||||
|
|
||||||
|
@ -45,38 +51,51 @@ impl Model {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ADIS1647X<T> where T: SpiDevice {
|
/// microseconds between requests
|
||||||
|
const STALL_TIME: u32 = 16;
|
||||||
|
|
||||||
|
#[maybe_async_cfg::maybe(
|
||||||
|
idents(DelayNs, SpiDevice),
|
||||||
|
sync(feature="sync"),
|
||||||
|
async(feature="async")
|
||||||
|
)]
|
||||||
|
pub struct ADIS1647<T, D> where T: SpiDevice, D: DelayNs {
|
||||||
bus: T,
|
bus: T,
|
||||||
model: Model
|
model: Model,
|
||||||
|
delay: D,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: SpiDevice> ADIS1647X<T> {
|
#[maybe_async_cfg::maybe(
|
||||||
pub async fn new(bus: T) -> Result<Self, T::Error> {
|
idents(DelayNs, SpiDevice),
|
||||||
//let bus = BlockingAsync::new(bus);
|
sync(feature="sync"),
|
||||||
|
async(feature="async")
|
||||||
let mut query_imu = Self { bus, model: Model::ADIS16475_1 };
|
)]
|
||||||
|
impl<T: SpiDevice, D: DelayNs> ADIS1647<T, D> {
|
||||||
|
pub async fn new(bus: T, delay: D) -> Result<Self, T::Error> {
|
||||||
|
let mut query_imu = Self { bus, model: Model::ADIS16475_1, delay };
|
||||||
let range = query_imu.read_u16(RANG_MDL).await?;
|
let range = query_imu.read_u16(RANG_MDL).await?;
|
||||||
|
|
||||||
let model = Model::detect(range);
|
let model = Model::detect(range);
|
||||||
|
|
||||||
Ok(Self::with_model(query_imu.take_bus(), model))
|
Ok(Self::with_model(query_imu.bus, model, query_imu.delay))
|
||||||
}
|
|
||||||
|
|
||||||
fn take_bus(self) -> T {
|
|
||||||
self.bus
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// use a known model instead of detecting it
|
/// 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, delay }
|
||||||
Self { bus, model }
|
}
|
||||||
|
|
||||||
|
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> {
|
pub async fn read_u16(&mut self, addr: u8) -> Result<u16, T::Error> {
|
||||||
let request = [addr & 0x7F, 0];
|
let request = [addr & 0x7F, 0];
|
||||||
self.bus.write(&request).await?;
|
self.bus.write(&request).await?;
|
||||||
|
self.stall().await;
|
||||||
let mut dat = [0;2];
|
let mut dat = [0;2];
|
||||||
self.bus.read(&mut dat).await?;
|
self.bus.read(&mut dat).await?;
|
||||||
|
self.stall().await;
|
||||||
|
|
||||||
Ok(u16::from_be_bytes(dat))
|
Ok(u16::from_be_bytes(dat))
|
||||||
}
|
}
|
||||||
|
@ -84,6 +103,7 @@ impl<T: SpiDevice> ADIS1647X<T> {
|
||||||
pub async fn write_u8(&mut self, addr: u8, data: u8) -> Result<(), T::Error> {
|
pub async fn write_u8(&mut self, addr: u8, data: u8) -> Result<(), T::Error> {
|
||||||
let request = [addr | 0x80, data];
|
let request = [addr | 0x80, data];
|
||||||
self.bus.write(&request).await?;
|
self.bus.write(&request).await?;
|
||||||
|
self.stall().await;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -96,7 +116,6 @@ impl<T: SpiDevice> ADIS1647X<T> {
|
||||||
|
|
||||||
pub async fn write_u16(&mut self, addr: u8, data: u16) -> Result<(), T::Error> {
|
pub async fn write_u16(&mut self, addr: u8, data: u16) -> Result<(), T::Error> {
|
||||||
let data = u16::to_le_bytes(data);
|
let data = u16::to_le_bytes(data);
|
||||||
// TODO: do some soul searching
|
|
||||||
self.write_u8(addr, data[0]).await?; // lower byte
|
self.write_u8(addr, data[0]).await?; // lower byte
|
||||||
self.write_u8(addr+1, data[1]).await?; // higher byte
|
self.write_u8(addr+1, data[1]).await?; // higher byte
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -108,6 +127,7 @@ impl<T: SpiDevice> ADIS1647X<T> {
|
||||||
|
|
||||||
// first address
|
// first address
|
||||||
self.bus.write(&read(addr[0])).await?;
|
self.bus.write(&read(addr[0])).await?;
|
||||||
|
self.stall().await;
|
||||||
|
|
||||||
let mut responses = [0; N];
|
let mut responses = [0; N];
|
||||||
|
|
||||||
|
@ -119,6 +139,7 @@ impl<T: SpiDevice> ADIS1647X<T> {
|
||||||
for i in 1..(addr.len()*2) {
|
for i in 1..(addr.len()*2) {
|
||||||
let addr = addr[i/2] + (i as u8 % 2) * 2;
|
let addr = addr[i/2] + (i as u8 % 2) * 2;
|
||||||
self.bus.transfer(&mut buf, &read(addr)).await?;
|
self.bus.transfer(&mut buf, &read(addr)).await?;
|
||||||
|
self.stall().await;
|
||||||
|
|
||||||
partial[partial_idx] = i16::from_be_bytes(buf);
|
partial[partial_idx] = i16::from_be_bytes(buf);
|
||||||
partial_idx += 1;
|
partial_idx += 1;
|
||||||
|
@ -132,6 +153,7 @@ impl<T: SpiDevice> ADIS1647X<T> {
|
||||||
|
|
||||||
// last address
|
// last address
|
||||||
self.bus.read(&mut buf).await.unwrap();
|
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;
|
responses[addr.len() - 1] = partial[0] as i32 + (i16::from_be_bytes(buf) as i32) << 16;
|
||||||
|
|
||||||
Ok(responses)
|
Ok(responses)
|
||||||
|
|
Loading…
Reference in a new issue