Skip to content
This repository was archived by the owner on Apr 13, 2021. It is now read-only.

Commit 7d0fcef

Browse files
author
Roman Gezikov
committed
Merge pull request #294 from dt-exafore/i38-l2c-capability-monitor
Add decoding of L2C capability mask
2 parents 22e6cca + 44f1105 commit 7d0fcef

File tree

13 files changed

+243
-25
lines changed

13 files changed

+243
-25
lines changed

include/libswiftnav/ephemeris.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ u8 ephemeris_params_valid(const u8 valid, const u32 fit_interval,
107107
const gps_time_t* toe, const gps_time_t *t);
108108
u8 satellite_healthy(const ephemeris_t *e);
109109

110-
void decode_ephemeris(u32 frame_words[3][8], ephemeris_t *e);
110+
void decode_ephemeris(u32 frame_words[4][8], ephemeris_t *e);
111111
bool ephemeris_equal(const ephemeris_t *a, const ephemeris_t *b);
112112

113113
#endif /* LIBSWIFTNAV_EPHEMERIS_H */
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/*
2+
* Copyright (C) 2016 Swift Navigation Inc.
3+
* Contact: Dmitry Tatarinov <dmitry.tatarinov@exafore.com>
4+
*
5+
* This source is subject to the license found in the file 'LICENSE' which must
6+
* be be distributed together with this source. All other rights reserved.
7+
*
8+
* THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
9+
* EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
10+
* WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
11+
*/
12+
13+
#ifndef LIBSWIFTNAV_L2C_CAPABILITY_H
14+
#define LIBSWIFTNAV_L2C_CAPABILITY_H
15+
16+
#include <libswiftnav/common.h>
17+
#include <libswiftnav/nav_msg.h>
18+
19+
void decode_l2c_capability(const u32 *subframe4_words, u32 *l2c_cpbl);
20+
21+
#endif /* LIBSWIFTNAV_L2C_CAPABILITY_H */

include/libswiftnav/nav_msg.h

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,16 +35,26 @@ typedef struct {
3535
*/
3636
s16 subframe_start_index;
3737

38-
u32 frame_words[3][8];
38+
u32 frame_words[4][8];
3939
u8 next_subframe_id;
4040
s8 bit_polarity;
4141

4242
u8 alert;
4343
} nav_msg_t;
4444

45+
typedef struct {
46+
ephemeris_t ephemeris;
47+
bool ephemeris_upd_flag;
48+
49+
u32 gps_l2c_sv_capability;
50+
bool gps_l2c_sv_capability_upd_flag;
51+
} gps_l1ca_decoded_data_t;
52+
53+
4554
void nav_msg_init(nav_msg_t *n);
4655
s32 nav_msg_update(nav_msg_t *n, bool bit_val);
4756
bool subframe_ready(nav_msg_t *n);
48-
s8 process_subframe(nav_msg_t *n, ephemeris_t *e);
57+
s8 process_subframe(nav_msg_t *n, gnss_signal_t sid,
58+
gps_l1ca_decoded_data_t *data);
4959

5060
#endif /* LIBSWIFTNAV_NAV_MSG_H */

python/swiftnav/nav_msg.pxd

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,17 @@ cdef extern from "libswiftnav/nav_msg.h":
3030
u8 next_subframe_id
3131
s8 bit_polarity
3232

33+
ctypedef struct gps_l1ca_decoded_data_t:
34+
ephemeris_t ephemeris
35+
bool ephemeris_upd_flag
36+
u32 gps_l2c_sv_capability
37+
bool gps_l2c_sv_capability_upd_flag
38+
3339
void nav_msg_init(nav_msg_t *n)
3440
s32 nav_msg_update(nav_msg_t *n, bool bit_val)
3541
bool subframe_ready(nav_msg_t *n)
36-
s8 process_subframe(nav_msg_t *n, ephemeris_t *e)
42+
s8 process_subframe(nav_msg_t *n, gnss_signal_t sid,
43+
gps_l1ca_decoded_data_t *data)
3744

3845
cdef class NavMsg:
3946
cdef nav_msg_t _thisptr

python/swiftnav/nav_msg.pyx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,9 @@ cdef class NavMsg:
4040
def subframe_ready(self):
4141
return subframe_ready(&self._thisptr)
4242

43-
def process_subframe(self, e):
44-
cdef ephemeris_t tmp = e._thisptr
45-
return process_subframe(&self._thisptr, &tmp)
43+
def process_subframe(self, sid, d):
44+
cdef gps_l1ca_decoded_data_t tmp_d = d._thisptr
45+
return process_subframe(&self._thisptr, sid, &tmp_d)
4646

