Add TeleBalloon v1.2 support
[fw/altos] / src / teleballoon-v1.2 / ao_balloon.c
1 /*
2  * Copyright © 2009 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; version 2 of the License.
7  *
8  * This program is distributed in the hope that it will be useful, but
9  * WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11  * General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License along
14  * with this program; if not, write to the Free Software Foundation, Inc.,
15  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
16  */
17
18 #ifndef AO_FLIGHT_TEST
19 #include "ao.h"
20 #endif
21
22 #ifndef HAS_ACCEL
23 #error Please define HAS_ACCEL
24 #endif
25
26 #ifndef HAS_GPS
27 #error Please define HAS_GPS
28 #endif
29
30 #ifndef HAS_USB
31 #error Please define HAS_USB
32 #endif
33
34 /* Main flight thread. */
35
36 __pdata enum ao_flight_state    ao_flight_state;        /* current flight state */
37
38 __pdata uint8_t                 ao_flight_force_idle;
39 __pdata uint16_t                ao_motor_number;
40
41 void
42 ao_flight(void)
43 {
44         ao_sample_init();
45         ao_flight_state = ao_flight_startup;
46         for (;;) {
47
48                 /*
49                  * Process ADC samples, just looping
50                  * until the sensors are calibrated.
51                  */
52                 if (!ao_sample())
53                         continue;
54
55                 switch (ao_flight_state) {
56                 case ao_flight_startup:
57
58                         /* Check to see what mode we should go to.
59                          *  - Invalid mode if accel cal appears to be out
60                          *  - pad mode if we're upright,
61                          *  - idle mode otherwise
62                          */
63 #if HAS_ACCEL
64                         if (ao_config.accel_plus_g == 0 ||
65                             ao_config.accel_minus_g == 0 ||
66                             ao_ground_accel < ao_config.accel_plus_g - ACCEL_NOSE_UP ||
67                             ao_ground_accel > ao_config.accel_minus_g + ACCEL_NOSE_UP)
68                         {
69                                 /* Detected an accel value outside -1.5g to 1.5g
70                                  * (or uncalibrated values), so we go into invalid mode
71                                  */
72                                 ao_flight_state = ao_flight_invalid;
73
74 #if HAS_RADIO && PACKET_HAS_SLAVE
75                                 /* Turn on packet system in invalid mode on TeleMetrum */
76                                 ao_packet_slave_start();
77 #endif
78                         } else
79 #endif
80                                 if (!ao_flight_force_idle
81 #if HAS_ACCEL
82                                     && ao_ground_accel < ao_config.accel_plus_g + ACCEL_NOSE_UP
83 #endif
84                                         )
85                         {
86                                 /* Set pad mode - we can fly! */
87                                 ao_flight_state = ao_flight_drogue;
88 #if HAS_USB
89                                 /* Disable the USB controller in flight mode
90                                  * to save power
91                                  */
92                                 ao_usb_disable();
93 #endif
94
95                                 /* Disable packet mode in pad state */
96                                 ao_packet_slave_stop();
97
98                                 /* Turn on telemetry system */
99                                 ao_rdf_set(1);
100                                 ao_telemetry_set_interval(AO_TELEMETRY_INTERVAL_BALLOON);
101
102                                 /* signal successful initialization by turning off the LED */
103                                 ao_led_off(AO_LED_RED);
104
105                                 /* start logging data */
106                                 ao_log_start();
107
108 #if HAS_GPS
109                                 /* Record current GPS position by waking up GPS log tasks */
110                                 ao_wakeup(&ao_gps_data);
111                                 ao_wakeup(&ao_gps_tracking_data);
112 #endif
113
114                                 ao_wakeup(DATA_TO_XDATA(&ao_flight_state));
115                                 
116                         } else {
117                                 /* Set idle mode */
118                                 ao_flight_state = ao_flight_idle;
119  
120                                 /* signal successful initialization by turning off the LED */
121                                 ao_led_off(AO_LED_RED);
122                         }
123                         /* wakeup threads due to state change */
124                         ao_wakeup(DATA_TO_XDATA(&ao_flight_state));
125
126                         break;
127                 case ao_flight_drogue:
128                         break;
129                         
130                 }
131         }
132 }
133
134 static __xdata struct ao_task   flight_task;
135
136 void
137 ao_flight_init(void)
138 {
139         ao_flight_state = ao_flight_startup;
140         ao_add_task(&flight_task, ao_flight, "flight");
141 }