diff options
author | Eric S. Raymond <esr@thyrsus.com> | 2005-02-24 04:57:40 +0000 |
---|---|---|
committer | Eric S. Raymond <esr@thyrsus.com> | 2005-02-24 04:57:40 +0000 |
commit | 0fc6235f342aebb5740bf616e9cf4500df3e6984 (patch) | |
tree | c0a9cd46b1f9b6eb3bce201220fd433d4a9e33e6 | |
parent | 9c5de0a5887461b53037904ccad7126ccfdebb9c (diff) | |
download | gpsd-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.h | 4 | ||||
-rwxr-xr-x | gpsd.py | 24 | ||||
-rw-r--r-- | libgpsd_core.c | 2 | ||||
-rw-r--r-- | serial.c | 58 |
4 files changed, 47 insertions, 41 deletions
@@ -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); @@ -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 */ @@ -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; } |