Add configuration support
authorKeith Packard <keithp@keithp.com>
Sun, 26 Apr 2009 07:11:32 +0000 (00:11 -0700)
committerKeith Packard <keithp@keithp.com>
Sun, 26 Apr 2009 07:11:32 +0000 (00:11 -0700)
Current config variables:
Main deploy altitude above launch (in meters)
Acceleration zero g calibration (manual or automatic)
Radio channel (freq = 435.550MHz + channel * 100kHz)
Callsign (max 8 characters)

Supporting this involved shuffling code around so that the
non-telemetrum builds could include only the stuff they needed.

18 files changed:
Makefile
ao.h
ao_adc_fake.c [new file with mode: 0644]
ao_cmd.c
ao_config.c [new file with mode: 0644]
ao_convert.c
ao_ee.c
ao_ee_fake.c [new file with mode: 0644]
ao_flight.c
ao_flight_test.c
ao_gps.c
ao_gps_report.c [new file with mode: 0644]
ao_radio.c
ao_teledongle.c
ao_telemetrum.c
ao_telemetry.c
ao_teleterra.c
ao_tidongle.c

index 8ef86be5415c81c9074266a7e9a5207d35b67302..a7cca8695c3b5119243c98fd115b773940544364 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -33,6 +33,7 @@ ALTOS_SRC = \
 #
 ALTOS_DRIVER_SRC = \
        ao_beep.c \
+       ao_config.c \
        ao_led.c \
        ao_radio.c \
        ao_stdio.c \
@@ -56,12 +57,20 @@ TELE_DRIVER_SRC = \
        ao_gps.c \
        ao_serial.c
 
+#
+# Drivers for partially-flled boards (TT, TD and TI)
+#
+TELE_FAKE_SRC = \
+       ao_adc_fake.c \
+       ao_ee_fake.c
+
 # 
 # Drivers only on TeleMetrum
 #
 TM_DRIVER_SRC = \
        ao_adc.c \
        ao_ee.c \
+       ao_gps_report.c \
        ao_ignite.c
 
 #
@@ -97,6 +106,7 @@ TI_SRC = \
        $(ALTOS_DRIVER_SRC) \
        $(TELE_RECEIVER_SRC) \
        $(TELE_COMMON_SRC) \
+       $(TELE_FAKE_SRC) \
        $(TI_TASK_SRC)
        
 TT_TASK_SRC = \
@@ -110,6 +120,7 @@ TT_SRC = \
        $(TELE_RECEIVER_SRC) \
        $(TELE_DRIVER_SRC) \
        $(TELE_COMMON_SRC) \
+       $(TELE_FAKE_SRC) \
        $(TT_TASK_SRC)
        
        
@@ -125,6 +136,7 @@ TD_SRC = \
        $(ALTOS_DRIVER_SRC) \
        $(TELE_RECEIVER_SRC) \
        $(TELE_COMMON_SRC) \
+       $(TELE_FAKE_SRC) \
        $(TD_TASK_SRC)
 
 SRC = \
@@ -133,6 +145,7 @@ SRC = \
        $(TELE_DRIVER_SRC) \
        $(TELE_RECEIVER_SRC) \
        $(TELE_COMMON_SRC) \
+       $(TELE_FAKE_SRC) \
        $(TM_DRIVER_SRC) \
        $(TM_TASK_SRC) \
        $(TI_TASK_SRC) \
diff --git a/ao.h b/ao.h
index 338a40b0a42211b6f84067b09bb276b9515beeb7..13497095c450aff3f45e78777ab441c46628efe3 100644 (file)
--- a/ao.h
+++ b/ao.h
@@ -314,6 +314,9 @@ ao_cmd_white(void);
 void
 ao_cmd_hex(void);
 
