diff options
| -rw-r--r-- | Makefile | 13 | ||||
| -rw-r--r-- | ao.h | 42 | ||||
| -rw-r--r-- | ao_adc_fake.c | 27 | ||||
| -rw-r--r-- | ao_cmd.c | 8 | ||||
| -rw-r--r-- | ao_config.c | 285 | ||||
| -rw-r--r-- | ao_convert.c | 18 | ||||
| -rw-r--r-- | ao_ee.c | 1 | ||||
| -rw-r--r-- | ao_ee_fake.c | 37 | ||||
| -rw-r--r-- | ao_flight.c | 17 | ||||
| -rw-r--r-- | ao_flight_test.c | 25 | ||||
| -rw-r--r-- | ao_gps.c | 39 | ||||
| -rw-r--r-- | ao_gps_report.c | 62 | ||||
| -rw-r--r-- | ao_radio.c | 4 | ||||
| -rw-r--r-- | ao_teledongle.c | 7 | ||||
| -rw-r--r-- | ao_telemetrum.c | 2 | ||||
| -rw-r--r-- | ao_telemetry.c | 8 | ||||
| -rw-r--r-- | ao_teleterra.c | 15 | ||||
| -rw-r--r-- | ao_tidongle.c | 7 | 
18 files changed, 524 insertions, 93 deletions
@@ -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) \ @@ -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 @@ -699,6 +702,16 @@ 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 <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) +{ +} @@ -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 <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]); +} 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; -} @@ -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 <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; +} 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);  } @@ -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 <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"); +} @@ -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) -{ -}  | 
