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// }