1
Fork 0
mpu6050/src/device.rs
2021-02-19 22:57:04 +01:00

358 lines
No EOL
10 KiB
Rust

//! All constants used in the driver, mostly register addresses
//! Register map: https://arduino.ua/docs/RM-MPU-6000A.pdf
//! Datasheet with WAY more info about interrupts (Revision 3.2) https://www.cdiweb.com/datasheets/invensense/ps-mpu-6000a.pdf
//!
//!
/// Gyro Sensitivity
///
/// Measurements are scaled like this:
/// x * range/2**(resolution-1) or x / (2**(resolution-1) / range)
/// Sources:
/// * https://www.nxp.com/docs/en/application-note/AN3461.pdf
/// * https://theccontinuum.com/2012/09/24/arduino-imu-pitch-roll-from-accelerometer/
/// * https://makersportal.com/blog/2019/8/17/arduino-mpu6050-high-frequency-accelerometer-and-gyroscope-data-saver#accel_test
/// * https://github.com/kriswiner/MPU6050/wiki/2014-Invensense-Developer%27s-Conference
/// * rust MPU9250 driver on github
pub const GYRO_SENS: (f32, f32, f32, f32) = (131., 65.5, 32.8, 16.4);
/// Accelerometer Sensitivity
///
/// Measurements are scaled like this:
/// x * range/2**(resolution-1) or x / (2**(resolution-1) / range)
/// Sources:
/// * https://www.nxp.com/docs/en/application-note/AN3461.pdf
/// * https://theccontinuum.com/2012/09/24/arduino-imu-pitch-roll-from-accelerometer/
/// * https://makersportal.com/blog/2019/8/17/arduino-mpu6050-high-frequency-accelerometer-and-gyroscope-data-saver#accel_test
/// * https://github.com/kriswiner/MPU6050/wiki/2014-Invensense-Developer%27s-Conference
/// * rust MPU9250 driver on github
pub const ACCEL_SENS: (f32, f32, f32, f32) = (16384., 8192., 4096., 2048.);
/// Temperature Offset
pub const TEMP_OFFSET: f32 = 36.53;
/// Temperature Sensitivity
pub const TEMP_SENSITIVITY: f32 = 340.;
#[allow(non_camel_case_types)]
#[derive(Copy, Clone, Debug)]
pub struct Specs;
impl Specs {
// pub const ACCEL_SELF_TEST_MIN: u8 = -14;
pub const ACCEL_SELF_TEST_MAX: u8 = 14;
}
#[allow(non_camel_case_types)]
#[derive(Copy, Clone, Debug)]
/// Register addresses
pub enum Registers {
/// High Byte Register Gyro x orientation
GYRO_REGX_H = 0x43,
/// High Byte Register Gyro y orientation
GYRO_REGY_H = 0x45,
/// High Byte Register Gyro z orientation
GYRO_REGZ_H = 0x47,
/// High Byte Register Calc roll
ACC_REGX_H = 0x3b,
/// High Byte Register Calc pitch
ACC_REGY_H = 0x3d,
/// High Byte Register Calc yaw
ACC_REGZ_H = 0x3f,
/// High Byte Register Temperature
TEMP_OUT_H = 0x41,
//
}
/// Slave address of Mpu6050
pub const SLAVE_ADDR: u8 = 0x68;
/// Internal register to check slave addr
pub const WHOAMI: u8 = 0x75;
/// Motion Threshold Register
pub const MOT_THR: u8 = 0x1F;
/// Motion Duration Detection Register
pub const MOT_DUR: u8 = 0x20;
/// Describes a bit block from bit number 'bit' to 'bit'+'length'
pub struct BitBlock {
pub bit: u8,
pub length: u8
}
impl Registers {
pub fn addr(&self) -> u8 {
*self as u8
}
}
#[allow(non_camel_case_types)]
#[derive(Copy, Clone, Debug)]
/// Register 26: Configuration (DLPF, External signal)
pub struct CONFIG;
impl CONFIG {
/// Base Address
pub const ADDR: u8 = 0x1a;
/// external Frame Synchronisation (FSYNC)
pub const EXT_SYNC_SET: BitBlock = BitBlock { bit: 5, length: 3};
/// Digital Low Pass Filter (DLPF) config
pub const DLPF_CFG: BitBlock = BitBlock { bit: 2, length: 3};
}
#[allow(non_camel_case_types)]
#[derive(Copy, Clone, Debug)]
/// Register 27: Gyro Config
pub struct GYRO_CONFIG;
impl GYRO_CONFIG {
pub const ADDR: u8 = 0x1b;
/// Gyro x axis self test bit
pub const XG_ST: u8 = 7;
/// Gyro y axis self test bit
pub const YG_ST: u8 = 6;
/// Gyro z axis self test bit
pub const ZG_ST: u8 = 5;
/// Gyro Config FS_SEL
pub const FS_SEL: BitBlock = BitBlock { bit: 4, length: 2 };
}
#[allow(non_camel_case_types)]
#[derive(Copy, Clone, Debug)]
/// Register 28: Accel Config
pub struct ACCEL_CONFIG;
impl ACCEL_CONFIG {
/// Base Address
pub const ADDR: u8 = 0x1c;
/// Accel x axis self test bit
pub const XA_ST: u8 = 7;
/// Accel y axis self test bit
pub const YA_ST: u8 = 6;
/// Accel z axis self test bit
pub const ZA_ST: u8 = 5;
/// Accel Config FS_SEL
pub const FS_SEL: BitBlock = BitBlock { bit: 4, length: 2};
/// Accel Config ACCEL_HPF
pub const ACCEL_HPF: BitBlock = BitBlock { bit: 2, length: 3};
}
#[allow(non_camel_case_types)]
#[derive(Copy, Clone, Debug)]
/// Register 55: INT Pin / Bypass Enable Configuration
pub struct INT_PIN_CFG;
impl INT_PIN_CFG {
/// Base Address
pub const ADDR: u8 = 0x37;
/// INT pin logic level
pub const INT_LEVEL: u8 = 7;
/// INT pin config
pub const INT_OPEN: u8 = 6;
/// Pulse (length)
pub const LATCH_INT_EN: u8 = 5;
/// INT clear conditions
pub const INT_RD_CLEAR: u8 = 4;
/// FSYNC PIN logic level
pub const FSYNC_INT_LEVEL: u8 = 3;
/// FSYNC PIN config
pub const FSYNC_INT_EN: u8 = 2;
/// i2c access/bypass
pub const I2C_BYPASS_EN: u8 = 1;
/// enable/disable reference clock output
pub const CLKOUT_EN: u8 = 0;
}
#[allow(non_camel_case_types)]
#[derive(Copy, Clone, Debug)]
/// Register 56: Interrupt Status
pub struct INT_ENABLE;
impl INT_ENABLE {
/// Base Address
pub const ADDR: u8 = 0x38;
/// Generate interrupt Free Fall Detection
pub const FF_EN: u8 = 7;
/// Generate interrupt with Motion Detected
pub const MOT_EN: u8 = 6;
/// Generate iterrrupt when Zero Motion Detection
pub const ZMOT_EN: u8 = 5;
/// Generate iterrupt when FIFO buffer overflow
pub const FIFO_OFLOW_END: u8 = 4;
/// this bit enables any of the I2C Masterinterrupt sources to generate an interrupt
pub const I2C_MST_INT_EN: u8 = 3;
/// enables Data Ready interrupt, each time a write operation to all sensor registers completed
pub const DATA_RDY_EN: u8 = 0;
}
#[allow(non_camel_case_types)]
#[derive(Copy, Clone, Debug)]
/// Register 58: Interrupt Status
pub struct INT_STATUS;
impl INT_STATUS {
/// Base Address
pub const ADDR: u8 = 0x3a;
/// Free Fall Interrupt
pub const FF_INT: u8 = 7;
/// Motion Detection Interrupt
pub const MOT_INT: u8 = 6;
/// Zero Motion Detection Interrupt
pub const ZMOT_INT: u8 = 5;
/// FIFO buffer overflow
pub const FIFO_OFLOW_INT: u8 = 4;
/// i2c master interrupt has been generated
pub const I2C_MSF_INT: u8 = 3;
/// Data is ready
pub const DATA_RDY_INT: u8 = 0;
}
#[allow(non_camel_case_types)]
#[derive(Copy, Clone, Debug)]
/// Register 97: Motion Detection Status
pub struct MOT_DETECT_STATUS;
impl MOT_DETECT_STATUS {
/// Base Address
pub const ADDR: u8 = 0x61;
/// motion in the negative X axis has generated a Motion detection interrupt
pub const MOT_XNEG: u8 = 7;
/// motion in the positive X axis has generated a Motion detection interrupt
pub const MOT_XPOS: u8 = 6;
/// motion in the negative Y axis has generated a Motion detection interrupt
pub const MOT_YNEG: u8 = 5;
/// motion in the positive Y axis has generated a Motion detection interrupt
pub const MOT_YPOS: u8 = 4;
/// motion in the negative Z axis has generated a Motion detection interrupt.
pub const MOT_ZNEG: u8 = 3;
/// motion in the positive Z axis has generated a Motion detection interrupt
pub const MOT_ZPOS: u8 = 2;
/// Zero Motion detection interrupt is generated
pub const MOT_ZRMOT: u8 = 0;
}
#[allow(non_camel_case_types)]
#[derive(Copy, Clone, Debug)]
/// Register 105: Motion Detection Control
pub struct MOT_DETECT_CONTROL;
impl MOT_DETECT_CONTROL {
/// Base Address
pub const ADDR: u8 = 0x69;
/// Additional delay
pub const ACCEL_ON_DELAY: BitBlock = BitBlock { bit: 5, length: 2};
/// Free Fall count
pub const FF_COUNT: BitBlock = BitBlock { bit: 3, length: 2};
/// Motion Detection cound
pub const MOT_COUNT: BitBlock = BitBlock { bit: 1, length: 2};
}
#[allow(non_camel_case_types)]
#[derive(Copy, Clone, Debug)]
/// Register 107: Power Management 1
pub struct PWR_MGMT_1;
impl PWR_MGMT_1 {
/// Base Address
pub const ADDR: u8 = 0x6b;
/// Device Reset bit
pub const DEVICE_RESET: u8 = 7;
/// Sleep mode bit (Should be called "Low Power", doesn't actually sleep)
pub const SLEEP: u8 = 6;
/// Cycle bit for wake operations
pub const CYCLE: u8 = 5;
/// Temperature sensor enable/disable bit
pub const TEMP_DIS: u8 = 3;
/// Clock Control
pub const CLKSEL: BitBlock = BitBlock { bit: 2, length: 3 };
}
#[allow(non_camel_case_types)]
#[derive(Copy, Clone, Debug)]
/// Register 107: Power Management 2
pub struct PWR_MGMT_2;
impl PWR_MGMT_2 {
/// Base Address
pub const ADDR: u8 = 0x6c;
/// Wake up frequency
pub const LP_WAKE_CTRL: BitBlock = BitBlock { bit: 7, length: 2};
/// disable accel axis x
pub const STBY_XA: u8 = 5;
/// disable accel axis y
pub const STBY_YA: u8 = 4;
/// disable accel axis z
pub const STBY_ZA: u8 = 3;
/// disable gyro axis x
pub const STBY_XG: u8 = 2;
/// disable gyro axis y
pub const STBY_YG: u8 = 1;
/// disable gyro axis z
pub const STBY_ZG: u8 = 0;
}
#[allow(non_camel_case_types)]
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
/// Wake values
pub enum LP_WAKE_CTRL {
_1P25 = 0,
_2P5,
_5,
_10,
}
#[allow(non_camel_case_types)]
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
/// Accelerometer High Pass Filter Values
pub enum ACCEL_HPF {
_RESET = 0,
_5 = 1,
_2P5 = 2,
_1P25 = 3,
_0P63 = 4,
_HOLD = 7
}
impl From<u8> for ACCEL_HPF {
fn from(range: u8) -> Self
{
match range {
0 => ACCEL_HPF::_RESET,
1 => ACCEL_HPF::_5,
2 => ACCEL_HPF::_2P5,
3 => ACCEL_HPF::_1P25,
4 => ACCEL_HPF::_0P63,
7 => ACCEL_HPF::_HOLD,
_ => ACCEL_HPF::_RESET,
}
}
}
#[allow(non_camel_case_types)]
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
/// Clock Source Select Values
pub enum CLKSEL {
OSCILL = 0,
GXAXIS = 1,
GYAXIS = 2,
GZAXIS = 3,
EXT_32p7 = 4,
EXT_19P2 = 5,
RESERV = 6,
STOP = 7,
}
impl From<u8> for CLKSEL {
fn from(clk: u8) -> Self {
match clk {
0 => CLKSEL::OSCILL,
1 => CLKSEL::GXAXIS,
2 => CLKSEL::GYAXIS,
3 => CLKSEL::GZAXIS,
4 => CLKSEL::EXT_32p7,
5 => CLKSEL::EXT_19P2,
6 => CLKSEL::RESERV,
7 => CLKSEL::STOP,
_ => CLKSEL::GXAXIS
}
}
}