gpsevermore.c 4.4 KB

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