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