Skip to main content

ilps22qs_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 Ilps22qs generic driver struct.
10#[bisync]
11pub struct Ilps22qs<B, T, S>
12where
13    B: BusOperation,
14    T: DelayNs,
15    S: SensorState,
16{
17    /// The bus driver.
18    pub bus: B,
19    /// The timing peripheral.
20    pub tim: T,
21    _state: PhantomData<S>,
22}
23
24///
25/// Driver errors.
26///
27#[derive(Debug)]
28#[bisync]
29pub enum Error<B> {
30    /// An error occurred at the bus level. Any methods that access the I2C/SPI bus to interact with the sensor may return this error if the bus operation fails.
31    ///
32    /// The generic type B represents the specific error generated by the HAL of the microcontroller in use.
33    Bus(B),
34    /// An error occured during boot procedure
35    Boot,
36    /// An error occured during software reset procedure
37    SwReset,
38    /// The error return when the fifo sample size is grater than the buffer size
39    FifoSampGraterThanBuff,
40}
41
42#[bisync]
43impl<P, T> Ilps22qs<i2c::I2cBus<P>, T, OnState>
44where
45    P: I2c,
46    T: DelayNs,
47{
48    /// Constructor method for using the I2C bus.
49    ///
50    /// # Arguments
51    ///
52    /// * `i2c`: The I2C peripheral.
53    /// * `address`: The I2C address of the COMPONENT sensor.
54    /// * `tim`: The timer of the COMPONENT sensor.
55    ///
56    /// # Returns
57    ///
58    /// * `Self`: Returns an instance of `Ilps22qs`.
59    pub fn new_i2c(i2c: P, address: I2CAddress, tim: T) -> Self {
60        // Initialize the I2C bus with the COMPONENT address
61        let bus = i2c::I2cBus::new(i2c, address as SevenBitAddress);
62        Self {
63            bus,
64            tim,
65            _state: PhantomData,
66        }
67    }
68}
69
70#[bisync]
71impl<B, T, S> Ilps22qs<B, T, S>
72where
73    B: BusOperation,
74    T: DelayNs,
75    S: SensorState,
76{
77    /// Create a safe fake buffer to use the sensor as master of the
78    /// sensor hub.
79    ///
80    /// # Arguments
81    ///
82    /// * `bus`: The bus that implements BusOperation.
83    /// * `tim`: The timer of the COMPONENT sensor.
84    /// * `slave_address`: The I2C address of the slave sensor
85    ///
86    /// # Returns
87    ///
88    /// * `Self`: Returns an instance of `Ilps22qs`.
89    pub fn from_bus(bus: B, tim: T) -> Self {
90        Self {
91            bus,
92            tim,
93            _state: PhantomData,
94        }
95    }
96}
97
98#[bisync]
99impl<P, T> Ilps22qs<spi::SpiBus<P>, T, OnState>
100where
101    P: SpiDevice,
102    T: DelayNs,
103{
104    /// Constructor method for using the SPI bus.
105    ///
106    /// # Arguments
107    ///
108    /// * `spi`: The SPI peripheral.
109    /// * `tim`: The timer of the COMPONENT sensor.
110    ///
111    /// # Returns
112    ///
113    /// * `Self`: Returns an instance of `Ilps22qs`.
114    pub fn new_spi(spi: P, tim: T) -> Self {
115        // Initialize the SPI bus
116        let bus = spi::SpiBus::new(spi);
117        Self {
118            bus,
119            tim,
120            _state: PhantomData,
121        }
122    }
123}
124
125#[bisync]
126impl<B: BusOperation, T: DelayNs, S: SensorState> SensorOperation for Ilps22qs<B, T, S> {
127    type Error = Error<B::Error>;
128
129    #[inline]
130    async fn read_from_register(&mut self, reg: u8, buf: &mut [u8]) -> Result<(), Error<B::Error>> {
131        self.bus
132            .read_from_register(reg, buf)
133            .await
134            .map_err(Error::Bus)
135    }
136
137    #[inline]
138    async fn write_to_register(&mut self, reg: u8, buf: &[u8]) -> Result<(), Error<B::Error>> {
139        self.bus
140            .write_to_register(reg, buf)
141            .await
142            .map_err(Error::Bus)
143    }
144}
145
146#[bisync]
147impl<B: BusOperation, T: DelayNs> Ilps22qs<B, T, OnState> {
148    /// Retrieves the "Who am I" ID value of the device.
149    ///
150    /// This function reads the device's identification register to obtain the "Who am I" ID value,
151    /// which uniquely identifies the device model. The ID value is useful for verifying the presence
152    /// and type of the device in a system.
153    ///
154    /// # Returns
155    ///
156    /// * `Result<Id, Error<B::Error>>`
157    ///     * `Id`: Contains the `whoami` field representing the ID value of the device.
158    ///     * `Err`: Returns an `Error::Bus(B)` if the operation fails due to a bus communication error.
159    ///
160    /// # Errors
161    ///
162    /// * `Error::Bus(B)`: Indicates a failure in the bus communication, which can occur if the device
163    ///   is not connected properly or if there is an issue with the communication interface.
164    ///
165    pub async fn id_get(&mut self) -> Result<WhoAmI, Error<B::Error>> {
166        WhoAmI::read(self).await
167    }
168
169    /// Configures the bus operating mode for the device.
170    ///
171    /// This function sets the communication interface mode and filter settings for the device. It
172    /// supports configuration of I2C, I3C, and SPI interfaces, allowing the user to tailor the
173    /// communication settings to their specific application requirements.
174    ///
175    /// # Parameters
176    ///
177    /// * `val`: An instance of `BusMode` that specifies the desired bus interface and filter
178    ///   settings.
179    ///
180    /// # Returns
181    ///
182    /// * `Result<(), Error<B::Error>>`
183    ///     * `Ok(())`: Indicates successful configuration of the bus operating mode.
184    ///     * `Err`: Returns an `Error::Bus(B)` if the operation fails due to a bus communication error.
185    ///
186    /// # Errors
187    ///
188    /// * `Error::Bus(B)`: Indicates a failure in the bus communication, which can occur if the device
189    ///   is not connected properly or if there is an issue with the communication interface.
190    ///
191    pub async fn bus_mode_set(&mut self, val: BusMode) -> Result<(), Error<B::Error>> {
192        let mut if_ctrl = IfCtrl::read(self).await?;
193
194        if_ctrl.set_i2c_i3c_dis(((val.interface as u8) & 0x02) >> 1);
195        if_ctrl.set_en_spi_read((val.interface as u8) & 0x01);
196        if_ctrl.write(self).await?;
197
198        let mut i3c_if_ctrl = I3cIfCtrl::read(self).await?;
199        i3c_if_ctrl.set_asf_on((val.filter as u8) & 0x01);
200        i3c_if_ctrl.write(self).await
201    }
202
203    /// Retrieves the current bus operating mode of the device.
204    ///
205    /// This function reads the device's configuration registers to determine the current settings
206    /// for the communication interface and filter mode. It provides insight into how the device
207    /// is currently configured to communicate with the host system.
208    ///
209    /// # Returns
210    ///
211    /// * `Result<BusMode, Error<B::Error>>`
212    ///     * `BusMode`: Contains the current bus interface and filter settings.
213    ///     * `Err`: Returns an `Error::Bus(B)` if the operation fails due to a bus communication error.
214    ///
215    /// # Errors
216    ///
217    /// * `Error::Bus(B)`: Indicates a failure in the bus communication, which can occur if the device
218    ///   is not connected properly or if there is an issue with the communication interface.
219    pub async fn bus_mode_get(&mut self) -> Result<BusMode, Error<B::Error>> {
220        let if_ctrl = IfCtrl::read(self).await?;
221        let i3c_if_ctrl = I3cIfCtrl::read(self).await?;
222
223        let interface = Interface::try_from(if_ctrl.i2c_i3c_dis() << 1).unwrap_or_default();
224        let filter = Filter::try_from(i3c_if_ctrl.asf_on()).unwrap_or_default();
225
226        Ok(BusMode { interface, filter })
227    }
228
229    /// Initializes the device with the specified settings.
230    ///
231    /// This function performs various initialization procedures on the device, including booting,
232    /// software resetting, and setting the device to be ready for operation. The initialization
233    /// settings are specified by the `Init` parameter, which determines the type of
234    /// initialization to perform.
235    ///
236    /// # Parameters
237    ///
238    /// * `val`: An instance of `Init` that specifies the desired initialization procedure.
239    ///   The options include booting the device, performing a software reset, or preparing the
240    ///   device for operation.
241    ///
242    /// # Returns
243    ///
244    /// * `Result<(), Error<B::Error>>`
245    ///     * `Ok(())`: Indicates successful initialization.
246    ///     * `Err`: Returns an error if the operation fails, with specific error types:
247    ///       - `Error::Bus(B)`: Indicates a failure in the bus communication.
248    ///       - `Error::Boot`: Indicates a failure in the boot procedure.
249    ///       - `Error::SwReset`: Indicates a failure in the software reset procedure.
250    ///
251    /// # Errors
252    ///
253    /// * `Error::Bus(B)`: Occurs if there is a communication issue with the device.
254    /// * `Error::Boot`: Occurs if the boot procedure does not complete successfully within the expected time.
255    /// * `Error::SwReset`: Occurs if the software reset procedure does not complete successfully within the expected time.
256    pub async fn init_set(&mut self, val: Init) -> Result<(), Error<B::Error>> {
257        let mut ctrl_reg2 = CtrlReg2::read(self).await?;
258        let mut ctrl_reg3 = CtrlReg3::read(self).await?;
259
260        match val {
261            Init::Boot => {
262                ctrl_reg2.set_boot(PROPERTY_ENABLE);
263                ctrl_reg2.write(self).await?;
264
265                let mut cnt: u8 = 0;
266                while cnt < 5 {
267                    let int_src = IntSource::read(self).await?;
268
269                    if int_src.boot_on() == PROPERTY_DISABLE {
270                        break;
271                    }
272
273                    self.tim.delay_ms(10).await; // 10ms of boot time
274                    cnt += 1;
275                }
276
277                if cnt >= 5 {
278                    return Err(Error::Boot);
279                }
280            }
281            Init::Reset => {
282                ctrl_reg2.set_swreset(PROPERTY_ENABLE);
283                ctrl_reg2.write(self).await?;
284
285                let mut cnt: u8 = 0;
286                while cnt < 5 {
287                    let status = self.status_get().await?;
288
289                    if status.sw_reset == PROPERTY_DISABLE {
290                        break;
291                    }
292
293                    self.tim.delay_us(50).await;
294                    cnt += 1;
295                }
296
297                if cnt >= 5 {
298                    return Err(Error::SwReset);
299                }
300            }
301            Init::DrvRdy => {
302                ctrl_reg2.set_bdu(PROPERTY_ENABLE);
303                ctrl_reg3.set_if_add_inc(PROPERTY_ENABLE);
304
305                ctrl_reg2.write(self).await?;
306                ctrl_reg3.write(self).await?;
307            }
308        }
309
310        Ok(())
311    }
312
313    /// Retrieves the current status of the device.
314    ///
315    /// This function reads multiple registers to gather comprehensive status information about the device,
316    /// including reset status, boot status, data readiness, and measurement completion. The status is
317    /// returned as an `Stat` struct, which provides detailed insights into the device's current
318    /// operational state.
319    ///
320    /// # Returns
321    ///
322    /// * `Result<Stat, Error<B::Error>>`
323    ///     * `Stat`: Contains various status indicators such as software reset, boot status,
324    ///       data readiness for pressure and temperature, and measurement completion.
325    ///     * `Err`: Returns an `Error::Bus(B)` if the operation fails due to a bus communication error.
326    ///
327    /// # Errors
328    ///
329    /// * `Error::Bus(B)`: Occurs if there is a communication issue with the device, which can prevent
330    ///   successful reading of the status registers.
331    pub async fn status_get(&mut self) -> Result<Stat, Error<B::Error>> {
332        let ctrl_reg2 = CtrlReg2::read(self).await?;
333        let int_source = IntSource::read(self).await?;
334        let status = Status::read(self).await?;
335
336        let interrupt_cfg = InterruptCfg::read(self).await?;
337
338        Ok(Stat {
339            sw_reset: ctrl_reg2.swreset(),
340            boot: int_source.boot_on(),
341            drdy_pres: status.p_da(),
342            drdy_temp: status.t_da(),
343            ovr_pres: status.p_or(),
344            ovr_temp: status.t_or(),
345            end_meas: !ctrl_reg2.oneshot(),
346            ref_done: !interrupt_cfg.autozero(),
347        })
348    }
349
350    /// Configures the electrical settings for the device's configurable pins.
351    ///
352    /// This function allows the user to set specific electrical configurations for the device's pins,
353    /// such as enabling or disabling pull-up resistors.
354    ///
355    /// # Parameters
356    ///
357    /// * `val`: A reference to `PinConf`, which contains the desired electrical settings for
358    ///   the configurable pins. This includes options for enabling or disabling pull-up resistors on
359    ///   specific pins such as SDA and CS.
360    ///
361    /// # Returns
362    ///
363    /// * `Result<(), Error<B::Error>>`
364    ///     * `Ok(())`: Indicates successful configuration of the electrical pin settings.
365    ///     * `Err`: Returns an `Error::Bus(B)` if the operation fails due to a bus communication error.
366    ///
367    /// # Errors
368    ///
369    /// * `Error::Bus(B)`: Occurs if there is a communication issue with the device, which can prevent
370    ///   successful writing of the pin configuration settings.
371    pub async fn pin_conf_set(&mut self, val: &PinConf) -> Result<(), Error<B::Error>> {
372        let mut if_ctrl = IfCtrl::read(self).await?;
373        if_ctrl.set_sda_pu_en(val.sda_pull_up);
374        if_ctrl.set_cs_pu_dis(!val.cs_pull_up);
375        if_ctrl.write(self).await
376    }
377
378    /// Retrieves the current electrical configuration of the device's configurable pins.
379    ///
380    /// This function reads the device's configuration registers to determine the current electrical
381    /// settings for the pins, such as the status of pull-up resistors.
382    ///
383    /// # Returns
384    ///
385    /// * `Result<PinConf, Error<B::Error>>`
386    ///     * `PinConf`: Contains the current electrical settings for the configurable pins,
387    ///       including the status of pull-up resistors on pins such as SDA and CS.
388    ///     * `Err`: Returns an `Error::Bus(B)` if the operation fails due to a bus communication error.
389    ///
390    /// # Errors
391    ///
392    /// * `Error::Bus(B)`: Occurs if there is a communication issue with the device, which can prevent
393    ///   successful reading of the pin configuration settings.
394    pub async fn pin_conf_get(&mut self) -> Result<PinConf, Error<B::Error>> {
395        let if_ctrl = IfCtrl::read(self).await?;
396
397        let sda_pull_up = if_ctrl.sda_pu_en();
398        let cs_pull_up = !if_ctrl.cs_pu_dis();
399
400        Ok(PinConf {
401            sda_pull_up,
402            cs_pull_up,
403        })
404    }
405
406    /// Retrieves the status of all interrupt sources for the device.
407    ///
408    /// This function reads multiple registers to gather comprehensive information about the status of
409    /// all interrupt sources, including data readiness, pressure thresholds, and FIFO conditions. The
410    /// status is returned as an `AllSources` struct, which provides detailed insights into the
411    /// device's current interrupt conditions.
412    ///
413    /// # Returns
414    ///
415    /// * `Result<AllSources, Error<B::Error>>`
416    ///     * `AllSources`: Contains various status indicators for all interrupt sources, such as
417    ///       data readiness for pressure and temperature, pressure thresholds, and FIFO conditions.
418    ///     * `Err`: Returns an `Error::Bus(B)` if the operation fails due to a bus communication error.
419    ///
420    /// # Errors
421    ///
422    /// * `Error::Bus(B)`: Occurs if there is a communication issue with the device, which can prevent
423    ///   successful reading of the interrupt source status.
424    pub async fn all_sources_get(&mut self) -> Result<AllSources, Error<B::Error>> {
425        let status = Status::read(self).await?;
426        let int_source = IntSource::read(self).await?;
427        let fifo_status2 = FifoStatus2::read(self).await?;
428
429        Ok(AllSources {
430            drdy_pres: status.p_da(),
431            drdy_temp: status.t_da(),
432            over_pres: int_source.ph(),
433            under_pres: int_source.pl(),
434            thrsld_pres: int_source.ia(),
435            fifo_full: fifo_status2.fifo_full_ia(),
436            fifo_ovr: fifo_status2.fifo_ovr_ia(),
437            fifo_th: fifo_status2.fifo_wtm_ia(),
438        })
439    }
440
441    /// Configures the sensor conversion parameters.
442    ///
443    /// This function sets various sensor conversion parameters, including output data rate (ODR),
444    /// averaging, low-pass filter settings, and full-scale mode. It also handles interleaved mode
445    /// settings for both regular operation and FIFO configuration, allowing for flexible sensor
446    /// data processing tailored to specific application needs.
447    ///
448    /// # Parameters
449    ///
450    /// * `val`: A reference to `Md`, which contains the desired sensor conversion parameters.
451    ///   This includes settings for ODR, averaging, low-pass filter, full-scale mode, and interleaved
452    ///   mode configuration.
453    ///
454    /// # Returns
455    ///
456    /// * `Result<(), Error<B::Error>>`
457    ///     * `Ok(())`: Indicates successful configuration of the sensor conversion parameters.
458    ///     * `Err`: Returns an `Error::Bus(B)` if the operation fails due to a bus communication error.
459    ///
460    /// # Errors
461    ///
462    /// * `Error::Bus(B)`: Occurs if there is a communication issue with the device, which can prevent
463    ///   successful writing of the sensor conversion settings.
464    pub async fn mode_set(&mut self, val: &Md) -> Result<(), Error<B::Error>> {
465        let mut ctrl_reg1 = CtrlReg1::read(self).await?;
466        let mut ctrl_reg2 = CtrlReg2::read(self).await?;
467        let mut ctrl_reg3 = CtrlReg3::read(self).await?;
468
469        let mut odr_save = PROPERTY_DISABLE;
470        let mut ah_qvar_en_save = PROPERTY_DISABLE;
471
472        // Handle interleaved mode setting
473        if ctrl_reg1.odr() != PROPERTY_DISABLE {
474            // Power down
475            odr_save = ctrl_reg1.odr();
476            ctrl_reg1.set_odr(PROPERTY_DISABLE);
477            ctrl_reg1.write(self).await?;
478        }
479
480        if ctrl_reg3.ah_qvar_en() != PROPERTY_DISABLE {
481            // Disable QVAR
482            ah_qvar_en_save = ctrl_reg3.ah_qvar_en();
483            ctrl_reg3.set_ah_qvar_en(PROPERTY_DISABLE);
484            ctrl_reg3.write(self).await?;
485        }
486
487        // Set interleaved mode (0 or 1)
488        ctrl_reg3.set_ah_qvar_p_auto_en(val.interleaved_mode);
489        ctrl_reg3.write(self).await?;
490
491        // Set FIFO interleaved mode (0 or 1)
492        let mut fifo_ctrl = FifoCtrl::read(self).await?;
493        fifo_ctrl.set_ah_qvar_p_fifo_en(val.interleaved_mode);
494        fifo_ctrl.write(self).await?;
495
496        if ah_qvar_en_save != PROPERTY_DISABLE {
497            // Restore ah_qvar_en back to previous setting
498            ctrl_reg3.set_ah_qvar_en(ah_qvar_en_save);
499        }
500
501        if odr_save != PROPERTY_DISABLE {
502            // Restore odr back to previous setting
503            ctrl_reg1.set_odr(odr_save);
504        }
505
506        ctrl_reg1.set_odr(val.odr as u8);
507        ctrl_reg1.set_avg(val.avg as u8);
508        ctrl_reg2.set_en_lpfp(val.lpf as u8 & 0x01);
509        ctrl_reg2.set_lfpf_cfg((val.lpf as u8 & 0x02) >> 2);
510        ctrl_reg2.set_fs_mode(val.fs as u8);
511
512        ctrl_reg1.write(self).await?;
513        ctrl_reg2.write(self).await?;
514        ctrl_reg3.write(self).await
515    }
516
517    /// Retrieves the current sensor conversion parameters.
518    ///
519    /// This function reads the device's configuration registers to determine the current settings for
520    /// sensor conversion parameters, including output data rate (ODR), averaging, low-pass filter settings,
521    /// full-scale mode, and interleaved mode. It provides insight into how the device is currently configured
522    /// for data processing and acquisition.
523    ///
524    /// # Returns
525    ///
526    /// * `Result<Md, Error<B::Error>>`
527    ///     * `Md`: Contains the current sensor conversion parameters, such as ODR, averaging,
528    ///       low-pass filter settings, full-scale mode, and interleaved mode configuration.
529    ///     * `Err`: Returns an `Error::Bus(B)` if the operation fails due to a bus communication error.
530    ///
531    /// # Errors
532    ///
533    /// * `Error::Bus(B)`: Occurs if there is a communication issue with the device, which can prevent
534    ///   successful reading of the sensor conversion settings.
535    pub async fn mode_get(&mut self) -> Result<Md, Error<B::Error>> {
536        let ctrl_reg1 = CtrlReg1::read(self).await?;
537        let ctrl_reg2 = CtrlReg2::read(self).await?;
538        let ctrl_reg3 = CtrlReg3::read(self).await?;
539
540        let fs = Fs::try_from(ctrl_reg2.fs_mode()).unwrap_or_default();
541        let odr = Odr::try_from(ctrl_reg1.odr()).unwrap_or_default();
542        let avg = Avg::try_from(ctrl_reg1.avg()).unwrap_or_default();
543        let lpf =
544            Lpf::try_from((ctrl_reg2.lfpf_cfg() << 2) | ctrl_reg2.en_lpfp()).unwrap_or_default();
545
546        Ok(Md {
547            interleaved_mode: ctrl_reg3.ah_qvar_p_auto_en(),
548            fs,
549            odr,
550            avg,
551            lpf,
552        })
553    }
554
555    /// Initiates a software trigger for a One-Shot sensor conversion.
556    ///
557    /// This function enables a One-Shot conversion mode, allowing the device to perform a single
558    /// measurement based on the provided sensor conversion parameters. The One-Shot mode is useful
559    /// for applications that require precise, on-demand measurements rather than continuous data
560    /// acquisition.
561    ///
562    /// # Parameters
563    ///
564    /// * `md`: A reference to `Md`, which contains the sensor conversion parameters. The function
565    ///   checks if the `odr` (output data rate) is set to `OneShot` before triggering the conversion.
566    ///
567    /// # Returns
568    ///
569    /// * `Result<(), Error<B::Error>>`
570    ///     * `Ok`: Indicates successful initiation of the One-Shot trigger.
571    ///     * `Err`: Returns an `Error::Bus(B)` if the operation fails due to a bus communication error.
572    ///
573    /// # Errors
574    ///
575    /// * `Error::Bus(B)`: Occurs if there is a communication issue with the device, which can prevent
576    ///   successful writing of the One-Shot trigger command.
577    pub async fn trigger_sw(&mut self, md: &Md) -> Result<(), Error<B::Error>> {
578        if md.odr == Odr::OneShot {
579            let mut ctrl_reg2 = CtrlReg2::read(self).await?;
580            ctrl_reg2.set_oneshot(PROPERTY_ENABLE);
581            ctrl_reg2.write(self).await?;
582        }
583        Ok(())
584    }
585
586    ///
587    /// This function modifies the AH/QVAR enable setting in the control register, allowing the user
588    /// to activate or deactivate the AH/QVAR functionality.
589    ///
590    /// # Parameters
591    ///
592    /// * `val`: A `u8` value that specifies whether to enable or disable the AH/QVAR function. The value
593    ///   is written to the `ah_qvar_en` field in the `CTRL_REG3` register.
594    ///
595    /// # Returns
596    ///
597    /// * `Result<(), Error<B::Error>>`
598    ///     * `Ok`: Indicates successful configuration of the AH/QVAR function.
599    ///     * `Err`: Returns an `Error::Bus(B)` if the operation fails due to a bus communication error.
600    ///
601    /// # Errors
602    ///
603    /// * `Error::Bus(B)`: Occurs if there is a communication issue with the device, which can prevent
604    ///   successful writing of the AH/QVAR enable setting.
605    pub async fn ah_qvar_en_set(&mut self, val: u8) -> Result<(), Error<B::Error>> {
606        let mut ctrl_reg3 = CtrlReg3::read(self).await?;
607        ctrl_reg3.set_ah_qvar_en(val);
608        ctrl_reg3.write(self).await
609    }
610
611    /// Retrieves the current status of the AH/QVAR function enable setting.
612    ///
613    /// This function reads the control register to determine whether the AH/QVAR function is currently
614    /// enabled or disabled.
615    ///
616    /// # Returns
617    ///
618    /// * `Result<u8, Error<B::Error>>`
619    ///     * `u8`: The current value of the `ah_qvar_en` field in the `CTRL_REG3` register, indicating
620    ///       whether the AH/QVAR function is enabled or disabled.
621    ///     * `Err`: Returns an `Error::Bus(B)` if the operation fails due to a bus communication error.
622    ///
623    /// # Errors
624    ///
625    /// * `Error::Bus(B)`: Occurs if there is a communication issue with the device, which can prevent
626    ///   successful reading of the AH/QVAR enable status.
627    pub async fn ah_qvar_en_get(&mut self) -> Result<u8, Error<B::Error>> {
628        Ok(CtrlReg3::read(self).await?.ah_qvar_en())
629    }
630
631    /// Retrieves sensor data, including pressure and temperature measurements.
632    ///
633    /// This function reads raw data from the sensor registers and processes it according to the specified
634    /// sensor conversion parameters. It supports both pressure and AH/QVAR data retrieval, depending on
635    /// the configuration, and converts the raw data into meaningful units such as hectopascals (hPa) and
636    /// degrees Celsius (°C).
637    ///
638    /// # Parameters
639    ///
640    /// * `md`: A reference to `Md`, which contains the sensor conversion parameters. These parameters
641    ///   include settings for full-scale mode, interleaved mode, and other conversion options that affect
642    ///   how the raw data is processed.
643    ///
644    /// # Returns
645    ///
646    /// * `Result<Data, Error<B::Error>>`
647    ///     * `Data`: Contains the processed sensor data, including pressure and temperature values.
648    ///     * `Err`: Returns an `Error::Bus(B)` if the operation fails due to a bus communication error.
649    ///
650    /// # Errors
651    ///
652    /// * `Error::Bus(B)`: Occurs if there is a communication issue with the device, which can prevent
653    ///   successful reading of the sensor data.
654    pub async fn data_get(&mut self, md: &Md) -> Result<Data, Error<B::Error>> {
655        let mut data = Data::default();
656        data.pressure.raw = self.pressure_raw_get().await?;
657
658        if md.interleaved_mode == PROPERTY_ENABLE {
659            if (data.pressure.raw & 0x1) == 0 {
660                // Data is a pressure sample
661                data.pressure.hpa = match md.fs {
662                    Fs::_1260hpa => from_fs1260_to_hpa(data.pressure.raw),
663                    Fs::_4060hpa => from_fs4000_to_hpa(data.pressure.raw),
664                };
665                data.ah_qvar.lsb = 0;
666            } else {
667                // Data is a AH_QVAR sample
668                data.ah_qvar.lsb = data.pressure.raw >> 8;
669                data.pressure.hpa = 0.;
670            }
671        } else {
672            data.pressure.hpa = match md.fs {
673                Fs::_1260hpa => from_fs1260_to_hpa(data.pressure.raw),
674                Fs::_4060hpa => from_fs4000_to_hpa(data.pressure.raw),
675            };
676            data.ah_qvar.lsb = 0;
677        }
678
679        // Temperature conversion
680        data.heat.raw = self.temperature_raw_get().await?;
681        data.heat.deg_c = from_lsb_to_celsius(data.heat.raw);
682
683        Ok(data)
684    }
685
686    ///
687    /// This function reads the pressure data registers to obtain the raw pressure measurement value. The
688    /// raw value is typically used for further processing or conversion into meaningful units such as
689    /// hectopascals (hPa). It provides the unprocessed data directly from the sensor, which can be useful
690    /// for custom data handling or debugging purposes.
691    ///
692    /// # Returns
693    ///
694    /// * `Result<u32, Error<B::Error>>`
695    ///     * `u32`: The raw pressure output value, represented as a 32-bit unsigned integer.
696    ///     * `Err`: Returns an `Error::Bus(B)` if the operation fails due to a bus communication error.
697    ///
698    /// # Errors
699    ///
700    /// * `Error::Bus(B)`: Occurs if there is a communication issue with the device, which can prevent
701    ///   successful reading of the pressure data registers.
702    pub async fn pressure_raw_get(&mut self) -> Result<i32, Error<B::Error>> {
703        Ok(PressOut::read(self).await?.pout())
704    }
705
706    ///
707    /// This function reads the temperature data registers to obtain the raw temperature measurement value.
708    /// The raw value is typically used for further processing or conversion into meaningful units such as
709    /// degrees Celsius (°C). It provides the unprocessed data directly from the sensor, which can be useful
710    /// for custom data handling or debugging purposes.
711    ///
712    /// # Returns
713    ///
714    /// * `Result<i16, Error<B::Error>>`
715    ///     * `i16`: The raw temperature output value, represented as a 16-bit signed integer.
716    ///     * `Err`: Returns an `Error::Bus(B)` if the operation fails due to a bus communication error.
717    ///
718    /// # Errors
719    ///
720    /// * `Error::Bus(B)`: Occurs if there is a communication issue with the device, which can prevent
721    ///   successful reading of the temperature data registers.
722    pub async fn temperature_raw_get(&mut self) -> Result<i16, Error<B::Error>> {
723        Ok(TempOut::read(self).await?.tout())
724    }
725
726    /// Retrieves AH/QVAR data from the sensor.
727    ///
728    /// This function reads the sensor registers to obtain AH/QVAR data, which is used for advanced
729    /// sensing applications. The data is processed to provide both the raw and converted values,
730    /// allowing for detailed analysis and application-specific processing.
731    ///
732    /// # Returns
733    ///
734    /// * `Result<AhQvarData, Error<B::Error>>`
735    ///     * `AhQvarData`: Contains the AH/QVAR data retrieved from the sensor, including the
736    ///       raw value, least significant byte (LSB), and the converted value in millivolts (mV).
737    ///     * `Err`: Returns an `Error::Bus(B)` if the operation fails due to a bus communication error.
738    ///
739    /// # Errors
740    ///
741    /// * `Error::Bus(B)`: Occurs if there is a communication issue with the device, which can prevent
742    ///   successful reading of the AH/QVAR data registers.
743    pub async fn ah_qvar_data_get(&mut self) -> Result<AhQvarData, Error<B::Error>> {
744        let raw = self.pressure_raw_get().await?;
745        let lsb = raw >> 8;
746        let mv = from_lsb_to_mv(lsb);
747
748        Ok(AhQvarData { mv, lsb, raw })
749    }
750
751    /// Configures the FIFO operation mode for the device.
752    ///
753    /// This function sets the FIFO (First-In, First-Out) operation mode, allowing the user to define
754    /// how data is buffered and managed within the device. It supports various modes and configurations,
755    /// including trigger modes and watermark levels, to optimize data handling for specific application
756    /// requirements.
757    ///
758    /// # Parameters
759    ///
760    /// * `val`: A reference to `FifoMd`, which contains the desired FIFO operation mode settings.
761    ///   This includes the operation mode, trigger modes, and watermark level for the FIFO buffer.
762    ///
763    /// # Returns
764    ///
765    /// * `Result<(), Error<B::Error>>`
766    ///     * `Ok`: Indicates successful configuration of the FIFO operation mode.
767    ///     * `Err`: Returns an `Error::Bus(B)` if the operation fails due to a bus communication error.
768    ///
769    /// # Errors
770    ///
771    /// * `Error::Bus(B)`: Occurs if there is a communication issue with the device, which can prevent
772    ///   successful writing of the FIFO configuration settings.
773    pub async fn fifo_mode_set(&mut self, val: &FifoMd) -> Result<(), Error<B::Error>> {
774        let mut fifo_ctrl = FifoCtrl::read(self).await?;
775        let mut fifo_wtm = FifoWtm::read(self).await?;
776
777        fifo_ctrl.set_f_mode((val.operation as u8) & 0x03);
778        fifo_ctrl.set_trig_modes(((val.operation as u8) & 0x04) >> 2);
779
780        if val.watermark != 0 {
781            fifo_ctrl.set_stop_on_wtm(PROPERTY_ENABLE);
782        } else {
783            fifo_ctrl.set_stop_on_wtm(PROPERTY_DISABLE);
784        }
785
786        fifo_wtm.set_wtm(val.watermark);
787
788        fifo_ctrl.write(self).await?;
789        fifo_wtm.write(self).await
790    }
791
792    /// Retrieves the current FIFO operation mode of the device.
793    ///
794    /// This function reads the FIFO control registers to determine the current configuration of the FIFO
795    /// operation mode. It provides insight into how the device is currently managing its data buffering,
796    /// including the operation mode and watermark level, which are crucial for understanding data flow
797    /// and storage within the device.
798    ///
799    /// # Returns
800    ///
801    /// * `Result<FifoMd, Error<B::Error>>`
802    ///     * `FifoMd`: Contains the current FIFO operation mode and watermark level.
803    ///     * `Err`: Returns an `Error::Bus(B)` if the operation fails due to a bus communication error.
804    ///
805    /// # Errors
806    ///
807    /// * `Error::Bus(B)`: Occurs if there is a communication issue with the device, which can prevent
808    ///   successful reading of the FIFO configuration settings.
809    pub async fn fifo_mode_get(&mut self) -> Result<FifoMd, Error<B::Error>> {
810        let fifo_ctrl = FifoCtrl::read(self).await?;
811        let fifo_wtm = FifoWtm::read(self).await?;
812
813        let operation = Operation::try_from((fifo_ctrl.trig_modes() << 2) | fifo_ctrl.f_mode())
814            .unwrap_or_default();
815        let watermark = fifo_wtm.wtm();
816
817        Ok(FifoMd {
818            operation,
819            watermark,
820        })
821    }
822
823    /// Retrieves the number of samples currently stored in the FIFO buffer.
824    ///
825    /// This function reads the FIFO status register to determine how many samples are currently buffered
826    /// in the device's FIFO. This information is useful for managing data flow and ensuring that the
827    /// FIFO does not overflow, which can be critical for applications requiring continuous data acquisition.
828    ///
829    /// # Returns
830    ///
831    /// * `Result<u8, Error<B::Error>>`
832    ///     * `u8`: The number of samples currently stored in the FIFO buffer.
833    ///     * `Err`: Returns an `Error::Bus(B)` if the operation fails due to a bus communication error.
834    ///
835    /// # Errors
836    ///
837    /// * `Error::Bus(B)`: Occurs if there is a communication issue with the device, which can prevent
838    ///   successful reading of the FIFO status register.
839    pub async fn fifo_level_get(&mut self) -> Result<u8, Error<B::Error>> {
840        Ok(FifoStatus1::read(self).await?.fss())
841    }
842
843    /// Retrieves data from the FIFO buffer and processes it according to the sensor conversion
844    /// parameters.
845    ///
846    /// This function reads a specified number of samples from the FIFO buffer and processes each sample
847    /// based on the sensor conversion parameters provided. It supports both pressure and AH_QVAR data
848    /// retrieval, depending on the configuration.
849    ///
850    /// # Parameters
851    /// * `samp` - The number of samples to retrieve from the FIFO buffer. This must not exceed the
852    ///   length of the `data` buffer provided.
853    /// * `md`: A reference to `Md`, which contains the sensor conversion parameters,
854    ///   including the full-scale range and interleaved mode settings.
855    /// * `data`: A mutable slice of `FifoData` where the retrieved and processed data will
856    ///   be stored.
857    ///
858    /// # Returns
859    /// * `Result<(), Error<B::Error>>`
860    ///     * `Ok`: Indicates successful data retrieval and processing.
861    ///     * `Err`: Returns an error if the operation fails, such as when the number of samples
862    ///       requested exceeds the buffer size.
863    ///
864    /// # Errors
865    /// * `Error::Bus(B)`: Returned if a bus operation fails.
866    /// * `Error::FifoSampGraterThanBuff`: Returned if the requested number of samples (`samp`) is
867    ///   greater than the length of the `data` buffer.
868    pub async fn fifo_data_get(
869        &mut self,
870        samp: u8,
871        md: &Md,
872        data: &mut [FifoData],
873    ) -> Result<(), Error<B::Error>> {
874        if samp > data.len() as u8 {
875            return Err(Error::FifoSampGraterThanBuff);
876        }
877
878        for value in data.iter_mut().take(samp as usize) {
879            value.raw = FifoDataOutPress::read(self).await?.fifo_p();
880
881            if md.interleaved_mode == PROPERTY_ENABLE {
882                if (value.raw & 0x1) == 0 {
883                    // Data is a pressure sample
884                    value.hpa = match md.fs {
885                        Fs::_1260hpa => from_fs1260_to_hpa(value.raw),
886                        Fs::_4060hpa => from_fs4000_to_hpa(value.raw),
887                    };
888                    value.lsb = 0;
889                } else {
890                    // Data is an AH_QVAR sample
891                    value.lsb = value.raw >> 8;
892                    value.hpa = 0.;
893                }
894            } else {
895                value.hpa = match md.fs {
896                    Fs::_1260hpa => from_fs1260_to_hpa(value.raw),
897                    Fs::_4060hpa => from_fs4000_to_hpa(value.raw),
898                };
899                value.lsb = 0;
900            }
901        }
902        Ok(())
903    }
904
905    /// Configures the hardware signal settings for the interrupt pins.
906    ///
907    /// This function sets the configuration for the device's interrupt pins, allowing the user to define
908    /// how interrupt signals are managed.
909    ///
910    /// # Parameters
911    ///
912    /// * `int_latched`: Contains the desired hardware signal settings for
913    ///   the interrupt pins.
914    ///
915    /// # Returns
916    ///
917    /// * `Result<(), Error<B::Error>>`
918    ///     * `Ok`: Indicates successful configuration of the interrupt pins.
919    ///     * `Err`: Returns an error if the operation fails due to a bus communication error.
920    ///
921    /// # Errors
922    ///
923    /// * `Error::Bus(B)`: Occurs if there is a communication issue with the device, which can prevent
924    ///   successful writing of the interrupt configuration settings.
925    pub async fn interrupt_mode_set(&mut self, int_latched: u8) -> Result<(), Error<B::Error>> {
926        let mut interrupt_cfg = InterruptCfg::read(self).await?;
927        interrupt_cfg.set_lir(int_latched);
928        interrupt_cfg.write(self).await
929    }
930
931    /// Retrieves the current hardware signal configuration for the interrupt pins.
932    ///
933    /// This function reads the device's configuration register to determine the current settings for
934    /// the interrupt pins.
935    ///
936    /// # Returns
937    ///
938    /// * `Result<IntMode, Error<B::Error>>`
939    ///     * `u8`: Contains the current status of latched interrupt signals.
940    ///     * `Err`: Returns an error if the operation fails due to a bus communication error.
941    ///
942    /// # Errors
943    ///
944    /// * `Error::Bus(B)`: Occurs if there is a communication issue with the device, which can prevent
945    ///   successful reading of the interrupt configuration settings.
946    pub async fn interrupt_mode_get(&mut self) -> Result<u8, Error<B::Error>> {
947        Ok(InterruptCfg::read(self).await?.lir())
948    }
949
950    /// Disables the AH/QVAR function on the device.
951    ///
952    /// This function writes to the device's register to disable the AH/QVAR functionality, which is used
953    /// for advanced sensing applications. Disabling this function can be necessary when the AH/QVAR feature
954    /// is not required, allowing for optimized power usage and simplified device operation.
955    ///
956    /// # Returns
957    ///
958    /// * `Result<(), Error<B::Error>>`
959    ///     * `Ok`: Indicates successful disablement of the AH/QVAR function.
960    ///     * `Err`: Returns an error if the operation fails due to a bus communication error.
961    ///
962    /// # Errors
963    ///
964    /// * `Error::Bus(B)`: Occurs if there is a communication issue with the device, which can prevent
965    ///   successful writing of the disable command to the register.
966    pub async fn ah_qvar_disable(&mut self) -> Result<(), Error<B::Error>> {
967        self.write_to_register(Reg::AnalogicHubDisable as u8, &[PROPERTY_DISABLE])
968            .await?;
969        Ok(())
970    }
971
972    /// Configures the device's wake-up and wake-up-to-sleep threshold settings.
973    ///
974    /// This function sets the parameters for the device's interrupt thresholds, which determine when
975    /// the device will trigger wake-up or sleep events based on pressure levels.
976    ///
977    /// # Parameters
978    ///
979    /// * `val`: A reference to `IntThMd`, which contains the configuration parameters for the
980    ///   interrupt thresholds. This includes settings for over-threshold and under-threshold events,
981    ///   as well as the specific threshold value.
982    ///
983    /// # Returns
984    ///
985    /// * `Result<(), Error<B::Error>>`
986    ///     * `Ok`: Indicates successful configuration of the wake-up and wake-up-to-sleep thresholds.
987    ///     * `Err`: Returns an error if the operation fails due to a bus communication error.
988    ///
989    /// # Errors
990    ///
991    /// * `Error::Bus(B)`: Occurs if there is a communication issue with the device, which can prevent
992    ///   successful writing of the threshold configuration settings.
993    pub async fn int_on_threshold_mode_set(
994        &mut self,
995        val: &IntThMd,
996    ) -> Result<(), Error<B::Error>> {
997        let mut interrupt_cfg = InterruptCfg::read(self).await?;
998        let mut ths_p = ThsP::read(self).await?;
999
1000        interrupt_cfg.set_phe(val.over_th);
1001        interrupt_cfg.set_ple(val.under_th);
1002
1003        ths_p.set_ths(val.threshold);
1004
1005        interrupt_cfg.write(self).await?;
1006        ths_p.write(self).await
1007    }
1008
1009    /// Retrieves the current configuration of wake-up and wake-up-to-sleep thresholds.
1010    ///
1011    /// This function reads the device's registers to obtain the current settings for interrupt thresholds,
1012    /// which determine when the device will trigger wake-up or sleep events based on pressure levels.
1013    /// It provides insight into the device's responsiveness to environmental changes and helps verify
1014    /// the current configuration for optimal operation.
1015    ///
1016    /// # Returns
1017    ///
1018    /// * `Result<IntThMd, Error<B::Error>>`
1019    ///     * `IntThMd`: Contains the current configuration parameters for the interrupt thresholds,
1020    ///       including settings for over-threshold and under-threshold events, as well as the specific
1021    ///       threshold value.
1022    ///     * `Err`: Returns an error if the operation fails due to a bus communication error.
1023    ///
1024    /// # Errors
1025    ///
1026    /// * `Error::Bus(B)`: Occurs if there is a communication issue with the device, which can prevent
1027    ///   successful reading of the threshold configuration settings.
1028    pub async fn int_on_threshold_mode_get(&mut self) -> Result<IntThMd, Error<B::Error>> {
1029        let interrupt_cfg = InterruptCfg::read(self).await?;
1030        let ths_p = ThsP::read(self).await?;
1031
1032        let over_th = interrupt_cfg.phe();
1033        let under_th = interrupt_cfg.ple();
1034        let threshold = ths_p.ths();
1035
1036        Ok(IntThMd {
1037            over_th,
1038            under_th,
1039            threshold,
1040        })
1041    }
1042
1043    /// Configures the reference mode settings for wake-up and wake-up-to-sleep functionality.
1044    ///
1045    /// This function sets the reference mode parameters, which are used to manage how the device
1046    /// handles reference pressure levels for triggering wake-up and sleep events.
1047    /// # Parameters
1048    ///
1049    /// * `val`: A reference to `RefMd`, which contains the configuration parameters for the
1050    ///   reference mode. This includes settings for obtaining and applying reference pressure levels,
1051    ///   as well as options for resetting reference configurations.
1052    ///
1053    /// # Returns
1054    ///
1055    /// * `Result<(), Error<B::Error>>`
1056    ///     * `Ok`: Indicates successful configuration of the reference mode settings.
1057    ///     * `Err`: Returns an error if the operation fails due to a bus communication error.
1058    ///
1059    /// # Errors
1060    ///
1061    /// * `Error::Bus(B)`: Occurs if there is a communication issue with the device, which can prevent
1062    ///   successful writing of the reference mode configuration settings.
1063    pub async fn reference_mode_set(&mut self, val: &RefMd) -> Result<(), Error<B::Error>> {
1064        let mut interrupt_cfg = InterruptCfg::read(self).await?;
1065
1066        interrupt_cfg.set_autozero(val.get_ref);
1067        interrupt_cfg.set_autorefp((val.apply_ref as u8) & 0x01);
1068
1069        interrupt_cfg.set_reset_az(((val.apply_ref as u8) & 0x02) >> 1);
1070        interrupt_cfg.set_reset_arp(((val.apply_ref as u8) & 0x02) >> 1);
1071
1072        interrupt_cfg.write(self).await
1073    }
1074
1075    /// Retrieves the current configuration of reference mode settings for wake-up and wake-up-to-sleep functionality.
1076    ///
1077    /// This function reads the device's registers to obtain the current settings for reference mode,
1078    /// which manage how the device handles reference pressure levels for triggering wake-up and sleep events.
1079    /// It provides insight into the device's responsiveness to changes in pressure and helps verify the
1080    /// current configuration for optimal operation.
1081    ///
1082    /// # Returns
1083    ///
1084    /// * `Result<RefMd, Error<B::Error>>`
1085    ///     * `RefMd`: Contains the current configuration parameters for the reference mode,
1086    ///       including settings for applying and obtaining reference pressure levels.
1087    ///     * `Err`: Returns an error if the operation fails due to a bus communication error.
1088    ///
1089    /// # Errors
1090    ///
1091    /// * `Error::Bus(B)`: Occurs if there is a communication issue with the device, which can prevent
1092    ///   successful reading of the reference mode configuration settings.
1093    pub async fn reference_mode_get(&mut self) -> Result<RefMd, Error<B::Error>> {
1094        let interrupt_cfg = InterruptCfg::read(self).await?;
1095
1096        let val = (interrupt_cfg.reset_az() << 1) | interrupt_cfg.autorefp();
1097
1098        let apply_ref = ApplyRef::try_from(val).unwrap_or_default();
1099        let get_ref = interrupt_cfg.autozero();
1100
1101        Ok(RefMd { apply_ref, get_ref })
1102    }
1103
1104    /// Sets the One-Point Calibration (OPC) value.
1105    ///
1106    /// This function writes the OPC value to the device's registers, allowing for precise calibration
1107    /// of pressure measurements.
1108    ///
1109    /// # Parameters
1110    ///
1111    /// * `val`: An `i16` value representing the One-Point Calibration to be set.
1112    ///
1113    /// # Returns
1114    ///
1115    /// * `Result<(), Error<B::Error>>`
1116    ///     * `Ok`: Indicates successful configuration of the OPC value.
1117    ///     * `Err`: Returns an error if the operation fails due to a bus communication error.
1118    ///
1119    /// # Errors
1120    ///
1121    /// * `Error::Bus(B)`: Occurs if there is a communication issue with the device, which can prevent
1122    ///   successful writing of the OPC value to the register.
1123    pub async fn opc_set(&mut self, val: i16) -> Result<(), Error<B::Error>> {
1124        Rpds::from_bits(val.cast_unsigned()).write(self).await
1125    }
1126
1127    /// Retrieves the current offset pressure calibration (OPC) value.
1128    ///
1129    /// This function reads the device's registers to obtain the current OPC value.
1130    ///
1131    /// # Returns
1132    ///
1133    /// * `Result<i16, Error<B::Error>>`
1134    ///     * `i16`: The current offset pressure calibration value.
1135    ///     * `Err`: Returns an error if the operation fails due to a bus communication error.
1136    ///
1137    /// # Errors
1138    ///
1139    /// * `Error::Bus(B)`: Occurs if there is a communication issue with the device, which can prevent
1140    ///   successful reading of the OPC value from the register.
1141    pub async fn opc_get(&mut self) -> Result<i16, Error<B::Error>> {
1142        Ok(Rpds::read(self).await?.rpds())
1143    }
1144}
1145
1146/// Converts raw pressure data from the full-scale 1260 hPa setting to hectopascals.
1147///
1148/// # Parameters
1149/// * `lsb`: The raw pressure data as a 32-bit integer.
1150///
1151/// # Returns
1152/// * `f32`: The pressure value in hectopascals.
1153#[bisync]
1154pub fn from_fs1260_to_hpa(lsb: i32) -> f32 {
1155    (lsb as f32) / 1048576.0
1156}
1157
1158/// Converts raw pressure data from the full-scale 4000 hPa setting to hectopascals.
1159///
1160/// # Parameters
1161/// * `lsb`: The raw pressure data as a 32-bit integer.
1162///
1163/// # Returns
1164/// * `f32`: The pressure value in hectopascals.
1165#[bisync]
1166pub fn from_fs4000_to_hpa(lsb: i32) -> f32 {
1167    (lsb as f32) / 524288.0
1168}
1169
1170/// Converts raw temperature data to degrees Celsius.
1171///
1172/// # Parameters
1173/// * `lsb`: The raw temperature data as a 16-bit integer.
1174///
1175/// # Returns
1176/// * `f32`: The temperature value in degrees Celsius.
1177#[bisync]
1178pub fn from_lsb_to_celsius(lsb: i16) -> f32 {
1179    (lsb as f32) / 100.0
1180}
1181
1182/// Converts raw AH/QVAR data to millivolts.
1183///
1184/// # Parameters
1185/// * `lsb`: The raw AH/QVAR data as a 32-bit integer.
1186///
1187/// # Returns
1188/// * `f32`: The voltage value in millivolts.
1189#[bisync]
1190pub fn from_lsb_to_mv(lsb: i32) -> f32 {
1191    (lsb as f32) / 438000.0
1192}
1193
1194/// Represents the I2C address for the device.
1195#[repr(u8)]
1196#[derive(Clone, Copy, PartialEq)]
1197pub enum I2CAddress {
1198    /// The I2C address for the device, set to `0x5c`.
1199    I2cAdd = 0x5c,
1200}
1201
1202/// Device Who am I.
1203#[bisync]
1204pub const ILPS22QS_ID: u8 = 0xB4;
1205
1206#[bisync]
1207pub const PROPERTY_ENABLE: u8 = 1;
1208#[bisync]
1209pub const PROPERTY_DISABLE: u8 = 0;