#![allow(non_camel_case_types, clippy::unreadable_literal)]
use accelerometer_hal::Error;
use bitflags::{bitflags, Flags};
use core::fmt::Debug;
mod read;
mod write;
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
#[repr(u8)]
pub enum Register {
CHIP_ID = 0x00,
XOUT1 = 0x02,
XOUT2 = 0x03,
YOUT1 = 0x04,
YOUT2 = 0x05,
ZOUT1 = 0x06,
ZOUT2 = 0x07,
INTSTS1 = 0x09,
INTSTS2 = 0x0A,
EVENTINFO1 = 0x0B,
RANGESEL = 0x0F,
BWSEL = 0x10,
POWMODE = 0x11,
DATASETUP = 0x13,
SWRST = 0x14,
INTEN1 = 0x16,
INTEN2 = 0x17,
INTMAP1 = 0x19,
INTMAP2 = 0x1A,
INTCFG1 = 0x20,
INTCFG2 = 0x21,
SLOPEDLY = 0x27,
SLOPETHD = 0x28,
SIGMOT1 = 0x29,
SIGMOT2 = 0x2A,
SIGMOT3 = 0x2B,
INTFCFG = 0x34,
OFSTCOMP1 = 0x36,
OFSTX = 0x38,
OFSTY = 0x39,
OFSTZ = 0x3A,
}
impl Register {
pub const fn addr(self) -> u8 {
self as u8
}
pub const fn read_only(self) -> bool {
matches!(
self,
Self::CHIP_ID
| Self::XOUT1
| Self::XOUT2
| Self::YOUT1
| Self::YOUT2
| Self::ZOUT1
| Self::ZOUT2
| Self::INTSTS1
| Self::INTSTS2
| Self::EVENTINFO1,
)
}
}
macro_rules! reg_from_flags {
($f:ident) => {
impl From<$f> for Register {
fn from(_value: $f) -> Self {
Self::$f
}
}
};
}
reg_from_flags!(INTSTS1);
reg_from_flags!(INTSTS2);
reg_from_flags!(EVENTINFO1);
reg_from_flags!(POWMODE);
reg_from_flags!(DATASETUP);
reg_from_flags!(INTEN1);
reg_from_flags!(INTEN2);
reg_from_flags!(INTMAP1);
reg_from_flags!(INTMAP2);
reg_from_flags!(INTCFG1);
reg_from_flags!(INTCFG2);
reg_from_flags!(SIGMOT2);
reg_from_flags!(INTFCFG);
reg_from_flags!(OFSTCOMP1);
pub enum Axis {
X,
Y,
Z,
}
bitflags! {
#[derive(Copy, Clone)]
pub struct INTSTS1: u8 {
const SIG_MOT_STS = 0b1;
const ANY_MOT_STS = 0b100;
}
#[derive(Copy, Clone)]
pub struct INTSTS2: u8 {
const DATA_STS = 0b1000_0000;
}
#[derive(Copy, Clone)]
pub struct EVENTINFO1: u8 {
const SLP_1ST_X = 0b1;
const SLP_1ST_Y = 0b10;
const SLP_1ST_Z = 0b100;
const SLPSIGN_X = 0b1_0000;
const SLPSIGN_Y = 0b10_0000;
const SLPSIGN_Z = 0b100_0000;
}
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, Default)]
#[repr(u8)]
pub enum RangeSel {
#[default]
PM2G = 0b0011,
PM4G = 0b0101,
PM8G = 0b1000,
Undefined = 0b0,
}
impl From<u8> for RangeSel {
fn from(value: u8) -> Self {
match value & 0b1111 {
0b0011 => Self::PM2G,
0b0101 => Self::PM4G,
0b1000 => Self::PM8G,
_ => Self::Undefined,
}
}
}
impl From<RangeSel> for Register {
fn from(_value: RangeSel) -> Self {
Self::RANGESEL
}
}
impl From<RangeSel> for f32 {
fn from(value: RangeSel) -> Self {
match value {
RangeSel::PM2G => 2.0,
RangeSel::PM4G => 4.0,
RangeSel::PM8G => 8.0,
RangeSel::Undefined => 0.0,
}
}
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, Default)]
#[repr(u8)]
pub enum BwSel {
Hz7C81 = 0b1000,
Hz15C64 = 0b1001,
Hz31C25 = 0b1010,
Hz62C5 = 0b1011,
Hz125 = 0b1100,
Hz250 = 0b1101,
Hz500 = 0b1110,
#[default]
Hz1000 = 0b1111,
}
impl From<u8> for BwSel {
fn from(value: u8) -> Self {
match value & 0b00011111 {
0..=0b1000 => Self::Hz7C81, 0b1001 => Self::Hz15C64,
0b1010 => Self::Hz31C25,
0b1011 => Self::Hz62C5,
0b1100 => Self::Hz125,
0b1101 => Self::Hz250,
0b1110 => Self::Hz500,
_ => Self::Hz1000, }
}
}
impl From<BwSel> for f32 {
fn from(value: BwSel) -> Self {
match value {
BwSel::Hz7C81 => 7.81,
BwSel::Hz15C64 => 15.64,
BwSel::Hz31C25 => 31.25,
BwSel::Hz62C5 => 62.5,
BwSel::Hz125 => 125.0,
BwSel::Hz250 => 250.0,
BwSel::Hz500 => 500.0,
BwSel::Hz1000 => 1000.0,
}
}
}
impl From<BwSel> for Register {
fn from(_value: BwSel) -> Self {
Self::BWSEL
}
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, Default)]
#[repr(u8)]
pub enum SleepDuration {
#[default]
Ms0C5 = 0b0101_0,
Ms1 = 0b0110_0,
Ms2 = 0b0111_0,
Ms4 = 0b1000_0,
Ms6 = 0b1001_0,
Ms10 = 0b1010_0,
Ms25 = 0b1011_0,
Ms50 = 0b1100_0,
Ms100 = 0b1101_0,
Ms500 = 0b1110_0,
Ms1000 = 0b1111_0,
}
impl From<u8> for SleepDuration {
fn from(value: u8) -> Self {
match value & 0b1111_0 {
0b0110_0 => Self::Ms1,
0b0111_0 => Self::Ms2,
0b1000_0 => Self::Ms4,
0b1001_0 => Self::Ms6,
0b1010_0 => Self::Ms10,
0b1011_0 => Self::Ms25,
0b1100_0 => Self::Ms50,
0b1101_0 => Self::Ms100,
0b1110_0 => Self::Ms500,
0b1111_0 => Self::Ms1000,
_ => Self::Ms0C5, }
}
}
impl From<SleepDuration> for Register {
fn from(_value: SleepDuration) -> Self {
Self::POWMODE
}
}
bitflags! {
#[derive(Copy, Clone)]
pub struct POWMODE: u8 {
const LOWPOWER = 0b01000000;
const SUSPEND = 0b10000000;
}
#[derive(Copy, Clone)]
pub struct DATASETUP: u8 {
const PROTECT_DIS = 0b01000000;
const DATA_SEL = 0b10000000;
}
#[derive(Copy, Clone)]
pub struct INTEN1: u8 {
const SLP_EN_X = 0b00000001;
const SLP_EN_Y = 0b00000010;
const SLP_EN_Z = 0b00000100;
}
#[derive(Copy, Clone)]
pub struct INTEN2: u8 {
const DATA_EN = 0b00001000;
}
#[derive(Copy, Clone)]
pub struct INTMAP1: u8 {
const SIGMOT2INT1 = 0b00000001;
const ANYMOT2INT1 = 0b0000100;
}
#[derive(Copy, Clone)]
pub struct INTMAP2: u8 {
const DATA2INT1 = 0b00000001;
}
#[derive(Copy, Clone)]
pub struct INTCFG1: u8 {
const INT1_LV = 0b00000001;
const INT1_OD = 0b00000010;
}
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, Default)]
#[repr(u8)]
pub enum IntLatch {
#[default]
NON_LATCHED = 0b0000,
LATCHED = 0b0111,
TEMP250US = 0b1001,
TEMP500US = 0b1010,
TEMP1MS = 0b1011,
TEMP12C5MS = 0b1100,
TEMP25MS = 0b1101,
TEMP50MS = 0b1110,
TEMP250MS = 0b0001,
TEMP500MS = 0b0010,
TEMP1S = 0b0011,
TEMP2S = 0b0100,
TEMP4S = 0b0101,
TEMP8S = 0b0110,
}
impl From<u8> for IntLatch {
fn from(value: u8) -> Self {
match value & 0b1111 {
0b0111 | 0b1111 => Self::LATCHED,
0b0001 => Self::TEMP250MS,
0b0010 => Self::TEMP500MS,
0b0011 => Self::TEMP1S,
0b0100 => Self::TEMP2S,
0b0101 => Self::TEMP4S,
0b0110 => Self::TEMP8S,
0b1001 => Self::TEMP250US,
0b1010 => Self::TEMP500US,
0b1011 => Self::TEMP1MS,
0b1100 => Self::TEMP12C5MS,
0b1101 => Self::TEMP25MS,
0b1110 => Self::TEMP50MS,
_ => Self::NON_LATCHED,
}
}
}
impl From<IntLatch> for Register {
fn from(_value: IntLatch) -> Self {
Self::INTCFG2
}
}
bitflags! {
#[derive(Copy, Clone)]
pub struct INTCFG2: u8 {
const INT_RST = 0b10000000;
}
#[derive(Copy, Clone)]
pub struct SIGMOT2: u8 {
const SIG_MOT_EN = 0b00000010;
const ANY_MOT_EN = 0b00000100;
}
#[derive(Copy, Clone)]
pub struct INTFCFG: u8 {
const I2C_WDT_SEL = 0b00000010;
const I2C_WDT_EN = 0b00000100;
}
#[derive(Copy, Clone)]
pub struct OFSTCOMP1: u8 {
const OFST_RST = 0b10000000;
}
}
pub trait Read<I2C, E> {
fn chip_id(&mut self) -> Result<u8, E>;
fn axis_lsb(&mut self, axis: &Axis) -> Result<u8, E>;
fn axis_msb(&mut self, axis: &Axis) -> Result<u8, E>;
fn axis_newdata(&mut self, axis: &Axis) -> Result<bool, E>;
fn read_flags<F: Flags<Bits = u8> + Into<Register>>(&mut self, flags: F) -> Result<F, E>;
fn read_mode<M: From<u8> + Into<Register>>(&mut self, mode: M) -> Result<M, E>;
}
pub trait Write<I2C, E>
where
E: Debug,
{
fn set_range(&mut self, range: RangeSel) -> Result<&mut Self, Error<E>>;
fn set_bandwidth(&mut self, bandwidth: BwSel) -> Result<&mut Self, Error<E>>;
fn set_sleep_duration(&mut self, sleep_duration: SleepDuration) -> Result<&mut Self, Error<E>>;
fn set_int_latch(&mut self, latch: IntLatch) -> Result<&mut Self, Error<E>>;
fn set_flags<F: Flags<Bits = u8> + Into<Register> + Copy>(
&mut self,
flags: F,
) -> Result<&mut Self, Error<E>>;
fn reset_all(&mut self) -> Result<&mut Self, Error<E>>;
}