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
141
142
143
144
145
146
147
148
149
use core::fmt;

use crate::Register;

/// The CFG_REG_B register
#[derive(Debug)]
pub struct CfgRegB(u8);

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

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

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

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

/// Enables offset cancellation in single measurement mode. The OFF_CANC bit
/// must be set to 1 when enabling offset cancellation in single measurement mode.
///
/// Default value: 0
///
/// (0: offset cancellation in single measurement mode disabled;
/// 1: offset cancellation in single measurement mode enabled)
const OFF_CANC_ONE_SHOT: u8 = 4;

/// If ‘1’, the interrupt block recognition checks data after the hard-iron correction to
/// discover the interrupt.
///
/// Default value: 0
const INT_ON_DATAOFF: u8 = 3;

/// Selects the frequency of the set pulse.
///
/// Default value: 0
///
/// (0: set pulse is released every 63 ODR;
/// 1: set pulse is released only at power-on after PD condition)
const SET_FREQ: u8 = 2;

/// Enables offset cancellation.
///
/// Default value: 0
///
/// (0: offset cancellation disabled; 1: offset cancellation enabled)
const OFF_CANC: u8 = 1;

///Enables low-pass filter.
///
/// Default value: 0
///
///(0: digital filter disabled; 1: digital filter enabled)
const LPF: u8 = 0;

impl Register for CfgRegB {}

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

    pub fn value<I2C>(&mut self, i2c: &mut I2C) -> Result<u8, I2C::Error>
    where
        I2C: embedded_hal::i2c::I2c,
    {
        self.read(i2c, ADDR)
    }

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

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

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

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

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

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

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

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

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

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