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