ao-tools: Fix warnings in ao-tools
[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 <ctype.h>
25 #include "cc-usb.h"
26 #include "cc.h"
27
28 #define NUM_BLOCK       512
29
30 static const struct option options[] = {
31         { .name = "tty", .has_arg = 1, .val = 'T' },
32         { .name = "device", .has_arg = 1, .val = 'D' },
33         { .name = "wait", .has_arg = 0, .val = 'w' },
34         { 0, 0, 0, 0},
35 };
36
37 static void usage(char *program)
38 {
39         fprintf(stderr, "usage: %s [--tty <tty-name>] [--device <device-name>] [--wait]\n", program);
40         exit(1);
41 }
42
43 static int get_nonwhite(struct cc_usb *cc, int timeout)
44 {
45         int     c;
46
47         for (;;) {
48                 c = cc_usb_getchar_timeout(cc, timeout);
49                 putchar(c);
50                 if (!isspace(c))
51                         return c;
52         }
53 }
54
55 static uint8_t
56 get_hexc(struct cc_usb *cc)
57 {
58         int     c = get_nonwhite(cc, 1000);
59
60         if ('0' <= c && c <= '9')
61                 return c - '0';
62         if ('a' <= c && c <= 'f')
63                 return c - 'a' + 10;
64         if ('A' <= c && c <= 'F')
65                 return c - 'A' + 10;
66         fprintf(stderr, "Non-hex char '%c'\n", c);
67         exit(1);
68 }
69
70 static int file_crc;
71
72 static const int POLY = 0x8408;
73
74 static int
75 log_crc(int crc, int b)
76 {
77         int     i;
78
79         for (i = 0; i < 8; i++) {
80                 if (((crc & 0x0001) ^ (b & 0x0001)) != 0)
81                         crc = (crc >> 1) ^ POLY;
82                 else
83                         crc = crc >> 1;
84                 b >>= 1;
85         }
86         return crc & 0xffff;
87 }
88
89 static uint8_t
90 get_hex(struct cc_usb *cc)
91 {
92         int     a = get_hexc(cc);
93         int     b = get_hexc(cc);
94         int     h = (a << 4) + b;
95
96         file_crc = log_crc(file_crc, h);
97         return h;
98 }
99
100 static int get_32(struct cc_usb *cc)
101 {
102         int     v = 0;
103         int     i;
104         for (i = 0; i < 4; i++) {
105                 v += get_hex(cc) << (i * 8);
106         }
107         return v;
108 }
109
110 static int get_16(struct cc_usb *cc)
111 {
112         int     v = 0;
113         int     i;
114         for (i = 0; i < 2; i++) {
115                 v += get_hex(cc) << (i * 8);
116         }
117         return v;
118 }
119
120 static int swap16(int i)
121 {
122         return ((i << 8) & 0xff00) | ((i >> 8) & 0xff);
123 }
124
125 static int find_header(struct cc_usb *cc)
126 {
127         for (;;) {
128                 if (get_nonwhite(cc, -1) == 'M' && get_nonwhite(cc, 1000) == 'P')
129                         return 1;
130         }
131 }
132
133 int
134 main (int argc, char **argv)
135 {
136         struct cc_usb   *cc;
137         char            *tty = NULL;
138         char            *device = NULL;
139         int             c;
140         int             nsamples;
141         int             i;
142         int             crc;
143         int             current_crc;
144         int             wait = 0;
145
146         while ((c = getopt_long(argc, argv, "wT:D:", options, NULL)) != -1) {
147                 switch (c) {
148                 case 'w':
149                         wait = 1;
150                         break;
151                 case 'T':
152                         tty = optarg;
153                         break;
154                 case 'D':
155                         device = optarg;
156                         break;
157                 default:
158                         usage(argv[0]);
159                         break;
160                 }
161         }
162         if (!tty) {
163                 for (;;) {
164                         tty = cc_usbdevs_find_by_arg(device, "FT230X Basic UART");
165                         if (tty) {
166                                 if (wait) {
167                                         printf("tty is %s\n", tty);
168                                         sleep(1);
169                                 }
170                                 break;
171                         }
172                         if (!wait)
173                                 break;
174                         sleep(1);
175                 }
176         }
177         if (!tty)
178                 tty = getenv("ALTOS_TTY");
179         if (!tty)
180                 tty="/dev/ttyUSB0";
181         cc = cc_usb_open(tty);
182         if (!cc)
183                 exit(1);
184         find_header(cc);
185         file_crc = 0xffff;
186         get_32(cc);     /* ground pressure */
187         get_32(cc);     /* min pressure */
188         nsamples = get_16(cc);  /* nsamples */
189         for (i = 0; i < nsamples; i++)
190                 get_16(cc);     /* sample i */
191         current_crc = swap16(~file_crc & 0xffff);
192         crc = get_16(cc);       /* crc */
193         putchar ('\n');
194         if (crc == current_crc)
195                 printf("CRC valid\n");
196         else
197                 printf("CRC invalid\n");
198         cc_usb_close(cc);
199         exit (0);
200 }