avoid copy by using iovecs
[protos/xbee-avr.git] / 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  */
31
32 #include <aversive.h>
33 #include <aversive/queue.h>
34 #include <aversive/endian.h>
35 #include <aversive/wait.h>
36 #include <aversive/error.h>
37
38 #include <uart.h>
39
40 #include <stdio.h>
41 #include <string.h>
42 #include <stdint.h>
43 #include <inttypes.h>
44 #include <stdlib.h>
45 #include <stdarg.h>
46 #include <errno.h>
47 #include <ctype.h>
48
49 #include <parse.h>
50 #include <rdline.h>
51 #include <timer.h>
52
53 #include "eeprom_config.h"
54 #include "beep.h"
55 #include "xbee_user.h"
56 #include "main.h"
57
58 struct xbeeboard xbeeboard;
59 volatile uint32_t global_ms;
60
61 /* global xbee device */
62 struct xbee_dev *xbee_dev;
63
64 void bootloader(void)
65 {
66 #define BOOTLOADER_ADDR 0x3f000
67         if (pgm_read_byte_far(BOOTLOADER_ADDR) == 0xff) {
68                 printf_P(PSTR("Bootloader is not present\r\n"));
69                 return;
70         }
71         cli();
72         /* ... very specific :( */
73         TIMSK0 = 0;
74         TIMSK1 = 0;
75         TIMSK2 = 0;
76         TIMSK3 = 0;
77         EIMSK = 0;
78         UCSR0B = 0;
79         UCSR1B = 0;
80         SPCR = 0;
81         TWCR = 0;
82         ACSR = 0;
83         ADCSRA = 0;
84
85         /* XXX */
86         /* __asm__ __volatile__ ("ldi r31,0xf8\n"); */
87         /* __asm__ __volatile__ ("ldi r30,0x00\n"); */
88         /* __asm__ __volatile__ ("eijmp\n"); */
89 }
90
91 /* return time in milliseconds on unsigned 16 bits */
92 static uint16_t get_time_ms(void)
93 {
94         return (uint16_t)global_ms;
95 }
96
97 static void main_timer_interrupt(void)
98 {
99         static uint16_t cycles;
100         static uint8_t cpt;
101
102         cpt++;
103
104         /* LED blink */
105         if (global_ms & 0x80)
106                 LED1_ON();
107         else
108                 LED1_OFF();
109
110         if (cpt & beep_mask)
111                 BUZZER_ON();
112         else
113                 BUZZER_OFF();
114
115         /* interrupt every 2048 cycles */
116         cycles += 2048;
117         if (cycles >= 12000) {
118                 cycles -= 12000;
119                 global_ms ++;
120         }
121
122         /* called every 682us (at 12 Mhz), but global_ms is not incremented at
123          * each call */
124         sei();
125         callout_manage(&xbeeboard.intr_cm);
126 }
127
128 int main(void)
129 {
130         //struct callout t1;
131         FILE *xbee_file;
132         int8_t err;
133         struct xbee_dev dev;
134
135         DDRA = 0x07 /* LEDs */ | 0x10 /* buzzer */;
136
137         uart_init();
138         uart_register_rx_event(CMDLINE_UART, emergency);
139
140         fdevopen(cmdline_dev_send, cmdline_dev_recv);
141         xbee_file = fdevopen(xbee_dev_send, xbee_dev_recv);
142         timer_init();
143         timer0_register_OV_intr(main_timer_interrupt);
144
145         callout_mgr_init(&xbeeboard.intr_cm, get_time_ms);
146         callout_mgr_init(&xbeeboard.mainloop_cm, get_time_ms);
147
148         cmdline_init();
149         spi_servo_init();
150         beep_init();
151
152         /* initialize libxbee */
153         err = xbee_init();
154         if (err < 0)
155                 return -1;
156
157         xbee_dev = &dev;
158
159         /* open xbee device */
160         if (xbee_open(xbee_dev, xbee_file) < 0)
161                 return -1;
162
163         /* register default channel with a callback */
164         if (xbee_register_channel(xbee_dev, XBEE_DEFAULT_CHANNEL,
165                                   xbeeapp_rx, NULL) < 0) {
166                 fprintf(stderr, "cannot register default channel\n");
167                 return -1;
168         }
169         sei();
170
171         eeprom_load_config();
172
173         printf_P(PSTR("\r\n"));
174         rdline_newline(&xbeeboard.rdl, xbeeboard.prompt);
175
176         xbee_mainloop();
177         return 0;
178 }