From 38a0b61b0a0b3c00f064c8d562950a17a6ddff4a Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 26 Apr 2009 00:11:32 -0700 Subject: [PATCH] Add configuration support 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. --- Makefile | 13 +++ ao.h | 42 ++++++- ao_adc_fake.c | 27 +++++ ao_cmd.c | 8 +- ao_config.c | 285 +++++++++++++++++++++++++++++++++++++++++++++++ ao_convert.c | 18 +-- ao_ee.c | 1 + ao_ee_fake.c | 37 ++++++ ao_flight.c | 17 ++- ao_flight_test.c | 25 ++++- ao_gps.c | 39 ------- ao_gps_report.c | 62 +++++++++++ ao_radio.c | 4 + ao_teledongle.c | 7 +- ao_telemetrum.c | 2 + ao_telemetry.c | 8 +- ao_teleterra.c | 15 +-- ao_tidongle.c | 7 +- 18 files changed, 524 insertions(+), 93 deletions(-) create mode 100644 ao_adc_fake.c create mode 100644 ao_config.c create mode 100644 ao_ee_fake.c create mode 100644 ao_gps_report.c diff --git a/Makefile b/Makefile index 8ef86be5..a7cca869 100644 --- 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 338a40b0..13497095 100644 --- 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 index 00000000..6ca88d4e --- /dev/null +++ b/ao_adc_fake.c @@ -0,0 +1,27 @@ +/* + * Copyright © 2009 Keith Packard + * + * 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) +{ +} diff --git a/ao_cmd.c b/ao_cmd.c index 7f786536..91abe7f0 100644 --- 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 index 00000000..e32dca45 --- /dev/null +++ b/ao_config.c @@ -0,0 +1,285 @@ +/* + * Copyright © 2009 Keith Packard + * + * 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 Set height above launch for main deploy (in meters)" }, + { 'a', ao_config_accel_zero_g_set, ao_config_accel_zero_g_show, + "a Set accelerometer zero g point (0 for auto)" }, + { 'r', ao_config_radio_channel_set, ao_config_radio_channel_show, + "r Set radio channel (freq = 434.550 + channel * .1)" }, + { 'c', ao_config_callsign_set, ao_config_callsign_show, + "c 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 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]); +} diff --git a/ao_convert.c b/ao_convert.c index 2585db54..57ed7370 100644 --- a/ao_convert.c +++ b/ao_convert.c @@ -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 bce293cd..a0f2e23a 100644 --- 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 index 00000000..b0c1d61e --- /dev/null +++ b/ao_ee_fake.c @@ -0,0 +1,37 @@ +/* + * Copyright © 2009 Keith Packard + * + * 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; +} diff --git a/ao_flight.c b/ao_flight.c index 1f56dab6..01bbcce9 100644 --- a/ao_flight.c +++ b/ao_flight.c @@ -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; diff --git a/ao_flight_test.c b/ao_flight_test.c index 0b18969e..aefe3da7 100644 --- a/ao_flight_test.c +++ b/ao_flight_test.c @@ -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); } diff --git a/ao_gps.c b/ao_gps.c index 651a59e5..353272f1 100644 --- 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 index 00000000..494714b6 --- /dev/null +++ b/ao_gps_report.c @@ -0,0 +1,62 @@ +/* + * Copyright © 2009 Keith Packard + * + * 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"); +} diff --git a/ao_radio.c b/ao_radio.c index 1b943ea8..dbef6a18 100644 --- a/ao_radio.c +++ b/ao_radio.c @@ -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, diff --git a/ao_teledongle.c b/ao_teledongle.c index 7473d810..af14472b 100644 --- a/ao_teledongle.c +++ b/ao_teledongle.c @@ -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) -{ -} diff --git a/ao_telemetrum.c b/ao_telemetrum.c index 87469521..d5d01f16 100644 --- a/ao_telemetrum.c +++ b/ao_telemetrum.c @@ -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(); } diff --git a/ao_telemetry.c b/ao_telemetry.c index ffee9bee..db2cfda0 100644 --- a/ao_telemetry.c +++ b/ao_telemetry.c @@ -18,12 +18,8 @@ #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); } } } diff --git a/ao_teleterra.c b/ao_teleterra.c index 41ab7bf0..b5ab4857 100644 --- a/ao_teleterra.c +++ b/ao_teleterra.c @@ -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; -} - diff --git a/ao_tidongle.c b/ao_tidongle.c index 4ef86971..c8e165c2 100644 --- a/ao_tidongle.c +++ b/ao_tidongle.c @@ -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) -{ -} -- 2.30.2