+void
+ao_cmd_decimal(void);
+
 struct ao_cmds {
        uint8_t         cmd;
        void            (*func)(void);
@@ -593,10 +596,10 @@ int16_t
 ao_pres_to_altitude(int16_t pres) __reentrant;
 
 int16_t
-ao_temp_to_dC(int16_t temp) __reentrant;
+ao_altitude_to_pres(int16_t alt) __reentrant;
 
 int16_t
-ao_accel_to_cm_per_s2(int16_t accel) __reentrant;
+ao_temp_to_dC(int16_t temp) __reentrant;
 
 /*
  * ao_dbg.c
@@ -698,6 +701,16 @@ ao_gps_print(__xdata struct ao_gps_data *gps_data);
 void
 ao_gps_init(void);
 
+/*
+ * ao_gps_report.c
+ */
+
+void
+ao_gps_report(void);
+
+void
+ao_gps_report_init(void);
+
 /*
  * ao_telemetry.c
  */
@@ -795,5 +808,28 @@ ao_igniter_status(enum ao_igniter igniter);
 void
 ao_igniter_init(void);
 
-#endif /* _AO_H_ */
+/*
+ * ao_config.c
+ */
+
+#define AO_CONFIG_MAJOR        1
+#define AO_CONFIG_MINOR        0
+
+struct ao_config {
+       uint8_t         major;
+       uint8_t         minor;
+       uint16_t        main_deploy;
+       int16_t         accel_zero_g;
+       uint8_t         radio_channel;
+       char            callsign[AO_MAX_CALLSIGN + 1];
+};
+
+extern __xdata struct ao_config ao_config;
 
+void
+ao_config_get(void);
+
+void
+ao_config_init(void);
+
+#endif /* _AO_H_ */
diff --git a/ao_adc_fake.c b/ao_adc_fake.c
new file mode 100644 (file)
index 0000000..6ca88d4
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * Copyright © 2009 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include "ao.h"
+
+volatile __xdata struct ao_adc ao_adc_ring[AO_ADC_RING];
+volatile __data uint8_t                ao_adc_head;
+
+/* Stub for systems which have no ADC */
+void
+ao_adc_poll(void)
+{
+}
index 7f7865364da5a4a10949a1a5e2d964aeecca1512..91abe7f08837c6d321aecc038c868d6daf7ee1aa 100644 (file)
--- a/ao_cmd.c
+++ b/ao_cmd.c
@@ -152,9 +152,8 @@ ao_cmd_hex(void)
                ao_cmd_status = r;
 }
 