4747
def __richcmp__(self, other, op):
4848
"""

src/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ set(libswiftnav_SRCS
4545
signal.c
4646
ionosphere.c
4747
bit_sync.c
48+
l2c_capability.c
4849
cnav_msg.c
4950
nav_msg_glo.c
5051
${plover_SRCS}

src/ephemeris.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -596,7 +596,7 @@ u32 decode_fit_interval(u8 fit_interval_flag, u16 iodc) {
596596
* 1, 2 and 3. Word is in the 30 LSBs of the u32.
597597
* \param e Pointer to an ephemeris struct to fill in.
598598
*/
599-
void decode_ephemeris(u32 frame_words[3][8], ephemeris_t *e)
599+
void decode_ephemeris(u32 frame_words[4][8], ephemeris_t *e)
600600
{
601601
assert(frame_words != NULL);
602602
assert(e != NULL);

src/l2c_capability.c

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/*
2+
* Copyright (C) 2016 Swift Navigation Inc.
3+
* Contact: Dmitry Tatarinov <dmitry.tatarinov@exafore.com>
4+
*
5+
* This source is subject to the license found in the file 'LICENSE' which must
6+
* be be distributed together with this source. All other rights reserved.
7+
*
8+
* THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
9+
* EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
10+
* WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
11+
*/
12+
#include <stdio.h>
13+
#include <assert.h>
14+
15+
#include <libswiftnav/common.h>
16+
#include <libswiftnav/nav_msg.h>
17+
#include <libswiftnav/l2c_capability.h>
18+
19+
/** \defgroup l2c_capability L2C Capability
20+
* Functions used in l2c capability
21+
* \{ */
22+
23+
/** Decode L2C capability data from Nav message.
24+
* \param subframe4_words Array containing words 3 through 10
25+
* of subframe 4.
26+
* SV configuration data is in words 3 through 8
27+
* \param l2c_cpbl output Pointer to 32-bit L2C capability container
28+
*
29+
*/
30+
void decode_l2c_capability(const u32 *subframe4_words, u32 *l2c_cpbl)
31+
{
32+
assert(subframe4_words != NULL);
33+
assert(l2c_cpbl != NULL);
34+
35+
*l2c_cpbl = 0;
36+
37+
struct sv_conf_location {
38+
u8 n_sv; /* for how many SVs config data in the Word */
39+
u8 end_bit_n; /* position of MSB for the 1st SV in the Word */
40+
};
41+
42+
const struct sv_conf_location sv_conf_loc[6] = {
43+
{4,12},{6,4},{6,4},{6,4},{6,4},{4,4},
44+
};
45+
46+
u8 sv_id = 0;
47+
48+
/* go through words 3-8 */
49+
for (u8 i = 3; i <= 8; i++ ) {
50+
51+
/* go through all sv inside the word */
52+
for (u8 j = 0; j < sv_conf_loc[i-3].n_sv; j++ ) {
53+
/* get SV config bits take into account only 3 LSB */
54+
u8 sv_conf =
55+
subframe4_words[i-3] >> (30 - (sv_conf_loc[i-3].end_bit_n + j*4)) & 7;
56+
57+
/* set or clear appropriate capability bit,
58+
* refer pg. 115-116 of IS-200H for the criteria */
59+
if (2 == sv_conf || 3 == sv_conf || 4 == sv_conf)
60+
*l2c_cpbl |= (1 << sv_id);
61+
62+
sv_id++;
63+
}
64+
}
65+
}
66+
67+
/** \} */

src/nav_msg.c

Lines changed: 31 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include <libswiftnav/constants.h>
2121
#include <libswiftnav/bits.h>
2222
#include <libswiftnav/nav_msg.h>
23+
#include <libswiftnav/l2c_capability.h>
2324

2425
void nav_msg_init(nav_msg_t *n)
2526
{
@@ -222,16 +223,13 @@ static u8 nav_parity(u32 *word)
222223
bool subframe_ready(nav_msg_t *n) {
223224
return (n->subframe_start_index != 0);
224225
}
225-
226-
s8 process_subframe(nav_msg_t *n, ephemeris_t *e) {
226+
s8 process_subframe(nav_msg_t *n, gnss_signal_t sid,
227+
gps_l1ca_decoded_data_t *data)
228+
{
227229
// Check parity and parse out the ephemeris from the most recently received subframe
228230

229-
if (!e) {
230-
log_error("process_subframe: CALLED WITH e = NULL!");
231-
n->subframe_start_index = 0; // Mark the subframe as processed
232-
n->next_subframe_id = 1; // Make sure we start again next time
233-
return -1;
234-
}
231+
assert(data != NULL);
232+
memset(data, 0, sizeof(gps_l1ca_decoded_data_t));
235233

236234
// First things first - check the parity, and invert bits if necessary.
237235
// process the data, skipping the first word, TLM, and starting with HOW
@@ -242,40 +240,40 @@ s8 process_subframe(nav_msg_t *n, ephemeris_t *e) {
242240
BIT_POLARITY_INVERTED;
243241
if ((prev_bit_polarity != BIT_POLARITY_UNKNOWN)
244242
&& (prev_bit_polarity != n->bit_polarity)) {
245-
log_warn_sid(e->sid, "Nav phase flip - half cycle slip detected, "
243+
log_warn_sid(sid, "Nav phase flip - half cycle slip detected, "
246244
"but not corrected");
247245
/* TODO: declare phase ambiguity to IAR */
248246
}
249247

250248
/* Complain if buffer overrun */
251249
if (n->overrun) {
252-
log_error_sid(e->sid, "nav_msg subframe buffer overrun!");
250+
log_error_sid(sid, "nav_msg subframe buffer overrun!");
253251
n->overrun = false;
254252
}
255253

256254
/* Extract word 2, and the last two parity bits of word 1 */
257255
u32 sf_word2 = extract_word(n, 28, 32, 0);
258256
if (nav_parity(&sf_word2)) {
259-
log_info_sid(e->sid, "subframe parity mismatch (word 2)");
257+
log_info_sid(sid, "subframe parity mismatch (word 2)");
260258
n->subframe_start_index = 0; // Mark the subframe as processed
261259
n->next_subframe_id = 1; // Make sure we start again next time
262260
return -2;
263261
}
264262

265263
n->alert = sf_word2 >> 12 & 0x01; // Alert flag, bit 18
266264
if (n->alert) {
267-
log_warn_sid(e->sid, "alert flag set! Ignoring satellite.");
265+
log_warn_sid(sid, "alert flag set! Ignoring satellite.");
268266
}
269267

270268
u8 sf_id = sf_word2 >> 8 & 0x07; // Which of 5 possible subframes is it? bits 20-22
271269

272-
if (sf_id <= 3 && sf_id == n->next_subframe_id) { // Is it the one that we want next?
270+
if (sf_id <= 4 && sf_id == n->next_subframe_id) { // Is it the one that we want next?
273271

274272
for (int w = 0; w < 8; w++) { // For words 3..10
275273
n->frame_words[sf_id-1][w] = extract_word(n, 30*(w+2) - 2, 32, 0); // Get the bits
276274
// MSBs are D29* and D30*. LSBs are D1...D30
277275
if (nav_parity(&n->frame_words[sf_id-1][w])) { // Check parity and invert bits if D30*
278-
log_info_sid(e->sid, "subframe parity mismatch (word %d)", w+3);
276+
log_info_sid(sid, "subframe parity mismatch (word %d)", w+3);
279277
n->next_subframe_id = 1; // Make sure we start again next time
280278
n->subframe_start_index = 0; // Mark the subframe as processed
281279
return -3;
@@ -285,14 +283,30 @@ s8 process_subframe(nav_msg_t *n, ephemeris_t *e) {
285283
n->next_subframe_id++;
286284

287285
if (sf_id == 3) {
288-
// Got all of subframes 1 to 3
289-
n->next_subframe_id = 1; // Make sure we start again next time
290286

291287
// Now let's actually decode the ephemeris...
292-
decode_ephemeris(n->frame_words, e);
288+
data->ephemeris.sid = sid;
289+
decode_ephemeris(n->frame_words, &data->ephemeris);
290+
data->ephemeris_upd_flag = true;
293291

294292
return 1;
293+
}
294+
295+
if (4 == sf_id) { /* parse Subframe 4 */
296+
/* get words 3-8 from 25th page (SV config
297+
* bits) */
298+
299+
/* check Word 3 bits 2..7 (63..69) for Page ID, see IS-200H, pg. 84
300+
* Page 25 has ID 63, see IS-200H, pg. 109-110 */
301+
if ((n->frame_words[3][3-3] >> (30-8) & 0x3f) == 63) {
302+
decode_l2c_capability(n->frame_words[3], &(data->gps_l2c_sv_capability));
303+
data->gps_l2c_sv_capability_upd_flag = true;
304+
}
305+
306+
/* Got all of subframes 1 to 4 */
307+
n->next_subframe_id = 1; /* Make sure we start again next time */
295308

309+
return 1;
296310
}
297311
} else { // didn't get the subframe that we want next
298312
n->next_subframe_id = 1; // Make sure we start again next time

tests/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ else (CMAKE_CROSSCOMPILING)
4747
check_ionosphere.c
4848
check_signal.c
4949
check_track.c
50+
check_decode_l2c_capability.c
5051
check_cnav.c
5152
check_glo_decoder.c
5253
)

0 commit comments

Comments
 (0)