Home | History | Annotate | Line # | Download | only in include
      1 /*	$NetBSD: mbg_gps166.h,v 1.6 2020/05/25 20:47:19 christos Exp $	*/
      2 
      3 /*
      4  * /src/NTP/REPOSITORY/ntp4-dev/include/mbg_gps166.h,v 4.7 2006/06/22 18:41:43 kardel RELEASE_20060622_A
      5  *
      6  * mbg_gps166.h,v 4.7 2006/06/22 18:41:43 kardel RELEASE_20060622_A
      7  *
      8  * $Created: Sun Jul 20 09:20:50 1997 $
      9  *
     10  * File GPSSERIO.H Copyright (c) by Meinberg Funkuhren (www.meinberg.de)
     11  *
     12  * Linkage to PARSE:
     13  * Copyright (c) 1997-2005 by Frank Kardel <kardel <AT> ntp.org>
     14  *
     15  * Redistribution and use in source and binary forms, with or without
     16  * modification, are permitted provided that the following conditions
     17  * are met:
     18  * 1. Redistributions of source code must retain the above copyright
     19  *    notice, this list of conditions and the following disclaimer.
     20  * 2. Redistributions in binary form must reproduce the above copyright
     21  *    notice, this list of conditions and the following disclaimer in the
     22  *    documentation and/or other materials provided with the distribution.
     23  * 3. Neither the name of the author nor the names of its contributors
     24  *    may be used to endorse or promote products derived from this software
     25  *    without specific prior written permission.
     26  *
     27  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
     28  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     29  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     30  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
     31  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     32  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     33  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     34  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     35  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     36  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     37  * SUCH DAMAGE.
     38  *
     39  */
     40 #ifndef MBG_GPS166_H
     41 #define MBG_GPS166_H
     42 
     43 
     44 /***************************************************************************
     45  *
     46  *  Definitions taken from Meinberg's gpsserio.h and gpsdefs.h files.
     47  *
     48  *  Author:  Martin Burnicki, Meinberg Funkuhren
     49  *
     50  *  Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
     51  *
     52  *  Description:
     53  *    Structures and codes to be used to access Meinberg GPS clocks via
     54  *    their serial interface COM0. COM0 should be set to a high baud rate,
     55  *    default is 19200.
     56  *
     57  *    Standard Meinberg GPS serial operation is to send the Meinberg
     58  *    standard time string automatically once per second, once per
     59  *    minute, or on request per ASCII '?'.
     60  *
     61  *    GPS parameter setup or parameter readout uses blocks of binary
     62  *    data which have to be isolated from the standard string. A block
     63  *    of data starts with a SOH code (ASCII Start Of Header, 0x01)
     64  *    followed by a message header with constant length and a block of
     65  *    data with variable length.
     66  *
     67  *    The first field (cmd) of the message header holds the command
     68  *    code resp. the type of data to be transmitted. The next field (len)
     69  *    gives the number of data bytes that follow the header. This number
     70  *    ranges from 0 to sizeof( MSG_DATA ). The third field (data_csum)
     71  *    holds a checksum of all data bytes and the last field of the header
     72  *    finally holds the checksum of the header itself.
     73  *
     74  ***************************************************************************/
     75 
     76 /**
     77  * @brief GPS epoch bias from ordinary time_t epoch
     78  *
     79  * The Unix time_t epoch is usually 1970-01-01 00:00 whereas
     80  * the GPS epoch is 1980-01-06 00:00, so the difference is 10 years,
     81  * plus 2 days due to leap years (1972 and 1976), plus the difference
     82  * of the day-of-month (6 - 1), so:<br>
     83  *
     84  * time_t t = ( gps_week * ::SECS_PER_WEEK ) + sec_of_week + ::GPS_SEC_BIAS
     85  */
     86 #define GPS_SEC_BIAS   315964800UL     // ( ( ( 10UL * 365UL ) + 2 + 5 ) * SECS_PER_DAY )
     87 
     88 
     89 #ifndef _COM_HS_DEFINED
     90   /**
     91    * @brief Enumeration of handshake modes
     92    */
     93   enum COM_HANSHAKE_MODES { HS_NONE, HS_XONXOFF, HS_RTSCTS, N_COM_HS };
     94   #define _COM_HS_DEFINED
     95 #endif
     96 
     97 #ifndef _COM_PARM_DEFINED
     98   /**
     99    * @brief A data type to configure a serial port's baud rate
    100    *
    101    * @see ::MBG_BAUD_RATES
    102    */
    103   typedef int32_t BAUD_RATE;
    104 
    105   /**
    106    * @brief Indices used to identify a parameter in the framing string
    107    *
    108    * @see ::MBG_FRAMING_STRS
    109    */
    110   enum MBG_FRAMING_STR_IDXS { F_DBITS, F_PRTY, F_STBITS };
    111 
    112   /**
    113    * @brief A structure to store the configuration of a serial port
    114    */
    115   typedef struct
    116   {
    117     BAUD_RATE baud_rate;  ///< transmission speed, e.g. 19200L, see ::MBG_BAUD_RATES
    118     char framing[4];      ///< ASCIIZ framing string, e.g. "8N1" or "7E2", see ::MBG_FRAMING_STRS
    119     int16_t handshake;    ///< handshake mode, yet only ::HS_NONE supported
    120 
    121   } COM_PARM;
    122 
    123   #define _COM_PARM_DEFINED
    124 #endif
    125 
    126 
    127 /**
    128  * @brief Enumeration of modes supported for time string transmission
    129  *
    130  * This determines e.g. at which point in time a string starts
    131  * to be transmitted via the serial port.
    132  * Used with ::PORT_SETTINGS::mode.
    133  *
    134  * @see ::STR_MODE_MASKS
    135  */
    136 enum STR_MODES
    137 {
    138   STR_ON_REQ,     ///< transmission on request by received '?' character only
    139   STR_PER_SEC,    ///< transmission automatically if second changes
    140   STR_PER_MIN,    ///< transmission automatically if minute changes
    141   STR_AUTO,       ///< transmission automatically if required, e.g. on capture event
    142   STR_ON_REQ_SEC, ///< transmission if second changes and a request has been received before
    143   N_STR_MODE      ///< the number of known modes
    144 };
    145 
    146 
    147 /**
    148  * The number of serial ports which are at least available
    149  * even with very old GPS receiver models. For devices providing
    150  * a ::RECEIVER_INFO structure the number of provided COM ports
    151  * is available in ::RECEIVER_INFO::n_com_ports.
    152  */
    153 #define DEFAULT_N_COM   2
    154 
    155 
    156 /**
    157  * @brief A The structure used to store the configuration of two serial ports
    158  *
    159  * @deprecated This structure is deprecated, ::PORT_SETTINGS and related structures
    160  * should be used instead, if supported by the device.
    161  */
    162 typedef struct
    163 {
    164   COM_PARM com[DEFAULT_N_COM];    ///< COM0 and COM1 settings
    165   uint8_t mode[DEFAULT_N_COM];    ///< COM0 and COM1 output mode
    166 
    167 } PORT_PARM;
    168 
    169 
    170 /**
    171  * @brief The type of a GPS command code
    172  *
    173  * @see ::GPS_CMD_CODES
    174  */
    175 typedef uint16_t GPS_CMD;
    176 
    177 
    178 /**
    179  * @brief Control codes to be or'ed with a particular command/type code
    180  */
    181 enum GPS_CMD_CTRL_CODES
    182 {
    183   GPS_REQACK = 0x8000,   ///< to device: request acknowledge
    184   GPS_ACK    = 0x4000,   ///< from device: acknowledge a command
    185   GPS_NACK   = 0x2000,   ///< from device: error evaluating a command
    186 };
    187 
    188 #define GPS_CTRL_MSK  0xF000   ///< bit mask of all ::GPS_CMD_CTRL_CODES
    189 
    190 
    191 /**
    192  * @brief Command codes for the binary protocol
    193  *
    194  * These codes specify commands and associated data types used by Meinberg's
    195  * binary protocol to exchange data with a device via serial port, direct USB,
    196  * or socket I/O.
    197  *
    198  * Some commands and associated data structures can be read (r) from a device, others
    199  * can be written (w) to the device, and some can also be sent automatically (a) by
    200  * a device after a ::GPS_AUTO_ON command has been sent to the device.
    201  * The individual command codes are marked with (rwa) accordingly, where '-' is used
    202  * to indicate that a particular mode is not supported.
    203  *
    204  * @note Not all command code are supported by all devices.
    205  * See the hints for a particular command.
    206  *
    207  * @note If ::GPS_ALM, ::GPS_EPH or a code named ..._IDX is sent to retrieve
    208  * some data from a device then an uint16_t parameter must be also supplied
    209  * in order to specify the index number of the data set to be returned.
    210  * The valid index range depends on the command code.
    211  * For ::GPS_ALM and ::GPS_EPH the index is the SV number which may be 0 or
    212  * ::MIN_SVNO_GPS to ::MAX_SVNO_GPS. If the number is 0 then all ::N_SVNO_GPS
    213  * almanacs or ephemeris data structures are returned.
    214  *
    215  * @see ::GPS_CMD_CODES_TABLE
    216  */
    217 enum GPS_CMD_CODES
    218 { /* system data */
    219   GPS_AUTO_ON = 0x000,  ///< (-w-) no data, enable auto-msgs from device
    220   GPS_AUTO_OFF,         ///< (-w-) no data, disable auto-msgs from device
    221   GPS_SW_REV,           ///< (r--) deprecated, ::SW_REV, software revision, use only if ::GPS_RECEIVER_INFO not supp.
    222   GPS_BVAR_STAT,        ///< (r--) ::BVAR_STAT, status of buffered variables, only if ::GPS_MODEL_HAS_BVAR_STAT
    223   GPS_TIME,             ///< (-wa) ::TTM, current time or capture, or init board time
    224   GPS_POS_XYZ,          ///< (rw-) ::XYZ, current position in ECEF coordinates, only if ::GPS_MODEL_HAS_POS_XYZ
    225   GPS_POS_LLA,          ///< (rw-) ::LLA, current position in geographic coordinates, only if ::GPS_MODEL_HAS_POS_LLA
    226   GPS_TZDL,             ///< (rw-) ::TZDL, time zone / daylight saving, only if ::GPS_MODEL_HAS_TZDL
    227   GPS_PORT_PARM,        ///< (rw-) deprecated, ::PORT_PARM, use ::PORT_SETTINGS etc. if ::GPS_RECEIVER_INFO supported
    228   GPS_SYNTH,            ///< (rw-) ::SYNTH, synthesizer settings, only if ::GPS_HAS_SYNTH
    229   GPS_ANT_INFO,         ///< (r-a) ::ANT_INFO, time diff after antenna disconnect, only if ::GPS_MODEL_HAS_ANT_INFO
    230   GPS_UCAP,             ///< (r-a) ::TTM, user capture events, only if ::RECEIVER_INFO::n_ucaps > 0
    231 
    232   /* GPS data */
    233   GPS_CFGH = 0x100,     ///< (rw-) ::CFGH, SVs' configuration and health codes
    234   GPS_ALM,              ///< (rw-) req: uint16_t SV num, ::SV_ALM, one SV's almanac
    235   GPS_EPH,              ///< (rw-) req: uint16_t SV num, ::SV_EPH, one SV's ephemeris
    236   GPS_UTC,              ///< (rw-) ::UTC, GPS %UTC correction parameters
    237   GPS_IONO,             ///< (rw-) ::IONO, GPS ionospheric correction parameters
    238   GPS_ASCII_MSG         ///< (r--) ::ASCII_MSG, the GPS ASCII message
    239 };
    240 
    241 
    242 #ifndef _CSUM_DEFINED
    243   typedef uint16_t CSUM;  /* checksum used by some structures stored in non-volatile memory */
    244   #define _CSUM_DEFINED
    245 #endif
    246 
    247 
    248 /**
    249  * @brief The header of a binary message.
    250  */
    251 typedef struct
    252 {
    253   GPS_CMD cmd;      ///< see ::GPS_CMD_CODES
    254   uint16_t len;     ///< length of the data portion appended after the header
    255   CSUM data_csum;   ///< checksum of the data portion appended after the header
    256   CSUM hdr_csum;    ///< checksum of the preceding header bytes
    257 
    258 } GPS_MSG_HDR;
    259 
    260 
    261 #define GPS_ID_STR_LEN      16
    262 #define GPS_ID_STR_SIZE     ( GPS_ID_STR_LEN + 1 )
    263 
    264 /**
    265  * @brief Software revision information
    266  *
    267  * Contains a software revision code, plus an optional
    268  * identifier for a customized version.
    269  */
    270 typedef struct
    271 {
    272   uint16_t code;               ///< Version number, e.g. 0x0120 means v1.20
    273   char name[GPS_ID_STR_SIZE];  ///< Optional string identifying a customized version
    274   uint8_t reserved;            ///< Reserved field to yield even structure size
    275 
    276 } SW_REV;
    277 
    278 
    279 /**
    280  * @brief GNSS satellite numbers
    281  *
    282  * @todo: Check if MAX_SVNO_GLN is 94 instead of 95, and thus
    283  *        N_SVNO_GLN is 30 instead of 31, as reported by Wikipedia.
    284  */
    285 enum GNSS_SVNOS
    286 {
    287   MIN_SVNO_GPS = 1,       ///< min. GPS satellite PRN number
    288   MAX_SVNO_GPS = 32,      ///< max. GPS satellite PRN number
    289   N_SVNO_GPS = 32,        ///< max. number of active GPS satellites
    290 
    291   MIN_SVNO_WAAS = 33,     ///< min. WAAS satellite number
    292   MAX_SVNO_WAAS = 64,     ///< max. WAAS satellite number
    293   N_SVNO_WAAS = 32,       ///< max. number of active WAAS satellites
    294 
    295   MIN_SVNO_GLONASS = 65,  ///< min. Glonass satellite number (64 + sat slot ID)
    296   MAX_SVNO_GLONASS = 95,  ///< max. Glonass satellite number (64 + sat slot ID)
    297   N_SVNO_GLONASS = 31     ///< max. number of active Glonass satellites
    298 };
    299 
    300 
    301 typedef uint16_t SVNO;    ///< the number of an SV (Space Vehicle, i.e. satellite)
    302 typedef uint16_t HEALTH;  ///< an SV's 6 bit health code
    303 typedef uint16_t CFG;     ///< an SV's 4 bit configuration code
    304 typedef uint16_t IOD;     ///< Issue-Of-Data code
    305 
    306 
    307 /**
    308  * @brief Status flags of battery buffered data
    309  *
    310  * Related to data received from the satellites, or data derived thereof.
    311  *
    312  * All '0' means OK, single bits set to '1' indicate
    313  * the associated type of GPS data is not available.
    314  *
    315  * @see ::BVAR_FLAGS
    316  */
    317 typedef uint16_t BVAR_STAT;
    318 
    319 #define _mbg_swab_bvar_stat( _p )  _mbg_swab16( (_p) )
    320 
    321 
    322 /**
    323  * @brief Enumeration of flag bits used to define ::BVAR_FLAGS
    324  *
    325  * For each bit which is set this means the associated data set in
    326  * non-volatile memory is not available, or incomplete.
    327  * Most data sets will just be re-collected from the data streams sent
    328  * by the satellites. However, the receiver position has usually been
    329  * computed earlier during normal operation, and will be re-computed
    330  * when a sufficient number of satellites can be received.
    331  *
    332  * @see ::BVAR_STAT
    333  * @see ::BVAR_FLAGS
    334  * @see ::BVAR_FLAG_NAMES
    335  */
    336 enum BVAR_FLAG_BITS
    337 {
    338   BVAR_BIT_CFGH_INVALID,      ///< Satellite configuration and health parameters incomplete
    339   BVAR_BIT_ALM_NOT_COMPLETE,  ///< Almanac parameters incomplete
    340   BVAR_BIT_UTC_INVALID,       ///< %UTC offset parameters incomplete
    341   BVAR_BIT_IONO_INVALID,      ///< Ionospheric correction parameters incomplete
    342   BVAR_BIT_RCVR_POS_INVALID,  ///< No valid receiver position available
    343   N_BVAR_BIT                  ///< number of defined ::BVAR_STAT bits
    344 };
    345 
    346 
    347 /**
    348  * @brief Bit masks associated with ::BVAR_FLAG_BITS
    349  *
    350  * Used with ::BVAR_STAT.
    351  *
    352  * @see ::BVAR_STAT
    353  * @see ::BVAR_FLAG_BITS
    354  * @see ::BVAR_FLAG_NAMES
    355  */
    356 enum BVAR_FLAGS
    357 {
    358   BVAR_CFGH_INVALID     = ( 1UL << BVAR_BIT_CFGH_INVALID ),      ///< see ::BVAR_BIT_CFGH_INVALID
    359   BVAR_ALM_NOT_COMPLETE = ( 1UL << BVAR_BIT_ALM_NOT_COMPLETE ),  ///< see ::BVAR_BIT_ALM_NOT_COMPLETE
    360   BVAR_UTC_INVALID      = ( 1UL << BVAR_BIT_UTC_INVALID ),       ///< see ::BVAR_BIT_UTC_INVALID
    361   BVAR_IONO_INVALID     = ( 1UL << BVAR_BIT_IONO_INVALID ),      ///< see ::BVAR_BIT_IONO_INVALID
    362   BVAR_RCVR_POS_INVALID = ( 1UL << BVAR_BIT_RCVR_POS_INVALID ),  ///< see ::BVAR_BIT_RCVR_POS_INVALID
    363 };
    364 
    365 
    366 /**
    367  * @brief A structure used to hold time in GPS format
    368  *
    369  * Date and time refer to the linear time scale defined by GPS, with
    370  * the epoch starting at %UTC midnight at the beginning of January 6, 1980.
    371  *
    372  * GPS time is counted by the week numbers since the epoch, plus second
    373  * of the week, plus fraction of the second. The week number transmitted
    374  * by the satellites rolls over from 1023 to 0, but Meinberg devices
    375  * just continue to count the weeks beyond the 1024 week limit to keep
    376  * the receiver's internal time.
    377  *
    378  * %UTC time differs from GPS time since a number of leap seconds have
    379  * been inserted in the %UTC time scale after the GPS epoche. The number
    380  * of leap seconds is disseminated by the satellites using the ::UTC
    381  * parameter set, which also provides info on pending leap seconds.
    382  */
    383 typedef struct
    384 {
    385   uint16_t wn;     ///< the week number since GPS has been installed
    386   uint32_t sec;    ///< the second of that week
    387   uint32_t tick;   ///< fractions of a second, 1/::RECEIVER_INFO::ticks_per_sec units
    388 
    389 } T_GPS;
    390 
    391 
    392 /**
    393  * @brief Local date and time computed from GPS time
    394  *
    395  * The current number of leap seconds have to be added to get %UTC
    396  * from GPS time. Additional corrections could have been made according
    397  * to the time zone/daylight saving parameters ::TZDL defined by the user.
    398  * The status field can be checked to see which corrections
    399  * have actually been applied.
    400  *
    401  * @note Conversion from GPS time to %UTC and/or local time can only be
    402  * done if some valid ::UTC correction parameters are available in the
    403  * receiver's non-volatile memory.
    404  */
    405 typedef struct
    406 {
    407   int16_t year;           ///< year number, 0..9999
    408   int8_t month;           ///< month, 1..12
    409   int8_t mday;            ///< day of month, 1..31
    410   int16_t yday;           ///< day of year, 1..365, or 366 in case of leap year
    411   int8_t wday;            ///< day of week, 0..6 == Sun..Sat
    412   int8_t hour;            ///< hours, 0..23
    413   int8_t min;             ///< minutes, 0..59
    414   int8_t sec;             ///< seconds, 0..59, or 60 in case of inserted leap second
    415   int32_t frac;           ///< fractions of a second, 1/::RECEIVER_INFO::ticks_per_sec units
    416   int32_t offs_from_utc;  ///< local time offset from %UTC [sec]
    417   uint16_t status;        ///< status flags, see ::TM_GPS_STATUS_BIT_MASKS
    418 
    419 } TM_GPS;
    420 
    421 
    422 
    423 /**
    424  * @brief Status flag bits used to define ::TM_GPS_STATUS_BIT_MASKS
    425  *
    426  * These bits report info on the time conversion from GPS time to %UTC
    427  * and/or local time as well as device status info.
    428  *
    429  * @see ::TM_GPS_STATUS_BIT_MASKS
    430  */
    431 enum TM_GPS_STATUS_BITS
    432 {
    433   TM_BIT_UTC,          ///< %UTC correction has been made
    434   TM_BIT_LOCAL,        ///< %UTC has been converted to local time according to ::TZDL settings
    435   TM_BIT_DL_ANN,       ///< state of daylight saving is going to change
    436   TM_BIT_DL_ENB,       ///< daylight saving is in effect
    437   TM_BIT_LS_ANN,       ///< leap second pending
    438   TM_BIT_LS_ENB,       ///< current second is leap second
    439   TM_BIT_LS_ANN_NEG,   ///< set in addition to ::TM_BIT_LS_ANN if leap sec is negative
    440   TM_BIT_INVT,         ///< invalid time, e.g. if RTC battery bas been empty
    441 
    442   TM_BIT_EXT_SYNC,     ///< synchronized externally
    443   TM_BIT_HOLDOVER,     ///< in holdover mode after previous synchronization
    444   TM_BIT_ANT_SHORT,    ///< antenna cable short circuited
    445   TM_BIT_NO_WARM,      ///< OCXO has not warmed up
    446   TM_BIT_ANT_DISCONN,  ///< antenna currently disconnected
    447   TM_BIT_SYN_FLAG,     ///< TIME_SYN output is low
    448   TM_BIT_NO_SYNC,      ///< time sync actually not verified
    449   TM_BIT_NO_POS        ///< position actually not verified, LOCK LED off
    450 };
    451 
    452 
    453 /**
    454  * @brief Status flag masks used with ::TM_GPS::status
    455  *
    456  * These bits report info on the time conversion from GPS time to %UTC
    457  * and/or local time as well as device status info.
    458  *
    459  * @see ::TM_GPS_STATUS_BITS
    460  */
    461 enum TM_GPS_STATUS_BIT_MASKS
    462 {
    463   TM_UTC         = ( 1UL << TM_BIT_UTC ),          ///< see ::TM_BIT_UTC
    464   TM_LOCAL       = ( 1UL << TM_BIT_LOCAL ),        ///< see ::TM_BIT_LOCAL
    465   TM_DL_ANN      = ( 1UL << TM_BIT_DL_ANN ),       ///< see ::TM_BIT_DL_ANN
    466   TM_DL_ENB      = ( 1UL << TM_BIT_DL_ENB ),       ///< see ::TM_BIT_DL_ENB
    467   TM_LS_ANN      = ( 1UL << TM_BIT_LS_ANN ),       ///< see ::TM_BIT_LS_ANN
    468   TM_LS_ENB      = ( 1UL << TM_BIT_LS_ENB ),       ///< see ::TM_BIT_LS_ENB
    469   TM_LS_ANN_NEG  = ( 1UL << TM_BIT_LS_ANN_NEG ),   ///< see ::TM_BIT_LS_ANN_NEG
    470   TM_INVT        = ( 1UL << TM_BIT_INVT ),         ///< see ::TM_BIT_INVT
    471 
    472   TM_EXT_SYNC    = ( 1UL << TM_BIT_EXT_SYNC ),     ///< see ::TM_BIT_EXT_SYNC
    473   TM_HOLDOVER    = ( 1UL << TM_BIT_HOLDOVER ),     ///< see ::TM_BIT_HOLDOVER
    474   TM_ANT_SHORT   = ( 1UL << TM_BIT_ANT_SHORT ),    ///< see ::TM_BIT_ANT_SHORT
    475   TM_NO_WARM     = ( 1UL << TM_BIT_NO_WARM ),      ///< see ::TM_BIT_NO_WARM
    476   TM_ANT_DISCONN = ( 1UL << TM_BIT_ANT_DISCONN ),  ///< see ::TM_BIT_ANT_DISCONN
    477   TM_SYN_FLAG    = ( 1UL << TM_BIT_SYN_FLAG ),     ///< see ::TM_BIT_SYN_FLAG
    478   TM_NO_SYNC     = ( 1UL << TM_BIT_NO_SYNC ),      ///< see ::TM_BIT_NO_SYNC
    479   TM_NO_POS      = ( 1UL << TM_BIT_NO_POS )        ///< see ::TM_BIT_NO_POS
    480 };
    481 
    482 
    483 /**
    484  * @brief A structure used to transmit information on date and time
    485  *
    486  * This structure can be used to transfer the current time, in which
    487  * case the channel field has to be set to -1, or an event capture time
    488  * retrieved from the on-board FIFO, in which case the channel field
    489  * contains the index of the time capture input, e.g. 0 or 1.
    490  */
    491 typedef struct
    492 {
    493   int16_t channel;  ///< -1: the current on-board time; >= 0 the capture channel number
    494   T_GPS t;          ///< time in GPS scale and format
    495   TM_GPS tm;        ///< time converted to %UTC and/or local time according to ::TZDL settings
    496 
    497 } TTM;
    498 
    499 
    500 
    501 /* Two types of variables used to store a position. Type XYZ is */
    502 /* used with a position in earth centered, earth fixed (ECEF) */
    503 /* coordinates whereas type LLA holds such a position converted */
    504 /* to geographic coordinates as defined by WGS84 (World Geodetic */
    505 /* System from 1984). */
    506 
    507 /**
    508  * @brief Sequence and number of components of a cartesian position
    509  */
    510 enum XYZ_FIELDS { XP, YP, ZP, N_XYZ };  // x, y, z
    511 
    512 /**
    513  * @brief A position in cartesian coordinates
    514  *
    515  * Usually earth centered, earth fixed (ECEF) coordinates,
    516  * in [m].
    517  *
    518  * @note In the original code this is an array of double.
    519  *
    520  * @see ::XYZ_FIELDS
    521  */
    522 typedef l_fp XYZ[N_XYZ];
    523 
    524 
    525 /**
    526  * @brief Sequence and number of components of a geographic position
    527  */
    528 enum LLA_FIELDS { LAT, LON, ALT, N_LLA };  /* latitude, longitude, altitude */
    529 
    530 /**
    531  * @brief A geographic position based on latitude, longitude, and altitude
    532  *
    533  * The geographic position associated to specific cartesian coordinates
    534  * depends on the characteristics of the ellipsoid used for the computation,
    535  * the so-called geographic datum. GPS uses the WGS84 (World Geodetic System
    536  * from 1984) ellipsoid by default.
    537  *
    538  * lon, lat in [rad], alt in [m]
    539  *
    540  * @note In the original code this is an array of double.
    541  *
    542  * @see ::LLA_FIELDS
    543  */
    544 typedef l_fp LLA[N_LLA];
    545 
    546 
    547 /**
    548  * @defgroup group_synth Synthesizer parameters
    549  *
    550  * Synthesizer frequency is expressed as a
    551  * four digit decimal number (freq) to be multiplied by 0.1 Hz and an
    552  * base 10 exponent (range). If the effective frequency is less than
    553  * 10 kHz its phase is synchronized corresponding to the variable phase.
    554  * Phase may be in a range from -360 deg to +360 deg with a resolution
    555  * of 0.1 deg, so the resulting numbers to be stored are in a range of
    556  * -3600 to +3600.
    557  *
    558  * Example:<br>
    559  * Assume the value of freq is 2345 (decimal) and the value of phase is 900.
    560  * If range == 0 the effective frequency is 234.5 Hz with a phase of +90 deg.
    561  * If range == 1 the synthesizer will generate a 2345 Hz output frequency
    562  * and so on.
    563  *
    564  * Limitations:<br>
    565  * If freq == 0 the synthesizer is disabled. If range == 0 the least
    566  * significant digit of freq is limited to 0, 3, 5 or 6. The resulting
    567  * frequency is shown in the examples below:
    568  *    - freq == 1230  -->  123.0 Hz
    569  *    - freq == 1233  -->  123 1/3 Hz (real 1/3 Hz, NOT 123.3 Hz)
    570  *    - freq == 1235  -->  123.5 Hz
    571  *    - freq == 1236  -->  123 2/3 Hz (real 2/3 Hz, NOT 123.6 Hz)
    572  *
    573  * If range == ::MAX_SYNTH_RANGE the value of freq must not exceed 1000, so
    574  * the output frequency is limited to 10 MHz (see ::MAX_SYNTH_FREQ_VAL).
    575  *
    576  * @{ */
    577 
    578 #define N_SYNTH_FREQ_DIGIT  4    ///< number of digits to edit
    579 #define MAX_SYNTH_FREQ   1000    ///< if range == ::MAX_SYNTH_RANGE
    580 
    581 #define MIN_SYNTH_RANGE     0
    582 #define MAX_SYNTH_RANGE     5
    583 #define N_SYNTH_RANGE       ( MAX_SYNTH_RANGE - MIN_SYNTH_RANGE + 1 )
    584 
    585 #define N_SYNTH_PHASE_DIGIT  4
    586 #define MAX_SYNTH_PHASE      3600
    587 
    588 
    589 #define MAX_SYNTH_FREQ_EDIT  9999  ///< max sequence of digits when editing
    590 
    591 
    592 /**
    593  * @brief The maximum frequency that can be configured for the synthesizer
    594  */
    595 #define MAX_SYNTH_FREQ_VAL   10000000UL     ///< 10 MHz
    596 /*   == MAX_SYNTH_FREQ * 10^(MAX_SYNTH_RANGE-1) */
    597 
    598 /**
    599  * @brief The synthesizer's phase is only be synchronized if the frequency is below this limit
    600  */
    601 #define SYNTH_PHASE_SYNC_LIMIT   10000UL    ///< 10 kHz
    602 
    603 /**
    604  * A Macro used to determine the position of the decimal point
    605  * when printing the synthesizer frequency as 4 digit value
    606  */
    607 #define _synth_dp_pos_from_range( _r ) \
    608   ( ( ( N_SYNTH_RANGE - (_r) ) % ( N_SYNTH_FREQ_DIGIT - 1 ) ) + 1 )
    609 
    610 /**
    611  * @brief Synthesizer frequency units
    612  *
    613  * An initializer for commonly displayed synthesizer frequency units
    614  * (::N_SYNTH_RANGE strings)
    615  */
    616 #define DEFAULT_FREQ_RANGES \
    617 {                           \
    618   "Hz",                     \
    619   "kHz",                    \
    620   "kHz",                    \
    621   "kHz",                    \
    622   "MHz",                    \
    623   "MHz",                    \
    624 }
    625 
    626 
    627 
    628 /**
    629  * @brief Synthesizer configuration parameters
    630  */
    631 typedef struct
    632 {
    633   int16_t freq;    ///< four digits used; scale: 0.1 Hz; e.g. 1234 -> 123.4 Hz
    634   int16_t range;   ///< scale factor for freq; 0..::MAX_SYNTH_RANGE
    635   int16_t phase;   ///< -::MAX_SYNTH_PHASE..+::MAX_SYNTH_PHASE; >0 -> pulses later
    636 
    637 } SYNTH;
    638 
    639 #define _mbg_swab_synth( _p )   \
    640 {                               \
    641   _mbg_swab16( &(_p)->freq );   \
    642   _mbg_swab16( &(_p)->range );  \
    643   _mbg_swab16( &(_p)->phase );  \
    644 }
    645 
    646 
    647 /**
    648  * @brief Enumeration of synthesizer states
    649  */
    650 enum SYNTH_STATES
    651 {
    652   SYNTH_DISABLED,   ///< disbled by cfg, i.e. freq == 0.0
    653   SYNTH_OFF,        ///< not enabled after power-up
    654   SYNTH_FREE,       ///< enabled, but not synchronized
    655   SYNTH_DRIFTING,   ///< has initially been sync'd, but now running free
    656   SYNTH_SYNC,       ///< fully synchronized
    657   N_SYNTH_STATE     ///< the number of known states
    658 };
    659 
    660 
    661 /**
    662  * @brief A structure used to report the synthesizer state
    663  */
    664 typedef struct
    665 {
    666   uint8_t state;     ///< state code as enumerated in ::SYNTH_STATES
    667   uint8_t flags;     ///< reserved, currently always 0
    668 
    669 } SYNTH_STATE;
    670 
    671 #define _mbg_swab_synth_state( _p )  _nop_macro_fnc()
    672 
    673 #define SYNTH_FLAG_PHASE_IGNORED  0x01
    674 
    675 /** @} defgroup group_synth */
    676 
    677 
    678 
    679 /**
    680  * @defgroup group_tzdl Time zone / daylight saving parameters
    681  *
    682  * Example: <br>
    683  * For automatic daylight saving enable/disable in Central Europe,
    684  * the variables are to be set as shown below: <br>
    685  *   - offs = 3600L           one hour from %UTC
    686  *   - offs_dl = 3600L        one additional hour if daylight saving enabled
    687  *   - tm_on = first Sunday from March 25, 02:00:00h ( year |= ::DL_AUTO_FLAG )
    688  *   - tm_off = first Sunday from October 25, 03:00:00h ( year |= ::DL_AUTO_FLAG )
    689  *   - name[0] == "CET  "     name if daylight saving not enabled
    690  *   - name[1] == "CEST "     name if daylight saving is enabled
    691  *
    692  * @{ */
    693 
    694 /**
    695  * @brief The name of a time zone
    696  *
    697  * @note Up to 5 printable characters, plus trailing zero
    698  */
    699 typedef char TZ_NAME[6];
    700 
    701 /**
    702  * @brief Time zone / daylight saving parameters
    703  *
    704  * This structure is used to specify how a device converts on-board %UTC
    705  * to local time, including computation of beginning and end of daylight
    706  * saving time (DST), if required.
    707  *
    708  * @note The ::TZDL structure contains members of type ::TM_GPS to specify
    709  * the times for beginning and end of DST. However, the ::TM_GPS::frac,
    710  * ::TM_GPS::offs_from_utc, and ::TM_GPS::status fields of these ::TZDL::tm_on
    711  * and ::TZDL::tm_off members are ignored for the conversion to local time,
    712  * and thus should be 0.
    713  */
    714 typedef struct
    715 {
    716   int32_t offs;      ///< standard offset from %UTC to local time [sec]
    717   int32_t offs_dl;   ///< additional offset if daylight saving enabled [sec]
    718   TM_GPS tm_on;      ///< date/time when daylight saving starts
    719   TM_GPS tm_off;     ///< date/time when daylight saving ends
    720   TZ_NAME name[2];   ///< names without and with daylight saving enabled
    721 
    722 } TZDL;
    723 
    724 /**
    725  * @brief A flag indicating automatic computation of DST
    726  *
    727  * If this flag is or'ed to the year numbers in ::TZDL::tm_on and ::TZDL::tm_off
    728  * then daylight saving is computed automatically year by year.
    729  */
    730 #define DL_AUTO_FLAG  0x8000
    731 
    732 /** @} defgroup group_tzdl */
    733 
    734 
    735 
    736 /**
    737  * @brief Antenna status and error at reconnect information
    738  *
    739  * The structure below reflects the status of the antenna,
    740  * the times of last disconnect/reconnect, and the board's
    741  * clock offset when it has synchronized again after the
    742  * disconnection interval.
    743  *
    744  * @note ::ANT_INFO::status changes back to ::ANT_RECONN only
    745  * after the antenna has been reconnected <b>and</b> the
    746  * receiver has re-synchronized to the satellite signal.
    747  * In this case ::ANT_INFO::delta_t reports the time offset
    748  * before resynchronization, i.e. how much the internal
    749  * time has drifted while the antenna was disconnected.
    750  */
    751 typedef struct
    752 {
    753   int16_t status;      ///< current status of antenna, see ::ANT_STATUS_CODES
    754   TM_GPS tm_disconn;   ///< time of antenna disconnect
    755   TM_GPS tm_reconn;    ///< time of antenna reconnect
    756   int32_t delta_t;     ///< clock offs at reconn. time in 1/::RECEIVER_INFO::ticks_per_sec units
    757 
    758 } ANT_INFO;
    759 
    760 
    761 /**
    762  * @brief Status code used with ::ANT_INFO::status
    763  */
    764 enum ANT_STATUS_CODES
    765 {
    766   ANT_INVALID,   ///< No other fields valid since antenna has not yet been disconnected
    767   ANT_DISCONN,   ///< Antenna is disconnected, tm_reconn and delta_t not yet set
    768   ANT_RECONN,    ///< Antenna has been disconnect, and receiver sync. after reconnect, so all fields valid
    769   N_ANT_STATUS_CODES  ///< the number of known status codes
    770 };
    771 
    772 
    773 
    774 /**
    775  * @brief Summary of configuration and health data of all satellites
    776  */
    777 typedef struct
    778 {
    779   CSUM csum;                  ///< checksum of the remaining bytes
    780   int16_t valid;              ///< flag data are valid
    781 
    782   T_GPS tot_51;               ///< time of transmission, page 51
    783   T_GPS tot_63;               ///< time of transmission, page 63
    784   T_GPS t0a;                  ///< complete reference time almanac
    785 
    786   CFG cfg[N_SVNO_GPS];        ///< 4 bit SV configuration code from page 63
    787   HEALTH health[N_SVNO_GPS];  ///< 6 bit SV health codes from pages 51, 63
    788 
    789 } CFGH;
    790 
    791 
    792 
    793 /**
    794  * @brief GPS %UTC correction parameters
    795  *
    796  * %UTC correction parameters basically as sent by the GPS satellites.
    797  *
    798  * The csum field is only used by the card's firmware to check the
    799  * consistency of the structure in non-volatile memory.
    800  *
    801  * The field labeled valid indicates if the parameter set is valid, i.e.
    802  * if it contains data received from the satellites.
    803  *
    804  * t0t, A0 and A1 contain fractional correction parameters for the current
    805  * GPS-%UTC time offset in addition to the whole seconds. This is evaluated
    806  * by the receivers' firmware to convert GPS time to %UTC time.
    807  *
    808  * The delta_tls field contains the current full seconds offset between
    809  * GPS time and %UTC, which corresponds to the number of leap seconds inserted
    810  * into the %UTC time scale since GPS was put into operation in January 1980.
    811  *
    812  * delta_tlfs holds the number of "future" leap seconds, i.e. the %UTC offset
    813  * after the next leap second event defined by WNlsf and DNt.
    814  *
    815  * The fields WNlsf and DNt specify the GPS week number and the day number
    816  * in that week for the end of which a leap second has been scheduled.
    817  *
    818  * @note: The satellites transmit WNlsf only as a signed 8 bit value, so it
    819  * can only define a point in time which is +/- 127 weeks off the current time.
    820  * The firmware tries to expand this based on the current week number, but
    821  * the result is ambiguous if the leap second occurs or occurred more
    822  * than 127 weeks in the future or past.
    823  *
    824  * So the leap second date should <b>only</b> be evaluated and displayed
    825  * in a user interface if the fields delta_tls and delta_tlsf have
    826  * different values, in which case there is indeed a leap second announcement
    827  * inside the +/- 127 week range.
    828  *
    829  * @note In the original code the type of A0 and A1 is double.
    830  */
    831 typedef struct
    832 {
    833   CSUM csum;          ///<  Checksum of the remaining bytes
    834   int16_t valid;      ///<  Flag indicating %UTC parameters are valid
    835 
    836   T_GPS t0t;          ///<  Reference Time %UTC Parameters [wn|sec]
    837   l_fp A0;            ///<  +- Clock Correction Coefficient 0 [sec]
    838   l_fp A1;            ///<  +- Clock Correction Coefficient 1 [sec/sec]
    839 
    840   uint16_t WNlsf;     ///<  Week number of nearest leap second
    841   int16_t DNt;        ///<  The day number at the end of which a leap second occurs
    842   int8_t delta_tls;   ///<  Current %UTC offset to GPS system time [sec]
    843   int8_t delta_tlsf;  ///<  Future %UTC offset to GPS system time after next leap second transition [sec]
    844 
    845 } UTC;
    846 
    847 
    848 /**
    849  * @brief GPS ASCII message
    850  */
    851 typedef struct
    852 {
    853   CSUM csum;       ///< checksum of the remaining bytes */
    854   int16_t valid;   ///< flag data are valid
    855   char s[23];      ///< 22 chars GPS ASCII message plus trailing zero
    856 
    857 } ASCII_MSG;
    858 
    859 
    860 /**
    861  * @brief Ephemeris parameters of one specific satellite
    862  *
    863  * Needed to compute the position of a satellite at a given time with
    864  * high precision. Valid for an interval of 4 to 6 hours from start
    865  * of transmission.
    866  */
    867 typedef struct
    868 {
    869   CSUM csum;       ///<    checksum of the remaining bytes
    870   int16_t valid;   ///<    flag data are valid
    871 
    872   HEALTH health;   ///<    health indication of transmitting SV      [---]
    873   IOD IODC;        ///<    Issue Of Data, Clock
    874   IOD IODE2;       ///<    Issue of Data, Ephemeris (Subframe 2)
    875   IOD IODE3;       ///<    Issue of Data, Ephemeris (Subframe 3)
    876   T_GPS tt;        ///<    time of transmission
    877   T_GPS t0c;       ///<    Reference Time Clock                      [---]
    878   T_GPS t0e;       ///<    Reference Time Ephemeris                  [---]
    879 
    880   l_fp sqrt_A;     ///<    Square Root of semi-major Axis        [sqrt(m)]
    881   l_fp e;          ///<    Eccentricity                              [---]
    882   l_fp M0;         ///< +- Mean Anomaly at Ref. Time                 [rad]
    883   l_fp omega;      ///< +- Argument of Perigee                       [rad]
    884   l_fp OMEGA0;     ///< +- Longit. of Asc. Node of orbit plane       [rad]
    885   l_fp OMEGADOT;   ///< +- Rate of Right Ascension               [rad/sec]
    886   l_fp deltan;     ///< +- Mean Motion Diff. from computed value [rad/sec]
    887   l_fp i0;         ///< +- Inclination Angle                         [rad]
    888   l_fp idot;       ///< +- Rate of Inclination Angle             [rad/sec]
    889   l_fp crc;        ///< +- Cosine Corr. Term to Orbit Radius           [m]
    890   l_fp crs;        ///< +- Sine Corr. Term to Orbit Radius             [m]
    891   l_fp cuc;        ///< +- Cosine Corr. Term to Arg. of Latitude     [rad]
    892   l_fp cus;        ///< +- Sine Corr. Term to Arg. of Latitude       [rad]
    893   l_fp cic;        ///< +- Cosine Corr. Term to Inclination Angle    [rad]
    894   l_fp cis;        ///< +- Sine Corr. Term to Inclination Angle      [rad]
    895 
    896   l_fp af0;        ///< +- Clock Correction Coefficient 0            [sec]
    897   l_fp af1;        ///< +- Clock Correction Coefficient 1        [sec/sec]
    898   l_fp af2;        ///< +- Clock Correction Coefficient 2      [sec/sec^2]
    899   l_fp tgd;        ///< +- estimated group delay differential        [sec]
    900 
    901   uint16_t URA;    ///<    predicted User Range Accuracy
    902 
    903   uint8_t L2code;  ///<    code on L2 channel                         [---]
    904   uint8_t L2flag;  ///<    L2 P data flag                             [---]
    905 
    906 } EPH;
    907 
    908 
    909 
    910 /**
    911  * @brief Almanac parameters of one specific satellite
    912  *
    913  * A reduced precision set of parameters used to check if a satellite
    914  * is in view at a given time. Valid for an interval of more than 7 days
    915  * from start of transmission.
    916  */
    917 typedef struct
    918 {
    919   CSUM csum;       ///<    checksum of the remaining bytes
    920   int16_t valid;   ///<    flag data are valid
    921 
    922   HEALTH health;   ///<                                               [---]
    923   T_GPS t0a;       ///<    Reference Time Almanac                     [sec]
    924 
    925   l_fp sqrt_A;     ///<    Square Root of semi-major Axis         [sqrt(m)]
    926   l_fp e;          ///<    Eccentricity                               [---]
    927 
    928   l_fp M0;         ///< +- Mean Anomaly at Ref. Time                  [rad]
    929   l_fp omega;      ///< +- Argument of Perigee                        [rad]
    930   l_fp OMEGA0;     ///< +- Longit. of Asc. Node of orbit plane        [rad]
    931   l_fp OMEGADOT;   ///< +- Rate of Right Ascension                [rad/sec]
    932   l_fp deltai;     ///< +-                                            [rad]
    933   l_fp af0;        ///< +- Clock Correction Coefficient 0             [sec]
    934   l_fp af1;        ///< +- Clock Correction Coefficient 1         [sec/sec]
    935 
    936 } ALM;
    937 
    938 
    939 
    940 /**
    941  * @brief Ionospheric correction parameters
    942  */
    943 typedef struct
    944 {
    945   CSUM csum;       ///<    checksum of the remaining bytes
    946   int16_t valid;   ///<    flag data are valid
    947 
    948   l_fp alpha_0;    ///<    Ionosph. Corr. Coeff. Alpha 0              [sec]
    949   l_fp alpha_1;    ///<    Ionosph. Corr. Coeff. Alpha 1          [sec/deg]
    950   l_fp alpha_2;    ///<    Ionosph. Corr. Coeff. Alpha 2        [sec/deg^2]
    951   l_fp alpha_3;    ///<    Ionosph. Corr. Coeff. Alpha 3        [sec/deg^3]
    952 
    953   l_fp beta_0;     ///<    Ionosph. Corr. Coeff. Beta 0               [sec]
    954   l_fp beta_1;     ///<    Ionosph. Corr. Coeff. Beta 1           [sec/deg]
    955   l_fp beta_2;     ///<    Ionosph. Corr. Coeff. Beta 2         [sec/deg^2]
    956   l_fp beta_3;     ///<    Ionosph. Corr. Coeff. Beta 3         [sec/deg^3]
    957 
    958 } IONO;
    959 
    960 
    961 
    962 void mbg_tm_str (char **, TM_GPS *, int, int);
    963 void mbg_tgps_str (char **, T_GPS *, int);
    964 void get_mbg_header (unsigned char **, GPS_MSG_HDR *);
    965 void put_mbg_header (unsigned char **, GPS_MSG_HDR *);
    966 void get_mbg_sw_rev (unsigned char **, SW_REV *);
    967 void get_mbg_ascii_msg (unsigned char **, ASCII_MSG *);
    968 void get_mbg_svno (unsigned char **, SVNO *);
    969 void get_mbg_health (unsigned char **, HEALTH *);
    970 void get_mbg_cfg (unsigned char **, CFG *);
    971 void get_mbg_tgps (unsigned char **, T_GPS *);
    972 void get_mbg_tm (unsigned char **, TM_GPS *);
    973 void get_mbg_ttm (unsigned char **, TTM *);
    974 void get_mbg_synth (unsigned char **, SYNTH *);
    975 void get_mbg_tzdl (unsigned char **, TZDL *);
    976 void get_mbg_antinfo (unsigned char **, ANT_INFO *);
    977 void get_mbg_cfgh (unsigned char **, CFGH *);
    978 void get_mbg_utc (unsigned char **, UTC *);
    979 void get_mbg_lla (unsigned char **, LLA);
    980 void get_mbg_xyz (unsigned char **, XYZ);
    981 void get_mbg_portparam (unsigned char **, PORT_PARM *);
    982 void get_mbg_eph (unsigned char **, EPH *);
    983 void get_mbg_alm (unsigned char **, ALM *);
    984 void get_mbg_iono (unsigned char **, IONO *);
    985 
    986 CSUM mbg_csum (unsigned char *, unsigned int);
    987 
    988 #endif
    989 /*
    990  * History:
    991  *
    992  * mbg_gps166.h,v
    993  * Revision 4.7  2006/06/22 18:41:43  kardel
    994  * clean up signedness (gcc 4)
    995  *
    996  * Revision 4.6  2005/10/07 22:11:56  kardel
    997  * bounded buffer implementation
    998  *
    999  * Revision 4.5.2.1  2005/09/25 10:23:48  kardel
   1000  * support bounded buffers
   1001  *
   1002  * Revision 4.5  2005/06/25 10:58:45  kardel
   1003  * add missing log keywords
   1004  *
   1005  * Revision 4.1  1998/06/12 15:07:30  kardel
   1006  * fixed prototyping
   1007  *
   1008  * Revision 4.0  1998/04/10 19:50:42  kardel
   1009  * Start 4.0 release version numbering
   1010  *
   1011  * Revision 1.1  1998/04/10 19:27:34  kardel
   1012  * initial NTP VERSION 4 integration of PARSE with GPS166 binary support
   1013  *
   1014  * Revision 1.1  1997/10/06 20:55:38  kardel
   1015  * new parse structure
   1016  *
   1017  */
   1018