1#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
35#[cfg_attr(feature = "defmt", derive(defmt::Format))]
36#[allow(clippy::struct_excessive_bools)]
37pub struct InterruptPinConfig {
38 pub active_low: bool,
40 pub open_drain: bool,
42 pub latch_enabled: bool,
44 pub clear_on_any_read: bool,
46}
47
48impl InterruptPinConfig {
49 pub const fn i2c_default() -> Self {
51 Self {
52 active_low: true,
53 open_drain: true,
54 latch_enabled: true,
55 clear_on_any_read: false,
56 }
57 }
58
59 pub const fn spi_default() -> Self {
61 Self {
62 active_low: false,
63 open_drain: false,
64 latch_enabled: true,
65 clear_on_any_read: false,
66 }
67 }
68}
69
70#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
72#[cfg_attr(feature = "defmt", derive(defmt::Format))]
73#[allow(clippy::struct_excessive_bools)]
74pub struct InterruptConfig {
75 pub raw_data_ready: bool,
77 pub fifo_overflow: bool,
79 pub fifo_watermark: bool,
81 pub wake_on_motion: bool,
83 pub dmp: bool,
85 pub i2c_master: bool,
87 pub pll_ready: bool,
89}
90
91impl InterruptConfig {
92 pub const fn data_ready_only() -> Self {
94 Self {
95 raw_data_ready: true,
96 fifo_overflow: false,
97 fifo_watermark: false,
98 wake_on_motion: false,
99 dmp: false,
100 i2c_master: false,
101 pll_ready: false,
102 }
103 }
104
105 pub const fn fifo_batch() -> Self {
107 Self {
108 raw_data_ready: false,
109 fifo_overflow: true,
110 fifo_watermark: true,
111 wake_on_motion: false,
112 dmp: false,
113 i2c_master: false,
114 pll_ready: false,
115 }
116 }
117
118 pub const fn wake_on_motion_only() -> Self {
120 Self {
121 raw_data_ready: false,
122 fifo_overflow: false,
123 fifo_watermark: false,
124 wake_on_motion: true,
125 dmp: false,
126 i2c_master: false,
127 pll_ready: false,
128 }
129 }
130
131 pub const fn any_enabled(&self) -> bool {
133 self.raw_data_ready
134 || self.fifo_overflow
135 || self.fifo_watermark
136 || self.wake_on_motion
137 || self.dmp
138 || self.i2c_master
139 || self.pll_ready
140 }
141}
142
143#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
145#[cfg_attr(feature = "defmt", derive(defmt::Format))]
146#[allow(clippy::struct_excessive_bools)]
147pub struct InterruptStatus {
148 pub raw_data_ready: bool,
150 pub fifo_overflow: bool,
152 pub fifo_watermark: bool,
154 pub wake_on_motion: bool,
156 pub dmp: bool,
158 pub i2c_master: bool,
160 pub pll_ready: bool,
162}
163
164impl InterruptStatus {
165 pub const fn new() -> Self {
167 Self {
168 raw_data_ready: false,
169 fifo_overflow: false,
170 fifo_watermark: false,
171 wake_on_motion: false,
172 dmp: false,
173 i2c_master: false,
174 pll_ready: false,
175 }
176 }
177
178 pub const fn any_set(&self) -> bool {
180 self.raw_data_ready
181 || self.fifo_overflow
182 || self.fifo_watermark
183 || self.wake_on_motion
184 || self.dmp
185 || self.i2c_master
186 || self.pll_ready
187 }
188
189 pub const fn clear() -> Self {
191 Self::new()
192 }
193
194 pub const fn to_raw(&self) -> u8 {
196 let mut value = 0u8;
197 if self.raw_data_ready {
198 value |= 0x01;
199 }
200 if self.fifo_overflow {
201 value |= 0x02;
202 }
203 if self.fifo_watermark {
204 value |= 0x04;
205 }
206 if self.i2c_master {
207 value |= 0x08;
208 }
209 if self.dmp {
210 value |= 0x10;
211 }
212 if self.pll_ready {
213 value |= 0x20;
214 }
215 if self.wake_on_motion {
216 value |= 0x40;
217 }
218 value
219 }
220}
221
222#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
224#[cfg_attr(feature = "defmt", derive(defmt::Format))]
225pub struct FsyncConfig {
226 pub enable: bool,
228 pub active_low: bool,
230}
231
232#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
234#[cfg_attr(feature = "defmt", derive(defmt::Format))]
235#[allow(clippy::struct_excessive_bools)]
236pub struct DataReadyStatus {
237 pub sensor0_ready: bool,
239 pub sensor1_ready: bool,
241 pub sensor2_ready: bool,
243 pub sensor3_ready: bool,
245}
246
247impl DataReadyStatus {
248 pub const fn new() -> Self {
250 Self {
251 sensor0_ready: false,
252 sensor1_ready: false,
253 sensor2_ready: false,
254 sensor3_ready: false,
255 }
256 }
257
258 pub const fn any_ready(&self) -> bool {
260 self.sensor0_ready || self.sensor1_ready || self.sensor2_ready || self.sensor3_ready
261 }
262}
263
264#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
266#[cfg_attr(feature = "defmt", derive(defmt::Format))]
267pub struct WomStatus {
268 pub x_motion: bool,
270 pub y_motion: bool,
272 pub z_motion: bool,
274}
275
276impl WomStatus {
277 pub const fn new() -> Self {
279 Self {
280 x_motion: false,
281 y_motion: false,
282 z_motion: false,
283 }
284 }
285
286 pub const fn any_motion(&self) -> bool {
288 self.x_motion || self.y_motion || self.z_motion
289 }
290
291 pub const fn motion_count(&self) -> u8 {
293 (self.x_motion as u8) + (self.y_motion as u8) + (self.z_motion as u8)
294 }
295}
296
297#[cfg(test)]
298mod tests {
299 use super::*;
300
301 #[test]
302 fn test_interrupt_pin_config_default() {
303 let config = InterruptPinConfig::default();
304 assert!(!config.active_low);
305 assert!(!config.open_drain);
306 assert!(!config.latch_enabled);
307 }
308
309 #[test]
310 fn test_interrupt_pin_config_i2c() {
311 let config = InterruptPinConfig::i2c_default();
312 assert!(config.active_low);
313 assert!(config.open_drain);
314 assert!(config.latch_enabled);
315 }
316
317 #[test]
318 fn test_interrupt_pin_config_spi() {
319 let config = InterruptPinConfig::spi_default();
320 assert!(!config.active_low);
321 assert!(!config.open_drain);
322 assert!(config.latch_enabled);
323 }
324
325 #[test]
326 fn test_interrupt_config_default() {
327 let config = InterruptConfig::default();
328 assert!(!config.any_enabled());
329 }
330
331 #[test]
332 fn test_interrupt_config_data_ready() {
333 let config = InterruptConfig::data_ready_only();
334 assert!(config.raw_data_ready);
335 assert!(config.any_enabled());
336 assert!(!config.fifo_overflow);
337 }
338
339 #[test]
340 fn test_interrupt_config_fifo() {
341 let config = InterruptConfig::fifo_batch();
342 assert!(!config.raw_data_ready);
343 assert!(config.fifo_overflow);
344 assert!(config.fifo_watermark);
345 assert!(config.any_enabled());
346 }
347
348 #[test]
349 fn test_interrupt_status() {
350 let mut status = InterruptStatus::new();
351 assert!(!status.any_set());
352
353 status.raw_data_ready = true;
354 assert!(status.any_set());
355
356 let status = InterruptStatus::clear();
357 assert!(!status.any_set());
358 }
359
360 #[test]
361 fn test_data_ready_status() {
362 let mut status = DataReadyStatus::new();
363 assert!(!status.any_ready());
364
365 status.sensor0_ready = true;
366 assert!(status.any_ready());
367 }
368
369 #[test]
370 fn test_wom_status() {
371 let mut status = WomStatus::new();
372 assert!(!status.any_motion());
373 assert_eq!(status.motion_count(), 0);
374
375 status.x_motion = true;
376 assert!(status.any_motion());
377 assert_eq!(status.motion_count(), 1);
378
379 status.y_motion = true;
380 assert_eq!(status.motion_count(), 2);
381
382 status.z_motion = true;
383 assert_eq!(status.motion_count(), 3);
384 }
385
386 #[test]
387 fn test_fsync_config_default() {
388 let config = FsyncConfig::default();
389 assert!(!config.enable);
390 assert!(!config.active_low);
391 }
392}