Skip to main content

iis2dlpc_rs/
driver.rs

1use super::{
2    BusOperation, DelayNs, I2c, RegisterOperation, SensorOperation, SevenBitAddress, SpiDevice,
3    bisync, i2c, prelude::*, spi,
4};
5
6use core::fmt::Debug;
7use core::marker::PhantomData;
8
9/// The Iis2dlpc generic driver struct.
10#[bisync]
11pub struct Iis2dlpc<B, T, S>
12where
13    B: BusOperation,
14    T: DelayNs,
15    S: SensorState,
16{
17    /// The bus driver.
18    pub bus: B,
19    pub tim: T,
20    _state: PhantomData<S>,
21}
22
23/// Driver errors.
24#[derive(Debug)]
25#[bisync]
26pub enum Error<B> {
27    Bus(B),          // Error at the bus level
28    WhoAmIError(u8), // Incorrect Iis2dlpc identifier
29    UnexpectedValue, // Unexpected value read from a register
30}
31
32#[bisync]
33impl<P, T> Iis2dlpc<i2c::I2cBus<P>, T, OnState>
34where
35    P: I2c,
36    T: DelayNs,
37{
38    /// Constructor method for using the I2C bus.
39    ///
40    /// # Arguments
41    ///
42    /// * `i2c`: The I2C peripheral.
43    /// * `address`: The I2C address of the Iis2dlpc sensor.
44    ///
45    /// # Returns
46    ///
47    /// * `Result`
48    ///     * `Self`: Returns an instance of `Iis2dlpc`.
49    ///     * `Err`: Returns an error if the initialization fails.
50    pub fn new_i2c(i2c: P, address: I2CAddress, tim: T) -> Self {
51        // Initialize the I2C bus with the Iis2dlpc address
52        let bus = i2c::I2cBus::new(i2c, address as SevenBitAddress);
53        Self {
54            bus,
55            tim,
56            _state: PhantomData,
57        }
58    }
59}
60
61#[bisync]
62impl<P, T> Iis2dlpc<spi::SpiBus<P>, T, OnState>
63where
64    P: SpiDevice,
65    T: DelayNs,
66{
67    /// Constructor method for using the SPI bus.
68    ///
69    /// # Arguments
70    ///
71    /// * `spi`: The SPI peripheral.
72    ///
73    /// # Returns
74    ///
75    /// * `Result`
76    ///     * `Self`: Returns an instance of `Iis2dlpc`.
77    ///     * `Err`: Returns an error if the initialization fails.
78    pub fn new_spi(spi: P, tim: T) -> Self {
79        // Initialize the SPI bus
80        let bus = spi::SpiBus::new(spi);
81        Self {
82            bus,
83            tim,
84            _state: PhantomData,
85        }
86    }
87}
88
89#[bisync]
90impl<B: BusOperation, T: DelayNs, S: SensorState> Iis2dlpc<B, T, S> {
91    /// # Arguments
92    ///
93    /// * `bus`: The bus that implements BusOperation.
94    /// * `tim`: The timer of the COMPONENT sensor.
95    ///
96    /// # Returns
97    ///
98    /// * `Self`: Returns an instance of `Iis2mdc`.
99    #[inline]
100    pub fn from_bus(bus: B, tim: T) -> Self {
101        Self {
102            bus,
103            tim,
104            _state: PhantomData,
105        }
106    }
107}
108
109#[bisync]
110impl<B: BusOperation, T: DelayNs, S: SensorState> SensorOperation for Iis2dlpc<B, T, S> {
111    type Error = Error<B::Error>;
112
113    #[inline]
114    async fn read_from_register(&mut self, reg: u8, buf: &mut [u8]) -> Result<(), Error<B::Error>> {
115        self.bus
116            .read_from_register(reg, buf)
117            .await
118            .map_err(Error::Bus)
119    }
120
121    #[inline]
122    async fn write_to_register(&mut self, reg: u8, buf: &[u8]) -> Result<(), Error<B::Error>> {
123        self.bus
124            .write_to_register(reg, buf)
125            .await
126            .map_err(Error::Bus)
127    }
128}
129
130#[bisync]
131impl<B: BusOperation, T: DelayNs> Iis2dlpc<B, T, OnState> {
132    /// Set the accelerometer operating mode.
133    ///
134    /// This function configures the accelerometer's operating mode by updating the `mode` and `lp_mode` fields in the `CTRL1` register,
135    /// and the `low_noise` field in the `CTRL6` register.
136    ///
137    /// ### Arguments
138    /// - `val`: A [`Mode`] value representing the desired operating mode. This includes settings for:
139    ///   - `mode`: Operating mode.
140    ///   - `lp_mode`: Low-power mode configuration.
141    ///   - `low_noise`: Low-noise mode configuration.
142    ///
143    /// ### Returns
144    /// - `Ok(())`: If the operation is successful.
145    /// - `Err(Error::Bus)`: If there is an error at the bus level during the read or write operation.
146    pub async fn power_mode_set(&mut self, val: Mode) -> Result<(), Error<B::Error>> {
147        let mut ctrl1 = Ctrl1::read(self).await?;
148        ctrl1.set_mode(val.mode());
149        ctrl1.set_lp_mode(val.lp_mode());
150        ctrl1.write(self).await?;
151
152        let mut ctrl6 = Ctrl6::read(self).await?;
153        ctrl6.set_low_noise(val.low_noise());
154        ctrl6.write(self).await
155    }
156
157    /// Get the accelerometer operating mode.
158    ///
159    /// This function retrieves the current operating mode of the accelerometer by reading the `mode` and `lp_mode` fields from the `CTRL1` register,
160    /// and the `low_noise` field from the `CTRL6` register.
161    ///
162    /// ### Returns
163    /// - `Ok(Mode)`: The current operating mode, represented as a [`Mode`] value.
164    /// - `Err(Error::Bus)`: If there is an error at the bus level during the read operation.
165    pub async fn power_mode_get(&mut self) -> Result<Mode, Error<B::Error>> {
166        let ctrl1 = Ctrl1::read(self).await?;
167        let ctrl6 = Ctrl6::read(self).await?;
168
169        Ok(Mode::new(ctrl1.mode(), ctrl1.lp_mode(), ctrl6.low_noise()))
170    }
171
172    /// Set the accelerometer data rate.
173    ///
174    /// This function configures the accelerometer's data rate by updating the `odr` field in the `CTRL1` register,
175    /// and the `slp_mode` field in the `CTRL3` register.
176    ///
177    /// ### Arguments
178    /// - `val`: A [`Odr`] value representing the desired data rate and sleep mode configuration.
179    ///
180    /// ### Returns
181    /// - `Ok(())`: If the operation is successful.
182    /// - `Err(Error::Bus)`: If there is an error at the bus level during the read or write operation.
183    pub async fn data_rate_set(&mut self, val: Odr) -> Result<(), Error<B::Error>> {
184        let mut ctrl1 = Ctrl1::read(self).await?;
185        ctrl1.set_odr(val.odr());
186        ctrl1.write(self).await?;
187
188        let mut ctrl3 = Ctrl3::read(self).await?;
189        ctrl3.set_slp_mode(val.slp_mode());
190        ctrl3.write(self).await
191    }
192
193    /// Get the accelerometer data rate.
194    ///
195    /// This function retrieves the current data rate of the accelerometer by reading the `odr` field from the `CTRL1` register,
196    /// and the `slp_mode` field from the `CTRL3` register.
197    ///
198    /// ### Returns
199    /// - `Ok(Odr)`: The current data rate, represented as an [`Odr`] value.
200    /// - `Err(Error::Bus)`: If there is an error at the bus level during the read operation.
201    pub async fn data_rate_get(&mut self) -> Result<Odr, Error<B::Error>> {
202        let ctrl1 = Ctrl1::read(self).await?;
203        let ctrl3 = Ctrl3::read(self).await?;
204
205        Ok(Odr::new(ctrl1.odr(), ctrl3.slp_mode()))
206    }
207
208    /// Set the block data update (BDU) configuration.
209    ///
210    /// This function configures the block data update (BDU) setting by updating the `bdu` field in the `CTRL2` register.
211    /// When BDU is enabled, the output registers are not updated until both the high and low parts are read, ensuring data consistency.
212    ///
213    /// ### Arguments
214    /// - `val`: The desired BDU value:
215    ///   - `0`: Continuous update.
216    ///   - `1`: Output registers not updated until MSB and LSB are read.
217    ///
218    /// ### Returns
219    /// - `Ok(())`: If the operation is successful.
220    /// - `Err(Error::Bus)`: If there is an error at the bus level during the read or write operation.
221    pub async fn block_data_update_set(&mut self, val: u8) -> Result<(), Error<B::Error>> {
222        let mut ctrl2 = Ctrl2::read(self).await?;
223        ctrl2.set_bdu(val);
224        ctrl2.write(self).await
225    }
226
227    /// Get the block data update (BDU) configuration.
228    ///
229    /// This function retrieves the current block data update (BDU) setting from the `CTRL2` register.
230    ///
231    /// ### Returns
232    /// - `Ok(u8)`: The current BDU value:
233    ///   - `0`: Continuous update.
234    ///   - `1`: Output registers not updated until MSB and LSB are read.
235    /// - `Err(Error::Bus)`: If there is an error at the bus level during the read operation.
236    pub async fn block_data_update_get(&mut self) -> Result<u8, Error<B::Error>> {
237        Ok(Ctrl2::read(self).await?.bdu())
238    }
239
240    /// Set the accelerometer full-scale selection.
241    ///
242    /// This function configures the full-scale range of the accelerometer by updating the `fs` field in the `CTRL6` register.
243    /// The full-scale range determines the maximum measurable acceleration.
244    ///
245    /// ### Arguments
246    /// - `val`: A [`Fs`] value representing the desired full-scale range:
247    ///   - `Fs2g`: ±2g (default).
248    ///   - `Fs4g`: ±4g.
249    ///   - `Fs8g`: ±8g.
250    ///   - `Fs16g`: ±16g.
251    ///
252    /// ### Returns
253    /// - `Ok(())`: If the operation is successful.
254    /// - `Err(Error::Bus)`: If there is an error at the bus level during the read or write operation.
255    pub async fn full_scale_set(&mut self, val: Fs) -> Result<(), Error<B::Error>> {
256        let mut ctrl6 = Ctrl6::read(self).await?;
257        ctrl6.set_fs(val as u8);
258        ctrl6.write(self).await
259    }
260
261    /// Get the accelerometer full-scale selection.
262    ///
263    /// This function retrieves the current full-scale range of the accelerometer from the `CTRL6` register.
264    ///
265    /// ### Returns
266    /// - `Ok(Fs)`: The current full-scale range as a [`Fs`] value.
267    /// - `Err(Error::Bus)`: If there is an error at the bus level during the read operation.
268    pub async fn full_scale_get(&mut self) -> Result<Fs, Error<B::Error>> {
269        Ok(Fs::try_from(Ctrl6::read(self).await?.fs()).unwrap_or_default())
270    }
271
272    /// Get the status register.
273    ///
274    /// This function retrieves the current status of the device by reading the `STATUS` register.
275    /// The `STATUS` register provides information about various events, such as data-ready, free-fall detection, and tap detection.
276    ///
277    /// ### Returns
278    /// - `Ok(Status)`: The current status as a [`Status`] struct, which represents the union of registers from `STATUS`.
279    /// - `Err(Error::Bus)`: If there is an error at the bus level during the read operation.
280    pub async fn status_reg_get(&mut self) -> Result<Status, Error<B::Error>> {
281        Status::read(self).await
282    }
283
284    /// Get the accelerometer new data availability flag.
285    ///
286    /// This function checks whether new accelerometer data is available by reading the `drdy` field in the `STATUS` register.
287    ///
288    /// ### Returns
289    /// - `Ok(u8)`: The value of the `drdy` field:
290    ///   - `0`: No new data available.
291    ///   - `1`: New data is available.
292    /// - `Err(Error::Bus)`: If there is an error at the bus level during the read operation..
293    pub async fn flag_data_ready_get(&mut self) -> Result<u8, Error<B::Error>> {
294        Ok(self.status_reg_get().await?.drdy())
295    }
296
297    /// Get all interrupt and status flags of the device.
298    ///
299    /// This function retrieves the status of all interrupt and status flags by reading the following registers:
300    /// - `STATUS_DUP`
301    /// - `WAKE_UP_SRC`
302    /// - `TAP_SRC`
303    /// - `SIXD_SRC`
304    /// - `ALL_INT_SRC`
305    ///
306    /// ### Returns
307    /// - `Ok(AllSources)`: A struct containing the values of all the above registers.
308    /// - `Err(Error::Bus)`: If there is an error at the bus level during the read operation.
309    pub async fn all_sources_get(&mut self) -> Result<AllSources, Error<B::Error>> {
310        Ok(AllSources {
311            status_dup: StatusDup::read(self).await?,
312            wake_up_src: WakeUpSrc::read(self).await?,
313            tap_src: TapSrc::read(self).await?,
314            sixd_src: SixdSrc::read(self).await?,
315            all_int_src: AllIntSrc::read(self).await?,
316        })
317    }
318
319    /// Set the X-axis user offset correction.
320    ///
321    /// This function configures the X-axis user offset correction value in the `X_OFS_USR` register.
322    /// The value's weight depends on the `USR_OFF_W` bit in the `CTRL7` register.
323    ///
324    /// ### Arguments
325    /// - `val`: The X-axis user offset correction value to set.
326    ///
327    /// ### Returns
328    /// - `Ok(())`: If the operation is successful.
329    /// - `Err(Error::Bus)`: If there is an error at the bus level during the write operation.
330    pub async fn usr_offset_x_set(&mut self, val: i8) -> Result<(), Error<B::Error>> {
331        XOfsUsr::from_bits(val.cast_unsigned()).write(self).await
332    }
333
334    /// Get the X-axis user offset correction.
335    ///
336    /// This function retrieves the X-axis user offset correction value from the `X_OFS_USR` register.
337    /// The value's weight depends on the `USR_OFF_W` bit in the `CTRL7` register.
338    ///
339    /// ### Returns
340    /// - `Ok(i8)`: The X-axis user offset correction value.
341    /// - `Err(Error::Bus)`: If there is an error at the bus level during the read operation.
342    pub async fn usr_offset_x_get(&mut self) -> Result<i8, Error<B::Error>> {
343        Ok(XOfsUsr::read(self).await?.x_ofs_usr())
344    }
345
346    /// Set the Y-axis user offset correction.
347    ///
348    /// This function configures the Y-axis user offset correction value in the `Y_OFS_USR` register.
349    /// The value's weight depends on the `USR_OFF_W` bit in the `CTRL7` register.
350    ///
351    /// ### Arguments
352    /// - `val`: The Y-axis user offset correction value to set.
353    ///
354    /// ### Returns
355    /// - `Ok(())`: If the operation is successful.
356    /// - `Err(Error::Bus)`: If there is an error at the bus level during the write operation.
357    pub async fn usr_offset_y_set(&mut self, val: i8) -> Result<(), Error<B::Error>> {
358        YOfsUsr::from_bits(val.cast_unsigned()).write(self).await
359    }
360
361    /// Get the Y-axis user offset correction.
362    ///
363    /// This function retrieves the Y-axis user offset correction value from the `Y_OFS_USR` register.
364    /// The value's weight depends on the `USR_OFF_W` bit in the `CTRL7` register.
365    ///
366    /// ### Returns
367    /// - `Ok(i8)`: The Y-axis user offset correction value.
368    /// - `Err(Error::Bus)`: If there is an error at the bus level during the read operation.
369    pub async fn usr_offset_y_get(&mut self) -> Result<i8, Error<B::Error>> {
370        Ok(YOfsUsr::read(self).await?.y_ofs_usr())
371    }
372
373    /// Set the Z-axis user offset correction.
374    ///
375    /// This function configures the Z-axis user offset correction value in the `Z_OFS_USR` register.
376    /// The value's weight depends on the `USR_OFF_W` bit in the `CTRL7` register.
377    ///
378    /// ### Arguments
379    /// - `val`: The Z-axis user offset correction value to set.
380    ///
381    /// ### Returns
382    /// - `Ok(())`: If the operation is successful.
383    /// - `Err(Error::Bus)`: If there is an error at the bus level during the write operation.
384    pub async fn usr_offset_z_set(&mut self, val: i8) -> Result<(), Error<B::Error>> {
385        ZOfsUsr::from_bits(val.cast_unsigned()).write(self).await
386    }
387
388    /// Get the Z-axis user offset correction.
389    ///
390    /// This function retrieves the Z-axis user offset correction value from the `Z_OFS_USR` register.
391    /// The value's weight depends on the `USR_OFF_W` bit in the `CTRL7` register.
392    ///
393    /// ### Returns
394    /// - `Ok(i8)`: The Z-axis user offset correction value.
395    /// - `Err(Error::Bus)`: If there is an error at the bus level during the read operation.
396    pub async fn usr_offset_z_get(&mut self) -> Result<i8, Error<B::Error>> {
397        Ok(ZOfsUsr::read(self).await?.z_ofs_usr())
398    }
399
400    /// Set the weight of XL user offset bits.
401    ///
402    /// This function configures the weight of the user offset bits in the `X_OFS_USR`, `Y_OFS_USR`, and `Z_OFS_USR` registers by updating the `usr_off_w` field in the `CTRL7` register.
403    ///
404    /// ### Arguments
405    /// - `val`: A [`UsrOffW`] value representing the desired weight:
406    ///   - `Lsb977ug`: 977 μg/LSB (default).
407    ///   - `Lsb15mg6`: 15.6 mg/LSB.
408    ///
409    /// ### Returns
410    /// - `Ok(())`: If the operation is successful.
411    /// - `Err(Error::Bus)`: If there is an error at the bus level during the read or write operation..
412    pub async fn offset_weight_set(&mut self, val: UsrOffW) -> Result<(), Error<B::Error>> {
413        let mut ctrl7 = Ctrl7::read(self).await?;
414        ctrl7.set_usr_off_w(val as u8);
415        ctrl7.write(self).await
416    }
417
418    /// Get the weight of XL user offset bits.
419    ///
420    /// This function retrieves the weight of the user offset bits from the `usr_off_w` field in the `CTRL7` register.
421    ///
422    /// ### Returns
423    /// - `Ok(UsrOffW)`: The current weight of the user offset bits:
424    ///   - `Lsb977ug`: 977 μg/LSB (default).
425    ///   - `Lsb15mg6`: 15.6 mg/LSB.
426    /// - `Err(Error::Bus)`: If there is an error at the bus level during the read operation..
427    pub async fn offset_weight_get(&mut self) -> Result<UsrOffW, Error<B::Error>> {
428        Ok(UsrOffW::try_from(Ctrl7::read(self).await?.usr_off_w()).unwrap_or_default())
429    }
430
431    /// Get the raw temperature data.
432    ///
433    /// This function retrieves the raw temperature data from the `OUT_T_L` and `OUT_T_H` registers.
434    /// The value is expressed as a 16-bit word in two's complement format.
435    ///
436    /// ### Returns
437    /// - `Ok(i16)`: The raw temperature data.
438    /// - `Err(Error::Bus)`: If there is an error at the bus level during the read operation.
439    pub async fn temperature_raw_get(&mut self) -> Result<i16, Error<B::Error>> {
440        Ok(OutT::read(self).await?.temp())
441    }
442
443    /// Get the raw acceleration data.
444    ///
445    /// This function retrieves the raw acceleration data for the X, Y, and Z axes from the `OUT_X_L`, `OUT_X_H`, `OUT_Y_L`, `OUT_Y_H`, `OUT_Z_L`, and `OUT_Z_H` registers.
446    /// The values are expressed as 16-bit words in two's complement format.
447    ///
448    /// ### Returns
449    /// - `Ok([i16; 3])`: An array containing the raw acceleration data for the X, Y, and Z axes.
450    /// - `Err(Error::Bus)`: If there is an error at the bus level during the read operation.
451    pub async fn acceleration_raw_get(&mut self) -> Result<[i16; 3], Error<B::Error>> {
452        Ok([
453            OutX::read(self).await?.x(),
454            OutY::read(self).await?.y(),
455            OutZ::read(self).await?.z(),
456        ])
457    }
458
459    /// Get the device ID.
460    ///
461    /// This function retrieves the device ID from the `WHO_AM_I` register.
462    /// The device ID is a fixed value that identifies the IIS2DLPC sensor.
463    ///
464    /// ### Returns
465    /// - `Ok(u8)`: The device ID (expected value: `0x44`).
466    /// - `Err(Error::Bus)`: If there is an error at the bus level during the read operation..
467    pub async fn device_id_get(&mut self) -> Result<u8, Error<B::Error>> {
468        let mut buff: [u8; 1] = [0];
469        self.read_from_register(Reg::WhoAmI as u8, &mut buff)
470            .await?;
471        Ok(buff[0])
472    }
473
474    /// Enable or disable automatic register address increment.
475    ///
476    /// This function configures the automatic register address increment feature by updating the `if_add_inc` field in the `CTRL2` register.
477    /// When enabled, the register address is automatically incremented during multiple-byte access.
478    ///
479    /// ### Arguments
480    /// - `val`: The desired value for the `if_add_inc` field:
481    ///   - `0`: Disable automatic increment.
482    ///   - `1`: Enable automatic increment.
483    ///
484    /// ### Returns
485    /// - `Ok(())`: If the operation is successful.
486    /// - `Err(Error::Bus)`: If there is an error at the bus level during the read or write operation.
487    pub async fn auto_increment_set(&mut self, val: u8) -> Result<(), Error<B::Error>> {
488        let mut ctrl2 = Ctrl2::read(self).await?;
489        ctrl2.set_if_add_inc(val);
490        ctrl2.write(self).await
491    }
492
493    /// Get the automatic register address increment configuration.
494    ///
495    /// This function retrieves the current value of the `if_add_inc` field from the `CTRL2` register.
496    ///
497    /// ### Returns
498    /// - `Ok(u8)`: The current value of the `if_add_inc` field:
499    ///   - `0`: Automatic increment is disabled.
500    ///   - `1`: Automatic increment is enabled.
501    /// - `Err(Error::Bus)`: If there is an error at the bus level during the read operation.
502    pub async fn auto_increment_get(&mut self) -> Result<u8, Error<B::Error>> {
503        Ok(Ctrl2::read(self).await?.if_add_inc())
504    }
505
506    /// Perform a software reset.
507    ///
508    /// This function performs a software reset by updating the `soft_reset` field in the `CTRL2` register.
509    /// A software reset restores the default values in all user registers.
510    ///
511    /// ### Returns
512    /// - `Ok(())`: If the operation is successful.
513    /// - `Err(Error::Bus)`: If there is an error at the bus level during the read or write operation.
514    pub async fn reset_set(&mut self) -> Result<(), Error<B::Error>> {
515        let mut ctrl2 = Ctrl2::read(self).await?;
516        ctrl2.set_soft_reset(PROPERTY_ENABLE);
517        ctrl2.write(self).await
518    }
519
520    /// Get the software reset status.
521    ///
522    /// This function retrieves the current value of the `soft_reset` field from the `CTRL2` register.
523    /// The value indicates whether a software reset has been performed.
524    ///
525    /// ### Returns
526    /// - `Ok(u8)`: The current value of the `soft_reset` field:
527    ///   - `0`: No reset in progress.
528    ///   - `1`: Reset in progress.
529    /// - `Err(Error::Bus)`: If there is an error at the bus level during the read operation.
530    pub async fn reset_get(&mut self) -> Result<u8, Error<B::Error>> {
531        Ok(Ctrl2::read(self).await?.soft_reset())
532    }
533
534    /// Reboot memory content and reload calibration parameters.
535    ///
536    /// This function triggers a reboot of the device's memory content by updating the `boot` field in the `CTRL2` register.
537    /// The reboot operation reloads the calibration parameters from non-volatile memory.
538    ///
539    /// ### Returns
540    /// - `Ok(())`: If the operation is successful.
541    /// - `Err(Error::Bus)`: If there is an error at the bus level during the read or write operation.
542    pub async fn boot_set(&mut self) -> Result<(), Error<B::Error>> {
543        let mut ctrl2 = Ctrl2::read(self).await?;
544        ctrl2.set_boot(PROPERTY_ENABLE);
545        ctrl2.write(self).await
546    }
547
548    /// Get the reboot memory content status.
549    ///
550    /// This function retrieves the current value of the `boot` field from the `CTRL2` register.
551    /// The value indicates whether a reboot operation is in progress.
552    ///
553    /// ### Returns
554    /// - `Ok(u8)`: The current value of the `boot` field:
555    ///   - `0`: No reboot in progress.
556    ///   - `1`: Reboot in progress.
557    /// - `Err(Error::Bus)`: If there is an error at the bus level during the read operation.
558    pub async fn boot_get(&mut self) -> Result<u8, Error<B::Error>> {
559        Ok(Ctrl2::read(self).await?.boot())
560    }
561
562    /// Enable or disable the sensor self-test.
563    ///
564    /// This function configures the self-test mode of the sensor by updating the `st` field in the `CTRL3` register.
565    /// The self-test mode allows verifying the functionality of the sensor without external stimuli.
566    ///
567    /// ### Arguments
568    /// - `val`: A [`St`] value representing the desired self-test mode:
569    ///   - `XlStDisable`: Self-test disabled (default).
570    ///   - `XlStPositive`: Positive sign self-test.
571    ///   - `XlStNegative`: Negative sign self-test.
572    ///
573    /// ### Returns
574    /// - `Ok(())`: If the operation is successful.
575    /// - `Err(Error::Bus)`: If there is an error at the bus level during the read or write operation.
576    pub async fn self_test_set(&mut self, val: St) -> Result<(), Error<B::Error>> {
577        let mut ctrl3 = Ctrl3::read(self).await?;
578        ctrl3.set_st(val as u8);
579        ctrl3.write(self).await
580    }
581
582    /// Get the sensor self-test mode.
583    ///
584    /// This function retrieves the current self-test mode of the sensor from the `st` field in the `CTRL3` register.
585    ///
586    /// ### Returns
587    /// - `Ok(St)`: The current self-test mode as a [`St`] value:
588    ///   - `XlStDisable`: Self-test disabled (default).
589    ///   - `XlStPositive`: Positive sign self-test.
590    ///   - `XlStNegative`: Negative sign self-test.
591    /// - `Err(Error::Bus)`: If there is an error at the bus level during the read operation.
592    pub async fn self_test_get(&mut self) -> Result<St, Error<B::Error>> {
593        Ok(St::try_from(Ctrl3::read(self).await?.st()).unwrap_or_default())
594    }
595
596    /// Set the data-ready interrupt mode.
597    ///
598    /// This function configures the data-ready interrupt mode by updating the `drdy_pulsed` field in the `CTRL7` register.
599    /// The data-ready interrupt can be configured as either latched or pulsed mode.
600    ///
601    /// ### Arguments
602    /// - `val`: A [`DrdyPulsed`] value representing the desired data-ready interrupt mode:
603    ///   - `Latched`: Latched mode (default).
604    ///   - `Pulsed`: Pulsed mode.
605    ///
606    /// ### Returns
607    /// - `Ok(())`: If the operation is successful.
608    /// - `Err(Error::Bus)`: If there is an error at the bus level during the read or write operation.
609    pub async fn data_ready_mode_set(&mut self, val: DrdyPulsed) -> Result<(), Error<B::Error>> {
610        let mut ctrl7 = Ctrl7::read(self).await?;
611        ctrl7.set_drdy_pulsed(val as u8);
612        ctrl7.write(self).await
613    }
614
615    /// Get the data-ready interrupt mode.
616    ///
617    /// This function retrieves the current data-ready interrupt mode from the `drdy_pulsed` field in the `CTRL7` register.
618    ///
619    /// ### Returns
620    /// - `Ok(DrdyPulsed)`: The current data-ready interrupt mode as a [`DrdyPulsed`] value:
621    ///   - `Latched`: Latched mode (default).
622    ///   - `Pulsed`: Pulsed mode.
623    /// - `Err(Error::Bus)`: If there is an error at the bus level during the read operation.
624    pub async fn data_ready_mode_get(&mut self) -> Result<DrdyPulsed, Error<B::Error>> {
625        Ok(DrdyPulsed::try_from(Ctrl7::read(self).await?.drdy_pulsed()).unwrap_or_default())
626    }
627
628    /// Set the accelerometer filtering path for outputs.
629    ///
630    /// This function configures the filtering path for accelerometer outputs by updating the `fds` field in the `CTRL6` register
631    /// and the `usr_off_on_out` field in the `CTRL7` register.
632    ///
633    /// ### Arguments
634    /// - `val`: A [`Fds`] value representing the desired filtering path:
635    ///   - `LpfOnOut`: Low-pass filter on output (default).
636    ///   - `UserOffsetOnOut`: User offset on output.
637    ///   - `HighPassOnOut`: High-pass filter on output.
638    ///
639    /// ### Returns
640    /// - `Ok(())`: If the operation is successful.
641    /// - `Err(Error::Bus)`: If there is an error at the bus level during the read or write operation.
642    pub async fn filter_path_set(&mut self, val: Fds) -> Result<(), Error<B::Error>> {
643        let mut ctrl6 = Ctrl6::read(self).await?;
644        ctrl6.set_fds(val.fds());
645        ctrl6.write(self).await?;
646
647        let mut ctrl7 = Ctrl7::read(self).await?;
648        ctrl7.set_usr_off_on_out(val.usr_off_on_out());
649        ctrl7.write(self).await
650    }
651
652    /// Get the accelerometer filtering path for outputs.
653    ///
654    /// This function retrieves the current filtering path for accelerometer outputs by reading the `fds` field from the `CTRL6` register
655    /// and the `usr_off_on_out` field from the `CTRL7` register.
656    ///
657    /// ### Returns
658    /// - `Ok(Fds)`: The current filtering path as a [`Fds`] value:
659    ///   - `LpfOnOut`: Low-pass filter on output (default).
660    ///   - `UserOffsetOnOut`: User offset on output.
661    ///   - `HighPassOnOut`: High-pass filter on output.
662    /// - `Err(Error::Bus)`: If there is an error at the bus level during the read operation.
663    pub async fn filter_path_get(&mut self) -> Result<Fds, Error<B::Error>> {
664        let ctrl6 = Ctrl6::read(self).await?;
665        let ctrl7 = Ctrl7::read(self).await?;
666
667        Ok(Fds::new(ctrl6.fds(), ctrl7.usr_off_on_out()))
668    }
669
670    /// Set the accelerometer cutoff filter frequency.
671    ///
672    /// This function configures the cutoff frequency for the accelerometer's low-pass or high-pass filter by updating the `bw_filt` field in the `CTRL6` register.
673    ///
674    /// ### Arguments
675    /// - `val`: A [`BwFilt`] value representing the desired cutoff frequency:
676    ///   - `OdrDiv2`: ODR/2 (default).
677    ///   - `OdrDiv4`: ODR/4.
678    ///   - `OdrDiv10`: ODR/10.
679    ///   - `OdrDiv20`: ODR/20.
680    ///
681    /// ### Returns
682    /// - `Ok(())`: If the operation is successful.
683    /// - `Err(Error::Bus)`: If there is an error at the bus level during the read or write operation.
684    pub async fn filter_bandwidth_set(&mut self, val: BwFilt) -> Result<(), Error<B::Error>> {
685        let mut ctrl6 = Ctrl6::read(self).await?;
686        ctrl6.set_bw_filt(val as u8);
687        ctrl6.write(self).await
688    }
689
690    /// Get the accelerometer cutoff filter frequency.
691    ///
692    /// This function retrieves the current cutoff frequency for the accelerometer's low-pass or high-pass filter by reading the `bw_filt` field from the `CTRL6` register.
693    ///
694    /// ### Returns
695    /// - `Ok(BwFilt)`: The current cutoff frequency as a [`BwFilt`] value:
696    ///   - `OdrDiv2`: ODR/2 (default).
697    ///   - `OdrDiv4`: ODR/4.
698    ///   - `OdrDiv10`: ODR/10.
699    ///   - `OdrDiv20`: ODR/20.
700    /// - `Err(Error::Bus)`: If there is an error at the bus level during the read operation.
701    pub async fn filter_bandwidth_get(&mut self) -> Result<BwFilt, Error<B::Error>> {
702        Ok(BwFilt::try_from(Ctrl6::read(self).await?.bw_filt()).unwrap_or_default())
703    }
704
705    /// Enable or disable the high-pass filter reference mode.
706    ///
707    /// This function configures the high-pass filter reference mode by updating the `hp_ref_mode` field in the `CTRL7` register.
708    ///
709    /// ### Arguments
710    /// - `val`: The desired value for the `hp_ref_mode` field:
711    ///   - `0`: Disable high-pass filter reference mode.
712    ///   - `1`: Enable high-pass filter reference mode.
713    ///
714    /// ### Returns
715    /// - `Ok(())`: If the operation is successful.
716    /// - `Err(Error::Bus)`: If there is an error at the bus level during the read or write operation.
717    pub async fn reference_mode_set(&mut self, val: u8) -> Result<(), Error<B::Error>> {
718        let mut ctrl7 = Ctrl7::read(self).await?;
719        ctrl7.set_hp_ref_mode(val);
720        ctrl7.write(self).await
721    }
722
723    /// Get the high-pass filter reference mode status.
724    ///
725    /// This function retrieves the current status of the high-pass filter reference mode from the `hp_ref_mode` field in the `CTRL7` register.
726    ///
727    /// ### Returns
728    /// - `Ok(u8)`: The current value of the `hp_ref_mode` field:
729    ///   - `0`: High-pass filter reference mode is disabled.
730    ///   - `1`: High-pass filter reference mode is enabled.
731    /// - `Err(Error::Bus)`: If there is an error at the bus level during the read operation.
732    pub async fn reference_mode_get(&mut self) -> Result<u8, Error<B::Error>> {
733        Ok(Ctrl7::read(self).await?.hp_ref_mode())
734    }
735
736    /// Set the SPI serial interface mode.
737    ///
738    /// This function configures the SPI serial interface mode by updating the `sim` field in the `CTRL2` register.
739    /// The SPI interface can operate in either 4-wire or 3-wire mode.
740    ///
741    /// ### Arguments
742    /// - `val`: A [`Sim`] value representing the desired SPI mode:
743    ///   - `Spi4Wire`: 4-wire SPI mode (default).
744    ///   - `Spi3Wire`: 3-wire SPI mode.
745    ///
746    /// ### Returns
747    /// - `Ok(())`: If the operation is successful.
748    /// - `Err(Error::Bus)`: If there is an error at the bus level during the read or write operation.
749    pub async fn spi_mode_set(&mut self, val: Sim) -> Result<(), Error<B::Error>> {
750        let mut ctrl2 = Ctrl2::read(self).await?;
751        ctrl2.set_sim(val as u8);
752        ctrl2.write(self).await
753    }
754
755    /// Get the SPI serial interface mode.
756    ///
757    /// This function retrieves the current SPI serial interface mode from the `sim` field in the `CTRL2` register.
758    ///
759    /// ### Returns
760    /// - `Ok(Sim)`: The current SPI mode as a [`Sim`] value:
761    ///   - `Spi4Wire`: 4-wire SPI mode (default).
762    ///   - `Spi3Wire`: 3-wire SPI mode.
763    /// - `Err(Error::Bus)`: If there is an error at the bus level during the read operation.
764    pub async fn spi_mode_get(&mut self) -> Result<Sim, Error<B::Error>> {
765        Ok(Sim::try_from(Ctrl2::read(self).await?.sim()).unwrap_or_default())
766    }
767
768    /// Enable or disable the I²C interface.
769    ///
770    /// This function configures the I²C interface by updating the `i2c_disable` field in the `CTRL2` register.
771    /// The I²C interface can be enabled or disabled based on the provided value.
772    ///
773    /// ### Arguments
774    /// - `val`: A [`I2cDisable`] value representing the desired I²C interface state:
775    ///   - `I2cEnable`: Enable the I²C interface (default).
776    ///   - `I2cDisable`: Disable the I²C interface.
777    ///
778    /// ### Returns
779    /// - `Ok(())`: If the operation is successful.
780    /// - `Err(Error::Bus)`: If there is an error at the bus level during the read or write operation.
781    pub async fn i2c_interface_set(&mut self, val: I2cDisable) -> Result<(), Error<B::Error>> {
782        let mut ctrl2 = Ctrl2::read(self).await?;
783        ctrl2.set_i2c_disable(val as u8);
784        ctrl2.write(self).await
785    }
786
787    /// Get the I²C interface state.
788    ///
789    /// This function retrieves the current state of the I²C interface from the `i2c_disable` field in the `CTRL2` register.
790    ///
791    /// ### Returns
792    /// - `Ok(I2cDisable)`: The current I²C interface state as a [`I2cDisable`] value:
793    ///   - `I2cEnable`: I²C interface is enabled (default).
794    ///   - `I2cDisable`: I²C interface is disabled.
795    /// - `Err(Error::Bus)`: If there is an error at the bus level during the read operation.
796    pub async fn i2c_interface_get(&mut self) -> Result<I2cDisable, Error<B::Error>> {
797        Ok(I2cDisable::try_from(Ctrl2::read(self).await?.i2c_disable()).unwrap_or_default())
798    }
799
800    /// Configure the CS pull-up resistor.
801    ///
802    /// This function configures the CS pull-up resistor by updating the `cs_pu_disc` field in the `CTRL2` register.
803    /// The pull-up resistor can be connected or disconnected based on the provided value.
804    ///
805    /// ### Arguments
806    /// - `val`: A [`CsPuDisc`] value representing the desired CS pull-up configuration:
807    ///   - `PullUpConnect`: Connect the pull-up resistor (default).
808    ///   - `PullUpDisconnect`: Disconnect the pull-up resistor.
809    ///
810    /// ### Returns
811    /// - `Ok(())`: If the operation is successful.
812    /// - `Err(Error::Bus)`: If there is an error at the bus level during the read or write operation.
813    pub async fn cs_mode_set(&mut self, val: CsPuDisc) -> Result<(), Error<B::Error>> {
814        let mut ctrl2 = Ctrl2::read(self).await?;
815        ctrl2.set_cs_pu_disc(val as u8);
816        ctrl2.write(self).await
817    }
818
819    /// Get the CS pull-up resistor configuration.
820    ///
821    /// This function retrieves the current CS pull-up resistor configuration from the `cs_pu_disc` field in the `CTRL2` register.
822    ///
823    /// ### Returns
824    /// - `Ok(CsPuDisc)`: The current CS pull-up configuration as a [`CsPuDisc`] value:
825    ///   - `PullUpConnect`: Pull-up resistor is connected (default).
826    ///   - `PullUpDisconnect`: Pull-up resistor is disconnected.
827    /// - `Err(Error::Bus)`: If there is an error at the bus level during the read operation.
828    pub async fn cs_mode_get(&mut self) -> Result<CsPuDisc, Error<B::Error>> {
829        Ok(CsPuDisc::try_from(Ctrl2::read(self).await?.cs_pu_disc()).unwrap_or_default())
830    }
831
832    /// Interrupt active-high/low.
833    ///
834    /// # Arguments
835    ///
836    /// * `val`: change the values of h_lactive in reg CTRL3.
837    ///
838    /// # Returns
839    ///
840    /// * `Result`
841    ///     * `()`
842    ///     * `Err`: Returns an error if the operation fails.
843    pub async fn pin_polarity_set(&mut self, val: HLactive) -> Result<(), Error<B::Error>> {
844        let mut ctrl3 = Ctrl3::read(self).await?;
845        ctrl3.set_h_lactive(val as u8);
846        ctrl3.write(self).await
847    }
848
849    /// Interrupt active-high/low.
850    ///
851    /// # Returns
852    ///
853    /// * `Result`
854    ///     * `HLactive`: Get the values of h_lactive in reg CTRL3.
855    ///     * `Err`: Returns an error if the operation fails.
856    pub async fn pin_polarity_get(&mut self) -> Result<HLactive, Error<B::Error>> {
857        Ok(HLactive::try_from(Ctrl3::read(self).await?.h_lactive()).unwrap_or_default())
858    }
859
860    /// Latched/pulsed interrupt.
861    ///
862    /// # Arguments
863    ///
864    /// * `val`: change the values of lir in reg CTRL3.
865    ///
866    /// # Returns
867    ///
868    /// * `Result`
869    ///     * `()`
870    ///     * `Err`: Returns an error if the operation fails.
871    pub async fn int_notification_set(&mut self, val: Lir) -> Result<(), Error<B::Error>> {
872        let mut ctrl3 = Ctrl3::read(self).await?;
873        ctrl3.set_lir(val as u8);
874        ctrl3.write(self).await
875    }
876
877    /// Latched/pulsed interrupt.
878    ///
879    /// # Arguments
880    ///
881    /// * `val`: Get the values of lir in reg CTRL3.
882    ///
883    /// # Returns
884    ///
885    /// * `Result`
886    ///     * `()`
887    pub async fn int_notification_get(&mut self) -> Result<Lir, Error<B::Error>> {
888        Ok(Lir::try_from(Ctrl3::read(self).await?.lir()).unwrap_or_default())
889    }
890
891    /// Push-pull/open drain selection on interrupt pads.
892    ///
893    /// # Arguments
894    ///
895    /// * `val`: change the values of pp_od in reg CTRL3.
896    ///
897    /// # Returns
898    ///
899    /// * `Result`
900    ///     * `()`
901    ///     * `Err`: Returns an error if the operation fails.
902    pub async fn pin_mode_set(&mut self, val: PpOd) -> Result<(), Error<B::Error>> {
903        let mut ctrl3 = Ctrl3::read(self).await?;
904        ctrl3.set_pp_od(val as u8);
905        ctrl3.write(self).await
906    }
907
908    /// Push-pull/open drain selection on interrupt pads.
909    ///
910    /// # Returns
911    ///
912    /// * `Result`
913    ///     * `PpOd`: Get the values of pp_od in reg CTRL3.
914    ///     * `Err`: Returns an error if the operation fails.
915    pub async fn pin_mode_get(&mut self) -> Result<PpOd, Error<B::Error>> {
916        Ok(PpOd::try_from(Ctrl3::read(self).await?.pp_od()).unwrap_or_default())
917    }
918
919    /// Select the signal that need to route on int1 pad.
920    pub async fn pin_int1_route_set(
921        &mut self,
922        val: &Ctrl4Int1PadCtrl,
923    ) -> Result<(), Error<B::Error>> {
924        let ctrl5 = Ctrl5Int2PadCtrl::read(self).await?;
925        let mut ctrl7: Ctrl7 = Ctrl7::read(self).await?;
926
927        if (ctrl5.int2_sleep_state()
928            | ctrl5.int2_sleep_chg()
929            | val.int1_tap()
930            | val.int1_ff()
931            | val.int1_wu()
932            | val.int1_single_tap()
933            | val.int1_6d())
934            != 0
935        {
936            ctrl7.set_interrupts_enable(PROPERTY_ENABLE);
937        } else {
938            ctrl7.set_interrupts_enable(PROPERTY_DISABLE);
939        }
940
941        val.write(self).await?;
942        ctrl7.write(self).await
943    }
944
945    /// Select the signal that need to route on int1 pad.
946    pub async fn pin_int1_route_get(&mut self) -> Result<Ctrl4Int1PadCtrl, Error<B::Error>> {
947        Ctrl4Int1PadCtrl::read(self).await
948    }
949
950    /// Select the signal that need to route on int2 pad.
951    pub async fn pin_int2_route_set(
952        &mut self,
953        val: &Ctrl5Int2PadCtrl,
954    ) -> Result<(), Error<B::Error>> {
955        let ctrl4 = Ctrl4Int1PadCtrl::read(self).await?;
956        let mut ctrl7 = Ctrl7::read(self).await?;
957
958        if (val.int2_sleep_state()
959            | val.int2_sleep_chg()
960            | ctrl4.int1_tap()
961            | ctrl4.int1_ff()
962            | ctrl4.int1_wu()
963            | ctrl4.int1_single_tap()
964            | ctrl4.int1_6d())
965            != 0
966        {
967            ctrl7.set_interrupts_enable(PROPERTY_ENABLE);
968        } else {
969            ctrl7.set_interrupts_enable(PROPERTY_DISABLE);
970        }
971
972        val.write(self).await?;
973        ctrl7.write(self).await
974    }
975
976    /// Select the signal that need to route on int2 pad.
977    ///
978    /// # Returns
979    ///
980    /// * `Result`
981    ///     * `Ctrl5Int2PadCtrl`: register CTRL5_INT2_PAD_CTRL.
982    ///     * `Err`: Returns an error if the operation fails.
983    pub async fn pin_int2_route_get(&mut self) -> Result<Ctrl5Int2PadCtrl, Error<B::Error>> {
984        Ctrl5Int2PadCtrl::read(self).await
985    }
986
987    /// All interrupt signals become available on INT1 pin.
988    ///
989    /// # Arguments
990    ///
991    /// * `val`: Change the values of int2_on_int1 in reg CTRL_REG7.
992    ///
993    /// # Returns
994    ///
995    /// * `Result`
996    ///     * `()`
997    ///     * `Err`: Returns an error if the operation fails.
998    pub async fn all_on_int1_set(&mut self, val: u8) -> Result<(), Error<B::Error>> {
999        let mut reg = Ctrl7::read(self).await?;
1000        reg.set_int2_on_int1(val);
1001        reg.write(self).await
1002    }
1003
1004    /// All interrupt signals become available on INT1 pin.
1005    ///
1006    /// # Returns
1007    ///
1008    /// * `Result`
1009    ///     * `u8`: change the values of int2_on_int1 in reg CTRL_REG7.
1010    ///     * `Err`: Returns an error if the operation fails.
1011    pub async fn all_on_int1_get(&mut self) -> Result<u8, Error<B::Error>> {
1012        Ok(Ctrl7::read(self).await?.int2_on_int1())
1013    }
1014
1015    /// Set the wake-up threshold.
1016    ///
1017    /// This function configures the wake-up threshold by updating the `wk_ths` field in the `WAKE_UP_THS` register.
1018    /// The threshold is expressed in LSB, where 1 LSB = FS_XL / 64.
1019    ///
1020    /// ### Arguments
1021    /// - `val`: The desired wake-up threshold value.
1022    ///
1023    /// ### Returns
1024    /// - `Ok(())`: If the operation is successful.
1025    /// - `Err(Error::Bus)`: If there is an error at the bus level during the read or write operation.
1026    pub async fn wkup_threshold_set(&mut self, val: u8) -> Result<(), Error<B::Error>> {
1027        let mut reg = WakeUpThs::read(self).await?;
1028        reg.set_wk_ths(val);
1029        reg.write(self).await
1030    }
1031
1032    /// Get the wake-up threshold.
1033    ///
1034    /// This function retrieves the current wake-up threshold from the `wk_ths` field in the `WAKE_UP_THS` register.
1035    /// The threshold is expressed in LSB, where 1 LSB = FS_XL / 64.
1036    ///
1037    /// ### Returns
1038    /// - `Ok(u8)`: The current wake-up threshold value.
1039    /// - `Err(Error::Bus)`: If there is an error at the bus level during the read operation.
1040    pub async fn wkup_threshold_get(&mut self) -> Result<u8, Error<B::Error>> {
1041        Ok(WakeUpThs::read(self).await?.wk_ths())
1042    }
1043
1044    /// Set the wake-up duration event.
1045    ///
1046    /// This function configures the wake-up duration by updating the `wake_dur` field in the `WAKE_UP_DUR` register.
1047    /// The duration is expressed in LSB, where 1 LSB = 1 / ODR.
1048    ///
1049    /// ### Arguments
1050    /// - `val`: The desired wake-up duration value.
1051    ///
1052    /// ### Returns
1053    /// - `Ok(())`: If the operation is successful.
1054    /// - `Err(Error::Bus)`: If there is an error at the bus level during the read or write operation.
1055    pub async fn wkup_dur_set(&mut self, val: u8) -> Result<(), Error<B::Error>> {
1056        let mut reg = WakeUpDur::read(self).await?;
1057        reg.set_wake_dur(val);
1058        reg.write(self).await
1059    }
1060
1061    /// Get the wake-up duration event.
1062    ///
1063    /// This function retrieves the current wake-up duration from the `wake_dur` field in the `WAKE_UP_DUR` register.
1064    /// The duration is expressed in LSB, where 1 LSB = 1 / ODR.
1065    ///
1066    /// ### Returns
1067    /// - `Ok(u8)`: The current wake-up duration value.
1068    /// - `Err(Error::Bus)`: If there is an error at the bus level during the read operation.
1069    pub async fn wkup_dur_get(&mut self) -> Result<u8, Error<B::Error>> {
1070        Ok(WakeUpDur::read(self).await?.wake_dur())
1071    }
1072
1073    /// Set the data sent to the wake-up interrupt function.
1074    ///
1075    /// This function configures the data source for the wake-up interrupt function by updating the `usr_off_on_wu` field in the `CTRL7` register.
1076    /// The data source can be either high-pass filtered data or user offset data.
1077    ///
1078    /// ### Arguments
1079    /// - `val`: A [`UsrOffOnWu`] value representing the desired data source:
1080    ///   - `HpFeed`: High-pass filtered data (default).
1081    ///   - `UserOffsetFeed`: User offset data.
1082    ///
1083    /// ### Returns
1084    /// - `Ok(())`: If the operation is successful.
1085    /// - `Err(Error::Bus)`: If there is an error at the bus level during the read or write operation.
1086    pub async fn wkup_feed_data_set(&mut self, val: UsrOffOnWu) -> Result<(), Error<B::Error>> {
1087        let mut reg = Ctrl7::read(self).await?;
1088        reg.set_usr_off_on_wu(val as u8);
1089        reg.write(self).await
1090    }
1091
1092    /// Get the data sent to the wake-up interrupt function.
1093    ///
1094    /// This function retrieves the current data source for the wake-up interrupt function from the `usr_off_on_wu` field in the `CTRL7` register.
1095    ///
1096    /// ### Returns
1097    /// - `Ok(UsrOffOnWu)`: The current data source as a [`UsrOffOnWu`] value:
1098    ///   - `HpFeed`: High-pass filtered data (default).
1099    ///   - `UserOffsetFeed`: User offset data.
1100    /// - `Err(Error::Bus)`: If there is an error at the bus level during the read operation.
1101    pub async fn wkup_feed_data_get(&mut self) -> Result<UsrOffOnWu, Error<B::Error>> {
1102        Ok(UsrOffOnWu::try_from(Ctrl7::read(self).await?.usr_off_on_wu()).unwrap_or_default())
1103    }
1104
1105    /// Configure activity/inactivity or stationary/motion detection.
1106    ///
1107    /// This function configures the activity/inactivity or stationary/motion detection by updating the `sleep_on` field in the `WAKE_UP_THS` register
1108    /// and the `stationary` field in the `WAKE_UP_DUR` register.
1109    ///
1110    /// ### Arguments
1111    /// - `val`: A [`SleepOn`] value representing the desired detection mode:
1112    ///   - `NoDetection`: No detection (default).
1113    ///   - `DetectActInact`: Detect activity/inactivity.
1114    ///   - `DetectStatMotion`: Detect stationary/motion.
1115    ///
1116    /// ### Returns
1117    /// - `Ok(())`: If the operation is successful.
1118    /// - `Err(Error::Bus)`: If there is an error at the bus level during the read or write operation.
1119    pub async fn act_mode_set(&mut self, val: SleepOn) -> Result<(), Error<B::Error>> {
1120        let mut wake_up_ths = WakeUpThs::read(self).await?;
1121        let mut wake_up_dur: WakeUpDur = WakeUpDur::read(self).await?;
1122
1123        wake_up_ths.set_sleep_on(val.sleep_on());
1124        wake_up_dur.set_stationary(val.stationary());
1125
1126        wake_up_ths.write(self).await?;
1127        wake_up_dur.write(self).await
1128    }
1129
1130    /// Get the activity/inactivity or stationary/motion detection configuration.
1131    ///
1132    /// This function retrieves the current detection mode by reading the `sleep_on` field from the `WAKE_UP_THS` register
1133    /// and the `stationary` field from the `WAKE_UP_DUR` register.
1134    ///
1135    /// ### Returns
1136    /// - `Ok(SleepOn)`: The current detection mode as a [`SleepOn`] value:
1137    ///   - `NoDetection`: No detection (default).
1138    ///   - `DetectActInact`: Detect activity/inactivity.
1139    ///   - `DetectStatMotion`: Detect stationary/motion.
1140    /// - `Err(Error::Bus)`: If there is an error at the bus level during the read operation.
1141    pub async fn act_mode_get(&mut self) -> Result<SleepOn, Error<B::Error>> {
1142        let wake_up_ths = WakeUpThs::read(self).await?;
1143        let wake_up_dur: WakeUpDur = WakeUpDur::read(self).await?;
1144
1145        Ok(SleepOn::new(
1146            wake_up_ths.sleep_on(),
1147            wake_up_dur.stationary(),
1148        ))
1149    }
1150
1151    /// Set the duration to enter sleep mode.
1152    ///
1153    /// This function configures the duration required to enter sleep mode by updating the `sleep_dur` field in the `WAKE_UP_DUR` register.
1154    /// The duration is expressed in LSB, where 1 LSB = 512 / ODR.
1155    ///
1156    /// ### Arguments
1157    /// - `val`: The desired sleep duration value.
1158    ///
1159    /// ### Returns
1160    /// - `Ok(())`: If the operation is successful.
1161    /// - `Err(Error::Bus)`: If there is an error at the bus level during the read or write operation.
1162    pub async fn act_sleep_dur_set(&mut self, val: u8) -> Result<(), Error<B::Error>> {
1163        let mut reg = WakeUpDur::read(self).await?;
1164        reg.set_sleep_dur(val);
1165        reg.write(self).await
1166    }
1167
1168    /// Get the duration to enter sleep mode.
1169    ///
1170    /// This function retrieves the current sleep duration from the `sleep_dur` field in the `WAKE_UP_DUR` register.
1171    /// The duration is expressed in LSB, where 1 LSB = 512 / ODR.
1172    ///
1173    /// ### Returns
1174    /// - `Ok(u8)`: The current sleep duration value.
1175    /// - `Err(Error::Bus)`: If there is an error at the bus level during the read operation.
1176    pub async fn act_sleep_dur_get(&mut self) -> Result<u8, Error<B::Error>> {
1177        Ok(WakeUpDur::read(self).await?.sleep_dur())
1178    }
1179
1180    /// Set the threshold for tap recognition on the X-axis.
1181    ///
1182    /// This function configures the tap threshold for the X-axis by updating the `tap_thsx` field in the `TAP_THS_X` register.
1183    ///
1184    /// ### Arguments
1185    /// - `val`: The desired tap threshold value for the X-axis.
1186    ///
1187    /// ### Returns
1188    /// - `Ok(())`: If the operation is successful.
1189    /// - `Err(Error::Bus)`: If there is an error at the bus level during the read or write operation.
1190    pub async fn tap_threshold_x_set(&mut self, val: u8) -> Result<(), Error<B::Error>> {
1191        let mut reg = TapThsX::read(self).await?;
1192        reg.set_tap_thsx(val);
1193        reg.write(self).await
1194    }
1195
1196    /// Get the threshold for tap recognition on the X-axis.
1197    ///
1198    /// This function retrieves the current tap threshold for the X-axis from the `tap_thsx` field in the `TAP_THS_X` register.
1199    ///
1200    /// ### Returns
1201    /// - `Ok(u8)`: The current tap threshold value for the X-axis.
1202    /// - `Err(Error::Bus)`: If there is an error at the bus level during the read operation.
1203    pub async fn tap_threshold_x_get(&mut self) -> Result<u8, Error<B::Error>> {
1204        Ok(TapThsX::read(self).await?.tap_thsx())
1205    }
1206
1207    /// Set the threshold for tap recognition on the Y-axis.
1208    ///
1209    /// This function configures the tap threshold for the Y-axis by updating the `tap_thsy` field in the `TAP_THS_Y` register.
1210    ///
1211    /// ### Arguments
1212    /// - `val`: The desired tap threshold value for the Y-axis.
1213    ///
1214    /// ### Returns
1215    /// - `Ok(())`: If the operation is successful.
1216    /// - `Err(Error::Bus)`: If there is an error at the bus level during the read or write operation.
1217    pub async fn tap_threshold_y_set(&mut self, val: u8) -> Result<(), Error<B::Error>> {
1218        let mut reg = TapThsY::read(self).await?;
1219        reg.set_tap_thsy(val);
1220        reg.write(self).await
1221    }
1222
1223    /// Get the threshold for tap recognition on the Y-axis.
1224    ///
1225    /// This function retrieves the current tap threshold for the Y-axis from the `tap_thsy` field in the `TAP_THS_Y` register.
1226    ///
1227    /// ### Returns
1228    /// - `Ok(u8)`: The current tap threshold value for the Y-axis.
1229    /// - `Err(Error::Bus)`: If there is an error at the bus level during the read operation.
1230    pub async fn tap_threshold_y_get(&mut self) -> Result<u8, Error<B::Error>> {
1231        Ok(TapThsY::read(self).await?.tap_thsy())
1232    }
1233
1234    /// Set the axis priority for tap detection.
1235    ///
1236    /// This function configures the axis priority for tap detection by updating the `tap_prior` field in the `TAP_THS_Y` register.
1237    ///
1238    /// ### Arguments
1239    /// - `val`: A [`TapPrior`] value representing the desired axis priority:
1240    ///   - `Xyz`: X > Y > Z (default).
1241    ///   - `Yxz`: Y > X > Z.
1242    ///   - `Xzy`: X > Z > Y.
1243    ///   - `Zyx`: Z > Y > X.
1244    ///   - `Yzx`: Y > Z > X.
1245    ///   - `Zxy`: Z > X > Y.
1246    ///
1247    /// ### Returns
1248    /// - `Ok(())`: If the operation is successful.
1249    /// - `Err(Error::Bus)`: If there is an error at the bus level during the read or write operation.
1250    pub async fn tap_axis_priority_set(&mut self, val: TapPrior) -> Result<(), Error<B::Error>> {
1251        let mut reg = TapThsY::read(self).await?;
1252        reg.set_tap_prior(val as u8);
1253        reg.write(self).await
1254    }
1255
1256    /// Get the axis priority for tap detection.
1257    ///
1258    /// This function retrieves the current axis priority for tap detection from the `tap_prior` field in the `TAP_THS_Y` register.
1259    ///
1260    /// ### Returns
1261    /// - `Ok(TapPrior)`: The current axis priority as a [`TapPrior`] value.
1262    /// - `Err(Error::Bus)`: If there is an error at the bus level during the read operation.
1263    pub async fn tap_axis_priority_get(&mut self) -> Result<TapPrior, Error<B::Error>> {
1264        Ok(TapPrior::try_from(TapThsY::read(self).await?.tap_prior()).unwrap_or_default())
1265    }
1266
1267    /// Set the threshold for tap recognition on the Z-axis.
1268    ///
1269    /// This function configures the tap threshold for the Z-axis by updating the `tap_thsz` field in the `TAP_THS_Z` register.
1270    ///
1271    /// ### Arguments
1272    /// - `val`: The desired tap threshold value for the Z-axis.
1273    ///
1274    /// ### Returns
1275    /// - `Ok(())`: If the operation is successful.
1276    /// - `Err(Error::Bus)`: If there is an error at the bus level during the read or write operation.
1277    pub async fn tap_threshold_z_set(&mut self, val: u8) -> Result<(), Error<B::Error>> {
1278        let mut reg = TapThsZ::read(self).await?;
1279        reg.set_tap_thsz(val);
1280        reg.write(self).await
1281    }
1282
1283    /// Get the threshold for tap recognition on the Z-axis.
1284    ///
1285    /// This function retrieves the current tap threshold for the Z-axis from the `tap_thsz` field in the `TAP_THS_Z` register.
1286    ///
1287    /// ### Returns
1288    /// - `Ok(u8)`: The current tap threshold value for the Z-axis.
1289    /// - `Err(Error::Bus)`: If there is an error at the bus level during the read operation.
1290    pub async fn tap_threshold_z_get(&mut self) -> Result<u8, Error<B::Error>> {
1291        Ok(TapThsZ::read(self).await?.tap_thsz())
1292    }
1293
1294    /// Enable Z direction in tap recognition.
1295    ///
1296    /// This function enables or disables tap recognition on the Z-axis by updating the `tap_z_en` field in the `TAP_THS_Z` register.
1297    ///
1298    /// ### Arguments
1299    /// - `val`: The desired value for the `tap_z_en` field:
1300    ///   - `0`: Disable Z-axis tap recognition.
1301    ///   - `1`: Enable Z-axis tap recognition.
1302    ///
1303    /// ### Returns
1304    /// - `Ok(())`: If the operation is successful.
1305    /// - `Err(Error::Bus)`: If there is an error at the bus level during the read or write operation.
1306    pub async fn tap_detection_on_z_set(&mut self, val: u8) -> Result<(), Error<B::Error>> {
1307        let mut reg = TapThsZ::read(self).await?;
1308        reg.set_tap_z_en(val);
1309        reg.write(self).await
1310    }
1311
1312    /// Get the Z direction tap recognition status.
1313    ///
1314    /// This function retrieves the current status of tap recognition on the Z-axis from the `tap_z_en` field in the `TAP_THS_Z` register.
1315    ///
1316    /// ### Returns
1317    /// - `Ok(u8)`: The current value of the `tap_z_en` field:
1318    ///   - `0`: Z-axis tap recognition is disabled.
1319    ///   - `1`: Z-axis tap recognition is enabled.
1320    /// - `Err(Error::Bus)`: If there is an error at the bus level during the read operation.
1321    pub async fn tap_detection_on_z_get(&mut self) -> Result<u8, Error<B::Error>> {
1322        Ok(TapThsZ::read(self).await?.tap_z_en())
1323    }
1324
1325    /// Enable Y direction in tap recognition.
1326    ///
1327    /// This function enables or disables tap recognition on the Y-axis by updating the `tap_y_en` field in the `TAP_THS_Z` register.
1328    ///
1329    /// ### Arguments
1330    /// - `val`: The desired value for the `tap_y_en` field:
1331    ///   - `0`: Disable Y-axis tap recognition.
1332    ///   - `1`: Enable Y-axis tap recognition.
1333    ///
1334    /// ### Returns
1335    /// - `Ok(())`: If the operation is successful.
1336    /// - `Err(Error::Bus)`: If there is an error at the bus level during the read or write operation.
1337    pub async fn tap_detection_on_y_set(&mut self, val: u8) -> Result<(), Error<B::Error>> {
1338        let mut reg = TapThsZ::read(self).await?;
1339        reg.set_tap_y_en(val);
1340        reg.write(self).await
1341    }
1342
1343    /// Get the Y direction tap recognition status.
1344    ///
1345    /// This function retrieves the current status of tap recognition on the Y-axis from the `tap_y_en` field in the `TAP_THS_Z` register.
1346    ///
1347    /// ### Returns
1348    /// - `Ok(u8)`: The current value of the `tap_y_en` field:
1349    ///   - `0`: Y-axis tap recognition is disabled.
1350    ///   - `1`: Y-axis tap recognition is enabled.
1351    /// - `Err(Error::Bus)`: If there is an error at the bus level during the read operation.
1352    pub async fn tap_detection_on_y_get(&mut self) -> Result<u8, Error<B::Error>> {
1353        Ok(TapThsZ::read(self).await?.tap_y_en())
1354    }
1355
1356    /// Enable X direction in tap recognition.
1357    ///
1358    /// This function enables or disables tap recognition on the X-axis by updating the `tap_x_en` field in the `TAP_THS_Z` register.
1359    ///
1360    /// ### Arguments
1361    /// - `val`: The desired value for the `tap_x_en` field:
1362    ///   - `0`: Disable X-axis tap recognition.
1363    ///   - `1`: Enable X-axis tap recognition.
1364    ///
1365    /// ### Returns
1366    /// - `Ok(())`: If the operation is successful.
1367    /// - `Err(Error::Bus)`: If there is an error at the bus level during the read or write operation.
1368    pub async fn tap_detection_on_x_set(&mut self, val: u8) -> Result<(), Error<B::Error>> {
1369        let mut reg = TapThsZ::read(self).await?;
1370        reg.set_tap_x_en(val);
1371        reg.write(self).await
1372    }
1373
1374    /// Get the X direction tap recognition status.
1375    ///
1376    /// This function retrieves the current status of tap recognition on the X-axis from the `tap_x_en` field in the `TAP_THS_Z` register.
1377    ///
1378    /// ### Returns
1379    /// - `Ok(u8)`: The current value of the `tap_x_en` field:
1380    ///   - `0`: X-axis tap recognition is disabled.
1381    ///   - `1`: X-axis tap recognition is enabled.
1382    /// - `Err(Error::Bus)`: If there is an error at the bus level during the read operation.
1383    pub async fn tap_detection_on_x_get(&mut self) -> Result<u8, Error<B::Error>> {
1384        Ok(TapThsZ::read(self).await?.tap_x_en())
1385    }
1386
1387    /// Set the maximum duration for tap recognition.
1388    ///
1389    /// This function configures the maximum time an over-threshold signal is detected to be recognized as a tap event.
1390    /// The duration is set in the `shock` field of the `INT_DUR` register.
1391    /// - The default value (`00b`) corresponds to `4 * ODR_XL` time.
1392    /// - If the `shock` bits are set to a different value, 1 LSB corresponds to `8 * ODR_XL` time.
1393    ///
1394    /// ### Arguments
1395    /// - `val`: The desired maximum duration value for tap recognition.
1396    ///
1397    /// ### Returns
1398    /// - `Ok(())`: If the operation is successful.
1399    /// - `Err(Error::Bus)`: If there is an error at the bus level during the read or write operation.
1400    pub async fn tap_shock_set(&mut self, val: u8) -> Result<(), Error<B::Error>> {
1401        let mut reg = IntDur::read(self).await?;
1402        reg.set_shock(val);
1403        reg.write(self).await
1404    }
1405
1406    /// Get the maximum duration for tap recognition.
1407    ///
1408    /// This function retrieves the current maximum time an over-threshold signal is detected to be recognized as a tap event.
1409    /// The duration is stored in the `shock` field of the `INT_DUR` register.
1410    ///
1411    /// ### Returns
1412    /// - `Ok(u8)`: The current maximum duration value for tap recognition.
1413    /// - `Err(Error::Bus)`: If there is an error at the bus level during the read operation.
1414    pub async fn tap_shock_get(&mut self) -> Result<u8, Error<B::Error>> {
1415        Ok(IntDur::read(self).await?.shock())
1416    }
1417
1418    /// Set the quiet time for tap recognition.
1419    ///
1420    /// This function configures the quiet time after the first detected tap during which no over-threshold event should occur.
1421    /// The quiet time is set in the `quiet` field of the `INT_DUR` register.
1422    /// - The default value (`00b`) corresponds to `2 * ODR_XL` time.
1423    /// - If the `quiet` bits are set to a different value, 1 LSB corresponds to `4 * ODR_XL` time.
1424    ///
1425    /// ### Arguments
1426    /// - `val`: The desired quiet time value.
1427    ///
1428    /// ### Returns
1429    /// - `Ok(())`: If the operation is successful.
1430    /// - `Err(Error::Bus)`: If there is an error at the bus level during the read or write operation.
1431    pub async fn tap_quiet_set(&mut self, val: u8) -> Result<(), Error<B::Error>> {
1432        let mut reg = IntDur::read(self).await?;
1433        reg.set_quiet(val);
1434        reg.write(self).await
1435    }
1436
1437    /// Get the quiet time for tap recognition.
1438    ///
1439    /// This function retrieves the current quiet time after the first detected tap during which no over-threshold event should occur.
1440    /// The quiet time is stored in the `quiet` field of the `INT_DUR` register.
1441    ///
1442    /// ### Returns
1443    /// - `Ok(u8)`: The current quiet time value.
1444    /// - `Err(Error::Bus)`: If there is an error at the bus level during the read operation.
1445    pub async fn tap_quiet_get(&mut self) -> Result<u8, Error<B::Error>> {
1446        Ok(IntDur::read(self).await?.quiet())
1447    }
1448
1449    /// Set the maximum duration for double-tap recognition.
1450    ///
1451    /// This function configures the maximum time between two consecutive detected taps to determine a double-tap event.
1452    /// The duration is set in the `latency` field of the `INT_DUR` register.
1453    /// - The default value (`0000b`) corresponds to `16 * ODR_XL` time.
1454    /// - If the `latency` bits are set to a different value, 1 LSB corresponds to `32 * ODR_XL` time.
1455    ///
1456    /// ### Arguments
1457    /// - `val`: The desired maximum duration value for double-tap recognition.
1458    ///
1459    /// ### Returns
1460    /// - `Ok(())`: If the operation is successful.
1461    /// - `Err(Error::Bus)`: If there is an error at the bus level during the read or write operation.
1462    pub async fn tap_dur_set(&mut self, val: u8) -> Result<(), Error<B::Error>> {
1463        let mut reg = IntDur::read(self).await?;
1464        reg.set_latency(val);
1465        reg.write(self).await
1466    }
1467
1468    /// Get the maximum duration for double-tap recognition.
1469    ///
1470    /// This function retrieves the current maximum time between two consecutive detected taps to determine a double-tap event.
1471    /// The duration is stored in the `latency` field of the `INT_DUR` register.
1472    ///
1473    /// ### Returns
1474    /// - `Ok(u8)`: The current maximum duration value for double-tap recognition.
1475    /// - `Err(Error::Bus)`: If there is an error at the bus level during the read operation.
1476    pub async fn tap_dur_get(&mut self) -> Result<u8, Error<B::Error>> {
1477        Ok(IntDur::read(self).await?.latency())
1478    }
1479
1480    /// Enable or disable single/double-tap event detection.
1481    ///
1482    /// This function configures the single/double-tap event detection by updating the `single_double_tap` field in the `WAKE_UP_THS` register.
1483    /// The mode determines whether only single-tap events or both single- and double-tap events are detected.
1484    ///
1485    /// ### Arguments
1486    /// - `val`: A [`SingleDoubleTap`] value representing the desired tap mode:
1487    ///   - `OnlySingle`: Detect only single-tap events (default).
1488    ///   - `BothSingleDouble`: Detect both single- and double-tap events.
1489    ///
1490    /// ### Returns
1491    /// - `Ok(())`: If the operation is successful.
1492    /// - `Err(Error::Bus)`: If there is an error at the bus level during the read or write operation.
1493    pub async fn tap_mode_set(&mut self, val: SingleDoubleTap) -> Result<(), Error<B::Error>> {
1494        let mut reg = WakeUpThs::read(self).await?;
1495        reg.set_single_double_tap(val as u8);
1496        reg.write(self).await
1497    }
1498
1499    /// Get the single/double-tap event detection mode.
1500    ///
1501    /// This function retrieves the current single/double-tap event detection mode from the `single_double_tap` field in the `WAKE_UP_THS` register.
1502    ///
1503    /// ### Returns
1504    /// - `Ok(SingleDoubleTap)`: The current tap mode as a [`SingleDoubleTap`] value:
1505    ///   - `OnlySingle`: Detect only single-tap events (default).
1506    ///   - `BothSingleDouble`: Detect both single- and double-tap events.
1507    /// - `Err(Error::Bus)`: If there is an error at the bus level during the read operation.
1508    pub async fn tap_mode_get(&mut self) -> Result<SingleDoubleTap, Error<B::Error>> {
1509        Ok(
1510            SingleDoubleTap::try_from(WakeUpThs::read(self).await?.single_double_tap())
1511                .unwrap_or_default(),
1512        )
1513    }
1514
1515    /// Read the tap/double-tap source register.
1516    ///
1517    /// This function retrieves the tap/double-tap source information from the `TAP_SRC` register.
1518    /// The `TAP_SRC` register provides details about the tap events, such as the axis of detection and the type of tap event.
1519    ///
1520    /// ### Returns
1521    /// - `Ok(TapSrc)`: The tap source information as a [`TapSrc`] struct.
1522    /// - `Err(Error::Bus)`: If there is an error at the bus level during the read operation.
1523    pub async fn tap_src_get(&mut self) -> Result<TapSrc, Error<B::Error>> {
1524        TapSrc::read(self).await
1525    }
1526
1527    /// Set the threshold for 4D/6D orientation detection.
1528    ///
1529    /// This function configures the threshold for 4D/6D orientation detection by updating the `6d_ths` field in the `TAP_THS_X` register.
1530    ///
1531    /// ### Arguments
1532    /// - `val`: The desired threshold value for 4D/6D orientation detection.
1533    ///
1534    /// ### Returns
1535    /// - `Ok(())`: If the operation is successful.
1536    /// - `Err(Error::Bus)`: If there is an error at the bus level during the read or write operation.
1537    pub async fn sixd_threshold_set(&mut self, val: u8) -> Result<(), Error<B::Error>> {
1538        let mut reg = TapThsX::read(self).await?;
1539        reg.set_six_d_ths(val);
1540        reg.write(self).await
1541    }
1542
1543    /// Get the threshold for 4D/6D orientation detection.
1544    ///
1545    /// This function retrieves the current threshold for 4D/6D orientation detection from the `6d_ths` field in the `TAP_THS_X` register.
1546    ///
1547    /// ### Returns
1548    /// - `Ok(u8)`: The current threshold value for 4D/6D orientation detection.
1549    /// - `Err(Error::Bus)`: If there is an error at the bus level during the read operation.
1550    pub async fn sixd_threshold_get(&mut self) -> Result<u8, Error<B::Error>> {
1551        Ok(TapThsX::read(self).await?.six_d_ths())
1552    }
1553
1554    /// Enable or disable 4D orientation detection.
1555    ///
1556    /// This function configures the 4D orientation detection by updating the `4d_en` field in the `TAP_THS_X` register.
1557    ///
1558    /// ### Arguments
1559    /// - `val`: The desired value for the `4d_en` field:
1560    ///   - `0`: Disable 4D orientation detection.
1561    ///   - `1`: Enable 4D orientation detection.
1562    ///
1563    /// ### Returns
1564    /// - `Ok(())`: If the operation is successful.
1565    /// - `Err(Error::Bus)`: If there is an error at the bus level during the read or write operation.
1566    pub async fn fourd_mode_set(&mut self, val: u8) -> Result<(), Error<B::Error>> {
1567        let mut reg = TapThsX::read(self).await?;
1568        reg.set_four_d_en(val);
1569        reg.write(self).await
1570    }
1571
1572    /// Get the 4D orientation detection status.
1573    ///
1574    /// This function retrieves the current status of 4D orientation detection from the `4d_en` field in the `TAP_THS_X` register.
1575    ///
1576    /// ### Returns
1577    /// - `Ok(u8)`: The current value of the `4d_en` field:
1578    ///   - `0`: 4D orientation detection is disabled.
1579    ///   - `1`: 4D orientation detection is enabled.
1580    /// - `Err(Error::Bus)`: If there is an error at the bus level during the read operation.
1581    pub async fn fourd_mode_get(&mut self) -> Result<u8, Error<B::Error>> {
1582        Ok(TapThsX::read(self).await?.four_d_en())
1583    }
1584
1585    /// Read the 6D tap source register.
1586    ///
1587    /// This function retrieves the 6D tap source information from the `SIXD_SRC` register.
1588    /// The `SIXD_SRC` register provides details about the 6D orientation events, such as axis-specific thresholds and event detection.
1589    ///
1590    /// ### Returns
1591    /// - `Ok(SixdSrc)`: The 6D source information as a [`SixdSrc`] struct.
1592    /// - `Err(Error::Bus)`: If there is an error at the bus level during the read operation.
1593    pub async fn sixd_src_get(&mut self) -> Result<SixdSrc, Error<B::Error>> {
1594        SixdSrc::read(self).await
1595    }
1596
1597    /// Set the data source for the 6D interrupt function.
1598    ///
1599    /// This function configures the data source for the 6D interrupt function by updating the `lpass_on6d` field in the `CTRL7` register.
1600    /// The data source can be either ODR/2 low-pass filtered data or LPF2 output data.
1601    ///
1602    /// ### Arguments
1603    /// - `val`: A [`LpassOn6d`] value representing the desired data source:
1604    ///   - `OdrDiv2Feed`: ODR/2 low-pass filtered data (default).
1605    ///   - `Lpf2Feed`: LPF2 output data.
1606    ///
1607    /// ### Returns
1608    /// - `Ok(())`: If the operation is successful.
1609    /// - `Err(Error::Bus)`: If there is an error at the bus level during the read or write operation.
1610    pub async fn sixd_feed_data_set(&mut self, val: LpassOn6d) -> Result<(), Error<B::Error>> {
1611        let mut reg = Ctrl7::read(self).await?;
1612        reg.set_lpass_on6d(val as u8);
1613        reg.write(self).await
1614    }
1615
1616    /// Get the data source for the 6D interrupt function.
1617    ///
1618    /// This function retrieves the current data source for the 6D interrupt function from the `lpass_on6d` field in the `CTRL7` register.
1619    ///
1620    /// ### Returns
1621    /// - `Ok(LpassOn6d)`: The current data source as a [`LpassOn6d`] value.
1622    /// - `Err(Error::Bus)`: If there is an error at the bus level during the read operation.
1623    pub async fn sixd_feed_data_get(&mut self) -> Result<LpassOn6d, Error<B::Error>> {
1624        Ok(LpassOn6d::try_from(Ctrl7::read(self).await?.lpass_on6d()).unwrap_or_default())
1625    }
1626
1627    /// Set the wake-up duration event.
1628    ///
1629    /// This function configures the wake-up duration event by updating the `ff_dur` field in the `WAKE_UP_DUR` and `FREE_FALL` registers.
1630    /// The duration is expressed in LSB, where 1 LSB = 1 / ODR.
1631    ///
1632    /// ### Arguments
1633    /// - `val`: The desired wake-up duration value.
1634    ///
1635    /// ### Returns
1636    /// - `Ok(())`: If the operation is successful.
1637    /// - `Err(Error::Bus)`: If there is an error at the bus level during the read or write operation.
1638    pub async fn ff_dur_set(&mut self, val: u8) -> Result<(), Error<B::Error>> {
1639        let mut wake_up_dur = WakeUpDur::read(self).await?;
1640        let mut free_fall = FreeFall::read(self).await?;
1641
1642        wake_up_dur.set_ff_dur((val & 0x20) >> 5);
1643        free_fall.set_ff_dur(val & 0x1F);
1644
1645        wake_up_dur.write(self).await?;
1646        free_fall.write(self).await
1647    }
1648
1649    /// Get the wake-up duration event.
1650    ///
1651    /// This function retrieves the current wake-up duration event from the `ff_dur` field in the `WAKE_UP_DUR` and `FREE_FALL` registers.
1652    /// The duration is expressed in LSB, where 1 LSB = 1 / ODR.
1653    ///
1654    /// ### Returns
1655    /// - `Ok(u8)`: The current wake-up duration value.
1656    /// - `Err(Error::Bus)`: If there is an error at the bus level during the read operation.
1657    pub async fn ff_dur_get(&mut self) -> Result<u8, Error<B::Error>> {
1658        let wake_up_dur = WakeUpDur::read(self).await?;
1659        let free_fall = FreeFall::read(self).await?;
1660
1661        Ok((wake_up_dur.ff_dur() << 5) + free_fall.ff_dur())
1662    }
1663
1664    /// Set the free-fall threshold.
1665    ///
1666    /// This function configures the free-fall threshold by updating the `ff_ths` field in the `FREE_FALL` register.
1667    /// The threshold determines the sensitivity of the free-fall detection.
1668    ///
1669    /// ### Arguments
1670    /// - `val`: A [`FfThs`] value representing the desired free-fall threshold:
1671    ///   - `FfTsh5lsbFs2g`: 5 LSB @ ±2g (default).
1672    ///   - `FfTsh7lsbFs2g`: 7 LSB @ ±2g.
1673    ///   - `FfTsh8lsbFs2g`: 8 LSB @ ±2g.
1674    ///   - `FfTsh10lsbFs2g`: 10 LSB @ ±2g.
1675    ///   - `FfTsh11lsbFs2g`: 11 LSB @ ±2g.
1676    ///   - `FfTsh13lsbFs2g`: 13 LSB @ ±2g.
1677    ///   - `FfTsh15lsbFs2g`: 15 LSB @ ±2g.
1678    ///   - `FfTsh16lsbFs2g`: 16 LSB @ ±2g.
1679    ///
1680    /// ### Returns
1681    /// - `Ok(())`: If the operation is successful.
1682    /// - `Err(Error::Bus)`: If there is an error at the bus level during the read or write operation.
1683    pub async fn ff_threshold_set(&mut self, val: FfThs) -> Result<(), Error<B::Error>> {
1684        let mut reg = FreeFall::read(self).await?;
1685        reg.set_ff_ths(val as u8);
1686        reg.write(self).await
1687    }
1688
1689    /// Get the free-fall threshold.
1690    ///
1691    /// This function retrieves the current free-fall threshold from the `ff_ths` field in the `FREE_FALL` register.
1692    ///
1693    /// ### Returns
1694    /// - `Ok(FfThs)`: The current free-fall threshold as a [`FfThs`] value.
1695    /// - `Err(Error::Bus)`: If there is an error at the bus level during the read operation.
1696    pub async fn ff_threshold_get(&mut self) -> Result<FfThs, Error<B::Error>> {
1697        Ok(FfThs::try_from(FreeFall::read(self).await?.ff_ths()).unwrap_or_default())
1698    }
1699
1700    /// Set the FIFO watermark level.
1701    ///
1702    /// This function configures the FIFO watermark level by updating the `fth` field in the `FIFO_CTRL` register.
1703    /// The watermark level determines the threshold at which the FIFO generates an interrupt when the number of unread samples reaches the specified level.
1704    ///
1705    /// ### Arguments
1706    /// - `val`: The desired FIFO watermark level.
1707    ///
1708    /// ### Returns
1709    /// - `Ok(())`: If the operation is successful.
1710    /// - `Err(Error::Bus)`: If there is an error at the bus level during the read or write operation.
1711    pub async fn fifo_watermark_set(&mut self, val: u8) -> Result<(), Error<B::Error>> {
1712        let mut reg = FifoCtrl::read(self).await?;
1713        reg.set_fth(val);
1714        reg.write(self).await
1715    }
1716
1717    /// Get the FIFO watermark level.
1718    ///
1719    /// This function retrieves the current FIFO watermark level from the `fth` field in the `FIFO_CTRL` register.
1720    ///
1721    /// ### Returns
1722    /// - `Ok(u8)`: The current FIFO watermark level.
1723    /// - `Err(Error::Bus)`: If there is an error at the bus level during the read operation.
1724    pub async fn fifo_watermark_get(&mut self) -> Result<u8, Error<B::Error>> {
1725        Ok(FifoCtrl::read(self).await?.fth())
1726    }
1727
1728    /// Set the FIFO mode.
1729    ///
1730    /// This function configures the FIFO operating mode by updating the `fmode` field in the `FIFO_CTRL` register.
1731    /// The FIFO mode determines how data is managed in the FIFO buffer.
1732    ///
1733    /// ### Arguments
1734    /// - `val`: A [`Fmode`] value representing the desired FIFO mode:
1735    ///   - `BypassMode`: FIFO is disabled (default).
1736    ///   - `FifoMode`: FIFO stops collecting data when full.
1737    ///   - `StreamToFifoMode`: Stream mode until a trigger event, then FIFO mode.
1738    ///   - `BypassToStreamMode`: Bypass mode until a trigger event, then stream mode.
1739    ///   - `StreamMode`: Continuously updates FIFO, overwriting old data when full.
1740    ///
1741    /// ### Returns
1742    /// - `Ok(())`: If the operation is successful.
1743    /// - `Err(Error::Bus)`: If there is an error at the bus level during the read or write operation.
1744    pub async fn fifo_mode_set(&mut self, val: Fmode) -> Result<(), Error<B::Error>> {
1745        let mut reg = FifoCtrl::read(self).await?;
1746        reg.set_fmode(val as u8);
1747        reg.write(self).await
1748    }
1749
1750    /// Get the FIFO mode.
1751    ///
1752    /// This function retrieves the current FIFO operating mode from the `fmode` field in the `FIFO_CTRL` register.
1753    ///
1754    /// ### Returns
1755    /// - `Ok(Fmode)`: The current FIFO mode as a [`Fmode`] value.
1756    /// - `Err(Error::Bus)`: If there is an error at the bus level during the read operation.
1757    pub async fn fifo_mode_get(&mut self) -> Result<Fmode, Error<B::Error>> {
1758        Ok(Fmode::try_from(FifoCtrl::read(self).await?.fmode()).unwrap_or_default())
1759    }
1760
1761    /// Get the number of unread samples stored in the FIFO.
1762    ///
1763    /// This function retrieves the number of unread samples currently stored in the FIFO buffer from the `diff` field in the `FIFO_SAMPLES` register.
1764    ///
1765    /// ### Returns
1766    /// - `Ok(u8)`: The number of unread samples in the FIFO.
1767    /// - `Err(Error::Bus)`: If there is an error at the bus level during the read operation.
1768    pub async fn fifo_data_level_get(&mut self) -> Result<u8, Error<B::Error>> {
1769        Ok(FifoSamples::read(self).await?.diff())
1770    }
1771
1772    /// Get the FIFO overrun status.
1773    ///
1774    /// This function retrieves the FIFO overrun status from the `fifo_ovr` field in the `FIFO_SAMPLES` register.
1775    /// The overrun status indicates whether the FIFO buffer has overwritten old data due to being full.
1776    ///
1777    /// ### Returns
1778    /// - `Ok(u8)`: The current FIFO overrun status:
1779    ///   - `0`: No overrun has occurred.
1780    ///   - `1`: FIFO has overwritten old data.
1781    /// - `Err(Error::Bus)`: If there is an error at the bus level during the read operation.
1782    pub async fn fifo_ovr_flag_get(&mut self) -> Result<u8, Error<B::Error>> {
1783        Ok(FifoSamples::read(self).await?.fifo_ovr())
1784    }
1785
1786    /// Get the FIFO threshold status flag.
1787    ///
1788    /// This function retrieves the FIFO threshold status flag from the `fifo_fth` field in the `FIFO_SAMPLES` register.
1789    /// The threshold status indicates whether the number of unread samples in the FIFO has reached the configured watermark level.
1790    ///
1791    /// ### Returns
1792    /// - `Ok(u8)`: The current FIFO threshold status flag:
1793    ///   - `0`: FIFO filling is below the threshold level.
1794    ///   - `1`: FIFO filling has reached or exceeded the threshold level.
1795    /// - `Err(Error::Bus)`: If there is an error at the bus level during the read operation.
1796    pub async fn fifo_wtm_flag_get(&mut self) -> Result<u8, Error<B::Error>> {
1797        Ok(FifoSamples::read(self).await?.fifo_fth())
1798    }
1799}
1800
1801/// Convert from full-scale ±2g to mg.
1802///
1803/// This function converts a raw sensor value in least significant bits (LSB) to mg for a full-scale range of ±2g.
1804///
1805/// ### Arguments
1806/// - `lsb`: The raw value in LSB.
1807///
1808/// ### Returns
1809/// - `f32`: The converted value in mg.
1810#[bisync]
1811pub fn from_fs2_to_mg(lsb: i16) -> f32 {
1812    (lsb as f32) * 0.244
1813}
1814
1815/// Convert from full-scale ±4g to mg.
1816///
1817/// This function converts a raw sensor value in least significant bits (LSB) to mg for a full-scale range of ±4g.
1818///
1819/// ### Arguments
1820/// - `lsb`: The raw value in LSB.
1821///
1822/// ### Returns
1823/// - `f32`: The converted value in mg.
1824#[bisync]
1825pub fn from_fs4_to_mg(lsb: i16) -> f32 {
1826    // (lsb as f32) * 0.122
1827    (lsb as f32) * 0.488
1828}
1829
1830/// Convert from full-scale ±8g to mg.
1831///
1832/// This function converts a raw sensor value in least significant bits (LSB) to mg for a full-scale range of ±8g.
1833///
1834/// ### Arguments
1835/// - `lsb`: The raw value in LSB.
1836///
1837/// ### Returns
1838/// - `f32`: The converted value in mg.
1839#[bisync]
1840pub fn from_fs8_to_mg(lsb: i16) -> f32 {
1841    (lsb as f32) * 0.976
1842}
1843
1844/// Convert from full-scale ±16g to mg.
1845///
1846/// This function converts a raw sensor value in least significant bits (LSB) to mg for a full-scale range of ±16g.
1847///
1848/// ### Arguments
1849/// - `lsb`: The raw value in LSB.
1850///
1851/// ### Returns
1852/// - `f32`: The converted value in mg.
1853#[bisync]
1854pub fn from_fs16_to_mg(lsb: i16) -> f32 {
1855    (lsb as f32) * 1.952
1856}
1857
1858/// Convert from full-scale ±2g (low-power mode 1) to mg.
1859///
1860/// This function converts a raw sensor value in least significant bits (LSB) to mg for a full-scale range of ±2g in low-power mode 1.
1861///
1862/// ### Arguments
1863/// - `lsb`: The raw value in LSB.
1864///
1865/// ### Returns
1866/// - `f32`: The converted value in mg.
1867#[bisync]
1868pub fn from_fs2_lp1_to_mg(lsb: i16) -> f32 {
1869    (lsb as f32) * 0.976
1870}
1871
1872/// Convert from full-scale ±4g (low-power mode 1) to mg.
1873///
1874/// This function converts a raw sensor value in least significant bits (LSB) to mg for a full-scale range of ±4g in low-power mode 1.
1875///
1876/// ### Arguments
1877/// - `lsb`: The raw value in LSB.
1878///
1879/// ### Returns
1880/// - `f32`: The converted value in mg.
1881#[bisync]
1882pub fn from_fs4_lp1_to_mg(lsb: i16) -> f32 {
1883    (lsb as f32) * 1.952
1884}
1885
1886/// Convert from full-scale ±8g (low-power mode 1) to mg.
1887///
1888/// This function converts a raw sensor value in least significant bits (LSB) to mg for a full-scale range of ±8g in low-power mode 1.
1889///
1890/// ### Arguments
1891/// - `lsb`: The raw value in LSB.
1892///
1893/// ### Returns
1894/// - `f32`: The converted value in mg.
1895#[bisync]
1896pub fn from_fs8_lp1_to_mg(lsb: i16) -> f32 {
1897    (lsb as f32) * 3.904
1898}
1899
1900/// Convert from full-scale ±16g (low-power mode 1) to mg.
1901///
1902/// This function converts a raw sensor value in least significant bits (LSB) to mg for a full-scale range of ±16g in low-power mode 1.
1903///
1904/// ### Arguments
1905/// - `lsb`: The raw value in LSB.
1906///
1907/// ### Returns
1908/// - `f32`: The converted value in mg.
1909#[bisync]
1910pub fn from_fs16_lp1_to_mg(lsb: i16) -> f32 {
1911    (lsb as f32) * 7.808
1912}
1913
1914/// Convert from LSB to Celsius.
1915///
1916/// This function converts a raw temperature value in least significant bits (LSB) to degrees Celsius (°C).
1917///
1918/// ### Arguments
1919/// - `lsb`: The raw temperature value in LSB.
1920///
1921/// ### Returns
1922/// - `f32`: The temperature in degrees Celsius.
1923#[bisync]
1924pub fn from_lsb_to_celsius(lsb: i16) -> f32 {
1925    (lsb as f32 / 16.0) + 25.0
1926}
1927
1928/// I²C Address Map.
1929///
1930/// This enum represents the possible I²C addresses for the IIS2DLPC sensor, depending on the configuration of the SA0 pin.
1931#[repr(u8)]
1932#[derive(Clone, Copy, PartialEq)]
1933#[bisync]
1934pub enum I2CAddress {
1935    /// I²C address when SA0 is connected to GND.
1936    I2cAddL = 0x18,
1937
1938    /// I²C address when SA0 is connected to VDD.
1939    I2cAddH = 0x19,
1940}
1941
1942/// Device ID for the IIS2DLPC sensor.
1943///
1944/// The `WhoAmI` register contains this value to identify the device.
1945#[bisync]
1946pub const ID: u8 = 0x44;
1947
1948#[bisync]
1949pub const PROPERTY_ENABLE: u8 = 1;
1950#[bisync]
1951pub const PROPERTY_DISABLE: u8 = 0;