Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 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
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*
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*
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*
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
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
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
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
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
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
}