lsm6dsv16x_rs/
lib.rs

1#![no_std]
2#![doc = include_str!("../README.md")]
3pub mod prelude;
4pub mod register;
5
6#[cfg(feature = "passthrough")]
7use core::cell::RefCell;
8#[cfg(feature = "passthrough")]
9use core::cell::RefMut;
10use core::fmt::Debug;
11use embedded_hal::delay::DelayNs;
12use embedded_hal::i2c::{I2c, SevenBitAddress};
13use embedded_hal::spi::SpiDevice;
14use half::f16;
15use st_mems_bus::{BusOperation, EmbAdvFunctions, MemBankFunctions, i2c::*};
16
17use prelude::*;
18
19/// Driver for the LSM6DSV16X sensor.
20///
21/// The struct takes a bus and a timer hardware object to write to the
22/// registers.
23/// The bus is generalized over the BusOperation trait, allowing the use
24/// of I2C or SPI protocols; this also allows the user to implement sharing
25/// techniques to share the underlying bus.
26pub struct Lsm6dsv16x<B, T> {
27    /// The bus driver.
28    pub bus: B,
29    pub tim: T,
30}
31
32/// Driver errors.
33#[derive(Debug)]
34pub enum Error<B> {
35    /// Incapsulate bus errors
36    Bus(B),
37    /// Unexpected value read from a register
38    UnexpectedValue,
39    FailedToReadMemBank,
40    FailedToSetMemBank(MemBank),
41}
42
43impl<B> From<B> for Error<B>
44where
45    B: Debug,
46{
47    fn from(bus_error: B) -> Self {
48        Error::Bus(bus_error)
49    }
50}
51
52impl<P, T> Lsm6dsv16x<I2cBus<P>, T>
53where
54    P: I2c,
55    T: DelayNs,
56{
57    /// Constructor method for using the I2C bus.
58    pub fn new_i2c(i2c: P, address: I2CAddress, tim: T) -> Self {
59        // Initialize the I2C bus with the COMPONENT address
60        let bus = st_mems_bus::i2c::I2cBus::new(i2c, address as SevenBitAddress);
61        Self { bus, tim }
62    }
63}
64impl<B, T> Lsm6dsv16x<B, T>
65where
66    B: BusOperation,
67    T: DelayNs,
68{
69    /// Create a sensor instance from a generic bus.
70    ///
71    /// The Bus must implement the `BusOperation` trait
72    pub fn from_bus(bus: B, tim: T) -> Self {
73        Self { bus, tim }
74    }
75}
76
77impl<P, T> Lsm6dsv16x<st_mems_bus::spi::SpiBus<P>, T>
78where
79    P: SpiDevice,
80    T: DelayNs,
81{
82    /// Constructor method for using the SPI bus.
83    pub fn new_spi(spi: P, tim: T) -> Self {
84        // Initialize the SPI bus
85        let bus = st_mems_bus::spi::SpiBus::new(spi);
86        Self { bus, tim }
87    }
88}
89
90impl<B, T> MemBankFunctions<MemBank> for Lsm6dsv16x<B, T>
91where
92    B: BusOperation,
93    T: DelayNs,
94{
95    type Error = Error<B::Error>;
96
97    /// Change memory bank.
98    fn mem_bank_set(&mut self, val: MemBank) -> Result<(), Self::Error> {
99        let mut func_cfg_access =
100            FuncCfgAccess::read(self).map_err(|_| Error::FailedToReadMemBank)?;
101
102        func_cfg_access.set_shub_reg_access(((val as u8) & 0x02) >> 1);
103        func_cfg_access.set_emb_func_reg_access(val as u8 & 0x01);
104        func_cfg_access
105            .write(self)
106            .map_err(|_| Error::FailedToSetMemBank(val))
107    }
108    /// Get the memory bank actually set.
109    fn mem_bank_get(&mut self) -> Result<MemBank, Self::Error> {
110        let func_cfg_access = FuncCfgAccess::read(self).map_err(|_| Error::FailedToReadMemBank)?;
111        let value =
112            (func_cfg_access.shub_reg_access() << 1) + func_cfg_access.emb_func_reg_access();
113
114        let val = match value {
115            0 => MemBank::MainMemBank,
116            1 => MemBank::EmbedFuncMemBank,
117            2 => MemBank::SensorHubMemBank,
118            _ => MemBank::MainMemBank,
119        };
120
121        Ok(val)
122    }
123}
124
125impl<B, T> EmbAdvFunctions for Lsm6dsv16x<B, T>
126where
127    B: BusOperation,
128    T: DelayNs,
129{
130    type Error = Error<B::Error>;
131
132    /// Write buffer in a page.
133    ///
134    /// # Arguments
135    ///
136    /// * `address`: Address where the page write begins.
137    /// * `buf`: Buffer to write in a page.
138    /// * `len`: Length of the buffer.
139    fn ln_pg_write(&mut self, address: u16, buf: &[u8], len: u8) -> Result<(), Self::Error> {
140        let mut msb = ((address >> 8) & 0x0F) as u8;
141        let mut lsb = (address & 0xFF) as u8;
142
143        MemBank::operate_over_embed(self, |state| {
144            // Set page write
145            let mut page_rw = PageRw::read(state)?;
146            page_rw.set_page_read(0);
147            page_rw.set_page_write(1);
148            page_rw.write(state)?;
149
150            // Select page
151            let mut page_sel = PageSel::read(state)?;
152            page_sel.set_page_sel(msb);
153            page_sel.write(state)?;
154
155            // Set page address
156            let mut page_address = PageAddress::from_bits(0);
157            page_address.set_page_addr(lsb);
158            page_address.write(state)?;
159
160            for i in 0..len {
161                state.write_to_register(
162                    EmbReg::PageValue as u8,
163                    &buf[i as usize..(i as usize + 1)],
164                )?;
165
166                lsb = lsb.wrapping_add(1);
167                // Check if page wrap
168                if lsb == 0x00 {
169                    msb += 1;
170                    page_sel = PageSel::read(state)?;
171                    page_sel.set_page_sel(msb);
172                    page_sel.write(state)?;
173                }
174            }
175
176            // Reset page selection
177            page_sel = PageSel::read(state)?;
178            page_sel.set_page_sel(0);
179            page_sel.write(state)?;
180
181            // Unset page write
182            page_rw = PageRw::read(state)?;
183            page_rw.set_page_read(0);
184            page_rw.set_page_write(0);
185            page_rw.write(state)
186        })
187    }
188
189    /// Read buffer in a page.
190    ///
191    /// # Arguments
192    ///
193    /// * `address`: The address to read from.
194    /// * `buf`: Write buffer in a page.
195    /// * `len`: Length of the buffer.
196    fn ln_pg_read(&mut self, address: u16, buf: &mut [u8], len: u8) -> Result<(), Self::Error> {
197        let mut msb = ((address >> 8) & 0x0F) as u8;
198        let mut lsb = (address & 0xFF) as u8;
199
200        MemBank::operate_over_embed(self, |state| {
201            // Set page read
202            let mut page_rw = PageRw::read(state)?;
203            page_rw.set_page_read(1);
204            page_rw.set_page_write(0);
205            page_rw.write(state)?;
206
207            // Select page
208            let mut page_sel = PageSel::read(state)?;
209            page_sel.set_page_sel(msb);
210            page_sel.write(state)?;
211
212            // Set page address
213            let mut page_address = PageAddress::from_bits(0);
214            page_address.set_page_addr(lsb);
215            page_address.write(state)?;
216
217            for i in 0..len {
218                state.read_from_register(
219                    EmbReg::PageValue as u8,
220                    &mut buf[i as usize..(i as usize + 1)],
221                )?;
222
223                lsb = lsb.wrapping_add(1);
224                // Check if page wrap
225                if lsb == 0x00 {
226                    msb += 1;
227                    page_sel = PageSel::read(state)?;
228                    page_sel.set_page_sel(msb);
229                    page_sel.write(state)?;
230                }
231            }
232
233            // Reset page selection
234            page_sel = PageSel::read(state)?;
235            page_sel.set_page_sel(0);
236            page_sel.write(state)?;
237
238            // Unset page read
239            page_rw = PageRw::read(state)?;
240            page_rw.set_page_read(0);
241            page_rw.set_page_write(0);
242            page_rw.write(state)
243        })
244    }
245}
246
247impl<B: BusOperation, T: DelayNs> Lsm6dsv16x<B, T> {
248    pub fn write_to_register(&mut self, reg: u8, buf: &[u8]) -> Result<(), Error<B::Error>> {
249        self.bus.write_to_register(reg, buf).map_err(Error::Bus)
250    }
251
252    pub fn read_from_register(&mut self, reg: u8, buf: &mut [u8]) -> Result<(), Error<B::Error>> {
253        self.bus.read_from_register(reg, buf).map_err(Error::Bus)
254    }
255    /// Enables accelerometer user offset correction block.
256    ///
257    /// It is valid for the low-pass path.
258    pub fn xl_offset_on_out_set(&mut self, val: u8) -> Result<(), Error<B::Error>> {
259        let mut ctrl9 = Ctrl9::read(self)?;
260        ctrl9.set_usr_off_on_out(val);
261        ctrl9.write(self)?;
262        Ok(())
263    }
264    /// Get accelerometer user offset correction block (enable/disable).
265    ///
266    /// It is valid for the low-pass path.
267    pub fn xl_offset_on_out_get(&mut self) -> Result<u8, Error<B::Error>> {
268        let val: u8 = Ctrl9::read(self).map(|reg| reg.usr_off_on_out())?;
269
270        Ok(val)
271    }
272    /// Set the Accelerometer user offset correction values in mg.
273    pub fn xl_offset_mg_set(&mut self, val: XlOffsetMg) -> Result<(), Error<B::Error>> {
274        let mut z_ofs_usr = ZOfsUsr::read(self)?;
275        let mut y_ofs_usr = YOfsUsr::read(self)?;
276        let mut x_ofs_usr = XOfsUsr::read(self)?;
277
278        let mut ctrl9 = Ctrl9::read(self)?;
279
280        if (val.x_mg < (0.0078125 * 127.0) && val.x_mg > (0.0078125 * -127.0))
281            && (val.y_mg < (0.0078125 * 127.0) && val.y_mg > (0.0078125 * -127.0))
282            && (val.z_mg < (0.0078125 * 127.0) && val.z_mg > (0.0078125 * -127.0))
283        {
284            ctrl9.set_usr_off_w(0);
285
286            let tmp = val.z_mg / 0.0078125;
287            z_ofs_usr.set_z_ofs_usr(tmp as u8);
288
289            let tmp = val.y_mg / 0.0078125;
290            y_ofs_usr.set_y_ofs_usr(tmp as u8);
291
292            let tmp = val.x_mg / 0.0078125;
293            x_ofs_usr.set_x_ofs_usr(tmp as u8);
294        } else if (val.x_mg < (0.125 * 127.0) && val.x_mg > (0.125 * -127.0))
295            && (val.y_mg < (0.125 * 127.0) && val.y_mg > (0.125 * -127.0))
296            && (val.z_mg < (0.125 * 127.0) && val.z_mg > (0.125 * -127.0))
297        {
298            ctrl9.set_usr_off_w(1);
299
300            let tmp = val.z_mg / 0.125;
301            z_ofs_usr.set_z_ofs_usr(tmp as u8);
302
303            let tmp = val.y_mg / 0.125;
304            y_ofs_usr.set_y_ofs_usr(tmp as u8);
305
306            let tmp = val.x_mg / 0.125;
307            x_ofs_usr.set_x_ofs_usr(tmp as u8);
308        } else {
309            ctrl9.set_usr_off_w(1);
310            z_ofs_usr.set_z_ofs_usr(0xFF);
311            y_ofs_usr.set_y_ofs_usr(0xFF);
312            x_ofs_usr.set_x_ofs_usr(0xFF);
313        }
314
315        z_ofs_usr.write(self)?;
316        y_ofs_usr.write(self)?;
317        x_ofs_usr.write(self)?;
318        ctrl9.write(self)
319    }
320    /// Get the Accelerometer user offset correction values in mg.
321    pub fn xl_offset_mg_get(&mut self) -> Result<XlOffsetMg, Error<B::Error>> {
322        let ctrl9 = Ctrl9::read(self)?;
323        let z_ofs_usr = ZOfsUsr::read(self)?;
324        let y_ofs_usr = YOfsUsr::read(self)?;
325        let x_ofs_usr = XOfsUsr::read(self)?;
326
327        let val = XlOffsetMg {
328            z_mg: if ctrl9.usr_off_w() == 0 {
329                z_ofs_usr.z_ofs_usr() as f32 * 0.0078125
330            } else {
331                z_ofs_usr.z_ofs_usr() as f32 * 0.125
332            },
333            y_mg: if ctrl9.usr_off_w() == 0 {
334                y_ofs_usr.y_ofs_usr() as f32 * 0.0078125
335            } else {
336                y_ofs_usr.y_ofs_usr() as f32 * 0.125
337            },
338            x_mg: if ctrl9.usr_off_w() == 0 {
339                x_ofs_usr.x_ofs_usr() as f32 * 0.0078125
340            } else {
341                x_ofs_usr.x_ofs_usr() as f32 * 0.125
342            },
343        };
344
345        Ok(val)
346    }
347    /// Reset of the device.
348    pub fn reset_set(&mut self, val: Reset) -> Result<(), Error<B::Error>> {
349        let mut ctrl3 = Ctrl3::read(self)?;
350        let mut func_cfg_access = FuncCfgAccess::read(self)?;
351
352        ctrl3.set_boot(((val as u8) & 0x04) >> 2);
353        ctrl3.set_sw_reset(((val as u8) & 0x02) >> 1);
354        func_cfg_access.set_sw_por(val as u8 & 0x01);
355
356        ctrl3.write(self)?;
357        func_cfg_access.write(self)
358    }
359    /// Get reset state of the device.
360    pub fn reset_get(&mut self) -> Result<Reset, Error<B::Error>> {
361        let ctrl3 = Ctrl3::read(self)?;
362        let func_cfg_access = FuncCfgAccess::read(self)?;
363
364        let value: u8 = (ctrl3.sw_reset() << 2) + (ctrl3.boot() << 1) + func_cfg_access.sw_por();
365        let val = Reset::try_from(value).unwrap_or(Reset::GlobalRst);
366
367        Ok(val)
368    }
369
370    /// Get Device ID.
371    ///
372    /// This function works also for OIS
373    /// (WHO_AM_I and SPI2_WHO_AM_I have same address).
374    pub fn device_id_get(&mut self) -> Result<u8, Error<B::Error>> {
375        WhoAmI::read(self).map(|reg| reg.into())
376    }
377    /// Set Accelerometer output data rate (ODR).
378    pub fn xl_data_rate_set(&mut self, val: Odr) -> Result<(), Error<B::Error>> {
379        let mut ctrl1 = Ctrl1::read(self)?;
380
381        ctrl1.set_odr_xl(val as u8 & 0x0F);
382        ctrl1.write(self)?;
383
384        let sel = (val as u8 >> 4) & 0x0F;
385        if sel != 0 {
386            let mut haodr = HaodrCfg::read(self)?;
387
388            haodr.set_haodr_sel(sel);
389            haodr.write(self)?;
390        }
391
392        Ok(())
393    }
394    /// Get accelerometer output data rate (ODR).
395    pub fn xl_data_rate_get(&mut self) -> Result<Odr, Error<B::Error>> {
396        let ctrl1 = Ctrl1::read(self)?;
397        let haodr = HaodrCfg::read(self)?;
398        let sel = haodr.haodr_sel() << 4;
399        let odr = sel | ctrl1.odr_xl();
400
401        Ok(Odr::try_from(odr).unwrap_or_default())
402    }
403    /// Set accelerometer operating mode.
404    pub fn xl_mode_set(&mut self, val: XlMode) -> Result<(), Error<B::Error>> {
405        let mut ctrl1 = Ctrl1::read(self)?;
406        ctrl1.set_op_mode_xl((val as u8) & 0x07);
407        ctrl1.write(self)
408    }
409    /// Get accelerometer operating mode.
410    pub fn xl_mode_get(&mut self) -> Result<XlMode, Error<B::Error>> {
411        let ctrl1 = Ctrl1::read(self)?;
412
413        let val = XlMode::try_from(ctrl1.op_mode_xl()).unwrap_or_default();
414
415        Ok(val)
416    }
417    /// Set gyroscope output data rate (ODR).
418    pub fn gy_data_rate_set(&mut self, val: Odr) -> Result<(), Error<B::Error>> {
419        let mut ctrl2 = Ctrl2::read(self)?;
420
421        ctrl2.set_odr_g((val as u8) & 0x0F);
422        ctrl2.write(self)?;
423
424        let sel = ((val as u8) >> 4) & 0x0F;
425        if sel != 0 {
426            let mut haodr = HaodrCfg::read(self)?;
427            haodr.set_haodr_sel(sel);
428            haodr.write(self)?;
429        }
430
431        Ok(())
432    }
433    /// Get gyroscope output data rate (ODR).
434    pub fn gy_data_rate_get(&mut self) -> Result<Odr, Error<B::Error>> {
435        let ctrl2 = Ctrl2::read(self)?;
436        let haodr = HaodrCfg::read(self)?;
437        let sel = haodr.haodr_sel();
438        let odr = sel | ctrl2.odr_g();
439
440        Ok(Odr::try_from(odr).unwrap_or_default())
441    }
442    /// Set gyroscope operating mode.
443    pub fn gy_mode_set(&mut self, val: GyMode) -> Result<(), Error<B::Error>> {
444        let mut ctrl2 = Ctrl2::read(self)?;
445        ctrl2.set_op_mode_g(val as u8 & 0x07);
446        ctrl2.write(self)
447    }
448    /// Get gyroscope operating mode.
449    pub fn gy_mode_get(&mut self) -> Result<GyMode, Error<B::Error>> {
450        let ctrl2 = Ctrl2::read(self)?;
451
452        let val = GyMode::try_from(ctrl2.op_mode_g()).unwrap_or_default();
453        Ok(val)
454    }
455    /// Enable/Disable the auto increment setting.
456    ///
457    /// If val == 1 it Enable automatic increment of the register address during
458    /// multiple-byte access with a serial interface; enabled by default.
459    pub fn auto_increment_set(&mut self, val: u8) -> Result<(), Error<B::Error>> {
460        let mut ctrl3 = Ctrl3::read(self)?;
461        ctrl3.set_if_inc(val);
462        ctrl3.write(self)
463    }
464    /// Get the actual auto increment setting
465    ///
466    /// Register address automatically incremented during a multiple byte access
467    /// with a serial interface (enable by default).
468    pub fn auto_increment_get(&mut self) -> Result<u8, Error<B::Error>> {
469        let val: u8 = Ctrl3::read(self).map(|reg| reg.if_inc())?;
470
471        Ok(val)
472    }
473    /// Enable/Disable Block Data Update (BDU)
474    ///
475    /// If active the output registers are not updated until LSB and MSB have been read.
476    pub fn block_data_update_set(&mut self, val: u8) -> Result<(), Error<B::Error>> {
477        let mut ctrl3 = Ctrl3::read(self)?;
478        ctrl3.set_bdu(val);
479        ctrl3.write(self)
480    }
481    /// Get actual settings of Block Data Update (BDU)
482    pub fn block_data_update_get(&mut self) -> Result<u8, Error<B::Error>> {
483        let val: u8 = Ctrl3::read(self).map(|reg| reg.bdu())?;
484
485        Ok(val)
486    }
487    /// Configure ODR trigger.
488    ///
489    /// Number of data generated in reference period when ODR-triggered mode is set.
490    /// Allowed values: 0 (default) or 4 to 255.
491    pub fn odr_trig_cfg_set(&mut self, val: u8) -> Result<(), Error<B::Error>> {
492        if !(1..=3).contains(&val) {
493            return Err(Error::UnexpectedValue);
494        }
495
496        let mut odr_trig = OdrTrigCfg::read(self)?;
497
498        odr_trig.set_odr_trig_nodr(val);
499        odr_trig.write(self)
500    }
501    /// Get the actual ODR trigger.
502    ///
503    /// Number of data generated in reference period when ODR-triggered mode is set.
504    pub fn odr_trig_cfg_get(&mut self) -> Result<u8, Error<B::Error>> {
505        let odr_trig_nodr: u8 = OdrTrigCfg::read(self).map(|reg| reg.odr_trig_nodr())?;
506
507        Ok(odr_trig_nodr)
508    }
509    /// Switch between pulsed and latched mode.
510    ///
511    /// Pulsed data-ready mode with ~75 us.
512    pub fn data_ready_mode_set(&mut self, val: DataReadyMode) -> Result<(), Error<B::Error>> {
513        let mut ctrl4 = Ctrl4::read(self)?;
514        ctrl4.set_drdy_pulsed((val as u8) & 0x1);
515        ctrl4.write(self)
516    }
517    /// Get actual pulsed data-ready mode
518    pub fn data_ready_mode_get(&mut self) -> Result<DataReadyMode, Error<B::Error>> {
519        let ctrl4 = Ctrl4::read(self)?;
520        let val = DataReadyMode::try_from(ctrl4.drdy_pulsed()).unwrap_or_default();
521
522        Ok(val)
523    }
524    /// Enables/disable interrupt and switch between latched/pulsed interrupts
525    pub fn interrupt_enable_set(&mut self, val: InterruptMode) -> Result<(), Error<B::Error>> {
526        let mut func = FunctionsEnable::read(self)?;
527        func.set_interrupts_enable(val.enable);
528        func.write(self)?;
529
530        let mut cfg = TapCfg0::read(self)?;
531        cfg.set_lir(val.lir);
532        cfg.write(self)
533    }
534    /// Get the interrupt Mode
535    ///
536    /// Enable/disabled and latched/pulsed information.
537    pub fn interrupt_enable_get(&mut self) -> Result<InterruptMode, Error<B::Error>> {
538        let func = FunctionsEnable::read(self)?;
539        let cfg = TapCfg0::read(self)?;
540
541        let enable = func.interrupts_enable();
542        let lir = cfg.lir();
543
544        Ok(InterruptMode { enable, lir })
545    }
546    /// Set the Gyroscope full-scale.
547    pub fn gy_full_scale_set(&mut self, val: GyFullScale) -> Result<(), Error<B::Error>> {
548        let mut ctrl6 = Ctrl6::read(self)?;
549
550        ctrl6.set_fs_g(val as u8 & 0xf);
551        ctrl6.write(self)
552    }
553    /// Get the actual Gyroscope full-scale.
554    pub fn gy_full_scale_get(&mut self) -> Result<GyFullScale, Error<B::Error>> {
555        let ctrl6 = Ctrl6::read(self)?;
556
557        let val = GyFullScale::try_from(ctrl6.fs_g()).unwrap_or_default();
558
559        Ok(val)
560    }
561    /// Set the Accelerometer full-scale.
562    pub fn xl_full_scale_set(&mut self, val: XlFullScale) -> Result<(), Error<B::Error>> {
563        let mut ctrl8 = Ctrl8::read(self)?;
564        ctrl8.set_fs_xl(val as u8 & 0x3);
565        ctrl8.write(self)
566    }
567    /// Get the Accelerometer full-scale.
568    pub fn xl_full_scale_get(&mut self) -> Result<XlFullScale, Error<B::Error>> {
569        let ctrl8 = Ctrl8::read(self)?;
570
571        let val = XlFullScale::try_from(ctrl8.fs_xl()).unwrap_or_default();
572
573        Ok(val)
574    }
575    /// Enables/Disables the accelerometer Dual channel mode:
576    ///
577    /// data with selected full scale and data with maximum full scale are sent
578    /// simultaneously to two different set of output registers.
579    pub fn xl_dual_channel_set(&mut self, val: u8) -> Result<(), Error<B::Error>> {
580        let mut ctrl8 = Ctrl8::read(self)?;
581        ctrl8.set_xl_dualc_en(val);
582        ctrl8.write(self)
583    }
584    /// Get the accelerometer Dual channel mode.
585    ///
586    /// Data with selected full scale and data with maximum full scale are sent
587    /// simultaneously to two different set of output registers.
588    pub fn xl_dual_channel_get(&mut self) -> Result<u8, Error<B::Error>> {
589        let val: u8 = Ctrl8::read(self).map(|reg| reg.xl_dualc_en())?;
590
591        Ok(val)
592    }
593    /// Set the Accelerometer self-test.
594    pub fn xl_self_test_set(&mut self, val: XlSelfTest) -> Result<(), Error<B::Error>> {
595        let mut ctrl10 = Ctrl10::read(self)?;
596        ctrl10.set_st_xl(val as u8 & 0x3);
597        ctrl10.write(self)
598    }
599    /// Get the actual Accelerometer self-test.
600    pub fn xl_self_test_get(&mut self) -> Result<XlSelfTest, Error<B::Error>> {
601        let ctrl10 = Ctrl10::read(self)?;
602
603        let val = XlSelfTest::try_from(ctrl10.st_xl()).unwrap_or_default();
604
605        Ok(val)
606    }
607    /// Set the Gyroscope self-test.
608    pub fn gy_self_test_set(&mut self, val: GySelfTest) -> Result<(), Error<B::Error>> {
609        let mut ctrl10 = Ctrl10::read(self)?;
610        ctrl10.set_st_g((val as u8) & 0x3);
611        ctrl10.write(self)
612    }
613    /// Get the actual Gyroscope self-test selection.
614    pub fn gy_self_test_get(&mut self) -> Result<GySelfTest, Error<B::Error>> {
615        let ctrl10 = Ctrl10::read(self)?;
616
617        let val = GySelfTest::try_from(ctrl10.st_g()).unwrap_or_default();
618
619        Ok(val)
620    }
621    /// Set the SPI2 Accelerometer self-test.
622    pub fn ois_xl_self_test_set(&mut self, val: OisXlSelfTest) -> Result<(), Error<B::Error>> {
623        let mut spi2_int_ois = Spi2IntOis::read(self)?;
624        spi2_int_ois.set_st_xl_ois((val as u8) & 0x3);
625        spi2_int_ois.write(self)
626    }
627    /// Get the actual SPI2 Accelerometer self-test.
628    pub fn ois_xl_self_test_get(&mut self) -> Result<OisXlSelfTest, Error<B::Error>> {
629        let spi2_int_ois = Spi2IntOis::read(self)?;
630        let val = OisXlSelfTest::try_from(spi2_int_ois.st_xl_ois()).unwrap_or_default();
631
632        Ok(val)
633    }
634    /// Set SPI2 Accelerometer self-test.
635    pub fn ois_gy_self_test_set(&mut self, val: OisGySelfTest) -> Result<(), Error<B::Error>> {
636        let mut spi2_int_ois = Spi2IntOis::read(self)?;
637
638        spi2_int_ois.set_st_g_ois((val as u8) & 0x3);
639        spi2_int_ois.set_st_ois_clampdis(((val as u8) & 0x04) >> 2);
640
641        spi2_int_ois.write(self)
642    }
643    /// Get the actual SPI2 Accelerometer self-test.
644    pub fn ois_gy_self_test_get(&mut self) -> Result<OisGySelfTest, Error<B::Error>> {
645        let spi2_int_ois = Spi2IntOis::read(self)?;
646
647        let val = match spi2_int_ois.st_g_ois() {
648            0 => OisGySelfTest::Disable,
649            1 => {
650                if spi2_int_ois.st_ois_clampdis() == 1 {
651                    OisGySelfTest::ClampPos
652                } else {
653                    OisGySelfTest::Positive
654                }
655            }
656            2 => {
657                if spi2_int_ois.st_ois_clampdis() == 1 {
658                    OisGySelfTest::ClampNeg
659                } else {
660                    OisGySelfTest::Negative
661                }
662            }
663            _ => OisGySelfTest::Disable,
664        };
665
666        Ok(val)
667    }
668    /// Set the signals that need to be routed on int1 pad.
669    ///
670    /// See `PinIntRoute` for a complete list of available events.
671    /// Data ready temperature is available only on int2
672    pub fn pin_int1_route_set(&mut self, val: &PinIntRoute) -> Result<(), Error<B::Error>> {
673        // Check if drdy_temp is set to 1, which is not available on INT1
674        if val.drdy_temp == 1 {
675            return Err(Error::UnexpectedValue);
676        }
677
678        // Read INT1_CTRL register
679        let mut int1_ctrl = Int1Ctrl::read(self)?;
680
681        // Set fields from `val` to `int1_ctrl`
682        int1_ctrl.set_int1_drdy_xl(val.drdy_xl);
683        int1_ctrl.set_int1_drdy_g(val.drdy_g);
684        int1_ctrl.set_int1_fifo_th(val.fifo_th);
685        int1_ctrl.set_int1_fifo_ovr(val.fifo_ovr);
686        int1_ctrl.set_int1_fifo_full(val.fifo_full);
687        int1_ctrl.set_int1_cnt_bdr(val.cnt_bdr);
688
689        // Write back to INT1_CTRL register
690        int1_ctrl.write(self)?;
691
692        // Read MD1_CFG register
693        let mut md1_cfg = Md1Cfg::read(self)?;
694
695        // Set fields from `val` to `md1_cfg`
696        md1_cfg.set_int1_shub(val.shub);
697        md1_cfg.set_int1_emb_func(val.emb_func);
698        md1_cfg.set_int1_6d(val.sixd);
699        md1_cfg.set_int1_single_tap(val.single_tap);
700        md1_cfg.set_int1_double_tap(val.double_tap);
701        md1_cfg.set_int1_wu(val.wakeup);
702        md1_cfg.set_int1_ff(val.freefall);
703        md1_cfg.set_int1_sleep_change(val.sleep_change);
704
705        // Write back to MD1_CFG register
706        md1_cfg.write(self)
707    }
708    /// Report the signals that are routed on int1 pad.
709    /// Values returned are:
710    ///     - drdy_xl
711    ///     - drdy_g
712    ///     - fifo_th
713    ///     - fifo_ovr
714    ///     - fifo_full
715    ///     - cnt_bdr
716    ///     - shub
717    ///     - emb_func
718    ///     - 6d
719    ///     - single_tap
720    ///     - double_tap
721    ///     - wakeup
722    ///     - free fall
723    ///     - sleep change
724    ///
725    /// The remaining are leaved default
726    pub fn pin_int1_route_get(&mut self) -> Result<PinIntRoute, Error<B::Error>> {
727        // Reading INT1 Control Register
728        let int1_ctrl = Int1Ctrl::read(self)?;
729
730        // Reading MD1 Configuration Register
731        let md1_cfg = Md1Cfg::read(self)?;
732
733        let val = PinIntRoute {
734            drdy_xl: int1_ctrl.int1_drdy_xl(),
735            drdy_g: int1_ctrl.int1_drdy_g(),
736            drdy_g_eis: 0,
737            drdy_temp: 0,
738            fifo_th: int1_ctrl.int1_fifo_th(),
739            fifo_ovr: int1_ctrl.int1_fifo_ovr(),
740            fifo_full: int1_ctrl.int1_fifo_full(),
741            cnt_bdr: int1_ctrl.int1_cnt_bdr(),
742            emb_func_endop: 0,
743            timestamp: 0,
744            shub: md1_cfg.int1_shub(),
745            emb_func: md1_cfg.int1_emb_func(),
746            sixd: md1_cfg.int1_6d(),
747            single_tap: md1_cfg.int1_single_tap(),
748            double_tap: md1_cfg.int1_double_tap(),
749            wakeup: md1_cfg.int1_wu(),
750            freefall: md1_cfg.int1_ff(),
751            sleep_change: md1_cfg.int1_sleep_change(),
752            drdy_ah_qvar: 0,
753        };
754
755        Ok(val)
756    }
757    /// Set the signals that need to be routed on int2 pad.
758    pub fn pin_int2_route_set(&mut self, val: &PinIntRoute) -> Result<(), Error<B::Error>> {
759        // Reading INT2 Control Register
760        let mut int2_ctrl = Int2Ctrl::read(self)?;
761
762        int2_ctrl.set_int2_drdy_xl(val.drdy_xl);
763        int2_ctrl.set_int2_drdy_g(val.drdy_g);
764        int2_ctrl.set_int2_fifo_th(val.fifo_th);
765        int2_ctrl.set_int2_fifo_ovr(val.fifo_ovr);
766        int2_ctrl.set_int2_fifo_full(val.fifo_full);
767        int2_ctrl.set_int2_cnt_bdr(val.cnt_bdr);
768        int2_ctrl.set_int2_drdy_g_eis(val.drdy_g_eis);
769        int2_ctrl.set_int2_emb_func_endop(val.emb_func_endop);
770
771        int2_ctrl.write(self)?;
772
773        // Reading CTRL4 Register
774        let mut ctrl4 = Ctrl4::read(self)?;
775
776        ctrl4.set_int2_drdy_temp(val.drdy_temp);
777        ctrl4.write(self)?;
778
779        // Reading CTRL7 Register
780        let mut ctrl7 = Ctrl7::read(self)?;
781
782        ctrl7.set_int2_drdy_ah_qvar(val.drdy_ah_qvar);
783        ctrl7.write(self)?;
784        // Reading MD2 Configuration Register
785        let mut md2_cfg = Md2Cfg::read(self)?;
786
787        md2_cfg.set_int2_timestamp(val.timestamp);
788        md2_cfg.set_int2_emb_func(val.emb_func);
789        md2_cfg.set_int2_6d(val.sixd);
790        md2_cfg.set_int2_single_tap(val.single_tap);
791        md2_cfg.set_int2_double_tap(val.double_tap);
792        md2_cfg.set_int2_wu(val.wakeup);
793        md2_cfg.set_int2_ff(val.freefall);
794        md2_cfg.set_int2_sleep_change(val.sleep_change);
795
796        md2_cfg.write(self)
797    }
798    /// Report the signals that are routed on int2 pad.
799    /// Values NOT returned are:
800    ///     - shub
801    pub fn pin_int2_route_get(&mut self) -> Result<PinIntRoute, Error<B::Error>> {
802        // Read from INT2_CTRL register
803        let int2_ctrl = Int2Ctrl::read(self)?;
804        // Read from CTRL4 register
805        let ctrl4 = Ctrl4::read(self)?;
806        // Read from CTRL7 register
807        let ctrl7 = Ctrl7::read(self)?;
808        // Read from MD2_CFG register
809        let md2_cfg = Md2Cfg::read(self)?;
810
811        let val = PinIntRoute {
812            drdy_xl: int2_ctrl.int2_drdy_xl(),
813            drdy_g: int2_ctrl.int2_drdy_g(),
814            fifo_th: int2_ctrl.int2_fifo_th(),
815            fifo_ovr: int2_ctrl.int2_fifo_ovr(),
816            fifo_full: int2_ctrl.int2_fifo_full(),
817            cnt_bdr: int2_ctrl.int2_cnt_bdr(),
818            drdy_g_eis: int2_ctrl.int2_drdy_g_eis(),
819            emb_func_endop: int2_ctrl.int2_emb_func_endop(),
820            timestamp: md2_cfg.int2_timestamp(),
821            emb_func: md2_cfg.int2_emb_func(),
822            sixd: md2_cfg.int2_6d(),
823            single_tap: md2_cfg.int2_single_tap(),
824            double_tap: md2_cfg.int2_double_tap(),
825            wakeup: md2_cfg.int2_wu(),
826            freefall: md2_cfg.int2_ff(),
827            sleep_change: md2_cfg.int2_sleep_change(),
828            drdy_ah_qvar: ctrl7.int2_drdy_ah_qvar(),
829            drdy_temp: ctrl4.int2_drdy_temp(),
830            shub: 0,
831        };
832
833        Ok(val)
834    }
835
836    /// Get routed embedded func interrupt signals on INT 1 pin.
837    pub fn emb_pin_int1_route_get(&mut self) -> Result<EmbPinIntRoute, Error<B::Error>> {
838        MemBank::operate_over_embed(self, |state| {
839            let emb_func_int1 = EmbFuncInt1::read(state)?;
840
841            let val = EmbPinIntRoute {
842                tilt: emb_func_int1.int1_tilt(),
843                sig_mot: emb_func_int1.int1_sig_mot(),
844                step_det: emb_func_int1.int1_step_detector(),
845                fsm_lc: emb_func_int1.int1_fsm_lc(),
846            };
847
848            Ok(val)
849        })
850    }
851
852    /// Routes embedded func interrupt signals on INT 1 pin.
853    pub fn emb_pin_int1_route_set(&mut self, val: EmbPinIntRoute) -> Result<(), Error<B::Error>> {
854        MemBank::operate_over_embed(self, |state| {
855            let mut emb_func_int1 = EmbFuncInt1::read(state)?;
856
857            emb_func_int1.set_int1_tilt(val.tilt);
858            emb_func_int1.set_int1_sig_mot(val.sig_mot);
859            emb_func_int1.set_int1_step_detector(val.step_det);
860            emb_func_int1.set_int1_fsm_lc(val.fsm_lc);
861
862            emb_func_int1.write(state)
863        })?;
864
865        let mut md1_cfg = Md1Cfg::read(self)?;
866        md1_cfg.set_int1_emb_func(1);
867        md1_cfg.write(self)
868    }
869
870    /// Get routed embedded func interrupt signals on INT 2 pin.
871    pub fn emb_pin_int2_route_get(&mut self) -> Result<EmbPinIntRoute, Error<B::Error>> {
872        MemBank::operate_over_embed(self, |state| {
873            let emb_func_int2 = EmbFuncInt2::read(state)?;
874
875            let val = EmbPinIntRoute {
876                tilt: emb_func_int2.int2_tilt(),
877                sig_mot: emb_func_int2.int2_sig_mot(),
878                step_det: emb_func_int2.int2_step_detector(),
879                fsm_lc: emb_func_int2.int2_fsm_lc(),
880            };
881
882            Ok(val)
883        })
884    }
885
886    /// Routes embedded func interrupt signals on INT 2 pin.
887    pub fn emb_pin_int2_route_set(&mut self, val: EmbPinIntRoute) -> Result<(), Error<B::Error>> {
888        MemBank::operate_over_embed(self, |state| {
889            let mut emb_func_int2 = EmbFuncInt2::read(state)?;
890
891            emb_func_int2.set_int2_tilt(val.tilt);
892            emb_func_int2.set_int2_sig_mot(val.sig_mot);
893            emb_func_int2.set_int2_step_detector(val.step_det);
894            emb_func_int2.set_int2_fsm_lc(val.fsm_lc);
895
896            emb_func_int2.write(state)
897        })?;
898
899        let mut md2_cfg = Md2Cfg::read(self)?;
900        md2_cfg.set_int2_emb_func(1);
901        md2_cfg.write(self)
902    }
903
904    /// Get interrupt configuration mode.
905    pub fn embedded_int_cfg_get(&mut self) -> Result<EmbeddedIntConf, Error<B::Error>> {
906        let mut val = EmbeddedIntConf::Pulsed;
907
908        MemBank::operate_over_embed(self, |state| {
909            let page_rw = PageRw::read(state)?;
910            if page_rw.emb_func_lir() == 1 {
911                val = EmbeddedIntConf::Latched;
912            }
913
914            Ok(val)
915        })
916    }
917
918    /// Set interrupt configuration mode.
919    pub fn embedded_int_cfg_set(&mut self, val: EmbeddedIntConf) -> Result<(), Error<B::Error>> {
920        MemBank::operate_over_embed(self, |state| {
921            let mut page_rw = PageRw::read(state)?;
922            match val {
923                EmbeddedIntConf::Latched => {
924                    page_rw.set_emb_func_lir(1);
925                }
926                EmbeddedIntConf::Pulsed => {
927                    page_rw.set_emb_func_lir(0);
928                }
929            };
930            page_rw.write(state)
931        })
932    }
933
934    /// Get the status of embedded functions.
935    pub fn embedded_status_get(&mut self) -> Result<EmbeddedStatus, Error<B::Error>> {
936        let status = EmbFuncStatusMainPage::read(self)?;
937        MemBank::operate_over_embed(self, |state| {
938            let src = EmbFuncSrc::read(state)?;
939
940            let val = EmbeddedStatus {
941                tilt: status.is_tilt(),
942                sig_mot: status.is_sigmot(),
943                fsm_lc: status.is_fsm_lc(),
944                step_count_inc: src.stepcounter_bit_set(),
945                step_count_overflow: src.step_overflow(),
946                step_on_delta_time: src.step_count_delta_ia(),
947                step_detector: src.step_detected(),
948            };
949
950            Ok(val)
951        })
952    }
953
954    /// Get the status of all the interrupt sources.
955    pub fn all_sources_get(&mut self) -> Result<AllSources, Error<B::Error>> {
956        let mut functions_enable = FunctionsEnable::read(self)?;
957        functions_enable.set_dis_rst_lir_all_int(1);
958        functions_enable.write(self)?;
959
960        let fifo_status = FifoStatusReg::read(self)?;
961        let all_int_src = AllIntSrc::read(self)?;
962        let status_reg = StatusReg::read(self)?;
963
964        functions_enable = FunctionsEnable::read(self)?;
965        functions_enable.set_dis_rst_lir_all_int(0);
966        functions_enable.write(self)?;
967
968        let status_reg_ois = UiStatusRegOis::read(self)?;
969        let wake_up_src = WakeUpSrc::read(self)?;
970        let tap_src = TapSrc::read(self)?;
971        let d6d_src = D6dSrc::read(self)?;
972
973        let emb_func_status_mainpage = EmbFuncStatusMainPage::read(self)?;
974        let fsm_status_mainpage = FsmStatusMainPage::read(self)?;
975        let mlc_status_mainpage = MlcStatusMainPage::read(self)?;
976
977        // Embedded function
978        let (emb_func_exec_status, emb_func_src) = MemBank::operate_over_embed(self, |state| {
979            let emb_func_exec_status = EmbFuncExecStatus::read(state)?;
980            let emb_func_src = EmbFuncSrc::read(state)?;
981            Ok((emb_func_exec_status, emb_func_src))
982        })?;
983
984        let status_shub = StatusMasterMainPage::read(self)?;
985
986        let val = AllSources {
987            drdy_xl: status_reg.xlda(),
988            drdy_gy: status_reg.gda(),
989            drdy_temp: status_reg.tda(),
990            drdy_ah_qvar: status_reg.ah_qvarda(),
991            drdy_eis: status_reg.gda_eis(),
992            drdy_ois: status_reg.ois_drdy(),
993            gy_settling: status_reg_ois.gyro_settling(),
994            timestamp: status_reg.timestamp_endcount(),
995            free_fall: all_int_src.ff_ia(),
996            wake_up: all_int_src.wu_ia(),
997            wake_up_z: wake_up_src.z_wu(),
998            wake_up_y: wake_up_src.y_wu(),
999            wake_up_x: wake_up_src.x_wu(),
1000            single_tap: tap_src.single_tap(),
1001            double_tap: tap_src.double_tap(),
1002            tap_z: tap_src.z_tap(),
1003            tap_y: tap_src.y_tap(),
1004            tap_x: tap_src.x_tap(),
1005            tap_sign: tap_src.tap_sign(),
1006            six_d: all_int_src.d6d_ia(),
1007            six_d_xl: d6d_src.xl(),
1008            six_d_xh: d6d_src.xh(),
1009            six_d_yl: d6d_src.yl(),
1010            six_d_yh: d6d_src.yh(),
1011            six_d_zl: d6d_src.zl(),
1012            six_d_zh: d6d_src.zh(),
1013            sleep_change: wake_up_src.sleep_change_ia(),
1014            sleep_state: wake_up_src.sleep_state(),
1015            step_detector: emb_func_src.step_detected(),
1016            step_count_inc: emb_func_src.stepcounter_bit_set(),
1017            step_count_overflow: emb_func_src.step_overflow(),
1018            step_on_delta_time: emb_func_src.step_count_delta_ia(),
1019            emb_func_stand_by: emb_func_exec_status.emb_func_endop(),
1020            emb_func_time_exceed: emb_func_exec_status.emb_func_exec_ovr(),
1021            tilt: emb_func_status_mainpage.is_tilt(),
1022            sig_mot: emb_func_status_mainpage.is_sigmot(),
1023            fsm_lc: emb_func_status_mainpage.is_fsm_lc(),
1024            fsm1: fsm_status_mainpage.is_fsm1(),
1025            fsm2: fsm_status_mainpage.is_fsm2(),
1026            fsm3: fsm_status_mainpage.is_fsm3(),
1027            fsm4: fsm_status_mainpage.is_fsm4(),
1028            fsm5: fsm_status_mainpage.is_fsm5(),
1029            fsm6: fsm_status_mainpage.is_fsm6(),
1030            fsm7: fsm_status_mainpage.is_fsm7(),
1031            fsm8: fsm_status_mainpage.is_fsm8(),
1032            mlc1: mlc_status_mainpage.is_mlc1(),
1033            mlc2: mlc_status_mainpage.is_mlc2(),
1034            mlc3: mlc_status_mainpage.is_mlc3(),
1035            mlc4: mlc_status_mainpage.is_mlc4(),
1036            sh_endop: status_shub.sens_hub_endop(),
1037            sh_slave0_nack: status_shub.slave0_nack(),
1038            sh_slave1_nack: status_shub.slave1_nack(),
1039            sh_slave2_nack: status_shub.slave2_nack(),
1040            sh_slave3_nack: status_shub.slave3_nack(),
1041            sh_wr_once: status_shub.wr_once_done(),
1042            fifo_bdr: fifo_status.counter_bdr_ia(),
1043            fifo_full: fifo_status.fifo_full_ia(),
1044            fifo_ovr: fifo_status.fifo_ovr_ia(),
1045            fifo_th: fifo_status.fifo_wtm_ia(),
1046        };
1047
1048        Ok(val)
1049    }
1050    /// Get Flag data ready
1051    ///
1052    /// Return data ready status about: xl, gy, temp
1053    pub fn flag_data_ready_get(&mut self) -> Result<DataReady, Error<B::Error>> {
1054        let status_reg = StatusReg::read(self)?;
1055
1056        let data_ready = DataReady {
1057            drdy_xl: status_reg.xlda(),
1058            drdy_gy: status_reg.gda(),
1059            drdy_temp: status_reg.tda(),
1060        };
1061
1062        Ok(data_ready)
1063    }
1064    /// Set Mask status bit reset
1065    pub fn int_ack_mask_set(&mut self, val: u8) -> Result<(), Error<B::Error>> {
1066        MemBank::operate_over_embed(self, |state| IntAckMask::from_bits(val).write(state))
1067    }
1068    /// Get the actual Mask status bit reset
1069    pub fn int_ack_mask_get(&mut self) -> Result<u8, Error<B::Error>> {
1070        MemBank::operate_over_embed(self, |state| {
1071            IntAckMask::read(state).map(|reg| reg.into_bits())
1072        })
1073    }
1074    /// Get the Temperature raw data
1075    pub fn temperature_raw_get(&mut self) -> Result<i16, Error<B::Error>> {
1076        OutTemp::read(self).map(|reg| reg.0)
1077    }
1078
1079    /// Get the Angular rate raw data.
1080    pub fn angular_rate_raw_get(&mut self) -> Result<[i16; 3], Error<B::Error>> {
1081        let val = OutXYZG::read(self)?;
1082
1083        Ok([val.x, val.y, val.z])
1084    }
1085    /// Get the OIS Angular rate raw data.
1086    ///
1087    /// Data comes through SPI2
1088    pub fn ois_angular_rate_raw_get(&mut self) -> Result<[i16; 3], Error<B::Error>> {
1089        let val = Spi2OutXYZGOis::read(self)?;
1090
1091        Ok([val.x, val.y, val.z])
1092    }
1093
1094    /// Get angular rate raw data for OIS gyro or the EIS gyro channel.
1095    pub fn ois_eis_angular_rate_raw_get(&mut self) -> Result<[i16; 3], Error<B::Error>> {
1096        let val = UiOutXYZGOisEis::read(self)?;
1097
1098        Ok([val.x, val.y, val.z])
1099    }
1100
1101    /// Get the Linear acceleration raw data.
1102    pub fn acceleration_raw_get(&mut self) -> Result<[i16; 3], Error<B::Error>> {
1103        let val = OutXYZA::read(self)?;
1104
1105        Ok([val.x, val.y, val.z])
1106    }
1107    /// Get the Linear acceleration sensor for Dual channel mode.
1108    pub fn dual_acceleration_raw_get(&mut self) -> Result<[i16; 3], Error<B::Error>> {
1109        let val = UiOutXYZAOisDualc::read(self)?;
1110
1111        Ok([val.x, val.y, val.z])
1112    }
1113    /// Get ah_qvar raw data.
1114    ///
1115    /// When the analog hub or Qvar is enabled, the output is
1116    /// the analog hub or Qvar sensor data.
1117    pub fn ah_qvar_raw_get(&mut self) -> Result<i16, Error<B::Error>> {
1118        AhQvarOut::read(self).map(|reg| reg.0)
1119    }
1120    /// Get difference in percentage of the effective ODR
1121    /// (and timestamp rate) with respect to the typical.
1122    ///
1123    /// Step: 0.13%. 8-bit format, 2's complement.
1124    pub fn odr_cal_reg_get(&mut self) -> Result<i8, Error<B::Error>> {
1125        let val: i8 = InternalFreq::read(self).map(|reg| reg.freq_fine() as i8)?;
1126
1127        Ok(val)
1128    }
1129
1130    /// Enable debug mode for embedded functions.
1131    pub fn emb_function_dbg_set(&mut self, val: u8) -> Result<(), Error<B::Error>> {
1132        let mut ctrl10 = Ctrl10::read(self)?;
1133        ctrl10.set_emb_func_debug(val);
1134        ctrl10.write(self)
1135    }
1136    /// Get if debug mode for embedded functions is enabled
1137    pub fn emb_function_dbg_get(&mut self) -> Result<u8, Error<B::Error>> {
1138        let val: u8 = Ctrl10::read(self).map(|reg| reg.emb_func_debug())?;
1139
1140        Ok(val)
1141    }
1142    /// It changes the polarity of INT2 pin input trigger for data enable (DEN) or embedded functions.
1143    pub fn den_polarity_set(&mut self, val: DenPolarity) -> Result<(), Error<B::Error>> {
1144        let mut ctrl4 = Ctrl4::read(self)?;
1145        ctrl4.set_int2_in_lh((val as u8) & 0x1);
1146        ctrl4.write(self)
1147    }
1148    /// Get the polarity of INT2 pin input trigger for data enable (DEN) or embedded functions.
1149    pub fn den_polarity_get(&mut self) -> Result<DenPolarity, Error<B::Error>> {
1150        let ctrl4 = Ctrl4::read(self)?;
1151
1152        let val = DenPolarity::try_from(ctrl4.int2_in_lh()).unwrap_or_default();
1153
1154        Ok(val)
1155    }
1156    /// Set Data ENable (DEN) configuration.
1157    pub fn den_conf_set(&mut self, val: DenConf) -> Result<(), Error<B::Error>> {
1158        let mut den = Den::read(self)?;
1159
1160        den.set_den_z(val.den_z);
1161        den.set_den_y(val.den_y);
1162        den.set_den_x(val.den_x);
1163
1164        den.set_lvl2_en((val.mode as u8) & 0x1);
1165        den.set_lvl1_en(((val.mode as u8) & 0x2) >> 1);
1166
1167        if val.stamp_in_gy_data == 1 && val.stamp_in_xl_data == 1 {
1168            den.set_den_xl_g(0);
1169            den.set_den_xl_en(1);
1170        } else if val.stamp_in_gy_data == 1 && val.stamp_in_xl_data == 0 {
1171            den.set_den_xl_g(0);
1172            den.set_den_xl_en(0);
1173        } else if val.stamp_in_gy_data == 0 && val.stamp_in_xl_data == 1 {
1174            den.set_den_xl_g(1);
1175            den.set_den_xl_en(0);
1176        } else {
1177            den.set_den_xl_g(0);
1178            den.set_den_xl_en(0);
1179            den.set_den_z(0);
1180            den.set_den_y(0);
1181            den.set_den_x(0);
1182            den.set_lvl2_en(0);
1183            den.set_lvl1_en(0);
1184        }
1185
1186        den.write(self)
1187    }
1188    /// Get Data ENable (DEN) configuration.
1189    pub fn den_conf_get(&mut self) -> Result<DenConf, Error<B::Error>> {
1190        let den = Den::read(self)?;
1191
1192        let mut val = DenConf {
1193            den_z: den.den_z(),
1194            den_y: den.den_y(),
1195            den_x: den.den_x(),
1196            stamp_in_gy_data: 0,
1197            stamp_in_xl_data: 0,
1198            mode: DenMode::DenNotDefined,
1199        };
1200
1201        if (den.den_x() | den.den_y() | den.den_z()) == 1 {
1202            if den.den_xl_g() == 0 && den.den_xl_en() == 1 {
1203                val.stamp_in_gy_data = 1;
1204                val.stamp_in_xl_data = 1;
1205            } else if den.den_xl_g() == 0 && den.den_xl_en() == 0 {
1206                val.stamp_in_gy_data = 1;
1207                val.stamp_in_xl_data = 0;
1208            } else {
1209                val.stamp_in_gy_data = 0;
1210                val.stamp_in_xl_data = 1;
1211            }
1212        }
1213
1214        match (den.lvl1_en() << 1) + den.lvl2_en() {
1215            3 => val.mode = DenMode::LevelTrigger,
1216            2 => val.mode = DenMode::LevelLatched,
1217            _ => val.mode = DenMode::DenNotDefined,
1218        }
1219
1220        Ok(val)
1221    }
1222    /// Gyroscope full-scale selection for EIS channel.
1223    ///
1224    /// WARNING: 4000dps will be available only if also User Interface chain is set to 4000dps.
1225    pub fn eis_gy_full_scale_set(&mut self, val: EisGyFullScale) -> Result<(), Error<B::Error>> {
1226        let mut ctrl_eis = CtrlEis::read(self)?;
1227        ctrl_eis.set_fs_g_eis(val as u8 & 0x7);
1228        ctrl_eis.write(self)
1229    }
1230    /// Get the actual Gyroscope full-scale selection for EIS channel.
1231    ///
1232    /// WARNING: 4000dps will be available only if also User Interface chain is set to 4000dps
1233    pub fn eis_gy_full_scale_get(&mut self) -> Result<EisGyFullScale, Error<B::Error>> {
1234        let ctrl_eis = CtrlEis::read(self)?;
1235        let val = EisGyFullScale::try_from(ctrl_eis.fs_g_eis()).unwrap_or_default();
1236
1237        Ok(val)
1238    }
1239    /// Enables routing of gyroscope EIS outputs on SPI2 (OIS interface).
1240    ///
1241    /// The gyroscope data on SPI2 (OIS interface) cannot be read from User Interface (UI).
1242    pub fn eis_gy_on_spi2_set(&mut self, val: u8) -> Result<(), Error<B::Error>> {
1243        let mut ctrl_eis = CtrlEis::read(self)?;
1244        ctrl_eis.set_g_eis_on_g_ois_out_reg(val);
1245        ctrl_eis.write(self)
1246    }
1247    /// Enables routing of gyroscope EIS outputs on SPI2 (OIS interface).
1248    ///
1249    /// The gyroscope data on SPI2 (OIS interface) cannot be read from User Interface (UI).
1250    pub fn eis_gy_on_spi2_get(&mut self) -> Result<u8, Error<B::Error>> {
1251        let val: u8 = CtrlEis::read(self).map(|reg| reg.g_eis_on_g_ois_out_reg())?;
1252
1253        Ok(val)
1254    }
1255    /// Enables and selects the ODR of the gyroscope EIS channel.
1256    pub fn gy_eis_data_rate_set(&mut self, val: GyEisDataRate) -> Result<(), Error<B::Error>> {
1257        let mut ctrl_eis = CtrlEis::read(self)?;
1258        ctrl_eis.set_odr_g_eis((val as u8) & 0x03);
1259        ctrl_eis.write(self)
1260    }
1261    /// Get the actual ODR of the gyroscope EIS channel.
1262    pub fn gy_eis_data_rate_get(&mut self) -> Result<GyEisDataRate, Error<B::Error>> {
1263        let ctrl_eis = CtrlEis::read(self)?;
1264
1265        let val = GyEisDataRate::try_from(ctrl_eis.odr_g_eis()).unwrap_or_default();
1266
1267        Ok(val)
1268    }
1269    /// Set FIFO watermark threshold
1270    ///
1271    /// 1 LSb = TAG (1 Byte) + 1 sensor (6 Bytes) written in FIFO.
1272    pub fn fifo_watermark_set(&mut self, val: u8) -> Result<(), Error<B::Error>> {
1273        let mut fifo_ctrl1 = FifoCtrl1::read(self)?;
1274        fifo_ctrl1.set_wtm(val);
1275        fifo_ctrl1.write(self)
1276    }
1277    /// Get the actual FIFO watermark threshold
1278    ///
1279    /// 1 LSb = TAG (1 Byte) + 1 sensor (6 Bytes) written in FIFO
1280    pub fn fifo_watermark_get(&mut self) -> Result<u8, Error<B::Error>> {
1281        let val: u8 = FifoCtrl1::read(self).map(|reg| reg.wtm())?;
1282
1283        Ok(val)
1284    }
1285    /// Enables FSM-triggered batching in FIFO of accelerometer channel 2, WHEN dual channel mode
1286    /// is enabled
1287    pub fn fifo_xl_dual_fsm_batch_set(&mut self, val: u8) -> Result<(), Error<B::Error>> {
1288        let mut fifo_ctrl2 = FifoCtrl2::read(self)?;
1289        fifo_ctrl2.set_xl_dualc_batch_from_fsm(val);
1290        fifo_ctrl2.write(self)
1291    }
1292    /// Get if FSM-triggered batching in FIFO of accelerometer channel 2 is enabled. Required dual channel mode enabled.
1293    pub fn fifo_xl_dual_fsm_batch_get(&mut self) -> Result<u8, Error<B::Error>> {
1294        let val: u8 = FifoCtrl2::read(self).map(|reg| reg.xl_dualc_batch_from_fsm())?;
1295
1296        Ok(val)
1297    }
1298    /// It configures the compression algorithm to write non-compressed data at each rate.
1299    pub fn fifo_compress_algo_set(&mut self, val: FifoCompressAlgo) -> Result<(), Error<B::Error>> {
1300        let mut fifo_ctrl2 = FifoCtrl2::read(self)?;
1301        fifo_ctrl2.set_uncompr_rate((val as u8) & 0x03);
1302        fifo_ctrl2.write(self)
1303    }
1304    /// Get the actual compression algorithm.
1305    ///
1306    /// The compression algorithm handles the write of non-compressed data at each rate.
1307    pub fn fifo_compress_algo_get(&mut self) -> Result<FifoCompressAlgo, Error<B::Error>> {
1308        let fifo_ctrl2 = FifoCtrl2::read(self)?;
1309
1310        let val = FifoCompressAlgo::try_from(fifo_ctrl2.uncompr_rate()).unwrap_or_default();
1311
1312        Ok(val)
1313    }
1314    /// Enables ODR CHANGE virtual sensor to be batched in FIFO.
1315    pub fn fifo_virtual_sens_odr_chg_set(&mut self, val: u8) -> Result<(), Error<B::Error>> {
1316        let mut fifo_ctrl2 = FifoCtrl2::read(self)?;
1317        fifo_ctrl2.set_odr_chg_en(val);
1318        fifo_ctrl2.write(self)
1319    }
1320    /// Get the configuration (enable/disable) of ODR CHANGE virtual sensor to be batched in FIFO.
1321    pub fn fifo_virtual_sens_odr_chg_get(&mut self) -> Result<u8, Error<B::Error>> {
1322        let val: u8 = FifoCtrl2::read(self).map(|reg| reg.odr_chg_en())?;
1323
1324        Ok(val)
1325    }
1326    /// Enables/Disables compression algorithm runtime.
1327    ///
1328    /// If val is 1: compression algorithm is active at runtime
1329    pub fn fifo_compress_algo_real_time_set(&mut self, val: u8) -> Result<(), Error<B::Error>> {
1330        let mut fifo_ctrl2 = FifoCtrl2::read(self)?;
1331        fifo_ctrl2.set_fifo_compr_rt_en(val);
1332        fifo_ctrl2.write(self)?;
1333
1334        MemBank::operate_over_embed(self, |state| {
1335            let mut emb_func_en_b = EmbFuncEnB::read(state)?;
1336            emb_func_en_b.set_fifo_compr_en(val);
1337            emb_func_en_b.write(state)
1338        })
1339    }
1340    /// Get the configuration (enable/disable) compression algorithm runtime.
1341    pub fn fifo_compress_algo_real_time_get(&mut self) -> Result<u8, Error<B::Error>> {
1342        let val: u8 = FifoCtrl2::read(self).map(|reg| reg.fifo_compr_rt_en())?;
1343
1344        Ok(val)
1345    }
1346    /// Sensing chain FIFO stop values memorization at threshold level.
1347    pub fn fifo_stop_on_wtm_set(&mut self, val: u8) -> Result<(), Error<B::Error>> {
1348        let mut fifo_ctrl2 = FifoCtrl2::read(self)?;
1349        fifo_ctrl2.set_stop_on_wtm(val);
1350        fifo_ctrl2.write(self)
1351    }
1352    /// Get the configuration (enable/disable) for sensing chain FIFO stop values memorization at threshold level.
1353    pub fn fifo_stop_on_wtm_get(&mut self) -> Result<u8, Error<B::Error>> {
1354        let val: u8 = FifoCtrl2::read(self).map(|reg| reg.stop_on_wtm())?;
1355
1356        Ok(val)
1357    }
1358    /// Selects Batch Data Rate (write frequency in FIFO) for accelerometer data.
1359    pub fn fifo_xl_batch_set(&mut self, val: FifoBatch) -> Result<(), Error<B::Error>> {
1360        let mut fifo_ctrl3 = FifoCtrl3::read(self)?;
1361        fifo_ctrl3.set_bdr_xl((val as u8) & 0xF);
1362        fifo_ctrl3.write(self)
1363    }
1364    /// Get the Batch Data Rate (write frequency in FIFO) for accelerometer data.
1365    pub fn fifo_xl_batch_get(&mut self) -> Result<FifoBatch, Error<B::Error>> {
1366        let fifo_ctrl3 = FifoCtrl3::read(self)?;
1367        let val = FifoBatch::try_from(fifo_ctrl3.bdr_xl()).unwrap_or_default();
1368
1369        Ok(val)
1370    }
1371    /// Selects Batch Data Rate (write frequency in FIFO) for gyroscope data.
1372    pub fn fifo_gy_batch_set(&mut self, val: FifoBatch) -> Result<(), Error<B::Error>> {
1373        let mut fifo_ctrl3 = FifoCtrl3::read(self)?;
1374        fifo_ctrl3.set_bdr_gy((val as u8) & 0x0F);
1375        fifo_ctrl3.write(self)
1376    }
1377    /// Get Batch Data Rate (write frequency in FIFO) for gyroscope data.
1378    pub fn fifo_gy_batch_get(&mut self) -> Result<FifoBatch, Error<B::Error>> {
1379        let fifo_ctrl3 = FifoCtrl3::read(self)?;
1380
1381        let val = FifoBatch::try_from(fifo_ctrl3.bdr_gy()).unwrap_or_default();
1382
1383        Ok(val)
1384    }
1385    /// Set FIFO mode.
1386    pub fn fifo_mode_set(&mut self, val: FifoMode) -> Result<(), Error<B::Error>> {
1387        let mut fifo_ctrl4 = FifoCtrl4::read(self)?;
1388        fifo_ctrl4.set_fifo_mode((val as u8) & 0x07);
1389        fifo_ctrl4.write(self)
1390    }
1391    /// Get FIFO mode.
1392    pub fn fifo_mode_get(&mut self) -> Result<FifoMode, Error<B::Error>> {
1393        let fifo_ctrl = FifoCtrl4::read(self)?;
1394        let fifo_mode = FifoMode::try_from(fifo_ctrl.fifo_mode()).unwrap_or_default();
1395
1396        Ok(fifo_mode)
1397    }
1398    /// Enables/Disables FIFO batching of EIS gyroscope output values.
1399    ///
1400    /// If val is 1 FIFO batching is enabled
1401    pub fn fifo_gy_eis_batch_set(&mut self, val: u8) -> Result<(), Error<B::Error>> {
1402        let mut fifo_ctrl4 = FifoCtrl4::read(self)?;
1403        fifo_ctrl4.set_g_eis_fifo_en(val);
1404        fifo_ctrl4.write(self)
1405    }
1406    /// Get the configuration (enabled/disabled) for FIFO batching of EIS gyroscope output values.
1407    pub fn fifo_gy_eis_batch_get(&mut self) -> Result<u8, Error<B::Error>> {
1408        let val: u8 = FifoCtrl4::read(self).map(|reg| reg.g_eis_fifo_en())?;
1409
1410        Ok(val)
1411    }
1412    /// Set batch data rate (write frequency in FIFO) for temperature data.
1413    pub fn fifo_temp_batch_set(&mut self, val: FifoTempBatch) -> Result<(), Error<B::Error>> {
1414        let mut fifo_ctrl4 = FifoCtrl4::read(self)?;
1415        fifo_ctrl4.set_odr_t_batch((val as u8) & 0x03);
1416        fifo_ctrl4.write(self)
1417    }
1418    /// Get actual batch data rate (write frequency in FIFO) for temperature data.
1419    pub fn fifo_temp_batch_get(&mut self) -> Result<FifoTempBatch, Error<B::Error>> {
1420        let fifo_ctrl4 = FifoCtrl4::read(self)?;
1421
1422        let val = FifoTempBatch::try_from(fifo_ctrl4.odr_t_batch()).unwrap_or_default();
1423
1424        Ok(val)
1425    }
1426    /// Selects decimation for timestamp batching in FIFO.
1427    ///
1428    /// Write rate will be the maximum rate between XL and GYRO BDR divided by decimation decoder.
1429    pub fn fifo_timestamp_batch_set(
1430        &mut self,
1431        val: FifoTimestampBatch,
1432    ) -> Result<(), Error<B::Error>> {
1433        let mut fifo_ctrl4 = FifoCtrl4::read(self)?;
1434        fifo_ctrl4.set_dec_ts_batch((val as u8) & 0x03);
1435        fifo_ctrl4.write(self)
1436    }
1437    /// Get the actual decimation for timestamp batching in FIFO.
1438    ///
1439    /// Write rate will be the maximum rate between XL and GYRO BDR divided by decimation decoder.
1440    pub fn fifo_timestamp_batch_get(&mut self) -> Result<FifoTimestampBatch, Error<B::Error>> {
1441        let fifo_ctrl4 = FifoCtrl4::read(self)?;
1442
1443        let val = FifoTimestampBatch::try_from(fifo_ctrl4.dec_ts_batch()).unwrap_or_default();
1444
1445        Ok(val)
1446    }
1447    /// Set the threshold for the internal counter of batch events.
1448    ///
1449    /// When this counter reaches the threshold, the counter is
1450    /// reset and the interrupt flag is set to 1.
1451    pub fn fifo_batch_counter_threshold_set(&mut self, val: u16) -> Result<(), Error<B::Error>> {
1452        let mut counter_bdr = CounterBdrReg::read(self)?;
1453        counter_bdr.set_cnt_bdr_th(val);
1454        counter_bdr.write(self)
1455    }
1456    /// Get the threshold for the internal counter of batch events.
1457    ///
1458    /// When this counter reaches the threshold, the counter is
1459    /// reset and the interrupt flag is set to 1.
1460    pub fn fifo_batch_counter_threshold_get(&mut self) -> Result<u16, Error<B::Error>> {
1461        let counter = CounterBdrReg::read(self)?;
1462
1463        Ok(counter.cnt_bdr_th())
1464    }
1465    /// Set the trigger for the internal counter of batch events.
1466    pub fn fifo_batch_cnt_event_set(
1467        &mut self,
1468        val: FifoBatchCntEvent,
1469    ) -> Result<(), Error<B::Error>> {
1470        let mut counter_bdr_reg1 = CounterBdrReg::read(self)?;
1471        counter_bdr_reg1.set_trig_counter_bdr(val as u8 & 0x03);
1472        counter_bdr_reg1.write(self)
1473    }
1474    /// Get the actual trigger for the internal counter of batch events.
1475    pub fn fifo_batch_cnt_event_get(&mut self) -> Result<FifoBatchCntEvent, Error<B::Error>> {
1476        let counter_bdr_reg1 = CounterBdrReg::read(self)?;
1477
1478        let val =
1479            FifoBatchCntEvent::try_from(counter_bdr_reg1.trig_counter_bdr()).unwrap_or_default();
1480
1481        Ok(val)
1482    }
1483    /// Retrieves FIFO status.
1484    pub fn fifo_status_get(&mut self) -> Result<FifoStatus, Error<B::Error>> {
1485        let status = FifoStatusReg::read(self)?;
1486
1487        let fifo_status = FifoStatus {
1488            fifo_bdr: status.counter_bdr_ia(),
1489            fifo_ovr: status.fifo_ovr_ia(),
1490            fifo_full: status.fifo_full_ia(),
1491            fifo_th: status.fifo_wtm_ia(),
1492            fifo_level: status.diff_fifo(),
1493        };
1494
1495        Ok(fifo_status)
1496    }
1497    /// Get the FIFO data tag and data.
1498    pub fn fifo_out_raw_get(&mut self) -> Result<FifoOutRaw, Error<B::Error>> {
1499        let fifo_data_out_tag = FifoDataOutTag::read(self)?;
1500        let tag_sensor = Tag::try_from(fifo_data_out_tag.tag_sensor()).unwrap_or_default();
1501        let cnt = fifo_data_out_tag.tag_cnt();
1502        let data = FifoDataOutXYZ::read(self)?;
1503
1504        Ok(FifoOutRaw {
1505            tag: tag_sensor,
1506            cnt,
1507            data: data.0,
1508        })
1509    }
1510    /// Set the batching in FIFO buffer of step counter value.
1511    pub fn fifo_stpcnt_batch_set(&mut self, val: u8) -> Result<(), Error<B::Error>> {
1512        MemBank::operate_over_embed(self, |state| {
1513            let mut emb_func_fifo_en_a = EmbFuncFifoEnA::read(state)?;
1514            emb_func_fifo_en_a.set_step_counter_fifo_en(val);
1515            emb_func_fifo_en_a.write(state)
1516        })
1517    }
1518    /// Get the acutal batching in FIFO buffer of step counter value.
1519    pub fn fifo_stpcnt_batch_get(&mut self) -> Result<u8, Error<B::Error>> {
1520        MemBank::operate_over_embed(self, |state| {
1521            EmbFuncFifoEnA::read(state).map(|reg| reg.step_counter_fifo_en())
1522        })
1523    }
1524    /// Enables/Disables batching in FIFO buffer of machine learning core results.
1525    pub fn fifo_mlc_batch_set(&mut self, val: u8) -> Result<(), Error<B::Error>> {
1526        MemBank::operate_over_embed(self, |state| {
1527            let mut emb_func_fifo_en_a = EmbFuncFifoEnA::read(state)?;
1528            emb_func_fifo_en_a.set_mlc_fifo_en(val);
1529            emb_func_fifo_en_a.write(state)
1530        })
1531    }
1532    /// Get the configuration (enables/disables) batching in FIFO buffer of machine learning core results.
1533    pub fn fifo_mlc_batch_get(&mut self) -> Result<u8, Error<B::Error>> {
1534        MemBank::operate_over_embed(self, |state| {
1535            let emb_func_fifo_en_a = EmbFuncFifoEnA::read(state)?;
1536            Ok(emb_func_fifo_en_a.mlc_fifo_en())
1537        })
1538    }
1539    /// Enables batching in FIFO buffer of machine learning core filters and features.
1540    pub fn fifo_mlc_filt_batch_set(&mut self, val: u8) -> Result<(), Error<B::Error>> {
1541        MemBank::operate_over_embed(self, |state| {
1542            let mut emb_func_fifo_en_b = EmbFuncFifoEnB::read(state)?;
1543            emb_func_fifo_en_b.set_mlc_filter_feature_fifo_en(val);
1544            emb_func_fifo_en_b.write(state)
1545        })
1546    }
1547    /// Get the configuration (enable/disable) of batching in FIFO buffer
1548    /// of machine learning core filters and features.
1549    pub fn fifo_mlc_filt_batch_get(&mut self) -> Result<u8, Error<B::Error>> {
1550        MemBank::operate_over_embed(self, |state| {
1551            EmbFuncFifoEnB::read(state).map(|reg| reg.mlc_filter_feature_fifo_en())
1552        })
1553    }
1554    /// Enable FIFO data batching of target idx.
1555    pub fn fifo_sh_batch_slave_set(&mut self, idx: u8, val: u8) -> Result<(), Error<B::Error>> {
1556        self.mem_bank_set(MemBank::SensorHubMemBank)?;
1557
1558        let mut buf = [0u8; 1];
1559        self.read_from_register(SnsHubReg::Slv0Config as u8 + idx * 3, &mut buf)?;
1560        let mut slv_config = Slv0Config::from_bits(buf[0]);
1561        slv_config.set_batch_ext_sens_0_en(val);
1562        self.write_to_register(SnsHubReg::Slv0Config as u8 + idx * 3, &[slv_config.into()])?;
1563
1564        self.mem_bank_set(MemBank::MainMemBank)
1565    }
1566    /// Get the actual configuration (enable/disable) FIFO data batching of target idx.
1567    pub fn fifo_sh_batch_slave_get(&mut self, idx: u8) -> Result<u8, Error<B::Error>> {
1568        self.mem_bank_set(MemBank::SensorHubMemBank)?;
1569
1570        let mut buf = [0u8; 1];
1571        self.read_from_register(SnsHubReg::Slv0Config as u8 + idx * 3, &mut buf)?;
1572        let val: u8 = Slv0Config::from_bits(buf[0]).batch_ext_sens_0_en();
1573
1574        self.mem_bank_set(MemBank::MainMemBank)?;
1575
1576        Ok(val)
1577    }
1578    /// Enable/Disable Batching in FIFO buffer of SFLP.
1579    pub fn fifo_sflp_batch_set(&mut self, val: FifoSflpRaw) -> Result<(), Error<B::Error>> {
1580        MemBank::operate_over_embed(self, |state| {
1581            let mut emb_func_fifo_en_a = EmbFuncFifoEnA::read(state)?;
1582            emb_func_fifo_en_a.set_sflp_game_fifo_en(val.game_rotation);
1583            emb_func_fifo_en_a.set_sflp_gravity_fifo_en(val.gravity);
1584            emb_func_fifo_en_a.set_sflp_gbias_fifo_en(val.gbias);
1585            emb_func_fifo_en_a.write(state)
1586        })
1587    }
1588    /// Get the actual configuration (enable/disable) for Batching in FIFO buffer of SFLP.
1589    pub fn fifo_sflp_batch_get(&mut self) -> Result<FifoSflpRaw, Error<B::Error>> {
1590        MemBank::operate_over_embed(self, |state| {
1591            let emb_func_fifo_en_a = EmbFuncFifoEnA::read(state)?;
1592
1593            let val = FifoSflpRaw {
1594                game_rotation: emb_func_fifo_en_a.sflp_game_fifo_en(),
1595                gravity: emb_func_fifo_en_a.sflp_gravity_fifo_en(),
1596                gbias: emb_func_fifo_en_a.sflp_gbias_fifo_en(),
1597            };
1598
1599            Ok(val)
1600        })
1601    }
1602    /// Set Protocol anti-spike filters.
1603    pub fn filt_anti_spike_set(&mut self, val: FiltAntiSpike) -> Result<(), Error<B::Error>> {
1604        let mut if_cfg = IfCfg::read(self)?;
1605        if_cfg.set_asf_ctrl((val as u8) & 0x01);
1606        if_cfg.write(self)
1607    }
1608    /// Get the actual Protocol anti-spike filters.
1609    pub fn filt_anti_spike_get(&mut self) -> Result<FiltAntiSpike, Error<B::Error>> {
1610        let if_cfg = IfCfg::read(self)?;
1611        let val = FiltAntiSpike::try_from(if_cfg.asf_ctrl()).unwrap_or_default();
1612
1613        Ok(val)
1614    }
1615    /// It masks DRDY and Interrupts RQ until filter settling ends.
1616    pub fn filt_settling_mask_set(&mut self, val: FiltSettlingMask) -> Result<(), Error<B::Error>> {
1617        // Read CTRL4 register and set the drdy_mask field
1618        let mut ctrl4 = Ctrl4::read(self)?;
1619        ctrl4.set_drdy_mask(val.drdy);
1620        ctrl4.write(self)?;
1621
1622        // Read EMB_FUNC_CFG register and set the irq_mask fields
1623        let mut emb_func_cfg = EmbFuncCfg::read(self)?;
1624        emb_func_cfg.set_emb_func_irq_mask_xl_settl(val.irq_xl);
1625        emb_func_cfg.set_emb_func_irq_mask_g_settl(val.irq_g);
1626        emb_func_cfg.write(self)?;
1627
1628        // Read UI_INT_OIS register and set the drdy_mask_ois field
1629        let mut ui_int_ois = UiIntOis::read(self)?;
1630        ui_int_ois.set_drdy_mask_ois(val.ois_drdy);
1631        ui_int_ois.write(self)
1632    }
1633    /// Get the configuration for masks DRDY and Interrupts RQ.
1634    pub fn filt_settling_mask_get(&mut self) -> Result<FiltSettlingMask, Error<B::Error>> {
1635        let emb_func_cfg = EmbFuncCfg::read(self)?;
1636        let ui_int_ois = UiIntOis::read(self)?;
1637        let ctrl4 = Ctrl4::read(self)?;
1638
1639        let val: FiltSettlingMask = FiltSettlingMask {
1640            irq_xl: emb_func_cfg.emb_func_irq_mask_xl_settl(),
1641            irq_g: emb_func_cfg.emb_func_irq_mask_g_settl(),
1642            drdy: ctrl4.drdy_mask(),
1643            ois_drdy: ui_int_ois.drdy_mask_ois(),
1644        };
1645
1646        Ok(val)
1647    }
1648    /// Set the masks for DRDY and Interrupts RQ until filter settling ends.
1649    pub fn filt_ois_settling_mask_set(&mut self, ois_drdy: u8) -> Result<(), Error<B::Error>> {
1650        let mut spi2_int_ois = Spi2IntOis::read(self)?;
1651        spi2_int_ois.set_drdy_mask_ois(ois_drdy);
1652        spi2_int_ois.write(self)
1653    }
1654    /// Get the masks DRDY and Interrupts RQ until filter settling ends.
1655    pub fn filt_ois_settling_mask_get(&mut self) -> Result<FiltOisSettlingMask, Error<B::Error>> {
1656        let spi2_int_ois = Spi2IntOis::read(self)?;
1657        let val = FiltOisSettlingMask {
1658            ois_drdy: spi2_int_ois.drdy_mask_ois(),
1659        };
1660        Ok(val)
1661    }
1662    /// Set the Gyroscope low-pass filter (LPF1) bandwidth
1663    pub fn filt_gy_lp1_bandwidth_set(
1664        &mut self,
1665        val: FiltGyLp1Bandwidth,
1666    ) -> Result<(), Error<B::Error>> {
1667        let mut ctrl6 = Ctrl6::read(self)?;
1668        ctrl6.set_lpf1_g_bw((val as u8) & 0x0F);
1669        ctrl6.write(self)
1670    }
1671    /// Get the gyroscope low-pass filter (LPF1) bandwidth.
1672    pub fn filt_gy_lp1_bandwidth_get(&mut self) -> Result<FiltGyLp1Bandwidth, Error<B::Error>> {
1673        let ctrl6 = Ctrl6::read(self)?;
1674        let bandwidth = FiltGyLp1Bandwidth::try_from(ctrl6.lpf1_g_bw()).unwrap_or_default();
1675
1676        Ok(bandwidth)
1677    }
1678    /// Enables/Disable gyroscope digital LPF1 filter.
1679    pub fn filt_gy_lp1_set(&mut self, val: u8) -> Result<(), Error<B::Error>> {
1680        let mut ctrl7 = Ctrl7::read(self)?;
1681        ctrl7.set_lpf1_g_en(val);
1682        ctrl7.write(self)
1683    }
1684    /// Get the configuration (enables/disables) gyroscope digital LPF1 filter.
1685    pub fn filt_gy_lp1_get(&mut self) -> Result<u8, Error<B::Error>> {
1686        Ctrl7::read(self).map(|reg| reg.lpf1_g_en())
1687    }
1688    /// Set the Accelerometer LPF2 and high pass filter configuration and cutoff setting.
1689    pub fn filt_xl_lp2_bandwidth_set(
1690        &mut self,
1691        val: FiltXlLp2Bandwidth,
1692    ) -> Result<(), Error<B::Error>> {
1693        let mut ctrl8 = Ctrl8::read(self)?;
1694        ctrl8.set_hp_lpf2_xl_bw((val as u8) & 0x07);
1695        ctrl8.write(self)
1696    }
1697    /// Get the current Accelerometer LPF2 and high pass filter configuration and cutoff setting.
1698    pub fn filt_xl_lp2_bandwidth_get(&mut self) -> Result<FiltXlLp2Bandwidth, Error<B::Error>> {
1699        let ctrl8 = Ctrl8::read(self)?;
1700        let bandwidth =
1701            FiltXlLp2Bandwidth::try_from(ctrl8.hp_lpf2_xl_bw() & 0x07).unwrap_or_default();
1702
1703        Ok(bandwidth)
1704    }
1705    /// Enable/Disable accelerometer LPS2 (Low Pass Filter 2) filtering stage.
1706    pub fn filt_xl_lp2_set(&mut self, val: u8) -> Result<(), Error<B::Error>> {
1707        let mut ctrl9 = Ctrl9::read(self)?;
1708        ctrl9.set_lpf2_xl_en(val);
1709        ctrl9.write(self)
1710    }
1711    /// Get the accelerometer LPS2 (Low Pass Filter 2) filtering stage.
1712    pub fn filt_xl_lp2_get(&mut self) -> Result<u8, Error<B::Error>> {
1713        let val: u8 = Ctrl9::read(self).map(|reg| reg.lpf2_xl_en())?;
1714
1715        Ok(val)
1716    }
1717    /// Accelerometer slope filter / high-pass filter selection.
1718    pub fn filt_xl_hp_set(&mut self, val: u8) -> Result<(), Error<B::Error>> {
1719        let mut ctrl9 = Ctrl9::read(self)?;
1720        ctrl9.set_hp_slope_xl_en(val);
1721        ctrl9.write(self)
1722    }
1723    /// Get the Accelerometer slope filter / high-pass filter selection.
1724    pub fn filt_xl_hp_get(&mut self) -> Result<u8, Error<B::Error>> {
1725        let val: u8 = Ctrl9::read(self).map(|reg| reg.hp_slope_xl_en())?;
1726
1727        Ok(val)
1728    }
1729    /// Enables accelerometer LPF2 and HPF fast-settling mode. The filter sets the first sample.
1730    pub fn filt_xl_fast_settling_set(&mut self, val: u8) -> Result<(), Error<B::Error>> {
1731        let mut ctrl9 = Ctrl9::read(self)?;
1732        ctrl9.set_xl_fastsettl_mode(val);
1733        ctrl9.write(self)
1734    }
1735    /// Get accelerometer LPF2 and HPF fast-settling mode. The filter sets the first sample.
1736    pub fn filt_xl_fast_settling_get(&mut self) -> Result<u8, Error<B::Error>> {
1737        let val: u8 = Ctrl9::read(self).map(|reg| reg.xl_fastsettl_mode())?;
1738
1739        Ok(val)
1740    }
1741    /// Set Accelerometer high-pass filter mode.
1742    pub fn filt_xl_hp_mode_set(&mut self, val: FiltXlHpMode) -> Result<(), Error<B::Error>> {
1743        let mut ctrl9 = Ctrl9::read(self)?;
1744        ctrl9.set_hp_ref_mode_xl(val as u8 & 0x01);
1745        ctrl9.write(self)
1746    }
1747    /// Get Accelerometer high-pass filter mode.
1748    pub fn filt_xl_hp_mode_get(&mut self) -> Result<FiltXlHpMode, Error<B::Error>> {
1749        let ctrl9 = Ctrl9::read(self)?;
1750
1751        let mode = FiltXlHpMode::try_from(ctrl9.hp_ref_mode_xl()).unwrap_or_default();
1752
1753        Ok(mode)
1754    }
1755    /// Filter wakeup activity feed set.
1756    ///
1757    /// Set HPF or SLOPE filter selection on wake-up and Activity/Inactivity functions.
1758    pub fn filt_wkup_act_feed_set(&mut self, val: FiltWkupActFeed) -> Result<(), Error<B::Error>> {
1759        let mut wake_up_ths = WakeUpThs::read(self)?;
1760        let mut tap_cfg0 = TapCfg0::read(self)?;
1761
1762        tap_cfg0.set_slope_fds((val as u8) & 0x01);
1763        tap_cfg0.write(self)?;
1764
1765        wake_up_ths.set_usr_off_on_wu(((val as u8) & 0x02) >> 1);
1766        wake_up_ths.write(self)
1767    }
1768    /// Filter wakeup activity feed get.
1769    ///
1770    /// Get the actual HPF or SLOPE filter on wake-up and Activity/Inactivity functions.
1771    pub fn filt_wkup_act_feed_get(&mut self) -> Result<FiltWkupActFeed, Error<B::Error>> {
1772        let wake_up_ths = WakeUpThs::read(self)?;
1773        let tap_cfg0 = TapCfg0::read(self)?;
1774
1775        let result =
1776            FiltWkupActFeed::try_from((wake_up_ths.usr_off_on_wu() << 1) + tap_cfg0.slope_fds())
1777                .unwrap_or_default();
1778
1779        Ok(result)
1780    }
1781    /// Mask hw function triggers when xl is settling.
1782    ///
1783    /// If val is 1 it enables the masking
1784    pub fn mask_trigger_xl_settl_set(&mut self, val: u8) -> Result<(), Error<B::Error>> {
1785        let mut tap_cfg0 = TapCfg0::read(self)?;
1786        tap_cfg0.set_hw_func_mask_xl_settl(val & 0x01);
1787        tap_cfg0.write(self)
1788    }
1789    /// Get current configuration (enable/disable) of mask hw function
1790    ///
1791    /// triggers when xl is settling.
1792    pub fn mask_trigger_xl_settl_get(&mut self) -> Result<u8, Error<B::Error>> {
1793        TapCfg0::read(self).map(|reg| reg.hw_func_mask_xl_settl())
1794    }
1795    /// Configure the LPF2 filter on 6D (sixd) function.
1796    pub fn filt_sixd_feed_set(&mut self, val: FiltSixdFeed) -> Result<(), Error<B::Error>> {
1797        let mut tap_cfg0 = TapCfg0::read(self)?;
1798        tap_cfg0.set_low_pass_on_6d((val as u8) & 0x01);
1799        tap_cfg0.write(self)
1800    }
1801    /// Get the actual LPF2 filter on 6D (sixd) function selection.
1802    pub fn filt_sixd_feed_get(&mut self) -> Result<FiltSixdFeed, Error<B::Error>> {
1803        let reg = TapCfg0::read(self)?;
1804        let val = FiltSixdFeed::try_from(reg.low_pass_on_6d()).unwrap_or_default();
1805        Ok(val)
1806    }
1807    /// Set the gyroscope digital LPF_EIS filter bandwidth.
1808    pub fn filt_gy_eis_lp_bandwidth_set(
1809        &mut self,
1810        val: FiltGyEisLpBandwidth,
1811    ) -> Result<(), Error<B::Error>> {
1812        let mut ctrl_eis = CtrlEis::read(self)?;
1813        ctrl_eis.set_lpf_g_eis_bw(val as u8 & 0x01);
1814        ctrl_eis.write(self)
1815    }
1816    /// Get the current gyroscope digital LPF_EIS filter bandwidth selection.
1817    pub fn filt_gy_eis_lp_bandwidth_get(
1818        &mut self,
1819    ) -> Result<FiltGyEisLpBandwidth, Error<B::Error>> {
1820        let ctrl_eis = CtrlEis::read(self)?;
1821
1822        let val = FiltGyEisLpBandwidth::try_from(ctrl_eis.lpf_g_eis_bw()).unwrap_or_default();
1823
1824        Ok(val)
1825    }
1826    /// Set the Gyroscope OIS digital LPF1 filter bandwidth.
1827    ///
1828    /// This function works also on OIS interface.
1829    pub fn filt_gy_ois_lp_bandwidth_set(
1830        &mut self,
1831        val: FiltGyOisLpBandwidth,
1832    ) -> Result<(), Error<B::Error>> {
1833        let mut ui_ctrl2_ois = UiCtrl2Ois::read(self)?;
1834
1835        ui_ctrl2_ois.set_lpf1_g_ois_bw((val as u8) & 0x03);
1836        ui_ctrl2_ois.write(self)
1837    }
1838    /// Get the current gyroscope OIS digital LPF1 filter bandwidth.
1839    ///
1840    /// This function works also on OIS interface.
1841    pub fn filt_gy_ois_lp_bandwidth_get(
1842        &mut self,
1843    ) -> Result<FiltGyOisLpBandwidth, Error<B::Error>> {
1844        let ui_ctrl2_ois = UiCtrl2Ois::read(self)?;
1845
1846        let val = FiltGyOisLpBandwidth::try_from(ui_ctrl2_ois.lpf1_g_ois_bw()).unwrap_or_default();
1847
1848        Ok(val)
1849    }
1850    /// Set accelerometer OIS channel bandwidth.
1851    ///
1852    /// This function works also on OIS interface.
1853    pub fn filt_xl_ois_lp_bandwidth_set(
1854        &mut self,
1855        val: FiltXlOisLpBandwidth,
1856    ) -> Result<(), Error<B::Error>> {
1857        let mut ui_ctrl3_ois = UiCtrl3Ois::read(self)?;
1858        ui_ctrl3_ois.set_lpf_xl_ois_bw((val as u8) & 0x07);
1859        ui_ctrl3_ois.write(self)
1860    }
1861    /// Get accelerometer OIS channel bandwidth.
1862    ///
1863    /// This function works also on OIS interface.
1864    pub fn filt_xl_ois_lp_bandwidth_get(
1865        &mut self,
1866    ) -> Result<FiltXlOisLpBandwidth, Error<B::Error>> {
1867        let reg = UiCtrl3Ois::read(self)?;
1868
1869        let val = FiltXlOisLpBandwidth::try_from(reg.lpf_xl_ois_bw()).unwrap_or_default();
1870
1871        Ok(val)
1872    }
1873    /// Enables the control of the CTRL registers to FSM.
1874    ///
1875    /// Warning: FSM can change some configurations of the device autonomously.
1876    pub fn fsm_permission_set(&mut self, val: FsmPermission) -> Result<(), Error<B::Error>> {
1877        let mut func_cfg_access = FuncCfgAccess::read(self)?;
1878        func_cfg_access.set_fsm_wr_ctrl_en(val as u8 & 0x01);
1879        func_cfg_access.write(self)
1880    }
1881    /// Get the FSM permission to change the CTRL registers.
1882    pub fn fsm_permission_get(&mut self) -> Result<FsmPermission, Error<B::Error>> {
1883        let func_cfg_access = FuncCfgAccess::read(self)?;
1884
1885        match func_cfg_access.fsm_wr_ctrl_en() {
1886            0 => Ok(FsmPermission::ProtectCtrlRegs),
1887            1 => Ok(FsmPermission::WriteCtrlReg),
1888            _ => Ok(FsmPermission::ProtectCtrlRegs),
1889        }
1890    }
1891    /// Get the FSM permission status
1892    ///
1893    /// Returns 0 if all registers writable from standard interface;
1894    /// 1 if some registers are under FSM control.
1895    pub fn fsm_permission_status(&mut self) -> Result<u8, Error<B::Error>> {
1896        let val: u8 = CtrlStatus::read(self).map(|reg| reg.fsm_wr_ctrl_status())?;
1897
1898        Ok(val)
1899    }
1900    /// Enable Finite State Machine (FSM) feature.
1901    pub fn fsm_mode_set(&mut self, val: FsmMode) -> Result<(), Error<B::Error>> {
1902        const PROPERTY_ENABLE: u8 = 1;
1903        const PROPERTY_DISABLE: u8 = 0;
1904
1905        MemBank::operate_over_embed(self, |state| {
1906            let mut emb_func_en_b = EmbFuncEnB::read(state)?;
1907            let mut fsm_enable = FsmEnable::read(state)?;
1908
1909            if (val.fsm1_en
1910                | val.fsm2_en
1911                | val.fsm3_en
1912                | val.fsm4_en
1913                | val.fsm5_en
1914                | val.fsm6_en
1915                | val.fsm7_en
1916                | val.fsm8_en)
1917                == PROPERTY_ENABLE
1918            {
1919                emb_func_en_b.set_fsm_en(PROPERTY_ENABLE);
1920            } else {
1921                emb_func_en_b.set_fsm_en(PROPERTY_DISABLE);
1922            }
1923
1924            fsm_enable.set_fsm1_en(val.fsm1_en);
1925            fsm_enable.set_fsm2_en(val.fsm2_en);
1926            fsm_enable.set_fsm3_en(val.fsm3_en);
1927            fsm_enable.set_fsm4_en(val.fsm4_en);
1928            fsm_enable.set_fsm5_en(val.fsm5_en);
1929            fsm_enable.set_fsm6_en(val.fsm6_en);
1930            fsm_enable.set_fsm7_en(val.fsm7_en);
1931            fsm_enable.set_fsm8_en(val.fsm8_en);
1932
1933            fsm_enable.write(state)?;
1934            emb_func_en_b.write(state)
1935        })
1936    }
1937    /// Enable Finite State Machine (FSM) feature.
1938    pub fn fsm_mode_get(&mut self) -> Result<FsmMode, Error<B::Error>> {
1939        MemBank::operate_over_embed(self, |state| {
1940            let fsm_enable = FsmEnable::read(state)?;
1941            Ok(FsmMode {
1942                fsm1_en: fsm_enable.fsm1_en(),
1943                fsm2_en: fsm_enable.fsm2_en(),
1944                fsm3_en: fsm_enable.fsm3_en(),
1945                fsm4_en: fsm_enable.fsm4_en(),
1946                fsm5_en: fsm_enable.fsm5_en(),
1947                fsm6_en: fsm_enable.fsm6_en(),
1948                fsm7_en: fsm_enable.fsm7_en(),
1949                fsm8_en: fsm_enable.fsm8_en(),
1950            })
1951        })
1952    }
1953    /// Set FSM long counter status register.
1954    ///
1955    /// Long counter value is an unsigned integer value (16-bit format).
1956    pub fn fsm_long_cnt_set(&mut self, val: u16) -> Result<(), Error<B::Error>> {
1957        MemBank::operate_over_embed(self, |state| FsmLongCounter(val).write(state))
1958    }
1959    /// Get FSM long counter status register.
1960    ///
1961    /// Long counter value is an unsigned integer value (16-bit format).
1962    pub fn fsm_long_cnt_get(&mut self) -> Result<u16, Error<B::Error>> {
1963        MemBank::operate_over_embed(self, |state| FsmLongCounter::read(state).map(|reg| reg.0))
1964    }
1965    /// Get the FSM output results.
1966    pub fn fsm_out_get(&mut self) -> Result<[FsmOutsElement; 8], Error<B::Error>> {
1967        MemBank::operate_over_embed(self, |state| FsmOut::read(state).map(|reg| reg.0))
1968    }
1969    /// Set the Finite State Machine Output Data Rate (ODR).
1970    pub fn fsm_data_rate_set(&mut self, val: FsmDataRate) -> Result<(), Error<B::Error>> {
1971        MemBank::operate_over_embed(self, |state| {
1972            let mut fsm_odr = FsmOdr::read(state)?;
1973            fsm_odr.set_fsm_odr((val as u8) & 0x07);
1974            fsm_odr.write(state)
1975        })
1976    }
1977    /// Get the finite State Machine Output Data Rate (ODR) configuration.
1978    pub fn fsm_data_rate_get(&mut self) -> Result<FsmDataRate, Error<B::Error>> {
1979        // Set the memory bank to EmbedFuncMemBank
1980        MemBank::operate_over_embed(self, |state| {
1981            // Read the FSM ODR register
1982            let fsm_odr = FsmOdr::read(state)?;
1983            // Determine the FSM data rate
1984            let val = FsmDataRate::try_from(fsm_odr.fsm_odr()).unwrap_or_default();
1985            Ok(val)
1986        })
1987    }
1988    /// Set SFLP GBIAS value for x/y/z axis.
1989    ///
1990    /// The register value is expressed as half-precision
1991    /// floating-point format: SEEEEEFFFFFFFFFF (S: 1 sign bit; E: 5 exponent
1992    /// bits; F: 10 fraction bits).
1993    pub fn sflp_game_gbias_set(&mut self, val: &SflpGbias) -> Result<(), Error<B::Error>> {
1994        let mut emb_func_en_saved: (EmbFuncEnA, EmbFuncEnB);
1995        let mut gbias_hf: [u16; 3] = [0; 3];
1996        let mut data_tmp: i32;
1997        let mut data_bytes: [u8; 4];
1998
1999        let sflp_odr = self.sflp_data_rate_get()?;
2000
2001        let k = match sflp_odr {
2002            SflpDataRate::_15hz => 0.04,
2003            SflpDataRate::_30hz => 0.02,
2004            SflpDataRate::_60hz => 0.01,
2005            SflpDataRate::_120hz => 0.005,
2006            SflpDataRate::_240hz => 0.0025,
2007            SflpDataRate::_480hz => 0.00125,
2008        };
2009
2010        // compute gbias as half precision float in order to be put in embedded advanced feature register
2011        gbias_hf[0] = self.npy_float_to_half(val.gbias_x * (core::f32::consts::PI / 180.0) / k);
2012        gbias_hf[1] = self.npy_float_to_half(val.gbias_y * (core::f32::consts::PI / 180.0) / k);
2013        gbias_hf[2] = self.npy_float_to_half(val.gbias_z * (core::f32::consts::PI / 180.0) / k);
2014
2015        // Save sensor configuration and set high-performance mode (if the sensor is in the power-down
2016        // mode, turn it on)
2017        let conf_saved = (Ctrl1::read(self)?, Ctrl2::read(self)?);
2018        self.xl_mode_set(XlMode::HighPerformanceMd)?;
2019        self.gy_mode_set(GyMode::HighPerformanceMd)?;
2020        if conf_saved.0.odr_xl() == Odr::Off as u8 {
2021            self.xl_data_rate_set(Odr::_120hz)?;
2022        }
2023
2024        // make sure to turn the sensor-hub master off
2025        let master_config = self.sh_master_get()?;
2026        self.sh_master_set(0)?;
2027
2028        // disable algos
2029        emb_func_en_saved = MemBank::operate_over_embed(self, |state| {
2030            let tmp_emb_func_en_saved = (EmbFuncEnA::read(state)?, EmbFuncEnB::read(state)?);
2031            EmbFuncEnA::from_bits(0).write(state)?;
2032            EmbFuncEnB::from_bits(0).write(state)?;
2033            loop {
2034                let emb_func_sts = EmbFuncExecStatus::read(state)?;
2035                if emb_func_sts.emb_func_endop() == 1 {
2036                    break;
2037                }
2038            }
2039
2040            Ok(tmp_emb_func_en_saved)
2041        })?;
2042
2043        // enable gbias setting
2044        let mut ctrl10 = Ctrl10::read(self)?;
2045        ctrl10.set_emb_func_debug(1);
2046        ctrl10.write(self)?;
2047
2048        // enable algos
2049        MemBank::operate_over_embed(self, |state| {
2050            emb_func_en_saved.0.set_sflp_game_en(1); // force SFLP GAME en
2051            emb_func_en_saved.0.write(state)?;
2052            emb_func_en_saved.1.write(state)
2053        })?;
2054
2055        let xl_fs = self.xl_full_scale_get()?;
2056
2057        loop {
2058            let drdy = self.flag_data_ready_get()?;
2059            if drdy.drdy_xl == 1 {
2060                break;
2061            }
2062        }
2063
2064        let xl_data: [i16; 3] = self.acceleration_raw_get()?;
2065
2066        // force sflp initialization
2067        self.mem_bank_set(MemBank::SensorHubMemBank)?;
2068        for i in 0..3 {
2069            data_tmp = xl_data[i as usize] as i32;
2070            data_tmp <<= xl_fs as i32; // shift based on current fs
2071            data_bytes = data_tmp.to_le_bytes();
2072            self.write_to_register(SnsHubReg::SensorHub1 as u8 + 3 * i, &[data_bytes[0]])?;
2073            self.write_to_register(SnsHubReg::SensorHub2 as u8 + 3 * i, &[data_bytes[1]])?;
2074            self.write_to_register(SnsHubReg::SensorHub3 as u8 + 3 * i, &[data_bytes[2]])?;
2075        }
2076        for i in 0..3 {
2077            data_tmp = 0;
2078            data_bytes = data_tmp.to_le_bytes();
2079            self.write_to_register(SnsHubReg::SensorHub10 as u8 + 3 * i, &[data_bytes[0]])?;
2080            self.write_to_register(SnsHubReg::SensorHub11 as u8 + 3 * i, &[data_bytes[1]])?;
2081            self.write_to_register(SnsHubReg::SensorHub12 as u8 + 3 * i, &[data_bytes[2]])?;
2082        }
2083        self.mem_bank_set(MemBank::MainMemBank)?;
2084
2085        // wait end op (and at least 30 us)
2086        self.tim.delay_ms(1);
2087        MemBank::operate_over_embed(self, |state| {
2088            loop {
2089                let emb_func_sts = EmbFuncExecStatus::read(state)?;
2090                if emb_func_sts.emb_func_endop() == 1 {
2091                    break;
2092                }
2093            }
2094            Ok(())
2095        })?;
2096
2097        // write gbias in embedded advanced features registers
2098        SflpGameGbiasXYZ(gbias_hf).write(self)?;
2099
2100        // reload previous sensor configuration
2101        conf_saved.0.write(self)?;
2102        conf_saved.1.write(self)?;
2103
2104        // disable gbias setting
2105        ctrl10.set_emb_func_debug(0);
2106        ctrl10.write(self)?;
2107
2108        // reload previous master configuration
2109        self.sh_master_set(master_config)
2110    }
2111    /// Set the External sensor sensitivity value register for the Finite State Machine.
2112    ///
2113    /// This register corresponds to the conversion value of the external sensor.
2114    /// The register value is expressed as half-precision floating-point format:
2115    /// SEEEEEFFFFFFFFFF (S: 1 sign bit; E: 5 exponent bits; F: 10 fraction bits).
2116    /// Default value is 0x1624 (when using an external magnetometer this value
2117    /// corresponds to 0.0015 gauss/LSB).
2118    pub fn fsm_ext_sens_sensitivity_set(&mut self, val: u16) -> Result<(), Error<B::Error>> {
2119        FsmExtSensitivity(val).write(self)
2120    }
2121    /// Get the External sensor sensitivity value register for the Finite State Machine.
2122    ///
2123    /// This register corresponds to the conversion value of the external sensor.
2124    /// The register value is expressed as half-precision floating-point format:
2125    /// SEEEEEFFFFFFFFFF (S: 1 sign bit; E: 5 exponent bits; F: 10 fraction bits).
2126    /// Default value is 0x1624 (when using an external magnetometer this value
2127    /// corresponds to 0.0015 gauss/LSB).
2128    pub fn fsm_ext_sens_sensitivity_get(&mut self) -> Result<u16, Error<B::Error>> {
2129        FsmExtSensitivity::read(self).map(|reg| reg.0)
2130    }
2131    /// Set External sensor offsets (X,Y,Z).
2132    ///
2133    /// The values are expressed as half-precision floating-point format:
2134    /// SEEEEEFFFFFFFFFF (S: 1 sign bit; E: 5 exponent bits; F: 10 fraction bits).
2135    pub fn fsm_ext_sens_offset_set(
2136        &mut self,
2137        val: XlFsmExtSensOffset,
2138    ) -> Result<(), Error<B::Error>> {
2139        FsmExtOffXYZ([val.x, val.y, val.z]).write(self)
2140    }
2141    /// Get External sensor offsets (X,Y,Z).
2142    ///
2143    /// The values are expressed as half-precision floating-point format:
2144    /// SEEEEEFFFFFFFFFF (S: 1 sign bit; E: 5 exponent bits; F: 10 fraction bits).
2145    pub fn fsm_ext_sens_offset_get(&mut self) -> Result<XlFsmExtSensOffset, Error<B::Error>> {
2146        FsmExtOffXYZ::read(self).map(|reg| XlFsmExtSensOffset {
2147            x: reg.0[0],
2148            y: reg.0[1],
2149            z: reg.0[2],
2150        })
2151    }
2152    /// Set External sensor transformation matrix.
2153    ///
2154    /// The value is expressed as half-precision floating-point format:
2155    /// SEEEEEFFFFFFFFFF (S: 1 sign bit; E: 5 exponent bits; F: 10 fraction bits).
2156    pub fn fsm_ext_sens_matrix_set(
2157        &mut self,
2158        val: XlFsmExtSensMatrix,
2159    ) -> Result<(), Error<B::Error>> {
2160        let buff: [u8; 12] = val.to_le_bytes();
2161
2162        FsmExtMatrix(buff).write(self)
2163    }
2164    /// Get the External sensor transformation matrix.
2165    ///
2166    /// The value is expressed as half-precision floating-point format:
2167    /// SEEEEEFFFFFFFFFF (S: 1 sign bit; E: 5 exponent bits; F: 10 fraction bits).
2168    pub fn fsm_ext_sens_matrix_get(&mut self) -> Result<XlFsmExtSensMatrix, Error<B::Error>> {
2169        let buff: [u8; 12] = FsmExtMatrix::read(self)?.0;
2170        Ok(XlFsmExtSensMatrix::from_le_bytes(buff))
2171    }
2172    /// Set External sensor z-axis coordinates rotation.
2173    pub fn fsm_ext_sens_z_orient_set(
2174        &mut self,
2175        val: FsmExtSensZOrient,
2176    ) -> Result<(), Error<B::Error>> {
2177        let mut ext_cfg_a = ExtCfgA::read(self)?;
2178        ext_cfg_a.set_ext_z_axis((val as u8) & 0x07);
2179        ext_cfg_a.write(self)
2180    }
2181    /// Get External sensor z-axis coordinates rotation.
2182    pub fn fsm_ext_sens_z_orient_get(&mut self) -> Result<FsmExtSensZOrient, Error<B::Error>> {
2183        let ext_cfg_a = ExtCfgA::read(self)?;
2184
2185        let orientation = match ext_cfg_a.ext_z_axis() {
2186            0x0 => FsmExtSensZOrient::ZEqY,
2187            0x1 => FsmExtSensZOrient::ZEqMinY,
2188            0x2 => FsmExtSensZOrient::ZEqX,
2189            0x3 => FsmExtSensZOrient::ZEqMinX,
2190            0x4 => FsmExtSensZOrient::ZEqMinZ,
2191            0x5 => FsmExtSensZOrient::ZEqZ,
2192            _ => FsmExtSensZOrient::ZEqY, // Default case
2193        };
2194
2195        Ok(orientation)
2196    }
2197    /// Set External sensor Y-axis coordinates rotation.
2198    pub fn fsm_ext_sens_y_orient_set(
2199        &mut self,
2200        val: FsmExtSensYOrient,
2201    ) -> Result<(), Error<B::Error>> {
2202        let mut ext_cfg_a = ExtCfgA::read(self)?;
2203        ext_cfg_a.set_ext_y_axis((val as u8) & 0x7);
2204        ext_cfg_a.write(self)
2205    }
2206    /// Get External sensor Y-axis coordinates rotation.
2207    pub fn fsm_ext_sens_y_orient_get(&mut self) -> Result<FsmExtSensYOrient, Error<B::Error>> {
2208        let ext_cfg_a = ExtCfgA::read(self)?;
2209        let val = FsmExtSensYOrient::try_from(ext_cfg_a.ext_y_axis()).unwrap_or_default();
2210
2211        Ok(val)
2212    }
2213    /// Set External sensor X-axis coordinates rotation.
2214    pub fn fsm_ext_sens_x_orient_set(
2215        &mut self,
2216        val: FsmExtSensXOrient,
2217    ) -> Result<(), Error<B::Error>> {
2218        let mut ext_cfg_b = ExtCfgB::read(self)?;
2219        ext_cfg_b.set_ext_x_axis((val as u8) & 0x7);
2220        ext_cfg_b.write(self)
2221    }
2222    /// Get External sensor X-axis coordinates rotation.
2223    pub fn fsm_ext_sens_x_orient_get(&mut self) -> Result<FsmExtSensXOrient, Error<B::Error>> {
2224        let ext_cfg_b = ExtCfgB::read(self)?;
2225        let val = FsmExtSensXOrient::try_from(ext_cfg_b.ext_x_axis()).unwrap_or_default();
2226
2227        Ok(val)
2228    }
2229    /// Set FSM long counter timeout.
2230    ///
2231    /// The long counter timeout value is an unsigned integer value (16-bit format).
2232    /// When the long counter value reaches this value, the FSM generates an interrupt.
2233    pub fn fsm_long_cnt_timeout_set(&mut self, val: u16) -> Result<(), Error<B::Error>> {
2234        FsmLcTimeout(val).write(self)
2235    }
2236    /// Get FSM long counter timeout.
2237    ///
2238    /// The long counter timeout value is an unsigned integer value (16-bit format).
2239    /// When the long counter value reached this value, the FSM generates an interrupt.
2240    pub fn fsm_long_cnt_timeout_get(&mut self) -> Result<u16, Error<B::Error>> {
2241        FsmLcTimeout::read(self).map(|reg| reg.0)
2242    }
2243    /// Set the FSM number of programs.
2244    ///
2245    /// Must be less than or equal to 8. Default 0.
2246    pub fn fsm_number_of_programs_set(&mut self, val: u8) -> Result<(), Error<B::Error>> {
2247        let mut fsm_programs = FsmPrograms::read(self)?;
2248        fsm_programs.set_fsm_n_prog(val);
2249        fsm_programs.write(self)
2250    }
2251    /// Get the actual FSM number of programs.
2252    pub fn fsm_number_of_programs_get(&mut self) -> Result<u8, Error<B::Error>> {
2253        let val: u8 = FsmPrograms::read(self)?.fsm_n_prog();
2254        Ok(val)
2255    }
2256    /// Set the FSM start address.
2257    ///
2258    /// First available address is 0x35C.
2259    pub fn fsm_start_address_set(&mut self, val: u16) -> Result<(), Error<B::Error>> {
2260        FsmStartAdd(val).write(self)
2261    }
2262    /// Get the actual FSM start address.
2263    ///
2264    /// First available address is 0x35C.
2265    pub fn fsm_start_address_get(&mut self) -> Result<u16, Error<B::Error>> {
2266        FsmStartAdd::read(self).map(|reg| reg.0)
2267    }
2268    /// Set the time windows configuration for Free Fall detection.
2269    ///
2270    /// 1 LSB = 1/ODR_XL time
2271    pub fn ff_time_windows_set(&mut self, val: u8) -> Result<(), Error<B::Error>> {
2272        // Read WAKE_UP_DUR and configure wake_up_dur
2273        let mut wake_up_dur = WakeUpDur::read(self)?;
2274        wake_up_dur.set_ff_dur((val & 0x20) >> 5);
2275        wake_up_dur.write(self)?;
2276
2277        // Read FREE_FALL and configure free_fall
2278        let mut free_fall = FreeFall::read(self)?;
2279        free_fall.set_ff_dur(val & 0x1F);
2280        free_fall.write(self)
2281    }
2282    /// Get the time windows configuration for Free Fall detection.
2283    ///
2284    /// 1 LSB = 1/ODR_XL time
2285    pub fn ff_time_windows_get(&mut self) -> Result<u8, Error<B::Error>> {
2286        let wake_up_dur = WakeUpDur::read(self)?;
2287        let free_fall = FreeFall::read(self)?;
2288
2289        let val: u8 = (wake_up_dur.ff_dur() << 5) + free_fall.ff_dur();
2290
2291        Ok(val)
2292    }
2293    /// Set the Free fall threshold.
2294    pub fn ff_thresholds_set(&mut self, val: FfThreshold) -> Result<(), Error<B::Error>> {
2295        let mut free_fall = FreeFall::read(self)?;
2296        free_fall.set_ff_ths((val as u8) & 0x7);
2297
2298        free_fall.write(self)
2299    }
2300    /// Get the current Free fall threshold setting.
2301    pub fn ff_thresholds_get(&mut self) -> Result<FfThreshold, Error<B::Error>> {
2302        let free_fall = FreeFall::read(self)?;
2303
2304        let val = FfThreshold::try_from(free_fall.ff_ths()).unwrap_or_default();
2305
2306        Ok(val)
2307    }
2308    /// Set Machine Learning Core mode (MLC).
2309    ///registermod
2310    /// When the Machine Learning Core is enabled the Finite State Machine (FSM)
2311    /// programs are executed before executing the MLC algorithms.
2312    pub fn mlc_set(&mut self, val: MlcMode) -> Result<(), Error<B::Error>> {
2313        MemBank::operate_over_embed(self, |state| {
2314            let mut emb_en_a = EmbFuncEnA::read(state)?;
2315            let mut emb_en_b = EmbFuncEnB::read(state)?;
2316
2317            match val {
2318                MlcMode::Off => {
2319                    emb_en_a.set_mlc_before_fsm_en(0);
2320                    emb_en_b.set_mlc_en(0);
2321                }
2322                MlcMode::On => {
2323                    emb_en_a.set_mlc_before_fsm_en(0);
2324                    emb_en_b.set_mlc_en(1);
2325                }
2326                MlcMode::OnBeforeFsm => {
2327                    emb_en_a.set_mlc_before_fsm_en(1);
2328                    emb_en_b.set_mlc_en(0);
2329                }
2330            }
2331
2332            emb_en_a.write(state)?;
2333            emb_en_b.write(state)
2334        })
2335    }
2336    /// Get the configuration ofMachine Learning Core (MLC).
2337    ///
2338    /// When the Machine Learning Core is enabled the Finite State Machine (FSM)
2339    /// programs are executed before executing the MLC algorithms.
2340    pub fn mlc_get(&mut self) -> Result<MlcMode, Error<B::Error>> {
2341        MemBank::operate_over_embed(self, |state| {
2342            let emb_en_a = EmbFuncEnA::read(state)?;
2343            let emb_en_b = EmbFuncEnB::read(state)?;
2344
2345            let val = match (emb_en_a.mlc_before_fsm_en(), emb_en_b.mlc_en()) {
2346                (0, 0) => MlcMode::Off,
2347                (0, 1) => MlcMode::On,
2348                (1, _) => MlcMode::OnBeforeFsm,
2349                _ => MlcMode::Off,
2350            };
2351
2352            Ok(val)
2353        })
2354    }
2355    /// Set Machine Learning Core Output Data Rate (ODR).
2356    pub fn mlc_data_rate_set(&mut self, val: MlcDataRate) -> Result<(), Error<B::Error>> {
2357        MemBank::operate_over_embed(self, |state| {
2358            let mut mlc_odr = MlcOdr::read(state)?;
2359            mlc_odr.set_mlc_odr((val as u8) & 0x07);
2360            mlc_odr.write(state)
2361        })
2362    }
2363    /// Get the Machine Learning Core Output Data Rate (ODR).
2364    pub fn mlc_data_rate_get(&mut self) -> Result<MlcDataRate, Error<B::Error>> {
2365        MemBank::operate_over_embed(self, |state| {
2366            let mlc_odr = MlcOdr::read(state)?;
2367            let val = MlcDataRate::try_from(mlc_odr.mlc_odr()).unwrap_or_default();
2368            Ok(val)
2369        })
2370    }
2371    /// Get the output value of all MLC decision trees.
2372    pub fn mlc_out_get(&mut self) -> Result<MlcOut, Error<B::Error>> {
2373        MemBank::operate_over_embed(self, |state| {
2374            let mlc_outs = MlcSrc::read(state)?.0;
2375            Ok(MlcOut::from_le_bytes(mlc_outs))
2376        })
2377    }
2378    /// Set the External sensor sensitivity value register for the Machine Learning Core.
2379    ///
2380    /// This register corresponds to the conversion value of the external sensor.
2381    /// The register value is expressed as half-precision floating-point format:
2382    /// SEEEEEFFFFFFFFFF (S: 1 sign bit; E: 5 exponent bits; F: 10 fraction bits).
2383    /// Default value is 0x3C00 (when using an external magnetometer this value
2384    /// corresponds to 1 gauss/LSB).
2385    pub fn mlc_ext_sens_sensitivity_set(&mut self, val: u16) -> Result<(), Error<B::Error>> {
2386        MlcExtSensitivity(val).write(self)
2387    }
2388    /// Get the External sensor sensitivity value register for the Machine Learning Core.
2389    ///
2390    /// This register corresponds to the conversion value of the external sensor.
2391    /// The register value is expressed as half-precision floating-point format:
2392    /// SEEEEEFFFFFFFFFF (S: 1 sign bit; E: 5 exponent bits; F: 10 fraction bits).
2393    /// Default value is 0x3C00 (when using an external magnetometer this value
2394    /// corresponds to 1 gauss/LSB).
2395    pub fn mlc_ext_sens_sensitivity_get(&mut self) -> Result<u16, Error<B::Error>> {
2396        MlcExtSensitivity::read(self).map(|reg| reg.0)
2397    }
2398    /// Get the configuration for the full control of OIS configurations from the UI (User Interface).
2399    pub fn ois_ctrl_mode_set(&mut self, val: OisCtrlMode) -> Result<(), Error<B::Error>> {
2400        let mut func_cfg_access = FuncCfgAccess::read(self)?;
2401        func_cfg_access.set_ois_ctrl_from_ui((val as u8) & 0x1);
2402        func_cfg_access.write(self)
2403    }
2404    /// Get the configuration for the full control of OIS configurations from the UI (User Interface).
2405    pub fn ois_ctrl_mode_get(&mut self) -> Result<OisCtrlMode, Error<B::Error>> {
2406        let func_cfg_access = FuncCfgAccess::read(self)?;
2407
2408        let val = OisCtrlMode::try_from(func_cfg_access.ois_ctrl_from_ui()).unwrap_or_default();
2409
2410        Ok(val)
2411    }
2412    /// Resets the control registers of OIS from the UI (User Interface).
2413    ///
2414    /// The bits set are not auto-cleared.
2415    pub fn ois_reset_set(&mut self, val: i8) -> Result<(), Error<B::Error>> {
2416        let mut func_cfg_access = FuncCfgAccess::read(self)?;
2417
2418        func_cfg_access.set_spi2_reset(val as u8);
2419
2420        func_cfg_access.write(self)
2421    }
2422    /// Get Resets the control registers of OIS from the UI (User Interface)
2423    pub fn ois_reset_get(&mut self) -> Result<i8, Error<B::Error>> {
2424        let val: i8 = FuncCfgAccess::read(self).map(|reg| reg.spi2_reset() as i8)?;
2425
2426        Ok(val)
2427    }
2428    /// Enable/disable pull up on OIS interface.
2429    pub fn ois_interface_pull_up_set(&mut self, val: u8) -> Result<(), Error<B::Error>> {
2430        let mut pin_ctrl = PinCtrl::read(self)?;
2431        pin_ctrl.set_ois_pu_dis(val);
2432        pin_ctrl.write(self)
2433    }
2434    /// Get the configuration (enable/disable) pull up on OIS interface.
2435    pub fn ois_interface_pull_up_get(&mut self) -> Result<u8, Error<B::Error>> {
2436        let val: u8 = PinCtrl::read(self).map(|reg| reg.ois_pu_dis())?;
2437
2438        Ok(val)
2439    }
2440    /// Set Handshake for UI (User Interface) SPI2 shared registers.
2441    ///
2442    /// ACK: This bit acknowledges the handshake. If the secondary interface is not accessing the shared registers,
2443    /// this bit is set to 1 by the device and the R/W operation on the UI_SPI2_SHARED registers is allowed
2444    /// on the primary interface.
2445    ///
2446    /// REQ: This bit is used by the primary interface master to request access to the UI_SPI2_SHARED registers.
2447    /// When the R/W operation is finished, the master must reset this bit.
2448    pub fn ois_handshake_from_ui_set(&mut self, val: OisHandshake) -> Result<(), Error<B::Error>> {
2449        let mut ui_handshake_ctrl = UiHandshakeCtrl::read(self)?;
2450        ui_handshake_ctrl.set_ui_shared_ack(val.ack);
2451        ui_handshake_ctrl.set_ui_shared_req(val.req);
2452        ui_handshake_ctrl.write(self)
2453    }
2454    /// Get Handshake for UI (User Interface) SPI2 shared registers.
2455    ///
2456    /// ACK: This bit acknowledges the handshake.
2457    /// If the secondary interface is not accessing the shared registers, this bit is set to 1 by the device and the R/W operation
2458    /// on the UI_SPI2_SHARED registers is allowed on the primary interface. REQ: This bit is used by the primary interface master
2459    /// to request access to the UI_SPI2_SHARED registers. When the R/W operation is finished, the master must reset this bit.
2460    pub fn ois_handshake_from_ui_get(&mut self) -> Result<OisHandshake, Error<B::Error>> {
2461        let ui_handshake_ctrl: UiHandshakeCtrl = UiHandshakeCtrl::read(self)?;
2462        let value = OisHandshake {
2463            ack: ui_handshake_ctrl.ui_shared_ack(),
2464            req: ui_handshake_ctrl.ui_shared_req(),
2465        };
2466        Ok(value)
2467    }
2468    /// Set Handshake for OIS interface SPI2 shared registers.
2469    ///
2470    /// ACK: This bit acknowledges the handshake. If the secondary interface is not accessing the shared registers,
2471    /// this bit is set to 1 by the device and the R/W operation on the UI_SPI2_SHARED registers is allowed on the primary interface.
2472    /// REQ: This bit is used by the primary interface master to request access to the UI_SPI2_SHARED registers.
2473    /// When the R/W operation is finished, the master must reset this bit.
2474    pub fn ois_handshake_from_ois_set(&mut self, val: OisHandshake) -> Result<(), Error<B::Error>> {
2475        let mut spi2_handshake_ctrl: Spi2HandshakeCtrl = Spi2HandshakeCtrl::read(self)?;
2476        spi2_handshake_ctrl.set_spi2_shared_ack(val.ack);
2477        spi2_handshake_ctrl.set_spi2_shared_req(val.req);
2478        spi2_handshake_ctrl.write(self)
2479    }
2480    /// Get Handshake for OIS interface SPI2 shared registers.
2481    ///
2482    /// ACK: This bit acknowledges the handshake. If the secondary interface is not accessing
2483    /// the shared registers, this bit is set to 1 by the device and the R/W operation on the
2484    /// UI_SPI2_SHARED registers is allowed on the primary interface.
2485    /// REQ: This bit is used by the primary interface master to request access to the
2486    /// UI_SPI2_SHARED registers. When the R/W operation is finished, the master must reset this bit.
2487    pub fn ois_handshake_from_ois_get(&mut self) -> Result<OisHandshake, Error<B::Error>> {
2488        let spi2_handshake_ctrl = Spi2HandshakeCtrl::read(self)?;
2489        let val = OisHandshake {
2490            ack: spi2_handshake_ctrl.spi2_shared_ack(),
2491            req: spi2_handshake_ctrl.spi2_shared_req(),
2492        };
2493
2494        Ok(val)
2495    }
2496    /// Set User interface (UI) / SPI2 (OIS) shared registers
2497    pub fn ois_shared_set(&mut self, val: [u8; 6]) -> Result<(), Error<B::Error>> {
2498        UiSpi2Shared(val).write(self)
2499    }
2500    /// Get User interface (UI) / SPI2 (OIS) shared registers
2501    pub fn ois_shared_get(&mut self) -> Result<[u8; 6], Error<B::Error>> {
2502        UiSpi2Shared::read(self).map(|reg| reg.0)
2503    }
2504    /// Enables SPI2 (OIS Interface) for reading OIS data when User Interface (UI) is in full control mode
2505    ///
2506    /// This function works also on OIS (UI_CTRL1_OIS = SPI2_CTRL1_OIS).
2507    pub fn ois_on_spi2_set(&mut self, val: u8) -> Result<(), Error<B::Error>> {
2508        let mut ui_ctrl1_ois = UiCtrl1Ois::read(self)?;
2509        ui_ctrl1_ois.set_spi2_read_en(val);
2510        ui_ctrl1_ois.write(self)
2511    }
2512    /// Get configuration (enable/disable) of SPI2 (OIS Interface) for reading OIS data when
2513    /// User Interface (UI) is in full control mode
2514    ///
2515    /// This function works also on OIS (UI_CTRL1_OIS = SPI2_CTRL1_OIS).
2516    pub fn ois_on_spi2_get(&mut self) -> Result<u8, Error<B::Error>> {
2517        let val: u8 = UiCtrl1Ois::read(self).map(|reg| reg.spi2_read_en())?;
2518
2519        Ok(val)
2520    }
2521    /// Enables gyroscope/accelerometer OIS chain.
2522    ///
2523    /// This function works also on OIS (UI_CTRL1_OIS = SPI2_CTRL1_OIS).
2524    pub fn ois_chain_set(&mut self, val: OisChain) -> Result<(), Error<B::Error>> {
2525        let mut ui_ctrl1_ois = UiCtrl1Ois::read(self)?;
2526        ui_ctrl1_ois.set_ois_g_en(val.gy);
2527        ui_ctrl1_ois.set_ois_xl_en(val.xl);
2528        ui_ctrl1_ois.write(self)
2529    }
2530    /// Get the configuration (enable/disable) gyroscope/accelerometer OIS chain.
2531    pub fn ois_chain_get(&mut self) -> Result<OisChain, Error<B::Error>> {
2532        let ui_ctrl1_ois = UiCtrl1Ois::read(self)?;
2533        let gy = ui_ctrl1_ois.ois_g_en();
2534        let xl = ui_ctrl1_ois.ois_xl_en();
2535
2536        let val = OisChain { gy, xl };
2537
2538        Ok(val)
2539    }
2540    /// Set gyroscope OIS full-scale
2541    pub fn ois_gy_full_scale_set(&mut self, val: OisGyFullScale) -> Result<(), Error<B::Error>> {
2542        let mut ui_ctrl2_ois = UiCtrl2Ois::read(self)?;
2543        ui_ctrl2_ois.set_fs_g_ois(val as u8 & 0x03);
2544        ui_ctrl2_ois.write(self)
2545    }
2546    /// Get the gyroscope OIS full-scale selection
2547    pub fn ois_gy_full_scale_get(&mut self) -> Result<OisGyFullScale, Error<B::Error>> {
2548        let fs_g_ois = UiCtrl2Ois::read(self).map(|reg| reg.fs_g_ois())?;
2549
2550        let val = OisGyFullScale::try_from(fs_g_ois).unwrap_or_default();
2551
2552        Ok(val)
2553    }
2554    /// Set accelerometer OIS channel full-scale.
2555    pub fn ois_xl_full_scale_set(&mut self, val: OisXlFullScale) -> Result<(), Error<B::Error>> {
2556        let mut ui_ctrl3_ois = UiCtrl3Ois::read(self)?;
2557        ui_ctrl3_ois.set_fs_xl_ois((val as u8) & 0x3);
2558        ui_ctrl3_ois.write(self)
2559    }
2560    /// Get accelerometer OIS channel full-scale.
2561    pub fn ois_xl_full_scale_get(&mut self) -> Result<OisXlFullScale, Error<B::Error>> {
2562        let ui_ctrl3_ois = UiCtrl3Ois::read(self)?;
2563
2564        let val = OisXlFullScale::try_from(ui_ctrl3_ois.fs_xl_ois()).unwrap_or_default();
2565
2566        Ok(val)
2567    }
2568    /// Set Threshold for 4D/6D function.
2569    pub fn threshold_6d_set(&mut self, val: SixDThreshold) -> Result<(), Error<B::Error>> {
2570        let mut tap_ths_6d = TapThs6d::read(self)?;
2571        tap_ths_6d.set_sixd_ths((val as u8) & 0x03);
2572        tap_ths_6d.write(self)
2573    }
2574    /// Get Threshold for 4D/6D function.
2575    pub fn threshold_6d_get(&mut self) -> Result<SixDThreshold, Error<B::Error>> {
2576        let tap_ths_6d = TapThs6d::read(self)?;
2577
2578        let value = SixDThreshold::try_from(tap_ths_6d.sixd_ths()).unwrap_or_default();
2579
2580        Ok(value)
2581    }
2582    /// Enables/Disables 4D orientation detection.
2583    ///
2584    /// Z-axis position detection is disabled.
2585    pub fn mode_4d_set(&mut self, val: u8) -> Result<(), Error<B::Error>> {
2586        let mut reg = TapThs6d::read(self)?;
2587        reg.set_d4d_en(val);
2588        reg.write(self)
2589    }
2590    /// Get the configuration for 4D orientation detection enable.
2591    ///
2592    /// Z-axis position detection is disabled.
2593    pub fn mode_4d_get(&mut self) -> Result<u8, Error<B::Error>> {
2594        let val: u8 = TapThs6d::read(self).map(|reg| reg.d4d_en())?;
2595
2596        Ok(val)
2597    }
2598    /// Configures the equivalent input impedance of the AH_QVAR buffers.
2599    pub fn ah_qvar_zin_set(&mut self, val: AhQvarZin) -> Result<(), Error<B::Error>> {
2600        let mut ctrl7 = Ctrl7::read(self)?;
2601        ctrl7.set_ah_qvar_c_zin((val as u8) & 0x03);
2602        ctrl7.write(self)
2603    }
2604    /// Get the actual input impedance of the AH_QVAR buffers.
2605    pub fn ah_qvar_zin_get(&mut self) -> Result<AhQvarZin, Error<B::Error>> {
2606        let ctrl7 = Ctrl7::read(self)?;
2607
2608        let result = AhQvarZin::try_from(ctrl7.ah_qvar_c_zin()).unwrap_or_default();
2609
2610        Ok(result)
2611    }
2612    /// Enables AH_QVAR chain.
2613    ///
2614    /// When this bit is set to '1', the AH_QVAR buffers are connected to the SDx/AH1/Qvar1 and SCx/AH2/Qvar2 pins.
2615    /// Before setting this bit to 1, the accelerometer and gyroscope sensor have to be configured in power-down mode.
2616    pub fn ah_qvar_mode_set(&mut self, val: AhQvarMode) -> Result<(), Error<B::Error>> {
2617        let mut ctrl7 = Ctrl7::read(self)?;
2618        ctrl7.set_ah_qvar_en(val.ah_qvar_en);
2619        ctrl7.write(self)
2620    }
2621    /// Get configuration (enable/disable) for AH_QVAR chain.
2622    ///
2623    /// When this bit is set to '1', the AH_QVAR buffers are connected to the SDx/AH1/Qvar1 and SCx/AH2/Qvar2 pins.
2624    /// Before setting this bit to 1, the accelerometer and gyroscope sensor have to be configured in power-down mode.
2625    pub fn ah_qvar_mode_get(&mut self) -> Result<AhQvarMode, Error<B::Error>> {
2626        let ctrl7 = Ctrl7::read(self)?;
2627        let val = AhQvarMode {
2628            ah_qvar_en: ctrl7.ah_qvar_en(),
2629        };
2630
2631        Ok(val)
2632    }
2633    /// Set the action the device will perform after "Reset whole chip" I3C pattern.
2634    pub fn i3c_reset_mode_set(&mut self, val: I3cResetMode) -> Result<(), Error<B::Error>> {
2635        let mut pin_ctrl = PinCtrl::read(self)?;
2636        pin_ctrl.set_ibhr_por_en((val as u8) & 0x01);
2637        pin_ctrl.write(self)
2638    }
2639    /// Get the i3c reset mode.
2640    ///
2641    /// After set the action the device will perform after "Reset whole chip" I3C pattern.
2642    pub fn i3c_reset_mode_get(&mut self) -> Result<I3cResetMode, Error<B::Error>> {
2643        let pin_ctrl = PinCtrl::read(self)?;
2644        let mode = I3cResetMode::try_from(pin_ctrl.ibhr_por_en()).unwrap_or_default();
2645        Ok(mode)
2646    }
2647    /// Enable/Disable INT pin when I3C is used.
2648    pub fn i3c_int_en_set(&mut self, val: u8) -> Result<(), Error<B::Error>> {
2649        let mut ctrl5 = Ctrl5::read(self)?;
2650        ctrl5.set_int_en_i3c(val & 0x01);
2651        ctrl5.write(self)
2652    }
2653    /// Get configuration (enable/disable) INT pin when I3C is used.
2654    pub fn i3c_int_en_get(&mut self) -> Result<u8, Error<B::Error>> {
2655        let val: u8 = Ctrl5::read(self).map(|reg| reg.int_en_i3c())?;
2656
2657        Ok(val)
2658    }
2659    /// Set the us activity time for IBI (In-Band Interrupt) with I3C.
2660    pub fn i3c_ibi_time_set(&mut self, val: I3cIbiTime) -> Result<(), Error<B::Error>> {
2661        let mut ctrl5 = Ctrl5::read(self)?;
2662        ctrl5.set_bus_act_sel((val as u8) & 0x03);
2663        ctrl5.write(self)
2664    }
2665    /// Get the us activity time for IBI (In-Band Interrupt) with I3C.
2666    pub fn i3c_ibi_time_get(&mut self) -> Result<I3cIbiTime, Error<B::Error>> {
2667        let ctrl5 = Ctrl5::read(self)?;
2668
2669        let val = I3cIbiTime::try_from(ctrl5.bus_act_sel()).unwrap_or_default();
2670
2671        Ok(val)
2672    }
2673    /// Enable/Disable Sensor Hub master I2C pull-up.
2674    pub fn sh_master_interface_pull_up_set(&mut self, val: u8) -> Result<(), Error<B::Error>> {
2675        let mut if_cfg = IfCfg::read(self)?;
2676        if_cfg.set_shub_pu_en(val);
2677        if_cfg.write(self)
2678    }
2679    /// Get Sensor Hub master I2C pull-up configuration (enable/disable).
2680    pub fn sh_master_interface_pull_up_get(&mut self) -> Result<u8, Error<B::Error>> {
2681        let val: u8 = IfCfg::read(self).map(|reg| reg.shub_pu_en())?;
2682
2683        Ok(val)
2684    }
2685    /// Sensor hub output registers.
2686    ///
2687    /// The length of the array input determines the length of the read.
2688    /// Valid range goes from 0..18
2689    pub fn sh_read_data_raw_get(&mut self, rbuf: &mut [u8]) -> Result<(), Error<B::Error>> {
2690        MemBank::operate_over_sensorhub(self, |state| SensorHub1::read_more(state, rbuf))
2691    }
2692    /// Set the number of external sensors to be read by the sensor hub.
2693    pub fn sh_slave_connected_set(&mut self, val: ShSlaveConnected) -> Result<(), Error<B::Error>> {
2694        MemBank::operate_over_sensorhub(self, |state| {
2695            let mut master_config = MasterConfig::read(state)?;
2696            master_config.set_aux_sens_on((val as u8) & 0x3);
2697            master_config.write(state)
2698        })
2699    }
2700    /// Get the number of external sensors to be read by the sensor hub.
2701    pub fn sh_slave_connected_get(&mut self) -> Result<ShSlaveConnected, Error<B::Error>> {
2702        MemBank::operate_over_sensorhub(self, |state| {
2703            let master_config = MasterConfig::read(state)?;
2704            let result =
2705                ShSlaveConnected::try_from(master_config.aux_sens_on()).unwrap_or_default();
2706            Ok(result)
2707        })
2708    }
2709    /// Enable/Disable Sensor hub I2C master configuration.
2710    pub fn sh_master_set(&mut self, val: u8) -> Result<(), Error<B::Error>> {
2711        MemBank::operate_over_sensorhub(self, |state| {
2712            let mut master_config = MasterConfig::read(state)?;
2713            master_config.set_master_on(val);
2714            master_config.write(state)
2715        })
2716    }
2717    /// Get Sensor hub I2C master configuration (enable/disable).
2718    pub fn sh_master_get(&mut self) -> Result<u8, Error<B::Error>> {
2719        MemBank::operate_over_sensorhub(self, |state| {
2720            let master_config = MasterConfig::read(state)?;
2721            let val: u8 = master_config.master_on();
2722            Ok(val)
2723        })
2724    }
2725    /// Enable/Disable I2C interface pass-through.
2726    pub fn sh_pass_through_set(&mut self, val: u8) -> Result<(), Error<B::Error>> {
2727        // Set the memory bank to SensorHubMemBank
2728        MemBank::operate_over_sensorhub(self, |state| {
2729            // Modify the MasterConfig register
2730            let mut master_config = MasterConfig::read(state)?;
2731            master_config.set_pass_through_mode(val);
2732            master_config.write(state)
2733        })
2734    }
2735    /// Get I2C interface pass-through configuration (enable/disable).
2736    pub fn sh_pass_through_get(&mut self) -> Result<u8, Error<B::Error>> {
2737        MemBank::operate_over_sensorhub(self, |state| {
2738            let master_config = MasterConfig::read(state)?;
2739            let val: u8 = master_config.pass_through_mode();
2740            Ok(val)
2741        })
2742    }
2743    /// Set Sensor hub trigger signal configuration.
2744    pub fn sh_syncro_mode_set(&mut self, val: ShSyncroMode) -> Result<(), Error<B::Error>> {
2745        MemBank::operate_over_sensorhub(self, |state| {
2746            let mut master_config = MasterConfig::read(state)?;
2747            master_config.set_start_config((val as u8) & 0x01);
2748            master_config.write(state)
2749        })
2750    }
2751    /// Get Sensor hub trigger signal configuration.
2752    pub fn sh_syncro_mode_get(&mut self) -> Result<ShSyncroMode, Error<B::Error>> {
2753        MemBank::operate_over_sensorhub(self, |state| {
2754            let master_config = MasterConfig::read(state)?;
2755            let val = ShSyncroMode::try_from(master_config.start_config()).unwrap_or_default();
2756            Ok(val)
2757        })
2758    }
2759    /// Set Slave 0 write operation mode.
2760    ///
2761    /// Permit switch write mode between: only at the first sensor hub cycle or at each sensor hub cycle.
2762    pub fn sh_write_mode_set(&mut self, val: ShWriteMode) -> Result<(), Error<B::Error>> {
2763        MemBank::operate_over_sensorhub(self, |state| {
2764            let mut master_config = MasterConfig::read(state)?;
2765            master_config.set_write_once(val as u8 & 0x01);
2766            master_config.write(state)
2767        })
2768    }
2769    /// Get Slave 0 write operation mode.
2770    pub fn sh_write_mode_get(&mut self) -> Result<ShWriteMode, Error<B::Error>> {
2771        MemBank::operate_over_sensorhub(self, |state| {
2772            let write_once = MasterConfig::read(state)?.write_once();
2773            let mode = ShWriteMode::try_from(write_once).unwrap_or_default();
2774            Ok(mode)
2775        })
2776    }
2777    /// Reset Master logic and output registers.
2778    ///
2779    /// Must be set to '1' and then set it to '0'.
2780    pub fn sh_reset_set(&mut self, val: u8) -> Result<(), Error<B::Error>> {
2781        MemBank::operate_over_sensorhub(self, |state| {
2782            let mut master_config = MasterConfig::read(state)?;
2783            master_config.set_rst_master_regs(val);
2784            master_config.write(state)
2785        })
2786    }
2787    /// Get Reset Master logic and output registers.
2788    ///
2789    /// Must be set to '1' and then set it to '0'.
2790    pub fn sh_reset_get(&mut self) -> Result<u8, Error<B::Error>> {
2791        MemBank::operate_over_sensorhub(self, |state| {
2792            let master_config = MasterConfig::read(state)?;
2793            Ok(master_config.rst_master_regs())
2794        })
2795    }
2796    /// Configure slave 0 to perform a write.
2797    pub fn sh_cfg_write(&mut self, val: ShCfgWrite) -> Result<(), Error<B::Error>> {
2798        // Set the memory bank to SensorHubMemBank
2799        MemBank::operate_over_sensorhub(self, |state| {
2800            let mut reg = Slv0Add::read(state)?;
2801            reg.set_slave0_add(val.slv0_add);
2802            reg.set_rw_0(0);
2803            // Write to the Slv0Add register
2804            reg.write(state)?;
2805
2806            // Write to the DatawriteSlv0 register
2807            let data_write_slv0 = DatawriteSlv0::from_bits(val.slv0_data);
2808            data_write_slv0.write(state)
2809        })
2810    }
2811    /// Set the rate at which the master communicates.
2812    pub fn sh_data_rate_set(&mut self, val: ShDataRate) -> Result<(), Error<B::Error>> {
2813        MemBank::operate_over_sensorhub(self, |state| {
2814            let mut slv0_config = Slv0Config::read(state)?;
2815
2816            slv0_config.set_shub_odr((val as u8) & 0x07);
2817            slv0_config.write(state)
2818        })
2819    }
2820    /// Get the rate at which the controller communicates.
2821    pub fn sh_data_rate_get(&mut self) -> Result<ShDataRate, Error<B::Error>> {
2822        MemBank::operate_over_sensorhub(self, |state| {
2823            let slv0_config = Slv0Config::read(state)?;
2824            let rate = ShDataRate::try_from(slv0_config.shub_odr()).unwrap_or_default();
2825            Ok(rate)
2826        })
2827    }
2828    /// Configure slave idx for performing a read.
2829    ///
2830    /// # Arguments
2831    ///
2832    /// * `idx`: Index of the slave.
2833    /// * `val`: Structure containing:
2834    ///    - `slv_add`: 8-bit I2C device address.
2835    ///    - `slv_subadd`: 8-bit register device address.
2836    ///    - `slv_len`: Number of bits to read.
2837    pub fn sh_slv_cfg_read(&mut self, idx: u8, val: &ShCfgRead) -> Result<(), Error<B::Error>> {
2838        self.mem_bank_set(MemBank::SensorHubMemBank)?;
2839        let mut arr: [u8; 1] = [0];
2840        let mut slv_add = Slv0Add::from_bits(arr[0]);
2841        slv_add.set_slave0_add(val.slv_add);
2842        slv_add.set_rw_0(1);
2843
2844        self.write_to_register(SnsHubReg::Slv0Add as u8 + (idx * 3), &[slv_add.into_bits()])?;
2845
2846        self.write_to_register(SnsHubReg::Slv0Subadd as u8 + (idx * 3), &[val.slv_subadd])?;
2847
2848        self.read_from_register(SnsHubReg::Slv0Config as u8 + (idx * 3), &mut arr)?;
2849        let mut slv_config = Slv0Config::from_bits(arr[0]);
2850        slv_config.set_slave0_numop(val.slv_len);
2851
2852        self.write_to_register(
2853            SnsHubReg::Slv0Config as u8 + (idx * 3),
2854            &[slv_config.into_bits()],
2855        )?;
2856
2857        self.mem_bank_set(MemBank::MainMemBank)
2858    }
2859    /// Get Sensor hub status register.
2860    pub fn sh_status_get(&mut self) -> Result<StatusMaster, Error<B::Error>> {
2861        let status = StatusMasterMainPage::read(self)?;
2862        Ok(StatusMaster::from_bits(status.into_bits()))
2863    }
2864    /// Enables/Disables pull-up on SDO pin of UI (User Interface).
2865    pub fn ui_sdo_pull_up_set(&mut self, val: u8) -> Result<(), Error<B::Error>> {
2866        let mut pin_ctrl = PinCtrl::read(self)?;
2867        pin_ctrl.set_sdo_pu_en(val);
2868        pin_ctrl.write(self)
2869    }
2870    /// Get the pull-up on SDO pin of UI (User Interface) configuration.
2871    pub fn ui_sdo_pull_up_get(&mut self) -> Result<u8, Error<B::Error>> {
2872        let val: u8 = PinCtrl::read(self).map(|reg| reg.sdo_pu_en())?;
2873
2874        Ok(val)
2875    }
2876    /// Enables/Disables I2C and I3C on UI (User Interface).
2877    pub fn ui_i2c_i3c_mode_set(&mut self, val: UiI2cI3cMode) -> Result<(), Error<B::Error>> {
2878        let mut if_cfg = IfCfg::read(self)?;
2879        if_cfg.set_i2c_i3c_disable((val as u8) & 0x1);
2880        if_cfg.write(self)
2881    }
2882    /// Get I2C and I3C on UI (User Interface) mode configuration.
2883    pub fn ui_i2c_i3c_mode_get(&mut self) -> Result<UiI2cI3cMode, Error<B::Error>> {
2884        let reg = IfCfg::read(self)?;
2885
2886        let val = UiI2cI3cMode::try_from(reg.i2c_i3c_disable()).unwrap_or_default();
2887
2888        Ok(val)
2889    }
2890    /// SPI Serial Interface Mode selection.
2891    pub fn spi_mode_set(&mut self, val: SpiMode) -> Result<(), Error<B::Error>> {
2892        let mut if_cfg = IfCfg::read(self)?;
2893        if_cfg.set_sim((val as u8) & 0x01);
2894        if_cfg.write(self)
2895    }
2896    /// Get the SPI Serial Interface Mode.
2897    pub fn spi_mode_get(&mut self) -> Result<SpiMode, Error<B::Error>> {
2898        let if_cfg = IfCfg::read(self)?;
2899
2900        let val = SpiMode::try_from(if_cfg.sim()).unwrap_or_default();
2901
2902        Ok(val)
2903    }
2904    /// Enables/Disables pull-up on SDA pin.
2905    pub fn ui_sda_pull_up_set(&mut self, val: u8) -> Result<(), Error<B::Error>> {
2906        let mut if_cfg = IfCfg::read(self)?;
2907        if_cfg.set_sda_pu_en(val);
2908        if_cfg.write(self)
2909    }
2910    /// Get pull-up configuration on SDA pin.
2911    pub fn ui_sda_pull_up_get(&mut self) -> Result<u8, Error<B::Error>> {
2912        let val: u8 = IfCfg::read(self).map(|reg| reg.sda_pu_en())?;
2913
2914        Ok(val)
2915    }
2916    /// Select SPI2 (OIS Interface) Serial Interface Mode.
2917    ///
2918    /// This function works also on OIS (UI_CTRL1_OIS = SPI2_CTRL1_OIS).
2919    pub fn spi2_mode_set(&mut self, val: Spi2Mode) -> Result<(), Error<B::Error>> {
2920        let mut ui_ctrl1_ois = UiCtrl1Ois::read(self)?;
2921        ui_ctrl1_ois.set_sim_ois((val as u8) & 0x01);
2922        ui_ctrl1_ois.write(self)
2923    }
2924    /// Get SPI2 (OIS Interface) Serial Interface Mode.
2925    /// This function also works on OIS (UI_CTRL1_OIS = SPI2_CTRL1_OIS).
2926    pub fn spi2_mode_get(&mut self) -> Result<Spi2Mode, Error<B::Error>> {
2927        let ui_ctrl1_ois = UiCtrl1Ois::read(self)?;
2928
2929        let val = Spi2Mode::try_from(ui_ctrl1_ois.sim_ois()).unwrap_or_default();
2930
2931        Ok(val)
2932    }
2933    /// Enables/Disables significant motion detection function.
2934    pub fn sigmot_mode_set(&mut self, val: u8) -> Result<(), Error<B::Error>> {
2935        MemBank::operate_over_embed(self, |state| {
2936            let mut emb_func_en_a = EmbFuncEnA::read(state)?;
2937            emb_func_en_a.set_sign_motion_en(val);
2938            emb_func_en_a.write(state)
2939        })
2940    }
2941    /// Get significant motion detection function configuration (enable/disable).
2942    pub fn sigmot_mode_get(&mut self) -> Result<u8, Error<B::Error>> {
2943        MemBank::operate_over_embed(self, |state| {
2944            EmbFuncEnA::read(state).map(|reg| reg.sign_motion_en())
2945        })
2946    }
2947    /// Set Step counter mode.
2948    pub fn stpcnt_mode_set(&mut self, val: StpcntMode) -> Result<(), Error<B::Error>> {
2949        MemBank::operate_over_embed(self, |state| {
2950            let mut emb_func_en_a = EmbFuncEnA::read(state)?;
2951            let emb_func_en_b = EmbFuncEnB::read(state)?;
2952
2953            if val.false_step_rej == 1
2954                && emb_func_en_a.mlc_before_fsm_en() & emb_func_en_b.mlc_en() == 0
2955            {
2956                emb_func_en_a.set_mlc_before_fsm_en(1);
2957            }
2958
2959            emb_func_en_a.set_pedo_en(val.step_counter_enable);
2960            emb_func_en_a.write(state)
2961        })?;
2962
2963        let mut pedo_cmd_reg = PedoCmdReg::read(self)?;
2964        pedo_cmd_reg.set_fp_rejection_en(val.false_step_rej);
2965        pedo_cmd_reg.write(self)
2966    }
2967    /// Get Step counter mode
2968    pub fn stpcnt_mode_get(&mut self) -> Result<StpcntMode, Error<B::Error>> {
2969        let emb_func_en_a = MemBank::operate_over_embed(self, |state| EmbFuncEnA::read(state))?;
2970        let pedo_cmd_reg = PedoCmdReg::read(self)?;
2971
2972        let val = StpcntMode {
2973            false_step_rej: pedo_cmd_reg.fp_rejection_en(),
2974            step_counter_enable: emb_func_en_a.pedo_en(),
2975        };
2976
2977        Ok(val)
2978    }
2979    /// Get Step counter output: number of detected steps.
2980    pub fn stpcnt_steps_get(&mut self) -> Result<u16, Error<B::Error>> {
2981        MemBank::operate_over_embed(self, |state| StepCounter::read(state).map(|reg| reg.0))
2982    }
2983    /// Reset step counter.
2984    ///
2985    /// If val is 1: step counter is reset
2986    pub fn stpcnt_rst_step_set(&mut self, val: u8) -> Result<(), Error<B::Error>> {
2987        MemBank::operate_over_embed(self, |state| {
2988            let mut emb_func_src: EmbFuncSrc = EmbFuncSrc::read(state)?;
2989            emb_func_src.set_pedo_rst_step(val);
2990            emb_func_src.write(state)
2991        })
2992    }
2993    /// Get reset step counter.
2994    pub fn stpcnt_rst_step_get(&mut self) -> Result<u8, Error<B::Error>> {
2995        MemBank::operate_over_embed(self, |state| {
2996            EmbFuncSrc::read(state).map(|reg| reg.pedo_rst_step())
2997        })
2998    }
2999    /// Set Pedometer debounce number.
3000    pub fn stpcnt_debounce_set(&mut self, val: u8) -> Result<(), Error<B::Error>> {
3001        let mut pedo_deb_steps_conf = PedoDebStepsConf::read(self)?;
3002        pedo_deb_steps_conf.set_deb_step(val);
3003        pedo_deb_steps_conf.write(self)
3004    }
3005    /// Get Pedometer debounce number.
3006    pub fn stpcnt_debounce_get(&mut self) -> Result<u8, Error<B::Error>> {
3007        let val: u8 = PedoDebStepsConf::read(self)?.deb_step();
3008
3009        Ok(val)
3010    }
3011    /// Set time period register for step detection on delta time.
3012    pub fn stpcnt_period_set(&mut self, val: u16) -> Result<(), Error<B::Error>> {
3013        let reg = PedoScDeltaT(val);
3014        reg.write(self)
3015    }
3016    /// Get time period register for step detection on delta time.
3017    pub fn stpcnt_period_get(&mut self) -> Result<u16, Error<B::Error>> {
3018        PedoScDeltaT::read(self).map(|reg| reg.0)
3019    }
3020    /// Enables/Disables SFLP Game Rotation Vector (6x).
3021    pub fn sflp_game_rotation_set(&mut self, val: u8) -> Result<(), Error<B::Error>> {
3022        MemBank::operate_over_embed(self, |state| {
3023            let mut emb_func_en_a = EmbFuncEnA::read(state)?;
3024            emb_func_en_a.set_sflp_game_en(val);
3025            emb_func_en_a.write(state)
3026        })
3027    }
3028    /// Get the configuration (enable/disable) for SFLP Game Rotation Vector (6x).
3029    pub fn sflp_game_rotation_get(&mut self) -> Result<u8, Error<B::Error>> {
3030        MemBank::operate_over_embed(self, |state| {
3031            let emb_func_en_a = EmbFuncEnA::read(state)?;
3032            Ok(emb_func_en_a.sflp_game_en())
3033        })
3034    }
3035    /// Set SFLP Data Rate (ODR).
3036    pub fn sflp_data_rate_set(&mut self, val: SflpDataRate) -> Result<(), Error<B::Error>> {
3037        MemBank::operate_over_embed(self, |state| {
3038            let mut sflp_odr = SflpOdr::read(state)?;
3039            sflp_odr.set_sflp_game_odr((val as u8) & 0x07);
3040            sflp_odr.write(state)
3041        })
3042    }
3043    /// Get SFLP Data Rate (ODR).
3044    pub fn sflp_data_rate_get(&mut self) -> Result<SflpDataRate, Error<B::Error>> {
3045        MemBank::operate_over_embed(self, |state| {
3046            let sflp = SflpOdr::read(state)?;
3047            let odr = SflpDataRate::try_from(sflp.sflp_game_odr()).unwrap_or_default();
3048            Ok(odr)
3049        })
3050    }
3051    /// Enable axis for Tap - Double Tap detection.
3052    pub fn tap_detection_set(&mut self, val: TapDetection) -> Result<(), Error<B::Error>> {
3053        let mut tap_cfg0 = TapCfg0::read(self)?;
3054        tap_cfg0.set_tap_x_en(val.tap_x_en);
3055        tap_cfg0.set_tap_y_en(val.tap_y_en);
3056        tap_cfg0.set_tap_z_en(val.tap_z_en);
3057        tap_cfg0.write(self)
3058    }
3059    /// Get configuration for Tap on each axis - Double Tap detection.
3060    pub fn tap_detection_get(&mut self) -> Result<TapDetection, Error<B::Error>> {
3061        let tap_cfg0 = TapCfg0::read(self)?;
3062
3063        let tap_detection = TapDetection {
3064            tap_x_en: tap_cfg0.tap_x_en(),
3065            tap_y_en: tap_cfg0.tap_y_en(),
3066            tap_z_en: tap_cfg0.tap_z_en(),
3067        };
3068
3069        Ok(tap_detection)
3070    }
3071    /// Set Double Tap recognition thresholds - axis Tap
3072    pub fn tap_thresholds_set(&mut self, val: TapThresholds) -> Result<(), Error<B::Error>> {
3073        let mut tap_cfg1 = TapCfg1::read(self)?;
3074        let mut tap_cfg2 = TapCfg2::read(self)?;
3075        let mut tap_ths_6d = TapThs6d::read(self)?;
3076
3077        tap_cfg1.set_tap_ths_x(val.x);
3078        tap_cfg2.set_tap_ths_y(val.y);
3079        tap_ths_6d.set_tap_ths_z(val.z);
3080
3081        tap_ths_6d.write(self)?;
3082        tap_cfg2.write(self)?;
3083        tap_cfg1.write(self)
3084    }
3085    /// Get Double Tap recognition thresholds - axis Tap
3086    pub fn tap_thresholds_get(&mut self) -> Result<TapThresholds, Error<B::Error>> {
3087        let tap_cfg1 = TapCfg1::read(self)?;
3088        let tap_cfg2 = TapCfg2::read(self)?;
3089        let tap_ths_6d = TapThs6d::read(self)?;
3090
3091        let thresholds = TapThresholds {
3092            // Dummy values or replace with appropriate method calls
3093            x: tap_cfg1.tap_ths_x(),
3094            y: tap_cfg2.tap_ths_y(),
3095            z: tap_ths_6d.tap_ths_z(),
3096        };
3097
3098        Ok(thresholds)
3099    }
3100    /// Set axis priority for TAP detection.
3101    pub fn tap_axis_priority_set(&mut self, val: TapAxisPriority) -> Result<(), Error<B::Error>> {
3102        let mut tap_cfg1 = TapCfg1::read(self)?;
3103        tap_cfg1.set_tap_priority((val as u8) & 0x7);
3104        tap_cfg1.write(self)
3105    }
3106    /// Get axis priority for TAP detection.
3107    pub fn tap_axis_priority_get(&mut self) -> Result<TapAxisPriority, Error<B::Error>> {
3108        let tap_cfg1 = TapCfg1::read(self)?;
3109
3110        let val = TapAxisPriority::try_from(tap_cfg1.tap_priority()).unwrap_or_default();
3111
3112        Ok(val)
3113    }
3114    /// Set Time windows configuration for Tap - Double Tap.
3115    ///
3116    /// SHOCK Maximum duration is the maximum time of an overthreshold
3117    /// signal detection to be recognized as a tap event.
3118    /// If the SHOCK bits are set to a different value, 1LSB corresponds to 8/ODR_XL time.
3119    ///
3120    /// QUIET Expected quiet time after a tap detection. Quiet time is the time
3121    /// after the first detected tap in which there must not be any overthreshold event.
3122    /// If the QUIET bits are set to a different value, 1LSB corresponds to 4/ODR_XL time.
3123    ///
3124    /// DUR Duration of maximum time gap for double tap recognition. This register expresses
3125    /// the maximum time between two consecutive detected taps to determine a double tap event.
3126    /// If the DUR_[3:0] bits are set to a different value, 1LSB corresponds to 32/ODR_XL time.
3127    pub fn tap_time_windows_set(&mut self, val: TapTimeWindows) -> Result<(), Error<B::Error>> {
3128        let mut tap_dur = TapDur::read(self)?;
3129        tap_dur.set_shock(val.shock);
3130        tap_dur.set_quiet(val.quiet);
3131        tap_dur.set_dur(val.tap_gap);
3132        tap_dur.write(self)
3133    }
3134    /// Get Time windows configuration for Tap - Double Tap SHOCK, QUIET, DUR.
3135    ///
3136    /// SHOCK Maximum duration is the maximum time of an overthreshold
3137    /// signal detection to be recognized as a tap event.
3138    /// If the SHOCK bits are set to a different value, 1LSB corresponds to 8/ODR_XL time.
3139    ///
3140    /// QUIET Expected quiet time after a tap detection. Quiet time is the time
3141    /// after the first detected tap in which there must not be any overthreshold event.
3142    /// If the QUIET bits are set to a different value, 1LSB corresponds to 4/ODR_XL time.
3143    ///
3144    /// DUR Duration of maximum time gap for double tap recognition. This register expresses
3145    /// the maximum time between two consecutive detected taps to determine a double tap event.
3146    /// If the DUR_[3:0] bits are set to a different value, 1LSB corresponds to 32/ODR_XL time.
3147    pub fn tap_time_windows_get(&mut self) -> Result<TapTimeWindows, Error<B::Error>> {
3148        let tap_dur = TapDur::read(self)?;
3149
3150        let val = TapTimeWindows {
3151            shock: tap_dur.shock(),
3152            quiet: tap_dur.quiet(),
3153            tap_gap: tap_dur.dur(),
3154        };
3155
3156        Ok(val)
3157    }
3158    /// Enable/Disable single/double-tap event.
3159    pub fn tap_mode_set(&mut self, val: TapMode) -> Result<(), Error<B::Error>> {
3160        let mut wake_up_ths = WakeUpThs::read(self)?;
3161        wake_up_ths.set_single_double_tap((val as u8) & 0x01);
3162        wake_up_ths.write(self)
3163    }
3164    /// Get configuration (enable/disable) for Single/double-tap event
3165    pub fn tap_mode_get(&mut self) -> Result<TapMode, Error<B::Error>> {
3166        let wake_up_ths = WakeUpThs::read(self)?;
3167
3168        let val = TapMode::try_from(wake_up_ths.single_double_tap()).unwrap_or_default();
3169
3170        Ok(val)
3171    }
3172    /// Set Tilt mode.
3173    pub fn tilt_mode_set(&mut self, val: u8) -> Result<(), Error<B::Error>> {
3174        MemBank::operate_over_embed(self, |state| {
3175            let mut emb_func_en_a = EmbFuncEnA::read(state)?;
3176            emb_func_en_a.set_tilt_en(val);
3177            emb_func_en_a.write(state)
3178        })
3179    }
3180    /// Get Tilt mode.
3181    pub fn tilt_mode_get(&mut self) -> Result<u8, Error<B::Error>> {
3182        // Switch to the embedded function memory bank
3183        MemBank::operate_over_embed(self, |state| {
3184            // Read the register values
3185            EmbFuncEnA::read(state).map(|reg| reg.tilt_en())
3186            // Switch back to the main memory bank
3187        })
3188    }
3189    /// Get Timestamp raw data
3190    pub fn timestamp_raw_get(&mut self) -> Result<u32, Error<B::Error>> {
3191        Timestamp::read(self).map(|reg| reg.0)
3192    }
3193    /// Enables timestamp counter.
3194    pub fn timestamp_set(&mut self, val: u8) -> Result<(), Error<B::Error>> {
3195        let mut functions_enable = FunctionsEnable::read(self)?;
3196        functions_enable.set_timestamp_en(val);
3197        functions_enable.write(self)
3198    }
3199    /// Get the actual timestamp counter configuration.
3200    ///
3201    /// If return 1 timestamp counter is active
3202    pub fn timestamp_get(&mut self) -> Result<u8, Error<B::Error>> {
3203        let val: u8 = FunctionsEnable::read(self).map(|reg| reg.timestamp_en())?;
3204
3205        Ok(val)
3206    }
3207
3208    /// Configure activity/inactivity (sleep)
3209    ///
3210    /// `ActMode` could handle different setting for accelerometer and gyroscope
3211    pub fn act_mode_set(&mut self, val: ActMode) -> Result<(), Error<B::Error>> {
3212        let mut functions_enable = FunctionsEnable::read(self)?;
3213        functions_enable.set_inact_en(val as u8 & 0x3);
3214        functions_enable.write(self)
3215    }
3216    /// Get activity/inactivity (sleep)
3217    pub fn act_mode_get(&mut self) -> Result<ActMode, Error<B::Error>> {
3218        let functions_enable = FunctionsEnable::read(self)?;
3219
3220        let val = ActMode::try_from(functions_enable.inact_en()).unwrap_or_default();
3221
3222        Ok(val)
3223    }
3224    /// Set duration in the transition from Stationary to Motion (from Inactivity to Activity).
3225    pub fn act_from_sleep_to_act_dur_set(
3226        &mut self,
3227        val: ActFromSleepToActDur,
3228    ) -> Result<(), Error<B::Error>> {
3229        let mut inactivity_dur = InactivityDur::read(self)?;
3230        inactivity_dur.set_inact_dur((val as u8) & 0x3);
3231        inactivity_dur.write(self)
3232    }
3233    /// Get duration in the transition from Stationary to Motion (from Inactivity to Activity).
3234    pub fn act_from_sleep_to_act_dur_get(
3235        &mut self,
3236    ) -> Result<ActFromSleepToActDur, Error<B::Error>> {
3237        let inactivity_dur = InactivityDur::read(self)?;
3238
3239        let val = ActFromSleepToActDur::try_from(inactivity_dur.inact_dur()).unwrap_or_default();
3240
3241        Ok(val)
3242    }
3243    /// Set the accelerometer data rate during Inactivity.
3244    pub fn act_sleep_xl_odr_set(&mut self, val: ActSleepXlOdr) -> Result<(), Error<B::Error>> {
3245        let mut inactivity_dur = InactivityDur::read(self)?;
3246        inactivity_dur.set_xl_inact_odr((val as u8) & 0x03);
3247        inactivity_dur.write(self)
3248    }
3249    /// Get the accelerometer data rate during Inactivity.
3250    pub fn act_sleep_xl_odr_get(&mut self) -> Result<ActSleepXlOdr, Error<B::Error>> {
3251        let inactivity_dur = InactivityDur::read(self)?;
3252
3253        let val = ActSleepXlOdr::try_from(inactivity_dur.xl_inact_odr()).unwrap_or_default();
3254
3255        Ok(val)
3256    }
3257    /// Set Wakeup and activity/inactivity threshold.
3258    pub fn act_thresholds_set(&mut self, val: ActThresholds) -> Result<(), Error<B::Error>> {
3259        // Read current values from registers
3260        let mut inactivity_dur = InactivityDur::read(self)?;
3261        let mut inactivity_ths = InactivityThs::read(self)?;
3262        let mut wake_up_ths = WakeUpThs::read(self)?;
3263        let mut wake_up_dur = WakeUpDur::read(self)?;
3264
3265        // Set new values
3266        inactivity_dur.set_wu_inact_ths_w(val.inactivity_cfg.wu_inact_ths_w());
3267        inactivity_dur.set_xl_inact_odr(val.inactivity_cfg.xl_inact_odr());
3268        inactivity_dur.set_inact_dur(val.inactivity_cfg.inact_dur());
3269
3270        inactivity_ths.set_inact_ths(val.inactivity_ths);
3271        wake_up_ths.set_wk_ths(val.threshold);
3272        wake_up_dur.set_wake_dur(val.duration);
3273
3274        // Write new values back to registers
3275        inactivity_dur.write(self)?;
3276        inactivity_ths.write(self)?;
3277        wake_up_ths.write(self)?;
3278        wake_up_dur.write(self)
3279    }
3280    /// Get Wakeup and activity/inactivity threshold.
3281    pub fn act_thresholds_get(&mut self) -> Result<ActThresholds, Error<B::Error>> {
3282        let inactivity_dur = InactivityDur::read(self)?;
3283        let inactivity_ths = InactivityThs::read(self)?;
3284        let wake_up_ths = WakeUpThs::read(self)?;
3285        let wake_up_dur = WakeUpDur::read(self)?;
3286
3287        let val = ActThresholds {
3288            inactivity_cfg: inactivity_dur,
3289            inactivity_ths: inactivity_ths.inact_ths(),
3290            threshold: wake_up_ths.wk_ths(),
3291            duration: wake_up_dur.wake_dur(),
3292        };
3293
3294        Ok(val)
3295    }
3296    /// Set Time windows for Wake Up - Activity - Inactivity (SLEEP, WAKE).
3297    ///
3298    /// Duration to go in sleep mode. Default value: 0000 (this corresponds to 16 ODR)
3299    /// 1 LSB = 512/ODR_XL time. Wake up duration event. 1 LSB = 1/ODR_XL time.
3300    pub fn act_wkup_time_windows_set(
3301        &mut self,
3302        val: ActWkupTimeWindows,
3303    ) -> Result<(), Error<B::Error>> {
3304        let mut wake_up_dur = WakeUpDur::read(self)?;
3305        wake_up_dur.set_wake_dur(val.shock);
3306        wake_up_dur.set_sleep_dur(val.quiet);
3307        wake_up_dur.write(self)
3308    }
3309    /// Get Time windows configuration for Wake Up - Activity - Inactivity (SLEEP, WAKE).
3310    ///
3311    /// Duration to go in sleep mode. Default value: 0000 (this corresponds to 16 ODR)
3312    /// 1 LSB = 512/ODR_XL time. Wake up duration event. 1 LSB = 1/ODR_XL time.
3313    pub fn act_wkup_time_windows_get(&mut self) -> Result<ActWkupTimeWindows, Error<B::Error>> {
3314        let wake_up_dur = WakeUpDur::read(self)?;
3315
3316        let val = ActWkupTimeWindows {
3317            shock: wake_up_dur.wake_dur(),
3318            quiet: wake_up_dur.sleep_dur(),
3319        };
3320
3321        Ok(val)
3322    }
3323    // pub fn npy_floatbits_to_halfbits(&mut self, f: u32) -> u16 {
3324    //     let f_exp: u32;
3325    //     let f_sig: u32;
3326    //     let h_sgn: u16;
3327    //     let h_exp: u16;
3328    //     let h_sig: u16;
3329
3330    //     h_sgn = ((f & 0x80000000) >> 16) as u16;
3331    //     f_exp = f & 0x7f800000;
3332
3333    //     // Exponent overflow/NaN converts to signed inf/NaN
3334    //     if f_exp >= 0x47800000 {
3335    //         if f_exp == 0x7f800000 {
3336    //             // Inf or NaN
3337    //             f_sig = f & 0x007fffff;
3338    //             if f_sig != 0 {
3339    //                 // NaN - propagate the flag in the significand...
3340    //                 let mut ret = (0x7c00 + (f_sig >> 13)) as u16;
3341    //                 // ...but make sure it stays a NaN
3342    //                 if ret == 0x7c00 {
3343    //                     ret += 1;
3344    //                 }
3345    //                 return h_sgn + ret;
3346    //             } else {
3347    //                 // signed inf
3348    //                 return h_sgn + 0x7c00;
3349    //             }
3350    //         } else {
3351    //             // overflow to signed inf
3352    //             if NPY_HALF_GENERATE_OVERFLOW {
3353    //                 // npy_set_floatstatus_overflow(); // Implement this if needed
3354    //             }
3355    //             return h_sgn + 0x7c00;
3356    //         }
3357    //     }
3358
3359    //     // Exponent underflow converts to a subnormal half or signed zero
3360    //     if f_exp <= 0x38000000 {
3361    //         // Signed zeros, subnormal floats, and floats with small exponents all convert to signed zero half-floats.
3362    //         if f_exp < 0x33000000 {
3363    //             if NPY_HALF_GENERATE_UNDERFLOW {
3364    //                 // If f != 0, it underflowed to 0
3365    //                 if (f & 0x7fffffff) != 0 {
3366    //                     // npy_set_floatstatus_underflow(); // Implement this if needed
3367    //                 }
3368    //             }
3369    //             return h_sgn;
3370    //         }
3371    //         // Make the subnormal significand
3372    //         let mut f_exp = f_exp >> 23;
3373    //         f_sig = 0x00800000 + (f & 0x007fffff);
3374    //         if NPY_HALF_GENERATE_UNDERFLOW {
3375    //             // If it's not exactly represented, it underflowed
3376    //             if (f_sig & ((1 << (126 - f_exp)) - 1)) != 0 {
3377    //                 // npy_set_floatstatus_underflow(); // Implement this if needed
3378    //             }
3379    //         }
3380    //         // Usually the significand is shifted by 13. For subnormals an additional shift needs to occur.
3381    //         f_sig >>= 113 - f_exp;
3382    //         // Handle rounding by adding 1 to the bit beyond half precision
3383    //         if NPY_HALF_ROUND_TIES_TO_EVEN {
3384    //             if ((f_sig & 0x00003fff) != 0x00001000) || (f & 0x000007ff) != 0 {
3385    //                 f_sig += 0x00001000;
3386    //             }
3387    //         } else {
3388    //             f_sig += 0x00001000;
3389    //         }
3390    //         h_sig = (f_sig >> 13) as u16;
3391    //         // If the rounding causes a bit to spill into h_exp, it will increment h_exp from zero to one and h_sig will be zero.
3392    //         return h_sgn + h_sig;
3393    //     }
3394
3395    //     // Regular case with no overflow or underflow
3396    //     h_exp = ((f_exp - 0x38000000) >> 13) as u16;
3397    //     f_sig = f & 0x007fffff;
3398    //     // Handle rounding by adding 1 to the bit beyond half precision
3399    //     if NPY_HALF_ROUND_TIES_TO_EVEN {
3400    //         if (f_sig & 0x00003fff) != 0x00001000 {
3401    //             f_sig += 0x00001000;
3402    //         }
3403    //     } else {
3404    //         f_sig += 0x00001000;
3405    //     }
3406    //     h_sig = (f_sig >> 13) as u16;
3407    //     // If the rounding causes a bit to spill into h_exp, it will increment h_exp by one and h_sig will be zero.
3408    //     if NPY_HALF_GENERATE_OVERFLOW {
3409    //         let mut h_sig = h_sig + h_exp;
3410    //         if h_sig == 0x7c00 {
3411    //             // npy_set_floatstatus_overflow(); // Implement this if needed
3412    //         }
3413    //         return h_sgn + h_sig;
3414    //     } else {
3415    //         return h_sgn + h_exp + h_sig;
3416    //     }
3417    // }
3418    pub fn npy_float_to_half(&mut self, f: f32) -> u16 {
3419        //let fbits: u32 = f.to_bits();
3420        //self.npy_floatbits_to_halfbits(bits)
3421        let half_float = f16::from_f32(f);
3422        half_float.to_bits()
3423    }
3424}
3425
3426pub fn from_sflp_to_mg(lsb: i16) -> f32 {
3427    (lsb as f32) * 0.061
3428}
3429
3430pub fn from_fs2_to_mg(lsb: i16) -> f32 {
3431    (lsb as f32) * 0.061
3432}
3433
3434pub fn from_fs4_to_mg(lsb: i16) -> f32 {
3435    (lsb as f32) * 0.122
3436}
3437
3438pub fn from_fs8_to_mg(lsb: i16) -> f32 {
3439    (lsb as f32) * 0.244
3440}
3441
3442pub fn from_fs16_to_mg(lsb: i16) -> f32 {
3443    (lsb as f32) * 0.488
3444}
3445
3446pub fn from_fs125_to_mdps(lsb: i16) -> f32 {
3447    (lsb as f32) * 4.375
3448}
3449
3450pub fn from_fs250_to_mdps(lsb: i16) -> f32 {
3451    (lsb as f32) * 8.750
3452}
3453
3454pub fn from_fs500_to_mdps(lsb: i16) -> f32 {
3455    (lsb as f32) * 17.50
3456}
3457
3458pub fn from_fs1000_to_mdps(lsb: i16) -> f32 {
3459    (lsb as f32) * 35.0
3460}
3461
3462pub fn from_fs2000_to_mdps(lsb: i16) -> f32 {
3463    (lsb as f32) * 70.0
3464}
3465
3466pub fn from_fs4000_to_mdps(lsb: i16) -> f32 {
3467    (lsb as f32) * 140.0
3468}
3469
3470pub fn from_lsb_to_celsius(lsb: i16) -> f32 {
3471    (lsb as f32) / 256.0 + 25.0
3472}
3473
3474pub fn from_lsb_to_nsec(lsb: u32) -> f32 {
3475    (lsb as f32) * 21750.0
3476}
3477
3478pub fn from_lsb_to_mv(lsb: i16) -> f32 {
3479    (lsb as f32) / 78.0
3480}
3481
3482/*
3483 * Original conversion routines taken from: https://github.com/numpy/numpy
3484 *
3485 * Converts from half-precision (16-bit) float number to single precision (32-bit).
3486 *
3487 * uint32_t  static uint32_t ToFloatBits(uint16_t h);
3488 * Released under BSD-3-Clause License
3489 */
3490pub fn from_half_to_single_precision(h: u16) -> u32 {
3491    let mut h_exp = h & 0x7c00;
3492    let f_sgn: u32 = ((h as u32) & 0x8000) << 16;
3493    match h_exp {
3494        0x0000 => {
3495            // 0 or subnormal
3496            let mut h_sig = h & 0x03ff;
3497            // Signed zero
3498            if h_sig == 0 {
3499                return f_sgn;
3500            }
3501            // Subnormal
3502            h_sig <<= 1;
3503            while (h_sig & 0x0400) == 0 {
3504                h_sig <<= 1;
3505                h_exp += 1;
3506            }
3507
3508            let f_exp = ((127 - 15 - h_exp) as u32) << 23;
3509            let f_sig = ((h_sig & 0x03ff) as u32) << 13;
3510            f_sgn + f_exp + f_sig
3511        }
3512        0x7c00 => {
3513            //inf or NaN
3514            // All-ones exponent and a copy of the significand
3515            f_sgn + 0x7f800000 + (((h & 0x03ff) as u32) << 13)
3516        }
3517        _ => {
3518            // normalized
3519            f_sgn + (((h & 0x7fff) as u32) << 13)
3520        }
3521    }
3522}
3523
3524#[cfg(feature = "passthrough")]
3525pub struct Lsm6dsv16xMaster<B, T> {
3526    pub sensor: RefCell<Lsm6dsv16x<B, T>>,
3527}
3528
3529#[cfg(feature = "passthrough")]
3530impl<B: BusOperation, T: DelayNs> Lsm6dsv16xMaster<B, T> {
3531    pub fn from_bus(bus: B, tim: T) -> Self {
3532        Self {
3533            sensor: RefCell::new(Lsm6dsv16x::from_bus(bus, tim)),
3534        }
3535    }
3536
3537    pub fn borrow_mut(&self) -> RefMut<Lsm6dsv16x<B, T>> {
3538        self.sensor.borrow_mut()
3539    }
3540
3541    /// Generates a wrapper for the sensor to enable its use as a passthrough
3542    /// from another sensor.
3543    ///
3544    /// The Sensor Hub may require this setup to redirect writes from the
3545    /// bus to the sensor that executes them as a passthrough.
3546    pub fn as_passthrough<'a>(
3547        &'a self,
3548        address: SevenBitAddress,
3549    ) -> Lsm6dsv16xPassthrough<'a, B, T> {
3550        Lsm6dsv16xPassthrough {
3551            sensor: &self.sensor,
3552            slave_address: address,
3553        }
3554    }
3555}
3556
3557#[cfg(feature = "passthrough")]
3558/// Struct to handle Sensor to do the passthrough write and read for the
3559/// slave sensor.
3560///
3561/// Do not usit as it, call the as_passthrough function on the Lsm6dsv16x instance
3562pub struct Lsm6dsv16xPassthrough<'a, B, T> {
3563    sensor: &'a RefCell<Lsm6dsv16x<B, T>>,
3564    slave_address: SevenBitAddress,
3565}
3566
3567#[cfg(feature = "passthrough")]
3568// LSM6DSV16X acts like a bus when used for the sensor hub.
3569impl<B, T> BusOperation for Lsm6dsv16xPassthrough<'_, B, T>
3570where
3571    B: BusOperation,
3572    T: DelayNs,
3573{
3574    type Error = Error<B::Error>;
3575
3576    fn read_bytes(&mut self, _rbuf: &mut [u8]) -> Result<(), Self::Error> {
3577        Err(Error::UnexpectedValue)
3578    }
3579
3580    fn write_bytes(&mut self, wbuf: &[u8]) -> Result<(), Self::Error> {
3581        let mut master = self.sensor.borrow_mut();
3582        for i in 1_u8..(wbuf.len() as u8) {
3583            // Configure Sensor Hub to read data
3584            let sh_cfg_write = ShCfgWrite {
3585                slv0_add: self.slave_address,
3586                slv0_subadd: wbuf[0] + i - 1,
3587                slv0_data: wbuf[i as usize],
3588            };
3589            master.sh_cfg_write(sh_cfg_write)?;
3590
3591            // Disable accelerometer
3592            master.xl_data_rate_set(Odr::Off)?;
3593            // Enable I2C Master
3594            master.sh_master_set(1)?;
3595            // Enable accelerometer to trigger Sensor Hub operation.
3596            master.xl_data_rate_set(Odr::_120hz)?;
3597            // Wait Sensor Hub operation flag set.
3598            master.acceleration_raw_get()?; // dummy read
3599
3600            let mut drdy = 0;
3601            while drdy == 0 {
3602                master.tim.delay_ms(20);
3603                drdy = master.flag_data_ready_get()?.drdy_xl;
3604            }
3605
3606            let mut end_op = 0;
3607            while end_op == 0 {
3608                master.tim.delay_ms(20);
3609                end_op = master.sh_status_get()?.sens_hub_endop();
3610            }
3611
3612            // Disable I2C master and XL (triger).
3613            master.sh_master_set(0)?;
3614            master.xl_data_rate_set(Odr::Off)?;
3615        }
3616
3617        Ok(())
3618    }
3619
3620    fn write_byte_read_bytes(
3621        &mut self,
3622        wbuf: &[u8; 1],
3623        rbuf: &mut [u8],
3624    ) -> Result<(), Self::Error> {
3625        let mut master = self.sensor.borrow_mut();
3626        // Disable accelerometer
3627        master.xl_data_rate_set(Odr::Off)?;
3628        // Configure Sensor Hub to read
3629        let sh_cfg_read = ShCfgRead {
3630            slv_add: self.slave_address,
3631            slv_subadd: wbuf[0],
3632            slv_len: rbuf.len() as u8,
3633        };
3634        master.sh_slv_cfg_read(0, &sh_cfg_read)?; // dummy read
3635        master.sh_slave_connected_set(ShSlaveConnected::_01)?;
3636        // Enable I2C Master
3637        master.sh_master_set(1)?;
3638        // Enable accelerometer to trigger Sensor Hub operation.
3639        master.xl_data_rate_set(Odr::_120hz)?;
3640        // Wait Sensor Hub operation flag set
3641        master.acceleration_raw_get()?; // dummy read
3642
3643        let mut drdy = 0;
3644        while drdy == 0 {
3645            master.tim.delay_ms(20);
3646            drdy = master.flag_data_ready_get()?.drdy_xl;
3647        }
3648
3649        let mut end_op = 0;
3650        while end_op == 0 {
3651            //master.tim.delay_ms(20);
3652            end_op = master.sh_status_get()?.sens_hub_endop();
3653        }
3654
3655        // Disable I2C master and XL(trigger)
3656        master.sh_master_set(0)?;
3657        master.xl_data_rate_set(Odr::Off)?;
3658
3659        // Read SensorHub registers
3660        master.sh_read_data_raw_get(rbuf)
3661    }
3662}
3663
3664#[derive(Clone, Copy, Default)]
3665pub struct AllSources {
3666    pub drdy_xl: u8,
3667    pub drdy_gy: u8,
3668    pub drdy_temp: u8,
3669    pub drdy_ah_qvar: u8,
3670    pub drdy_eis: u8,
3671    pub drdy_ois: u8,
3672    pub gy_settling: u8,
3673    pub timestamp: u8,
3674    pub free_fall: u8,
3675    pub wake_up: u8,
3676    pub wake_up_z: u8,
3677    pub wake_up_y: u8,
3678    pub wake_up_x: u8,
3679    pub single_tap: u8,
3680    pub double_tap: u8,
3681    pub tap_z: u8,
3682    pub tap_y: u8,
3683    pub tap_x: u8,
3684    pub tap_sign: u8,
3685    pub six_d: u8,
3686    pub six_d_xl: u8,
3687    pub six_d_xh: u8,
3688    pub six_d_yl: u8,
3689    pub six_d_yh: u8,
3690    pub six_d_zl: u8,
3691    pub six_d_zh: u8,
3692    pub sleep_change: u8,
3693    pub sleep_state: u8,
3694    pub step_detector: u8,
3695    pub step_count_inc: u8,
3696    pub step_count_overflow: u8,
3697    pub step_on_delta_time: u8,
3698    pub emb_func_stand_by: u8,
3699    pub emb_func_time_exceed: u8,
3700    pub tilt: u8,
3701    pub sig_mot: u8,
3702    pub fsm_lc: u8,
3703    pub fsm1: u8,
3704    pub fsm2: u8,
3705    pub fsm3: u8,
3706    pub fsm4: u8,
3707    pub fsm5: u8,
3708    pub fsm6: u8,
3709    pub fsm7: u8,
3710    pub fsm8: u8,
3711    pub mlc1: u8,
3712    pub mlc2: u8,
3713    pub mlc3: u8,
3714    pub mlc4: u8,
3715    pub sh_endop: u8,
3716    pub sh_slave0_nack: u8,
3717    pub sh_slave1_nack: u8,
3718    pub sh_slave2_nack: u8,
3719    pub sh_slave3_nack: u8,
3720    pub sh_wr_once: u8,
3721    pub fifo_bdr: u8,
3722    pub fifo_full: u8,
3723    pub fifo_ovr: u8,
3724    pub fifo_th: u8,
3725}
3726
3727#[repr(u8)]
3728#[derive(Clone, Copy, PartialEq)]
3729pub enum I2CAddress {
3730    I2cAddL = 0x6A,
3731    I2cAddH = 0x6B,
3732}
3733
3734pub const ID: u8 = 0x70;
3735
3736// const NPY_HALF_GENERATE_OVERFLOW: bool = false; // do not trigger FP overflow
3737// const NPY_HALF_GENERATE_UNDERFLOW: bool = false; // do not trigger FP underflow
3738// const NPY_HALF_ROUND_TIES_TO_EVEN: bool = true;