xref: /plan9/sys/src/cmd/aux/gps/gpsevermore.c (revision 14cc0f535177405a84c5b73603a98e5db6674719)
17c881178SDavid du Colombier #include <u.h>
27c881178SDavid du Colombier #include <libc.h>
37c881178SDavid du Colombier #include "dat.h"
47c881178SDavid du Colombier 
57c881178SDavid du Colombier char *serial = "/dev/eia0";
67c881178SDavid du Colombier 
77c881178SDavid du Colombier int ttyfd, ctlfd, debug;
87c881178SDavid du Colombier int baud = Baud;
97c881178SDavid du Colombier char *baudstr = "b%dd1r1pns1l8i1w5";
107c881178SDavid du Colombier 
117c881178SDavid du Colombier Place where = {-(74.0 + 23.9191/60.0), 40.0 + 41.1346/60.0};
127c881178SDavid du Colombier 
137c881178SDavid du Colombier void	setline(void);
147c881178SDavid du Colombier void	evermore80(Place, int);
157c881178SDavid du Colombier void	evermore89(int);
167c881178SDavid du Colombier void	evermore8e(void);
177c881178SDavid du Colombier 
187c881178SDavid du Colombier void
setline(void)197c881178SDavid du Colombier setline(void){
207c881178SDavid du Colombier 	char *serialctl;
217c881178SDavid du Colombier 
227c881178SDavid du Colombier 	serialctl = smprint("%sctl", serial);
237c881178SDavid du Colombier 	if((ttyfd = open(serial, ORDWR)) < 0)
247c881178SDavid du Colombier 		sysfatal("%s: %r", serial);
257c881178SDavid du Colombier 	if((ctlfd = open(serialctl, OWRITE)) >= 0){
267c881178SDavid du Colombier 		if(fprint(ctlfd, baudstr, baud) < 0)
277c881178SDavid du Colombier 			sysfatal("%s: %r", serialctl);
287c881178SDavid du Colombier 	}
297c881178SDavid du Colombier 	free(serialctl);
307c881178SDavid du Colombier }
317c881178SDavid du Colombier 
327c881178SDavid du Colombier enum {
337c881178SDavid du Colombier 	GGAon = 0x01,
347c881178SDavid du Colombier 	GLLon = 0x02,
357c881178SDavid du Colombier 	GSAon = 0x04,
367c881178SDavid du Colombier 	GSVon = 0x08,
377c881178SDavid du Colombier 	RMCon = 0x10,
387c881178SDavid du Colombier 	VTGon = 0x20,
397c881178SDavid du Colombier 	CRCon = 0x40,
407c881178SDavid du Colombier 	EMTon = 0x80
417c881178SDavid du Colombier };
427c881178SDavid du Colombier 
437c881178SDavid du Colombier char*
putbyte(char * s,int v)447c881178SDavid du Colombier putbyte(char *s, int v)
457c881178SDavid du Colombier {
467c881178SDavid du Colombier 	*s++ = v;
477c881178SDavid du Colombier 	if((v & 0xff) == 0x10)
487c881178SDavid du Colombier 		*s++ = v;
497c881178SDavid du Colombier 	return s;
507c881178SDavid du Colombier }
517c881178SDavid du Colombier 
527c881178SDavid du Colombier char*
putshort(char * s,int v)537c881178SDavid du Colombier putshort(char *s, int v)
547c881178SDavid du Colombier {
557c881178SDavid du Colombier 	s = putbyte(s, v);
567c881178SDavid du Colombier 	s = putbyte(s, v >> 8);
577c881178SDavid du Colombier 	return s;
587c881178SDavid du Colombier }
597c881178SDavid du Colombier 
607c881178SDavid du Colombier char*
putlong(char * s,long v)617c881178SDavid du Colombier putlong(char *s, long v)
627c881178SDavid du Colombier {
637c881178SDavid du Colombier 	s = putbyte(s, v);
647c881178SDavid du Colombier 	s = putbyte(s, v >> 8);
657c881178SDavid du Colombier 	s = putbyte(s, v >> 16);
667c881178SDavid du Colombier 	s = putbyte(s, v >> 24);
677c881178SDavid du Colombier 	return s;
687c881178SDavid du Colombier }
697c881178SDavid du Colombier 
707c881178SDavid du Colombier void
evermoresend(char * body,int l)717c881178SDavid du Colombier evermoresend(char *body, int l)
727c881178SDavid du Colombier {
737c881178SDavid du Colombier 	char buf[8], *s;
747c881178SDavid du Colombier 	int crc, i;
757c881178SDavid du Colombier 
767c881178SDavid du Colombier 	s = buf;
777c881178SDavid du Colombier 	*s++ = 0x10;			/* DCE */
787c881178SDavid du Colombier 	*s++ = 0x02;			/* STX */
797c881178SDavid du Colombier 	s = putbyte(s, l);		/* length */
807c881178SDavid du Colombier 	write(ttyfd, buf, s-buf);	/* write header */
817c881178SDavid du Colombier 
827c881178SDavid du Colombier 	write(ttyfd, body, l);		/* write body */
837c881178SDavid du Colombier 
847c881178SDavid du Colombier 	crc = 0;
857c881178SDavid du Colombier 	for(i = 0; i < l; i++)
867c881178SDavid du Colombier 		crc += body[i];		/* calculate crc */
877c881178SDavid du Colombier 	s = buf;
887c881178SDavid du Colombier 	s = putbyte(s, crc);		/* checksum */
897c881178SDavid du Colombier 	*s++ = 0x10;			/* DCE */
907c881178SDavid du Colombier 	*s++ = 0x03;			/* ETX */
917c881178SDavid du Colombier 	write(ttyfd, buf, s-buf);	/* write trailer */
927c881178SDavid du Colombier }
937c881178SDavid du Colombier 
947c881178SDavid du Colombier void
evermore80(Place pl,int baud)957c881178SDavid du Colombier evermore80(Place pl, int baud)
967c881178SDavid du Colombier {
977c881178SDavid du Colombier 	char buf[32], *s;
987c881178SDavid du Colombier 	long now, seconds, week;
997c881178SDavid du Colombier 
1007c881178SDavid du Colombier 	fprint(2, "Evermore80");
1017c881178SDavid du Colombier 
1027c881178SDavid du Colombier 	time(&now);
1037c881178SDavid du Colombier 	seconds = now - 315964800;
1047c881178SDavid du Colombier 	week = (seconds / (7*24*3600));
1057c881178SDavid du Colombier 	seconds = seconds %  (7*24*3600);
1067c881178SDavid du Colombier 	s = buf;
1077c881178SDavid du Colombier 
1087c881178SDavid du Colombier 	s = putbyte(s, 0x80);		/* message ID */
1097c881178SDavid du Colombier 	s = putshort(s, week);		/* week number */
1107c881178SDavid du Colombier 	s = putlong(s, seconds*100);	/* seconds */
1117c881178SDavid du Colombier 	s = putshort(s, pl.lat*10.0);	/* latitude tenths degree */
1127c881178SDavid du Colombier 	s = putshort(s, pl.lon*10.0);	/* longitude tenths degree */
1137c881178SDavid du Colombier 	s = putshort(s, 100);		/* altitude meters */
1147c881178SDavid du Colombier 	s = putshort(s, 0);		/* datumn ID */
1157c881178SDavid du Colombier 	s = putbyte(s, 2);		/* warm start */
1167c881178SDavid du Colombier 	s = putbyte(s, GGAon|GSAon|GSVon|RMCon|CRCon);
1177c881178SDavid du Colombier 	switch(baud){
1187c881178SDavid du Colombier 	case 4800:	s = putbyte(s, 0);	break;
1197c881178SDavid du Colombier 	case 9600:	s = putbyte(s, 1);	break;
1207c881178SDavid du Colombier 	case 19200:	s = putbyte(s, 2);	break;
1217c881178SDavid du Colombier 	case 38400:	s = putbyte(s, 3);	break;
1227c881178SDavid du Colombier 	default:
1237c881178SDavid du Colombier 		sysfatal("Illegal baud rate");
1247c881178SDavid du Colombier 	}
1257c881178SDavid du Colombier 
1267c881178SDavid du Colombier 	evermoresend(buf, s - buf);
1277c881178SDavid du Colombier 	fprint(2, "\n");
1287c881178SDavid du Colombier }
1297c881178SDavid du Colombier 
1307c881178SDavid du Colombier void
evermore89(int baud)1317c881178SDavid du Colombier evermore89(int baud)
1327c881178SDavid du Colombier {
1337c881178SDavid du Colombier 	char buf[32], *s;
1347c881178SDavid du Colombier 
1357c881178SDavid du Colombier 	fprint(2, "Evermore89");
1367c881178SDavid du Colombier 	s = buf;
1377c881178SDavid du Colombier 	s = putbyte(s, 0x89);		/* message ID */
1387c881178SDavid du Colombier 	s = putbyte(s, 0x01);		/* set main serial port */
1397c881178SDavid du Colombier 	switch(baud){
1407c881178SDavid du Colombier 	case  4800:	s = putbyte(s, 0x00);	break;
1417c881178SDavid du Colombier 	case  9600:	s = putbyte(s, 0x01);	break;
1427c881178SDavid du Colombier 	case 19200:	s = putbyte(s, 0x02);	break;
1437c881178SDavid du Colombier 	case 38400:	s = putbyte(s, 0x03);	break;
1447c881178SDavid du Colombier 	default:
145*14cc0f53SDavid du Colombier 		sysfatal("illegal baud rate %d", baud);
1467c881178SDavid du Colombier 	}
1477c881178SDavid du Colombier 
1487c881178SDavid du Colombier 	evermoresend(buf, s - buf);
1497c881178SDavid du Colombier 	fprint(2, "\n");
1507c881178SDavid du Colombier }
1517c881178SDavid du Colombier 
1527c881178SDavid du Colombier void
evermore8e(void)1537c881178SDavid du Colombier evermore8e(void)
1547c881178SDavid du Colombier {
1557c881178SDavid du Colombier 	char buf[32], *s;
1567c881178SDavid du Colombier 
1577c881178SDavid du Colombier 	fprint(2, "Evermore8e");
1587c881178SDavid du Colombier 	s = buf;
1597c881178SDavid du Colombier 	s = putbyte(s, 0x8e);		/* message ID */
1607c881178SDavid du Colombier 	s = putbyte(s, GGAon|GSAon|GSVon|RMCon);		/* all messages except GLL and VTG */
1617c881178SDavid du Colombier 	s = putbyte(s, 0x01);		/* checksum on */
1627c881178SDavid du Colombier 	s = putbyte(s, 0x01);		/* GGA update rate */
1637c881178SDavid du Colombier 	s = putbyte(s, 0x0b);		/* GLL update rate */
1647c881178SDavid du Colombier 	s = putbyte(s, 0x0a);		/* GSA update rate */
1657c881178SDavid du Colombier 	s = putbyte(s, 0x14);		/* GSV update rate */
1667c881178SDavid du Colombier 	s = putbyte(s, 0x08);		/* RMC update rate */
1677c881178SDavid du Colombier 	s = putbyte(s, 0x0d);		/* VTG update rate */
1687c881178SDavid du Colombier 
1697c881178SDavid du Colombier 	evermoresend(buf, s - buf);
1707c881178SDavid du Colombier 	fprint(2, "\n");
1717c881178SDavid du Colombier }
1727c881178SDavid du Colombier 
1737c881178SDavid du Colombier void
main(int argc,char * argv[])1747c881178SDavid du Colombier main(int argc, char*argv[])
1757c881178SDavid du Colombier {
1767c881178SDavid du Colombier 	char *p;
1777c881178SDavid du Colombier 	Place pl;
1787c881178SDavid du Colombier 	int newbaud;
1797c881178SDavid du Colombier 
1807c881178SDavid du Colombier 	newbaud = -1;
1817c881178SDavid du Colombier 	pl = nowhere;
1827c881178SDavid du Colombier 	ARGBEGIN {
1837c881178SDavid du Colombier 	default:
1847c881178SDavid du Colombier 		fprint(2, "usage: %s [-b baud] [-d device] [-l longitude latitude] [-n newbaud]\n", argv0);
1857c881178SDavid du Colombier 		exits("usage");
1867c881178SDavid du Colombier 	case 'D':
1877c881178SDavid du Colombier 		debug++;
1887c881178SDavid du Colombier 		break;
1897c881178SDavid du Colombier 	case 'b':
1907c881178SDavid du Colombier 		baud = strtol(ARGF(), nil, 0);
1917c881178SDavid du Colombier 		break;
1927c881178SDavid du Colombier 	case 'd':
1937c881178SDavid du Colombier 		serial = ARGF();
1947c881178SDavid du Colombier 		break;
1957c881178SDavid du Colombier 	case 'l':
1967c881178SDavid du Colombier 		p = ARGF();
1977c881178SDavid du Colombier 		if(strtolatlon(p, &p, &pl) < 0)
1987c881178SDavid du Colombier 			sysfatal("bad position");
1997c881178SDavid du Colombier 		while(*p == ' ' || *p == '\t' || *p == '\n')
2007c881178SDavid du Colombier 			p++;
2017c881178SDavid du Colombier 		if(*p == '\0')
2027c881178SDavid du Colombier 			p = ARGF();
2037c881178SDavid du Colombier 		if (strtolatlon(p, &p, &pl) < 0)
2047c881178SDavid du Colombier 			sysfatal("bad position");
2057c881178SDavid du Colombier 		while(*p == ' ' || *p == '\t' || *p == '\n')
2067c881178SDavid du Colombier 			p++;
2077c881178SDavid du Colombier 		if(*p != '\0')
2087c881178SDavid du Colombier 			sysfatal("trailing gunk in position");
2097c881178SDavid du Colombier 		where = pl;
2107c881178SDavid du Colombier 		break;
2117c881178SDavid du Colombier 	case 'n':
2127c881178SDavid du Colombier 		newbaud = strtol(ARGF(), nil, 0);
2137c881178SDavid du Colombier 		break;
2147c881178SDavid du Colombier 	} ARGEND
2157c881178SDavid du Colombier 
2167c881178SDavid du Colombier 	if(newbaud < 0)
2177c881178SDavid du Colombier 		newbaud = baud;
2187c881178SDavid du Colombier 
2197c881178SDavid du Colombier 	fmtinstall('L', placeconv);
2207c881178SDavid du Colombier 	print("Initializing GPS to %d baud, at %L, time %s\n",
2217c881178SDavid du Colombier 		newbaud, where, ctime(time(nil)));
2227c881178SDavid du Colombier 	setline();
2237c881178SDavid du Colombier 	evermore80(where, newbaud);
2247c881178SDavid du Colombier }
225