1616#include <libswiftnav/nav_msg_glo.h>
1717#include <libswiftnav/time.h>
1818#include <libswiftnav/logging.h>
19+ #include <libswiftnav/bits.h>
1920
2021/* Word Ft (accuracy of measurements), refer to GLO ICD, Table 4.4 */
2122const 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] = {
3637 { 0 , 0 , 0x1ffffe },
3738};
3839
40+ static u32 extract_word_glo (const nav_msg_glo_t * n , u16 bit_index , u8 n_bits );
41+
3942/** Initialize the necessary parts of the nav message state structure.
4043 * \param n Pointer to GLO nav message structure to be initialized
4144 */
@@ -46,24 +49,6 @@ void nav_msg_init_glo(nav_msg_glo_t *n)
4649 n -> state = SYNC_TM ;
4750}
4851
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-
6752/** The function performs data verification and error correction
6853 * in received GLO navigation string. Refer to GLO ICD, section 4.7
6954 * \param n pointer to GLO nav message structure
@@ -88,9 +73,9 @@ s8 error_detection_glo(nav_msg_glo_t *n)
8873 data2 = extract_word_glo (n , 33 , 32 ) & e_masks [i ][1 ];
8974 data3 = extract_word_glo (n , 65 , 32 ) & e_masks [i ][2 ];
9075 /* 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 );
9479 bool p = beta ^ p1 ^ p2 ^ p3 ;
9580 /* calculate common parity and set according C bit */
9681 c |= p << i ;
@@ -105,10 +90,10 @@ s8 error_detection_glo(nav_msg_glo_t *n)
10590 data1 = extract_word_glo (n , 1 , 32 ) & 0xffffff00 ;
10691 data2 = extract_word_glo (n , 33 , 32 );
10792 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 ));
11297 c_sum = p0 ^ p1 ^ p2 ^ p3 ;
11398
11499 /* 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)
144129 * \param n_bits how many bits should be extracted [1..32]
145130 * \return word extracted from navigation string
146131 */
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 )
148133{
149134 assert (n_bits <= 32 && n_bits > 0 );
150135 assert (bit_index <= 85 && bit_index > 0 );
@@ -252,6 +237,7 @@ s8 process_string_glo(nav_msg_glo_t *n, ephemeris_t *e)
252237 u8 sign ;
253238 /* is the string we need? */
254239 if (n -> next_string_id == m ) {
240+ n -> decode_done = 0 ;
255241 switch (m ) {
256242 case 1 : /* string 1 */
257243 /* extract x */
@@ -342,24 +328,39 @@ s8 process_string_glo(nav_msg_glo_t *n, ephemeris_t *e)
342328 /* extract N4 */
343329 n -> n4 = (u8 ) extract_word_glo (n , 32 , 5 );
344330
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 */
346333 break ;
347334 default :
348335 break ;
349336 }
350337 }
351338 /* all needed strings decoded?
352339 * fill ephemeris structure if we was not able to do it before*/
353- if (n -> next_string_id == 0 ) {
340+ if (n -> decode_done ) {
354341 e -> sid .code = CODE_GLO_L1CA ;
355342 /* convert GLO TOE to GPS TOE */
356343 e -> toe = glo_time2gps_time (n -> nt , n -> n4 , n -> hrs , n -> min , n -> sec );
357344 e -> healthy ^= 1 ; /* invert healthy bit */
358345 e -> valid = e -> healthy ; //NOTE: probably Valid needs to be defined by other way
359- n -> next_string_id = 1 ; /* start from string 1 */
360346 return 1 ;
361347 }
362348
363349
364350 return 0 ;
365351}
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