5410074ba7e9e6e744cdfa2a82d0737c96a25e18
[fpv.git] / imuboard / main.c
1 /*
2  * Copyright (c) 2011, Olivier MATZ <zer0@droids-corp.org>
3  * All rights reserved.
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *
7  *     * Redistributions of source code must retain the above copyright
8  *       notice, this list of conditions and the following disclaimer.
9  *     * Redistributions in binary form must reproduce the above copyright
10  *       notice, this list of conditions and the following disclaimer in the
11  *       documentation and/or other materials provided with the distribution.
12  *     * Neither the name of the University of California, Berkeley nor the
13  *       names of its contributors may be used to endorse or promote products
14  *       derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
17  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19  * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
20  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27
28 /* fuses:
29  * avrdude -p atmega1284p -P usb -c avrispmkii -U lfuse:w:0xff:m -U hfuse:w:0x91:m -U efuse:w:0xff:m
30  * -> it failed but I answered y, then make reset and it was ok
31  */
32
33 #include <aversive.h>
34 #include <aversive/queue.h>
35 #include <aversive/endian.h>
36 #include <aversive/wait.h>
37 #include <aversive/error.h>
38
39 #include <uart.h>
40
41 #include <stdio.h>
42 #include <string.h>
43 #include <stdint.h>
44 #include <inttypes.h>
45 #include <stdlib.h>
46 #include <stdarg.h>
47 #include <errno.h>
48 #include <ctype.h>
49
50 #include <parse.h>
51 #include <rdline.h>
52 #include <timer.h>
53 #include <i2cm_sw.h>
54 #include <i2c.h>
55
56 #include "eeprom_config.h"
57 #include "gps.h"
58 #ifdef GPS_VENUS
59 #include "gps_venus.h"
60 #endif
61 #ifdef GPS_UBX
62 #include "gps_ubx.h"
63 #endif
64 #include "sd_log.h"
65 #include "../common/i2c_commands.h"
66 #include "i2c_protocol.h"
67 #include "imu.h"
68 #include "main.h"
69
70 struct imuboard imuboard;
71 volatile uint32_t global_ms;
72
73 void bootloader(void)
74 {
75 #define BOOTLOADER_ADDR 0x3f000
76         if (pgm_read_byte_far(BOOTLOADER_ADDR) == 0xff) {
77                 printf_P(PSTR("Bootloader is not present\r\n"));
78                 return;
79         }
80         cli();
81         /* ... very specific :( */
82         TIMSK0 = 0;
83         TIMSK1 = 0;
84         TIMSK2 = 0;
85         TIMSK3 = 0;
86         EIMSK = 0;
87         UCSR0B = 0;
88         UCSR1B = 0;
89         SPCR = 0;
90         TWCR = 0;
91         ACSR = 0;
92         ADCSRA = 0;
93
94         /* XXX */
95         /* __asm__ __volatile__ ("ldi r31,0xf8\n"); */
96         /* __asm__ __volatile__ ("ldi r30,0x00\n"); */
97         /* __asm__ __volatile__ ("eijmp\n"); */
98 }
99
100 /* return time in milliseconds on unsigned 16 bits */
101 uint16_t get_time_ms(void)
102 {
103         uint16_t ms;
104         uint8_t flags;
105         IRQ_LOCK(flags);
106         ms = global_ms;
107         IRQ_UNLOCK(flags);
108         return ms;
109 }
110
111 static void main_timer_interrupt(void)
112 {
113         static uint16_t cycles;
114         static uint8_t stack = 0;
115         static uint8_t cpt = 0;
116         cpt++;
117
118         /* LED blink */
119         if (global_ms & 0x80)
120                 LED1_ON();
121         else
122                 LED1_OFF();
123
124         if ((cpt & 0x03) != 0)
125                 return;
126
127         /* the following code is only called one interrupt among 4: every 682us
128          * (at 12 Mhz) = 8192 cycles */
129         cycles += 8192;
130         if (cycles >= 12000) {
131                 cycles -= 12000;
132                 global_ms ++;
133         }
134
135         /* called  */
136         if (stack++ == 0)
137                 LED2_ON();
138         sei();
139         if ((cpt & 0x3) == 0)
140                 callout_manage(&imuboard.intr_cm);
141         cli();
142         if (--stack == 0)
143                 LED2_OFF();
144 }
145
146 int main(void)
147 {
148         DDRB = 0x18 /* LEDs */;
149
150         uart_init();
151         uart_register_rx_event(CMDLINE_UART, emergency);
152
153         fdevopen(cmdline_dev_send, cmdline_dev_recv);
154         timer_init();
155         timer0_register_OV_intr(main_timer_interrupt);
156
157         callout_mgr_init(&imuboard.intr_cm, get_time_ms);
158
159 #if 0
160         sei(); //XXX
161         printf_P(PSTR("starting...\r\n"));
162         while (1) {
163                 int16_t c;
164                 c = uart_recv_nowait(0);
165                 if (c >= 0)
166                         printf("%x\n", (uint8_t)c);
167         }
168 #endif
169
170         cmdline_init();
171         /* LOGS */
172         error_register_emerg(mylog);
173         error_register_error(mylog);
174         error_register_warning(mylog);
175         error_register_notice(mylog);
176         error_register_debug(mylog);
177
178         /* communication with mpu6050 */
179         i2cm_init();
180
181         /* i2c hw to communicate with mainboard */
182         i2c_init(I2C_MODE_SLAVE, I2C_IMUBOARD_ADDR);
183         i2c_protocol_init();
184         i2c_register_recv_event(i2c_recvevent);
185         i2c_register_send_event(i2c_sendevent);
186
187         sei();
188         printf_P(PSTR("starting...\r\n"));
189         eeprom_load_config();
190
191         sd_log_open();
192
193         printf_P(PSTR("\r\n"));
194         rdline_newline(&imuboard.rdl, imuboard.prompt);
195
196         imu_init();
197 #ifdef GPS_VENUS
198         gps_venus_init();
199 #endif
200 #ifdef GPS_UBX
201         gps_ubx_init();
202 #endif
203
204         imuboard.flags |= IMUBOARD_F_BOOT_OK;
205
206         while (1) {
207                 imu_log(0);
208                 gps_log(0);
209                 cmdline_poll();
210         }
211
212         return 0;
213 }