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
//! Various functions related to interrupts
//!
//! TO DO: the INT_SOURCE could be read to a struct, with a single function
//! the struct would have three fields:
//! interrupt_active, low_pressure_event and high_pressure_event, all of them bools
use super::*;
/// Interrupt pin settings
#[derive(Debug)]
pub struct InterruptConfig {
/// configure interrupt pin as active high or active low
pub active_high_or_low: bool,
/// configure interrupt pin as push-pull or open drain
pub pushpull_or_opendrain: bool,
/// configure data signal on the interrupt pin
pub data_signal_config: INT_DRDY,
/// enable FIFO empty flag on interrupt pin
pub enable_fifo_empty: bool,
/// enable FIFO watermark flag on interrupt pin
pub enable_fifo_fth: bool,
/// enable FIFO overrun flag on interrupt pin
pub enable_fifo_overrun: bool,
/// enable data ready signal on interrupt pin
pub enable_data_ready: bool,
/// enable latching interrupt request to INT_SOURCE register
pub enable_latch_interrupt: bool,
/// enable low pressure event on interrupt pin
pub enable_low_event: bool,
/// enable hihg pressure event on interrupt pin
pub enable_high_event: bool,
}
impl Default for InterruptConfig {
fn default() -> Self {
InterruptConfig {
active_high_or_low: false, // active high (CTRL_REG3)
pushpull_or_opendrain: false, // push-pull (CTRL_REG3)
data_signal_config: INT_DRDY::DataSignal, // data signal on INT_DRDY pin (CTRL_REG3)
enable_fifo_empty: false, // disabled (CTRL_REG4)
enable_fifo_fth: false, // disabled (CTRL_REG4)
enable_fifo_overrun: false, // disabled (CTRL_REG4)
enable_data_ready: false, // disabled (CTRL_REG4)
enable_latch_interrupt: false, // inferrupt request not latched (INTERRUPT_CFG)
enable_low_event: false, // disable interrupt request on low pressure event (INTERRUPT_CFG)
enable_high_event: false, // disable interrupt request on low pressure event (INTERRUPT_CFG)
}
}
}
impl InterruptConfig {
/// Returns values to be written to CTRL_REG3, CTRL_REG4 and INTERRUPT_CFG:
fn int_ctrl_reg3(&self) -> u8 {
let mut data = 0u8;
if self.active_high_or_low {
data |= 1 << 7;
}
if self.pushpull_or_opendrain {
data |= 1 << 6;
}
// MUST USE THE ACTUAL u8 VALUE HERE
data |= self.data_signal_config.value();
data
}
fn int_ctrl_reg4(&self) -> u8 {
let mut data = 0u8;
if self.enable_fifo_empty {
data |= 1 << 3;
}
if self.enable_fifo_fth {
data |= 1 << 2;
}
if self.enable_fifo_overrun {
data |= 1 << 1;
}
if self.enable_data_ready {
data |= 1;
}
data
}
fn int_interrupt_cfg(&self) -> u8 {
let mut data = 0u8;
if self.enable_latch_interrupt {
data |= 1 << 2;
}
if self.enable_low_event {
data |= 1 << 1;
}
if self.enable_high_event {
data |= 1;
}
data
}
}
#[derive(Debug)]
/// Contents of the INT_SOURCE register (interrupt active and differential pressure events flags)
pub struct IntSource {
pub interrupt_active: bool,
pub diff_press_low: bool,
pub diff_press_high: bool,
}
impl<T, E> LPS25HB<T>
where
T: Interface<Error = E>,
{
/// Enable interrupts and configure the interrupt pin
pub fn enable_interrupts(
&mut self,
flag: bool,
config: InterruptConfig,
) -> Result<(), T::Error> {
match flag {
true => self.set_register_bit_flag(Registers::CTRL_REG1, Bitmasks::DIFF_EN),
false => self.clear_register_bit_flag(Registers::CTRL_REG1, Bitmasks::DIFF_EN),
}?;
self.interface
.write(Registers::CTRL_REG3.addr(), config.int_ctrl_reg3())?;
self.interface
.write(Registers::CTRL_REG4.addr(), config.int_ctrl_reg4())?;
self.interface
.write(Registers::INTERRUPT_CFG.addr(), config.int_interrupt_cfg())?;
Ok(())
}
// --- THE FOLLOWING SECTION COULD BE REMOVED ---
/*
/// Configuration of the interrupt generation (enabled/disable)
pub fn int_generation_enable(&mut self, flag: bool) -> Result<(), T::Error> {
match flag {
true => self.set_register_bit_flag(Registers::CTRL_REG1, Bitmasks::DIFF_EN),
false => self.clear_register_bit_flag(Registers::CTRL_REG1, Bitmasks::DIFF_EN),
}
}
/// Interrupt request latching to INT_SOURCE
pub fn int_latch_enable(&mut self, flag: bool) -> Result<(), T::Error> {
match flag {
true => self.set_register_bit_flag(Registers::INTERRUPT_CFG, Bitmasks::LIR),
false => self.clear_register_bit_flag(Registers::INTERRUPT_CFG, Bitmasks::LIR),
}
}
/// Enable interrupt on differential pressure low event
pub fn diff_press_low_enable(&mut self, flag: bool) -> Result<(), T::Error> {
match flag {
true => self.set_register_bit_flag(Registers::INTERRUPT_CFG, Bitmasks::PL_E),
false => self.clear_register_bit_flag(Registers::INTERRUPT_CFG, Bitmasks::PL_E),
}
}
/// Enable interrupt on differential pressure high event
pub fn diff_press_high_enable(&mut self, flag: bool) -> Result<(), T::Error> {
match flag {
true => self.set_register_bit_flag(Registers::INTERRUPT_CFG, Bitmasks::PH_E),
false => self.clear_register_bit_flag(Registers::INTERRUPT_CFG, Bitmasks::PH_E),
}
}
/// Data-ready signal on INT_DRDY pin
pub fn data_signal_drdy_enable(&mut self, flag: bool) -> Result<(), T::Error> {
match flag {
true => self.set_register_bit_flag(Registers::CTRL_REG4, Bitmasks::DRDY),
false => self.clear_register_bit_flag(Registers::CTRL_REG4, Bitmasks::DRDY),
}
}
/// Interrupt active high/low (default active high)
pub fn interrupt_pin_active(&mut self, setting: INT_ACTIVE) -> Result<(), T::Error> {
match setting {
INT_ACTIVE::High => {
self.clear_register_bit_flag(Registers::CTRL_REG3, Bitmasks::INT_H_L)
}
INT_ACTIVE::Low => self.set_register_bit_flag(Registers::CTRL_REG3, Bitmasks::INT_H_L),
}
}
/// Interrupt pin configuration: push-pull (default) or open drain
pub fn interrupt_pin_config(&mut self, setting: INT_PIN) -> Result<(), T::Error> {
match setting {
INT_PIN::PushPull => {
self.clear_register_bit_flag(Registers::CTRL_REG3, Bitmasks::PP_OD)
}
INT_PIN::OpenDrain => self.set_register_bit_flag(Registers::CTRL_REG3, Bitmasks::PP_OD),
}
}
/// Configure INT_DRDY pin
pub fn int_drdy_config(&mut self, config: INT_DRDY) -> Result<(), T::Error> {
let mut reg_data = [0u8];
self.interface
.read(Registers::CTRL_REG3.addr(), &mut reg_data)?;
let mut payload = reg_data[0];
payload &= !Bitmasks::INT_S_MASK;
payload |= config.value();
self.interface.write(Registers::CTRL_REG3.addr(), payload)?;
Ok(())
}
*/
// --- END OF THE SECTION THAT COULD BE REMOVED ---
/// Get all the flags from the INT_SOURCE register (NOTE: INT_SOURCE register is cleared by reading it)
pub fn get_int_status(&mut self) -> Result<IntSource, T::Error> {
let status = IntSource {
/// Has any interrupt event been generated? (self clearing)
interrupt_active: self.is_register_bit_flag_high(Registers::INT_SOURCE, Bitmasks::IA)?,
/// Has low differential pressure event been generated? (self clearing)
diff_press_low: self.is_register_bit_flag_high(Registers::INT_SOURCE, Bitmasks::PL)?,
/// Has high differential pressure event been generated? (self clearing)
diff_press_high: self.is_register_bit_flag_high(Registers::INT_SOURCE, Bitmasks::PH)?,
};
Ok(status)
}
// --- THESE FUNCTIONS COULD BE REMOVED ---
/*
/// Has any interrupt event been generated? (self clearing)
pub fn interrupt_active(&mut self) -> Result<bool, T::Error> {
self.is_register_bit_flag_high(Registers::INT_SOURCE, Bitmasks::IA)
}
/// Has low differential pressure event been generated? (self clearing)
pub fn low_pressure_event_occurred(&mut self) -> Result<bool, T::Error> {
self.is_register_bit_flag_high(Registers::INT_SOURCE, Bitmasks::PL)
}
/// Has high differential pressure event been generated? (self clearing)
pub fn high_pressure_event_occurred(&mut self) -> Result<bool, T::Error> {
self.is_register_bit_flag_high(Registers::INT_SOURCE, Bitmasks::PH)
}
*/
}