summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric S. Raymond <esr@thyrsus.com>2013-11-12 02:54:04 -0500
committerEric S. Raymond <esr@thyrsus.com>2013-11-12 02:54:04 -0500
commitc36073c801eb2fd3f84e5e7e6253af6a5d671dc8 (patch)
treeeee5079bf788c92231f297bef47cf443b4f4abd0
parent9675e72c85748b4323b7a08fae59d5b09658f05f (diff)
downloadgpsd-c36073c801eb2fd3f84e5e7e6253af6a5d671dc8.tar.gz
We can now change baud rates on the GR601-W.
This required some unfortunate klugery because the GR601-W is a USB device that nevertheless has port ID 1 in the u-blox CFG-PRT message (associated with the primary USART) rather than port ID 3 which is what u-blox USB would give it.
-rw-r--r--driver_ubx.c46
-rw-r--r--drivers.c4
-rw-r--r--gpsd.h-tail1
3 files changed, 37 insertions, 14 deletions
diff --git a/driver_ubx.c b/driver_ubx.c
index b213a675..9205b8f7 100644
--- a/driver_ubx.c
+++ b/driver_ubx.c
@@ -471,6 +471,12 @@ gps_mask_t ubx_parse(struct gps_device_t * session, unsigned char *buf,
ubx_msg_inf(buf, data_len, session->context->debug);
break;
+ case UBX_CFG_PRT:
+ session->driver.ubx.port_id = (int)buf[UBX_MESSAGE_DATA_OFFSET + 0];
+ gpsd_report(session->context->debug, LOG_INF, "UBX_CFG_PRT: port %d\n",
+ session->driver.ubx.port_id);
+ break;
+
case UBX_TIM_TP:
gpsd_report(session->context->debug, LOG_IO, "UBX_TIM_TP\n");
break;
@@ -659,19 +665,35 @@ static void ubx_cfg_prt(struct gps_device_t *session,
memset(buf, '\0', UBX_CFG_LEN);
/*@ +ignoresigns +charint @*/
- switch(session->sourcetype) {
- case source_rs232:
- buf[0] = USART1_ID;
- break;
- case source_usb:
+ /*
+ * When this is called from gpsd, the initial probe for UBX should
+ * have picked up the device's port number from the CFG_PRT response.
+ */
+ if (session->driver.ubx.port_id != 0)
+ buf[0] = session->driver.ubx.port_id;
+ /*
+ * This default can be hit if we haven't sent a CFG_PRT query yet,
+ * which can happen in gpsmon because it doesn't autoprobe.
+ *
+ * What we'd like to do here is dispatch to USART1_ID or
+ * USB_ID intelligently based on whether this is a USB or RS232
+ * source. Unfortunately the GR601-W screws that up by being
+ * a USB device with port_id 1. So we bite the bullet and
+ * default to port 1.
+ *
+ * Without further logic, this means gpsmon wouldn't be able to
+ * change the speed on the EVK 6H's USB port. But! To pick off
+ * the EVK 6H on Linux as a special case, we notice that its
+ * USB device name is /dev/ACMx - it presents as a USB modem.
+ *
+ * This logic will fail on any USB u-blox device that presents
+ * as an ordinary USB serial device (/dev/USB*) and actually
+ * has port ID 3 the way it ought to.
+ */
+ else if (strstr(session->gpsdata.dev.path, "/ACM") != NULL)
buf[0] = USB_ID;
- break;
- default:
- gpsd_report(session->context->debug, LOG_WARN,
- "UBX driver sees unexpected source type %d.",
- session->sourcetype);
- return;
- }
+ else
+ buf[0] = USART1_ID;
putle32(buf, 8, speed);
diff --git a/drivers.c b/drivers.c
index db2f288e..f38d2569 100644
--- a/drivers.c
+++ b/drivers.c
@@ -224,10 +224,10 @@ static void nmea_event_hook(struct gps_device_t *session, event_t event)
#endif /* ASHTECH_ENABLE */
#ifdef UBLOX_ENABLE
case 7:
- /* probe for UBX -- query software version */
+ /* probe for UBX -- query port configuration */
gpsd_report(session->context->debug, LOG_PROG,
"=> Probing for UBX\n");
- (void)ubx_write(session, 0x0au, 0x04, NULL, 0);
+ (void)ubx_write(session, 0x06, 0x00, NULL, 0);
break;
#endif /* UBLOX_ENABLE */
#ifdef MTK3301_ENABLE
diff --git a/gpsd.h-tail b/gpsd.h-tail
index 28b0f0e5..8a2e37cb 100644
--- a/gpsd.h-tail
+++ b/gpsd.h-tail
@@ -610,6 +610,7 @@ struct gps_device_t {
#endif /* ZODIAC_ENABLE */
#ifdef UBLOX_ENABLE
struct {
+ unsigned char port_id;
unsigned char sbas_in_use;
bool user_switched;
} ubx;