summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric S. Raymond <esr@thyrsus.com>2005-03-02 13:41:42 +0000
committerEric S. Raymond <esr@thyrsus.com>2005-03-02 13:41:42 +0000
commitb764fdfd490c6161c28c8ce883628bb5c15705eb (patch)
tree5d0e827a5b19c2d70f74a033019b05b6d74b311a
parent8b47a203456aeac8056cbb5740b3155e92580d6b (diff)
downloadgpsd-b764fdfd490c6161c28c8ce883628bb5c15705eb.tar.gz
Logic to automatically switch to SiRF binary...
...and fall back if the firmware is too old, is already in place.
-rw-r--r--drivers.c14
-rw-r--r--gpsd.h1
-rw-r--r--sirf.c78
3 files changed, 58 insertions, 35 deletions
diff --git a/drivers.c b/drivers.c
index c5d94c11..684b30be 100644
--- a/drivers.c
+++ b/drivers.c
@@ -77,15 +77,20 @@ struct gps_type_t nmea = {
#ifdef SIRFII_ENABLE
/**************************************************************************
*
- * SiRF-II
+ * SiRF-II NMEA
+ *
+ * This NMEA -mode driver is a fallback in case the SiRF chipset has
+ * firmware too old for binary to be useful.
*
**************************************************************************/
+#ifndef BINARY_ENABLE
static void sirf_initializer(struct gps_session_t *session)
{
if (!strcmp(session->device_type->typename, "SiRF-II"))
nmea_send(session->gNMEAdata.gps_fd, "$PSRF105,0");
}
+#endif /* BINARY_ENABLE */
static int sirf_switcher(struct gps_session_t *session, int speed)
/* switch GPS to specified mode at 8N1, optionally to binary */
@@ -108,8 +113,13 @@ static int sirf_switcher(struct gps_session_t *session, int speed)
struct gps_type_t sirfII = {
'\0', /* selected implicitly */
"SiRF-II NMEA", /* full name of type */
+#ifdef BINARY_ENABLE
+ NULL, /* recognizing SiRF flips us to binary */
+ NULL, /* no initialization */
+#else
"$Ack Input105.", /* expected response to SiRF PSRF105 */
- sirf_initializer, /* no initialization */
+ sirf_initializer, /* turn off debugging messages */
+#endif /* BINARY_ENABLE */
nmea_handle_input, /* read text sentence */
nmea_write_rtcm, /* write RTCM data straight */
sirf_switcher, /* we can change speeds */
diff --git a/gpsd.h b/gpsd.h
index f4dca249..c09029a6 100644
--- a/gpsd.h
+++ b/gpsd.h
@@ -111,6 +111,7 @@ struct gps_session_t {
int hours, minutes;
double seconds;
unsigned int driverstate; /* for private use */
+#define SIRF_LT_231 0x01 /* SiRF at firmware rev < 231 */
#endif /* BINARY_ENABLE */
#ifdef ZODIAC_ENABLE /* private housekeeping stuff for the Zodiac driver */
unsigned short sn; /* packet sequence number */
diff --git a/sirf.c b/sirf.c
index 1583cebd..7143803a 100644
--- a/sirf.c
+++ b/sirf.c
@@ -29,6 +29,7 @@
#include <stdio.h>
#include "gpsd.h"
+#if defined(SIRFII_ENABLE) && defined(BINARY_ENABLE)
#define HI(n) ((n) >> 8)
#define LO(n) ((n) & 0xff)
@@ -70,7 +71,6 @@ static int sirf_speed(int ttyfd, int speed)
return (write(ttyfd, msg, 9+8) != 9+8);
}
-#ifdef __UNUSED__
static int sirf_to_nmea(int ttyfd, int speed)
/* switch from binary to NMEA at specified baud */
{
@@ -93,6 +93,7 @@ static int sirf_to_nmea(int ttyfd, int speed)
return (write(ttyfd, msg, 0x18+8) != 0x18+8);
}
+#ifdef __UNUSED__
static int sirf_waas_ctrl(int ttyfd, int enable)
/* enable or disable WAAS */
{
@@ -269,9 +270,6 @@ static int sirf_power_save(int ttyfd, int enable)
* message 41.
*/
-/* driver state flags */
-#define GNI_NAVTYPE_VALID 0x01 /* NAVtype in packet type 41 is good */
-
#define getb(off) (buf[off])
#define getw(off) ((short)((getb(off) << 8) | getb(off+1)))
#define getl(off) ((int)((getw(off) << 16) | (getw(off+2) & 0xffff)))
@@ -365,7 +363,7 @@ static void decode_ecef(struct gps_data_t *ud,
static void decode_sirf(struct gps_session_t *session,
unsigned char *buf, int len)
{
- int st, i, j, cn;
+ int st, i, j, cn, navtype;
char buf2[MAX_PACKET_LENGTH*3] = "";
switch (buf[0])
@@ -380,7 +378,7 @@ static void decode_sirf(struct gps_session_t *session,
(double)getw(15)/8.0,
(double)getw(17)/8.0);
/* fix status is byte 19 */
- int navtype = getb(19);
+ navtype = getb(19);
session->gNMEAdata.status = STATUS_NO_FIX;
session->gNMEAdata.mode = MODE_NO_FIX;
if (navtype & 0x80)
@@ -457,8 +455,11 @@ static void decode_sirf(struct gps_session_t *session,
case 0x06: /* Software Version String */
gpsd_report(4, "Firmware version: %s\n", session->outbuffer+5);
- if (atof(session->outbuffer+5) >= 232)
- session->driverstate |= GNI_NAVTYPE_VALID;
+ if (atof(session->outbuffer+5) < 231) {
+ session->driverstate |= SIRF_LT_231;
+ sirf_to_nmea(session->gNMEAdata.gps_fd,session->gNMEAdata.baudrate);
+ packet_sniff(session);
+ }
gpsd_report(4, "Driver state flags are: %0x\n", session->driverstate);
break;
@@ -496,24 +497,22 @@ static void decode_sirf(struct gps_session_t *session,
* To work around the incomplete implementation of this
* packet in 231, we use the status byte in sentence 0x02.
*/
- if (session->driverstate & GNI_NAVTYPE_VALID) {
- int navtype = getw(3);
- session->gNMEAdata.status = STATUS_NO_FIX;
- session->gNMEAdata.mode = MODE_NO_FIX;
- if (navtype & 0x80)
- session->gNMEAdata.status = STATUS_DGPS_FIX;
- else if ((navtype & 0x07) > 0 && (navtype & 0x07) < 7)
- session->gNMEAdata.status = STATUS_FIX;
- REFRESH(session->gNMEAdata.status_stamp);
- session->gNMEAdata.mode = MODE_NO_FIX;
- if ((navtype & 0x07) == 4 || (navtype & 0x07) == 6)
- session->gNMEAdata.mode = MODE_3D;
- else if (session->gNMEAdata.status)
- session->gNMEAdata.mode = MODE_2D;
- REFRESH(session->gNMEAdata.mode_stamp);
- gpsd_report(4, "Navtype = 0x%0x, Status = %d, mode = %d\n",
- navtype, session->gNMEAdata.status, session->gNMEAdata.mode);
- }
+ navtype = getw(3);
+ session->gNMEAdata.status = STATUS_NO_FIX;
+ session->gNMEAdata.mode = MODE_NO_FIX;
+ if (navtype & 0x80)
+ session->gNMEAdata.status = STATUS_DGPS_FIX;
+ else if ((navtype & 0x07) > 0 && (navtype & 0x07) < 7)
+ session->gNMEAdata.status = STATUS_FIX;
+ REFRESH(session->gNMEAdata.status_stamp);
+ session->gNMEAdata.mode = MODE_NO_FIX;
+ if ((navtype & 0x07) == 4 || (navtype & 0x07) == 6)
+ session->gNMEAdata.mode = MODE_3D;
+ else if (session->gNMEAdata.status)
+ session->gNMEAdata.mode = MODE_2D;
+ REFRESH(session->gNMEAdata.mode_stamp);
+ gpsd_report(4, "Navtype = 0x%0x, Status = %d, mode = %d\n",
+ navtype, session->gNMEAdata.status, session->gNMEAdata.mode);
/*
* Compute UTC from extended GPS time. The protocol reference
* claims this 16-bit field is "extended" GPS weeks, but I'm
@@ -580,12 +579,24 @@ static void sirfbin_handle_input(struct gps_session_t *session)
static void sirfbin_initializer(struct gps_session_t *session)
/* poll for software version in order to check for old firmware */
{
- u_int8_t msg[] = {0xa0, 0xa2, 0x00, 0x02,
- 0x84, 0x00,
- 0x00, 0x00, 0xb0, 0xb3};
- crc_sirf(msg);
- write(session->gNMEAdata.gps_fd, msg, 10);
- gpsd_report(4, "Probing for firmware version...\n");
+ if (session->packet_type == NMEA_PACKET) {
+ if (session->driverstate & SIRF_LT_231) {
+ gpsd_report(1, "SiRF chipset has old firmware, falling back to SiRF NMEA\n");
+ nmea_send(session->gNMEAdata.gps_fd, "$PSRF105,0");
+ gpsd_switch_driver(session, 'r');
+ } else {
+ u_int8_t msg[] = {0xa0, 0xa2, 0x00, 0x02,
+ 0x84, 0x00,
+ 0x00, 0x00, 0xb0, 0xb3};
+
+ gpsd_report(1, "Switching chip mode to SiRF binary.\n");
+ nmea_send(session->gNMEAdata.gps_fd, "$PSRF100,0,%d,8,1,0", session->gNMEAdata.baudrate);
+ packet_sniff(session);
+ crc_sirf(msg);
+ write(session->gNMEAdata.gps_fd, msg, 10);
+ gpsd_report(4, "Probing for firmware version...\n");
+ }
+ }
}
static int sirfbin_switch(struct gps_session_t *session, int speed)
@@ -598,7 +609,7 @@ struct gps_type_t sirf_binary =
{
's', /* invoke with -T s */
"SIRF-II binary", /* full name of type */
- NULL, /* only switched to by some other driver */
+ "$Ack Input105.", /* expected response to SiRF PSRF105 */
sirfbin_initializer, /* initialize the device */
sirfbin_handle_input,/* read and parse message packets */
NULL, /* send DGPS correction */
@@ -606,3 +617,4 @@ struct gps_type_t sirf_binary =
NULL, /* caller needs to supply a close hook */
1, /* updates every second */
};
+#endif /* defined(SIRFII_ENABLE) && defined(BINARY_ENABLE) */