imuboard: fix call to bootloader
[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  * with bootloader:
33  * avrdude -p atmega1284p -P usb -c avrispmkii -U lfuse:w:0xff:m -U hfuse:w:0x90:m -U efuse:w:0xff:m
34  */
35
36 #include <aversive.h>
37 #include <aversive/queue.h>
38 #include <aversive/endian.h>
39 #include <aversive/wait.h>
40 #include <aversive/error.h>
41
42 #include <uart.h>
43
44 #include <stdio.h>
45 #include <string.h>
46 #include <stdint.h>
47 #include <inttypes.h>
48 #include <stdlib.h>
49 #include <stdarg.h>
50 #include <errno.h>
51 #include <ctype.h>
52
53 #include <parse.h>
54 #include <rdline.h>
55 #include <timer.h>
56 #include <i2cm_sw.h>
57 #include <i2c.h>
58
59 #include "eeprom_config.h"
60 #include "gps.h"
61 #ifdef GPS_VENUS
62 #include "gps_venus.h"
63 #endif
64 #ifdef GPS_UBX
65 #include "gps_ubx.h"
66 #endif
67 #include "sd_log.h"
68 #include "../common/i2c_commands.h"
69 #include "i2c_protocol.h"
70 #include "imu.h"
71 #include "main.h"
72
73 struct imuboard imuboard;
74 volatile uint32_t global_ms;
75
76 void bootloader(void)
77 {
78 #define BOOTLOADER_ADDR 0x1e000
79         if (pgm_read_byte_far(BOOTLOADER_ADDR) == 0xff) {
80                 printf_P(PSTR("Bootloader is not present\r\n"));
81                 return;
82         }
83         cli();
84         /* ... very specific :( */
85         TIMSK0 = 0;
86         TIMSK1 = 0;
87         TIMSK2 = 0;
88         TIMSK3 = 0;
89         EIMSK = 0;
90         UCSR0B = 0;
91         UCSR1B = 0;
92         SPCR = 0;
93         TWCR = 0;
94         ACSR = 0;
95         ADCSRA = 0;
96
97         __asm__ __volatile__ ("ldi r30,0x00\n");
98         __asm__ __volatile__ ("ldi r31,0xf0\n");
99         //__asm__ __volatile__ ("eijmp\n");
100         __asm__ __volatile__ ("ijmp\n");
101 }
102
103 /* return time in milliseconds on unsigned 16 bits */
104 uint16_t get_time_ms(void)
105 {
106         uint16_t ms;
107         uint8_t flags;
108         IRQ_LOCK(flags);
109         ms = global_ms;
110         IRQ_UNLOCK(flags);
111         return ms;
112 }
113
114 static void main_timer_interrupt(void)
115 {
116         static uint16_t cycles;
117         static uint8_t stack = 0;
118         static uint8_t cpt = 0;
119         cpt++;
120
121         /* LED blink */
122         if (global_ms & 0x80)
123                 LED1_ON();
124         else
125                 LED1_OFF();
126
127         if ((cpt & 0x03) != 0)
128                 return;
129
130         /* the following code is only called one interrupt among 4: every 682us
131          * (at 12 Mhz) = 8192 cycles */
132         cycles += 8192;
133         if (cycles >= 12000) {
134                 cycles -= 12000;
135                 global_ms ++;
136         }
137
138         /* called  */
139         if (stack++ == 0)
140                 LED2_ON();
141         sei();
142         if ((cpt & 0x3) == 0)
143                 callout_manage(&imuboard.intr_cm);
144         cli();
145         if (--stack == 0)
146                 LED2_OFF();
147 }
148
149 int main(void)
150 {
151         DDRB = 0x18 /* LEDs */;
152
153         uart_init();
154         uart_register_rx_event(CMDLINE_UART, emergency);
155
156         fdevopen(cmdline_dev_send, cmdline_dev_recv);
157         timer_init();
158         timer0_register_OV_intr(main_timer_interrupt);
159
160         callout_mgr_init(&imuboard.intr_cm, get_time_ms);
161
162 #if 0
163         sei(); //XXX
164         printf_P(PSTR("starting...\r\n"));
165         while (1) {
166                 int16_t c;
167                 c = uart_recv_nowait(0);
168                 if (c >= 0)
169                         printf("%x\n", (uint8_t)c);
170         }
171 #endif
172
173         cmdline_init();
174         /* LOGS */
175         error_register_emerg(mylog);
176         error_register_error(mylog);
177         error_register_warning(mylog);
178         error_register_notice(mylog);
179         error_register_debug(mylog);
180
181         /* communication with mpu6050 */
182         i2cm_init();
183
184         /* i2c hw to communicate with mainboard */
185         i2c_init(I2C_MODE_SLAVE, I2C_IMUBOARD_ADDR);
186         i2c_protocol_init();
187         i2c_register_recv_event(i2c_recvevent);
188         i2c_register_send_event(i2c_sendevent);
189
190         sei();
191         printf_P(PSTR("starting...\r\n"));
192         eeprom_load_config();
193
194         sd_log_open();
195
196         printf_P(PSTR("\r\n"));
197         rdline_newline(&imuboard.rdl, imuboard.prompt);
198
199         imu_init();
200 #ifdef GPS_VENUS
201         gps_venus_init();
202 #endif
203 #ifdef GPS_UBX
204         gps_ubx_init();
205 #endif
206
207         imuboard.flags |= IMUBOARD_F_BOOT_OK;
208
209         while (1) {
210                 imu_log(0);
211                 gps_log(0);
212                 cmdline_poll();
213         }
214
215         return 0;
216 }