diff options
author | Chris Kuethe <chris.kuethe@gmail.com> | 2007-12-23 18:44:43 +0000 |
---|---|---|
committer | Chris Kuethe <chris.kuethe@gmail.com> | 2007-12-23 18:44:43 +0000 |
commit | f365557b3fc821c6a5d13deb3aad0ec3d84ac7dd (patch) | |
tree | 20e38dace3e30a586423b5e142d595c1a2a37843 /contrib/ashctl.c | |
parent | c67dd9f2f3c9beae0cc333cc1e0bab8dd8fdd4a4 (diff) | |
download | gpsd-f365557b3fc821c6a5d13deb3aad0ec3d84ac7dd.tar.gz |
ashctl is a simple test tool to configure an ashtech receiver...
...to (not)? output raw measurements and to set up a useful set of
output messages.
Diffstat (limited to 'contrib/ashctl.c')
-rw-r--r-- | contrib/ashctl.c | 172 |
1 files changed, 172 insertions, 0 deletions
diff --git a/contrib/ashctl.c b/contrib/ashctl.c new file mode 100644 index 00000000..6ec153d6 --- /dev/null +++ b/contrib/ashctl.c @@ -0,0 +1,172 @@ +/* $Id$ */ +#include <sys/types.h> +#include <err.h> +#include <errno.h> +#include <fcntl.h> +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <termios.h> +#include <unistd.h> + +#define MODE_RAW 0 +#define MODE_NORMAL 1 +#define ASHSPD_9600 5 +#define ASHSPD_57600 8 + +static int nmea_send(int , const char *, ... ); +static void nmea_add_checksum(char *); +static void serial_speed(int, int); +static void config_raw(int); +static void config_normal(int); + +int main(int argc, char **argv) { + int i, speed, op, fd; + int rates[] = {57600, 9600, 115200, 4800, 19200, 1200, 0}; /* RTFM */ + char buf[BUFSIZ]; + + /* check number of args */ + if (argc != 3){ +u: fprintf(stderr, "usage: ashctl <port> [raw|normal]\n" + "normal = 9600, GGA+GSA+GSV+RMC+ZDA\n" + "raw = 57600, normal+XPG+POS+SAT+MCA+PBN+SNV\n" + ); + return 1; + } + + /* validate command */ + if (strcmp(argv[2], "raw") == 0) + op = MODE_RAW; + else if (strcmp(argv[2], "normal") == 0) + op = MODE_NORMAL; + else + goto u; + + if ((fd = open(argv[1], O_RDWR | O_NONBLOCK | O_NOCTTY, 0644)) == -1) + err(1, "open"); + + i = 0; + /* spam receiver w/ config messages */ + while((speed = rates[i++])){ + fprintf(stderr, + "\010\010\010\010\010\010\010\010" + "\010\010\010\010\010\010\010\010" + "\010\010\010\010\010\010\010\010" + "\010\010\010\010\010\010\010\010" + "configuring at %d bps... ", speed); + serial_speed(fd, speed); + if (op == MODE_NORMAL) { + config_normal(fd); + serial_speed(fd, 9600); + } else if (op == MODE_RAW) { + config_raw(fd); + serial_speed(fd, 57600); + } + + sleep(1); + read(fd, buf, BUFSIZ-1); + buf[BUFSIZ-1] = '\0'; + if (strstr(buf, "$PASH") || strstr(buf, "$GP")) + goto done; + } +done: fprintf(stderr, + "\010\010\010\010\010\010\010\010" + "\010\010\010\010\010\010\010\010" + "\010\010\010\010\010\010\010\010" + "\010\010\010\010\010\010\010\010" + "receiver configuration done \n"); + return 0; +} + +static void serial_speed(int fd, int speed){ + struct termios term; + + tcgetattr(fd, &term); + cfmakeraw(&term); + cfsetospeed(&term, speed); + cfsetispeed(&term, speed); + if (tcsetattr(fd, TCSANOW | TCSAFLUSH, &term) == -1) + err(1, "tcsetattr"); + + tcflush(fd, TCIOFLUSH); + return; +} + +static void config_normal(int fd){ + nmea_send(fd, "$PASHS,NME,ALL,A,OFF"); /* silence outbound chatter */ + nmea_send(fd, "$PASHS,NME,ALL,B,OFF"); + nmea_send(fd, "$PASHS,NME,GGA,A,ON"); + nmea_send(fd, "$PASHS,NME,GSA,A,ON"); + nmea_send(fd, "$PASHS,NME,GSV,A,ON"); + nmea_send(fd, "$PASHS,NME,RMC,A,ON"); + nmea_send(fd, "$PASHS,NME,ZDA,A,ON"); + + nmea_send(fd, "$PASHS,INI,%d,%d,,,0,",ASHSPD_9600, ASHSPD_9600); + sleep(6); /* it takes 4-6 sec for the receiver to reboot */ + nmea_send(fd, "$PASHS,WAS,ON"); /* enable WAAS */ +} + +static void config_raw(int fd){ + nmea_send(fd, "$PASHS,NME,ALL,A,OFF"); /* silence outbound chatter */ + nmea_send(fd, "$PASHS,NME,ALL,B,OFF"); + nmea_send(fd, "$PASHS,NME,GGA,A,ON"); + nmea_send(fd, "$PASHS,NME,GSA,A,ON"); + nmea_send(fd, "$PASHS,NME,GSV,A,ON"); + nmea_send(fd, "$PASHS,NME,RMC,A,ON"); + nmea_send(fd, "$PASHS,NME,ZDA,A,ON"); + + nmea_send(fd, "$PASHS,INI,%d,%d,,,0,",ASHSPD_57600, ASHSPD_9600); + sleep(6); /* it takes 4-6 sec for the receiver to reboot */ + nmea_send(fd, "$PASHS,WAS,ON"); /* enable WAAS */ + + nmea_send(fd, "$PASHS,NME,POS,A,ON"); /* Ashtech PVT solution */ + nmea_send(fd, "$PASHS,NME,SAT,A,ON"); /* Ashtech Satellite status */ + nmea_send(fd, "$PASHS,NME,MCA,A,ON"); /* MCA measurements */ + nmea_send(fd, "$PASHS,NME,PBN,A,ON"); /* ECEF PVT solution */ + nmea_send(fd, "$PASHS,NME,SNV,A,ON,10"); /* Almanac data */ + + nmea_send(fd, "$PASHS,NME,XMG,A,ON"); /* exception messages */ +} + +static void nmea_add_checksum(char *sentence) +/* add NMEA checksum to a possibly *-terminated sentence */ +{ + unsigned char sum = '\0'; + char c, *p = sentence; + + if (*p == '$') { + p++; + while ( ((c = *p) != '*') && (c != '\0')) { + sum ^= c; + p++; + } + *p++ = '*'; + (void)snprintf(p, 5, "%02X\r\n", (unsigned int)sum); + } +} + +static int nmea_send(int fd, const char *fmt, ... ) +/* ship a command to the GPS, adding * and correct checksum */ +{ + size_t status; + char buf[BUFSIZ]; + va_list ap; + + va_start(ap, fmt) ; + (void)vsnprintf(buf, sizeof(buf)-5, fmt, ap); + va_end(ap); + (void)strlcat(buf, "*", BUFSIZ); + nmea_add_checksum(buf); + // (void)fputs(buf, stderr); /* debug output */ + tcflush(fd, TCIOFLUSH); + status = (size_t)write(fd, buf, strlen(buf)); + tcdrain(fd); + usleep(100000); + if (status == strlen(buf)) { + return (int)status; + } else { + perror("nmea_send"); + return -1; + } +} |