diff options
author | Eric S. Raymond <esr@thyrsus.com> | 2011-02-28 15:12:39 -0500 |
---|---|---|
committer | Eric S. Raymond <esr@thyrsus.com> | 2011-02-28 15:12:39 -0500 |
commit | 51bf98b8da22f882349ff5fc9c52ab157209e81a (patch) | |
tree | 45ef7d85a63adae14479a8ee44ab98827f365255 /driver_rtcm2.c | |
parent | 5d1d82a566d9c91c1495110e148cee519a6b72a2 (diff) | |
download | gpsd-51bf98b8da22f882349ff5fc9c52ab157209e81a.tar.gz |
Inline a header that is only used once. No code changes.
Diffstat (limited to 'driver_rtcm2.c')
-rw-r--r-- | driver_rtcm2.c | 443 |
1 files changed, 442 insertions, 1 deletions
diff --git a/driver_rtcm2.c b/driver_rtcm2.c index 2bb6a1f5..1d1be108 100644 --- a/driver_rtcm2.c +++ b/driver_rtcm2.c @@ -54,7 +54,448 @@ BSD terms apply: see the file COPYING in the distribution root for details. #include <string.h> #include "gpsd.h" -#include "driver_rtcm2.h" + +/* + * Structures for interpreting words in an RTCM-104 2.x message (after + * parity checking and removing inversion). Note, these structures + * are overlayed on the raw data in order to decode them into + * bitfields; this will fail horribly if your C compiler ever + * introduces padding between or before bit fields, or between + * 8-bit-aligned bitfields and character arrays. + * + * (In practice, the only class of machines on which this is likely + * to fail are word-aligned architectures without barrel shifters. + * Very few of these are left in 2008.) + * + * The RTCM 2.1 standard is less explicit than it should be about signed-integer + * representations. Two's complement is specified for prc and rrc (msg1wX), + * but not everywhere. + */ + +#define ZCOUNT_SCALE 0.6 /* sec */ +#define PCSMALL 0.02 /* meters */ +#define PCLARGE 0.32 /* meters */ +#define RRSMALL 0.002 /* meters/sec */ +#define RRLARGE 0.032 /* meters/sec */ + +#define MAXPCSMALL (0x7FFF * PCSMALL) /* 16-bits signed */ +#define MAXRRSMALL (0x7F * RRSMALL) /* 8-bits signed */ + +#define XYZ_SCALE 0.01 /* meters */ +#define DXYZ_SCALE 0.1 /* meters */ +#define LA_SCALE (90.0/32767.0) /* degrees */ +#define LO_SCALE (180.0/32767.0) /* degrees */ +#define FREQ_SCALE 0.1 /* kHz */ +#define FREQ_OFFSET 190.0 /* kHz */ +#define CNR_OFFSET 24 /* dB */ +#define TU_SCALE 5 /* minutes */ + +#pragma pack(1) + +#ifndef WORDS_BIGENDIAN /* little-endian, like x86 */ + +struct rtcm2_msg_t { + struct rtcm2_msghw1 { /* header word 1 */ + uint parity:6; + uint refstaid:10; /* reference station ID */ + uint msgtype:6; /* RTCM message type */ + uint preamble:8; /* fixed at 01100110 */ + uint _pad:2; + } w1; + + struct rtcm2_msghw2 { /* header word 2 */ + uint parity:6; + uint stathlth:3; /* station health */ + uint frmlen:5; + uint sqnum:3; + uint zcnt:13; + uint _pad:2; + } w2; + + union { + /* msg 1 - differential gps corrections */ + struct rtcm2_msg1 { + struct b_correction_t { + struct { /* msg 1 word 3 */ + uint parity:6; + int pc1:16; + uint satident1:5; /* satellite ID */ + uint udre1:2; + uint scale1:1; + uint _pad:2; + } w3; + + struct { /* msg 1 word 4 */ + uint parity:6; + uint satident2:5; /* satellite ID */ + uint udre2:2; + uint scale2:1; + uint issuedata1:8; + int rangerate1:8; + uint _pad:2; + } w4; + + struct { /* msg 1 word 5 */ + uint parity:6; + int rangerate2:8; + int pc2:16; + uint _pad:2; + } w5; + + struct { /* msg 1 word 6 */ + uint parity:6; + int pc3_h:8; + uint satident3:5; /* satellite ID */ + uint udre3:2; + uint scale3:1; + uint issuedata2:8; + uint _pad:2; + } w6; + + struct { /* msg 1 word 7 */ + uint parity:6; + uint issuedata3:8; + int rangerate3:8; + uint pc3_l:8; /* NOTE: uint for low byte */ + uint _pad:2; + } w7; + } corrections[(RTCM2_WORDS_MAX - 2) / 5]; + } type1; + + /* msg 3 - reference station parameters */ + struct rtcm2_msg3 { + struct { + uint parity:6; + uint x_h:24; + uint _pad:2; + } w3; + struct { + uint parity:6; + uint y_h:16; + uint x_l:8; + uint _pad:2; + } w4; + struct { + uint parity:6; + uint z_h:8; + uint y_l:16; + uint _pad:2; + } w5; + + struct { + uint parity:6; + uint z_l:24; + uint _pad:2; + } w6; + } type3; + + /* msg 4 - reference station datum */ + struct rtcm2_msg4 { + struct { + uint parity:6; + uint datum_alpha_char2:8; + uint datum_alpha_char1:8; + uint spare:4; + uint dat:1; + uint dgnss:3; + uint _pad:2; + } w3; + struct { + uint parity:6; + uint datum_sub_div_char2:8; + uint datum_sub_div_char1:8; + uint datum_sub_div_char3:8; + uint _pad:2; + } w4; + struct { + uint parity:6; + uint dy_h:8; + uint dx:16; + uint _pad:2; + } w5; + struct { + uint parity:6; + uint dz:24; + uint dy_l:8; + uint _pad:2; + } w6; + } type4; + + /* msg 5 - constellation health */ + struct rtcm2_msg5 { + struct b_health_t { + uint parity:6; + uint unassigned:2; + uint time_unhealthy:4; + uint loss_warn:1; + uint new_nav_data:1; + uint health_enable:1; + uint cn0:5; + uint data_health:3; + uint issue_of_data_link:1; + uint sat_id:5; + uint reserved:1; + uint _pad:2; + } health[MAXHEALTH]; + } type5; + + /* msg 6 - null message */ + + /* msg 7 - beacon almanac */ + struct rtcm2_msg7 { + struct b_station_t { + struct { + uint parity:6; + int lon_h:8; + int lat:16; + uint _pad:2; + } w3; + struct { + uint parity:6; + uint freq_h:6; + uint range:10; + uint lon_l:8; + uint _pad:2; + } w4; + struct { + uint parity:6; + uint encoding:1; + uint sync_type:1; + uint mod_mode:1; + uint bit_rate:3; + /* + * ITU-R M.823-2 page 9 and RTCM-SC104 v2.1 pages + * 4-21 and 4-22 are in conflict over the next two + * field sizes. ITU says 9+3, RTCM says 10+2. + * The latter correctly decodes the USCG station + * id's so I'll use that one here. -wsr + */ + uint station_id:10; + uint health:2; + uint freq_l:6; + uint _pad:2; + } w5; + } almanac[(RTCM2_WORDS_MAX - 2)/3]; + } type7; + + /* msg 16 - text msg */ + struct rtcm2_msg16 { + struct { + uint parity:6; + uint byte3:8; + uint byte2:8; + uint byte1:8; + uint _pad:2; + } txt[RTCM2_WORDS_MAX-2]; + } type16; + + /* unknown message */ + isgps30bits_t rtcm2_msgunk[RTCM2_WORDS_MAX-2]; + } msg_type; +}; + +#endif /* LITTLE_ENDIAN */ + +#ifdef WORDS_BIGENDIAN +/* This struct was generated from the above using invert-bitfields.pl */ +#ifndef S_SPLINT_S /* splint thinks it's a duplicate definition */ + +struct rtcm2_msg_t { + struct rtcm2_msghw1 { /* header word 1 */ + uint _pad:2; + uint preamble:8; /* fixed at 01100110 */ + uint msgtype:6; /* RTCM message type */ + uint refstaid:10; /* reference station ID */ + uint parity:6; + } w1; + + struct rtcm2_msghw2 { /* header word 2 */ + uint _pad:2; + uint zcnt:13; + uint sqnum:3; + uint frmlen:5; + uint stathlth:3; /* station health */ + uint parity:6; + } w2; + + union { + /* msg 1 - differential gps corrections */ + struct rtcm2_msg1 { + struct b_correction_t { + struct { /* msg 1 word 3 */ + uint _pad:2; + uint scale1:1; + uint udre1:2; + uint satident1:5; /* satellite ID */ + int pc1:16; + uint parity:6; + } w3; + + struct { /* msg 1 word 4 */ + uint _pad:2; + int rangerate1:8; + uint issuedata1:8; + uint scale2:1; + uint udre2:2; + uint satident2:5; /* satellite ID */ + uint parity:6; + } w4; + + struct { /* msg 1 word 5 */ + uint _pad:2; + int pc2:16; + int rangerate2:8; + uint parity:6; + } w5; + + struct { /* msg 1 word 6 */ + uint _pad:2; + uint issuedata2:8; + uint scale3:1; + uint udre3:2; + uint satident3:5; /* satellite ID */ + int pc3_h:8; + uint parity:6; + } w6; + + struct { /* msg 1 word 7 */ + uint _pad:2; + uint pc3_l:8; /* NOTE: uint for low byte */ + int rangerate3:8; + uint issuedata3:8; + uint parity:6; + } w7; + } corrections[(RTCM2_WORDS_MAX - 2) / 5]; + } type1; + + /* msg 3 - reference station parameters */ + struct rtcm2_msg3 { + struct { + uint _pad:2; + uint x_h:24; + uint parity:6; + } w3; + struct { + uint _pad:2; + uint x_l:8; + uint y_h:16; + uint parity:6; + } w4; + struct { + uint _pad:2; + uint y_l:16; + uint z_h:8; + uint parity:6; + } w5; + + struct { + uint _pad:2; + uint z_l:24; + uint parity:6; + } w6; + } type3; + + /* msg 4 - reference station datum */ + struct rtcm2_msg4 { + struct { + uint _pad:2; + uint dgnss:3; + uint dat:1; + uint spare:4; + uint datum_alpha_char1:8; + uint datum_alpha_char2:8; + uint parity:6; + } w3; + struct { + uint _pad:2; + uint datum_sub_div_char3:8; + uint datum_sub_div_char1:8; + uint datum_sub_div_char2:8; + uint parity:6; + } w4; + struct { + uint _pad:2; + uint dx:16; + uint dy_h:8; + uint parity:6; + } w5; + struct { + uint _pad:2; + uint dy_l:8; + uint dz:24; + uint parity:6; + } w6; + } type4; + + /* msg 5 - constellation health */ + struct rtcm2_msg5 { + struct b_health_t { + uint _pad:2; + uint reserved:1; + uint sat_id:5; + uint issue_of_data_link:1; + uint data_health:3; + uint cn0:5; + uint health_enable:1; + uint new_nav_data:1; + uint loss_warn:1; + uint time_unhealthy:4; + uint unassigned:2; + uint parity:6; + } health[MAXHEALTH]; + } type5; + + /* msg 6 - null message */ + + /* msg 7 - beacon almanac */ + struct rtcm2_msg7 { + struct b_station_t { + struct { + uint _pad:2; + int lat:16; + int lon_h:8; + uint parity:6; + } w3; + struct { + uint _pad:2; + uint lon_l:8; + uint range:10; + uint freq_h:6; + uint parity:6; + } w4; + struct { + uint _pad:2; + uint freq_l:6; + uint health:2; + uint station_id:10; + /* see comments in LE struct above. */ + uint bit_rate:3; + uint mod_mode:1; + uint sync_type:1; + uint encoding:1; + uint parity:6; + } w5; + } almanac[(RTCM2_WORDS_MAX - 2)/3]; + } type7; + + /* msg 16 - text msg */ + struct rtcm2_msg16 { + struct { + uint _pad:2; + uint byte1:8; + uint byte2:8; + uint byte3:8; + uint parity:6; + } txt[RTCM2_WORDS_MAX-2]; + } type16; + + /* unknown message */ + isgps30bits_t rtcm2_msgunk[RTCM2_WORDS_MAX-2]; + } msg_type; +}; + +#endif /* S_SPLINT_S */ +#endif /* BIG ENDIAN */ #ifdef RTCM104V2_ENABLE |