-#if 0
-static void
-decimal(void)
+void
+ao_cmd_decimal(void)
 {
        __xdata uint8_t r = ao_cmd_lex_error;
        
@@ -162,7 +161,7 @@ decimal(void)
        ao_cmd_white();
        for(;;) {
                if ('0' <= ao_cmd_lex_c && ao_cmd_lex_c <= '9')
-                       ao_cmd_lex_i = (ao_cmd_lex_i * 10 ) | (ao_cmd_lex_c - '0');
+                       ao_cmd_lex_i = (ao_cmd_lex_i * 10) + (ao_cmd_lex_c - '0');
                else
                        break;
                r = ao_cmd_success;
@@ -171,7 +170,6 @@ decimal(void)
        if (r != ao_cmd_success)
                ao_cmd_status = r;
 }
-#endif
 
 static void
 eol(void)
diff --git a/ao_config.c b/ao_config.c
new file mode 100644 (file)
index 0000000..e32dca4
--- /dev/null
@@ -0,0 +1,285 @@
+/*
+ * Copyright © 2009 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include "ao.h"
+
+__xdata struct ao_config ao_config;
+__xdata uint8_t ao_config_loaded;
+__xdata uint8_t ao_config_dirty;
+__xdata uint8_t ao_config_mutex;
+
+#define AO_CONFIG_DEFAULT_MAIN_DEPLOY  250
+#define AO_CONFIG_DEFAULT_RADIO_CHANNEL        0
+#define AO_CONFIG_DEFAULT_CALLSIGN     "KD7SGQ"
+#define AO_CONFIG_DEFAULT_ACCEL_ZERO_G 16000
+
+static void
+_ao_config_put(void)
+{
+       ao_ee_write_config((uint8_t *) &ao_config, sizeof (ao_config));
+}
+
+static void
+_ao_config_get(void)
+{
+       if (ao_config_loaded)
+               return;
+       ao_ee_read_config((uint8_t *) &ao_config, sizeof (ao_config));
+       if (ao_config.major != AO_CONFIG_MAJOR) {
+               ao_config.major = AO_CONFIG_MAJOR;
+               ao_config.minor = AO_CONFIG_MINOR;
+               ao_config.main_deploy = AO_CONFIG_DEFAULT_MAIN_DEPLOY;
+               ao_config.radio_channel = AO_CONFIG_DEFAULT_RADIO_CHANNEL;
+               ao_config.accel_zero_g = AO_CONFIG_DEFAULT_ACCEL_ZERO_G;
+               memset(&ao_config.callsign, '\0', sizeof (ao_config.callsign));
+               memcpy(&ao_config.callsign, AO_CONFIG_DEFAULT_CALLSIGN,
+                      sizeof(AO_CONFIG_DEFAULT_CALLSIGN) - 1);
+               ao_config_dirty = 1;
+       }
+       /* deal with minor version issues here, at 0 we haven't any */
+       ao_config_loaded = 1;
+}
+
+void
+ao_config_get(void)
+{
+       ao_mutex_get(&ao_config_mutex);
+       _ao_config_get();
+       ao_mutex_put(&ao_config_mutex);
+}
+
+void
+ao_config_callsign_show(void)
+{
+       printf ("Callsign: \"%s\"\n", ao_config.callsign);
+}
+
+void
+ao_config_callsign_set(void) __reentrant
+{
+       uint8_t c;
+       char callsign[AO_MAX_CALLSIGN + 1];
+
+       ao_cmd_white();
+       c = 0;
+       while (ao_cmd_lex_c != '\n') {
+               if (c < AO_MAX_CALLSIGN)
+                       callsign[c++] = ao_cmd_lex_c;
+               else
+                       ao_cmd_status = ao_cmd_lex_error;
+               ao_cmd_lex();
+       }
+       if (ao_cmd_status != ao_cmd_success)
+               return;
+       ao_mutex_get(&ao_config_mutex);
+       _ao_config_get();
+       memcpy(&ao_config.callsign, &callsign,
+              AO_MAX_CALLSIGN + 1);
+       ao_config_dirty = 1;
+       ao_mutex_put(&ao_config_mutex);
+       ao_config_callsign_show();
+}
+
+void
+ao_config_radio_channel_show(void) __reentrant
+{
+       uint32_t        freq = 435550L + ao_config.radio_channel * 100L;
+       uint16_t        mhz = freq / 1000L;
+       uint16_t        khz = freq % 1000L;
+
+       printf("Radio channel: %d (%d.%03dMHz)\n",
+              ao_config.radio_channel, mhz, khz);
+}
+
+void
+ao_config_radio_channel_set(void) __reentrant
+{
+       ao_cmd_decimal();
+       if (ao_cmd_status != ao_cmd_success)
+               return;
+       ao_mutex_get(&ao_config_mutex);
+       _ao_config_get();
+       ao_config.radio_channel = ao_cmd_lex_i;
+       ao_config_dirty = 1;
+       ao_mutex_put(&ao_config_mutex);
+       ao_config_radio_channel_show();
+}
+
+void
+ao_config_main_deploy_show(void) __reentrant
+{
+       printf("Main deploy set to %d meters (%d feet)\n",
+              ao_config.main_deploy,
+              (int16_t) ((int32_t) ao_config.main_deploy * 328 / 100));
+}
+
+void
+ao_config_main_deploy_set(void) __reentrant
+{
+       ao_cmd_decimal();
+       if (ao_cmd_status != ao_cmd_success)
+               return;
+       ao_mutex_get(&ao_config_mutex);
+       _ao_config_get();
+       ao_config.main_deploy = ao_cmd_lex_i;
+       ao_config_dirty = 1;
+       ao_mutex_put(&ao_config_mutex);
+       ao_config_main_deploy_show();
+}
+
+void
+ao_config_accel_zero_g_show(void) __reentrant
+{
+       printf("Accel zero g point set to %d\n",
+              ao_config.accel_zero_g);
+}
+
+#define ZERO_G_SAMPLES 1000
+
+static int16_t
+ao_config_accel_zero_g_auto(void) __reentrant
+{
+       uint16_t        i;
+       int32_t         accel_total;
+       uint8_t         cal_adc_ring;
+
+       puts("Calibrating accelerometer..."); flush();
+       i = ZERO_G_SAMPLES;
+       accel_total = 0;
+       cal_adc_ring = ao_adc_head;
+       while (i) {
+               ao_sleep(&ao_adc_ring);
+               while (i && cal_adc_ring != ao_adc_head) {
+                       accel_total += (int32_t) ao_adc_ring[cal_adc_ring].accel;
+                       cal_adc_ring = ao_adc_ring_next(cal_adc_ring);
+                       i--;
+               }
+       }
+       return (int16_t) (accel_total / ZERO_G_SAMPLES);
+}
+void
+ao_config_accel_zero_g_set(void) __reentrant
+{
+       ao_cmd_decimal();
+       if (ao_cmd_status != ao_cmd_success)
+               return;
+       if (ao_cmd_lex_i == 0)
+               ao_cmd_lex_i = ao_config_accel_zero_g_auto();
+       ao_mutex_get(&ao_config_mutex);
+       _ao_config_get();
+       ao_config.accel_zero_g = ao_cmd_lex_i;
+       ao_config_dirty = 1;
+       ao_mutex_put(&ao_config_mutex);
+       ao_config_accel_zero_g_show();
+}
+
+struct ao_config_var {
+       uint8_t         cmd;
+       void            (*set)(void) __reentrant;
+       void            (*show)(void) __reentrant;
+       const char      *help;
+};
+
+void
+ao_config_help(void) __reentrant;
+
+void
+ao_config_show(void) __reentrant;
+
+void
+ao_config_write(void) __reentrant;
+
+__code struct ao_config_var ao_config_vars[] = {
+       { 'm',  ao_config_main_deploy_set,      ao_config_main_deploy_show,
+               "m <meters>  Set height above launch for main deploy (in meters)" },
+       { 'a',  ao_config_accel_zero_g_set,     ao_config_accel_zero_g_show,
+               "a <value>   Set accelerometer zero g point (0 for auto)" },
+       { 'r',  ao_config_radio_channel_set,    ao_config_radio_channel_show,
+               "r <channel> Set radio channel (freq = 434.550 + channel * .1)" },
+       { 'c',  ao_config_callsign_set,         ao_config_callsign_show,
+               "c <call>    Set callsign broadcast in each packet (8 char max)" },
+       { 's',  ao_config_show,                 ao_config_show,
+               "s           Show current config values" },
+       { 'w',  ao_config_write,                ao_config_write,
+               "w           Write current values to eeprom" },
+       { '?',  ao_config_help,                 ao_config_help,
+               "?           Show available config variables" },
+       { 0,    ao_config_main_deploy_set,      ao_config_main_deploy_show,
+               NULL },
+};
+
+void
+ao_config_set(void)
+{
+       uint8_t c;
+       uint8_t cmd;
+       void (*__xdata func)(void) __reentrant;
+
+       ao_cmd_white();
+       c = ao_cmd_lex_c;
+       ao_cmd_lex();
+       func = 0;
+       for (cmd = 0; ao_config_vars[cmd].cmd != '\0'; cmd++)
+               if (ao_config_vars[cmd].cmd == c) {
+                       func = ao_config_vars[cmd].set;
+                       break;
+               }
+       if (func)
+               (*func)();
+       else
+               ao_cmd_status = ao_cmd_syntax_error;
+}
+
+void
+ao_config_help(void) __reentrant
+{
+       uint8_t cmd;
+       for (cmd = 0; ao_config_vars[cmd].cmd != '\0'; cmd++)
+               puts (ao_config_vars[cmd].help);
+}
+
+void
+ao_config_show(void) __reentrant
+{
+       uint8_t cmd;
+       for (cmd = 0; ao_config_vars[cmd].cmd != '\0'; cmd++)
+               if (ao_config_vars[cmd].show != ao_config_vars[cmd].set)
+                       (*ao_config_vars[cmd].show)();
+}
+
+void
+ao_config_write(void) __reentrant
+{
+       ao_mutex_get(&ao_config_mutex);
+       if (ao_config_dirty) {
+               _ao_config_put();
+               ao_config_dirty = 0;
+               printf("Saved\n");
+       }
+       ao_mutex_put(&ao_config_mutex);
+}
+
+__code struct ao_cmds ao_config_cmds[] = {
+       { 'c',  ao_config_set,  "c <var> <value>                    Set config variable (? for help, s to show)" },
+       { '\0', ao_config_set, NULL },
+};
+
+void
+ao_config_init(void)
+{
+       ao_cmd_register(&ao_config_cmds[0]);
+}
index 2585db54264586818b68ca538f3525144f538587..57ed73701abefe29d99d888ddbe35b4a586b982a 100644 (file)
@@ -30,6 +30,17 @@ ao_pres_to_altitude(int16_t pres) __reentrant
        return altitude_table[pres];
 }
 
