altos: Add telerepeat-v1.0
[fw/altos] / src / kernel / ao_log_micro.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; version 2 of the License.
7  *
8  * This program is distributed in the hope that it will be useful, but
9  * WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11  * General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License along
14  * with this program; if not, write to the Free Software Foundation, Inc.,
15  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
16  */
17
18 #include <ao.h>
19 #include <ao_micropeak.h>
20 #include <ao_log_micro.h>
21 #include <ao_async.h>
22
23 static uint16_t ao_log_offset = STARTING_LOG_OFFSET;
24
25 #define AO_LOG_ID_SHIFT 12
26 #define AO_LOG_ID_MASK  ((1 << AO_LOG_ID_SHIFT) - 1)
27
28 void
29 ao_log_micro_save(void)
30 {
31         uint16_t        n_samples = (ao_log_offset - STARTING_LOG_OFFSET) / sizeof (uint16_t);
32
33 #if AO_LOG_ID
34         n_samples |= AO_LOG_ID << AO_LOG_ID_SHIFT;
35 #endif
36         ao_eeprom_write(PA_GROUND_OFFSET, &pa_ground, sizeof (pa_ground));
37         ao_eeprom_write(PA_MIN_OFFSET, &pa_min, sizeof (pa_min));
38         ao_eeprom_write(N_SAMPLES_OFFSET, &n_samples, sizeof (n_samples));
39 }
40
41 void
42 ao_log_micro_restore(void)
43 {
44         ao_eeprom_read(PA_GROUND_OFFSET, &pa_ground, sizeof (pa_ground));
45         ao_eeprom_read(PA_MIN_OFFSET, &pa_min, sizeof (pa_min));
46 }
47
48 void
49 ao_log_micro_data(void)
50 {
51         uint16_t        low_bits = pa;
52
53         if (ao_log_offset < MAX_LOG_OFFSET) {
54                 ao_eeprom_write(ao_log_offset, &low_bits, sizeof (low_bits));
55                 ao_log_offset += sizeof (low_bits);
56         }
57 }
58
59 #define POLY 0x8408
60
61 static uint16_t
62 ao_log_micro_crc(uint16_t crc, uint8_t byte)
63 {
64         uint8_t i;
65
66         for (i = 0; i < 8; i++) {
67                 if ((crc & 0x0001) ^ (byte & 0x0001))
68                         crc = (crc >> 1) ^ POLY;
69                 else
70                         crc = crc >> 1;
71                 byte >>= 1;
72         }
73         return crc;
74 }
75
76 static void
77 ao_log_hex_nibble(uint8_t b)
78 {
79         if (b < 10)
80                 ao_async_byte('0' + b);
81         else
82                 ao_async_byte('a' - 10 + b);
83 }
84
85 static void
86 ao_log_hex(uint8_t b)
87 {
88         ao_log_hex_nibble(b>>4);
89         ao_log_hex_nibble(b&0xf);
90 }
91
92 static void
93 ao_log_newline(void)
94 {
95         ao_async_byte('\r');
96         ao_async_byte('\n');
97 }
98
99 void
100 ao_log_micro_dump(void)
101 {
102         uint16_t        n_samples;
103         uint16_t        nbytes;
104         uint8_t         byte;
105         uint16_t        b;
106         uint16_t        crc = 0xffff;
107
108         ao_eeprom_read(N_SAMPLES_OFFSET, &n_samples, sizeof (n_samples));
109
110         if (n_samples == 0xffff)
111                 n_samples = 0;
112 #if AO_LOG_ID
113         n_samples &= AO_LOG_ID_MASK;
114 #endif
115         nbytes = STARTING_LOG_OFFSET + sizeof (uint16_t) * n_samples;
116         ao_async_start();
117         ao_async_byte('M');
118         ao_async_byte('P');
119         for (b = 0; b < nbytes; b++) {
120                 if ((b & 0xf) == 0)
121                         ao_log_newline();
122                 ao_eeprom_read(b, &byte, 1);
123                 ao_log_hex(byte);
124                 crc = ao_log_micro_crc(crc, byte);
125         }
126         ao_log_newline();
127         crc = ~crc;
128         ao_log_hex(crc >> 8);
129         ao_log_hex(crc);
130         ao_log_newline();
131         ao_async_stop();
132 }