25a1662f287ca45f2a335305613e35f9bfd60382
[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 #include "gps_venus.h"
59 #include "sd_log.h"
60 #include "../common/i2c_commands.h"
61 #include "i2c_protocol.h"
62 #include "imu.h"
63 #include "main.h"
64
65 struct imuboard imuboard;
66 volatile uint32_t global_ms;
67
68 /* global xbee device */
69 struct xbee_dev *xbee_dev;
70
71 void bootloader(void)
72 {
73 #define BOOTLOADER_ADDR 0x3f000
74         if (pgm_read_byte_far(BOOTLOADER_ADDR) == 0xff) {
75                 printf_P(PSTR("Bootloader is not present\r\n"));
76                 return;
77         }
78         cli();
79         /* ... very specific :( */
80         TIMSK0 = 0;
81         TIMSK1 = 0;
82         TIMSK2 = 0;
83         TIMSK3 = 0;
84         EIMSK = 0;
85         UCSR0B = 0;
86         UCSR1B = 0;
87         SPCR = 0;
88         TWCR = 0;
89         ACSR = 0;
90         ADCSRA = 0;
91
92         /* XXX */
93         /* __asm__ __volatile__ ("ldi r31,0xf8\n"); */
94         /* __asm__ __volatile__ ("ldi r30,0x00\n"); */
95         /* __asm__ __volatile__ ("eijmp\n"); */
96 }
97
98 /* return time in milliseconds on unsigned 16 bits */
99 uint16_t get_time_ms(void)
100 {
101         uint16_t ms;
102         uint8_t flags;
103         IRQ_LOCK(flags);
104         ms = global_ms;
105         IRQ_UNLOCK(flags);
106         return ms;
107 }
108
109 static void main_timer_interrupt(void)
110 {
111         static uint16_t cycles;
112         static uint8_t stack = 0;
113         static uint8_t cpt = 0;
114         cpt++;
115
116         /* LED blink */
117         if (global_ms & 0x80)
118                 LED1_ON();
119         else
120                 LED1_OFF();
121
122         if ((cpt & 0x03) != 0)
123                 return;
124
125         /* the following code is only called one interrupt among 4: every 682us
126          * (at 12 Mhz) = 8192 cycles */
127         cycles += 8192;
128         if (cycles >= 12000) {
129                 cycles -= 12000;
130                 global_ms ++;
131         }
132
133         /* called  */
134         if (stack++ == 0)
135                 LED2_ON();
136         sei();
137         if ((cpt & 0x3) == 0)
138                 callout_manage(&imuboard.intr_cm);
139         cli();
140         if (--stack == 0)
141                 LED2_OFF();
142 }
143
144 int main(void)
145 {
146         DDRB = 0x18 /* LEDs */;
147
148         uart_init();
149         uart_register_rx_event(CMDLINE_UART, emergency);
150
151         fdevopen(cmdline_dev_send, cmdline_dev_recv);
152         timer_init();
153         timer0_register_OV_intr(main_timer_interrupt);
154
155         callout_mgr_init(&imuboard.intr_cm, get_time_ms);
156
157         cmdline_init();
158         /* LOGS */
159         error_register_emerg(mylog);
160         error_register_error(mylog);
161         error_register_warning(mylog);
162         error_register_notice(mylog);
163         error_register_debug(mylog);
164
165         /* communication with mpu6050 */
166         i2cm_init();
167
168         /* i2c hw to communicate with mainboard */
169         i2c_init(I2C_MODE_SLAVE, I2C_IMUBOARD_ADDR);
170         i2c_protocol_init();
171         i2c_register_recv_event(i2c_recvevent);
172         i2c_register_send_event(i2c_sendevent);
173
174         sei();
175         printf_P(PSTR("starting...\r\n"));
176         eeprom_load_config();
177
178         sd_log_open();
179
180         printf_P(PSTR("\r\n"));
181         rdline_newline(&imuboard.rdl, imuboard.prompt);
182
183         imu_init();
184         gps_venus_init();
185
186         imuboard.flags |= IMUBOARD_F_BOOT_OK;
187
188         while (1) {
189                 imu_log(0);
190                 gps_log(0);
191                 cmdline_poll();
192         }
193
194         return 0;
195 }