+int16_t
+ao_altitude_to_pres(int16_t alt) __reentrant
+{
+       int16_t pres;
+
+       for (pres = 0; pres < 2047; pres++)
+               if (altitude_table[pres] <= alt)
+                       break;
+       return pres << 4;
+}
+
 static __xdata uint8_t ao_temp_mutex;
 
 int16_t
@@ -42,10 +53,3 @@ ao_temp_to_dC(int16_t temp) __reentrant
        ao_mutex_put(&ao_temp_mutex);
        return ret;
 }
-
-int16_t
-ao_accel_to_cm_per_s2(int16_t accel) __reentrant
-{
-       /* this is wrong */
-       return (998 - (accel >> 4)) * 3300 / 2047;
-}
diff --git a/ao_ee.c b/ao_ee.c
index bce293cdbc1b739db8f3501697c2bde9cf738a4a..a0f2e23a3f9392e4d1ed781d156f43c6cdf815d1 100644 (file)
--- a/ao_ee.c
+++ b/ao_ee.c
@@ -331,6 +331,7 @@ ao_ee_write_config(uint8_t *buf, uint16_t len) __reentrant
                ao_ee_fill(AO_EE_CONFIG_BLOCK);
                memcpy(ao_ee_data, buf, len);
                ao_ee_block_dirty = 1;
