blackbox_log/frame/main/
mod.rs

1mod def;
2
3use alloc::vec::Vec;
4
5pub use self::def::*;
6use super::{DataFrameKind, FrameKind, Unit};
7use crate::data::MainFrameHistory;
8use crate::filter::AppliedFilter;
9use crate::parser::InternalResult;
10use crate::units::prelude::*;
11use crate::{units, Headers, Reader};
12
13/// Data parsed from a main frame.
14#[derive(Debug)]
15pub struct MainFrame<'data, 'headers, 'parser> {
16    headers: &'headers Headers<'data>,
17    raw: &'parser RawMainFrame,
18    filter: &'parser AppliedFilter,
19}
20
21impl super::seal::Sealed for MainFrame<'_, '_, '_> {}
22
23impl super::Frame for MainFrame<'_, '_, '_> {
24    type Value = MainValue;
25
26    #[inline]
27    fn len(&self) -> usize {
28        self.filter.len()
29    }
30
31    fn get_raw(&self, index: usize) -> Option<u32> {
32        let index = self.filter.get(index)?;
33
34        let value = if index == 0 {
35            self.raw.iteration
36        } else {
37            self.raw.values[index - 1]
38        };
39
40        Some(value)
41    }
42
43    fn get(&self, index: usize) -> Option<MainValue> {
44        let frame_def = self.headers.main_frame_def();
45        let index = self.filter.get(index)?;
46
47        if index == 0 {
48            return Some(MainValue::Unsigned(self.raw.iteration));
49        }
50        let index = index - 1;
51
52        let def = &frame_def.fields[index];
53        let raw = self.raw.values[index];
54
55        let value = match def.unit {
56            MainUnit::Amperage => {
57                debug_assert!(def.signed);
58                let raw = raw.cast_signed();
59                MainValue::Amperage(units::new::current(raw))
60            }
61            MainUnit::Voltage => {
62                debug_assert!(!def.signed);
63                MainValue::Voltage(units::new::vbat(raw))
64            }
65            MainUnit::Acceleration => {
66                debug_assert!(def.signed);
67                let raw = raw.cast_signed();
68                MainValue::Acceleration(units::new::acceleration(raw, self.headers))
69            }
70            MainUnit::Rotation => {
71                debug_assert!(def.signed);
72                let raw = raw.cast_signed();
73                MainValue::Rotation(units::new::angular_velocity(raw, self.headers))
74            }
75            MainUnit::Unitless => MainValue::new_unitless(raw, def.signed),
76        };
77
78        Some(value)
79    }
80}
81
82impl<'data, 'headers, 'parser> MainFrame<'data, 'headers, 'parser> {
83    pub(crate) fn new(
84        headers: &'headers Headers<'data>,
85        raw: &'parser RawMainFrame,
86        filter: &'parser AppliedFilter,
87    ) -> Self {
88        Self {
89            headers,
90            raw,
91            filter,
92        }
93    }
94
95    /// Returns the parsed time since power on.
96    #[inline]
97    pub fn time(&self) -> Time {
98        units::new::time(self.raw.time)
99    }
100
101    /// Returns the raw microsecond counter since power on.
102    ///
103    /// **Note:** This does not currently handle overflow of the transmitted
104    /// 32bit counter. See [#54](https://github.com/blackbox-log/blackbox-log/issues/54).
105    #[inline]
106    pub fn time_raw(&self) -> u64 {
107        self.raw.time
108    }
109}
110
111#[derive(Debug, Clone)]
112pub(crate) struct RawMainFrame {
113    intra: bool,
114    pub(crate) iteration: u32,
115    pub(crate) time: u64,
116    pub(crate) values: Vec<u32>,
117}
118
119impl RawMainFrame {
120    pub(crate) fn parse(
121        data: &mut Reader,
122        headers: &Headers,
123        kind: FrameKind,
124        history: &MainFrameHistory,
125    ) -> InternalResult<Self> {
126        let last = history.last();
127        let def = headers.main_frame_def();
128
129        if kind == FrameKind::Data(DataFrameKind::Intra) {
130            def.parse_intra(data, headers, last)
131        } else {
132            let skipped = 0; // FIXME
133
134            def.parse_inter(data, headers, last, history.last_last(), skipped)
135        }
136    }
137}
138
139#[derive(Debug, Clone, Copy, PartialEq)]
140pub enum MainValue {
141    Amperage(ElectricCurrent),
142    Voltage(ElectricPotential),
143    Acceleration(Acceleration),
144    Rotation(AngularVelocity),
145    Unsigned(u32),
146    Signed(i32),
147}
148
149impl MainValue {
150    const fn new_unitless(value: u32, signed: bool) -> Self {
151        if signed {
152            Self::Signed(value.cast_signed())
153        } else {
154            Self::Unsigned(value)
155        }
156    }
157}
158
159impl From<MainValue> for super::Value {
160    fn from(value: MainValue) -> Self {
161        match value {
162            MainValue::Amperage(a) => Self::Amperage(a),
163            MainValue::Voltage(v) => Self::Voltage(v),
164            MainValue::Acceleration(a) => Self::Acceleration(a),
165            MainValue::Rotation(r) => Self::Rotation(r),
166            MainValue::Unsigned(x) => Self::Unsigned(x),
167            MainValue::Signed(x) => Self::Signed(x),
168        }
169    }
170}
171
172#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
173pub enum MainUnit {
174    Amperage,
175    Voltage,
176    Acceleration,
177    Rotation,
178    Unitless,
179}
180
181impl From<MainUnit> for Unit {
182    fn from(unit: MainUnit) -> Self {
183        match unit {
184            MainUnit::Amperage => Self::Amperage,
185            MainUnit::Voltage => Self::Voltage,
186            MainUnit::Acceleration => Self::Acceleration,
187            MainUnit::Rotation => Self::Rotation,
188            MainUnit::Unitless => Self::Unitless,
189        }
190    }
191}