altos: Add bit-bang i2c driver
[fw/altos] / src / microtest / ao_microtest.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 <ao.h>
20 #include <ao_micropeak.h>
21 #include <ao_ms5607.h>
22 #include <ao_async.h>
23 #include <ao_log_micro.h>
24
25 static struct ao_ms5607_value   value;
26
27 alt_t           ground_alt, max_alt;
28 alt_t           ao_max_height;
29
30 void
31 ao_pa_get(void)
32 {
33         ao_ms5607_sample(&ao_ms5607_current);
34         ao_ms5607_convert(&ao_ms5607_current, &value);
35         pa = value.pres;
36 }
37 static void
38 ao_pips(void)
39 {
40         uint8_t i;
41         for (i = 0; i < 10; i++) {
42                 ao_led_toggle(AO_LED_REPORT);
43                 ao_delay(AO_MS_TO_TICKS(80));
44         }
45         ao_delay(AO_MS_TO_TICKS(200));
46 }
47
48 #define POLY 0x8408
49
50 static uint16_t
51 ao_log_micro_crc(uint16_t crc, uint8_t byte)
52 {
53         uint8_t i;
54
55         for (i = 0; i < 8; i++) {
56                 if ((crc & 0x0001) ^ (byte & 0x0001))
57                         crc = (crc >> 1) ^ POLY;
58                 else
59                         crc = crc >> 1;
60                 byte >>= 1;
61         }
62         return crc;
63 }
64
65 struct header {
66         uint32_t        pa_ground_offset;
67         uint32_t        pa_min_offset;
68         N_SAMPLES_TYPE  nsamples;
69 };
70
71 static const struct header head = {
72         .pa_ground_offset = 0xfffefdfc,
73         .pa_min_offset = 0xfbfaf9f8,
74         .nsamples = 64
75 };
76
77 static void
78 ao_test_micro_dump(void)
79 {
80         N_SAMPLES_TYPE  n_samples;
81         uint16_t        nbytes;
82         uint8_t         byte;
83         uint16_t        b;
84         uint16_t        crc = 0xffff;
85
86         n_samples = head.nsamples;
87         nbytes = STARTING_LOG_OFFSET + sizeof (uint16_t) * n_samples;
88
89         /*
90          * Rewrite n_samples so that it includes the log ID value with
91          * 32-bit n_samples split into two chunks
92          */
93         if (sizeof (n_samples) > 2) {
94                 N_SAMPLES_TYPE  n_samples_low;
95                 N_SAMPLES_TYPE  n_samples_high;
96                 n_samples_low = n_samples & ((1 << AO_LOG_ID_SHIFT) - 1);
97                 n_samples_high = (n_samples - n_samples_low) << AO_LOG_ID_WIDTH;
98                 n_samples = n_samples_low | n_samples_high;
99         }
100 #if AO_LOG_ID
101         n_samples |= AO_LOG_ID << AO_LOG_ID_SHIFT;
102 #endif
103         ao_async_start();
104         ao_async_byte('M');
105         ao_async_byte('P');
106         for (b = 0; b < nbytes; b++) {
107                 if ((b & 0xf) == 0)
108                         ao_log_newline();
109                 if (b < sizeof (head))
110                         byte = ((uint8_t *) &head)[b];
111                 else
112                         byte = b;
113 #if AO_LOG_ID
114                 if (N_SAMPLES_OFFSET <= b && b < (N_SAMPLES_OFFSET + sizeof(n_samples))) {
115                         byte = n_samples >> ((b - N_SAMPLES_OFFSET) << 3);
116                 }
117 #endif
118                 ao_log_hex(byte);
119                 crc = ao_log_micro_crc(crc, byte);
120         }
121         ao_log_newline();
122         crc = ~crc;
123         ao_log_hex(crc >> 8);
124         ao_log_hex(crc);
125         ao_log_newline();
126         ao_async_stop();
127 }
128
129 int
130 main(void)
131 {
132         ao_led_init();
133         ao_timer_init();
134
135         /* Init external hardware */
136         ao_spi_init();
137         ao_ms5607_init();
138         ao_ms5607_setup();
139
140         for (;;)
141         {
142                 ao_delay(AO_MS_TO_TICKS(1000));
143
144                 ao_pips();
145                 ao_test_micro_dump();
146         }
147 }