+               ao_ee_flush_internal();
        } ao_mutex_put(&ao_ee_mutex);
        return 1;
 }
diff --git a/ao_ee_fake.c b/ao_ee_fake.c
new file mode 100644 (file)
index 0000000..b0c1d61
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Copyright © 2009 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include "ao.h"
+
+/*
+ * For hardware without eeprom, the config code still
+ * wants to call these functions
+ */
+uint8_t
+ao_ee_write_config(uint8_t *buf, uint16_t len) __reentrant
+{
+       (void) buf;
+       (void) len;
+       return 1;
+}
+
+uint8_t
+ao_ee_read_config(uint8_t *buf, uint16_t len) __reentrant
+{
+       memset(buf, '\0', len);
+       return 1;
+}
index 1f56dab694bea189ade842888f02e8452b239902..01bbcce901e1977c86c0215a8028dcfdd0b1279f 100644 (file)
@@ -76,7 +76,7 @@ __pdata int16_t ao_raw_accel, ao_raw_accel_prev, ao_raw_pres;
 
 #define ACCEL_G                265
 #define ACCEL_ZERO_G   16000
-#define ACCEL_NOSE_UP  (ACCEL_ZERO_G - ACCEL_G * 2 /3)
+#define ACCEL_NOSE_UP  (ACCEL_G * 2 /3)
 #define ACCEL_BOOST    ACCEL_G * 2
 #define ACCEL_INT_LAND (ACCEL_G / 10)
 #define ACCEL_VEL_LAND VEL_MPS_TO_COUNT(10)
@@ -229,14 +229,16 @@ ao_flight(void)
                        ao_ground_accel = (ao_raw_accel_sum / nsamples);
                        ao_ground_pres = (ao_raw_pres_sum / nsamples);
                        ao_min_pres = ao_ground_pres;
-                       ao_main_pres = ao_ground_pres - BARO_MAIN;
+                       ao_config_get();
+                       ao_main_pres = ao_altitude_to_pres(ao_pres_to_altitude(ao_ground_pres) + ao_config.main_deploy);
                        ao_flight_vel = 0;
                        ao_min_vel = 0;
 
                        ao_interval_end = ao_flight_tick;
 
                        /* Go to launchpad state if the nose is pointing up */
