e89726552dce132bddaf0c4f09f6a45471c0b12a
[fw/altos] / src / teleballoon-v1.1 / 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
40 void
41 ao_flight(void)
42 {
43         ao_sample_init();
44         ao_flight_state = ao_flight_startup;
45         for (;;) {
46
47                 /*
48                  * Process ADC samples, just looping
49                  * until the sensors are calibrated.
50                  */
51                 if (!ao_sample())
52                         continue;
53
54                 switch (ao_flight_state) {
55                 case ao_flight_startup:
56
57                         /* Check to see what mode we should go to.
58                          *  - Invalid mode if accel cal appears to be out
59                          *  - pad mode if we're upright,
60                          *  - idle mode otherwise
61                          */
62                         if (!ao_flight_force_idle)
63                         {
64                                 /* Set pad mode - we can fly! */
65                                 ao_flight_state = ao_flight_pad;
66 #if HAS_USB
67                                 /* Disable the USB controller in flight mode
68                                  * to save power
69                                  */
70                                 ao_usb_disable();
71 #endif
72
73                                 /* Disable packet mode in pad state */
74                                 ao_packet_slave_stop();
75
76                                 /* Turn on telemetry system */
77                                 ao_rdf_set(1);
78                                 ao_telemetry_set_interval(AO_TELEMETRY_INTERVAL_BALLOON);
79
80                                 /* signal successful initialization by turning off the LED */
81                                 ao_led_off(AO_LED_RED);
82                         } else {
83                                 /* Set idle mode */
84                                 ao_flight_state = ao_flight_idle;
85  
86                                 /* signal successful initialization by turning off the LED */
87                                 ao_led_off(AO_LED_RED);
88                         }
89                         /* wakeup threads due to state change */
90                         ao_wakeup(DATA_TO_XDATA(&ao_flight_state));
91
92                         break;
93                 case ao_flight_pad:
94
95                         /* pad to coast:
96                          *
97                          * barometer: > 20m vertical motion
98                          */
99                         if (ao_height > AO_M_TO_HEIGHT(20))
100                         {
101                                 ao_flight_state = ao_flight_drogue;
102
103                                 /* start logging data */
104                                 ao_log_start();
105
106 #if HAS_GPS
107                                 /* Record current GPS position by waking up GPS log tasks */
108                                 ao_wakeup(&ao_gps_data);
109                                 ao_wakeup(&ao_gps_tracking_data);
110 #endif
111
112                                 ao_wakeup(DATA_TO_XDATA(&ao_flight_state));
113                         }
114                         break;
115                 case ao_flight_drogue:
116                         break;
117                         
118                 }
119         }
120 }
121
122 static __xdata struct ao_task   flight_task;
123
124 void
125 ao_flight_init(void)
126 {
127         ao_flight_state = ao_flight_startup;
128         ao_add_task(&flight_task, ao_flight, "flight");
129 }