Skip to main content

gnss_protos/gps/
mod.rs

1//! GPS / QZSS protocol
2
3/// GPS uses 30 bit data words, and is not aligned.
4pub const GPS_WORD_SIZE: usize = 30;
5
6/// Minimal allocation to encode a correct GPS data frame.
7pub const GPS_MIN_SIZE: usize = GPS_WORD_SIZE * 10;
8
9mod bytes;
10mod decoder;
11mod errors;
12mod frame1;
13mod frame2;
14mod frame3;
15mod frame_id;
16mod how;
17mod tlm;
18
19pub use bytes::GpsDataByte;
20pub use decoder::GpsQzssDecoder;
21pub use errors::GpsError;
22pub use frame_id::GpsQzssFrameId;
23pub use how::GpsQzssHow;
24pub use tlm::GpsQzssTelemetry;
25
26pub use frame1::GpsQzssFrame1;
27pub use frame2::GpsQzssFrame2;
28pub use frame3::GpsQzssFrame3;
29
30/// GPS / QZSS interpreted frame.
31#[derive(Debug, Copy, Clone, PartialEq)]
32pub struct GpsQzssFrame {
33    /// [GpsQzssHow] describes following frame.
34    pub how: GpsQzssHow,
35
36    /// [GpsQzssTelemetry] describes following frame.
37    pub telemetry: GpsQzssTelemetry,
38
39    /// [GpsQzssSubframe] depends on associated How.
40    pub subframe: GpsQzssSubframe,
41}
42
43/// GPS / QZSS Interpreted subframes
44#[derive(Debug, Copy, Clone, PartialEq)]
45pub enum GpsQzssSubframe {
46    /// GPS Ephemeris Frame #1
47    Ephemeris1(GpsQzssFrame1),
48
49    /// GPS Ephemeris Frame #2
50    Ephemeris2(GpsQzssFrame2),
51
52    /// GPS Ephemeris Frame #3
53    Ephemeris3(GpsQzssFrame3),
54}
55
56impl Default for GpsQzssSubframe {
57    fn default() -> Self {
58        Self::Ephemeris1(Default::default())
59    }
60}
61
62impl GpsQzssSubframe {
63    /// Unwraps self as [GpsQzssFrame1] reference (if feasible)
64    pub fn as_eph1(&self) -> Option<&GpsQzssFrame1> {
65        match self {
66            Self::Ephemeris1(frame) => Some(frame),
67            _ => None,
68        }
69    }
70
71    /// Unwraps self as mutable [GpsQzssFrame1] reference (if feasible)
72    pub fn as_mut_eph1(&mut self) -> Option<&mut GpsQzssFrame1> {
73        match self {
74            Self::Ephemeris1(frame) => Some(frame),
75            _ => None,
76        }
77    }
78
79    /// Unwraps self as [GpsQzssFrame2] reference (if feasible)
80    pub fn as_eph2(&self) -> Option<&GpsQzssFrame2> {
81        match self {
82            Self::Ephemeris2(frame) => Some(frame),
83            _ => None,
84        }
85    }
86
87    /// Unwraps self as [GpsQzssFrame2] reference (if feasible)
88    pub fn as_mut_eph2(&mut self) -> Option<&mut GpsQzssFrame2> {
89        match self {
90            Self::Ephemeris2(frame) => Some(frame),
91            _ => None,
92        }
93    }
94
95    /// Unwraps self as [GpsQzssFrame3] reference (if feasible)
96    pub fn as_eph3(&self) -> Option<&GpsQzssFrame3> {
97        match self {
98            Self::Ephemeris3(frame) => Some(frame),
99            _ => None,
100        }
101    }
102
103    /// Unwraps self as [GpsQzssFrame3] reference (if feasible)
104    pub fn as_mut_eph3(&mut self) -> Option<&mut GpsQzssFrame3> {
105        match self {
106            Self::Ephemeris3(frame) => Some(frame),
107            _ => None,
108        }
109    }
110}
111
112// /// Verifies 24-bit LSB (right aligned) parity
113// pub(crate) fn check_parity(value: u32) -> bool {
114//     let data = value >> 6;
115//     let expected = parity_encoding(data);
116//     let parity = (value & 0x3f) as u8;
117//
118//     if expected == parity {
119//         true
120//     } else {
121//         #[cfg(feature = "log")]
122//         error!(
123//             "GPS: parity error - expected 0x{:02X} - got 0x{:02X}",
124//             expected, parity
125//         );
126//
127//         false
128//     }
129// }
130//
131// /// Encodes 24-bit LSB into 6 bit parity (right aligned!)
132// pub(crate) fn parity_encoding(value: u32) -> u8 {
133//     let generator = 0x61_u32;
134//     let mut reg = value << 6;
135//
136//     for _ in 0..24 {
137//         if reg & (1 << 29) != 0 {
138//             reg ^= generator << 23;
139//         }
140//         reg <<= 1;
141//     }
142//
143//     ((reg >> 30) & 0x3f) as u8
144// }