-                       if (ao_flight_accel < ACCEL_NOSE_UP) {
+                       ao_config_get();
+                       if (ao_flight_accel < ao_config.accel_zero_g - ACCEL_NOSE_UP) {
 
                                /* Disable the USB controller in flight mode
                                 * to save power
@@ -256,7 +258,6 @@ ao_flight(void)
                                /* Turn on the Green LED in idle mode
                                 */
                                ao_led_on(AO_LED_GREEN);
-                               ao_timer_set_adc_interval(100);
                                ao_wakeup(DATA_TO_XDATA(&ao_flight_state));
                        }
                        /* signal successful initialization by turning off the LED */
@@ -362,6 +363,9 @@ ao_flight(void)
                                /* slow down the telemetry system */
                                ao_telemetry_set_interval(AO_TELEMETRY_INTERVAL_RECOVER);
 
+                               /* slow down the ADC sample rate */
+                               ao_timer_set_adc_interval(10);
+
                                /* Enable RDF beacon */
                                ao_rdf_set(1);
 
@@ -422,11 +426,12 @@ ao_flight(void)
 static void
 ao_flight_status(void)
 {
-       printf("STATE: %7s accel: %d speed: %d altitude: %d\n",
+       printf("STATE: %7s accel: %d speed: %d altitude: %d main: %d\n",
               ao_state_names[ao_flight_state],
               AO_ACCEL_COUNT_TO_MSS(ACCEL_ZERO_G - ao_flight_accel),
               AO_VEL_COUNT_TO_MS(ao_flight_vel),
-              ao_pres_to_altitude(ao_flight_pres));
+              ao_pres_to_altitude(ao_flight_pres),
+              ao_pres_to_altitude(ao_main_pres));
 }
 
 static __xdata struct ao_task  flight_task;
index 0b18969e7409238d197b636ce2319a20ed35aea1..aefe3da748ad2e0da07f6877d52b439eec2b4471 100644 (file)
@@ -127,6 +127,26 @@ ao_pres_to_altitude(int16_t pres) __reentrant
        return altitude_table[pres];
 }
 
+int16_t
+ao_altitude_to_pres(int16_t alt) __reentrant
+{
+       int16_t pres;
+
+       for (pres = 0; pres < 2047; pres++)
+               if (altitude_table[pres] <= alt)
+                       break;
+       return pres << 4;
+}
+
+struct ao_config {
+       uint16_t        main_deploy;
+       int16_t         accel_zero_g;
+};
+
+#define ao_config_get()
+
+struct ao_config ao_config = { 250, 16000 };
+
 #include "ao_flight.c"
 
 void
@@ -204,11 +224,12 @@ ao_dump_state(void)
 {
        if (ao_flight_state == ao_flight_startup)
                return;
-       printf ("\t\t\t\t\t%s accel %g vel %g alt %d\n",
+       printf ("\t\t\t\t\t%s accel %g vel %g alt %d main %d\n",
                ao_state_names[ao_flight_state],
                (ao_flight_accel - ao_ground_accel) / COUNTS_PER_G * GRAVITY,
                (double) ao_flight_vel / 100 / COUNTS_PER_G * GRAVITY,
-               altitude_table[ao_flight_pres >> 4]);
+               ao_pres_to_altitude(ao_flight_pres),
+               ao_pres_to_altitude(ao_main_pres));
        if (ao_flight_state == ao_flight_landed)
                exit(0);
 }
index 651a59e543d1a8336a76bff238447471e115141f..353272f1badb4558a7825a13387d49b2b87b4564 100644 (file)
--- a/ao_gps.c
+++ b/ao_gps.c
@@ -253,45 +253,7 @@ ao_gps(void) __reentrant
        }
 }
 
