summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric S. Raymond <esr@thyrsus.com>2005-02-24 04:57:40 +0000
committerEric S. Raymond <esr@thyrsus.com>2005-02-24 04:57:40 +0000
commit0fc6235f342aebb5740bf616e9cf4500df3e6984 (patch)
treec0a9cd46b1f9b6eb3bce201220fd433d4a9e33e6
parent9c5de0a5887461b53037904ccad7126ccfdebb9c (diff)
downloadgpsd-0fc6235f342aebb5740bf616e9cf4500df3e6984.tar.gz
More efficient baud hunting -- always start at the last successful speed,
hunt only if that doesn't match.
-rw-r--r--gpsd.h4
-rwxr-xr-xgpsd.py24
-rw-r--r--libgpsd_core.c2
-rw-r--r--serial.c58
4 files changed, 47 insertions, 41 deletions
diff --git a/gpsd.h b/gpsd.h
index 2943c66b..b8479664 100644
--- a/gpsd.h
+++ b/gpsd.h
@@ -84,8 +84,8 @@ extern int nmea_send(int fd, const char *fmt, ... );
extern int nmea_sane_satellites(struct gps_data_t *out);
extern void nmea_add_checksum(char *sentence);
extern int nmea_validate_buffer(char *buf, size_t n);
-extern int gpsd_open(int device_speed, int stopbits, struct gps_session_t *context);
-extern int gpsd_set_speed(struct gps_session_t *session, int speed);
+extern int gpsd_open(struct gps_session_t *context);
+extern int gpsd_set_speed(struct gps_session_t *session, unsigned int speed);
extern int gpsd_get_speed(struct termios *);
extern void gpsd_drain(int ttyfd);
extern void gpsd_close(struct gps_session_t *context);
diff --git a/gpsd.py b/gpsd.py
index b99e665d..3c3bd723 100755
--- a/gpsd.py
+++ b/gpsd.py
@@ -302,11 +302,12 @@ class gpsd(gps.gpsdata):
return buf
def set_speed(self, speed):
- self.raw[4] = self.raw[5] = eval("termios.B" + `speed`)
- termios.tcflush(self.ttyfd, termios.TCIOFLUSH)
- termios.tcsetattr(self.ttyfd, termios.TCSANOW, self.raw)
- termios.tcflush(self.ttyfd, termios.TCIOFLUSH)
- time.sleep(1)
+ if self.bps != speed:
+ self.raw[4] = self.raw[5] = eval("termios.B" + `speed`)
+ termios.tcflush(self.ttyfd, termios.TCIOFLUSH)
+ termios.tcsetattr(self.ttyfd, termios.TCSANOW, self.raw)
+ termios.tcflush(self.ttyfd, termios.TCIOFLUSH)
+ time.sleep(3)
if self.readline().find("$GP") > -1:
self.bps = speed
return 1
@@ -331,17 +332,14 @@ class gpsd(gps.gpsdata):
self.raw[2] |= (termios.CSIZE & termios.CS8) # cflag
self.raw[2] |= termios.CREAD | termios.CLOCAL # cflag
self.raw[3] = 0 # lflag
- if self.bps:
- if not self.set_speed(self.bps):
- self.ttyfd = -1
- return -1
- else:
+ if self.bps and not self.set_speed(self.bps):
for speed in (4800, 9600, 19200, 38400, 57600):
- if self.set_speed(speed):
- break
+ if speed != self.bps:
+ if self.set_speed(speed):
+ break
else:
self.ttyfd = -1
- return -1
+ return self.ttyfd
if self.devtype.initializer:
self.devtype.initializer(self)
self.online = True;
diff --git a/libgpsd_core.c b/libgpsd_core.c
index 24d0b2b7..39f8af8e 100644
--- a/libgpsd_core.c
+++ b/libgpsd_core.c
@@ -88,7 +88,7 @@ void gpsd_deactivate(struct gps_session_t *session)
int gpsd_activate(struct gps_session_t *session)
/* acquire a connection to the GPS device */
{
- if (gpsd_open(session->gNMEAdata.baudrate, session->device_type->stopbits, session) < 0)
+ if (gpsd_open(session) < 0)
return -1;
else {
tcflush(session->gNMEAdata.gps_fd, TCIOFLUSH); /* ignore old sentences */
diff --git a/serial.c b/serial.c
index a31d7e4f..5c521a33 100644
--- a/serial.c
+++ b/serial.c
@@ -36,10 +36,10 @@ int gpsd_get_speed(struct termios* ttyctl)
/* every rate we're likely to see on a GPS */
static int rates[] = {4800, 9600, 19200, 38400, 57600};
-int gpsd_set_speed(struct gps_session_t *session, int speed)
+int gpsd_set_speed(struct gps_session_t *session, unsigned int speed)
{
char buf[NMEA_MAX+1];
- unsigned int n, rate;
+ unsigned int n, rate, ok;
if (speed < 300)
rate = 0;
@@ -60,31 +60,38 @@ int gpsd_set_speed(struct gps_session_t *session, int speed)
else
rate = B57600;
- tcflush(session->gNMEAdata.gps_fd, TCIOFLUSH);
- cfsetispeed(&session->ttyset, (speed_t)rate);
- cfsetospeed(&session->ttyset, (speed_t)rate);
- if (tcsetattr(session->gNMEAdata.gps_fd, TCSANOW, &session->ttyset) != 0)
- return 0;
- tcflush(session->gNMEAdata.gps_fd, TCIOFLUSH);
+ if (speed != cfgetispeed(&session->ttyset)) {
+ tcflush(session->gNMEAdata.gps_fd, TCIOFLUSH);
+ cfsetispeed(&session->ttyset, (speed_t)rate);
+ cfsetospeed(&session->ttyset, (speed_t)rate);
+ if (tcsetattr(session->gNMEAdata.gps_fd, TCSANOW, &session->ttyset) != 0)
+ return 0;
+ tcflush(session->gNMEAdata.gps_fd, TCIOFLUSH);
- usleep(1250000); /* allow the UART time to settle */
+ usleep(3000000); /* allow the UART time to settle */
+ }
if (session->device_type->validate_buffer) {
n = 0;
while (n < NMEA_MAX) {
n += read(session->gNMEAdata.gps_fd, buf+n, sizeof(buf)-n-1);
+ if (n > 2 && buf[n-2] == '\r' && buf[n-1] == '\n')
+ break;
}
gpsd_report(4, "validating %d bytes.\n", n);
- return session->device_type->validate_buffer(buf, n);
+ ok = session->device_type->validate_buffer(buf, n);
} else {
/* this has the effect of disabling baud hunting on future connects */
gpsd_report(4, "no buffer validation.\n");
- session->gNMEAdata.baudrate = speed;
- return 1;
+ ok = 1;
}
+
+ if (ok)
+ session->gNMEAdata.baudrate = speed;
+ return ok;
}
-int gpsd_open(int device_speed, int stopbits, struct gps_session_t *session)
+int gpsd_open(struct gps_session_t *session)
{
int *ip;
@@ -103,25 +110,26 @@ int gpsd_open(int device_speed, int stopbits, struct gps_session_t *session)
* in the presence of flow control. Thus, turn off CRTSCTS.
*/
session->ttyset.c_cflag &= ~(PARENB | CRTSCTS);
- session->ttyset.c_cflag |= (CSIZE & (stopbits==2 ? CS7 : CS8)) | CREAD | CLOCAL;
+ session->ttyset.c_cflag |= (CSIZE & (session->gNMEAdata.stopbits==2 ? CS7 : CS8)) | CREAD | CLOCAL;
session->ttyset.c_iflag = session->ttyset.c_oflag = session->ttyset.c_lflag = (tcflag_t) 0;
session->ttyset.c_oflag = (ONLCR);
- if (device_speed) {
+ if (session->gNMEAdata.baudrate) {
gpsd_report(1, "setting speed %d, %d stopbits, no parity\n",
- device_speed, stopbits);
- if (gpsd_set_speed(session, device_speed)) {
+ session->gNMEAdata.baudrate,
+ session->gNMEAdata.stopbits);
+ if (gpsd_set_speed(session, session->gNMEAdata.baudrate)) {
return session->gNMEAdata.gps_fd;
}
- } else
- for (ip = rates; ip < rates + sizeof(rates)/sizeof(rates[0]); ip++) {
- gpsd_report(1, "hunting at speed %d, %d stopbits, no parity\n",
- *ip, stopbits);
- if (gpsd_set_speed(session, *ip)) {
+ }
+ for (ip = rates; ip < rates + sizeof(rates)/sizeof(rates[0]); ip++)
+ if (*ip != session->gNMEAdata.baudrate) {
+ gpsd_report(1, "hunting at speed %d, %d stopbits, no parity\n",
+ *ip, session->gNMEAdata.stopbits);
+ if (gpsd_set_speed(session, *ip))
return session->gNMEAdata.gps_fd;
- }
- }
- return -1;
+ }
+ session->gNMEAdata.gps_fd = -1;
}
return session->gNMEAdata.gps_fd;
}