Skip to content

Commit

Permalink
Add explicit types for WHO_AM_I values. (#15)
Browse files Browse the repository at this point in the history
* Add explicit types for `WHO_AM_I` values.

* Add changelog entry.

* Rename method device ID is_correct

* Update CHANGELOG.md

Co-authored-by: Diego Barrios Romero <eldruin@gmail.com>
  • Loading branch information
reitermarkus and eldruin committed Aug 10, 2022
1 parent 5f40ea9 commit 01883f9
Show file tree
Hide file tree
Showing 5 changed files with 104 additions and 46 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
- [breaking-change] Simplify API by using explicit types for each measurement.
- Minimum supported Rust version has been upgraded to 1.54.0.
- Pass delay into functions to handle turn-on times.
- Add explicit types for accelerometer and magnetometer IDs.

## [0.2.2] - 2021-09-21

Expand Down
30 changes: 10 additions & 20 deletions src/device_impl.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
use crate::{
interface::{I2cInterface, ReadData, SpiInterface, WriteData},
mode,
register_address::{WHO_AM_I_A_VAL, WHO_AM_I_M_VAL},
Acceleration, BitFlags as BF, Config, Error, Lsm303agr, PhantomData, Register, Status,
Temperature, TemperatureStatus,
mode, Acceleration, AccelerometerId, BitFlags as BF, Config, Error, Lsm303agr, MagnetometerId,
PhantomData, Register, Status, Temperature, TemperatureStatus,
};

impl<I2C> Lsm303agr<I2cInterface<I2C>, mode::MagOneShot> {
Expand Down Expand Up @@ -131,24 +129,16 @@ where
.map(Status::new)
}

/// Get accelerometer device ID
pub fn accelerometer_id(&mut self) -> Result<u8, Error<CommE, PinE>> {
self.iface.read_accel_register(Register::WHO_AM_I_A)
/// Get the accelerometer device ID.
pub fn accelerometer_id(&mut self) -> Result<AccelerometerId, Error<CommE, PinE>> {
let id = self.iface.read_accel_register(Register::WHO_AM_I_A)?;
Ok(AccelerometerId { raw: id })
}

/// Read and verify the accelerometer device ID
pub fn accelerometer_is_detected(&mut self) -> Result<bool, Error<CommE, PinE>> {
Ok(self.accelerometer_id()? == WHO_AM_I_A_VAL)
}

/// Get magnetometer device ID
pub fn magnetometer_id(&mut self) -> Result<u8, Error<CommE, PinE>> {
self.iface.read_mag_register(Register::WHO_AM_I_M)
}

/// Read and verify the magnetometer device ID
pub fn magnetometer_is_detected(&mut self) -> Result<bool, Error<CommE, PinE>> {
Ok(self.magnetometer_id()? == WHO_AM_I_M_VAL)
/// Get the magnetometer device ID.
pub fn magnetometer_id(&mut self) -> Result<MagnetometerId, Error<CommE, PinE>> {
let id = self.iface.read_mag_register(Register::WHO_AM_I_M)?;
Ok(MagnetometerId { raw: id })
}

/// Get measured temperature.
Expand Down
5 changes: 3 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,9 @@ mod mag_mode_change;
mod magnetometer;
mod types;
pub use crate::types::{
mode, AccelMode, AccelOutputDataRate, AccelScale, Acceleration, Error, MagOutputDataRate,
MagneticField, ModeChangeError, Status, Temperature, TemperatureStatus,
mode, AccelMode, AccelOutputDataRate, AccelScale, Acceleration, AccelerometerId, Error,
MagOutputDataRate, MagneticField, MagnetometerId, ModeChangeError, Status, Temperature,
TemperatureStatus,
};
mod register_address;
use crate::register_address::{BitFlags, Register};
Expand Down
38 changes: 38 additions & 0 deletions src/types.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use bitflags::bitflags;

use crate::register_address::{WHO_AM_I_A_VAL, WHO_AM_I_M_VAL};

/// All possible errors in this crate
#[derive(Debug)]
pub enum Error<CommE, PinE> {
Expand Down Expand Up @@ -30,6 +32,24 @@ pub mod mode {
pub enum MagContinuous {}
}

/// An Accelerometer ID.
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct AccelerometerId {
pub(crate) raw: u8,
}

impl AccelerometerId {
/// Raw accelerometer ID.
pub const fn raw(&self) -> u8 {
self.raw
}

/// Check if the ID corresponds to the expected value.
pub const fn is_correct(&self) -> bool {
self.raw == WHO_AM_I_A_VAL
}
}

/// An acceleration measurement.
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct Acceleration {
Expand Down Expand Up @@ -127,6 +147,24 @@ impl Acceleration {
}
}

/// A Magnetometer ID.
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct MagnetometerId {
pub(crate) raw: u8,
}

impl MagnetometerId {
/// Raw magnetometer ID.
pub const fn raw(&self) -> u8 {
self.raw
}

/// Check if the ID corresponds to the expected value.
pub const fn is_correct(&self) -> bool {
self.raw == WHO_AM_I_M_VAL
}
}

/// A magnetic field measurement.
#[derive(Debug, Default, Clone, Copy, PartialEq)]
pub struct MagneticField {
Expand Down
76 changes: 52 additions & 24 deletions tests/integration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,86 +20,107 @@ fn can_create_and_destroy_spi() {
}

#[test]
fn i2c_can_get_accel_id() {
let accel_id = 0xAB;
fn i2c_acc_id_is_not_correct() {
let acc_id = 0xAB;
let mut sensor = new_i2c(&[I2cTrans::write_read(
ACCEL_ADDR,
vec![Register::WHO_AM_I_A],
vec![accel_id],
vec![acc_id],
)]);
let id = sensor.accelerometer_id().unwrap();
assert_eq!(accel_id, id);

assert_eq!(id.raw(), acc_id);
assert!(!id.is_correct());

destroy_i2c(sensor);
}

#[test]
fn i2c_accelerometer_is_detected() {
let accel_id = 0x33;
fn i2c_acc_id_is_correct() {
let acc_id = 0x33;
let mut sensor = new_i2c(&[I2cTrans::write_read(
ACCEL_ADDR,
vec![Register::WHO_AM_I_A],
vec![accel_id],
vec![acc_id],
)]);
assert!(sensor.accelerometer_is_detected().unwrap());
let id = sensor.accelerometer_id().unwrap();

assert_eq!(id.raw(), acc_id);
assert!(id.is_correct());

destroy_i2c(sensor);
}

#[test]
fn i2c_can_get_mag_id() {
fn i2c_mag_id_is_not_correct() {
let mag_id = 0xAB;
let mut sensor = new_i2c(&[I2cTrans::write_read(
MAG_ADDR,
vec![Register::WHO_AM_I_M],
vec![mag_id],
)]);
let id = sensor.magnetometer_id().unwrap();
assert_eq!(mag_id, id);

assert_eq!(id.raw(), mag_id);
assert!(!id.is_correct());

destroy_i2c(sensor);
}

#[test]
fn i2c_magnetometer_is_detected() {
fn i2c_mag_id_is_correct() {
let mag_id = 0x40;
let mut sensor = new_i2c(&[I2cTrans::write_read(
MAG_ADDR,
vec![Register::WHO_AM_I_M],
vec![mag_id],
)]);
assert!(sensor.magnetometer_is_detected().unwrap());
let id = sensor.magnetometer_id().unwrap();

assert_eq!(id.raw(), mag_id);
assert!(id.is_correct());

destroy_i2c(sensor);
}

#[test]
fn spi_can_get_accel_id() {
let accel_id = 0xAB;
fn spi_acc_id_is_not_correct() {
let acc_id = 0xAB;
let mut sensor = new_spi_accel(
&[SpiTrans::transfer(
vec![BF::SPI_RW | Register::WHO_AM_I_A, 0],
vec![0, accel_id],
vec![0, acc_id],
)],
default_cs(),
);
let id = sensor.accelerometer_id().unwrap();
assert_eq!(accel_id, id);

assert_eq!(id.raw(), acc_id);
assert!(!id.is_correct());

destroy_spi(sensor);
}

#[test]
fn spi_accelerometer_is_detected() {
let accel_id = 0x33;
fn spi_acc_id_is_correct() {
let acc_id = 0x33;
let mut sensor = new_spi_accel(
&[SpiTrans::transfer(
vec![BF::SPI_RW | Register::WHO_AM_I_A, 0],
vec![0, accel_id],
vec![0, acc_id],
)],
default_cs(),
);
assert!(sensor.accelerometer_is_detected().unwrap());
let id = sensor.accelerometer_id().unwrap();

assert_eq!(id.raw(), acc_id);
assert!(id.is_correct());

destroy_spi(sensor);
}

#[test]
fn spi_can_get_mag_id() {
fn spi_mag_id_is_not_correct() {
let mag_id = 0xAB;
let mut sensor = new_spi_mag(
&[SpiTrans::transfer(
Expand All @@ -109,12 +130,15 @@ fn spi_can_get_mag_id() {
default_cs(),
);
let id = sensor.magnetometer_id().unwrap();
assert_eq!(mag_id, id);

assert_eq!(id.raw(), mag_id);
assert!(!id.is_correct());

destroy_spi(sensor);
}

#[test]
fn spi_magnetometer_is_detected() {
fn spi_mag_id_is_correct() {
let mag_id = 0x40;
let mut sensor = new_spi_mag(
&[SpiTrans::transfer(
Expand All @@ -123,7 +147,11 @@ fn spi_magnetometer_is_detected() {
)],
default_cs(),
);
assert!(sensor.magnetometer_is_detected().unwrap());
let id = sensor.magnetometer_id().unwrap();

assert_eq!(id.raw(), mag_id);
assert!(id.is_correct());

destroy_spi(sensor);
}

Expand Down

0 comments on commit 01883f9

Please sign in to comment.