-void
-ao_gps_report(void)
-{
-       static __xdata struct ao_log_record     gps_log;
-       static __xdata struct ao_gps_data       gps_data;
-
-       for (;;) {
-               ao_sleep(&ao_gps_data);
-               ao_mutex_get(&ao_gps_mutex);
-               memcpy(&gps_data, &ao_gps_data, sizeof (struct ao_gps_data));
-               ao_mutex_put(&ao_gps_mutex);
-
-               gps_log.tick = ao_time();
-               gps_log.type = AO_LOG_GPS_TIME;
-               gps_log.u.gps_time.hour = gps_data.hour;
-               gps_log.u.gps_time.minute = gps_data.minute;
-               gps_log.u.gps_time.second = gps_data.second;
-               gps_log.u.gps_time.flags = gps_data.flags;
-               ao_log_data(&gps_log);
-               gps_log.type = AO_LOG_GPS_LAT;
-               gps_log.u.gps_latitude.degrees = gps_data.latitude.degrees;
-               gps_log.u.gps_latitude.minutes = gps_data.latitude.minutes;
-               gps_log.u.gps_latitude.minutes_fraction = gps_data.latitude.minutes_fraction;
-               ao_log_data(&gps_log);
-               gps_log.type = AO_LOG_GPS_LON;
-               gps_log.u.gps_longitude.degrees = gps_data.longitude.degrees;
-               gps_log.u.gps_longitude.minutes = gps_data.longitude.minutes;
-               gps_log.u.gps_longitude.minutes_fraction = gps_data.longitude.minutes_fraction;
-               ao_log_data(&gps_log);
-               gps_log.type = AO_LOG_GPS_ALT;
-               gps_log.u.gps_altitude.altitude = gps_data.altitude;
-               gps_log.u.gps_altitude.unused = 0xffff;
-               ao_log_data(&gps_log);
-       }
-               
-}
-
 __xdata struct ao_task ao_gps_task;
-__xdata struct ao_task ao_gps_report_task;
 
 static void
 gps_dump(void) __reentrant
@@ -310,6 +272,5 @@ void
 ao_gps_init(void)
 {
        ao_add_task(&ao_gps_task, ao_gps, "gps");
-       ao_add_task(&ao_gps_report_task, ao_gps_report, "gps_report");
        ao_cmd_register(&ao_gps_cmds[0]);
 }
