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
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
//! Various functions related to FIFO
//!
use super::*;
/// FIFO settings
#[derive(Debug)]
pub struct FIFOConfig {
/// Stop on FIFO watermark (enable FIFO watermark use)
pub enable_watermark: bool, // default disabled
/// Enable decimating output pressure to 1Hz with FIFO Mean mode
pub enable_decimating: bool, // default disabled
/// Select FIFO operation mode (see Table 22 for details)
pub fifo_mode: FIFO_MODE, // default Bypass
/// Set the watermark level
pub watermark_level: u8, // default 0
/// Select sample size for FIFO Mean mode running average (see Table 23 for details)
pub fifo_mean_config: FIFO_MEAN, // default 2-sample
}
impl Default for FIFOConfig {
fn default() -> Self {
FIFOConfig {
enable_watermark: false, // disabled
enable_decimating: false, // disabled
fifo_mode: FIFO_MODE::Bypass, // Bypass mode
watermark_level: 32u8, // 0 does not make sense as a default value
fifo_mean_config: FIFO_MEAN::_2sample, // 2 samples
}
}
}
impl FIFOConfig {
/// Returns values to be written to CTRL_REG2 and FIFO_CTRL:
fn f_ctrl_reg2(&self) -> u8 {
let mut data = 0u8;
// THIS RESULT MUST THEN BE COMBINED WITH THE OTHER BIT SETTINGS
if self.enable_watermark {
data |= 1 << 5;
}
if self.enable_decimating {
data |= 1 << 4;
}
data
}
fn f_fifo_ctrl(&self) -> u8 {
let mut data = 0u8;
data |= self.fifo_mode.value();
let wtm = match self.fifo_mode {
FIFO_MODE::FIFO_Mean => self.fifo_mean_config.value(),
_ => self.watermark_level,
};
data |= wtm;
data
}
}
#[derive(Debug)]
/// Contents of the FIFO_STATUS register (threshold reached, overrun, empty, stored data level)
pub struct FifoStatus {
pub fifo_thresh_reached: bool,
pub fifo_overrun: bool,
pub fifo_empty: bool,
pub fifo_level: u8,
}
impl<T, E> LPS25HB<T>
where
T: Interface<Error = E>,
{
/// Enable and configure FIFO
pub fn enable_fifo(&mut self, flag: bool, config: FIFOConfig) -> Result<(), T::Error> {
match flag {
true => self.set_register_bit_flag(Registers::CTRL_REG2, Bitmasks::FIFO_EN),
false => self.clear_register_bit_flag(Registers::CTRL_REG2, Bitmasks::FIFO_EN),
}?;
let mut reg_data = [0u8];
self.interface
.read(Registers::CTRL_REG2.addr(), &mut reg_data)?;
reg_data[0] |= config.f_ctrl_reg2();
self.interface
.write(Registers::CTRL_REG2.addr(), reg_data[0])?;
self.interface
.write(Registers::FIFO_CTRL.addr(), config.f_fifo_ctrl())?;
Ok(())
}
// --- THE FOLLOWING SECTION COULD BE REMOVED ---
/*
/// FIFO enable/disable
pub fn fifo_enable(&mut self, flag: bool) -> Result<(), T::Error> {
match flag {
true => self.set_register_bit_flag(Registers::CTRL_REG2, Bitmasks::FIFO_EN),
false => self.clear_register_bit_flag(Registers::CTRL_REG2, Bitmasks::FIFO_EN),
}
}
/// Select FIFO operation mode (see Table 22 for details)
pub fn fifo_mode_config(&mut self, mode: FIFO_MODE) -> Result<(), T::Error> {
let mut reg_data = [0u8];
self.interface
.read(Registers::FIFO_CTRL.addr(), &mut reg_data)?;
let mut payload = reg_data[0];
payload &= !Bitmasks::F_MODE_MASK;
payload |= mode.value();
self.interface.write(Registers::FIFO_CTRL.addr(), payload)?;
Ok(())
}
/// Select sample size for FIFO Mean mode running average (see Table 23 for details)
pub fn fifo_mean_config(&mut self, sample: FIFO_MEAN) -> Result<(), T::Error> {
let mut reg_data = [0u8];
self.interface
.read(Registers::FIFO_CTRL.addr(), &mut reg_data)?;
let mut payload = reg_data[0];
payload &= !Bitmasks::WTM_POINT_MASK;
payload |= sample.value();
self.interface.write(Registers::FIFO_CTRL.addr(), payload)?;
Ok(())
}
/// Stop on FIFO watermark (enable FIFO watermark use)
pub fn stop_on_fth(&mut self, flag: bool) -> Result<(), T::Error> {
match flag {
true => self.set_register_bit_flag(Registers::CTRL_REG2, Bitmasks::STOP_ON_FTH),
false => self.clear_register_bit_flag(Registers::CTRL_REG2, Bitmasks::STOP_ON_FTH),
}
}
/// Enable decimating output pressure to 1Hz with FIFO Mean mode
pub fn fifo_decimate_enable(&mut self, flag: bool) -> Result<(), T::Error> {
match flag {
true => self.set_register_bit_flag(Registers::CTRL_REG2, Bitmasks::FIFO_MEAN_DEC),
false => self.clear_register_bit_flag(Registers::CTRL_REG2, Bitmasks::FIFO_MEAN_DEC),
}
}
/*
/// Set the watermark level
pub fn set_watermark_level(&mut self, level: u8) -> Result<(), T::Error> {
let wtm: u8 = match level {
// if the input value exceeds the capacity, default to maximum
l if l < 33 => l,
_ => 32,
};
let mut reg_data = [0u8];
self.interface
.read(Registers::FIFO_CTRL.addr(), &mut reg_data)?;
let mut payload = reg_data[0];
payload &= !Bitmasks::WTM_MASK;
payload |= mode.value();
self.interface.write(Registers::FIFO_CTRL.addr(), payload)?;
Ok(())
}
*/
/// FIFO empty flag on INT_DRDY pin
pub fn fifo_empty_drdy_enable(&mut self, flag: bool) -> Result<(), T::Error> {
match flag {
true => self.set_register_bit_flag(Registers::CTRL_REG4, Bitmasks::F_EMPTY),
false => self.clear_register_bit_flag(Registers::CTRL_REG4, Bitmasks::F_EMPTY),
}
}
/// FIFO filled up to threshold (watermark) level on INT_DRDY pin
pub fn fifo_filled_drdy_enable(&mut self, flag: bool) -> Result<(), T::Error> {
match flag {
true => self.set_register_bit_flag(Registers::CTRL_REG4, Bitmasks::F_FTH),
false => self.clear_register_bit_flag(Registers::CTRL_REG4, Bitmasks::F_FTH),
}
}
/// FIFO overrun interrupt on INT_DRDY pin
pub fn fifo_overrun_drdy_enable(&mut self, flag: bool) -> Result<(), T::Error> {
match flag {
true => self.set_register_bit_flag(Registers::CTRL_REG4, Bitmasks::F_OVR),
false => self.clear_register_bit_flag(Registers::CTRL_REG4, Bitmasks::F_OVR),
}
}
*/
// --- END OF THE SECTION THAT COULD BE REMOVED ---
/// Get flags and FIFO level from the FIFO_STATUS register
pub fn get_fifo_status(&mut self) -> Result<FifoStatus, T::Error> {
let status = FifoStatus {
/// Is FIFO filling equal or higher than the threshold?
fifo_thresh_reached: self
.is_register_bit_flag_high(Registers::FIFO_STATUS, Bitmasks::FTH_FIFO)?,
/// Is FIFO full and at least one sample has been overwritten?
fifo_overrun: self.is_register_bit_flag_high(Registers::FIFO_STATUS, Bitmasks::OVR)?,
/// Is FIFO empty?
fifo_empty: self
.is_register_bit_flag_high(Registers::FIFO_STATUS, Bitmasks::EMPTY_FIFO)?,
/// Read FIFO stored data level
fifo_level: self.read_fifo_level()?,
};
Ok(status)
}
// --- THESE FUNCTIONS COULD BE REMOVED ---
/*
/// Is FIFO filling equal or higher than the threshold?
pub fn fifo_threshold_status(&mut self) -> Result<bool, T::Error> {
self.is_register_bit_flag_high(Registers::FIFO_STATUS, Bitmasks::FTH_FIFO)
}
/// Is FIFO full and at least one sample has been overwritten?
pub fn fifo_overrun_status(&mut self) -> Result<bool, T::Error> {
self.is_register_bit_flag_high(Registers::FIFO_STATUS, Bitmasks::OVR)
}
/// Is FIFO empty?
pub fn fifo_empty_status(&mut self) -> Result<bool, T::Error> {
self.is_register_bit_flag_high(Registers::FIFO_STATUS, Bitmasks::EMPTY_FIFO)
}
*/
// --- THIS FUNCTION COULD BE PRIVATE ---
/// Read FIFO stored data level
//pub fn read_fifo_level(&mut self) -> Result<u8, T::Error> {
fn read_fifo_level(&mut self) -> Result<u8, T::Error> {
let mut reg_data = [0u8];
self.interface
.read(Registers::FIFO_STATUS.addr(), &mut reg_data)?;
let fifo_level: u8 = match self.is_register_bit_flag_high(Registers::FIFO_STATUS, Bitmasks::EMPTY_FIFO)? {
true => 0,
false => (reg_data[0] & Bitmasks::FSS_MASK) + 1,
};
Ok(fifo_level)
}
}