ao-tools: Change ao-eeprom into eeprom analysis tool
[fw/altos] / ao-tools / lib / ao-eeprom-read.h
1 /*
2  * Copyright © 2017 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
15 #ifndef _AO_EEPROM_READ_H_
16 #define _AO_EEPROM_READ_H_
17
18 #include <stdint.h>
19 #include <stdio.h>
20 #include <ao-ms5607.h>
21
22 #define AO_MAX_CALLSIGN 8
23 #define AO_AES_LEN      16
24 #define AO_PYRO_NUM     8
25
26 /* required functions from the underlying log system */
27
28 #define AO_LOG_FORMAT_UNKNOWN           0       /* unknown; altosui will have to guess */
29 #define AO_LOG_FORMAT_FULL              1       /* 8 byte typed log records */
30 #define AO_LOG_FORMAT_TINY              2       /* two byte state/baro records */
31 #define AO_LOG_FORMAT_TELEMETRY         3       /* 32 byte ao_telemetry records */
32 #define AO_LOG_FORMAT_TELESCIENCE       4       /* 32 byte typed telescience records */
33 #define AO_LOG_FORMAT_TELEMEGA_OLD      5       /* 32 byte typed telemega records */
34 #define AO_LOG_FORMAT_EASYMINI1         6       /* 16-byte MS5607 baro only, 3.0V supply */
35 #define AO_LOG_FORMAT_TELEMETRUM        7       /* 16-byte typed telemetrum records */
36 #define AO_LOG_FORMAT_TELEMINI2         8       /* 16-byte MS5607 baro only, 3.3V supply, cc1111 SoC */
37 #define AO_LOG_FORMAT_TELEGPS           9       /* 32 byte telegps records */
38 #define AO_LOG_FORMAT_TELEMEGA          10      /* 32 byte typed telemega records with 32 bit gyro cal */
39 #define AO_LOG_FORMAT_DETHERM           11      /* 16-byte MS5607 baro only, no ADC */
40 #define AO_LOG_FORMAT_TELEMINI3         12      /* 16-byte MS5607 baro only, 3.3V supply, stm32f042 SoC */
41 #define AO_LOG_FORMAT_TELEFIRETWO       13      /* 32-byte test stand data */
42 #define AO_LOG_FORMAT_EASYMINI2         14      /* 16-byte MS5607 baro only, 3.3V supply, stm32f042 SoC */
43 #define AO_LOG_FORMAT_TELEMEGA_3        15      /* 32 byte typed telemega records with 32 bit gyro cal and mpu9250 */
44 #define AO_LOG_FORMAT_EASYMEGA_2        16      /* 32 byte typed telemega records with 32 bit gyro cal, mpu9250 rotated 90° and adxl375 */
45 #define AO_LOG_FORMAT_TELESTATIC        17      /* 32 byte typed telestatic records */
46 #define AO_LOG_FORMAT_MICROPEAK2        18      /* 2-byte baro values with header */
47 #define AO_LOG_FORMAT_NONE              127     /* No log at all */
48
49 enum ao_pyro_flag {
50         ao_pyro_none                    = 0x00000000,
51
52         ao_pyro_accel_less              = 0x00000001,
53         ao_pyro_accel_greater           = 0x00000002,
54
55         ao_pyro_speed_less              = 0x00000004,
56         ao_pyro_speed_greater           = 0x00000008,
57
58         ao_pyro_height_less             = 0x00000010,
59         ao_pyro_height_greater          = 0x00000020,
60
61         ao_pyro_orient_less             = 0x00000040,
62         ao_pyro_orient_greater          = 0x00000080,
63
64         ao_pyro_time_less               = 0x00000100,
65         ao_pyro_time_greater            = 0x00000200,
66
67         ao_pyro_ascending               = 0x00000400,
68         ao_pyro_descending              = 0x00000800,
69
70         ao_pyro_after_motor             = 0x00001000,
71
72         ao_pyro_delay                   = 0x00002000,
73
74         ao_pyro_state_less              = 0x00004000,
75         ao_pyro_state_greater_or_equal  = 0x00008000,
76 };
77
78 struct ao_pyro {
79         enum ao_pyro_flag       flags;
80         int16_t                 accel_less, accel_greater;
81         int16_t                 speed_less, speed_greater;
82         int16_t                 height_less, height_greater;
83         int16_t                 orient_less, orient_greater;
84         int16_t                 time_less, time_greater;
85         int16_t                 delay;
86         uint8_t                 state_less, state_greater_or_equal;
87         int16_t                 motor;
88         uint16_t                delay_done;
89         uint8_t                 _unused;        /* was 'fired' */
90 };
91
92 struct ao_config {
93         uint8_t         major;
94         uint8_t         minor;
95         uint16_t        main_deploy;
96         int16_t         accel_plus_g;           /* changed for minor version 2 */
97         uint8_t         _legacy_radio_channel;
98         char            callsign[AO_MAX_CALLSIGN + 1];
99         uint8_t         apogee_delay;           /* minor version 1 */
100         int16_t         accel_minus_g;          /* minor version 2 */
101         uint32_t        radio_cal;              /* minor version 3 */
102         uint32_t        flight_log_max;         /* minor version 4 */
103         uint8_t         ignite_mode;            /* minor version 5 */
104         uint8_t         pad_orientation;        /* minor version 6 */
105         uint32_t        radio_setting;          /* minor version 7 */
106         uint8_t         radio_enable;           /* minor version 8 */
107         uint8_t         aes_key[AO_AES_LEN];    /* minor version 9 */
108         uint32_t        frequency;              /* minor version 10 */
109         uint16_t        apogee_lockout;         /* minor version 11 */
110         struct ao_pyro  pyro[AO_PYRO_NUM];      /* minor version 12 */
111         uint16_t        aprs_interval;          /* minor version 13 */
112         uint8_t         radio_power;            /* minor version 14 */
113         uint8_t         radio_amp;              /* minor version 14 */
114         int16_t         accel_zero_along;       /* minor version 15 */
115         int16_t         accel_zero_across;      /* minor version 15 */
116         int16_t         accel_zero_through;     /* minor version 15 */
117         uint8_t         mid_beep;               /* minor version 16 */
118         uint16_t        tracker_motion;         /* minor version 17 */
119         uint8_t         tracker_interval;       /* minor version 17 */
120         uint16_t        pyro_time;              /* minor version 18 */
121         uint8_t         aprs_ssid;              /* minor version 19 */
122         uint8_t         radio_rate;             /* minor version 20 */
123         uint32_t        send_frequency;         /* minor version 21 */
124         uint8_t         aprs_format;            /* minor version 22 */
125         uint8_t         pad_box;                /* minor version 22 */
126         uint8_t         pad_idle;               /* minor version 23 */
127 };
128
129 /*
130  * ao_log_big.c
131  */
132
133 /*
134  * The data log is recorded in the eeprom as a sequence
135  * of data packets.
136  *
137  * Each packet starts with a 4-byte header that has the
138  * packet type, the packet checksum and the tick count. Then
139  * they all contain 2 16 bit values which hold packet-specific
140  * data.
141  *
142  * For each flight, the first packet
143  * is FLIGHT packet, indicating the serial number of the
144  * device and a unique number marking the number of flights
145  * recorded by this device.
146  *
147  * During flight, data from the accelerometer and barometer
148  * are recorded in SENSOR packets, using the raw 16-bit values
149  * read from the A/D converter.
150  *
151  * Also during flight, but at a lower rate, the deployment
152  * sensors are recorded in DEPLOY packets. The goal here is to
153  * detect failure in the deployment circuits.
154  *
155  * STATE packets hold state transitions as the flight computer
156  * transitions through different stages of the flight.
157  */
158 #define AO_LOG_FLIGHT           'F'
159 #define AO_LOG_SENSOR           'A'
160 #define AO_LOG_TEMP_VOLT        'T'
161 #define AO_LOG_DEPLOY           'D'
162 #define AO_LOG_STATE            'S'
163 #define AO_LOG_GPS_TIME         'G'
164 #define AO_LOG_GPS_LAT          'N'
165 #define AO_LOG_GPS_LON          'W'
166 #define AO_LOG_GPS_ALT          'H'
167 #define AO_LOG_GPS_SAT          'V'
168 #define AO_LOG_GPS_DATE         'Y'
169 #define AO_LOG_GPS_POS          'P'
170
171 #define AO_LOG_POS_NONE         (~0UL)
172
173 /* Common header in all log formats */
174 struct ao_log_header {
175         char                    type;                           /* 0 */
176         uint8_t                 csum;                           /* 1 */
177         uint16_t                tick;                           /* 2 */
178 };
179
180 struct ao_log_record {
181         char                    type;                           /* 0 */
182         uint8_t                 csum;                           /* 1 */
183         uint16_t                tick;                           /* 2 */
184         union {
185                 struct {
186                         int16_t         ground_accel;           /* 4 */
187                         uint16_t        flight;                 /* 6 */
188                 } flight;
189                 struct {
190                         int16_t         accel;                  /* 4 */
191                         int16_t         pres;                   /* 6 */
192                 } sensor;
193                 struct {
194                         int16_t         temp;
195                         int16_t         v_batt;
196                 } temp_volt;
197                 struct {
198                         int16_t         drogue;
199                         int16_t         main;
200                 } deploy;
201                 struct {
202                         uint16_t        state;
203                         uint16_t        reason;
204                 } state;
205                 struct {
206                         uint8_t         hour;
207                         uint8_t         minute;
208                         uint8_t         second;
209                         uint8_t         flags;
210                 } gps_time;
211                 int32_t         gps_latitude;
212                 int32_t         gps_longitude;
213                 struct {
214                         uint16_t        altitude_low;
215                         int16_t         altitude_high;
216                 } gps_altitude;
217                 struct {
218                         uint16_t        svid;
219                         uint8_t         unused;
220                         uint8_t         c_n;
221                 } gps_sat;
222                 struct {
223                         uint8_t         year;
224                         uint8_t         month;
225                         uint8_t         day;
226                         uint8_t         extra;
227                 } gps_date;
228                 struct {
229                         uint16_t        d0;
230                         uint16_t        d1;
231                 } anon;
232         } u;
233 };
234
235 struct ao_log_mega {
236         char                    type;                   /* 0 */
237         uint8_t                 csum;                   /* 1 */
238         uint16_t                tick;                   /* 2 */
239         union {                                         /* 4 */
240                 /* AO_LOG_FLIGHT */
241                 struct {
242                         uint16_t        flight;                 /* 4 */
243                         int16_t         ground_accel;           /* 6 */
244                         uint32_t        ground_pres;            /* 8 */
245                         int16_t         ground_accel_along;     /* 12 */
246                         int16_t         ground_accel_across;    /* 14 */
247                         int16_t         ground_accel_through;   /* 16 */
248                         int16_t         pad_18;                 /* 18 */
249                         int32_t         ground_roll;            /* 20 */
250                         int32_t         ground_pitch;           /* 24 */
251                         int32_t         ground_yaw;             /* 28 */
252                 } flight;                                       /* 32 */
253                 struct {
254                         uint16_t        flight;                 /* 4 */
255                         int16_t         ground_accel;           /* 6 */
256                         uint32_t        ground_pres;            /* 8 */
257                         int16_t         ground_accel_along;     /* 12 */
258                         int16_t         ground_accel_across;    /* 14 */
259                         int16_t         ground_accel_through;   /* 16 */
260                         int16_t         ground_roll;            /* 18 */
261                         int16_t         ground_pitch;           /* 20 */
262                         int16_t         ground_yaw;             /* 22 */
263                 } flight_old;                                   /* 24 */
264                 /* AO_LOG_STATE */
265                 struct {
266                         uint16_t        state;
267                         uint16_t        reason;
268                 } state;
269                 /* AO_LOG_SENSOR */
270                 struct {
271                         uint32_t        pres;           /* 4 */
272                         uint32_t        temp;           /* 8 */
273                         int16_t         accel_x;        /* 12 */
274                         int16_t         accel_y;        /* 14 */
275                         int16_t         accel_z;        /* 16 */
276                         int16_t         gyro_x;         /* 18 */
277                         int16_t         gyro_y;         /* 20 */
278                         int16_t         gyro_z;         /* 22 */
279                         int16_t         mag_x;          /* 24 */
280                         int16_t         mag_z;          /* 26 */
281                         int16_t         mag_y;          /* 28 */
282                         int16_t         accel;          /* 30 */
283                 } sensor;       /* 32 */
284                 /* AO_LOG_TEMP_VOLT */
285                 struct {
286                         int16_t         v_batt;         /* 4 */
287                         int16_t         v_pbatt;        /* 6 */
288                         int16_t         n_sense;        /* 8 */
289                         int16_t         sense[10];      /* 10 */
290                         uint16_t        pyro;           /* 30 */
291                 } volt;                                 /* 32 */
292                 /* AO_LOG_GPS_TIME */
293                 struct {
294                         int32_t         latitude;       /* 4 */
295                         int32_t         longitude;      /* 8 */
296                         uint16_t        altitude_low;   /* 12 */
297                         uint8_t         hour;           /* 14 */
298                         uint8_t         minute;         /* 15 */
299                         uint8_t         second;         /* 16 */
300                         uint8_t         flags;          /* 17 */
301                         uint8_t         year;           /* 18 */
302                         uint8_t         month;          /* 19 */
303                         uint8_t         day;            /* 20 */
304                         uint8_t         course;         /* 21 */
305                         uint16_t        ground_speed;   /* 22 */
306                         int16_t         climb_rate;     /* 24 */
307                         uint8_t         pdop;           /* 26 */
308                         uint8_t         hdop;           /* 27 */
309                         uint8_t         vdop;           /* 28 */
310                         uint8_t         mode;           /* 29 */
311                         int16_t         altitude_high;  /* 30 */
312                 } gps;  /* 32 */
313                 /* AO_LOG_GPS_SAT */
314                 struct {
315                         uint16_t        channels;       /* 4 */
316                         struct {
317                                 uint8_t svid;
318                                 uint8_t c_n;
319                         } sats[12];                     /* 6 */
320                 } gps_sat;                              /* 30 */
321         } u;
322 };
323
324 #define AO_LOG_MEGA_GPS_ALTITUDE(l)     ((int32_t) ((l)->u.gps.altitude_high << 16) | ((l)->u.gps.altitude_low))
325 #define AO_LOG_MEGA_SET_GPS_ALTITUDE(l,a)       (((l)->u.gps.mode |= AO_GPS_MODE_ALTITUDE_24), \
326                                                  ((l)->u.gps.altitude_high = (a) >> 16), \
327                                                  (l)->u.gps.altitude_low = (a))
328
329 struct ao_log_firetwo {
330         char                    type;                   /* 0 */
331         uint8_t                 csum;                   /* 1 */
332         uint16_t                tick;                   /* 2 */
333         union {                                         /* 4 */
334                 /* AO_LOG_FLIGHT */
335                 struct {
336                         uint16_t        flight;         /* 4 */
337                 } flight;       /* 6 */
338                 /* AO_LOG_STATE */
339                 struct {
340                         uint16_t        state;          /* 4 */
341                         uint16_t        reason;         /* 6 */
342                 } state;        /* 8 */
343                 /* AO_LOG_SENSOR */
344                 struct {
345                         uint16_t        pressure;       /* 4 */
346                         uint16_t        thrust;         /* 6 */
347                         uint16_t        thermistor[4];  /* 8 */
348                 } sensor;       /* 24 */
349                 uint8_t         align[28];              /* 4 */
350         } u;    /* 32 */
351 };
352
353 struct ao_log_telestatic {
354         char                    type;                   /* 0 */
355         uint8_t                 csum;                   /* 1 */
356         uint16_t                tick;                   /* 2 */
357         union {                                         /* 4 */
358                 /* AO_LOG_FLIGHT */
359                 struct {
360                         uint16_t        flight;         /* 4 */
361                 } flight;       /* 6 */
362                 /* AO_LOG_STATE */
363                 struct {
364                         uint16_t        state;          /* 4 */
365                         uint16_t        reason;         /* 6 */
366                 } state;        /* 8 */
367                 /* AO_LOG_SENSOR */
368                 struct {
369                         uint32_t        pressure;       /* 4 */
370                         uint32_t        pressure2;      /* 8 */
371                         uint32_t        thrust;         /* 12 */
372                         uint32_t        mass;           /* 16 */
373                         uint16_t        t_low;          /* 20 */
374                         uint16_t        t_high[4];      /* 22 */
375                 } sensor;       /* 30 */
376                 uint8_t         align[28];              /* 4 */
377         } u;    /* 32 */
378 };
379
380 struct ao_log_metrum {
381         char                    type;                   /* 0 */
382         uint8_t                 csum;                   /* 1 */
383         uint16_t                tick;                   /* 2 */
384         union {                                         /* 4 */
385                 /* AO_LOG_FLIGHT */
386                 struct {
387                         uint16_t        flight;         /* 4 */
388                         int16_t         ground_accel;   /* 6 */
389                         uint32_t        ground_pres;    /* 8 */
390                         uint32_t        ground_temp;    /* 12 */
391                 } flight;       /* 16 */
392                 /* AO_LOG_STATE */
393                 struct {
394                         uint16_t        state;          /* 4 */
395                         uint16_t        reason;         /* 6 */
396                 } state;        /* 8 */
397                 /* AO_LOG_SENSOR */
398                 struct {
399                         uint32_t        pres;           /* 4 */
400                         uint32_t        temp;           /* 8 */
401                         int16_t         accel;          /* 12 */
402                 } sensor;       /* 14 */
403                 /* AO_LOG_TEMP_VOLT */
404                 struct {
405                         int16_t         v_batt;         /* 4 */
406                         int16_t         sense_a;        /* 6 */
407                         int16_t         sense_m;        /* 8 */
408                 } volt;         /* 10 */
409                 /* AO_LOG_GPS_POS */
410                 struct {
411                         int32_t         latitude;       /* 4 */
412                         int32_t         longitude;      /* 8 */
413                         uint16_t        altitude_low;   /* 12 */
414                         int16_t         altitude_high;  /* 14 */
415                 } gps;          /* 16 */
416                 /* AO_LOG_GPS_TIME */
417                 struct {
418                         uint8_t         hour;           /* 4 */
419                         uint8_t         minute;         /* 5 */
420                         uint8_t         second;         /* 6 */
421                         uint8_t         flags;          /* 7 */
422                         uint8_t         year;           /* 8 */
423                         uint8_t         month;          /* 9 */
424                         uint8_t         day;            /* 10 */
425                         uint8_t         pdop;           /* 11 */
426                 } gps_time;     /* 12 */
427                 /* AO_LOG_GPS_SAT (up to three packets) */
428                 struct {
429                         uint8_t channels;               /* 4 */
430                         uint8_t more;                   /* 5 */
431                         struct {
432                                 uint8_t svid;
433                                 uint8_t c_n;
434                         } sats[4];                      /* 6 */
435                 } gps_sat;                              /* 14 */
436                 uint8_t         raw[12];                /* 4 */
437         } u;    /* 16 */
438 };
439
440 struct ao_log_mini {
441         char            type;                           /* 0 */
442         uint8_t         csum;                           /* 1 */
443         uint16_t        tick;                           /* 2 */
444         union {                                         /* 4 */
445                 /* AO_LOG_FLIGHT */
446                 struct {
447                         uint16_t        flight;         /* 4 */
448                         uint16_t        r6;
449                         uint32_t        ground_pres;    /* 8 */
450                 } flight;
451                 /* AO_LOG_STATE */
452                 struct {
453                         uint16_t        state;          /* 4 */
454                         uint16_t        reason;         /* 6 */
455                 } state;
456                 /* AO_LOG_SENSOR */
457                 struct {
458                         uint8_t         pres[3];        /* 4 */
459                         uint8_t         temp[3];        /* 7 */
460                         int16_t         sense_a;        /* 10 */
461                         int16_t         sense_m;        /* 12 */
462                         int16_t         v_batt;         /* 14 */
463                 } sensor;                               /* 16 */
464         } u;                                            /* 16 */
465 };                                                      /* 16 */
466
467 #define ao_log_pack24(dst,value) do {           \
468                 (dst)[0] = (value);             \
469                 (dst)[1] = (value) >> 8;        \
470                 (dst)[2] = (value) >> 16;       \
471         } while (0)
472
473 struct ao_log_gps {
474         char                    type;                   /* 0 */
475         uint8_t                 csum;                   /* 1 */
476         uint16_t                tick;                   /* 2 */
477         union {                                         /* 4 */
478                 /* AO_LOG_FLIGHT */
479                 struct {
480                         uint16_t        flight;                 /* 4 */
481                         int16_t         start_altitude;         /* 6 */
482                         int32_t         start_latitude;         /* 8 */
483                         int32_t         start_longitude;        /* 12 */
484                 } flight;                                       /* 16 */
485                 /* AO_LOG_GPS_TIME */
486                 struct {
487                         int32_t         latitude;       /* 4 */
488                         int32_t         longitude;      /* 8 */
489                         uint16_t        altitude_low;   /* 12 */
490                         uint8_t         hour;           /* 14 */
491                         uint8_t         minute;         /* 15 */
492                         uint8_t         second;         /* 16 */
493                         uint8_t         flags;          /* 17 */
494                         uint8_t         year;           /* 18 */
495                         uint8_t         month;          /* 19 */
496                         uint8_t         day;            /* 20 */
497                         uint8_t         course;         /* 21 */
498                         uint16_t        ground_speed;   /* 22 */
499                         int16_t         climb_rate;     /* 24 */
500                         uint8_t         pdop;           /* 26 */
501                         uint8_t         hdop;           /* 27 */
502                         uint8_t         vdop;           /* 28 */
503                         uint8_t         mode;           /* 29 */
504                         int16_t         altitude_high;  /* 30 */
505                 } gps;  /* 31 */
506                 /* AO_LOG_GPS_SAT */
507                 struct {
508                         uint16_t        channels;       /* 4 */
509                         struct {
510                                 uint8_t svid;
511                                 uint8_t c_n;
512                         } sats[12];                     /* 6 */
513                 } gps_sat;                              /* 30 */
514         } u;
515 };
516
517 struct ao_eeprom {
518         struct ao_config        config;
519         struct ao_ms5607_prom   ms5607_prom;
520         int                     log_format;
521         uint16_t                serial_number;
522         uint8_t                 *data;
523         uint32_t                len;
524 };
525
526 struct ao_eeprom *ao_eeprom_read(FILE *file);
527
528 struct ao_eeprom *ao_eeprom_read_old(FILE *file);
529
530 void ao_eeprom_free_data(struct ao_eeprom *ao_eeprom);
531
532 #endif /* _AO_EEPROM_READ_H_ */