1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
use core::fmt;
use embedded_hal::blocking::i2c::Write;

use crate::Register;

/// The CTRL3_C register.
///
/// Contains memory reboot, block data update, interruct activation level, push-pull/open-drain selection on INT1 and INT2 pins
/// SPI Serial Interface Mode selection, register address automatically incrementation and software reset
#[derive(Debug)]
pub struct Ctrl3C(u8);

impl fmt::Display for Ctrl3C {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{}", self.0)
    }
}

impl fmt::Binary for Ctrl3C {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{:b}", self.0)
    }
}

impl fmt::LowerHex for Ctrl3C {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        fmt::LowerHex::fmt(&self.0, f)
    }
}

/// Sub-address of the register.
pub const ADDR: u8 = 0x12;

/// Reboots memory content.
///
/// Default value: 0
///
/// (0: normal mode; 1: reboot memory content)
///
/// Note: the accelerometer must be ON. This bit is automatically cleared.
pub const BOOT: u8 = 7;

/// Block Data Update.
///
/// Default value: 0
///
/// (0: continuous update; 1: output registers are not updated until MSB and LSB have been read)
pub const BDU: u8 = 6;

/// Interrupt activation level.
///
/// Default value: 0
///
/// (0: interrupt output pins active high; 1: interrupt output pins active low
pub const H_LACTIVE: u8 = 5;

/// Push-pull/open-drain selection on INT1 and INT2 pins. This bit must be set to '0' when H_LACTIVE is set to '1'.
///
/// Default value: 0
///
/// (0: push-pull mode; 1: open-drain mode)
pub const PP_OD: u8 = 4;

/// SPI Serial Interface Mode selection.
///
/// Default value: 0
///
/// (0: 4-wire interface; 1: 3-wire interface)
pub const SIM: u8 = 3;

/// Register address automatically incremented during a multiple byte access with a serial interface (I²C or SPI).
///
/// Default value: 1
///
/// (0: disabled; 1: enabled)
pub const IF_INC: u8 = 2;

///Software reset.
///
/// Default value: 0
///
///(0: normal mode; 1: reset device)
///
///This bit is automatically cleared.
pub const SW_RESET: u8 = 0;

impl Register for Ctrl3C {}

impl Ctrl3C {
    pub fn new(bits: u8) -> Self {
        Ctrl3C(bits)
    }

    pub fn boot(&mut self) -> bool {
        self.0 & (1 << BOOT) != 0
    }

    pub fn set_boot<I2C>(&mut self, i2c: &mut I2C, value: bool) -> Result<(), I2C::Error>
    where
        I2C: Write,
    {
        self.0 &= !(1 << BOOT);
        self.0 |= u8::from(value) << BOOT;
        self.write(i2c, ADDR, self.0)
    }

    pub fn bdu(&mut self) -> bool {
        self.0 & (1 << BDU) != 0
    }

    pub fn set_bdu<I2C>(&mut self, i2c: &mut I2C, value: bool) -> Result<(), I2C::Error>
    where
        I2C: Write,
    {
        self.0 &= !(1 << BDU);
        self.0 |= (value as u8) << BDU;
        self.write(i2c, ADDR, self.0)
    }

    pub fn sw_reset<I2C>(&mut self, i2c: &mut I2C) -> Result<(), I2C::Error>
    where
        I2C: Write,
    {
        self.0 |= 1 << SW_RESET;
        self.write(i2c, ADDR, self.0)
    }

    pub fn if_inc(&mut self) -> bool {
        self.0 & (1 << IF_INC) != 0
    }

    pub fn set_if_inc<I2C>(&mut self, i2c: &mut I2C, value: bool) -> Result<(), I2C::Error>
    where
        I2C: Write,
    {
        self.0 &= !(1 << IF_INC);
        self.0 |= (value as u8) << IF_INC;
        self.write(i2c, ADDR, self.0)
    }
}