altosui: Remove un-implemented --fetchmaps argument
[fw/altos] / ao-tools / ao-dump-up / ao-dump-up.c
1 /*
2  * Copyright © 2009 Keith Packard <keithp@keithp.com>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License along
15  * with this program; if not, write to the Free Software Foundation, Inc.,
16  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
17  */
18
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <unistd.h>
22 #include <getopt.h>
23 #include <string.h>
24 #include "cc-usb.h"
25 #include "cc.h"
26
27 #define NUM_BLOCK       512
28
29 static const struct option options[] = {
30         { .name = "tty", .has_arg = 1, .val = 'T' },
31         { .name = "device", .has_arg = 1, .val = 'D' },
32         { 0, 0, 0, 0},
33 };
34
35 static void usage(char *program)
36 {
37         fprintf(stderr, "usage: %s [--tty <tty-name>] [--device <device-name>]\n", program);
38         exit(1);
39 }
40
41 static uint8_t
42 log_checksum(int d[8])
43 {
44         uint8_t sum = 0x5a;
45         int     i;
46
47         for (i = 0; i < 8; i++)
48                 sum += (uint8_t) d[i];
49         return -sum;
50 }
51
52 static int get_nonwhite(struct cc_usb *cc, int timeout)
53 {
54         int     c;
55
56         for (;;) {
57                 c = cc_usb_getchar_timeout(cc, timeout);
58                 putchar(c);
59                 if (!isspace(c))
60                         return c;
61         }
62 }
63
64 static uint8_t
65 get_hexc(struct cc_usb *cc)
66 {
67         int     c = get_nonwhite(cc, 1000);
68
69         if ('0' <= c && c <= '9')
70                 return c - '0';
71         if ('a' <= c && c <= 'f')
72                 return c - 'a' + 10;
73         if ('A' <= c && c <= 'F')
74                 return c - 'A' + 10;
75         fprintf(stderr, "Non-hex char '%c'\n", c);
76         exit(1);
77 }
78
79 static int file_crc;
80
81 static const int POLY = 0x8408;
82
83 static int
84 log_crc(int crc, int b)
85 {
86         int     i;
87
88         for (i = 0; i < 8; i++) {
89                 if (((crc & 0x0001) ^ (b & 0x0001)) != 0)
90                         crc = (crc >> 1) ^ POLY;
91                 else
92                         crc = crc >> 1;
93                 b >>= 1;
94         }
95         return crc & 0xffff;
96 }
97
98 static uint8_t
99 get_hex(struct cc_usb *cc)
100 {
101         int     a = get_hexc(cc);
102         int     b = get_hexc(cc);
103         int     h = (a << 4) + b;
104
105         file_crc = log_crc(file_crc, h);
106         return h;
107 }
108
109 static int get_32(struct cc_usb *cc)
110 {
111         int     v = 0;
112         int     i;
113         for (i = 0; i < 4; i++) {
114                 v += get_hex(cc) << (i * 8);
115         }
116         return v;
117 }
118
119 static int get_16(struct cc_usb *cc)
120 {
121         int     v = 0;
122         int     i;
123         for (i = 0; i < 2; i++) {
124                 v += get_hex(cc) << (i * 8);
125         }
126         return v;
127 }
128
129 static int swap16(int i)
130 {
131         return ((i << 8) & 0xff00) | ((i >> 8) & 0xff);
132 }
133
134 static int find_header(struct cc_usb *cc)
135 {
136         for (;;) {
137                 if (get_nonwhite(cc, 0) == 'M' && get_nonwhite(cc, 1000) == 'P')
138                         return 1;
139         }
140 }
141
142 static const char *state_names[] = {
143         "startup",
144         "idle",
145         "pad",
146         "boost",
147         "fast",
148         "coast",
149         "drogue",
150         "main",
151         "landed",
152         "invalid"
153 };
154
155
156 int
157 main (int argc, char **argv)
158 {
159         struct cc_usb   *cc;
160         char            *tty = NULL;
161         char            *device = NULL;
162         int             c;
163         char            line[8192];
164         int             nsamples;
165         int             i;
166         int             crc;
167         int             current_crc;
168
169         while ((c = getopt_long(argc, argv, "T:D:", options, NULL)) != -1) {
170                 switch (c) {
171                 case 'T':
172                         tty = optarg;
173                         break;
174                 case 'D':
175                         device = optarg;
176                         break;
177                 default:
178                         usage(argv[0]);
179                         break;
180                 }
181         }
182         if (!tty)
183                 tty = cc_usbdevs_find_by_arg(device, "FT230X Basic UART");
184         if (!tty)
185                 tty = getenv("ALTOS_TTY");
186         if (!tty)
187                 tty="/dev/ttyUSB0";
188         cc = cc_usb_open(tty);
189         if (!cc)
190                 exit(1);
191         find_header(cc);
192         file_crc = 0xffff;
193         get_32(cc);     /* ground pressure */
194         get_32(cc);     /* min pressure */
195         nsamples = get_16(cc);  /* nsamples */
196         for (i = 0; i < nsamples; i++)
197                 get_16(cc);     /* sample i */
198         current_crc = swap16(~file_crc & 0xffff);
199         crc = get_16(cc);       /* crc */
200         putchar ('\n');
201         if (crc == current_crc)
202                 printf("CRC valid\n");
203         else
204                 printf("CRC invalid\n");
205         cc_usb_close(cc);
206         exit (0);
207 }