summaryrefslogtreecommitdiff
path: root/driver_sirf.c
diff options
context:
space:
mode:
authorEric S. Raymond <esr@thyrsus.com>2013-11-18 04:40:17 -0500
committerEric S. Raymond <esr@thyrsus.com>2013-11-18 04:40:17 -0500
commitb935cd9dfa021ef1857263bb059507bb47c34772 (patch)
treeeaa296f49338d60afec66a598c9a32f1c0da1952 /driver_sirf.c
parentd4a915c757c7749cc2b16e31919e5c2bf45e6431 (diff)
downloadgpsd-b935cd9dfa021ef1857263bb059507bb47c34772.tar.gz
Stall SiRF writes the minimum necessary to guarantee a 4-second cooldown.
Works on a BU-355 (SiRF-III); at least, it gets through the configuration sends with little stalling.
Diffstat (limited to 'driver_sirf.c')
-rw-r--r--driver_sirf.c129
1 files changed, 86 insertions, 43 deletions
diff --git a/driver_sirf.c b/driver_sirf.c
index 7897bee4..9c7039e5 100644
--- a/driver_sirf.c
+++ b/driver_sirf.c
@@ -43,9 +43,16 @@
#include "bits.h"
#if defined(SIRF_ENABLE) && defined(BINARY_ENABLE)
-/* arbitrary back off time to not overload the SiRF, 330 too short for
- * SiRF IV. We should instead be waiting for the ACK, at least on SiRF IV */
-#define SIRF_SETTLE 30330
+/*
+ * Gary: "I read the SiRF IV doc. It specifically says that once you initialize
+ * a SiRCC IV that you must wait for each ACK before proceeding. I found
+ * that by lengthening the delays between initialization messages that
+ * things work a bit better. But the doc says that waits up to 4 seconds
+ * may be required and that sending another message before the ACK will
+ * result in problems. Looks pretty much like what I am seeing."
+ */
+#define SIRF_SETTLE 4
+
#define HI(n) ((n) >> 8)
#define LO(n) ((n) & 0xff)
@@ -233,6 +240,12 @@ static bool sirf_write(struct gps_device_t *session, unsigned char *msg)
unsigned int crc;
size_t i, len;
bool ok;
+ time_t cooldown;
+
+ /* control strings spaced too closely together confuse the SiRF IV */
+ cooldown = time(NULL) - session->driver.sirf.last_send;
+ if (cooldown < SIRF_SETTLE)
+ (void)sleep(SIRF_SETTLE - cooldown);
len = (size_t) ((msg[2] << 8) | msg[3]);
@@ -249,7 +262,8 @@ static bool sirf_write(struct gps_device_t *session, unsigned char *msg)
gpsd_report(session->context->debug, LOG_PROG,
"SiRF: Writing control type %02x:\n", msg[4]);
ok = (gpsd_write(session, (const char *)msg, len+8) == (ssize_t) (len+8));
- (void)usleep(SIRF_SETTLE); /* guessed settling time */
+
+ session->driver.sirf.last_send = time(NULL);
return (ok);
}
@@ -385,7 +399,6 @@ static void sirfbin_mode(struct gps_device_t *session, int mode)
session->gpsdata.dev.baudrate,
9 - session->gpsdata.dev.stopbits,
session->gpsdata.dev.stopbits, parity);
- (void)usleep(SIRF_SETTLE); /* guessed settling time */
}
session->back_to_nmea = false;
}
@@ -1367,63 +1380,93 @@ static void sirfbin_event_hook(struct gps_device_t *session, event_t event)
return;
if (event == event_identified || event == event_reactivate) {
+ session->driver.sirf.cfg_stage = 0;
if (session->packet.type == NMEA_PACKET) {
gpsd_report(session->context->debug, LOG_PROG,
"SiRF: Switching chip mode to binary.\n");
(void)nmea_send(session,
"$PSRF100,0,%d,8,1,0",
session->gpsdata.dev.baudrate);
- (void)usleep(SIRF_SETTLE); /* guessed settling time */
}
+ }
- gpsd_report(session->context->debug, LOG_PROG,
- "SiRF: Probing for firmware version...\n");
- (void)sirf_write(session, versionprobe);
-
- gpsd_report(session->context->debug, LOG_PROG,
- "SiRF: Requesting navigation parameters...\n");
- (void)sirf_write(session, navparams);
+ if (event == event_configure) {
+ /* might not be time for the next init string yet */
+ if (session->driver.sirf.last_send + SIRF_SETTLE > time(NULL))
+ return;
-#ifdef RECONFIGURE_ENABLE
- /* unset MID 64 first since there is a flood of them */
- gpsd_report(session->context->debug, LOG_PROG, "SiRF: unset MID 64...\n");
- putbyte(unsetmidXX, 6, 0x40);
- (void)sirf_write(session, unsetmidXX);
+ switch (session->driver.sirf.cfg_stage++) {
+ case 0:
+ /* this slot used by event_identified */
+ return;
- gpsd_report(session->context->debug, LOG_PROG,
- "SiRF: Requesting periodic ecef reports...\n");
- (void)sirf_write(session, requestecef);
+ case 1:
+ gpsd_report(session->context->debug, LOG_PROG,
+ "SiRF: Probing for firmware version...\n");
+ (void)sirf_write(session, versionprobe);
+ break;
- gpsd_report(session->context->debug, LOG_PROG,
- "SiRF: Requesting periodic tracker reports...\n");
- (void)sirf_write(session, requesttracker);
+ case 2:
+ gpsd_report(session->context->debug, LOG_PROG,
+ "SiRF: Requesting navigation parameters...\n");
+ (void)sirf_write(session, navparams);
+ break;
- gpsd_report(session->context->debug, LOG_PROG,
- "SiRF: Setting DGPS control to use SBAS...\n");
- (void)sirf_write(session, dgpscontrol);
+ case 3:
+#ifdef RECONFIGURE_ENABLE
+ /* unset MID 64 first since there is a flood of them */
+ gpsd_report(session->context->debug, LOG_PROG, "SiRF: unset MID 64...\n");
+ putbyte(unsetmidXX, 6, 0x40);
+ (void)sirf_write(session, unsetmidXX);
+ break;
- gpsd_report(session->context->debug, LOG_PROG,
- "SiRF: Setting SBAS to auto/integrity mode...\n");
- (void)sirf_write(session, sbasparams);
+ case 4:
+ gpsd_report(session->context->debug, LOG_PROG,
+ "SiRF: Requesting periodic ecef reports...\n");
+ (void)sirf_write(session, requestecef);
+ break;
- gpsd_report(session->context->debug, LOG_PROG,
- "SiRF: Enabling PPS message...\n");
- (void)sirf_write(session, enablemid52);
+ case 5:
+ gpsd_report(session->context->debug, LOG_PROG,
+ "SiRF: Requesting periodic tracker reports...\n");
+ (void)sirf_write(session, requesttracker);
+ break;
- /* SiRF recommends at least 57600 for SiRF IV nav data */
- if (session->gpsdata.dev.baudrate >= 57600) {
- /* fast enough, turn on nav data */
+ case 7:
gpsd_report(session->context->debug, LOG_PROG,
- "SiRF: Enabling subframe transmission...\n");
- (void)sirf_write(session, enablesubframe);
- } else {
- /* too slow, turn off nav data */
+ "SiRF: Setting DGPS control to use SBAS...\n");
+ (void)sirf_write(session, dgpscontrol);
+ break;
+
+ case 8:
gpsd_report(session->context->debug, LOG_PROG,
- "SiRF: Disabling subframe transmission...\n");
- (void)sirf_write(session, disablesubframe);
- }
+ "SiRF: Setting SBAS to auto/integrity mode...\n");
+ (void)sirf_write(session, sbasparams);
+ break;
+ case 9:
+ gpsd_report(session->context->debug, LOG_PROG,
+ "SiRF: Enabling PPS message...\n");
+ (void)sirf_write(session, enablemid52);
+
+ /* SiRF recommends at least 57600 for SiRF IV nav data */
+ if (session->gpsdata.dev.baudrate >= 57600) {
+ /* fast enough, turn on nav data */
+ gpsd_report(session->context->debug, LOG_PROG,
+ "SiRF: Enabling subframe transmission...\n");
+ (void)sirf_write(session, enablesubframe);
+ } else {
+ /* too slow, turn off nav data */
+ gpsd_report(session->context->debug, LOG_PROG,
+ "SiRF: Disabling subframe transmission...\n");
+ (void)sirf_write(session, disablesubframe);
+ }
+ break;
#endif /* RECONFIGURE_ENABLE */
+ default:
+ /* initialization is done */
+ return;
+ }
}
if (event == event_deactivate) {