1use super::{AccelRaw, GyroRaw, Sample, TemperatureRaw};
4use super::scale::{accel_lsb_per_g, gyro_lsb_per_dps, temperature_lsb_per_celsius};
5use crate::config::common::{AccelRange, GyroRange};
6
7pub type Fixed = crate::fixed_crate::types::I32F32;
9
10#[derive(Clone, Copy, Debug, PartialEq, Eq)]
12pub struct AccelFixed {
13 pub x: Fixed,
15 pub y: Fixed,
17 pub z: Fixed,
19}
20
21#[derive(Clone, Copy, Debug, PartialEq, Eq)]
23pub struct GyroFixed {
24 pub x: Fixed,
26 pub y: Fixed,
28 pub z: Fixed,
30}
31
32#[derive(Clone, Copy, Debug, PartialEq, Eq)]
34pub struct TemperatureFixed {
35 pub celsius: Fixed,
37}
38
39pub fn accel_to_g(raw: AccelRaw, range: AccelRange) -> AccelFixed {
41 let scale = Fixed::from_num(accel_lsb_per_g(range));
42 AccelFixed {
43 x: Fixed::from_num(raw.x) / scale,
44 y: Fixed::from_num(raw.y) / scale,
45 z: Fixed::from_num(raw.z) / scale,
46 }
47}
48
49pub fn gyro_to_dps(raw: GyroRaw, range: GyroRange) -> GyroFixed {
51 let scale = Fixed::from_num(gyro_lsb_per_dps(range));
52 GyroFixed {
53 x: Fixed::from_num(raw.x) / scale,
54 y: Fixed::from_num(raw.y) / scale,
55 z: Fixed::from_num(raw.z) / scale,
56 }
57}
58
59pub fn temperature_celsius(raw: TemperatureRaw) -> TemperatureFixed {
63 let scale = Fixed::from_num(temperature_lsb_per_celsius());
64 TemperatureFixed {
65 celsius: Fixed::from_num(raw.value) / scale,
66 }
67}
68
69pub fn accel_sample_to_g(sample: Sample<AccelRaw>, range: AccelRange) -> Sample<AccelFixed> {
71 Sample {
72 timestamp: sample.timestamp,
73 data: accel_to_g(sample.data, range),
74 }
75}
76
77pub fn gyro_sample_to_dps(sample: Sample<GyroRaw>, range: GyroRange) -> Sample<GyroFixed> {
79 Sample {
80 timestamp: sample.timestamp,
81 data: gyro_to_dps(sample.data, range),
82 }
83}
84
85pub fn temperature_sample_celsius(sample: Sample<TemperatureRaw>) -> Sample<TemperatureFixed> {
87 Sample {
88 timestamp: sample.timestamp,
89 data: temperature_celsius(sample.data),
90 }
91}
92
93#[cfg(test)]
94mod tests {
95 use super::*;
96 use crate::config::common::{AccelRange, GyroRange};
97 use crate::data::Timestamp;
98
99 #[test]
100 fn accel_conversion_matches_scale() {
101 let raw = AccelRaw {
102 x: 16_384,
103 y: -16_384,
104 z: 0,
105 };
106 let fixed = accel_to_g(raw, AccelRange::G2);
107 assert_eq!(fixed.x, Fixed::from_num(1));
108 assert_eq!(fixed.y, Fixed::from_num(-1));
109 assert_eq!(fixed.z, Fixed::from_num(0));
110 }
111
112 #[test]
113 fn gyro_conversion_matches_scale() {
114 let raw = GyroRaw {
115 x: 2_048,
116 y: -2_048,
117 z: 0,
118 };
119 let fixed = gyro_to_dps(raw, GyroRange::Dps16);
120 assert_eq!(fixed.x, Fixed::from_num(1));
121 assert_eq!(fixed.y, Fixed::from_num(-1));
122 assert_eq!(fixed.z, Fixed::from_num(0));
123 }
124
125 #[test]
126 fn temperature_conversion_matches_scale() {
127 let raw = TemperatureRaw { value: 256 };
128 let fixed = temperature_celsius(raw);
129 assert_eq!(fixed.celsius, Fixed::from_num(1));
130 }
131
132 #[test]
133 fn sample_conversion_preserves_timestamp() {
134 let sample = Sample {
135 timestamp: Timestamp { ticks: 123 },
136 data: AccelRaw { x: 0, y: 0, z: 0 },
137 };
138 let fixed = accel_sample_to_g(sample, AccelRange::G8);
139 assert_eq!(fixed.timestamp.ticks, 123);
140 }
141}