#[derive(Debug)]
pub enum Error<CommE> {
Comm(CommE),
InvalidChipId(u8),
}
#[derive(Debug, Clone, Copy)]
#[repr(u8)]
pub enum PowerMode {
Standby = 0b00,
Normal = 0b01,
Forced = 0b10,
Continuous = 0b11,
}
impl PowerMode {
pub fn from_u8(reg: u8) -> Option<Self> {
match reg {
0b00 => Some(PowerMode::Standby),
0b01 => Some(PowerMode::Normal),
0b10 => Some(PowerMode::Forced),
0b11 => Some(PowerMode::Continuous),
_ => None,
}
}
}
#[derive(Debug, Clone, Copy)]
#[repr(u8)]
pub enum Osr {
Osr1 = 0b000,
Osr2 = 0b001,
Osr4 = 0b010,
Osr8 = 0b011,
Osr16 = 0b100,
Osr32 = 0b101,
Osr64 = 0b110,
Osr128 = 0b111,
}
impl Osr {
pub fn from_u8(reg: u8) -> Self {
match reg {
0b000 => Osr::Osr1,
0b001 => Osr::Osr2,
0b010 => Osr::Osr4,
0b011 => Osr::Osr8,
0b100 => Osr::Osr16,
0b101 => Osr::Osr32,
0b110 => Osr::Osr64,
0b111 => Osr::Osr128,
_ => panic!("Invalid OSR value"),
}
}
}
#[derive(Debug, Clone, Copy)]
#[repr(u8)]
pub enum Odr {
Hz240_000 = 0x00,
Hz218_537 = 0x01,
Hz199_111 = 0x02,
Hz179_200 = 0x03,
Hz160_000 = 0x04,
Hz149_333 = 0x05,
Hz140_000 = 0x06,
Hz129_855 = 0x07,
Hz120_000 = 0x08,
Hz110_164 = 0x09,
Hz100_299 = 0x0A,
Hz89_600 = 0x0B,
Hz80_000 = 0x0C,
Hz70_000 = 0x0D,
Hz60_000 = 0x0E,
Hz50_056 = 0x0F,
Hz45_025 = 0x10,
Hz40_000 = 0x11,
Hz35_000 = 0x12,
Hz30_000 = 0x13,
Hz25_005 = 0x14,
Hz20_000 = 0x15,
Hz15_000 = 0x16,
Hz10_000 = 0x17,
Hz5_000 = 0x18,
Hz4_000 = 0x19,
Hz3_000 = 0x1A,
Hz2_000 = 0x1B,
Hz1_000 = 0x1C,
Hz0_500 = 0x1D,
Hz0_250 = 0x1E,
Hz0_125 = 0x1F,
}
impl Odr {
pub fn from_u8(value: u8) -> Option<Self> {
match value {
0x00 => Some(Odr::Hz240_000),
0x01 => Some(Odr::Hz218_537),
0x02 => Some(Odr::Hz199_111),
0x03 => Some(Odr::Hz179_200),
0x04 => Some(Odr::Hz160_000),
0x05 => Some(Odr::Hz149_333),
0x06 => Some(Odr::Hz140_000),
0x07 => Some(Odr::Hz129_855),
0x08 => Some(Odr::Hz120_000),
0x09 => Some(Odr::Hz110_164),
0x0A => Some(Odr::Hz100_299),
0x0B => Some(Odr::Hz89_600),
0x0C => Some(Odr::Hz80_000),
0x0D => Some(Odr::Hz70_000),
0x0E => Some(Odr::Hz60_000),
0x0F => Some(Odr::Hz50_056),
0x10 => Some(Odr::Hz45_025),
0x11 => Some(Odr::Hz40_000),
0x12 => Some(Odr::Hz35_000),
0x13 => Some(Odr::Hz30_000),
0x14 => Some(Odr::Hz25_005),
0x15 => Some(Odr::Hz20_000),
0x16 => Some(Odr::Hz15_000),
0x17 => Some(Odr::Hz10_000),
0x18 => Some(Odr::Hz5_000),
0x19 => Some(Odr::Hz4_000),
0x1A => Some(Odr::Hz3_000),
0x1B => Some(Odr::Hz2_000),
0x1C => Some(Odr::Hz1_000),
0x1D => Some(Odr::Hz0_500),
0x1E => Some(Odr::Hz0_250),
0x1F => Some(Odr::Hz0_125),
_ => None,
}
}
}
pub struct StatusMask;
impl StatusMask {
pub const STATUS_CORE_RDY: u8 = 1 << 0;
pub const STATUS_NVM_RDY: u8 = 1 << 1;
pub const STATUS_NVM_ERR: u8 = 1 << 2;
pub const STATUS_NVM_CMD_ERR: u8 = 1 << 3;
pub const STATUS_BOOT_ERR_CORRECTED: u8 = 1 << 4;
pub const STATUS_CRACK_PASS: u8 = 1 << 7;
}
#[derive(Clone, Debug)]
pub struct Status {
pub core_ready: bool,
pub nvm_ready: bool,
pub nvm_error: bool,
pub nvm_cmd_error: bool,
pub boot_err_corrected: bool,
pub crack_pass: bool,
}
impl Status {
pub fn from_reg(reg: u8) -> Self {
Status {
core_ready: (reg & StatusMask::STATUS_CORE_RDY) != 0,
nvm_ready: (reg & StatusMask::STATUS_NVM_RDY) != 0,
nvm_error: (reg & StatusMask::STATUS_NVM_ERR) != 0,
nvm_cmd_error: (reg & StatusMask::STATUS_NVM_CMD_ERR) != 0,
boot_err_corrected: (reg & StatusMask::STATUS_BOOT_ERR_CORRECTED) != 0,
crack_pass: (reg & StatusMask::STATUS_CRACK_PASS) != 0,
}
}
}
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum IntMode {
Pulsed,
Latched,
}
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum IntPolarity {
ActiveLow,
ActiveHigh,
}
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum IntPinMode {
PushPull,
OpenDrain,
}
pub struct IntConfigMask;
impl IntConfigMask {
pub const PAD_INT_DRV: u8 = 0b11110000;
pub const EN: u8 = 0b00001000;
pub const OD: u8 = 0b00000100;
pub const POL: u8 = 0b00000010;
pub const MODE: u8 = 0b00000001;
}
#[derive(Clone, Debug)]
pub struct IntConfig {
pub pad_int_drv: u8,
pub en: bool,
pub od: IntPinMode,
pub pol: IntPolarity,
pub mode: IntMode,
}
impl IntConfig {
pub fn from_reg(reg: u8) -> Self {
IntConfig {
pad_int_drv: (reg & IntConfigMask::PAD_INT_DRV) >> 4,
en: (reg & IntConfigMask::EN) != 0,
od: match (reg & IntConfigMask::OD) >> 2 {
0x00 => IntPinMode::PushPull,
0x01 => IntPinMode::OpenDrain,
_ => panic!("Invalid INT_OD value"),
},
pol: match (reg & IntConfigMask::POL) >> 1 {
0x00 => IntPolarity::ActiveLow,
0x01 => IntPolarity::ActiveHigh,
_ => panic!("Invalid POL value"),
},
mode: match reg & IntConfigMask::MODE {
0x00 => IntMode::Pulsed,
0x01 => IntMode::Latched,
_ => panic!("Invalid MODE value"),
},
}
}
pub fn to_reg(&self) -> u8 {
let pad_int_drv = self.pad_int_drv as u8;
let en = if self.en { 0x01 } else { 0x00 };
let od = self.od as u8;
let pol = self.pol as u8;
let mode = self.mode as u8;
(pad_int_drv & 0b0000_1111) << 4 | en << 3 | od << 2 | pol << 1 | mode
}
}
impl Default for IntConfig {
fn default() -> Self {
IntConfig {
pad_int_drv: 3,
en: false,
od: IntPinMode::PushPull,
pol: IntPolarity::ActiveLow,
mode: IntMode::Pulsed,
}
}
}
#[derive(Clone, Debug)]
pub struct IntStatus {
pub drdy_data_reg: bool,
pub fifo_full: bool,
pub fifo_threshold: bool,
pub oor_pressure: bool,
pub por: bool,
}
impl IntStatus {
pub fn from_reg(reg: u8) -> Self {
IntStatus {
drdy_data_reg: (reg & 0b00000001) != 0,
fifo_full: (reg & 0b00000010) != 0,
fifo_threshold: (reg & 0b00000100) != 0,
oor_pressure: (reg & 0b00001000) != 0,
por: (reg & 0b00010000) != 0,
}
}
pub fn any_interrupt_active(&self) -> bool {
self.drdy_data_reg ||
self.fifo_full ||
self.fifo_threshold ||
self.oor_pressure ||
self.por
}
}
#[derive(Clone, Debug)]
pub struct IntSource {
pub drdy_data_reg_en: bool,
pub fifo_full_en: bool,
pub fifo_threshold_en: bool,
pub oor_p_en: bool,
}
impl IntSource {
pub fn from_reg(reg: u8) -> Self {
IntSource {
drdy_data_reg_en: (reg & 0b00000001) != 0,
fifo_full_en: (reg & 0b00000010) != 0,
fifo_threshold_en: (reg & 0b00000100) != 0,
oor_p_en: (reg & 0b00001000) != 0,
}
}
pub fn to_reg(&self) -> u8 {
(self.drdy_data_reg_en as u8) |
((self.fifo_full_en as u8) << 1) |
((self.fifo_threshold_en as u8) << 2) |
((self.oor_p_en as u8) << 3)
}
pub fn any_interrupt_enabled(&self) -> bool {
self.drdy_data_reg_en ||
self.fifo_full_en ||
self.fifo_threshold_en ||
self.oor_p_en
}
}
impl Default for Status {
fn default() -> Self {
Status {
core_ready: false,
nvm_ready: false,
nvm_error: false,
nvm_cmd_error: false,
boot_err_corrected: false,
crack_pass: false,
}
}
}
impl Default for IntStatus {
fn default() -> Self {
IntStatus {
drdy_data_reg: false,
fifo_full: false,
fifo_threshold: false,
oor_pressure: false,
por: false,
}
}
}
impl Default for IntSource {
fn default() -> Self {
IntSource {
drdy_data_reg_en: false,
fifo_full_en: false,
fifo_threshold_en: false,
oor_p_en: false,
}
}
}
#[derive(Debug, Clone, Copy)]
pub struct OsrConfig {
pub pressure_enable: bool,
pub osr_pressure: Osr,
pub osr_temperature: Osr,
}
pub struct OsrConfigMasks;
impl OsrConfigMasks {
pub const PRESSURE_ENABLE: u8 = 0b0100_0000;
pub const OSR_PRESSURE: u8 = 0b0011_1000;
pub const OSR_TEMPERATURE: u8 = 0b0000_0111;
}
impl OsrConfig {
pub fn from_reg(reg: u8) -> Self {
OsrConfig {
pressure_enable: reg & OsrConfigMasks::PRESSURE_ENABLE != 0,
osr_pressure: Osr::from_u8(reg & OsrConfigMasks::OSR_PRESSURE),
osr_temperature: Osr::from_u8(reg & OsrConfigMasks::OSR_TEMPERATURE),
}
}
pub fn to_reg(&self) -> u8 {
let pressure_enable: u8 = if self.pressure_enable { 0x01 } else { 0x00 };
let osr_pressure: u8 = self.osr_pressure as u8;
let osr_temperature: u8 = self.osr_temperature as u8;
pressure_enable << 6 | osr_pressure << 3 | osr_temperature << 0
}
}
#[derive(Debug, Clone, Copy)]
#[repr(u8)]
pub enum DeepDis {
Enabled,
Disabled,
}
#[derive(Debug, Clone, Copy)]
pub struct OdrConfig {
pub deep_dis: DeepDis,
pub odr: Odr,
pub power_mode: PowerMode,
}
pub struct OdrConfigMasks;
impl OdrConfigMasks {
pub const DEEP_DIS: u8 = 0b1000_0000;
pub const ODR: u8 = 0b0111_1100;
pub const POWER_MODE: u8 = 0b0000_0011;
}
impl OdrConfig {
pub fn from_reg(reg: u8) -> Self {
OdrConfig {
deep_dis: match (reg & OdrConfigMasks::DEEP_DIS) >> 7 {
0x00 => DeepDis::Enabled,
0x01 => DeepDis::Disabled,
_ => panic!("Invalid DEEP_DIS value"),
},
odr: Odr::from_u8((reg & OdrConfigMasks::ODR) >> 2).unwrap(),
power_mode: PowerMode::from_u8(reg & OdrConfigMasks::POWER_MODE).unwrap(),
}
}
pub fn to_reg(&self) -> u8 {
let deep_dis: u8 = match self.deep_dis {
DeepDis::Disabled => 0x01,
DeepDis::Enabled => 0x00,
};
let odr: u8 = self.odr as u8;
let power_mode: u8 = self.power_mode as u8;
deep_dis << 7 | odr << 2 | power_mode << 0
}
}