1#![deny(missing_docs)]
10#![deny(warnings)]
11#![no_std]
12#![forbid(unsafe_code)]
13
14mod reg;
15
16use core::fmt::Debug;
17use core::marker::PhantomData;
18
19#[cfg(feature = "out_f32")]
20pub use accelerometer::vector::F32x3;
21pub use accelerometer::vector::I16x3;
22pub use accelerometer::{Accelerometer, Error, ErrorKind, RawAccelerometer};
23use cast::u16;
24#[cfg(feature = "out_f32")]
25use cast::{f32, i16};
26use embedded_hal as hal;
27use hal::i2c::I2c;
28#[cfg(feature = "out_f32")]
29use num_traits::FromPrimitive;
30
31use crate::reg::*;
32pub use crate::reg::{Aoi6d, FifoMode, FullScale, Mode, Odr};
33
34pub enum SlaveAddr {
36 Default,
38 Alternative(bool),
40}
41
42impl SlaveAddr {
43 fn addr(self) -> u8 {
44 match self {
45 SlaveAddr::Default => I2C_SAD,
46 SlaveAddr::Alternative(a0) => I2C_SAD | a0 as u8,
47 }
48 }
49}
50
51#[derive(Debug)]
54pub struct DataStatus {
55 pub zyxor: bool,
57 pub xyzor: (bool, bool, bool),
59 pub zyxda: bool,
61 pub xyzda: (bool, bool, bool),
63}
64
65pub struct Lis2dh12<I2C> {
67 i2c: I2C,
69 addr: u8,
71 #[cfg(feature = "out_f32")]
73 fs: FullScale,
74}
75
76#[derive(Debug)]
78pub enum AddrDetectionError<I2cError: Debug> {
79 I2c(I2cError),
81 InvalidDeviceId,
83}
84
85impl<I2cError: Debug> From<I2cError> for AddrDetectionError<I2cError> {
86 fn from(value: I2cError) -> Self {
87 AddrDetectionError::I2c(value)
88 }
89}
90
91pub fn detect_i2c_addr<I2C: I2c>(
94 i2c: &mut I2C,
95) -> Result<SlaveAddr, AddrDetectionError<I2C::Error>> {
96 let mut buf = [0u8];
97 let write_buf = &[reg::Register::WHO_AM_I.addr()];
98 match i2c.write_read(reg::I2C_SAD | 0b1, write_buf, &mut buf) {
99 Ok(_) => {
100 if buf[0] == reg::DEVICE_ID {
101 return Ok(SlaveAddr::Alternative(true));
102 }
103 Err(AddrDetectionError::InvalidDeviceId)
104 }
105 Err(_) => {
106 let result = i2c.write_read(reg::I2C_SAD, write_buf, &mut buf);
107 if result.is_ok() {
108 if buf[0] == reg::DEVICE_ID {
109 return Ok(SlaveAddr::Default);
110 } else {
111 return Err(AddrDetectionError::InvalidDeviceId);
112 }
113 }
114 Err(result.unwrap_err().into())
115 }
116 }
117}
118
119pub struct Int<'a, REG, I2C> {
121 dev: &'a mut Lis2dh12<I2C>,
122 reg: PhantomData<REG>,
123}
124
125impl<I2C: I2c> Lis2dh12<I2C> {
126 pub fn new(i2c: I2C, addr: SlaveAddr) -> Result<Self, Error<I2C::Error>> {
128 let mut dev = Self {
129 i2c,
130 addr: addr.addr(),
131 #[cfg(feature = "out_f32")]
132 fs: FullScale::G2,
133 };
134
135 if dev.get_device_id()? != DEVICE_ID {
137 ErrorKind::Device.err()?;
138 }
139
140 Ok(dev)
141 }
142
143 pub fn destroy(self) -> I2C {
145 self.i2c
146 }
147
148 pub fn get_device_id(&mut self) -> Result<u8, Error<I2C::Error>> {
150 self.read_reg(Register::WHO_AM_I).map_err(Into::into)
151 }
152
153 pub fn set_mode(&mut self, mode: Mode) -> Result<(), Error<I2C::Error>> {
157 match mode {
158 Mode::LowPower => {
159 self.reg_reset_bits(Register::CTRL_REG4, HR)?;
160 self.reg_set_bits(Register::CTRL_REG1, LPen)?;
161 }
162 Mode::Normal => {
163 self.reg_reset_bits(Register::CTRL_REG1, LPen)?;
164 self.reg_reset_bits(Register::CTRL_REG4, HR)?;
165 }
166 Mode::HighResolution => {
167 self.reg_reset_bits(Register::CTRL_REG1, LPen)?;
168 self.reg_set_bits(Register::CTRL_REG4, HR)?;
169 }
170 }
171 Ok(())
172 }
173
174 pub fn set_odr(&mut self, odr: Odr) -> Result<(), Error<I2C::Error>> {
177 self.modify_reg(Register::CTRL_REG1, |v| {
178 (v & !ODR_MASK) | ((odr as u8) << 4)
179 })?;
180 if let Odr::PowerDown = odr {
184 self.get_ref()?;
185 }
186 Ok(())
187 }
188
189 pub fn enable_axis(&mut self, (x, y, z): (bool, bool, bool)) -> Result<(), Error<I2C::Error>> {
192 self.modify_reg(Register::CTRL_REG1, |mut v| {
193 v &= !(Xen | Yen | Zen); v |= if x { Xen } else { 0 };
195 v |= if y { Yen } else { 0 };
196 v |= if z { Zen } else { 0 };
197 v
198 })?;
199 Ok(())
200 }
201
202 pub fn enable_hp_filter(
204 &mut self,
205 click: bool,
206 ia2: bool,
207 ia1: bool,
208 ) -> Result<(), Error<I2C::Error>> {
209 self.modify_reg(Register::CTRL_REG2, |mut v| {
210 v &= !(HPCLICK | HP_IA2 | HP_IA1); v |= if click { HPCLICK } else { 0 };
212 v |= if ia2 { HP_IA2 } else { 0 };
213 v |= if ia1 { HP_IA1 } else { 0 };
214 v
215 })?;
216 Ok(())
217 }
218
219 pub fn enable_i1_click(&mut self, enable: bool) -> Result<(), Error<I2C::Error>> {
222 self.reg_xset_bits(Register::CTRL_REG3, I1_CLICK, enable)?;
223 Ok(())
224 }
225
226 pub fn enable_i1_ia1(&mut self, enable: bool) -> Result<(), Error<I2C::Error>> {
229 self.reg_xset_bits(Register::CTRL_REG3, I1_IA1, enable)?;
230 Ok(())
231 }
232
233 pub fn enable_i1_ia2(&mut self, enable: bool) -> Result<(), Error<I2C::Error>> {
236 self.reg_xset_bits(Register::CTRL_REG3, I1_IA2, enable)?;
237 Ok(())
238 }
239
240 pub fn enable_i1_zyxda(&mut self, enable: bool) -> Result<(), Error<I2C::Error>> {
243 self.reg_xset_bits(Register::CTRL_REG3, I1_ZYXDA, enable)?;
244 Ok(())
245 }
246
247 pub fn enable_i1_wtm(&mut self, enable: bool) -> Result<(), Error<I2C::Error>> {
250 self.reg_xset_bits(Register::CTRL_REG3, I1_WTM, enable)?;
251 Ok(())
252 }
253
254 pub fn get_stored_samples(&mut self) -> Result<u8, Error<I2C::Error>> {
256 let value = self.read_reg(Register::FIFO_SRC_REG)?;
257 Ok(value & FSS)
258 }
259
260 pub fn enable_i1_overrun(&mut self, enable: bool) -> Result<(), Error<I2C::Error>> {
263 self.reg_xset_bits(Register::CTRL_REG3, I1_OVERRUN, enable)?;
264 Ok(())
265 }
266
267 pub fn set_bdu(&mut self, bdu: bool) -> Result<(), Error<I2C::Error>> {
270 self.reg_xset_bits(Register::CTRL_REG4, BDU, bdu)?;
271 Ok(())
272 }
273
274 pub fn set_fs(&mut self, fs: FullScale) -> Result<(), Error<I2C::Error>> {
277 self.modify_reg(Register::CTRL_REG4, |v| (v & !FS_MASK) | ((fs as u8) << 4))?;
278 #[cfg(feature = "out_f32")]
279 {
280 self.fs = fs;
281 }
282 Ok(())
283 }
284
285 pub fn reboot(&mut self, reboot: bool) -> Result<(), Error<I2C::Error>> {
288 self.reg_xset_bits(Register::CTRL_REG5, BOOT, reboot)?;
289 Ok(())
290 }
291
292 pub fn in_boot(&mut self) -> Result<bool, Error<I2C::Error>> {
295 let reg = self.read_reg(Register::CTRL_REG5)?;
296 Ok((reg & BOOT) != 0)
297 }
298
299 pub fn enable_fifo(&mut self, enable: bool) -> Result<(), Error<I2C::Error>> {
302 self.reg_xset_bits(Register::CTRL_REG5, FIFO_EN, enable)?;
303 Ok(())
304 }
305
306 pub fn enable_lir_int1(&mut self, latch: bool) -> Result<(), Error<I2C::Error>> {
310 self.reg_xset_bits(Register::CTRL_REG5, LIR_INT1, latch)?;
311 Ok(())
312 }
313
314 pub fn enable_d4d_int1(&mut self, enable: bool) -> Result<(), Error<I2C::Error>> {
318 self.reg_xset_bits(Register::CTRL_REG5, D4D_INT1, enable)?;
319 Ok(())
320 }
321
322 pub fn enable_lir_int2(&mut self, latch: bool) -> Result<(), Error<I2C::Error>> {
326 self.reg_xset_bits(Register::CTRL_REG5, LIR_INT2, latch)?;
327 Ok(())
328 }
329
330 pub fn enable_d4d_int2(&mut self, enable: bool) -> Result<(), Error<I2C::Error>> {
334 self.reg_xset_bits(Register::CTRL_REG5, D4D_INT2, enable)?;
335 Ok(())
336 }
337
338 pub fn enable_i2_click(&mut self, enable: bool) -> Result<(), Error<I2C::Error>> {
341 self.reg_xset_bits(Register::CTRL_REG6, I2_CLICK, enable)?;
342 Ok(())
343 }
344
345 pub fn enable_i2_ia1(&mut self, enable: bool) -> Result<(), Error<I2C::Error>> {
348 self.reg_xset_bits(Register::CTRL_REG6, I2_IA1, enable)?;
349 Ok(())
350 }
351
352 pub fn enable_i2_ia2(&mut self, enable: bool) -> Result<(), Error<I2C::Error>> {
355 self.reg_xset_bits(Register::CTRL_REG6, I2_IA2, enable)?;
356 Ok(())
357 }
358
359 pub fn enable_i2_boot(&mut self, enable: bool) -> Result<(), Error<I2C::Error>> {
362 self.reg_xset_bits(Register::CTRL_REG6, I2_BOOT, enable)?;
363 Ok(())
364 }
365
366 pub fn enable_i2_act(&mut self, enable: bool) -> Result<(), Error<I2C::Error>> {
369 self.reg_xset_bits(Register::CTRL_REG6, I2_ACT, enable)?;
370 Ok(())
371 }
372
373 pub fn set_int_polarity(&mut self, active_low: bool) -> Result<(), Error<I2C::Error>> {
376 self.reg_xset_bits(Register::CTRL_REG6, INT_POLARITY, active_low)?;
377 Ok(())
378 }
379
380 pub fn get_status(&mut self) -> Result<DataStatus, Error<I2C::Error>> {
384 let reg = self.read_reg(Register::STATUS_REG)?;
385 Ok(DataStatus {
386 zyxor: (reg & ZYXOR) != 0,
387 xyzor: ((reg & XOR) != 0, (reg & YOR) != 0, (reg & ZOR) != 0),
388 zyxda: (reg & ZYXDA) != 0,
389 xyzda: ((reg & XDA) != 0, (reg & YDA) != 0, (reg & ZDA) != 0),
390 })
391 }
392
393 pub fn set_fm(&mut self, fm: FifoMode) -> Result<(), Error<I2C::Error>> {
396 self.modify_reg(Register::FIFO_CTRL_REG, |v| {
397 (v & !FM_MASK) | ((fm as u8) << 6)
398 })?;
399 Ok(())
400 }
401
402 pub fn set_fth(&mut self, fth: u8) -> Result<(), Error<I2C::Error>> {
405 self.modify_reg(Register::FIFO_CTRL_REG, |v| {
406 (v & !FTH_MASK) | (fth & FTH_MASK)
407 })?;
408 Ok(())
409 }
410
411 pub fn disable_click(&mut self) -> Result<(), Error<I2C::Error>> {
414 self.write_reg(Register::CLICK_CFG, 0x00)?;
415 Ok(())
416 }
417
418 pub fn enable_double_click(
421 &mut self,
422 (x, y, z): (bool, bool, bool),
423 ) -> Result<(), Error<I2C::Error>> {
424 self.modify_reg(Register::CLICK_CFG, |mut v| {
425 v &= !(XD | YD | ZD); v |= if x { XD } else { 0 };
427 v |= if y { YD } else { 0 };
428 v |= if z { ZD } else { 0 };
429 v
430 })?;
431 Ok(())
432 }
433
434 pub fn enable_single_click(
437 &mut self,
438 (x, y, z): (bool, bool, bool),
439 ) -> Result<(), Error<I2C::Error>> {
440 self.modify_reg(Register::CLICK_CFG, |mut v| {
441 v &= !(XS | YS | ZS); v |= if x { XS } else { 0 };
443 v |= if y { YS } else { 0 };
444 v |= if z { ZS } else { 0 };
445 v
446 })?;
447 Ok(())
448 }
449
450 #[allow(clippy::type_complexity)]
453 pub fn get_click_src(
454 &mut self,
455 ) -> Result<Option<((bool, bool), bool, (bool, bool, bool))>, Error<I2C::Error>> {
456 let reg = self.read_reg(Register::CLICK_SRC)?;
457 if (reg & IA) != 0 {
458 Ok(Some((
459 ((reg & DClick) != 0, (reg & SClick) != 0),
460 (reg & Sign) != 0,
461 ((reg & X) != 0, (reg & Y) != 0, (reg & Z) != 0),
462 )))
463 } else {
464 Ok(None)
465 }
466 }
467
468 pub fn enable_lir_click(&mut self, latch: bool) -> Result<(), Error<I2C::Error>> {
474 self.reg_xset_bits(Register::CLICK_THS, LIR_Click, latch)?;
475 Ok(())
476 }
477
478 pub fn set_click_ths(&mut self, ths: u8) -> Result<(), Error<I2C::Error>> {
481 self.write_reg(Register::CLICK_THS, ths & THS_MASK)?;
482 Ok(())
483 }
484
485 #[cfg(feature = "out_f32")]
488 pub fn set_click_thsf(&mut self, ths: f32) -> Result<(), Error<I2C::Error>> {
489 self.set_click_ths(self.fs.convert_ths_f32tou8(ths))
490 }
491
492 pub fn set_time_limit(&mut self, tli: u8) -> Result<(), Error<I2C::Error>> {
495 self.write_reg(Register::TIME_LIMIT, tli & TLI_MASK)?;
496 Ok(())
497 }
498
499 pub fn set_time_latency(&mut self, tla: u8) -> Result<(), Error<I2C::Error>> {
502 self.write_reg(Register::TIME_LATENCY, tla)?;
503 Ok(())
504 }
505
506 pub fn set_time_window(&mut self, tw: u8) -> Result<(), Error<I2C::Error>> {
509 self.write_reg(Register::TIME_WINDOW, tw)?;
510 Ok(())
511 }
512
513 pub fn set_act_ths(&mut self, ths: u8) -> Result<(), Error<I2C::Error>> {
516 self.write_reg(Register::ACT_THS, ths & Acth_MASK)?;
517 Ok(())
518 }
519
520 #[cfg(feature = "out_f32")]
523 pub fn set_act_thsf(&mut self, ths: f32) -> Result<(), Error<I2C::Error>> {
524 self.set_act_ths(self.fs.convert_ths_f32tou8(ths))
525 }
526
527 pub fn set_act_dur(&mut self, d: u8) -> Result<(), Error<I2C::Error>> {
530 self.write_reg(Register::ACT_DUR, d)?;
531 Ok(())
532 }
533
534 pub fn enable_temp(&mut self, enable: bool) -> Result<(), Error<I2C::Error>> {
538 self.reg_xset_bits(Register::TEMP_CFG_REG, TEMP_EN, enable)?;
539 if enable {
540 self.reg_set_bits(Register::CTRL_REG4, BDU)?;
542 }
543 Ok(())
544 }
545
546 pub fn get_temp_status(&mut self) -> Result<(bool, bool), Error<I2C::Error>> {
550 let reg = self.read_reg(Register::STATUS_REG_AUX)?;
551 Ok(((reg & TOR) != 0, (reg & TDA) != 0))
552 }
553
554 pub fn get_temp_out(&mut self) -> Result<(i8, u8), Error<I2C::Error>> {
557 let mut buf = [0u8; 2];
558 self.read_regs(Register::OUT_TEMP_L, &mut buf)?;
559 Ok((buf[1] as i8, buf[0]))
560 }
561
562 #[cfg(feature = "out_f32")]
565 pub fn get_temp_outf(&mut self) -> Result<f32, Error<I2C::Error>> {
566 let (out_h, out_l) = self.get_temp_out()?;
567 let value = (i16(out_h) << 8) | i16(out_l);
569 Ok(25.0 + f32(value) / 256.0)
570 }
571
572 pub fn set_ref(&mut self, reference: u8) -> Result<(), Error<I2C::Error>> {
574 self.write_reg(Register::REFERENCE, reference)?;
575 Ok(())
576 }
577
578 pub fn get_ref(&mut self) -> Result<u8, Error<I2C::Error>> {
580 self.read_reg(Register::REFERENCE).map_err(Into::into)
581 }
582
583 pub fn int1(&mut self) -> Int<Int1Regs, I2C> {
585 Int::new(self)
586 }
587
588 pub fn int2(&mut self) -> Int<Int2Regs, I2C> {
590 Int::new(self)
591 }
592
593 pub fn reset(&mut self) -> Result<(), Error<I2C::Error>> {
595 self.write_reg(Register::CTRL_REG1, CTRL_REG1_DEFAULT)?;
596 self.write_reg(Register::CTRL_REG2, CTRL_REG2_DEFAULT)?;
597 self.write_reg(Register::CTRL_REG3, CTRL_REG3_DEFAULT)?;
598 self.write_reg(Register::CTRL_REG4, CTRL_REG4_DEFAULT)?;
599 self.write_reg(Register::CTRL_REG5, CTRL_REG5_DEFAULT)?;
600 self.write_reg(Register::CTRL_REG6, CTRL_REG6_DEFAULT)?;
601 self.write_reg(Register::INT1_CFG, INT_CFG_DEFAULT)?;
602 self.write_reg(Register::INT2_CFG, INT_CFG_DEFAULT)?;
603 self.write_reg(Register::INT1_THS, INT_THS_DEFAULT)?;
604 self.write_reg(Register::INT2_THS, INT_THS_DEFAULT)?;
605 Ok(())
606 }
607
608 pub fn enable_st0(&mut self, enable: bool) -> Result<(), Error<I2C::Error>> {
610 self.reg_xset_bits(Register::CTRL_REG4, ST0, enable)?;
611 Ok(())
612 }
613
614 pub fn enable_st1(&mut self, enable: bool) -> Result<(), Error<I2C::Error>> {
616 self.reg_xset_bits(Register::CTRL_REG4, ST1, enable)?;
617 Ok(())
618 }
619
620 #[cfg(debug_assertions)]
622 pub fn dump_regs<W>(&mut self, w: &mut W) -> Result<(), Error<I2C::Error>>
623 where
624 W: core::fmt::Write,
625 {
626 writeln!(
627 w,
628 "CTRL_REG1 (20h) = {:#010b}",
629 self.read_reg(Register::CTRL_REG1)?
630 )
631 .unwrap();
632 writeln!(
633 w,
634 "CTRL_REG3 (22h) = {:#010b}",
635 self.read_reg(Register::CTRL_REG3)?
636 )
637 .unwrap();
638 writeln!(
639 w,
640 "CTRL_REG4 (23h) = {:#010b}",
641 self.read_reg(Register::CTRL_REG4)?
642 )
643 .unwrap();
644 writeln!(
645 w,
646 "CTRL_REG5 (24h) = {:#010b}",
647 self.read_reg(Register::CTRL_REG5)?
648 )
649 .unwrap();
650 writeln!(
651 w,
652 "CTRL_REG6 (25h) = {:#010b}",
653 self.read_reg(Register::CTRL_REG6)?
654 )
655 .unwrap();
656 writeln!(
657 w,
658 "INT1_CFG (30h) = {:#010b}",
659 self.read_reg(Register::INT1_CFG)?
660 )
661 .unwrap();
662 writeln!(
663 w,
664 "INT1_THS (32h) = {:#010b}",
665 self.read_reg(Register::INT1_THS)?
666 )
667 .unwrap();
668 writeln!(
669 w,
670 "FIFO_SRC_REG (2Fh) = {:#010b}",
671 self.read_reg(Register::FIFO_SRC_REG)?
672 )
673 .unwrap();
674 writeln!(
675 w,
676 "FIFO_CTRL_REG (2Fh) = {:#010b}",
677 self.read_reg(Register::FIFO_CTRL_REG)?
678 )
679 .unwrap();
680 Ok(())
681 }
682
683 #[inline]
684 fn read_reg(&mut self, reg: Register) -> Result<u8, I2C::Error> {
685 let mut buf = [0u8];
686 self.i2c.write_read(self.addr, &[reg.addr()], &mut buf)?;
687 Ok(buf[0])
688 }
689
690 #[inline]
691 fn read_regs(&mut self, reg: Register, buffer: &mut [u8]) -> Result<(), I2C::Error> {
692 self.i2c
693 .write_read(self.addr, &[reg.addr() | I2C_SUB_MULTI], buffer)
694 }
695
696 #[inline]
697 fn write_reg(&mut self, reg: Register, val: u8) -> Result<(), I2C::Error> {
698 self.i2c.write(self.addr, &[reg.addr(), val])
699 }
700
701 #[inline]
702 fn modify_reg<F>(&mut self, reg: Register, f: F) -> Result<(), I2C::Error>
703 where
704 F: FnOnce(u8) -> u8,
705 {
706 let r = self.read_reg(reg)?;
707 self.write_reg(reg, f(r))?;
708 Ok(())
709 }
710
711 #[inline]
712 fn reg_set_bits(&mut self, reg: Register, bits: u8) -> Result<(), I2C::Error> {
713 self.modify_reg(reg, |v| v | bits)
714 }
715
716 #[inline]
717 fn reg_reset_bits(&mut self, reg: Register, bits: u8) -> Result<(), I2C::Error> {
718 self.modify_reg(reg, |v| v & !bits)
719 }
720
721 #[inline]
722 fn reg_xset_bits(&mut self, reg: Register, bits: u8, set: bool) -> Result<(), I2C::Error> {
723 if set {
724 self.reg_set_bits(reg, bits)
725 } else {
726 self.reg_reset_bits(reg, bits)
727 }
728 }
729}
730
731impl<I2C: I2c> RawAccelerometer<I16x3> for Lis2dh12<I2C> {
732 type Error = I2C::Error;
733
734 fn accel_raw(&mut self) -> Result<I16x3, Error<Self::Error>> {
736 let mut buf = [0u8; 6];
737 self.read_regs(Register::OUT_X_L, &mut buf)?;
738
739 Ok(I16x3::new(
740 (u16(buf[0]) + (u16(buf[1]) << 8)) as i16,
741 (u16(buf[2]) + (u16(buf[3]) << 8)) as i16,
742 (u16(buf[4]) + (u16(buf[5]) << 8)) as i16,
743 ))
744 }
745}
746
747#[cfg(feature = "out_f32")]
748impl<I2C: I2c> Accelerometer for Lis2dh12<I2C> {
749 type Error = I2C::Error;
750
751 fn accel_norm(&mut self) -> Result<F32x3, Error<Self::Error>> {
753 let acc_raw: I16x3 = self.accel_raw()?;
754
755 Ok(F32x3::new(
756 self.fs.convert_out_i16tof32(acc_raw.x),
757 self.fs.convert_out_i16tof32(acc_raw.y),
758 self.fs.convert_out_i16tof32(acc_raw.z),
759 ))
760 }
761
762 fn sample_rate(&mut self) -> Result<f32, Error<Self::Error>> {
764 let creg1 = self.read_reg(Register::CTRL_REG1)?;
765 let rate = match FromPrimitive::from_u8(creg1 >> 4) {
766 Some(Odr::PowerDown) => 0.0,
767 Some(Odr::Hz1) => 1.0,
768 Some(Odr::Hz10) => 10.0,
769 Some(Odr::Hz25) => 25.0,
770 Some(Odr::Hz50) => 50.0,
771 Some(Odr::Hz100) => 100.0,
772 Some(Odr::Hz200) => 200.0,
773 Some(Odr::Hz400) => 400.0,
774 Some(Odr::HighRate0) => 1620.0,
775 Some(Odr::HighRate1) => {
776 if creg1 & LPen == 0 {
777 1344.0
778 } else {
779 5376.0
780 }
781 }
782 None => 0.0,
783 };
784 Ok(rate)
785 }
786}
787
788impl<'a, REG, I2C: I2c> Int<'a, REG, I2C>
789where
790 REG: IntRegs,
791{
792 fn new(dev: &'a mut Lis2dh12<I2C>) -> Self {
793 Self {
794 dev,
795 reg: PhantomData,
796 }
797 }
798
799 pub fn disable(&mut self) -> Result<(), Error<I2C::Error>> {
802 self.dev.write_reg(REG::reg_cfg(), 0x00)?;
803 Ok(())
804 }
805
806 pub fn set_mode(&mut self, mode: Aoi6d) -> Result<(), Error<I2C::Error>> {
809 self.dev
810 .modify_reg(REG::reg_cfg(), |v| (v & !AOI_6D_MASK) | ((mode as u8) << 6))?;
811 Ok(())
812 }
813
814 pub fn enable_high(&mut self, (x, y, z): (bool, bool, bool)) -> Result<(), Error<I2C::Error>> {
817 self.dev.modify_reg(REG::reg_cfg(), |mut v| {
818 v &= !(XHIE | YHIE | ZHIE); v |= if x { XHIE } else { 0 };
820 v |= if y { YHIE } else { 0 };
821 v |= if z { ZHIE } else { 0 };
822 v
823 })?;
824 Ok(())
825 }
826
827 pub fn enable_low(&mut self, (x, y, z): (bool, bool, bool)) -> Result<(), Error<I2C::Error>> {
830 self.dev.modify_reg(REG::reg_cfg(), |mut v| {
831 v &= !(XLIE | YLIE | ZLIE); v |= if x { XLIE } else { 0 };
833 v |= if y { YLIE } else { 0 };
834 v |= if z { ZLIE } else { 0 };
835 v
836 })?;
837 Ok(())
838 }
839
840 #[allow(clippy::type_complexity)]
843 pub fn get_src(
844 &mut self,
845 ) -> Result<Option<((bool, bool), (bool, bool), (bool, bool))>, Error<I2C::Error>> {
846 let reg = self.dev.read_reg(REG::reg_src())?;
847 if (reg & IA) != 0 {
848 Ok(Some((
849 ((reg & XH) != 0, (reg & XL) != 0),
850 ((reg & YH) != 0, (reg & YL) != 0),
851 ((reg & ZH) != 0, (reg & ZL) != 0),
852 )))
853 } else {
854 Ok(None)
855 }
856 }
857
858 pub fn set_ths(&mut self, ths: u8) -> Result<(), Error<I2C::Error>> {
861 self.dev.write_reg(REG::reg_ths(), ths & THS_MASK)?;
862 Ok(())
863 }
864
865 #[cfg(feature = "out_f32")]
868 pub fn set_thsf(&mut self, ths: f32) -> Result<(), Error<I2C::Error>> {
869 self.set_ths(self.dev.fs.convert_ths_f32tou8(ths))
870 }
871
872 pub fn set_duration(&mut self, d: u8) -> Result<(), Error<I2C::Error>> {
875 self.dev.write_reg(REG::reg_duration(), d & D_MASK)?;
876 Ok(())
877 }
878}