xref: /plan9/sys/src/cmd/aux/gps/gpsevermore.c (revision 14cc0f535177405a84c5b73603a98e5db6674719)
1 #include <u.h>
2 #include <libc.h>
3 #include "dat.h"
4 
5 char *serial = "/dev/eia0";
6 
7 int ttyfd, ctlfd, debug;
8 int baud = Baud;
9 char *baudstr = "b%dd1r1pns1l8i1w5";
10 
11 Place where = {-(74.0 + 23.9191/60.0), 40.0 + 41.1346/60.0};
12 
13 void	setline(void);
14 void	evermore80(Place, int);
15 void	evermore89(int);
16 void	evermore8e(void);
17 
18 void
setline(void)19 setline(void){
20 	char *serialctl;
21 
22 	serialctl = smprint("%sctl", serial);
23 	if((ttyfd = open(serial, ORDWR)) < 0)
24 		sysfatal("%s: %r", serial);
25 	if((ctlfd = open(serialctl, OWRITE)) >= 0){
26 		if(fprint(ctlfd, baudstr, baud) < 0)
27 			sysfatal("%s: %r", serialctl);
28 	}
29 	free(serialctl);
30 }
31 
32 enum {
33 	GGAon = 0x01,
34 	GLLon = 0x02,
35 	GSAon = 0x04,
36 	GSVon = 0x08,
37 	RMCon = 0x10,
38 	VTGon = 0x20,
39 	CRCon = 0x40,
40 	EMTon = 0x80
41 };
42 
43 char*
putbyte(char * s,int v)44 putbyte(char *s, int v)
45 {
46 	*s++ = v;
47 	if((v & 0xff) == 0x10)
48 		*s++ = v;
49 	return s;
50 }
51 
52 char*
putshort(char * s,int v)53 putshort(char *s, int v)
54 {
55 	s = putbyte(s, v);
56 	s = putbyte(s, v >> 8);
57 	return s;
58 }
59 
60 char*
putlong(char * s,long v)61 putlong(char *s, long v)
62 {
63 	s = putbyte(s, v);
64 	s = putbyte(s, v >> 8);
65 	s = putbyte(s, v >> 16);
66 	s = putbyte(s, v >> 24);
67 	return s;
68 }
69 
70 void
evermoresend(char * body,int l)71 evermoresend(char *body, int l)
72 {
73 	char buf[8], *s;
74 	int crc, i;
75 
76 	s = buf;
77 	*s++ = 0x10;			/* DCE */
78 	*s++ = 0x02;			/* STX */
79 	s = putbyte(s, l);		/* length */
80 	write(ttyfd, buf, s-buf);	/* write header */
81 
82 	write(ttyfd, body, l);		/* write body */
83 
84 	crc = 0;
85 	for(i = 0; i < l; i++)
86 		crc += body[i];		/* calculate crc */
87 	s = buf;
88 	s = putbyte(s, crc);		/* checksum */
89 	*s++ = 0x10;			/* DCE */
90 	*s++ = 0x03;			/* ETX */
91 	write(ttyfd, buf, s-buf);	/* write trailer */
92 }
93 
94 void
evermore80(Place pl,int baud)95 evermore80(Place pl, int baud)
96 {
97 	char buf[32], *s;
98 	long now, seconds, week;
99 
100 	fprint(2, "Evermore80");
101 
102 	time(&now);
103 	seconds = now - 315964800;
104 	week = (seconds / (7*24*3600));
105 	seconds = seconds %  (7*24*3600);
106 	s = buf;
107 
108 	s = putbyte(s, 0x80);		/* message ID */
109 	s = putshort(s, week);		/* week number */
110 	s = putlong(s, seconds*100);	/* seconds */
111 	s = putshort(s, pl.lat*10.0);	/* latitude tenths degree */
112 	s = putshort(s, pl.lon*10.0);	/* longitude tenths degree */
113 	s = putshort(s, 100);		/* altitude meters */
114 	s = putshort(s, 0);		/* datumn ID */
115 	s = putbyte(s, 2);		/* warm start */
116 	s = putbyte(s, GGAon|GSAon|GSVon|RMCon|CRCon);
117 	switch(baud){
118 	case 4800:	s = putbyte(s, 0);	break;
119 	case 9600:	s = putbyte(s, 1);	break;
120 	case 19200:	s = putbyte(s, 2);	break;
121 	case 38400:	s = putbyte(s, 3);	break;
122 	default:
123 		sysfatal("Illegal baud rate");
124 	}
125 
126 	evermoresend(buf, s - buf);
127 	fprint(2, "\n");
128 }
129 
130 void
evermore89(int baud)131 evermore89(int baud)
132 {
133 	char buf[32], *s;
134 
135 	fprint(2, "Evermore89");
136 	s = buf;
137 	s = putbyte(s, 0x89);		/* message ID */
138 	s = putbyte(s, 0x01);		/* set main serial port */
139 	switch(baud){
140 	case  4800:	s = putbyte(s, 0x00);	break;
141 	case  9600:	s = putbyte(s, 0x01);	break;
142 	case 19200:	s = putbyte(s, 0x02);	break;
143 	case 38400:	s = putbyte(s, 0x03);	break;
144 	default:
145 		sysfatal("illegal baud rate %d", baud);
146 	}
147 
148 	evermoresend(buf, s - buf);
149 	fprint(2, "\n");
150 }
151 
152 void
evermore8e(void)153 evermore8e(void)
154 {
155 	char buf[32], *s;
156 
157 	fprint(2, "Evermore8e");
158 	s = buf;
159 	s = putbyte(s, 0x8e);		/* message ID */
160 	s = putbyte(s, GGAon|GSAon|GSVon|RMCon);		/* all messages except GLL and VTG */
161 	s = putbyte(s, 0x01);		/* checksum on */
162 	s = putbyte(s, 0x01);		/* GGA update rate */
163 	s = putbyte(s, 0x0b);		/* GLL update rate */
164 	s = putbyte(s, 0x0a);		/* GSA update rate */
165 	s = putbyte(s, 0x14);		/* GSV update rate */
166 	s = putbyte(s, 0x08);		/* RMC update rate */
167 	s = putbyte(s, 0x0d);		/* VTG update rate */
168 
169 	evermoresend(buf, s - buf);
170 	fprint(2, "\n");
171 }
172 
173 void
main(int argc,char * argv[])174 main(int argc, char*argv[])
175 {
176 	char *p;
177 	Place pl;
178 	int newbaud;
179 
180 	newbaud = -1;
181 	pl = nowhere;
182 	ARGBEGIN {
183 	default:
184 		fprint(2, "usage: %s [-b baud] [-d device] [-l longitude latitude] [-n newbaud]\n", argv0);
185 		exits("usage");
186 	case 'D':
187 		debug++;
188 		break;
189 	case 'b':
190 		baud = strtol(ARGF(), nil, 0);
191 		break;
192 	case 'd':
193 		serial = ARGF();
194 		break;
195 	case 'l':
196 		p = ARGF();
197 		if(strtolatlon(p, &p, &pl) < 0)
198 			sysfatal("bad position");
199 		while(*p == ' ' || *p == '\t' || *p == '\n')
200 			p++;
201 		if(*p == '\0')
202 			p = ARGF();
203 		if (strtolatlon(p, &p, &pl) < 0)
204 			sysfatal("bad position");
205 		while(*p == ' ' || *p == '\t' || *p == '\n')
206 			p++;
207 		if(*p != '\0')
208 			sysfatal("trailing gunk in position");
209 		where = pl;
210 		break;
211 	case 'n':
212 		newbaud = strtol(ARGF(), nil, 0);
213 		break;
214 	} ARGEND
215 
216 	if(newbaud < 0)
217 		newbaud = baud;
218 
219 	fmtinstall('L', placeconv);
220 	print("Initializing GPS to %d baud, at %L, time %s\n",
221 		newbaud, where, ctime(time(nil)));
222 	setline();
223 	evermore80(where, newbaud);
224 }
225