Skip to main content

gnss_protos/gps/
frame3.rs

1use crate::twos_complement;
2
3const WORD3_CIC_MASK: u32 = 0x3fffc000;
4const WORD3_CIC_SHIFT: u32 = 14;
5const WORD3_OMEGA0_MASK: u32 = 0x00003fc0;
6const WORD3_OMEGA0_SHIFT: u32 = 6;
7
8const WORD4_OMEGA0_MASK: u32 = 0x3fffffc0;
9const WORD4_OMEGA0_SHIFT: u32 = 6;
10
11const WORD5_CIS_MASK: u32 = 0x3fffc000;
12const WORD5_CIS_SHIFT: u32 = 14;
13const WORD5_I0_MASK: u32 = 0x00003fc0;
14const WORD5_I0_SHIFT: u32 = 6;
15
16const WORD6_I0_MASK: u32 = 0x3fffffc0;
17const WORD6_I0_SHIFT: u32 = 6;
18
19const WORD7_CRC_MASK: u32 = 0x3fffc000;
20const WORD7_CRC_SHIFT: u32 = 14;
21const WORD7_OMEGA_MASK: u32 = 0x00003fc0;
22const WORD7_OMEGA_SHIFT: u32 = 6;
23
24const WORD8_OMEGA_MASK: u32 = 0x3fffffc0;
25const WORD8_OMEGA_SHIFT: u32 = 6;
26
27const WORD9_OMEGADOT_MASK: u32 = 0x3fffffc0;
28const WORD9_OMEGADOT_SHIFT: u32 = 6;
29
30const WORD10_IODE_MASK: u32 = 0x3fc00000;
31const WORD10_IODE_SHIFT: u32 = 22;
32const WORD10_IDOT_MASK: u32 = 0x003fff00;
33const WORD10_IDOT_SHIFT: u32 = 8;
34
35/// GPS / QZSS Frame #3 interpretation
36#[derive(Debug, Default, Copy, Clone, PartialEq)]
37pub struct GpsQzssFrame3 {
38    /// Inclination angle cosine harmonic correction term
39    pub cic: f64,
40
41    /// Inclination angle sine harmonic correction term
42    pub cis: f64,
43
44    /// Orbit radius cosine harmonic correction term
45    pub crc: f64,
46
47    /// Inclination angle at reference time  (in semi circles)
48    pub i0: f64,
49
50    /// IODE: Issue of Data (Ephemeris)
51    pub iode: u8,
52
53    /// Rate of inclination angle (in semi circles.s⁻¹)
54    pub idot: f64,
55
56    /// Longitude of ascending node of orbit plane at weekly epoch (in semi circles)
57    pub omega0: f64,
58
59    /// Omega (in semi circles)
60    pub omega: f64,
61
62    /// Omega_dot (in semi circles.s⁻¹)
63    pub omega_dot: f64,
64}
65
66#[derive(Debug, Default, Clone)]
67pub struct Word3 {
68    pub cic: i32,
69
70    /// Omega0 (8) MSB, you will have to associate this to Word #4
71    pub omega0_msb: u8,
72}
73
74impl Word3 {
75    pub(crate) fn decode(dword: u32) -> Self {
76        let cic = ((dword & WORD3_CIC_MASK) >> WORD3_CIC_SHIFT) as u32;
77        let cic = twos_complement(cic, 0xffff, 0x8000);
78        let omega0_msb = ((dword & WORD3_OMEGA0_MASK) >> WORD3_OMEGA0_SHIFT) as u8;
79        Self { cic, omega0_msb }
80    }
81}
82
83#[derive(Debug, Default, Clone)]
84pub struct Word4 {
85    /// Omega0 (24) LSB, you will have to associate this to Word #3
86    pub omega0_lsb: u32,
87}
88
89impl Word4 {
90    pub(crate) fn decode(dword: u32) -> Self {
91        let omega0_lsb = ((dword & WORD4_OMEGA0_MASK) >> WORD4_OMEGA0_SHIFT) as u32;
92        Self { omega0_lsb }
93    }
94}
95#[derive(Debug, Default, Clone)]
96pub struct Word5 {
97    pub cis: i32,
98
99    /// I0 (8) MSB, you will have to associate this to Word #6
100    pub i0_msb: u8,
101}
102
103impl Word5 {
104    pub(crate) fn decode(dword: u32) -> Self {
105        let cis = ((dword & WORD5_CIS_MASK) >> WORD5_CIS_SHIFT) as u32;
106        let cis = twos_complement(cis, 0xffff, 0x8000);
107        let i0_msb = ((dword & WORD5_I0_MASK) >> WORD5_I0_SHIFT) as u8;
108        Self { cis, i0_msb }
109    }
110}
111
112#[derive(Debug, Default, Clone)]
113pub struct Word6 {
114    /// I0 (24) LSB, you will have to associate this to Word #5
115    pub i0_lsb: u32,
116}
117
118impl Word6 {
119    pub(crate) fn decode(dword: u32) -> Self {
120        let i0_lsb = ((dword & WORD6_I0_MASK) >> WORD6_I0_SHIFT) as u32;
121        Self { i0_lsb }
122    }
123}
124
125#[derive(Debug, Default, Clone)]
126pub struct Word7 {
127    pub crc: i32,
128
129    /// Omega (8) MSB, you will have to associate this to Word #8
130    pub omega_msb: u8,
131}
132
133impl Word7 {
134    pub(crate) fn decode(dword: u32) -> Self {
135        let crc = ((dword & WORD7_CRC_MASK) >> WORD7_CRC_SHIFT) as u32;
136        let crc = twos_complement(crc, 0xffff, 0x8000);
137        let omega_msb = ((dword & WORD7_OMEGA_MASK) >> WORD7_OMEGA_SHIFT) as u8;
138        Self { crc, omega_msb }
139    }
140}
141
142#[derive(Debug, Default, Clone)]
143pub struct Word8 {
144    /// Omega (24) LSB, you will have to associate this to Word #7
145    pub omega_lsb: u32,
146}
147
148impl Word8 {
149    pub(crate) fn decode(dword: u32) -> Self {
150        let omega_lsb = ((dword & WORD8_OMEGA_MASK) >> WORD8_OMEGA_SHIFT) as u32;
151        Self { omega_lsb }
152    }
153}
154
155#[derive(Debug, Default, Clone)]
156pub struct Word9 {
157    // 24-bit Omega_dot
158    pub omega_dot: i32,
159}
160
161impl Word9 {
162    pub(crate) fn decode(dword: u32) -> Self {
163        let omega_dot = ((dword & WORD9_OMEGADOT_MASK) >> WORD9_OMEGADOT_SHIFT) as u32;
164        let omega_dot = twos_complement(omega_dot, 0xffffff, 0x800000);
165        Self { omega_dot }
166    }
167}
168
169#[derive(Debug, Default, Clone)]
170pub struct Word10 {
171    /// 8-bit IODE
172    pub iode: u8,
173
174    /// 14-bit IDOT
175    pub idot: i32,
176}
177
178impl Word10 {
179    pub(crate) fn decode(dword: u32) -> Self {
180        let iode = ((dword & WORD10_IODE_MASK) >> WORD10_IODE_SHIFT) as u8;
181
182        // 14-bit signed 2's
183        let idot = ((dword & WORD10_IDOT_MASK) >> WORD10_IDOT_SHIFT) as u32;
184        let idot = twos_complement(idot, 0x3fff, 0x2000);
185
186        Self { iode, idot }
187    }
188}