Skip to main content

ph_qmi8658/data/
scale.rs

1//! Integer scaling helpers for raw sensor data.
2
3use crate::config::common::{AccelRange, GyroRange};
4
5/// Ratio representing a scale factor without floating-point math.
6#[derive(Clone, Copy, Debug, PartialEq, Eq)]
7pub struct ScaleFactor {
8    /// Scale numerator.
9    pub numerator: i32,
10    /// Scale denominator.
11    pub denominator: i32,
12}
13
14impl ScaleFactor {
15    /// Creates a new scale ratio.
16    pub const fn new(numerator: i32, denominator: i32) -> Self {
17        Self {
18            numerator,
19            denominator,
20        }
21    }
22}
23
24/// Returns the accelerometer sensitivity in LSB/g.
25pub const fn accel_lsb_per_g(range: AccelRange) -> i32 {
26    match range {
27        AccelRange::G2 => 16_384,
28        AccelRange::G4 => 8_192,
29        AccelRange::G8 => 4_096,
30        AccelRange::G16 => 2_048,
31    }
32}
33
34/// Returns the gyroscope sensitivity in LSB/dps.
35pub const fn gyro_lsb_per_dps(range: GyroRange) -> i32 {
36    match range {
37        GyroRange::Dps16 => 2_048,
38        GyroRange::Dps32 => 1_024,
39        GyroRange::Dps64 => 512,
40        GyroRange::Dps128 => 256,
41        GyroRange::Dps256 => 128,
42        GyroRange::Dps512 => 64,
43        GyroRange::Dps1024 => 32,
44        GyroRange::Dps2048 => 16,
45    }
46}
47
48/// Returns the temperature sensitivity in LSB per degree Celsius.
49pub const fn temperature_lsb_per_celsius() -> i32 {
50    256
51}
52
53/// Returns the accelerometer scale in milli-g per LSB as a ratio.
54pub const fn accel_mg_per_lsb(range: AccelRange) -> ScaleFactor {
55    ScaleFactor::new(1000, accel_lsb_per_g(range))
56}
57
58/// Returns the gyroscope scale in milli-deg/s per LSB as a ratio.
59pub const fn gyro_mdps_per_lsb(range: GyroRange) -> ScaleFactor {
60    ScaleFactor::new(1000, gyro_lsb_per_dps(range))
61}
62
63/// Returns the temperature scale in milli-deg C per LSB as a ratio.
64pub const fn temperature_mdegc_per_lsb() -> ScaleFactor {
65    ScaleFactor::new(1000, temperature_lsb_per_celsius())
66}
67
68#[cfg(test)]
69mod tests {
70    use super::*;
71
72    #[test]
73    fn accel_lsb_per_g_values() {
74        assert_eq!(accel_lsb_per_g(AccelRange::G2), 16_384);
75        assert_eq!(accel_lsb_per_g(AccelRange::G16), 2_048);
76    }
77
78    #[test]
79    fn gyro_lsb_per_dps_values() {
80        assert_eq!(gyro_lsb_per_dps(GyroRange::Dps16), 2_048);
81        assert_eq!(gyro_lsb_per_dps(GyroRange::Dps2048), 16);
82    }
83
84    #[test]
85    fn temperature_scale_values() {
86        assert_eq!(temperature_lsb_per_celsius(), 256);
87        assert_eq!(
88            temperature_mdegc_per_lsb(),
89            ScaleFactor::new(1000, 256)
90        );
91    }
92}