From e2ff6c04f61ae492224b1899248d208e67c4bbfa Mon Sep 17 00:00:00 2001 From: Walter Bonetti Date: Wed, 24 Apr 2024 21:23:18 -0400 Subject: [PATCH] refactoring/add: minimal read support (unstable api) --- src/command.rs | 404 ++++++++++++++++++++-------------------- src/driver.rs | 485 ++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 691 insertions(+), 198 deletions(-) diff --git a/src/command.rs b/src/command.rs index d56bef7..fc47815 100644 --- a/src/command.rs +++ b/src/command.rs @@ -1,195 +1,199 @@ #![allow(dead_code)] -/// Device Identifier Register (R) -/// Default: 00000101 -pub const WHO_AM_I: u8 = 0x00; -/// Device Revision ID Register (R) -/// Default: 01101000 -pub const REVISION_ID: u8 = 0x01; -/// SPI Interface and Sensor Enable Register (W) -/// Default: 00100000 -pub const CTRL1: u8 = 0x02; -/// Accelerometer: Output Data Rate, Full Scale, Self-Test Register (W) -/// Default: 00000000 -pub const CTRL2: u8 = 0x03; -/// Gyroscope: Output Data Rate, Full Scale, Self-Test Register (W) -/// Default: 00000000 -pub const CTRL3: u8 = 0x04; -/// Reserved Register (W) -/// Default: 00000000 -pub const RESERVED_U1: u8 = 0x05; -/// Low pass filter setting Register (W) -/// Default: 00000000 -pub const CTRL5: u8 = 0x06; -/// Reserved Register (W) -/// Default: 00000000 -pub const RESERVED_U2: u8 = 0x07; -/// Enable Sensors Register (W) -/// Default: 00000000 -pub const CTRL7: u8 = 0x08; -/// Motion Detection Control Register (W) -/// Default: 00000000 -pub const CTRL8: u8 = 0x09; -/// Host Commands Host Controlled Calibration Registers (See CTRL9, Usage is Optional) Register (W) -/// Default: 00000000 -pub const CTRL9: u8 = 0x0A; -/// Calibration Low Register Register (RW) -/// Default: 00000000 -pub const CAL1_LOW: u8 = 0x0B; -/// Calibration High Register Register (RW) -/// Default: 00000000 -pub const CAL1_HIGH: u8 = 0x0C; -/// Calibration Low Register Register (RW) -/// Default: 00000000 -pub const CAL2_LOW: u8 = 0x0D; -/// Calibration High Register Register (RW) -/// Default: 00000000 -pub const CAL2_HIGH: u8 = 0x0E; -/// Calibration Low Register Register (RW) -/// Default: 00000000 -pub const CAL3_LOW: u8 = 0x0F; -/// Calibration High Register Register (RW) -/// Default: 00000000 -pub const CAL3_HIGH: u8 = 0x10; -/// Calibration Low Register Register (RW) -/// Default: 00000000 -pub const CAL4_LOW: u8 = 0x11; -/// Calibration High Register Register (RW) -/// Default: 00000000 -pub const CAL4_HIGH: u8 = 0x12; -/// FIFO watermark level, in ODRs Register (W) -/// Default: 00000000 -pub const FIFO_WTM_TH: u8 = 0x13; -/// FIFO Setup Register (W) -/// Default: 00000000 -pub const FIFO_CTRL: u8 = 0x14; -/// FIFO sample count LSBs Register (R) -/// Default: 00000000 -pub const FIFO_SMPL_CNT: u8 = 0x15; -/// FIFO Status Register (R) -/// Default: 00000000 -pub const FIFO_STATUS: u8 = 0x16; -/// FIFO Data Status Registers Register (R) -/// Default: 00000000 -pub const FIFO_DATA: u8 = 0x17; -/// Sensor Data Availability with the Locking mechanism, `CmdDone` (CTRL9 protocol bit). Register (R) -/// Default: 00000000 -pub const STATUSINT: u8 = 0x2D; -/// Output Data Over Run and Data Availability. Register (R) -/// Default: 00000000 -pub const STATUS0: u8 = 0x2E; -/// Miscellaneous Status: Any Motion, No Motion, Significant Motion, Pedometer, Tap. Timestamp Register Register (R) -/// Default: 00000000 -pub const STATUS1: u8 = 0x2F; -/// Sample Time Stamp Register (R) -/// Default: 00000000 -pub const TIMESTAMP_LOW: u8 = 0x30; -/// Register (R) -/// Default: 00000000 -pub const TIMESTAMP_MID: u8 = 0x31; -/// Register (R) -/// Default: 00000000 -pub const TIMESTAMP_HIGH: u8 = 0x32; -/// Temperature Output Data Register (R) -/// Default: 00000000 -pub const TEMP_LOW: u8 = 0x33; -/// `TEMP_LOW` – Low 8 bits. `TEMP_HIGH` – upper 8 bits Register (R) -/// Default: 00000000 -pub const TEMP_HIGH: u8 = 0x34; -/// X-axis Acceleration Low Register (R) -/// Default: 00000000 -pub const AX_LOW: u8 = 0x35; -/// X-axis Acceleration High Register (R) -/// Default: 00000000 -pub const AX_HIGH: u8 = 0x36; -/// Y-axis Acceleration Low Register (R) -/// Default: 00000000 -pub const AY_LOW: u8 = 0x37; -/// Y-axis Acceleration High Register (R) -/// Default: 00000000 -pub const AY_HIGH: u8 = 0x38; -/// Z-axis Acceleration Low Register (R) -/// Default: 00000000 -pub const AZ_LOW: u8 = 0x39; -/// Z-axis Acceleration High Register (R) -/// Default: 00000000 -pub const AZ_HIGH: u8 = 0x3A; -/// X-axis Angular Rate Low Register (R) -/// Default: 00000000 -pub const GX_LOW: u8 = 0x3B; -/// X-axis Angular Rate High Register (R) -/// Default: 00000000 -pub const GX_HIGH: u8 = 0x3C; -/// Y-axis Angular Rate Low Register (R) -/// Default: 00000000 -pub const GY_LOW: u8 = 0x3D; -/// Z-axis Angular Rate High Register (R) -/// Default: 00000000 -pub const GY_HIGH: u8 = 0x3E; -/// Z-axis Angular Rate Low Register (R) -/// Default: 00000000 -pub const GZ_LOW: u8 = 0x3F; -/// Calibration-On-Demand status register Register (R) -/// Default: 00000000 -pub const COD_STATUS: u8 = 0x46; -/// General purpose register Register (R) -/// Default: 00000000 -pub const D_QW_LOW: u8 = 0x49; -/// General purpose register Register (R) -/// Default: 00000000 -pub const D_QW_HIGH: u8 = 0x4A; -/// General purpose register Register (R) -/// Default: 00000000 -pub const D_QX_LOW: u8 = 0x4B; -/// Reserved Register (R) -/// Default: 00000000 -pub const D_QX_HIGH: u8 = 0x4C; -/// General purpose register Register (R) -/// Default: 00000000 -pub const D_QY_LOW: u8 = 0x4D; -/// Reserved Register (R) -/// Default: 00000000 -pub const D_QY_HIGH: u8 = 0x4E; -/// Reserved Register (R) -/// Default: 00000000 -pub const D_QZ_LOW: u8 = 0x4F; -/// Reserved Register (R) -/// Default: 00000000 -pub const D_QZ_HIGH: u8 = 0x50; -/// General purpose register Register (R) -/// Default: 00000000 -pub const D_VX_LOW: u8 = 0x51; -/// General purpose register Register (R) -/// Default: 00000000 -pub const D_VX_HIGH: u8 = 0x52; -/// General purpose register Register (R) -/// Default: 00000000 -pub const D_VY_LOW: u8 = 0x53; -/// General purpose register Register (R) -/// Default: 00000000 -pub const D_VY_HIGH: u8 = 0x54; -/// General purpose register Register (R) -/// Default: 00000000 -pub const D_VZ_LOW: u8 = 0x55; -/// General purpose register Register (R) -/// Default: 00000000 -pub const D_VZ_HIGH: u8 = 0x56; -/// Axis, direction, number of detected Tap Register (R) -/// Default: 00000000 -pub const TAP_STATUS: u8 = 0x59; -/// Low byte of step count of Pedometer Register (R) -/// Default: 00000000 -pub const STEP_CNT_LOWOW: u8 = 0x5A; -/// Middle byte of step count of Pedometer Register (R) -/// Default: 00000000 -pub const STEP_CNT_MIDL: u8 = 0x5B; -/// High byte of step count of Pedometer Register (R) -/// Default: 00000000 -pub const STEP_CNT_HIGHIGH: u8 = 0x5C; -/// Soft Reset Register Register (W) -/// Default: 00000000 -pub const RESET: u8 = 0x60; - +pub mod constants { + /// Device Identifier Register (R) + /// Default: 00000101 + pub const WHO_AM_I: u8 = 0x00; + /// Device Revision ID Register (R) + /// Default: 01101000 + pub const REVISION_ID: u8 = 0x01; + /// SPI Interface and Sensor Enable Register (W) + /// Default: 00100000 + pub const CTRL1: u8 = 0x02; + /// Accelerometer: Output Data Rate, Full Scale, Self-Test Register (W) + /// Default: 00000000 + pub const CTRL2: u8 = 0x03; + /// Gyroscope: Output Data Rate, Full Scale, Self-Test Register (W) + /// Default: 00000000 + pub const CTRL3: u8 = 0x04; + /// Reserved Register (W) + /// Default: 00000000 + pub const RESERVED_U1: u8 = 0x05; + /// Low pass filter setting Register (W) + /// Default: 00000000 + pub const CTRL5: u8 = 0x06; + /// Reserved Register (W) + /// Default: 00000000 + pub const RESERVED_U2: u8 = 0x07; + /// Enable Sensors Register (W) + /// Default: 00000000 + pub const CTRL7: u8 = 0x08; + /// Motion Detection Control Register (W) + /// Default: 00000000 + pub const CTRL8: u8 = 0x09; + /// Host Commands Host Controlled Calibration Registers (See CTRL9, Usage is Optional) Register (W) + /// Default: 00000000 + pub const CTRL9: u8 = 0x0A; + /// Calibration Low Register Register (RW) + /// Default: 00000000 + pub const CAL1_LOW: u8 = 0x0B; + /// Calibration High Register Register (RW) + /// Default: 00000000 + pub const CAL1_HIGH: u8 = 0x0C; + /// Calibration Low Register Register (RW) + /// Default: 00000000 + pub const CAL2_LOW: u8 = 0x0D; + /// Calibration High Register Register (RW) + /// Default: 00000000 + pub const CAL2_HIGH: u8 = 0x0E; + /// Calibration Low Register Register (RW) + /// Default: 00000000 + pub const CAL3_LOW: u8 = 0x0F; + /// Calibration High Register Register (RW) + /// Default: 00000000 + pub const CAL3_HIGH: u8 = 0x10; + /// Calibration Low Register Register (RW) + /// Default: 00000000 + pub const CAL4_LOW: u8 = 0x11; + /// Calibration High Register Register (RW) + /// Default: 00000000 + pub const CAL4_HIGH: u8 = 0x12; + /// FIFO watermark level, in ODRs Register (W) + /// Default: 00000000 + pub const FIFO_WTM_TH: u8 = 0x13; + /// FIFO Setup Register (W) + /// Default: 00000000 + pub const FIFO_CTRL: u8 = 0x14; + /// FIFO sample count LSBs Register (R) + /// Default: 00000000 + pub const FIFO_SMPL_CNT: u8 = 0x15; + /// FIFO Status Register (R) + /// Default: 00000000 + pub const FIFO_STATUS: u8 = 0x16; + /// FIFO Data Status Registers Register (R) + /// Default: 00000000 + pub const FIFO_DATA: u8 = 0x17; + /// Sensor Data Availability with the Locking mechanism, `CmdDone` (CTRL9 protocol bit). Register (R) + /// Default: 00000000 + pub const STATUSINT: u8 = 0x2D; + /// Output Data Over Run and Data Availability. Register (R) + /// Default: 00000000 + pub const STATUS0: u8 = 0x2E; + /// Miscellaneous Status: Any Motion, No Motion, Significant Motion, Pedometer, Tap. Timestamp Register Register (R) + /// Default: 00000000 + pub const STATUS1: u8 = 0x2F; + /// Sample Time Stamp Register (R) + /// Default: 00000000 + pub const TIMESTAMP_LOW: u8 = 0x30; + /// Register (R) + /// Default: 00000000 + pub const TIMESTAMP_MID: u8 = 0x31; + /// Register (R) + /// Default: 00000000 + pub const TIMESTAMP_HIGH: u8 = 0x32; + /// Temperature Output Data Register (R) + /// Default: 00000000 + pub const TEMP_LOW: u8 = 0x33; + /// `TEMP_LOW` – Low 8 bits. `TEMP_HIGH` – upper 8 bits Register (R) + /// Default: 00000000 + pub const TEMP_HIGH: u8 = 0x34; + /// X-axis Acceleration Low Register (R) + /// Default: 00000000 + pub const AX_LOW: u8 = 0x35; + /// X-axis Acceleration High Register (R) + /// Default: 00000000 + pub const AX_HIGH: u8 = 0x36; + /// Y-axis Acceleration Low Register (R) + /// Default: 00000000 + pub const AY_LOW: u8 = 0x37; + /// Y-axis Acceleration High Register (R) + /// Default: 00000000 + pub const AY_HIGH: u8 = 0x38; + /// Z-axis Acceleration Low Register (R) + /// Default: 00000000 + pub const AZ_LOW: u8 = 0x39; + /// Z-axis Acceleration High Register (R) + /// Default: 00000000 + pub const AZ_HIGH: u8 = 0x3A; + /// X-axis Angular Rate Low Register (R) + /// Default: 00000000 + pub const GX_LOW: u8 = 0x3B; + /// X-axis Angular Rate High Register (R) + /// Default: 00000000 + pub const GX_HIGH: u8 = 0x3C; + /// Y-axis Angular Rate Low Register (R) + /// Default: 00000000 + pub const GY_LOW: u8 = 0x3D; + /// Z-axis Angular Rate High Register (R) + /// Default: 00000000 + pub const GY_HIGH: u8 = 0x3E; + /// Z-axis Angular Rate Low Register (R) + /// Default: 00000000 + pub const GZ_LOW: u8 = 0x3F; + /// Z-axis Angular Rate High Register (R) + /// Default: 00000000 + pub const GZ_HIGH: u8 = 0x40; + /// Calibration-On-Demand status register Register (R) + /// Default: 00000000 + pub const COD_STATUS: u8 = 0x46; + /// General purpose register Register (R) + /// Default: 00000000 + pub const D_QW_LOW: u8 = 0x49; + /// General purpose register Register (R) + /// Default: 00000000 + pub const D_QW_HIGH: u8 = 0x4A; + /// General purpose register Register (R) + /// Default: 00000000 + pub const D_QX_LOW: u8 = 0x4B; + /// Reserved Register (R) + /// Default: 00000000 + pub const D_QX_HIGH: u8 = 0x4C; + /// General purpose register Register (R) + /// Default: 00000000 + pub const D_QY_LOW: u8 = 0x4D; + /// Reserved Register (R) + /// Default: 00000000 + pub const D_QY_HIGH: u8 = 0x4E; + /// Reserved Register (R) + /// Default: 00000000 + pub const D_QZ_LOW: u8 = 0x4F; + /// Reserved Register (R) + /// Default: 00000000 + pub const D_QZ_HIGH: u8 = 0x50; + /// General purpose register Register (R) + /// Default: 00000000 + pub const D_VX_LOW: u8 = 0x51; + /// General purpose register Register (R) + /// Default: 00000000 + pub const D_VX_HIGH: u8 = 0x52; + /// General purpose register Register (R) + /// Default: 00000000 + pub const D_VY_LOW: u8 = 0x53; + /// General purpose register Register (R) + /// Default: 00000000 + pub const D_VY_HIGH: u8 = 0x54; + /// General purpose register Register (R) + /// Default: 00000000 + pub const D_VZ_LOW: u8 = 0x55; + /// General purpose register Register (R) + /// Default: 00000000 + pub const D_VZ_HIGH: u8 = 0x56; + /// Axis, direction, number of detected Tap Register (R) + /// Default: 00000000 + pub const TAP_STATUS: u8 = 0x59; + /// Low byte of step count of Pedometer Register (R) + /// Default: 00000000 + pub const STEP_CNT_LOW: u8 = 0x5A; + /// Middle byte of step count of Pedometer Register (R) + /// Default: 00000000 + pub const STEP_CNT_MID: u8 = 0x5B; + /// High byte of step count of Pedometer Register (R) + /// Default: 00000000 + pub const STEP_CNT_HIGH: u8 = 0x5C; + /// Soft Reset Register Register (W) + /// Default: 00000000 + pub const RESET: u8 = 0x60; +} pub mod register { pub mod ship_info { @@ -902,27 +906,35 @@ pub mod register { /// Acceleration Register Size pub type AccelerationRegister = u8; + /// Acceleration Register Size + pub type AccelerationFullRegister = u16; + /// Angular Register Size pub type AngularRegister = u8; + /// Angular Register Size + pub type AngularFullRegister = u16; + /// Acceleration Output. Register Address: 0x35 – 0x3A + #[derive(Debug, PartialEq, Eq, Clone, Copy)] pub struct AccelerationOutput { /// AX - pub x: u16, + pub x: AccelerationFullRegister, /// AY - pub y: u16, + pub y: AccelerationFullRegister, /// AZ - pub z: u16, + pub z: AccelerationFullRegister, } /// Angular Rate Output. Register Address: 0x3B – 0x40 + #[derive(Debug, PartialEq, Eq, Clone, Copy)] pub struct AngularRateOutput { /// AX - pub x: u16, + pub x: AngularFullRegister, /// AY - pub y: u16, + pub y: AngularFullRegister, /// AZ - pub z: u16, + pub z: AngularFullRegister, } } diff --git a/src/driver.rs b/src/driver.rs index a21f62f..0d90afc 100644 --- a/src/driver.rs +++ b/src/driver.rs @@ -2,8 +2,36 @@ use embedded_hal::delay::DelayNs; use embedded_hal::i2c::{I2c, SevenBitAddress}; +use crate::command::constants::{ + AX_HIGH, AX_LOW, AY_HIGH, AZ_HIGH, AZ_LOW, COD_STATUS, CTRL1, CTRL2, CTRL3, CTRL5, CTRL7, + CTRL8, CTRL9, FIFO_CTRL, FIFO_DATA, FIFO_SMPL_CNT, FIFO_STATUS, FIFO_WTM_TH, GX_HIGH, GX_LOW, + GY_HIGH, GZ_HIGH, GZ_LOW, STATUS0, STATUS1, STATUSINT, STEP_CNT_HIGH, STEP_CNT_LOW, + STEP_CNT_MID, TAP_STATUS, TEMP_HIGH, TEMP_LOW, TIMESTAMP_HIGH, TIMESTAMP_LOW, TIMESTAMP_MID, + WHO_AM_I, +}; +use crate::command::register::acceleration::{ + AccelerationFullRegister, AccelerationOutput, AngularFullRegister, AngularRateOutput, +}; +use crate::command::register::cod_status::CODStatusRegister; +use crate::command::register::ctrl1::Ctrl1Register; +use crate::command::register::ctrl2::Ctrl2Register; +use crate::command::register::ctrl3::Ctrl3Register; +use crate::command::register::ctrl5::Ctrl5Register; +use crate::command::register::ctrl7::Ctrl7Register; +use crate::command::register::ctrl8::Ctrl8Register; +use crate::command::register::ctrl9::Ctrl9Register; +use crate::command::register::fifo_ctrl::FIFOControlRegister; +use crate::command::register::fifo_data::FIFODataRegister; +use crate::command::register::fifo_sample_count::FIFOSampleCountRegister; +use crate::command::register::fifo_status::FIFOStatusRegister; +use crate::command::register::fifo_wtm_th::FIFOWTMRegister; use crate::command::register::ship_info::{DeviceID, RevisionID}; -use crate::command::WHO_AM_I; +use crate::command::register::status_0::OutputDataStatusRegister; +use crate::command::register::status_1::MiscellaneousStatusRegister; +use crate::command::register::status_int::SensorDataAvailableAndLockRegister; +use crate::command::register::tap_status::TapStatusRegister; +use crate::command::register::temp::Temperature; +use crate::command::register::timestamp::SampleTimeStamp; #[repr(u8)] #[derive(Debug, Clone, Copy)] @@ -73,10 +101,16 @@ where self.interface } - /// Get the device id + /// Get the device id. + /// + /// This function retrieves the device ID from the connected device. /// /// # Errors /// + /// This function can return an error if there is an issue during the communication process. + /// + /// Possible errors include: + /// - Communication error: This can occur if there is a problem communicating with the device over the interface. pub fn get_device_id(&mut self) -> Result { let mut buffer = [0u8; 1]; self.interface @@ -93,10 +127,457 @@ where /// /// # Errors /// + /// This function can return an error if there is an issue during the communication process. + /// + /// Possible errors include: + /// - Communication error: This can occur if there is a problem communicating with the device over the interface. pub fn get_device_revision_id(&mut self) -> Result { let mut buffer = [0u8; 1]; self.interface .write_read(self.addr.into(), &[WHO_AM_I], &mut buffer)?; + + Ok(buffer[0]) + } + + /// Get Serial Interface and Sensor Enable. + /// + /// # Errors + /// + /// This function can return an error if there is an issue during the communication process. + /// + /// Possible errors include: + /// - Communication error: This can occur if there is a problem communicating with the device over the interface. + pub fn get_crtl1(&mut self) -> Result { + let mut buffer = [0u8; 1]; + self.interface + .write_read(self.addr.into(), &[CTRL1], &mut buffer)?; + + Ok(Ctrl1Register(buffer[0])) + } + + /// Accelerometer Settings + /// + /// # Errors + /// + /// This function can return an error if there is an issue during the communication process. + /// + /// Possible errors include: + /// - Communication error: This can occur if there is a problem communicating with the device over the interface. + pub fn get_ctrl2(&mut self) -> Result { + let mut buffer = [0u8; 1]; + self.interface + .write_read(self.addr.into(), &[CTRL2], &mut buffer)?; + + Ok(Ctrl2Register(buffer[0])) + } + + /// Gyroscope Settings + /// + /// # Errors + /// + /// This function can return an error if there is an issue during the communication process. + /// + /// Possible errors include: + /// - Communication error: This can occur if there is a problem communicating with the device over the interface. + pub fn get_ctrl3(&mut self) -> Result { + let mut buffer = [0u8; 1]; + self.interface + .write_read(self.addr.into(), &[CTRL3], &mut buffer)?; + + Ok(Ctrl3Register(buffer[0])) + } + + /// Sensor Data Processing Settings + /// + /// # Errors + /// + /// This function can return an error if there is an issue during the communication process. + /// + /// Possible errors include: + /// - Communication error: This can occur if there is a problem communicating with the device over the interface. + pub fn get_ctrl5(&mut self) -> Result { + let mut buffer = [0u8; 1]; + self.interface + .write_read(self.addr.into(), &[CTRL5], &mut buffer)?; + + Ok(Ctrl5Register(buffer[0])) + } + + /// Enable Sensors and Configure Data Reads + /// + /// # Errors + /// + /// This function can return an error if there is an issue during the communication process. + /// + /// Possible errors include: + /// - Communication error: This can occur if there is a problem communicating with the device over the interface. + pub fn get_ctrl7(&mut self) -> Result { + let mut buffer = [0u8; 1]; + self.interface + .write_read(self.addr.into(), &[CTRL7], &mut buffer)?; + + Ok(Ctrl7Register(buffer[0])) + } + + /// Motion Detection Control + /// + /// # Errors + /// + /// This function can return an error if there is an issue during the communication process. + /// + /// Possible errors include: + /// - Communication error: This can occur if there is a problem communicating with the device over the interface. + pub fn get_ctrl8(&mut self) -> Result { + let mut buffer = [0u8; 1]; + self.interface + .write_read(self.addr.into(), &[CTRL8], &mut buffer)?; + + Ok(Ctrl8Register(buffer[0])) + } + + /// Host Commands. Register Address: 10 (0x0A) + /// Referred to: CTRL 9 Functionality (Executing Pre-defined Commands) + /// + /// # Errors + /// + /// This function can return an error if there is an issue during the communication process. + /// + /// Possible errors include: + /// - Communication error: This can occur if there is a problem communicating with the device over the interface. + /// + pub fn get_ctrl9(&mut self) -> Result { + let mut buffer = [0u8; 1]; + self.interface + .write_read(self.addr.into(), &[CTRL9], &mut buffer)?; + + Ok(match buffer[0] { + 0x04 => Ctrl9Register::CtrlCmdRstFifo, + 0x05 => Ctrl9Register::CtrlCmdReqFifo, + 0x08 => Ctrl9Register::CtrlCmdWriteWomSetting, + 0x09 => Ctrl9Register::CtrlCmdAccelHostDeltaOffset, + 0x0A => Ctrl9Register::CtrlCmdGyroHostDeltaOffset, + 0x0C => Ctrl9Register::CtrlCmdConfigureTap, + 0x0D => Ctrl9Register::CtrlCmdConfigurePedometer, + 0x0E => Ctrl9Register::CtrlCmdConfigureMotion, + 0x0F => Ctrl9Register::CtrlCmdResetPedometer, + 0x10 => Ctrl9Register::CtrlCmdCopyUsid, + 0x11 => Ctrl9Register::CtrlCmdSetRpu, + 0x12 => Ctrl9Register::CtrlCmdAhbClockGating, + 0xA2 => Ctrl9Register::CtrlCmdOnDemandCalibration, + 0xAA => Ctrl9Register::CtrlCmdApplyGyroGains, + // TODO: improve this error handling + _ => Ctrl9Register::CtrlCmdAck, + }) + } + + /// FIFO Watermark Register Address + /// + /// # Errors + /// + /// This function can return an error if there is an issue during the communication process. + /// + /// Possible errors include: + /// - Communication error: This can occur if there is a problem communicating with the device over the interface. + pub fn get_fifo_wtm(&mut self) -> Result { + let mut buffer = [0u8; 1]; + self.interface + .write_read(self.addr.into(), &[FIFO_WTM_TH], &mut buffer)?; + Ok(buffer[0]) } + + /// FIFO Control Register Address + /// + /// # Errors + /// + /// This function can return an error if there is an issue during the communication process. + /// + /// Possible errors include: + /// - Communication error: This can occur if there is a problem communicating with the device over the interface. + pub fn get_fifo_ctrl(&mut self) -> Result { + let mut buffer = [0u8; 1]; + self.interface + .write_read(self.addr.into(), &[FIFO_CTRL], &mut buffer)?; + + Ok(FIFOControlRegister(buffer[0])) + } + + /// FIFO Sample Count Register Address + /// + /// # Errors + /// + /// This function can return an error if there is an issue during the communication process. + /// + /// Possible errors include: + /// - Communication error: This can occur if there is a problem communicating with the device over the interface. + pub fn get_fifo_sample_cnt(&mut self) -> Result { + let mut buffer = [0u8; 1]; + self.interface + .write_read(self.addr.into(), &[FIFO_SMPL_CNT], &mut buffer)?; + + Ok(FIFOSampleCountRegister(buffer[0])) + } + + /// FIFO Status + /// + /// # Errors + /// + /// This function can return an error if there is an issue during the communication process. + /// + /// Possible errors include: + /// - Communication error: This can occur if there is a problem communicating with the device over the interface. + pub fn get_fifo_status(&mut self) -> Result { + let mut buffer = [0u8; 1]; + self.interface + .write_read(self.addr.into(), &[FIFO_STATUS], &mut buffer)?; + + Ok(FIFOStatusRegister(buffer[0])) + } + + /// FIFO Data + /// + /// # Errors + /// + /// This function can return an error if there is an issue during the communication process. + /// + /// Possible errors include: + /// - Communication error: This can occur if there is a problem communicating with the device over the interface. + pub fn get_fifo_data(&mut self) -> Result { + let mut buffer = [0u8; 1]; + self.interface + .write_read(self.addr.into(), &[FIFO_DATA], &mut buffer)?; + + Ok(FIFODataRegister(buffer[0])) + } + + /// Sensor Data Available and Lock Register Address + /// + /// # Errors + /// + /// This function can return an error if there is an issue during the communication process. + /// + /// Possible errors include: + /// - Communication error: This can occur if there is a problem communicating with the device over the interface. + pub fn get_sensor_data_available_and_lock( + &mut self, + ) -> Result { + let mut buffer = [0u8; 1]; + self.interface + .write_read(self.addr.into(), &[STATUSINT], &mut buffer)?; + + Ok(SensorDataAvailableAndLockRegister(buffer[0])) + } + + /// Output Data Status Register + /// + /// # Errors + /// + /// This function can return an error if there is an issue during the communication process. + /// + /// Possible errors include: + /// - Communication error: This can occur if there is a problem communicating with the device over the interface. + pub fn get_output_data_status(&mut self) -> Result { + let mut buffer = [0u8; 1]; + self.interface + .write_read(self.addr.into(), &[STATUS0], &mut buffer)?; + + Ok(OutputDataStatusRegister(buffer[0])) + } + + /// Miscellaneous Status + /// + /// # Errors + /// + /// This function can return an error if there is an issue during the communication process. + /// + /// Possible errors include: + /// - Communication error: This can occur if there is a problem communicating with the device over the interface. + pub fn get_miscellaneous_status(&mut self) -> Result { + let mut buffer = [0u8; 1]; + self.interface + .write_read(self.addr.into(), &[STATUS1], &mut buffer)?; + + Ok(MiscellaneousStatusRegister(buffer[0])) + } + + /// 3 Bytes Sample Time Stamp – Output Count. + /// + /// # Errors + /// + /// This function can return an error if there is an issue during the communication process. + /// + /// Possible errors include: + /// - Communication error: This can occur if there is a problem communicating with the device over the interface. + pub fn get_sample_time_stamp_output_count(&mut self) -> Result { + let mut buffer = [0u8; 1]; + let mut timestamp: SampleTimeStamp = 0; + self.interface + .write_read(self.addr.into(), &[TIMESTAMP_HIGH], &mut buffer)?; + timestamp |= SampleTimeStamp::from(buffer[0]) << 16; + self.interface + .write_read(self.addr.into(), &[TIMESTAMP_MID], &mut buffer)?; + timestamp |= SampleTimeStamp::from(buffer[0]) << 8; + self.interface + .write_read(self.addr.into(), &[TIMESTAMP_LOW], &mut buffer)?; + timestamp |= SampleTimeStamp::from(buffer[0]); + + Ok(timestamp) + } + + /// Temp Sensor Output + /// + /// # Errors + /// + /// This function can return an error if there is an issue during the communication process. + /// + /// Possible errors include: + /// - Communication error: This can occur if there is a problem communicating with the device over the interface. + pub fn get_temperature(&mut self) -> Result { + let mut buffer = [0u8; 1]; + let mut temp: Temperature = 0; + self.interface + .write_read(self.addr.into(), &[TEMP_HIGH], &mut buffer)?; + temp |= Temperature::from(buffer[0]) << 8; + self.interface + .write_read(self.addr.into(), &[TEMP_LOW], &mut buffer)?; + temp |= Temperature::from(buffer[0]); + + Ok(temp) + } + + /// Get Acceleration Output Helper + /// + /// # Errors + /// + /// This function can return an error if there is an issue during the communication process. + /// + /// Possible errors include: + /// - Communication error: This can occur if there is a problem communicating with the device over the interface. + fn get_acceleration_helper( + &mut self, + high_addr: u8, + low_addr: u8, + ) -> Result { + let mut buffer = [0u8; 1]; + let mut tmp: AccelerationFullRegister = 0; + self.interface + .write_read(self.addr.into(), &[high_addr], &mut buffer)?; + tmp |= AccelerationFullRegister::from(buffer[0]) << 8; + self.interface + .write_read(self.addr.into(), &[low_addr], &mut buffer)?; + tmp |= AccelerationFullRegister::from(buffer[0]); + Ok(tmp) + } + + /// Get Acceleration Output + /// + /// # Errors + /// + /// This function can return an error if there is an issue during the communication process. + /// + /// Possible errors include: + /// - Communication error: This can occur if there is a problem communicating with the device over the interface. + pub fn get_acceleration(&mut self) -> Result { + Ok(AccelerationOutput { + x: self.get_acceleration_helper(AX_HIGH, AX_LOW)?, + y: self.get_acceleration_helper(AY_HIGH, AX_LOW)?, + z: self.get_acceleration_helper(AZ_HIGH, AZ_LOW)?, + }) + } + + /// Get Angular Rate Output Helper + /// + /// # Errors + /// + /// This function can return an error if there is an issue during the communication process. + /// + /// Possible errors include: + /// - Communication error: This can occur if there is a problem communicating with the device over the interface. + fn get_angular_rate_helper( + &mut self, + high_addr: u8, + low_addr: u8, + ) -> Result { + let mut buffer = [0u8; 1]; + let mut tmp: AngularFullRegister = 0; + self.interface + .write_read(self.addr.into(), &[high_addr], &mut buffer)?; + tmp |= AngularFullRegister::from(buffer[0]) << 8; + self.interface + .write_read(self.addr.into(), &[low_addr], &mut buffer)?; + tmp |= AngularFullRegister::from(buffer[0]); + Ok(tmp) + } + + /// Get Angular Rate Output + /// + /// # Errors + /// + /// This function can return an error if there is an issue during the communication process. + /// + /// Possible errors include: + /// - Communication error: This can occur if there is a problem communicating with the device over the interface. + pub fn get_angular_rate(&mut self) -> Result { + Ok(AngularRateOutput { + x: self.get_angular_rate_helper(GX_HIGH, GX_LOW)?, + y: self.get_angular_rate_helper(GY_HIGH, GX_LOW)?, + z: self.get_angular_rate_helper(GZ_HIGH, GZ_LOW)?, + }) + } + + /// Get Calibration-On-Demand (COD) Status Register + /// + /// # Errors + /// + /// This function can return an error if there is an issue during the communication process. + /// + /// Possible errors include: + /// - Communication error: This can occur if there is a problem communicating with the device over the interface. + pub fn get_cod_status(&mut self) -> Result { + let mut buffer = [0u8; 1]; + self.interface + .write_read(self.addr.into(), &[COD_STATUS], &mut buffer)?; + + Ok(CODStatusRegister(buffer[0])) + } + + /// Get Activity Detection Output Registers + /// + /// # Errors + /// + /// This function can return an error if there is an issue during the communication process. + /// + /// Possible errors include: + /// - Communication error: This can occur if there is a problem communicating with the device over the interface. + pub fn get_tap_status(&mut self) -> Result { + let mut buffer: [u8; 1] = [0u8; 1]; + self.interface + .write_read(self.addr.into(), &[TAP_STATUS], &mut buffer)?; + + Ok(TapStatusRegister(buffer[0])) + } + + /// 24-bit Step Count detected by Pedometer engine + /// + /// # Errors + /// + /// This function can return an error if there is an issue during the communication process. + /// + /// Possible errors include: + /// - Communication error: This can occur if there is a problem communicating with the device over the interface. + pub fn get_step_cnt(&mut self) -> Result { + let mut buffer = [0u8; 1]; + let mut timestamp: SampleTimeStamp = 0; + self.interface + .write_read(self.addr.into(), &[STEP_CNT_HIGH], &mut buffer)?; + timestamp |= SampleTimeStamp::from(buffer[0]) << 16; + self.interface + .write_read(self.addr.into(), &[STEP_CNT_MID], &mut buffer)?; + timestamp |= SampleTimeStamp::from(buffer[0]) << 8; + self.interface + .write_read(self.addr.into(), &[STEP_CNT_LOW], &mut buffer)?; + timestamp |= SampleTimeStamp::from(buffer[0]); + + Ok(timestamp) + } }