diff --git a/ao_gps_report.c b/ao_gps_report.c
new file mode 100644 (file)
index 0000000..494714b
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * Copyright © 2009 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include "ao.h"
+
+void
+ao_gps_report(void)
+{
+       static __xdata struct ao_log_record     gps_log;
+       static __xdata struct ao_gps_data       gps_data;
+
+       for (;;) {
+               ao_sleep(&ao_gps_data);
+               ao_mutex_get(&ao_gps_mutex);
+               memcpy(&gps_data, &ao_gps_data, sizeof (struct ao_gps_data));
+               ao_mutex_put(&ao_gps_mutex);
+
+               gps_log.tick = ao_time();
+               gps_log.type = AO_LOG_GPS_TIME;
+               gps_log.u.gps_time.hour = gps_data.hour;
+               gps_log.u.gps_time.minute = gps_data.minute;
+               gps_log.u.gps_time.second = gps_data.second;
+               gps_log.u.gps_time.flags = gps_data.flags;
+               ao_log_data(&gps_log);
+               gps_log.type = AO_LOG_GPS_LAT;
+               gps_log.u.gps_latitude.degrees = gps_data.latitude.degrees;
+               gps_log.u.gps_latitude.minutes = gps_data.latitude.minutes;
+               gps_log.u.gps_latitude.minutes_fraction = gps_data.latitude.minutes_fraction;
+               ao_log_data(&gps_log);
+               gps_log.type = AO_LOG_GPS_LON;
+               gps_log.u.gps_longitude.degrees = gps_data.longitude.degrees;
+               gps_log.u.gps_longitude.minutes = gps_data.longitude.minutes;
+               gps_log.u.gps_longitude.minutes_fraction = gps_data.longitude.minutes_fraction;
+               ao_log_data(&gps_log);
+               gps_log.type = AO_LOG_GPS_ALT;
+               gps_log.u.gps_altitude.altitude = gps_data.altitude;
+               gps_log.u.gps_altitude.unused = 0xffff;
+               ao_log_data(&gps_log);
+       }
+}
+
+__xdata struct ao_task ao_gps_report_task;
+
+void
+ao_gps_report_init(void)
+{
+       ao_add_task(&ao_gps_report_task, ao_gps_report, "gps_report");
+}
index 1b943ea88b1099a64043a15e9bf791ed1372df32..dbef6a188a60957bff523b6bc2c399d04167182a 100644 (file)
@@ -275,8 +275,10 @@ ao_radio_idle(void)
 void
 ao_radio_send(__xdata struct ao_telemetry *telemetry) __reentrant
 {
+       ao_config_get();
        ao_mutex_get(&ao_radio_mutex);
        ao_radio_idle();
+       RF_CHANNR = ao_config.radio_channel;
        ao_dma_set_transfer(ao_radio_dma,
                            telemetry,
                            &RFDXADDR,
@@ -297,8 +299,10 @@ ao_radio_send(__xdata struct ao_telemetry *telemetry) __reentrant
 void
 ao_radio_recv(__xdata struct ao_radio_recv *radio) __reentrant
 {
+       ao_config_get();
        ao_mutex_get(&ao_radio_mutex);
        ao_radio_idle();
+       RF_CHANNR = ao_config.radio_channel;
        ao_dma_set_transfer(ao_radio_dma,
                            &RFDXADDR,
                            radio,
index 7473d81074b8fac19bdeb329db9812d9b53a502d..af14472be78192a45b78fb9e11796b273eca46e0 100644 (file)
@@ -35,11 +35,6 @@ main(void)
        ao_monitor_init(AO_LED_GREEN);
        ao_radio_init();
        ao_dbg_init();
+       ao_config_init();
        ao_start_scheduler();
 }
-
-/* Stub for systems which have no ADC */
-void
-ao_adc_poll(void)
-{
-}
index 8746952183ec877ddbc7cfa797f54a6a9b63753a..d5d01f16a1549b2818f7dee5d2a88c300287e9d9 100644 (file)
@@ -39,10 +39,12 @@ main(void)
        ao_usb_init();
        ao_serial_init();
        ao_gps_init();
+       ao_gps_report_init();
        ao_telemetry_init();
        ao_radio_init();
        ao_monitor_init(AO_LED_GREEN);
        ao_igniter_init();
        ao_dbg_init();
+       ao_config_init();
        ao_start_scheduler();
 }
index ffee9beeae70e941d070d892841610b9d8db9265..db2cfda0e3103e2717debe588c64f63ee2d2e731 100644 (file)
 #include "ao.h"
 
 /* XXX make serial numbers real */
-
 __xdata uint8_t        ao_serial_number = 2;
 
-/* XXX make callsigns real */
-__xdata char ao_callsign[AO_MAX_CALLSIGN] = "KD7SQG";
-
 __xdata uint16_t ao_telemetry_interval = 0;
 __xdata uint8_t ao_rdf = 0;
 __xdata uint16_t ao_rdf_time;
@@ -35,8 +31,9 @@ ao_telemetry(void)
 {
        static __xdata struct ao_telemetry telemetry;
 
+       ao_config_get();
+       memcpy(telemetry.callsign, ao_config.callsign, AO_MAX_CALLSIGN);
        telemetry.addr = ao_serial_number;
-       memcpy(telemetry.callsign, ao_callsign, AO_MAX_CALLSIGN);
        ao_rdf_time = ao_time();
        for (;;) {
                while (ao_telemetry_interval == 0)
@@ -53,6 +50,7 @@ ao_telemetry(void)
                {
                        ao_rdf_time = ao_time() + AO_RDF_INTERVAL;
                        ao_radio_rdf();
+                       ao_delay(ao_telemetry_interval);
                }
        }
 }
index 41ab7bf0459e06caf3b9de26acbe83f8e919e434..b5ab4857de2e323b86109c362e9b83fc6cd0d1e4 100644 (file)
@@ -37,19 +37,6 @@ main(void)
        ao_monitor_init(AO_LED_GREEN);
        ao_radio_init();
        ao_dbg_init();
+       ao_config_init();
        ao_start_scheduler();
 }
-
-/* Stub for systems which have no ADC */
-void
-ao_adc_poll(void)
-{
-}
-
-/* Stub to not log GPS data */
-void
-ao_log_data(struct ao_log_record *log)
-{
-       (void) log;
-}
-
index 4ef86971e2dd8f721de2330b419ee8414142dca7..c8e165c2887703e9023a7ac0bd0e8fddbd7b97b7 100644 (file)
@@ -35,14 +35,9 @@ main(void)
        ao_monitor_init(AO_LED_RED);
        ao_radio_init();
        ao_dbg_init();
+       ao_config_init();
        /* Bring up the USB link */
        P1DIR |= 1;
        P1 |= 1;
        ao_start_scheduler();
 }
-
-/* Stub for systems which have no ADC */
-void
-ao_adc_poll(void)
-{
-}