#![no_std]
pub mod accel;
pub mod gyro;
pub mod mag;
pub mod register;
use accel::AccelSettings;
use gyro::GyroSettings;
use mag::MagSettings;
pub mod interface;
use interface::{Interface, Sensor};
const WHO_AM_I_AG: u8 = 0x68;
const WHO_AM_I_M: u8 = 0x3D;
const TEMP_SCALE: f32 = 16.0;
const TEMP_BIAS: f32 = 25.0;
pub struct LSM9DS1Init {
pub accel: AccelSettings,
pub gyro: GyroSettings,
pub mag: MagSettings,
}
impl Default for LSM9DS1Init {
fn default() -> Self {
Self {
accel: AccelSettings::default(),
gyro: GyroSettings::default(),
mag: MagSettings::default(),
}
}
}
impl LSM9DS1Init {
pub fn with_interface<T>(self, interface: T) -> LSM9DS1<T>
where
T: Interface,
{
LSM9DS1 {
interface,
accel: self.accel,
gyro: self.gyro,
mag: self.mag,
}
}
}
pub struct LSM9DS1<T>
where
T: Interface,
{
interface: T,
accel: AccelSettings,
gyro: GyroSettings,
mag: MagSettings,
}
impl<T> LSM9DS1<T>
where
T: Interface,
{
fn reachable(&mut self, sensor: Sensor) -> Result<bool, T::Error> {
use Sensor::*;
let mut bytes = [0u8; 1];
let (who_am_i, register) = match sensor {
Accelerometer | Gyro | Temperature => (WHO_AM_I_AG, register::AG::WHO_AM_I.addr()),
Magnetometer => (WHO_AM_I_M, register::Mag::WHO_AM_I.addr()),
};
self.interface.read(sensor, register, &mut bytes)?;
Ok(bytes[0] == who_am_i)
}
pub fn accel_is_reacheable(&mut self) -> Result<bool, T::Error> {
self.reachable(Sensor::Accelerometer)
}
pub fn mag_is_reacheable(&mut self) -> Result<bool, T::Error> {
self.reachable(Sensor::Magnetometer)
}
pub fn begin_accel(&mut self) -> Result<(), T::Error> {
self.interface.write(
Sensor::Accelerometer,
register::AG::CTRL_REG5_XL.addr(),
self.accel.ctrl_reg5_xl(),
)?;
self.interface.write(
Sensor::Accelerometer,
register::AG::CTRL_REG6_XL.addr(),
self.accel.ctrl_reg6_xl(),
)?;
self.interface.write(
Sensor::Accelerometer,
register::AG::CTRL_REG7_XL.addr(),
self.accel.ctrl_reg7_xl(),
)?;
Ok(())
}
pub fn begin_gyro(&mut self) -> Result<(), T::Error> {
self.interface.write(
Sensor::Gyro,
register::AG::CTRL_REG1_G.addr(),
self.gyro.ctrl_reg1_g(),
)?;
self.interface.write(
Sensor::Gyro,
register::AG::CTRL_REG2_G.addr(),
self.gyro.ctrl_reg2_g(),
)?;
self.interface.write(
Sensor::Gyro,
register::AG::CTRL_REG3_G.addr(),
self.gyro.ctrl_reg3_g(),
)?;
self.interface.write(
Sensor::Gyro,
register::AG::CTRL_REG4.addr(),
self.gyro.ctrl_reg4(),
)?;
Ok(())
}
pub fn begin_mag(&mut self) -> Result<(), T::Error> {
self.interface.write(
Sensor::Magnetometer,
register::Mag::CTRL_REG1_M.addr(),
self.mag.ctrl_reg1_m(),
)?;
self.interface.write(
Sensor::Magnetometer,
register::Mag::CTRL_REG2_M.addr(),
self.mag.ctrl_reg2_m(),
)?;
self.interface.write(
Sensor::Magnetometer,
register::Mag::CTRL_REG3_M.addr(),
self.mag.ctrl_reg3_m(),
)?;
self.interface.write(
Sensor::Magnetometer,
register::Mag::CTRL_REG4_M.addr(),
self.mag.ctrl_reg4_m(),
)?;
self.interface.write(
Sensor::Magnetometer,
register::Mag::CTRL_REG5_M.addr(),
self.mag.ctrl_reg5_m(),
)?;
Ok(())
}
fn data_available(&mut self, sensor: Sensor) -> Result<u8, T::Error> {
use Sensor::*;
let register = match sensor {
Accelerometer | Gyro | Temperature => register::AG::STATUS_REG_1.addr(),
Magnetometer => register::Mag::STATUS_REG_M.addr(),
};
let mut bytes = [0u8; 1];
self.interface.read(sensor, register, &mut bytes)?;
Ok(bytes[0])
}
pub fn accel_data_available(&mut self) -> Result<bool, T::Error> {
match self.data_available(Sensor::Accelerometer)? {
x if x & 0x01 > 0 => Ok(true),
_ => Ok(false),
}
}
pub fn gyro_data_available(&mut self) -> Result<bool, T::Error> {
match self.data_available(Sensor::Gyro)? {
x if x & 0x02 > 0 => Ok(true),
_ => Ok(false),
}
}
pub fn mag_data_available(&mut self) -> Result<bool, T::Error> {
match self.data_available(Sensor::Magnetometer)? {
x if x & 0x01 > 0 => Ok(true),
_ => Ok(false),
}
}
pub fn temp_data_available(&mut self) -> Result<bool, T::Error> {
match self.data_available(Sensor::Temperature)? {
x if x & 0x04 > 0 => Ok(true),
_ => Ok(false),
}
}
fn read_sensor_raw(&mut self, sensor: Sensor, addr: u8) -> Result<(i16, i16, i16), T::Error> {
let mut bytes = [0u8; 6];
self.interface.read(sensor, addr, &mut bytes)?;
let x: i16 = (bytes[1] as i16) << 8 | bytes[0] as i16;
let y: i16 = (bytes[3] as i16) << 8 | bytes[2] as i16;
let z: i16 = (bytes[5] as i16) << 8 | bytes[4] as i16;
Ok((x, y, z))
}
pub fn read_accel_raw(&mut self) -> Result<(i16, i16, i16), T::Error> {
self.read_sensor_raw(Sensor::Accelerometer, register::AG::OUT_X_L_XL.addr())
}
pub fn read_accel(&mut self) -> Result<(f32, f32, f32), T::Error> {
let (x, y, z) = self.read_accel_raw()?;
let sensitivity = self.accel.scale.sensitivity();
Ok((
x as f32 * sensitivity,
y as f32 * sensitivity,
z as f32 * sensitivity,
))
}
pub fn read_gyro_raw(&mut self) -> Result<(i16, i16, i16), T::Error> {
self.read_sensor_raw(Sensor::Gyro, register::AG::OUT_X_L_G.addr())
}
pub fn read_gyro(&mut self) -> Result<(f32, f32, f32), T::Error> {
let (x, y, z) = self.read_gyro_raw()?;
let sensitivity = self.gyro.scale.sensitivity();
Ok((
x as f32 * sensitivity,
y as f32 * sensitivity,
z as f32 * sensitivity,
))
}
pub fn read_mag_raw(&mut self) -> Result<(i16, i16, i16), T::Error> {
self.read_sensor_raw(Sensor::Magnetometer, register::Mag::OUT_X_L_M.addr())
}
pub fn read_mag(&mut self) -> Result<(f32, f32, f32), T::Error> {
let (x, y, z) = self.read_mag_raw()?;
let sensitivity = self.mag.scale.sensitivity();
Ok((
x as f32 * sensitivity,
y as f32 * sensitivity,
z as f32 * sensitivity,
))
}
pub fn read_temp(&mut self) -> Result<f32, T::Error> {
let mut bytes = [0u8; 2];
self.interface.read(
Sensor::Accelerometer,
register::AG::OUT_TEMP_L.addr(),
&mut bytes,
)?;
let result: i16 = (bytes[1] as i16) << 8 | bytes[0] as i16;
Ok((result as f32) / TEMP_SCALE + TEMP_BIAS)
}
}