diff options
| author | Keith Packard <keithp@keithp.com> | 2013-08-20 11:40:17 -0700 | 
|---|---|---|
| committer | Keith Packard <keithp@keithp.com> | 2013-08-27 21:56:42 -0600 | 
| commit | 7b0f9b25a56fa8b4aa1c2e9d79c43e6a97cab0c0 (patch) | |
| tree | d6b0c692976bf8086c5fce18193a4624623d0835 | |
| parent | 3ded57394f6dfd7beb9526c031a5c6c6c9926917 (diff) | |
altos: Initial TeleMetrum v2.0 bits
Adds new telemetry and logging formats along with code for TeleMetrum
v2.0 design.
Signed-off-by: Keith Packard <keithp@keithp.com>
| -rw-r--r-- | src/core/ao_gps_report_metrum.c | 110 | ||||
| -rw-r--r-- | src/core/ao_log.h | 66 | ||||
| -rw-r--r-- | src/core/ao_log_metrum.c | 175 | ||||
| -rw-r--r-- | src/core/ao_telemetry.c | 66 | ||||
| -rw-r--r-- | src/core/ao_telemetry.h | 44 | ||||
| -rw-r--r-- | src/stm/ao_arch.h | 2 | ||||
| -rw-r--r-- | src/stm/ao_beep_stm.c | 48 | ||||
| -rw-r--r-- | src/stm/stm32l.h | 2 | ||||
| -rw-r--r-- | src/telemetrum-v2.0/.gitignore | 2 | ||||
| -rw-r--r-- | src/telemetrum-v2.0/Makefile | 122 | ||||
| -rw-r--r-- | src/telemetrum-v2.0/ao_pins.h | 282 | ||||
| -rw-r--r-- | src/telemetrum-v2.0/ao_telemetrum.c | 90 | 
12 files changed, 1004 insertions, 5 deletions
| diff --git a/src/core/ao_gps_report_metrum.c b/src/core/ao_gps_report_metrum.c new file mode 100644 index 00000000..4fefe223 --- /dev/null +++ b/src/core/ao_gps_report_metrum.c @@ -0,0 +1,110 @@ +/* + * 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" +#include "ao_log.h" + +void +ao_gps_report_metrum(void) +{ +	static __xdata struct ao_log_metrum		gps_log; +	static __xdata struct ao_telemetry_location	gps_data; +	uint8_t	date_reported = 0; + +	for (;;) { +		ao_sleep(&ao_gps_data); +		ao_mutex_get(&ao_gps_mutex); +		ao_xmemcpy(&gps_data, &ao_gps_data, sizeof (ao_gps_data)); +		ao_mutex_put(&ao_gps_mutex); + +		if (!(gps_data.flags & AO_GPS_VALID)) +			continue; + +		gps_log.tick = ao_gps_tick; +		gps_log.type = AO_LOG_GPS_POS; +		gps_log.u.gps.latitude = gps_data.latitude; +		gps_log.u.gps.longitude = gps_data.longitude; +		gps_log.u.gps.altitude = gps_data.altitude; +		ao_log_metrum(&gps_log); + +		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; +		gps_log.u.gps_time.year = gps_data.year; +		gps_log.u.gps_time.month = gps_data.month; +		gps_log.u.gps_time.day = gps_data.day; +		ao_log_metrum(&gps_log); +	} +} + +void +ao_gps_tracking_report_metrum(void) +{ +	static __xdata struct ao_log_metrum		gps_log; +	static __xdata struct ao_telemetry_satellite	gps_tracking_data; +	uint8_t	c, n, i, p, valid, packets; +	uint8_t svid; + +	for (;;) { +		ao_sleep(&ao_gps_tracking_data); +		ao_mutex_get(&ao_gps_mutex); +		ao_xmemcpy(&gps_tracking_data, &ao_gps_tracking_data, sizeof (ao_gps_tracking_data)); +		ao_mutex_put(&ao_gps_mutex); + +		if (!(n = gps_tracking_data.channels)) +			continue; + +		gps_log.type = AO_LOG_GPS_SAT; +		gps_log.tick = ao_gps_tick; +		i = 0; +		for (c = 0; c < n; c++) { +			svid = gps_tracking_data.sats[c].svid; +			if (svid != 0) { +				if (i == 4) { +					gps_log.u.gps_sat.channels = i; +					gps_log.u.gps_sat.more = 1; +					ao_log_metrum(&gps_log); +					i = 0; +				} +				gps_log.u.gps_sat.sats[i].svid = svid; +				gps_log.u.gps_sat.sats[i].c_n = gps_tracking_data.sats[c].c_n_1; +				i++; +			} +		} +		if (i) { +			gps_log.u.gps_sat.channels = i; +			gps_log.u.gps_sat.more = 0; +			ao_log_metrum(&gps_log); +		} +	} +} + +__xdata struct ao_task ao_gps_report_metrum_task; +__xdata struct ao_task ao_gps_tracking_report_metrum_task; + +void +ao_gps_report_metrum_init(void) +{ +	ao_add_task(&ao_gps_report_metrum_task, +		    ao_gps_report_metrum, +		    "gps_report"); +	ao_add_task(&ao_gps_tracking_report_metrum_task, +		    ao_gps_tracking_report_metrum, +		    "gps_tracking_report"); +} diff --git a/src/core/ao_log.h b/src/core/ao_log.h index dce12f02..f6ab4520 100644 --- a/src/core/ao_log.h +++ b/src/core/ao_log.h @@ -45,6 +45,7 @@ extern __pdata enum ao_flight_state ao_log_state;  #define AO_LOG_FORMAT_TELESCIENCE	4	/* 32 byte typed telescience records */  #define AO_LOG_FORMAT_TELEMEGA		5	/* 32 byte typed telemega records */  #define AO_LOG_FORMAT_MINI		6	/* 16-byte MS5607 baro only */ +#define AO_LOG_FORMAT_TELEMETRUM	7	/* 16-byte typed telemetrum records */  #define AO_LOG_FORMAT_NONE		127	/* No log at all */  extern __code uint8_t ao_log_format; @@ -135,6 +136,7 @@ ao_log_full(void);  #define AO_LOG_GPS_ALT		'H'  #define AO_LOG_GPS_SAT		'V'  #define AO_LOG_GPS_DATE		'Y' +#define AO_LOG_GPS_POS		'P'  #define AO_LOG_POS_NONE		(~0UL) @@ -263,6 +265,64 @@ struct ao_log_mega {  	} u;  }; +struct ao_log_metrum { +	char			type;			/* 0 */ +	uint8_t			csum;			/* 1 */ +	uint16_t		tick;			/* 2 */ +	union {						/* 4 */ +		/* AO_LOG_FLIGHT */ +		struct { +			uint16_t	flight;		/* 4 */ +			int16_t		ground_accel;	/* 6 */ +			uint32_t	ground_pres;	/* 8 */ +		} flight;	/* 12 */ +		/* AO_LOG_STATE */ +		struct { +			uint16_t	state;		/* 4 */ +			uint16_t	reason;		/* 6 */ +		} state;	/* 8 */ +		/* AO_LOG_SENSOR */ +		struct { +			uint32_t	pres;		/* 4 */ +			uint32_t	temp;		/* 8 */ +			int16_t		accel;		/* 12 */ +		} sensor;	/* 14 */ +		/* AO_LOG_TEMP_VOLT */ +		struct { +			int16_t		v_batt;		/* 4 */ +			int16_t		sense_a;	/* 6 */ +			int16_t		sense_m;	/* 8 */ +		} volt;		/* 10 */ +		/* AO_LOG_GPS_POS */ +		struct { +			int32_t		latitude;	/* 4 */ +			int32_t		longitude;	/* 8 */ +			int16_t		altitude;	/* 12 */ +		} gps;		/* 14 */ +		/* AO_LOG_GPS_TIME */ +		struct { +			uint8_t		hour;		/* 4 */ +			uint8_t		minute;		/* 5 */ +			uint8_t		second;		/* 6 */ +			uint8_t		flags;		/* 7 */ +			uint8_t		year;		/* 8 */ +			uint8_t		month;		/* 9 */ +			uint8_t		day;		/* 10 */ +			uint8_t		pad;		/* 11 */ +		} gps_time;	/* 12 */ +		/* AO_LOG_GPS_SAT (up to three packets) */ +		struct { +			uint8_t	channels;		/* 4 */ +			uint8_t	more;			/* 5 */ +			struct { +				uint8_t	svid; +				uint8_t c_n; +			} sats[4];			/* 6 */ +		} gps_sat;				/* 14 */ +		uint8_t		raw[12];		/* 4 */ +	} u;	/* 16 */ +}; +  struct ao_log_mini {  	char		type;				/* 0 */  	uint8_t		csum;				/* 1 */ @@ -304,9 +364,15 @@ uint8_t  ao_log_mega(__xdata struct ao_log_mega *log) __reentrant;  uint8_t +ao_log_metrum(__xdata struct ao_log_metrum *log) __reentrant; + +uint8_t  ao_log_mini(__xdata struct ao_log_mini *log) __reentrant;  void  ao_log_flush(void); +void +ao_gps_report_metrum_init(void); +  #endif /* _AO_LOG_H_ */ diff --git a/src/core/ao_log_metrum.c b/src/core/ao_log_metrum.c new file mode 100644 index 00000000..9c17eeed --- /dev/null +++ b/src/core/ao_log_metrum.c @@ -0,0 +1,175 @@ +/* + * Copyright © 2012 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" +#include <ao_log.h> +#include <ao_data.h> +#include <ao_flight.h> + +static __xdata uint8_t	ao_log_mutex; +static __xdata struct ao_log_metrum log; + +__code uint8_t ao_log_format = AO_LOG_FORMAT_TELEMETRUM; + +static uint8_t +ao_log_csum(__xdata uint8_t *b) __reentrant +{ +	uint8_t	sum = 0x5a; +	uint8_t	i; + +	for (i = 0; i < sizeof (struct ao_log_metrum); i++) +		sum += *b++; +	return -sum; +} + +uint8_t +ao_log_metrum(__xdata struct ao_log_metrum *log) __reentrant +{ +	uint8_t wrote = 0; +	/* set checksum */ +	log->csum = 0; +	log->csum = ao_log_csum((__xdata uint8_t *) log); +	ao_mutex_get(&ao_log_mutex); { +		if (ao_log_current_pos >= ao_log_end_pos && ao_log_running) +			ao_log_stop(); +		if (ao_log_running) { +			wrote = 1; +			ao_storage_write(ao_log_current_pos, +					 log, +					 sizeof (struct ao_log_metrum)); +			ao_log_current_pos += sizeof (struct ao_log_metrum); +		} +	} ao_mutex_put(&ao_log_mutex); +	return wrote; +} + +static uint8_t +ao_log_dump_check_data(void) +{ +	if (ao_log_csum((uint8_t *) &log) != 0) +		return 0; +	return 1; +} + +#if HAS_ADC +static __data uint8_t	ao_log_data_pos; + +/* a hack to make sure that ao_log_metrums fill the eeprom block in even units */ +typedef uint8_t check_log_size[1-(256 % sizeof(struct ao_log_metrum))] ; + +#ifndef AO_SENSOR_INTERVAL_ASCENT +#define AO_SENSOR_INTERVAL_ASCENT	1 +#define AO_SENSOR_INTERVAL_DESCENT	10 +#define AO_OTHER_INTERVAL		32 +#endif + +void +ao_log(void) +{ +	__pdata uint16_t	next_sensor, next_other; +	uint8_t			i; + +	ao_storage_setup(); + +	ao_log_scan(); + +	while (!ao_log_running) +		ao_sleep(&ao_log_running); + +#if HAS_FLIGHT +	log.type = AO_LOG_FLIGHT; +	log.tick = ao_sample_tick; +#if HAS_ACCEL +	log.u.flight.ground_accel = ao_ground_accel; +#endif +	log.u.flight.ground_pres = ao_ground_pres; +	log.u.flight.flight = ao_flight_number; +	ao_log_metrum(&log); +#endif + +	/* Write the whole contents of the ring to the log +	 * when starting up. +	 */ +	ao_log_data_pos = ao_data_ring_next(ao_data_head); +	next_other = next_sensor = ao_data_ring[ao_log_data_pos].tick; +	ao_log_state = ao_flight_startup; +	for (;;) { +		/* Write samples to EEPROM */ +		while (ao_log_data_pos != ao_data_head) { +			log.tick = ao_data_ring[ao_log_data_pos].tick; +			if ((int16_t) (log.tick - next_sensor) >= 0) { +				log.type = AO_LOG_SENSOR; +#if HAS_MS5607 +				log.u.sensor.pres = ao_data_ring[ao_log_data_pos].ms5607_raw.pres; +				log.u.sensor.temp = ao_data_ring[ao_log_data_pos].ms5607_raw.temp; +#endif +				log.u.sensor.accel = ao_data_accel(&ao_data_ring[ao_log_data_pos]); +				ao_log_metrum(&log); +				if (ao_log_state <= ao_flight_coast) +					next_sensor = log.tick + AO_SENSOR_INTERVAL_ASCENT; +				else +					next_sensor = log.tick + AO_SENSOR_INTERVAL_DESCENT; +			} +			if ((int16_t) (log.tick - next_other) >= 0) { +				log.type = AO_LOG_TEMP_VOLT; +				log.u.volt.v_batt = ao_data_ring[ao_log_data_pos].adc.v_batt; +				log.u.volt.sense_a = ao_data_ring[ao_log_data_pos].adc.sense[0]; +				log.u.volt.sense_m = ao_data_ring[ao_log_data_pos].adc.sense[1]; +				ao_log_metrum(&log); +				next_other = log.tick + AO_OTHER_INTERVAL; +			} +			ao_log_data_pos = ao_data_ring_next(ao_log_data_pos); +		} +#if HAS_FLIGHT +		/* Write state change to EEPROM */ +		if (ao_flight_state != ao_log_state) { +			ao_log_state = ao_flight_state; +			log.type = AO_LOG_STATE; +			log.tick = ao_time(); +			log.u.state.state = ao_log_state; +			log.u.state.reason = 0; +			ao_log_metrum(&log); + +			if (ao_log_state == ao_flight_landed) +				ao_log_stop(); +		} +#endif + +		ao_log_flush(); + +		/* Wait for a while */ +		ao_delay(AO_MS_TO_TICKS(100)); + +		/* Stop logging when told to */ +		while (!ao_log_running) +			ao_sleep(&ao_log_running); +	} +} +#endif + +uint16_t +ao_log_flight(uint8_t slot) +{ +	if (!ao_storage_read(ao_log_pos(slot), +			     &log, +			     sizeof (struct ao_log_metrum))) +		return 0; + +	if (ao_log_dump_check_data() && log.type == AO_LOG_FLIGHT) +		return log.u.flight.flight; +	return 0; +} diff --git a/src/core/ao_telemetry.c b/src/core/ao_telemetry.c index 03a8a273..fb40451c 100644 --- a/src/core/ao_telemetry.c +++ b/src/core/ao_telemetry.c @@ -40,6 +40,10 @@ static __pdata uint16_t ao_aprs_time;  #define AO_SEND_MEGA	1  #endif +#if defined (TELEMETRUM_V_2_0) +#define AO_SEND_METRUM	1 +#endif +  #if defined(TELEMETRUM_V_0_1) || defined(TELEMETRUM_V_0_2) || defined(TELEMETRUM_V_1_0) || defined(TELEMETRUM_V_1_1) || defined(TELEBALLOON_V_1_1) || defined(TELEMETRUM_V_1_2)  #define AO_TELEMETRY_SENSOR	AO_TELEMETRY_SENSOR_TELEMETRUM  #endif @@ -171,6 +175,57 @@ ao_send_mega_data(void)  }  #endif /* AO_SEND_MEGA */ +#ifdef AO_SEND_METRUM +/* Send telemetrum sensor packet */ +static void +ao_send_metrum_sensor(void) +{ +	__xdata	struct ao_data *packet = (__xdata struct ao_data *) &ao_data_ring[ao_data_ring_prev(ao_sample_data)]; +			 +	telemetry.generic.tick = packet->tick; +	telemetry.generic.type = AO_TELEMETRY_METRUM_SENSOR; + +	telemetry.metrum_sensor.state = ao_flight_state; +	telemetry.metrum_sensor.accel = ao_data_accel(packet); +	telemetry.metrum_sensor.pres = ao_data_pres(packet); +	telemetry.metrum_sensor.temp = ao_data_temp(packet); + +	telemetry.metrum_sensor.acceleration = ao_accel; +	telemetry.metrum_sensor.speed = ao_speed; +	telemetry.metrum_sensor.height = ao_height; + +	telemetry.metrum_sensor.v_batt = packet->adc.v_batt; +	telemetry.metrum_sensor.sense_a = packet->adc.sense[0]; +	telemetry.metrum_sensor.sense_m = packet->adc.sense[1]; + +	ao_radio_send(&telemetry, sizeof (telemetry)); +} + +static __pdata int8_t ao_telemetry_metrum_data_max; +static __pdata int8_t ao_telemetry_metrum_data_cur; + +/* Send telemetrum data packet */ +static void +ao_send_metrum_data(void) +{ +	if (--ao_telemetry_metrum_data_cur <= 0) { +		__xdata	struct ao_data *packet = (__xdata struct ao_data *) &ao_data_ring[ao_data_ring_prev(ao_sample_data)]; +		uint8_t	i; + +		telemetry.generic.tick = packet->tick; +		telemetry.generic.type = AO_TELEMETRY_MEGA_DATA; + +		telemetry.metrum_data.ground_pres = ao_ground_pres; +		telemetry.metrum_data.ground_accel = ao_ground_accel; +		telemetry.metrum_data.accel_plus_g = ao_config.accel_plus_g; +		telemetry.metrum_data.accel_minus_g = ao_config.accel_minus_g; + +		ao_radio_send(&telemetry, sizeof (telemetry)); +		ao_telemetry_metrum_data_cur = ao_telemetry_metrum_data_max; +	} +} +#endif /* AO_SEND_MEGA */ +  #ifdef AO_SEND_ALL_BARO  static uint8_t		ao_baro_sample; @@ -327,9 +382,14 @@ ao_telemetry(void)  				ao_send_mega_sensor();  				ao_send_mega_data();  #else +#ifdef AO_SEND_METRUM +				ao_send_metrum_sensor(); +				ao_send_metrum_data(); +#else  				ao_send_sensor();  #endif  #endif +#endif  #if HAS_COMPANION  				if (ao_companion_running) @@ -399,6 +459,12 @@ ao_telemetry_set_interval(uint16_t interval)  		cur++;  	ao_telemetry_mega_data_cur = cur;  #endif +#if AO_SEND_METRUM +	ao_telemetry_metrum_data_max = AO_SEC_TO_TICKS(1) / interval; +	if (ao_telemetry_metrum_data_max > cur) +		cur++; +	ao_telemetry_metrum_data_cur = cur; +#endif  #if HAS_COMPANION  	if (!ao_companion_setup.update_period) diff --git a/src/core/ao_telemetry.h b/src/core/ao_telemetry.h index f2d201de..17dc3e93 100644 --- a/src/core/ao_telemetry.h +++ b/src/core/ao_telemetry.h @@ -207,6 +207,48 @@ struct ao_telemetry_mega_data {  }; +#define AO_TELEMETRY_METRUM_SENSOR	0x0A + +struct ao_telemetry_metrum_sensor { +	uint16_t	serial;		/*  0 */ +	uint16_t	tick;		/*  2 */ +	uint8_t		type;		/*  4 */ + +	uint8_t         state;          /*  5 flight state */ +	int16_t		accel;		/*  6 Z axis */ + +	int32_t		pres;		/*  8 Pa * 10 */ +	int16_t		temp;		/* 12 °C * 100 */ + +	int16_t         acceleration;   /* 14 m/s² * 16 */ +	int16_t         speed;          /* 16 m/s * 16 */ +	int16_t         height;         /* 18 m */ + +	int16_t		v_batt;		/* 20 battery voltage */ +	int16_t		sense_a;	/* 22 apogee continuity sense */ +	int16_t		sense_m;	/* 24 main continuity sense */ + +	uint8_t		pad[6];		/* 26 */ +	/* 32 */ +}; +	 +#define AO_TELEMETRY_METRUM_DATA	0x0B + +struct ao_telemetry_metrum_data { +	uint16_t	serial;		/*  0 */ +	uint16_t	tick;		/*  2 */ +	uint8_t		type;		/*  4 */ + +	int32_t		ground_pres;	/* 8 average pres on pad */ +	int16_t		ground_accel;	/* 12 average accel on pad */ +	int16_t		accel_plus_g;	/* 14 accel calibration at +1g */ +	int16_t		accel_minus_g;	/* 16 accel calibration at -1g */ + +	uint8_t		pad[14];	/* 18 */ +	/* 32 */ +}; + +  /* #define AO_SEND_ALL_BARO */  #define AO_TELEMETRY_BARO		0x80 @@ -240,6 +282,8 @@ union ao_telemetry_all {  	struct ao_telemetry_companion		companion;  	struct ao_telemetry_mega_sensor		mega_sensor;  	struct ao_telemetry_mega_data		mega_data; +	struct ao_telemetry_metrum_sensor	metrum_sensor; +	struct ao_telemetry_metrum_data		metrum_data;  	struct ao_telemetry_baro		baro;  }; diff --git a/src/stm/ao_arch.h b/src/stm/ao_arch.h index adc288c3..42fe727a 100644 --- a/src/stm/ao_arch.h +++ b/src/stm/ao_arch.h @@ -34,6 +34,8 @@  #define AO_TICK_SIGNED	int16_t  #endif +#define AO_PORT_TYPE	uint16_t +  /* Various definitions to make GCC look more like SDCC */  #define ao_arch_naked_declare	__attribute__((naked)) diff --git a/src/stm/ao_beep_stm.c b/src/stm/ao_beep_stm.c index 4761fbfc..a95d869b 100644 --- a/src/stm/ao_beep_stm.c +++ b/src/stm/ao_beep_stm.c @@ -17,6 +17,10 @@  #include "ao.h" +#ifndef BEEPER_CHANNEL +#define BEEPER_CHANNEL	1 +#endif +  void  ao_beep(uint8_t beep)  { @@ -56,6 +60,7 @@ ao_beep(uint8_t beep)  		 *  is enabled and active high.  		 */ +#if BEEPER_CHANNEL == 1  		stm_tim3.ccmr1 = ((0 << STM_TIM234_CCMR1_OC2CE) |  				  (STM_TIM234_CCMR1_OC2M_FROZEN << STM_TIM234_CCMR1_OC2M) |  				  (0 << STM_TIM234_CCMR1_OC2PE) | @@ -68,7 +73,6 @@ ao_beep(uint8_t beep)  				  (0 << STM_TIM234_CCMR1_OC1FE) |  				  (STM_TIM234_CCMR1_CC1S_OUTPUT << STM_TIM234_CCMR1_CC1S)); -  		stm_tim3.ccer = ((0 << STM_TIM234_CCER_CC4NP) |  				 (0 << STM_TIM234_CCER_CC4P) |  				 (0 << STM_TIM234_CCER_CC4E) | @@ -81,6 +85,33 @@ ao_beep(uint8_t beep)  				 (0 << STM_TIM234_CCER_CC1NP) |  				 (0 << STM_TIM234_CCER_CC1P) |  				 (1 << STM_TIM234_CCER_CC1E)); +#endif +#if BEEPER_CHANNEL == 4 +		stm_tim3.ccmr2 = ((0 << STM_TIM234_CCMR2_OC4CE) | +				  (STM_TIM234_CCMR2_OC4M_TOGGLE << STM_TIM234_CCMR2_OC4M) | +				  (0 << STM_TIM234_CCMR2_OC4PE) | +				  (0 << STM_TIM234_CCMR2_OC4FE) | +				  (STM_TIM234_CCMR2_CC4S_OUTPUT << STM_TIM234_CCMR2_CC4S) | + +				  (0 << STM_TIM234_CCMR2_OC3CE) | +				  (STM_TIM234_CCMR2_OC3M_FROZEN << STM_TIM234_CCMR2_OC3M) | +				  (0 << STM_TIM234_CCMR2_OC3PE) | +				  (0 << STM_TIM234_CCMR2_OC3FE) | +				  (STM_TIM234_CCMR2_CC3S_OUTPUT << STM_TIM234_CCMR2_CC3S)); + +		stm_tim3.ccer = ((0 << STM_TIM234_CCER_CC4NP) | +				 (0 << STM_TIM234_CCER_CC4P) | +				 (1 << STM_TIM234_CCER_CC4E) | +				 (0 << STM_TIM234_CCER_CC3NP) | +				 (0 << STM_TIM234_CCER_CC3P) | +				 (0 << STM_TIM234_CCER_CC3E) | +				 (0 << STM_TIM234_CCER_CC2NP) | +				 (0 << STM_TIM234_CCER_CC2P) | +				 (0 << STM_TIM234_CCER_CC2E) | +				 (0 << STM_TIM234_CCER_CC1NP) | +				 (0 << STM_TIM234_CCER_CC1P) | +				 (0 << STM_TIM234_CCER_CC1E)); +#endif  		/* 5. Enable the counter by setting the CEN bit in the TIMx_CR1 register. */ @@ -110,13 +141,22 @@ ao_beep_for(uint8_t beep, uint16_t ticks) __reentrant  void  ao_beep_init(void)  { -	/* Our beeper is on PC6, which is hooked to TIM3_CH1, -	 * which is on PC6 -	 */ +#if BEEPER_CHANNEL == 1 +	/* Our beeper is on PC6, which is hooked to TIM3_CH1. +	 */  	stm_rcc.ahbenr |= (1 << STM_RCC_AHBENR_GPIOCEN);  	stm_afr_set(&stm_gpioc, 6, STM_AFR_AF2); +#endif +#if BEEPER_CHANNEL == 4 + +	/* Our beeper is on PB1, which is hooked to TIM3_CH4. +	 */ +	stm_rcc.ahbenr |= (1 << STM_RCC_AHBENR_GPIOBEN); + +	stm_afr_set(&stm_gpiob, 1, STM_AFR_AF2); +#endif  	/* Leave the timer off until requested */ diff --git a/src/stm/stm32l.h b/src/stm/stm32l.h index 1868468f..ff3f5336 100644 --- a/src/stm/stm32l.h +++ b/src/stm/stm32l.h @@ -1739,7 +1739,7 @@ extern struct stm_tim234 stm_tim2, stm_tim3, stm_tim4;  #define  STM_TIM234_CCMR1_CC1S_INPUT_TRC		3  #define  STM_TIM234_CCMR1_CC1S_MASK			3 -#define STM_TIM234_CCMR2_OC2CE	15 +#define STM_TIM234_CCMR2_OC4CE	15  #define STM_TIM234_CCMR2_OC4M	12  #define  STM_TIM234_CCMR2_OC4M_FROZEN			0  #define  STM_TIM234_CCMR2_OC4M_SET_HIGH_ON_MATCH	1 diff --git a/src/telemetrum-v2.0/.gitignore b/src/telemetrum-v2.0/.gitignore new file mode 100644 index 00000000..35ce24d4 --- /dev/null +++ b/src/telemetrum-v2.0/.gitignore @@ -0,0 +1,2 @@ +ao_product.h +telemetrum-*.elf diff --git a/src/telemetrum-v2.0/Makefile b/src/telemetrum-v2.0/Makefile new file mode 100644 index 00000000..c03a5539 --- /dev/null +++ b/src/telemetrum-v2.0/Makefile @@ -0,0 +1,122 @@ +# +# AltOS build +# +# + +include ../stm/Makefile.defs + +INC = \ +	ao.h \ +	ao_arch.h \ +	ao_arch_funcs.h \ +	ao_companion.h \ +	ao_data.h \ +	ao_sample.h \ +	ao_pins.h \ +	altitude-pa.h \ +	ao_kalman.h \ +	ao_product.h \ +	ao_ms5607.h \ +	ao_mma655x.h \ +	ao_cc1120_CC1120.h \ +	ao_profile.h \ +	ao_task.h \ +	ao_whiten.h \ +	ao_sample_profile.h \ +	ao_mpu.h \ +	stm32l.h \ +	Makefile + +#PROFILE=ao_profile.c +#PROFILE_DEF=-DAO_PROFILE=1 + +#SAMPLE_PROFILE=ao_sample_profile.c \ +#	ao_sample_profile_timer.c +#SAMPLE_PROFILE_DEF=-DHAS_SAMPLE_PROFILE=1 + +#STACK_GUARD=ao_mpu_stm.c +#STACK_GUARD_DEF=-DHAS_STACK_GUARD=1 + +ALTOS_SRC = \ +	ao_boot_chain.c \ +	ao_interrupt.c \ +	ao_product.c \ +	ao_romconfig.c \ +	ao_cmd.c \ +	ao_config.c \ +	ao_task.c \ +	ao_led.c \ +	ao_stdio.c \ +	ao_panic.c \ +	ao_timer.c \ +	ao_mutex.c \ +	ao_serial_stm.c \ +	ao_gps_ublox.c \ +	ao_gps_show.c \ +	ao_gps_report_metrum.c \ +	ao_ignite.c \ +	ao_freq.c \ +	ao_dma_stm.c \ +	ao_spi_stm.c \ +	ao_cc1120.c \ +	ao_fec_tx.c \ +	ao_fec_rx.c \ +	ao_data.c \ +	ao_ms5607.c \ +	ao_mma655x.c \ +	ao_adc_stm.c \ +	ao_beep_stm.c \ +	ao_storage.c \ +	ao_m25.c \ +	ao_usb_stm.c \ +	ao_exti_stm.c \ +	ao_report.c \ +	ao_convert_pa.c \ +	ao_log.c \ +	ao_log_metrum.c \ +	ao_sample.c \ +	ao_kalman.c \ +	ao_flight.c \ +	ao_telemetry.c \ +	ao_packet_slave.c \ +	ao_packet.c \ +	ao_companion.c \ +	ao_aprs.c \ +	$(PROFILE) \ +	$(SAMPLE_PROFILE) \ +	$(STACK_GUARD) + +PRODUCT=TeleMetrum-v2.0 +PRODUCT_DEF=-DTELEMETRUM_V_2_0 +IDPRODUCT=0x000b + +CFLAGS = $(PRODUCT_DEF) $(STM_CFLAGS) $(PROFILE_DEF) $(SAMPLE_PROFILE_DEF) $(STACK_GUARD_DEF) -Os -g + +PROGNAME=telemetrum-v2.0 +PROG=$(PROGNAME)-$(VERSION).elf + +SRC=$(ALTOS_SRC) ao_telemetrum.c +OBJ=$(SRC:.c=.o) + +all: $(PROG) + +$(PROG): Makefile $(OBJ) altos.ld +	$(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(OBJ) $(SAT_CLIB) -lgcc + +../altitude-pa.h: make-altitude-pa +	nickle $< > $@ + +$(OBJ): $(INC) + +ao_product.h: ao-make-product.5c ../Version +	$(call quiet,NICKLE,$<) $< -m altusmetrum.org -i $(IDPRODUCT) -p $(PRODUCT) -v $(VERSION) > $@ + +distclean:	clean + +clean: +	rm -f *.o $(PROGNAME)-*.elf +	rm -f ao_product.h + +install: + +uninstall: diff --git a/src/telemetrum-v2.0/ao_pins.h b/src/telemetrum-v2.0/ao_pins.h new file mode 100644 index 00000000..36cfc7e0 --- /dev/null +++ b/src/telemetrum-v2.0/ao_pins.h @@ -0,0 +1,282 @@ +/* + * Copyright © 2012 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. + */ + +#ifndef _AO_PINS_H_ +#define _AO_PINS_H_ + +#define HAS_TASK_QUEUE		1 + +/* 8MHz High speed external crystal */ +#define AO_HSE			8000000 + +/* PLLVCO = 96MHz (so that USB will work) */ +#define AO_PLLMUL		12 +#define AO_RCC_CFGR_PLLMUL	(STM_RCC_CFGR_PLLMUL_12) + +/* SYSCLK = 32MHz (no need to go faster than CPU) */ +#define AO_PLLDIV		3 +#define AO_RCC_CFGR_PLLDIV	(STM_RCC_CFGR_PLLDIV_3) + +/* HCLK = 32MHz (CPU clock) */ +#define AO_AHB_PRESCALER	1 +#define AO_RCC_CFGR_HPRE_DIV	STM_RCC_CFGR_HPRE_DIV_1 + +/* Run APB1 at 16MHz (HCLK/2) */ +#define AO_APB1_PRESCALER	2 +#define AO_RCC_CFGR_PPRE1_DIV	STM_RCC_CFGR_PPRE2_DIV_2 + +/* Run APB2 at 16MHz (HCLK/2) */ +#define AO_APB2_PRESCALER	2 +#define AO_RCC_CFGR_PPRE2_DIV	STM_RCC_CFGR_PPRE2_DIV_2 + +#define HAS_SERIAL_1		0 +#define USE_SERIAL_1_STDIN	0 +#define SERIAL_1_PB6_PB7	0 +#define SERIAL_1_PA9_PA10	1 + +#define HAS_SERIAL_2		0 +#define USE_SERIAL_2_STDIN	0 +#define SERIAL_2_PA2_PA3	0 +#define SERIAL_2_PD5_PD6	0 + +#define HAS_SERIAL_3		1 +#define USE_SERIAL_3_STDIN	0 +#define SERIAL_3_PB10_PB11	1 +#define SERIAL_3_PC10_PC11	0 +#define SERIAL_3_PD8_PD9	0 + +#define ao_gps_getchar		ao_serial3_getchar +#define ao_gps_putchar		ao_serial3_putchar +#define ao_gps_set_speed	ao_serial3_set_speed +#define ao_gps_fifo		(ao_stm_usart3.rx_fifo) + +#define HAS_EEPROM		1 +#define USE_INTERNAL_FLASH	0 +#define HAS_USB			1 +#define HAS_BEEP		1 +#define BEEPER_CHANNEL		4 +#define HAS_RADIO		1 +#define HAS_TELEMETRY		1 +#define HAS_APRS		1 + +#define HAS_SPI_1		1 +#define SPI_1_PA5_PA6_PA7	1	/* Barometer */ +#define SPI_1_PB3_PB4_PB5	1	/* Accelerometer */ +#define SPI_1_PE13_PE14_PE15	0 +#define SPI_1_OSPEEDR		STM_OSPEEDR_10MHz + +#define HAS_SPI_2		1 +#define SPI_2_PB13_PB14_PB15	1	/* Flash, Companion, Radio */ +#define SPI_2_PD1_PD3_PD4	0 +#define SPI_2_OSPEEDR		STM_OSPEEDR_10MHz + +#define SPI_2_PORT		(&stm_gpiob) +#define SPI_2_SCK_PIN		13 +#define SPI_2_MISO_PIN		14 +#define SPI_2_MOSI_PIN		15 + +#define HAS_I2C_1		0 +#define I2C_1_PB8_PB9		0 + +#define HAS_I2C_2		0 +#define I2C_2_PB10_PB11		0 + +#define PACKET_HAS_SLAVE	1 +#define PACKET_HAS_MASTER	0 + +#define LOW_LEVEL_DEBUG		0 + +#define LED_PORT_ENABLE		STM_RCC_AHBENR_GPIOCEN +#define LED_PORT		(&stm_gpioc) +#define LED_PIN_RED		14 +#define LED_PIN_GREEN		15 +#define AO_LED_RED		(1 << LED_PIN_RED) +#define AO_LED_GREEN		(1 << LED_PIN_GREEN) + +#define LEDS_AVAILABLE		(AO_LED_RED | AO_LED_GREEN) + +#define HAS_GPS			1 +#define HAS_FLIGHT		1 +#define HAS_ADC			1 +#define HAS_ADC_TEMP		1 +#define HAS_LOG			1 + +/* + * Igniter + */ + +#define HAS_IGNITE		1 +#define HAS_IGNITE_REPORT	1 + +#define AO_SENSE_DROGUE(p)	((p)->adc.sense[0]) +#define AO_SENSE_MAIN(p)	((p)->adc.sense[1]) +#define AO_IGNITER_CLOSED	400 +#define AO_IGNITER_OPEN		60 + +/* Drogue */ +#define AO_IGNITER_DROGUE_PORT	(&stm_gpioa) +#define AO_IGNITER_DROGUE_PIN	8 + +/* Main */ +#define AO_IGNITER_MAIN_PORT	(&stm_gpioa) +#define AO_IGNITER_MAIN_PIN	9 + +#define AO_IGNITER_SET_DROGUE(v)	stm_gpio_set(AO_IGNITER_DROGUE_PORT, AO_IGNITER_DROGUE_PIN, v) +#define AO_IGNITER_SET_MAIN(v)		stm_gpio_set(AO_IGNITER_MAIN_PORT, AO_IGNITER_MAIN_PIN, v) + +/* + * ADC + */ +#define AO_DATA_RING		32 +#define AO_ADC_NUM_SENSE	2 + +struct ao_adc { +	int16_t			sense[AO_ADC_NUM_SENSE]; +	int16_t			v_batt; +	int16_t			temp; +}; + +#define AO_ADC_DUMP(p) \ +	printf("tick: %5u drogue: %5d main: %5d batt: %5d pbatt: %5d temp: %5d\n", \ +	       (p)->tick, \ +	       (p)->adc.sense[0], (p)->adc.sense[1], \ +	       (p)->adc.v_batt, (p)->adc.temp) + +#define AO_ADC_SENSE_DROGUE	0 +#define AO_ADC_SENSE_DROGUE_PORT	(&stm_gpioa) +#define AO_ADC_SENSE_DROGUE_PIN	0 + +#define AO_ADC_SENSE_MAIN	1 +#define AO_ADC_SENSE_MAIN_PORT	(&stm_gpioa) +#define AO_ADC_SENSE_MAIN_PIN	1 + +#define AO_ADC_V_BATT		8 +#define AO_ADC_V_BATT_PORT	(&stm_gpiob) +#define AO_ADC_V_BATT_PIN	0 + +#define AO_ADC_TEMP		16 + +#define AO_ADC_RCC_AHBENR	((1 << STM_RCC_AHBENR_GPIOAEN) | \ +				 (1 << STM_RCC_AHBENR_GPIOEEN) | \ +				 (1 << STM_RCC_AHBENR_GPIOBEN)) + +#define AO_NUM_ADC_PIN		3 + +#define AO_ADC_PIN0_PORT	AO_ADC_SENSE_DROGUE_PORT +#define AO_ADC_PIN0_PIN		AO_ADC_SENSE_DROGUE_PIN +#define AO_ADC_PIN1_PORT	AO_ADC_SENSE_MAIN_PORT +#define AO_ADC_PIN1_PIN		AO_ADC_SENSE_MAIN_PIN +#define AO_ADC_PIN2_PORT	AO_ADC_V_BATT_PORT +#define AO_ADC_PIN2_PIN		AO_ADC_V_BATT_PIN + +#define AO_NUM_ADC	       	(AO_NUM_ADC_PIN + 1) + +#define AO_ADC_SQ1		AO_ADC_SENSE_DROGUE +#define AO_ADC_SQ2		AO_ADC_SENSE_MAIN +#define AO_ADC_SQ3		AO_ADC_V_BATT +#define AO_ADC_SQ4		AO_ADC_TEMP + +/* + * Pressure sensor settings + */ +#define HAS_MS5607		1 +#define HAS_MS5611		0 +#define AO_MS5607_PRIVATE_PINS	1 +#define AO_MS5607_CS_PORT	(&stm_gpiob) +#define AO_MS5607_CS_PIN	12 +#define AO_MS5607_CS_MASK	(1 << AO_MS5607_CS) +#define AO_MS5607_MISO_PORT	(&stm_gpioa) +#define AO_MS5607_MISO_PIN	6 +#define AO_MS5607_MISO_MASK	(1 << AO_MS5607_MISO) +#define AO_MS5607_SPI_INDEX	AO_SPI_1_PA5_PA6_PA7 + +/* + * SPI Flash memory + */ + +#define M25_MAX_CHIPS		1 +#define AO_M25_SPI_CS_PORT	(&stm_gpiob) +#define AO_M25_SPI_CS_MASK	(1 << 8) +#define AO_M25_SPI_BUS		AO_SPI_2_PB13_PB14_PB15 + +/* + * Radio (cc1120) + */ + +/* gets pretty close to 434.550 */ + +#define AO_RADIO_CAL_DEFAULT 	0x6ca333 + +#define AO_FEC_DEBUG		0 +#define AO_CC1120_SPI_CS_PORT	(&stm_gpioa) +#define AO_CC1120_SPI_CS_PIN	2 +#define AO_CC1120_SPI_BUS	AO_SPI_2_PB13_PB14_PB15 +#define AO_CC1120_SPI		stm_spi2 + +#define AO_CC1120_INT_PORT		(&stm_gpioa) +#define AO_CC1120_INT_PIN		(3) +#define AO_CC1120_MCU_WAKEUP_PORT	(&stm_gpioa) +#define AO_CC1120_MCU_WAKEUP_PIN	(4) + +#define AO_CC1120_INT_GPIO	2 +#define AO_CC1120_INT_GPIO_IOCFG	CC1120_IOCFG2 + +#define AO_CC1120_MARC_GPIO	3 +#define AO_CC1120_MARC_GPIO_IOCFG	CC1120_IOCFG3 + +#define HAS_BOOT_RADIO		0 + +#define HAS_HIGHG_ACCEL		1 + +/* + * mma655x + */ + +#define HAS_MMA655X		1 +#define AO_MMA655X_SPI_INDEX	AO_SPI_1_PE13_PE14_PE15 +#define AO_MMA655X_CS_PORT	(&stm_gpiod) +#define AO_MMA655X_CS_PIN	4 + +#define NUM_CMDS		16 + +/* + * Companion + */ + +#define AO_COMPANION_CS_PORT	(&stm_gpiob) +#define AO_COMPANION_CS_PIN	(6) +#define AO_COMPANION_SPI_BUS	AO_SPI_2_PB13_PB14_PB15 + +/* + * Monitor + */ + +#define HAS_MONITOR		0 +#define LEGACY_MONITOR		0 +#define HAS_MONITOR_PUT		1 +#define AO_MONITOR_LED		0 +#define HAS_RSSI		0 + +/* + * Profiling Viterbi decoding + */ + +#ifndef AO_PROFILE +#define AO_PROFILE	       	0 +#endif + +#endif /* _AO_PINS_H_ */ diff --git a/src/telemetrum-v2.0/ao_telemetrum.c b/src/telemetrum-v2.0/ao_telemetrum.c new file mode 100644 index 00000000..e365417d --- /dev/null +++ b/src/telemetrum-v2.0/ao_telemetrum.c @@ -0,0 +1,90 @@ +/* + * Copyright © 2011 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> +#include <ao_ms5607.h> +#include <ao_mma655x.h> +#include <ao_log.h> +#include <ao_exti.h> +#include <ao_packet.h> +#include <ao_companion.h> +#include <ao_profile.h> +#if HAS_SAMPLE_PROFILE +#include <ao_sample_profile.h> +#endif +#if HAS_STACK_GUARD +#include <ao_mpu.h> +#endif + +int +main(void) +{ +	ao_clock_init(); +	 +#if HAS_STACK_GUARD +	ao_mpu_init(); +#endif + +	ao_task_init(); +	ao_serial_init(); +	ao_led_init(LEDS_AVAILABLE); +	ao_led_on(AO_LED_GREEN); +	ao_timer_init(); + +	ao_spi_init(); +	ao_dma_init(); +	ao_exti_init(); + +	ao_adc_init(); +#if HAS_BEEP +	ao_beep_init(); +#endif +	ao_cmd_init(); + +#if HAS_MS5607 +	ao_ms5607_init(); +#endif +#if HAS_MMA655X +	ao_mma655x_init(); +#endif + +	ao_storage_init(); +	 +	ao_flight_init(); +	ao_log_init(); +	ao_report_init(); + +	ao_usb_init(); +	ao_gps_init(); +	ao_gps_report_metrum_init(); +	ao_telemetry_init(); +	ao_radio_init(); +	ao_packet_slave_init(FALSE); +	ao_igniter_init(); +	ao_companion_init(); + +	ao_config_init(); +#if AO_PROFILE +	ao_profile_init(); +#endif +#if HAS_SAMPLE_PROFILE +	ao_sample_profile_init(); +#endif +	 +	ao_start_scheduler(); +	return 0; +} | 
