Skip to content

Commit

Permalink
Add register types for temperature and temperature status.
Browse files Browse the repository at this point in the history
  • Loading branch information
reitermarkus committed Aug 10, 2022
1 parent 06ad776 commit 297708c
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 20 deletions.
10 changes: 5 additions & 5 deletions src/device_impl.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
use crate::{
interface::{I2cInterface, ReadData, SpiInterface, WriteData},
mode, Acceleration, AccelerometerId, BitFlags as BF, Config, Error, Lsm303agr, MagnetometerId,
mode,
register_address::{RegRead, StatusRegAuxA},
Acceleration, AccelerometerId, BitFlags as BF, Config, Error, Lsm303agr, MagnetometerId,
PhantomData, Register, Status, Temperature, TemperatureStatus,
};

Expand Down Expand Up @@ -143,17 +145,15 @@ where

/// Get measured temperature.
pub fn temperature(&mut self) -> Result<Temperature, Error<CommE, PinE>> {
let data = self
.iface
.read_accel_double_register(Register::OUT_TEMP_L_A)?;
let data = self.iface.read_accel_double_register(Temperature::ADDR)?;

Ok(Temperature { raw: data })
}

/// Temperature sensor status
pub fn temperature_status(&mut self) -> Result<TemperatureStatus, Error<CommE, PinE>> {
self.iface
.read_accel_register(Register::STATUS_REG_AUX_A)
.read_accel_register(StatusRegAuxA::ADDR)
.map(TemperatureStatus::new)
}
}
76 changes: 74 additions & 2 deletions src/register_address.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
pub struct Register;

impl Register {
pub const STATUS_REG_AUX_A: u8 = 0x07;
pub const OUT_TEMP_L_A: u8 = 0x0C;
pub const WHO_AM_I_A: u8 = 0x0F;
pub const TEMP_CFG_REG_A: u8 = 0x1F;
pub const CTRL_REG1_A: u8 = 0x20;
Expand All @@ -20,6 +19,7 @@ pub const WHO_AM_I_A_VAL: u8 = 0x33;
pub const WHO_AM_I_M_VAL: u8 = 0x40;

pub struct BitFlags;

impl BitFlags {
pub const SPI_RW: u8 = 1 << 7;
pub const SPI_MS: u8 = 1 << 6;
Expand All @@ -38,3 +38,75 @@ impl BitFlags {
pub const TEMP_EN1: u8 = 1 << 7;
pub const TEMP_EN: u8 = Self::TEMP_EN0 | Self::TEMP_EN1;
}

pub trait RegRead<D = u8> {
type Output;

const ADDR: u8;

fn from_data(data: D) -> Self::Output;
}

pub trait RegWrite<D = u8>: RegRead<D> {
fn data(&self) -> D;
}

macro_rules! register {
(@impl_reg_read $ty:ident, $addr:literal, $output:ident) => {
impl RegRead for $ty {
type Output = $output;

const ADDR: u8 = $addr;

fn from_data(data: u8) -> Self::Output {
Self::Output::from_bits_truncate(data)
}
}
};
(@impl_reg_write $ty:ident, $addr:literal, $output:ident) => {
register!(@impl_reg_read $ty, $addr, Self);

impl RegWrite for $ty {
fn data(&self) -> u8 {
self.bits()
}
}
};
(
#[doc = $name:expr]
$(#[$meta:meta])*
$vis:vis type $ty:ident: $addr:literal = $ty2:ident;
) => {
#[doc = concat!($name, " register (`", stringify!($addr), "`)")]
$(#[$meta])*
$vis enum $ty {}

register!(@impl_reg_read $ty, $addr, $ty2);
};
(
#[doc = $name:expr]
$(#[$meta:meta])*
$vis:vis struct $ty:ident: $addr:literal {
$(const $bit_name:ident = $bit_val:expr;)*
}
) => {
::bitflags::bitflags! {
#[doc = concat!($name, " register (`", stringify!($addr), "`)")]
$(#[$meta])*
$vis struct $ty: u8 {
$(const $bit_name = $bit_val;)*
}
}

register!(@impl_reg_write $ty, $addr, Self);
};
}

register! {
/// STATUS_REG_AUX_A
#[derive(Default)]
pub struct StatusRegAuxA: 0x07 {
const TOR = 0b01000000;
const TDA = 0b00000100;
}
}
30 changes: 17 additions & 13 deletions src/types.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use bitflags::bitflags;

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

/// All possible errors in this crate
#[derive(Debug)]
Expand Down Expand Up @@ -495,37 +495,29 @@ impl Status {
}
}

bitflags! {
#[derive(Default)]
struct TemperatureStatusFlags: u8 {
const TDA = 1 << 2;
const TOR = 1 << 6;
}
}

/// Temperature sensor status
#[derive(Debug, Default, Clone, Copy, PartialEq)]
pub struct TemperatureStatus {
flags: TemperatureStatusFlags,
flags: StatusRegAuxA,
}

impl TemperatureStatus {
pub(crate) const fn new(flags: u8) -> Self {
Self {
flags: TemperatureStatusFlags::from_bits_truncate(flags),
flags: StatusRegAuxA::from_bits_truncate(flags),
}
}

/// Temperature data overrun.
#[inline]
pub const fn overrun(&self) -> bool {
self.flags.contains(TemperatureStatusFlags::TOR)
self.flags.contains(StatusRegAuxA::TOR)
}

/// Temperature new data available.
#[inline]
pub const fn new_data(&self) -> bool {
self.flags.contains(TemperatureStatusFlags::TDA)
self.flags.contains(StatusRegAuxA::TDA)
}
}

Expand All @@ -535,6 +527,18 @@ pub struct Temperature {
pub(crate) raw: u16,
}

impl RegRead<u16> for Temperature {
type Output = Self;

/// OUT_TEMP_L_A
const ADDR: u8 = 0x0C;

#[inline]
fn from_data(data: u16) -> Self::Output {
Temperature { raw: data }
}
}

impl Temperature {
const DEFAULT: f32 = 25.0;

Expand Down

0 comments on commit 297708c

Please sign in to comment.