16
16
#include <libswiftnav/nav_msg_glo.h>
17
17
#include <libswiftnav/time.h>
18
18
#include <libswiftnav/logging.h>
19
+ #include <libswiftnav/bits.h>
19
20
20
21
/* Word Ft (accuracy of measurements), refer to GLO ICD, Table 4.4 */
21
22
const float f_t [] = { 1.0f , 2.0f , 2.5f , 4.0f , 5.0f , 7.0f , 10.0f , 12.0f , 14.0f ,
@@ -36,6 +37,8 @@ const u32 e_masks[7][3] = {
36
37
{ 0 , 0 , 0x1ffffe },
37
38
};
38
39
40
+ static u32 extract_word_glo (const nav_msg_glo_t * n , u16 bit_index , u8 n_bits );
41
+
39
42
/** Initialize the necessary parts of the nav message state structure.
40
43
* \param n Pointer to GLO nav message structure to be initialized
41
44
*/
@@ -46,24 +49,6 @@ void nav_msg_init_glo(nav_msg_glo_t *n)
46
49
n -> state = SYNC_TM ;
47
50
}
48
51
49
- /* The algorithm based on
50
- * https://graphics.stanford.edu/~seander/bithacks.html#ParityParallel
51
- * \param in input data to calculate parity
52
- * \param word if true, calculate parity for 32 bits otherwise for 8 bits
53
- * \return parity bit */
54
- static bool parity (u32 in , bool word )
55
- {
56
- u32 a = in ;
57
- if (word ) {
58
- a ^= a >> 16 ;
59
- a ^= a >> 8 ;
60
- } else
61
- a &= 0x000000ff ;
62
- a ^= a >> 4 ;
63
- a &= 0xf ;
64
- return (0x6996 >> a ) & 1 ;
65
- }
66
-
67
52
/** The function performs data verification and error correction
68
53
* in received GLO navigation string. Refer to GLO ICD, section 4.7
69
54
* \param n pointer to GLO nav message structure
@@ -88,9 +73,9 @@ s8 error_detection_glo(nav_msg_glo_t *n)
88
73
data2 = extract_word_glo (n , 33 , 32 ) & e_masks [i ][1 ];
89
74
data3 = extract_word_glo (n , 65 , 32 ) & e_masks [i ][2 ];
90
75
/* calculate parity for data[1..3] */
91
- p1 = parity (data1 , true );
92
- p2 = parity (data2 , true );
93
- p3 = parity (data3 , true );
76
+ p1 = parity (data1 );
77
+ p2 = parity (data2 );
78
+ p3 = parity (data3 );
94
79
bool p = beta ^ p1 ^ p2 ^ p3 ;
95
80
/* calculate common parity and set according C bit */
96
81
c |= p << i ;
@@ -105,10 +90,10 @@ s8 error_detection_glo(nav_msg_glo_t *n)
105
90
data1 = extract_word_glo (n , 1 , 32 ) & 0xffffff00 ;
106
91
data2 = extract_word_glo (n , 33 , 32 );
107
92
data3 = extract_word_glo (n , 65 , 32 );
108
- p1 = parity (data1 , true );
109
- p2 = parity (data2 , true );
110
- p3 = parity (data3 , true );
111
- p0 = parity (extract_word_glo (n , 1 , 8 ), false );
93
+ p1 = parity (data1 );
94
+ p2 = parity (data2 );
95
+ p3 = parity (data3 );
96
+ p0 = parity (extract_word_glo (n , 1 , 8 ));
112
97
c_sum = p0 ^ p1 ^ p2 ^ p3 ;
113
98
114
99
/* Now check C word to figure out is the string good, bad or
@@ -144,7 +129,7 @@ s8 error_detection_glo(nav_msg_glo_t *n)
144
129
* \param n_bits how many bits should be extracted [1..32]
145
130
* \return word extracted from navigation string
146
131
*/
147
- u32 extract_word_glo (const nav_msg_glo_t * n , u16 bit_index , u8 n_bits )
132
+ static u32 extract_word_glo (const nav_msg_glo_t * n , u16 bit_index , u8 n_bits )
148
133
{
149
134
assert (n_bits <= 32 && n_bits > 0 );
150
135
assert (bit_index <= 85 && bit_index > 0 );
@@ -252,6 +237,7 @@ s8 process_string_glo(nav_msg_glo_t *n, ephemeris_t *e)
252
237
u8 sign ;
253
238
/* is the string we need? */
254
239
if (n -> next_string_id == m ) {
240
+ n -> decode_done = 0 ;
255
241
switch (m ) {
256
242
case 1 : /* string 1 */
257
243
/* extract x */
@@ -342,24 +328,39 @@ s8 process_string_glo(nav_msg_glo_t *n, ephemeris_t *e)
342
328
/* extract N4 */
343
329
n -> n4 = (u8 ) extract_word_glo (n , 32 , 5 );
344
330
345
- n -> next_string_id = 0 ; /* all string parsed */
331
+ n -> next_string_id = 1 ; /* start decode from 1st string next time */
332
+ n -> decode_done = 1 ; /* all string parsed */
346
333
break ;
347
334
default :
348
335
break ;
349
336
}
350
337
}
351
338
/* all needed strings decoded?
352
339
* fill ephemeris structure if we was not able to do it before*/
353
- if (n -> next_string_id == 0 ) {
340
+ if (n -> decode_done ) {
354
341
e -> sid .code = CODE_GLO_L1CA ;
355
342
/* convert GLO TOE to GPS TOE */
356
343
e -> toe = glo_time2gps_time (n -> nt , n -> n4 , n -> hrs , n -> min , n -> sec );
357
344
e -> healthy ^= 1 ; /* invert healthy bit */
358
345
e -> valid = e -> healthy ; //NOTE: probably Valid needs to be defined by other way
359
- n -> next_string_id = 1 ; /* start from string 1 */
360
346
return 1 ;
361
347
}
362
348
363
349
364
350
return 0 ;
365
351
}
352
+
353
+ /** This function just a wrapper for glo_time2gps_time
354
+ * \param n pointer to GLO nav message
355
+ * \return time of GLO referenced to the end of the 5th GLO nav string presented as
356
+ * GPS time, -1 if ephemeris cannot be decoded */
357
+ double nav_msg_get_tow_glo (const nav_msg_glo_t * n )
358
+ {
359
+ /* + 10 sec for the end of 5th string */
360
+ if (!n -> decode_done )
361
+ return -1 ;
362
+ else {
363
+ gps_time_t t = glo_time2gps_time (n -> nt , n -> n4 , n -> hrs , n -> min , n -> sec + 10 );
364
+ return t .tow ;
365
+ }
366
+ }
0 commit comments