lis3dh_spi/
ctrl_reg_4_value.rs1use crate::enabled_enum::OnOff;
2use num_derive::FromPrimitive;
3use num_traits::FromPrimitive;
4
5#[repr(u8)]
6#[derive(Copy, Clone, Debug, PartialEq)]
7pub enum SpiModeSelection {
8 FourWireInterface,
9 ThreeWireInterface,
10}
11impl Default for SpiModeSelection {
12 fn default() -> Self {
13 SpiModeSelection::FourWireInterface
14 }
15}
16
17const SELF_TEST_BIT_OFFSET: u8 = 1;
18#[repr(u8)]
19#[derive(Copy, Clone, Debug, FromPrimitive, PartialEq)]
20pub enum SelfTest {
21 NormalMode,
22 SelfTest0,
23 SelfTest1,
24}
25impl Default for SelfTest {
26 fn default() -> Self {
27 SelfTest::NormalMode
28 }
29}
30
31const HIGH_RESOLUTION_OUTPUT_MODE_BIT_OFFSET: u8 = 3;
32
33const FULL_SCALE_SELECTION_OUTPUT_MODE_BIT_OFFSET: u8 = 4;
34#[repr(u8)]
35#[derive(Copy, Clone, Debug, FromPrimitive, PartialEq)]
36pub enum FullScaleSelection {
37 Gravity2G,
38 Gravity4G,
39 Gravity8G,
40 Gravity16G,
41}
42impl Default for FullScaleSelection {
43 fn default() -> Self {
44 FullScaleSelection::Gravity2G
45 }
46}
47
48const BLE_SETTING_BIT_OFFSET: u8 = 6;
49#[repr(u8)]
50#[derive(Copy, Clone, Debug, PartialEq)]
51pub enum Endianness {
52 LSBLowerAddress,
53 MSBLowerAddress,
54}
55impl Default for Endianness {
56 fn default() -> Self {
57 Endianness::LSBLowerAddress
58 }
59}
60
61const BDU_SETTING_BIT_OFFSET: u8 = 7;
62#[repr(u8)]
63#[derive(Copy, Clone, Debug, PartialEq)]
64pub enum BlockDataUpdate {
65 ContinuousUpdate,
66 NotUpdated,
67}
68impl Default for BlockDataUpdate {
69 fn default() -> Self {
70 BlockDataUpdate::ContinuousUpdate
71 }
72}
73
74#[derive(Clone, Copy, Default, PartialEq)]
75pub struct CtrlReg4Value {
76 sim: SpiModeSelection,
77 st: SelfTest,
78 hr: OnOff,
79 fs: FullScaleSelection,
80 ble: Endianness,
81 bdu: BlockDataUpdate,
82}
83
84impl CtrlReg4Value {
85 pub(super) fn set_sim(&mut self, sim: SpiModeSelection) {
86 self.sim = sim;
87 }
88
89 pub(super) fn set_st(&mut self, st: SelfTest) {
90 self.st = st;
91 }
92
93 pub(super) fn set_hr(&mut self, hr: OnOff) {
94 self.hr = hr;
95 }
96
97 pub(super) fn set_fs(&mut self, fs: FullScaleSelection) {
98 self.fs = fs;
99 }
100
101 pub(super) fn set_ble(&mut self, ble: Endianness) {
102 self.ble = ble;
103 }
104
105 pub(super) fn set_bdu(&mut self, bdu: BlockDataUpdate) {
106 self.bdu = bdu;
107 }
108
109 pub(super) fn sim(&self) -> SpiModeSelection {
110 self.sim
111 }
112 pub(super) fn st(&self) -> SelfTest {
113 self.st
114 }
115 pub(super) fn hr(&self) -> OnOff {
116 self.hr
117 }
118 pub(super) fn fs(&self) -> FullScaleSelection {
119 self.fs
120 }
121 pub(super) fn ble(&self) -> Endianness {
122 self.ble
123 }
124 pub(super) fn bdu(&self) -> BlockDataUpdate {
125 self.bdu
126 }
127
128 pub(super) fn get_raw_value(&self) -> u8 {
129 (self.bdu as u8) << BDU_SETTING_BIT_OFFSET
130 | (self.ble as u8) << BLE_SETTING_BIT_OFFSET
131 | (self.fs as u8) << FULL_SCALE_SELECTION_OUTPUT_MODE_BIT_OFFSET
132 | (self.hr as u8) << HIGH_RESOLUTION_OUTPUT_MODE_BIT_OFFSET
133 | (self.st as u8) << SELF_TEST_BIT_OFFSET
134 | self.sim as u8
135 }
136 pub(super) fn from_raw_value(value: u8) -> Self {
137 let sim = if value & 1 == 1 {
138 SpiModeSelection::ThreeWireInterface
139 } else {
140 SpiModeSelection::FourWireInterface
141 };
142 let st =
143 SelfTest::from_u8((value & 0b110) >> SELF_TEST_BIT_OFFSET).unwrap();
144 let hr = if (value >> HIGH_RESOLUTION_OUTPUT_MODE_BIT_OFFSET) & 1 == 1 {
145 OnOff::Enabled
146 } else {
147 OnOff::Disabled
148 };
149 let fs = FullScaleSelection::from_u8(
150 (value & 0b0011_0000)
151 >> FULL_SCALE_SELECTION_OUTPUT_MODE_BIT_OFFSET,
152 )
153 .unwrap();
154 let ble = if value >> BLE_SETTING_BIT_OFFSET & 1 == 1 {
155 Endianness::MSBLowerAddress
156 } else {
157 Endianness::LSBLowerAddress
158 };
159 let bdu = if value >> BDU_SETTING_BIT_OFFSET & 1 == 1 {
160 BlockDataUpdate::NotUpdated
161 } else {
162 BlockDataUpdate::ContinuousUpdate
163 };
164 CtrlReg4Value {
165 sim,
166 st,
167 hr,
168 fs,
169 ble,
170 bdu,
171 }
172 }
173}
174
175#[cfg(test)]
176mod test {
177 #[test]
178 fn conversion_from_raw_value_works() {
179 let raw_value = 0b0101_0100_u8;
180 let ctrl_reg_4 = super::CtrlReg4Value::from_raw_value(raw_value);
181 assert_eq!(ctrl_reg_4.st, super::SelfTest::SelfTest1)
182 }
183
184 #[test]
185 fn conversion_to_raw_value_works() {
186 let mut ctrl_reg_value = super::CtrlReg4Value::default();
187
188 ctrl_reg_value.sim = super::SpiModeSelection::ThreeWireInterface;
189 ctrl_reg_value.st = super::SelfTest::SelfTest1;
190 ctrl_reg_value.hr = super::OnOff::Enabled;
191 ctrl_reg_value.fs = super::FullScaleSelection::Gravity8G;
192 ctrl_reg_value.ble = super::Endianness::MSBLowerAddress;
193 assert_eq!(ctrl_reg_value.get_raw_value(), 0b0110_1101);
194 }
195}