📄 sirf.c
字号:
gpsd_hexdump(buf, len)); (void)snprintf(session->gpsdata.tag, sizeof(session->gpsdata.tag), "MID%d",(int)buf[0]); switch (buf[0]) { case 0x02: /* Measure Navigation Data Out */ return sirf_msg_navsol(session, buf, len); case 0x04: /* Measured tracker data out */ return sirf_msg_svinfo(session, buf, len); case 0x05: /* Raw Tracker Data Out */ return 0; case 0x06: /* Software Version String */ return sirf_msg_swversion(session, buf, len); case 0x07: /* Clock Status Data */ gpsd_report(LOG_PROG, "CLK 0x07\n"); return 0; case 0x08: /* subframe data -- extract leap-second from this */ /* * Chris Kuethe says: * "Message 8 is generated as the data is received. It is not * buffered on the chip. So when you enable message 8, you'll * get one subframe every 6 seconds. Of the data received, the * almanac and ephemeris are buffered and stored, so you can * query them at will. Alas, the time parameters are not * stored, which is really lame, as the UTC-GPS correction * changes 1 second every few years. Maybe." */ return sirf_msg_navdata(session, buf, len); case 0x09: /* CPU Throughput */ gpsd_report(LOG_PROG, "THR 0x09: SegStatMax=%.3f, SegStatLat=%3.f, AveTrkTime=%.3f, Last MS=%3.f\n", (float)getuw(buf, 1)/186, (float)getuw(buf, 3)/186, (float)getuw(buf, 5)/186, getuw(buf, 7)); return 0; case 0x0a: /* Error ID Data */ return sirf_msg_errors(buf, len); case 0x0b: /* Command Acknowledgement */ gpsd_report(LOG_PROG, "ACK 0x0b: %02x\n",getub(buf, 1)); return 0; case 0x0c: /* Command NAcknowledgement */ gpsd_report(LOG_PROG, "NAK 0x0c: %02x\n",getub(buf, 1)); return 0; case 0x0d: /* Visible List */ gpsd_report(LOG_PROG, "VIS 0x0d\n"); return 0; case 0x0e: /* Almanac Data */ gpsd_report(LOG_PROG, "ALM 0x0e: %s\n", gpsd_hexdump(buf, len)); return 0; case 0x0f: /* Ephemeris Data */ gpsd_report(LOG_PROG, "EPH 0x0f: %s\n", gpsd_hexdump(buf, len)); return 0; case 0x11: /* Differential Corrections */ gpsd_report(LOG_PROG, "DIFF 0x11: %s\n", gpsd_hexdump(buf, len)); return 0; case 0x12: /* OK To Send */ gpsd_report(LOG_PROG, "OTS 0x12: send indicator = %d\n",getub(buf, 1)); return 0;#ifdef ALLOW_RECONFIGURE case 0x13: /* Navigation Parameters */ return sirf_msg_sysparam(session, buf, len);#endif /* ALLOW_RECONFIGURE */ case 0x1b: /* DGPS status (undocumented) */ /****************************************************************** Not actually documented in any published materials. Here is what Chris Kuethe got from the SiRF folks, (plus some corrections from the GpsPaSsion forums): Start of message ---------------- Message ID 1 byte 27 Correction Source 1 byte 0=None, 1=SBAS, 2=Serial, 3=Beacon, 4=Software total: 2 bytes Middle part of message varies if using beacon or other: ------------------------------------------------------- If Beacon: Receiver Freq Hz 4 bytes Bit rate BPS 1 byte Status bit map 1 byte 01=Signal Valid, 02=Auto frequency detect 04=Auto bit rate detect Signal Magnitude 4 bytes Note: in internal units Signal Strength dB 2 bytes derived from Signal Magnitude SNR dB 2 bytes total: 14 bytes If Not Beacon: Correction Age[12] 1 byte x 12 Age in seconds in same order as follows Reserved 2 bytes total: 14 bytes End of Message -------------- Repeated 12 times (pad with 0 if less than 12 SV corrections): SVID 1 byte Correction (cm) 2 bytes (signed short) total 3 x 12 = 36 bytes ******************************************************************/ return 0; case 0x1c: /* Navigation Library Measurement Data */ gpsd_report(LOG_PROG, "NLMD 0x1c: %s\n", gpsd_hexdump(buf, len)); return 0; case 0x1d: /* Navigation Library DGPS Data */ gpsd_report(LOG_PROG, "NLDG 0x1d: %s\n", gpsd_hexdump(buf, len)); return 0; case 0x1e: /* Navigation Library SV State Data */ gpsd_report(LOG_PROG, "NLSV 0x1e: %s\n", gpsd_hexdump(buf, len)); return 0; case 0x1f: /* Navigation Library Initialization Data */ gpsd_report(LOG_PROG, "NLID 0x1f: %s\n", gpsd_hexdump(buf, len)); return 0; case 0x29: /* Geodetic Navigation Information */ return sirf_msg_geodetic(session, buf, len); case 0x32: /* SBAS corrections */ return 0; case 0x34: /* PPS Time */ /* * Carl Carter from SiRF writes: "We do not output on the * second (unless you are using message ID 52). We make * measurements in the receiver in time with an internal * counter that is not slaved to GPS time, so the measurements * are made at a time that wanders around the second. Then, * after the measurements are made (all normalized to the same * point in time) we dispatch the navigation software to make * a solution, and that solution comes out some 200 to 300 ms * after the measurement time. So you may get a message at * 700 ms after the second that uses measurements time tagged * 450 ms after the second. And if some other task jumps up * and delays things, that message may not come out until 900 * ms after the second. Things can get out of sync to the * point that if you try to resolve the GPS time of our 1 PPS * pulses using the navigation messages, you will find it * impossible to be consistent. That is why I added message * ID 52 to our system -- it is tied to the creation of the 1 * PPS and always comes out right around the top of the * second." */ return sirf_msg_ppstime(session, buf, len); case 0x62: /* uBlox Extended Measured Navigation Data */ return sirf_msg_ublox(session, buf, len); case 0x80: /* Initialize Data Source */ gpsd_report(LOG_PROG, "INIT 0x80: %s\n", gpsd_hexdump(buf, len)); return 0; case 0xe1: /* Development statistics messages */ /* FALLTHROUGH */ case 0xff: /* Debug messages */ (void)sirf_msg_debug(buf, len); return 0; default: gpsd_report(LOG_WARN, "Unknown SiRF packet id %d length %d: %s\n", buf[0], len, gpsd_hexdump(buf, len)); return 0; }}static gps_mask_t sirfbin_parse_input(struct gps_device_t *session){ gps_mask_t st; if (session->packet.type == SIRF_PACKET){ st = sirf_parse(session, session->packet.outbuffer, session->packet.outbuflen); session->gpsdata.driver_mode = 1; /* binary */ return st;#ifdef NMEA_ENABLE } else if (session->packet.type == NMEA_PACKET) { st = nmea_parse((char *)session->packet.outbuffer, session); session->gpsdata.driver_mode = 0; /* NMEA */ return st;#endif /* NMEA_ENABLE */ } else return 0;}#ifdef ALLOW_RECONFIGUREstatic void sirfbin_configure(struct gps_device_t *session, unsigned int seq){ if (seq != 0) return; if (session->packet.type == NMEA_PACKET) { gpsd_report(LOG_PROG, "Switching chip mode to SiRF binary.\n"); (void)nmea_send(session->gpsdata.gps_fd, "$PSRF100,0,%d,8,1,0", session->gpsdata.baudrate); } /* do this every time*/ { /*@ +charint @*/ static unsigned char navparams[] = {0xa0, 0xa2, 0x00, 0x02, 0x98, 0x00, 0x00, 0x00, 0xb0, 0xb3}; static unsigned char dgpscontrol[] = {0xa0, 0xa2, 0x00, 0x07, 0x85, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0xb3}; static unsigned char sbasparams[] = {0xa0, 0xa2, 0x00, 0x06, 0xaa, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0xb3}; static unsigned char versionprobe[] = {0xa0, 0xa2, 0x00, 0x02, 0x84, 0x00, 0x00, 0x00, 0xb0, 0xb3}; static unsigned char requestecef[] = {0xa0, 0xa2, 0x00, 0x08, 0xa6, 0x00, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0xb3}; static unsigned char requesttracker[] = {0xa0, 0xa2, 0x00, 0x08, 0xa6, 0x00, 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0xb3}; /*@ -charint @*/ gpsd_report(LOG_PROG, "Requesting periodic ecef reports...\n"); (void)sirf_write(session->gpsdata.gps_fd, requestecef); gpsd_report(LOG_PROG, "Requesting periodic tracker reports...\n"); (void)sirf_write(session->gpsdata.gps_fd, requesttracker); gpsd_report(LOG_PROG, "Setting DGPS control to use SBAS...\n"); (void)sirf_write(session->gpsdata.gps_fd, dgpscontrol); gpsd_report(LOG_PROG, "Setting SBAS to auto/integrity mode...\n"); (void)sirf_write(session->gpsdata.gps_fd, sbasparams); gpsd_report(LOG_PROG, "Probing for firmware version...\n"); (void)sirf_write(session->gpsdata.gps_fd, versionprobe); gpsd_report(LOG_PROG, "Requesting navigation parameters...\n"); (void)sirf_write(session->gpsdata.gps_fd, navparams); }}static void sirfbin_revert(struct gps_device_t *session){ /*@ +charint @*/ static unsigned char moderevert[] = {0xa0, 0xa2, 0x00, 0x0e, 0x88, 0x00, 0x00, /* pad bytes */ 0x00, /* degraded mode */ 0x00, 0x00, /* pad bytes */ 0x00, 0x00, /* altitude source */ 0x00, /* altitude hold mode */ 0x00, /* use last computed alt */ 0x00, /* reserved */ 0x00, /* degraded mode timeout */ 0x00, /* dead reckoning timeout */ 0x00, /* track smoothing */ 0x00, 0x00, 0xb0, 0xb3}; /*@ -charint -shiftimplementation @*/ putbyte(moderevert, 7, session->driver.sirf.degraded_mode); putword(moderevert, 10, session->driver.sirf.altitude_source_input); putbyte(moderevert, 12, session->driver.sirf.altitude_hold_mode); putbyte(moderevert, 13, session->driver.sirf.altitude_hold_source); putbyte(moderevert, 15, session->driver.sirf.degraded_timeout); putbyte(moderevert, 16, session->driver.sirf.dr_timeout); putbyte(moderevert, 17, session->driver.sirf.track_smooth_mode); /*@ +shiftimplementation @*/ gpsd_report(LOG_PROG, "Reverting navigation parameters...\n"); (void)sirf_write(session->gpsdata.gps_fd, moderevert);}#endif /* ALLOW_RECONFIGURE */static bool sirfbin_speed(struct gps_device_t *session, speed_t speed){ return sirf_speed(session->gpsdata.gps_fd, speed);}/* this is everything we export */struct gps_type_t sirf_binary ={ .type_name = "SiRF binary", /* full name of type */ .trigger = NULL, /* no trigger */ .channels = SIRF_CHANNELS, /* consumer-grade GPS */ .probe_wakeup = NULL, /* no wakeup to be done before hunt */ .probe_detect = NULL, /* no probe */ .probe_subtype = NULL, /* can't probe more in NMEA mode */#ifdef ALLOW_RECONFIGURE .configurator = sirfbin_configure,/* initialize the device */#endif /* ALLOW_RECONFIGURE */ .get_packet = generic_get, /* use the generic packet getter */ .parse_packet = sirfbin_parse_input,/* parse message packets */ .rtcm_writer = pass_rtcm, /* send RTCM data straight */ .speed_switcher = sirfbin_speed, /* we can change baud rate */ .mode_switcher = sirfbin_mode, /* there's a mode switcher */ .rate_switcher = NULL, /* no sample-rate switcher */ .cycle_chars = -1, /* not relevant, no rate switch */#ifdef ALLOW_RECONFIGURE .revert = sirfbin_revert, /* no reversion code */#endif /* ALLOW_RECONFIGURE */ .wrapup = NULL, /* no close hook */ .cycle = 1, /* updates every second */};#endif /* defined(SIRF_ENABLE) && defined(BINARY_ENABLE) */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -