Switch from GPLv2 to GPLv2+
[fw/altos] / ao-tools / lib / cc-mega.c
1 /*
2  * Copyright © 2012 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 "cc.h"
20 #include <string.h>
21 #include <ctype.h>
22
23 static const char *
24 parse_hex(const char *data, int *result)
25 {
26         char    d[12];
27         int     x;
28         int     i;
29
30         while (isspace (*data))
31                 data++;
32         for (i = 0; i < sizeof (d) - 1 && isxdigit(*data); i++)
33                 d[i] = *data++;
34         d[i] = '\0';
35         if (sscanf(d, "%x", &x) != 1)
36                 return NULL;
37         *result = x;
38         return data;
39 }
40
41 static const char *
42 parse_uint16(const char *data, uint16_t *result)
43 {
44         int     x;
45         data = parse_hex(data, &x);
46         *result =x;
47         return data;
48 }
49
50 static const char *
51 parse_uint8(const char *data, uint8_t *result)
52 {
53         int     x;
54         data = parse_hex(data, &x);
55         *result =x;
56         return data;
57 }
58
59 static int
60 parse_eeprom(const char *input_line, struct ao_log_mega *l) {
61         const char      *line;
62         int     b;
63
64         if (input_line[1] != ' ')
65                 return 0;
66         if (!isupper(input_line[0]))
67                 return 0;
68
69         l->type = input_line[0];
70         l->is_config = 0;
71         line = input_line + 2;
72
73         line = parse_uint16(line, &l->tick);
74         for (b = 0; b < 28; b++) {
75                 if (!line)
76                         return 0;
77                 line = parse_uint8(line, &l->u.bytes[b]);
78         }
79         return 1;
80 }
81
82 #define YUP(t) do {                             \
83                 l->u.config_int.kind = (t);     \
84                 l->is_config = 1;               \
85                 return 1;                       \
86         } while (0);
87
88 static int
89 parse_config(const char *input_line, struct ao_log_mega *l) {
90         if (sscanf (input_line, "Config version: %d.%d",
91                     &l->u.config_int.data[0],
92                     &l->u.config_int.data[1]))
93                 YUP(AO_CONFIG_CONFIG);
94         if (sscanf (input_line, "Main deploy: %d",
95                     &l->u.config_int.data[0]))
96                 YUP(AO_CONFIG_MAIN);
97         if (sscanf (input_line, "Apogee delay: %d",
98                     &l->u.config_int.data[0]))
99                 YUP(AO_CONFIG_APOGEE);
100         if (sscanf (input_line, "Apogee lockout: %d",
101                     &l->u.config_int.data[0]))
102                 YUP(AO_CONFIG_LOCKOUT);
103         if (sscanf (input_line, "Frequency: %d",
104                     &l->u.config_int.data[0]))
105                 YUP(AO_CONFIG_FREQUENCY);
106         if (sscanf (input_line, "Radio enable:  %d",
107                     &l->u.config_int.data[0]))
108                 YUP(AO_CONFIG_RADIO_ENABLE);
109         if (sscanf (input_line, "Accel cal +1g: %d -1g: %d",
110                     &l->u.config_int.data[0],
111                     &l->u.config_int.data[1]))
112                 YUP(AO_CONFIG_ACCEL_CAL);
113         if (sscanf (input_line, "Radio cal: %d",
114                     &l->u.config_int.data[0]))
115                 YUP(AO_CONFIG_RADIO_CAL);
116         if (sscanf (input_line, "Max flight log: %d",
117                     &l->u.config_int.data[0]))
118                 YUP(AO_CONFIG_MAX_LOG);
119         if (sscanf (input_line, "Ignite mode: %d",
120                     &l->u.config_int.data[0]))
121                 YUP(AO_CONFIG_IGNITE_MODE);
122         if (sscanf (input_line, "Pad orientation: %d",
123                     &l->u.config_int.data[0]))
124                 YUP(AO_CONFIG_PAD_ORIENTATION);
125         if (sscanf (input_line, "serial-number %d",
126                     &l->u.config_int.data[0]))
127                 YUP(AO_CONFIG_SERIAL_NUMBER);
128         if (sscanf (input_line, "log-format %d",
129                     &l->u.config_int.data[0]))
130                 YUP(AO_CONFIG_LOG_FORMAT);
131         if (sscanf (input_line, "ms5607 reserved: %d",
132                     &l->u.config_int.data[0]))
133                 YUP(AO_CONFIG_MS5607_RESERVED);
134         if (sscanf (input_line, "ms5607 sens: %d",
135                     &l->u.config_int.data[0]))
136                 YUP(AO_CONFIG_MS5607_SENS);
137         if (sscanf (input_line, "ms5607 off: %d",
138                     &l->u.config_int.data[0]))
139                 YUP(AO_CONFIG_MS5607_OFF);
140         if (sscanf (input_line, "ms5607 tcs: %d",
141                     &l->u.config_int.data[0]))
142                 YUP(AO_CONFIG_MS5607_TCS);
143         if (sscanf (input_line, "ms5607 tco: %d",
144                     &l->u.config_int.data[0]))
145                 YUP(AO_CONFIG_MS5607_TCO);
146         if (sscanf (input_line, "ms5607 tref: %d",
147                     &l->u.config_int.data[0]))
148                 YUP(AO_CONFIG_MS5607_TREF);
149         if (sscanf (input_line, "ms5607 tempsens: %d",
150                     &l->u.config_int.data[0]))
151                 YUP(AO_CONFIG_MS5607_TEMPSENS);
152         if (sscanf (input_line, "ms5607 crc: %d",
153                     &l->u.config_int.data[0]))
154                 YUP(AO_CONFIG_MS5607_CRC);
155         return 0;
156 }
157
158 int
159 cc_mega_parse(const char *input_line, struct ao_log_mega *l) {
160         return parse_eeprom(input_line, l) || parse_config(input_line, l);
161 }