Merge branch 'master' into skytraq
[fw/altos] / ao-tools / ao-dumplog / ao-dumplog.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 "cc-usb.h"
24 #include "cc.h"
25
26 #define NUM_BLOCK       512
27
28 static const struct option options[] = {
29         { .name = "tty", .has_arg = 1, .val = 'T' },
30         { .name = "device", .has_arg = 1, .val = 'D' },
31         { 0, 0, 0, 0},
32 };
33
34 static void usage(char *program)
35 {
36         fprintf(stderr, "usage: %s [--tty <tty-name>] [--device <device-name>\n", program);
37         exit(1);
38 }
39
40 static uint8_t
41 log_checksum(int d[8])
42 {
43         uint8_t sum = 0x5a;
44         int     i;
45
46         for (i = 0; i < 8; i++)
47                 sum += (uint8_t) d[i];
48         return -sum;
49 }
50
51 static const char *state_names[] = {
52         "startup",
53         "idle",
54         "pad",
55         "boost",
56         "fast",
57         "coast",
58         "drogue",
59         "main",
60         "landed",
61         "invalid"
62 };
63
64 int
65 main (int argc, char **argv)
66 {
67         struct cc_usb   *cc;
68         char            *tty = NULL;
69         char            *device = NULL;
70         int             c;
71         char            line[8192];
72         FILE            *out;
73         char            *filename;
74         int             serial_number;
75         char            cmd;
76         int             tick, a, b;
77         int             block;
78         int             addr;
79         int             received_addr;
80         int             data[8];
81         int             done;
82         int             column;
83
84         while ((c = getopt_long(argc, argv, "T:D:", options, NULL)) != -1) {
85                 switch (c) {
86                 case 'T':
87                         tty = optarg;
88                         break;
89                 case 'D':
90                         device = optarg;
91                         break;
92                 default:
93                         usage(argv[0]);
94                         break;
95                 }
96         }
97         if (!tty)
98                 tty = cc_usbdevs_find_by_arg(device, "TeleMetrum");
99         if (!tty)
100                 tty = getenv("ALTOS_TTY");
101         if (!tty)
102                 tty="/dev/ttyACM0";
103         cc = cc_usb_open(tty);
104         if (!cc)
105                 exit(1);
106         /* send a 'version' command followed by a 'log' command */
107         cc_usb_printf(cc, "v\n");
108         out = NULL;
109         for (;;) {
110                 cc_usb_getline(cc, line, sizeof (line));
111                 if (sscanf(line, "serial-number %u", &serial_number) == 1) {
112                         filename = cc_make_filename(serial_number, "eeprom");
113                         out = fopen (filename, "w");
114                         if (!out) {
115                                 perror(filename);
116                         }
117                         fprintf (out, "%s\n", line);
118                 }
119                 if (!strncmp(line, "software-version", 16))
120                         break;
121         }
122         if (!out) {
123                 fprintf(stderr, "no serial number found\n");
124                 cc_usb_close(cc);
125                 exit(1);
126         }
127         printf ("Serial number: %d\n", serial_number);
128         printf ("File name:     %s\n", filename);
129         done = 0;
130         column = 0;
131         for (block = 0; !done && block < 511; block++) {
132                 cc_usb_printf(cc, "e %x\n", block);
133                 if (column == 64) {
134                         putchar('\n');
135                         column = 0;
136                 }
137                 putchar('.'); fflush(stdout); column++;
138                 for (addr = 0; addr < 0x100;) {
139                         cc_usb_getline(cc, line, sizeof (line));
140                         if (sscanf(line, "00%x %x %x %x %x %x %x %x %x",
141                                           &received_addr,
142                                           &data[0], &data[1], &data[2], &data[3],
143                                           &data[4], &data[5], &data[6], &data[7]) == 9)
144                         {
145                                 if (received_addr != addr)
146                                         fprintf(stderr, "data out of sync at 0x%x\n",
147                                                 block * 256 + received_addr);
148
149                                 if (log_checksum(data) != 0)
150                                         fprintf (stderr, "invalid checksum at 0x%x\n",
151                                                  block * 256 + received_addr);
152
153                                 cmd = data[0];
154                                 tick = data[2] + (data[3] << 8);
155                                 a = data[4] + (data[5] << 8);
156                                 b = data[6] + (data[7] << 8);
157                                 if (cmd == 'S' && a <= 8) {
158                                         if (column) putchar('\n');
159                                         printf("%s\n", state_names[a]);
160                                         column = 0;
161                                 }
162                                 if (out) {
163                                         fprintf(out, "%c %4x %4x %4x\n",
164                                                 cmd, tick, a, b);
165                                         if (cmd == 'S' && a == 8) {
166                                                 fclose(out);
167                                                 out = NULL;
168                                                 done = 1;
169                                         }
170                                 }
171                                 addr += 8;
172                         }
173                 }
174         }
175         if (column)
176                 putchar('\n');
177         if (out)
178                 fclose (out);
179         cc_usb_close(cc);
180         exit (0);
181 }