diff options
Diffstat (limited to 'src/core')
| -rw-r--r-- | src/core/ao.h | 2 | ||||
| -rw-r--r-- | src/core/ao_cmd.c | 4 | ||||
| -rw-r--r-- | src/core/ao_data.c | 2 | ||||
| -rw-r--r-- | src/core/ao_data.h | 2 | ||||
| -rw-r--r-- | src/core/ao_int64.c | 158 | ||||
| -rw-r--r-- | src/core/ao_int64.h | 48 | ||||
| -rw-r--r-- | src/core/ao_kalman.c | 4 | ||||
| -rw-r--r-- | src/core/ao_log_mini.c | 1 | ||||
| -rw-r--r-- | src/core/ao_log_telem.c | 2 | ||||
| -rw-r--r-- | src/core/ao_sample.h | 4 | ||||
| -rw-r--r-- | src/core/ao_task.c | 2 | ||||
| -rw-r--r-- | src/core/ao_task.h | 5 | ||||
| -rw-r--r-- | src/core/ao_telemetry.c | 66 | ||||
| -rw-r--r-- | src/core/ao_telemetry.h | 25 | 
14 files changed, 296 insertions, 29 deletions
| diff --git a/src/core/ao.h b/src/core/ao.h index caa0ec19..e7320327 100644 --- a/src/core/ao.h +++ b/src/core/ao.h @@ -182,7 +182,7 @@ void  ao_cmd_hex(void);  void -ao_cmd_decimal(void); +ao_cmd_decimal(void) __reentrant;  /* Read a single hex nibble off stdin. */  uint8_t diff --git a/src/core/ao_cmd.c b/src/core/ao_cmd.c index 5113548b..4ebaa607 100644 --- a/src/core/ao_cmd.c +++ b/src/core/ao_cmd.c @@ -206,9 +206,9 @@ ao_cmd_hex(void)  }  void -ao_cmd_decimal(void) +ao_cmd_decimal(void) __reentrant  { -	__pdata uint8_t	r = ao_cmd_lex_error; +	uint8_t	r = ao_cmd_lex_error;  	ao_cmd_lex_u32 = 0;  	ao_cmd_white(); diff --git a/src/core/ao_data.c b/src/core/ao_data.c index 38d2f7ff..6a3d02a1 100644 --- a/src/core/ao_data.c +++ b/src/core/ao_data.c @@ -22,6 +22,7 @@ volatile __xdata struct ao_data	ao_data_ring[AO_DATA_RING];  volatile __data uint8_t		ao_data_head;  volatile __data uint8_t		ao_data_present; +#ifndef ao_data_count  void  ao_data_get(__xdata struct ao_data *packet)  { @@ -32,3 +33,4 @@ ao_data_get(__xdata struct ao_data *packet)  #endif  	memcpy(packet, (void *) &ao_data_ring[i], sizeof (struct ao_data));  } +#endif diff --git a/src/core/ao_data.h b/src/core/ao_data.h index c873e9d3..339afe69 100644 --- a/src/core/ao_data.h +++ b/src/core/ao_data.h @@ -101,7 +101,7 @@ extern volatile __data uint8_t		ao_data_count;   * signaled by the timer tick   */  #define AO_DATA_WAIT() do {				\ -		ao_sleep((void *) &ao_data_count);	\ +		ao_sleep(DATA_TO_XDATA ((void *) &ao_data_count));	\  	} while (0)  #endif /* AO_DATA_RING */ diff --git a/src/core/ao_int64.c b/src/core/ao_int64.c new file mode 100644 index 00000000..aa23dbe0 --- /dev/null +++ b/src/core/ao_int64.c @@ -0,0 +1,158 @@ +/* + * Copyright © 2013 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_int64.h> + +__pdata ao_int64_t *__data ao_64r, *__data ao_64a, *__data ao_64b; + +void ao_plus64(__pdata ao_int64_t *r, __pdata ao_int64_t *a, __pdata ao_int64_t *b) __FATTR { +	__LOCAL uint32_t	t; + +	r->high = a->high + b->high; +	t = a->low + b->low; +	if (t < a->low) +		r->high++; +	r->low = t; +} + +void ao_minus64(__pdata ao_int64_t *r, __pdata ao_int64_t *a, __pdata ao_int64_t *b) __FATTR { +	__LOCAL uint32_t	t; + +	r->high = a->high - b->high; +	t = a->low - b->low; +	if (t > a->low) +		r->high--; +	r->low = t; +} + +void ao_rshift64(__pdata ao_int64_t *r, __pdata ao_int64_t *a, uint8_t d) __FATTR { +	if (d < 32) { +		r->low = a->low >> d; +		if (d) +			r->low |= a->high << (32 - d); +		r->high = (int32_t) a->high >> d; +	} else { +		d &= 0x1f; +		r->low = (int32_t) a->high >> d; +		r->high = 0; +	} +} + +void ao_lshift64(__pdata ao_int64_t *r, __pdata ao_int64_t *a, uint8_t d) __FATTR { +	if (d < 32) { +		r->high = a->high << d; +		if (d) +			r->high |= a->low >> (32 - d); +		r->low = a->low << d; +	} else { +		d &= 0x1f; +		r->high = a->low << d; +		r->low = 0; +	} +} + +static void ao_umul64_32_32(__ARG ao_int64_t *r, uint32_t a, uint32_t b) __reentrant { +	__LOCAL uint32_t	s; +	__LOCAL ao_int64_t	t; +	r->low = (uint32_t) (uint16_t) a * (uint16_t) b; +	r->high = (uint32_t) (uint16_t) (a >> 16) * (uint16_t) (b >> 16); + +	s = (uint32_t) (uint16_t) (a >> 16) * (uint16_t) b; + +	t.high = s >> 16; +	t.low = s << 16; +	ao_plus64(r, r, &t); + +	s = (uint32_t) (uint16_t) a * (uint16_t) (b >> 16); + +	t.high = s >> 16; +	t.low = s << 16; +	ao_plus64(r, r, &t); +} + +void ao_neg64(__pdata ao_int64_t *r, __pdata ao_int64_t *a) __FATTR { +	r->high = ~a->high; +	if (!(r->low = ~a->low + 1)) +		r->high++; +} + +void ao_mul64_32_32(__ARG ao_int64_t *r, int32_t a, int32_t b) __FATTR { +	uint8_t		negative = 0; + +	if (a < 0) { +		a = -a; +		++negative; +	} +	if (b < 0) { +		b = -b; +		--negative; +	} +	ao_umul64_32_32(r, a, b); +	if (negative) +		ao_neg64(r, r); +} + +static void ao_umul64(__ARG ao_int64_t *r, __ARG ao_int64_t *a, __ARG ao_int64_t *b) __reentrant { +	__LOCAL ao_int64_t	r2, r3; + +	ao_umul64_32_32(&r2, a->high, b->low); +	ao_umul64_32_32(&r3, a->low, b->high); +	ao_umul64_32_32(r, a->low, b->low); + +	r->high += r2.low + r3.low; +} + +static __ARG ao_int64_t	ap, bp; + +void ao_mul64(__ARG ao_int64_t *r, __ARG ao_int64_t *a, __ARG ao_int64_t *b) __FATTR { +	uint8_t	negative = 0; + +	if (ao_int64_negativep(a)) { +		ao_neg64(&ap, a); +		a = ≈ +		++negative; +	} +	if (ao_int64_negativep(b)) { +		ao_neg64(&bp, b); +		b = &bp; +		--negative; +	} +	ao_umul64(r, a, b); +	if (negative) +		ao_neg64(r, r); +} + +static void ao_umul64_64_16(__ARG ao_int64_t *r, __ARG ao_int64_t *a, uint16_t b) __reentrant { +	__LOCAL uint32_t h; + +	h = a->high * b; +	ao_umul64_32_32(r, a->low, b); +	r->high += h; +} + +void ao_mul64_64_16(__ARG ao_int64_t *r, __ARG ao_int64_t *a, __ARG uint16_t b) __FATTR { +	uint8_t		negative = 0; + +	if ((int32_t) a->high < 0) { +		ao_neg64(&ap, a); +		a = ≈ +		negative++; +	} else +		ao_umul64_64_16(r, a, b); +	if (negative) +		ao_neg64(r, r); +} diff --git a/src/core/ao_int64.h b/src/core/ao_int64.h new file mode 100644 index 00000000..b16db58c --- /dev/null +++ b/src/core/ao_int64.h @@ -0,0 +1,48 @@ +/* + * Copyright © 2013 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_INT64_H_ +#define _AO_INT64_H_ + +#include <stdint.h> + +typedef struct { +	uint32_t	high; +	uint32_t	low; +} ao_int64_t; + +#define __FATTR +#define __ARG __pdata +#define __LOCAL static __pdata + +void ao_plus64(__pdata ao_int64_t *ao_64r, __pdata ao_int64_t *ao_64a, __pdata ao_int64_t *ao_64b) __FATTR; +void ao_minus64(__pdata ao_int64_t *ao_64r, __pdata ao_int64_t *ao_64a, __pdata ao_int64_t *ao_64b) __FATTR; +void ao_neg64(__pdata ao_int64_t *ao_64r, __pdata ao_int64_t *ao_64a) __FATTR; +void ao_rshift64(__pdata ao_int64_t *ao_64r, __pdata ao_int64_t *ao_64a, uint8_t d) __FATTR; +void ao_lshift64(__pdata ao_int64_t *ao_64r, __pdata ao_int64_t *ao_64a, uint8_t d) __FATTR; +void ao_mul64_32_32(__ARG ao_int64_t *r, __ARG int32_t a, __ARG int32_t b) __FATTR; +void ao_mul64_64_16(__ARG ao_int64_t *r, __ARG ao_int64_t *a, __ARG uint16_t b) __FATTR; +void ao_mul64(__ARG ao_int64_t * __ARG r, __ARG ao_int64_t * __ARG a, __ARG ao_int64_t *__ARG b) __FATTR; + +#define ao_int64_init32(r, a) (((r)->high = 0), (r)->low = (a)) +#define ao_int64_init64(r, a, b) (((r)->high = (a)), (r)->low = (b)) + +#define ao_cast64(a) (((int64_t) (a)->high << 32) | (a)->low) + +#define ao_int64_negativep(a)	(((int32_t) (a)->high) < 0) + +#endif /* _AO_INT64_H_ */ diff --git a/src/core/ao_kalman.c b/src/core/ao_kalman.c index 59ffd8b2..762b2c0a 100644 --- a/src/core/ao_kalman.c +++ b/src/core/ao_kalman.c @@ -40,9 +40,9 @@ static __pdata int32_t		ao_k_accel;  __pdata int16_t			ao_height;  __pdata int16_t			ao_speed;  __pdata int16_t			ao_accel; -__pdata int16_t			ao_max_height; +__xdata int16_t			ao_max_height;  static __pdata int32_t		ao_avg_height_scaled; -__pdata int16_t			ao_avg_height; +__xdata int16_t			ao_avg_height;  __pdata int16_t			ao_error_h;  __pdata int16_t			ao_error_h_sq_avg; diff --git a/src/core/ao_log_mini.c b/src/core/ao_log_mini.c index 1273b0e3..46b285f3 100644 --- a/src/core/ao_log_mini.c +++ b/src/core/ao_log_mini.c @@ -79,7 +79,6 @@ void  ao_log(void)  {  	__pdata uint16_t	next_sensor, next_other; -	uint8_t			i;  	ao_storage_setup(); diff --git a/src/core/ao_log_telem.c b/src/core/ao_log_telem.c index 23ebf7dd..095aca37 100644 --- a/src/core/ao_log_telem.c +++ b/src/core/ao_log_telem.c @@ -23,7 +23,7 @@ __code uint8_t ao_log_format = AO_LOG_FORMAT_TELEMETRY;  static __data uint8_t			ao_log_monitor_pos;  __pdata enum ao_flight_state		ao_flight_state; -__pdata int16_t				ao_max_height;	/* max of ao_height */ +__xdata int16_t				ao_max_height;	/* max of ao_height */  __pdata int16_t				sense_d, sense_m;  __pdata uint8_t				ao_igniter_present; diff --git a/src/core/ao_sample.h b/src/core/ao_sample.h index a2dac979..5bd29536 100644 --- a/src/core/ao_sample.h +++ b/src/core/ao_sample.h @@ -136,8 +136,8 @@ uint8_t ao_sample(void);  extern __pdata int16_t			ao_height;	/* meters */  extern __pdata int16_t			ao_speed;	/* m/s * 16 */  extern __pdata int16_t			ao_accel;	/* m/s² * 16 */ -extern __pdata int16_t			ao_max_height;	/* max of ao_height */ -extern __pdata int16_t			ao_avg_height;	/* running average of height */ +extern __xdata int16_t			ao_max_height;	/* max of ao_height */ +extern __xdata int16_t			ao_avg_height;	/* running average of height */  extern __pdata int16_t			ao_error_h;  extern __pdata int16_t			ao_error_h_sq_avg; diff --git a/src/core/ao_task.c b/src/core/ao_task.c index 4f48e32d..bafb4943 100644 --- a/src/core/ao_task.c +++ b/src/core/ao_task.c @@ -423,7 +423,7 @@ ao_sleep(__xdata void *wchan)  }  void -ao_wakeup(__xdata void *wchan) +ao_wakeup(__xdata void *wchan) __reentrant  {  #if HAS_TASK_QUEUE  	struct ao_task	*sleep, *next; diff --git a/src/core/ao_task.h b/src/core/ao_task.h index 1a4b5b6b..9c56b480 100644 --- a/src/core/ao_task.h +++ b/src/core/ao_task.h @@ -45,7 +45,10 @@ struct ao_task {  #endif  }; +#ifndef AO_NUM_TASKS  #define AO_NUM_TASKS		16	/* maximum number of tasks */ +#endif +  #define AO_NO_TASK		0	/* no task id */  extern __xdata struct ao_task * __xdata ao_tasks[AO_NUM_TASKS]; @@ -67,7 +70,7 @@ ao_sleep(__xdata void *wchan);  /* Wake all tasks sleeping on wchan */  void -ao_wakeup(__xdata void *wchan); +ao_wakeup(__xdata void *wchan) __reentrant;  /* set an alarm to go off in 'delay' ticks */  void diff --git a/src/core/ao_telemetry.c b/src/core/ao_telemetry.c index 65d7d08f..cd95aa6b 100644 --- a/src/core/ao_telemetry.c +++ b/src/core/ao_telemetry.c @@ -181,8 +181,7 @@ 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; @@ -213,7 +212,7 @@ ao_send_metrum_data(void)  		uint8_t	i;  		telemetry.generic.tick = packet->tick; -		telemetry.generic.type = AO_TELEMETRY_MEGA_DATA; +		telemetry.generic.type = AO_TELEMETRY_METRUM_DATA;  		telemetry.metrum_data.ground_pres = ao_ground_pres;  		telemetry.metrum_data.ground_accel = ao_ground_accel; @@ -224,7 +223,37 @@ ao_send_metrum_data(void)  		ao_telemetry_metrum_data_cur = ao_telemetry_metrum_data_max;  	}  } -#endif /* AO_SEND_MEGA */ +#endif /* AO_SEND_METRUM */ + +#ifdef AO_SEND_MINI + +static void +ao_send_mini(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_MINI; + +	telemetry.mini.state = ao_flight_state; + +	telemetry.mini.v_batt = packet->adc.v_batt; +	telemetry.mini.sense_a = packet->adc.sense_a; +	telemetry.mini.sense_m = packet->adc.sense_m; + +	telemetry.mini.pres = ao_data_pres(packet); +	telemetry.mini.temp = ao_data_temp(packet); + +	telemetry.mini.acceleration = ao_accel; +	telemetry.mini.speed = ao_speed; +	telemetry.mini.height = ao_height; + +	telemetry.mini.ground_pres = ao_ground_pres; + +	ao_radio_send(&telemetry, sizeof (telemetry)); +} + +#endif /* AO_SEND_MINI */  #ifdef AO_SEND_ALL_BARO  static uint8_t		ao_baro_sample; @@ -369,7 +398,6 @@ ao_telemetry(void)  		ao_aprs_time = time;  #endif  		while (ao_telemetry_interval) { -  #if HAS_APRS  			if (!(ao_config.radio_enable & AO_RADIO_DISABLE_TELEMETRY))  #endif @@ -377,19 +405,23 @@ ao_telemetry(void)  #ifdef AO_SEND_ALL_BARO  				ao_send_baro();  #endif +  #if HAS_FLIGHT -#ifdef AO_SEND_MEGA +# ifdef AO_SEND_MEGA  				ao_send_mega_sensor();  				ao_send_mega_data(); -#else -#ifdef AO_SEND_METRUM +# endif +# ifdef AO_SEND_METRUM  				ao_send_metrum_sensor();  				ao_send_metrum_data(); -#else +# endif +# ifdef AO_SEND_MINI +				ao_send_mini(); +# endif +# ifdef AO_TELEMETRY_SENSOR  				ao_send_sensor(); -#endif -#endif -#endif +# endif +#endif /* HAS_FLIGHT */  #if HAS_COMPANION  				if (ao_companion_running) @@ -406,18 +438,18 @@ ao_telemetry(void)  			if (ao_rdf &&  #if HAS_APRS  			    !(ao_config.radio_enable & AO_RADIO_DISABLE_RDF) && -#endif +#endif /* HAS_APRS */  			    (int16_t) (ao_time() - ao_rdf_time) >= 0)  			{  #if HAS_IGNITE_REPORT  				uint8_t	c; -#endif +#endif /* HAS_IGNITE_REPORT */  				ao_rdf_time = ao_time() + AO_RDF_INTERVAL_TICKS;  #if HAS_IGNITE_REPORT  				if (ao_flight_state == ao_flight_pad && (c = ao_report_igniter()))  					ao_radio_continuity(c);  				else -#endif +#endif /* HAS_IGNITE_REPORT*/  					ao_radio_rdf();  			}  #endif /* HAS_RDF */ @@ -428,8 +460,8 @@ ao_telemetry(void)  				ao_aprs_time = ao_time() + AO_SEC_TO_TICKS(ao_config.aprs_interval);  				ao_aprs_send();  			} -#endif -#endif +#endif /* HAS_APRS */ +#endif /* !AO_SEND_ALL_BARO */  			time += ao_telemetry_interval;  			delay = time - ao_time();  			if (delay > 0) { diff --git a/src/core/ao_telemetry.h b/src/core/ao_telemetry.h index 17dc3e93..fd6b76b3 100644 --- a/src/core/ao_telemetry.h +++ b/src/core/ao_telemetry.h @@ -248,6 +248,30 @@ struct ao_telemetry_metrum_data {  	/* 32 */  }; +#define AO_TELEMETRY_MINI		0x10 + +struct ao_telemetry_mini { +	uint16_t	serial;		/*  0 */ +	uint16_t	tick;		/*  2 */ +	uint8_t		type;		/*  4 */ + +	uint8_t         state;          /*  5 flight state */ +	int16_t		v_batt;		/*  6 battery voltage */ +	int16_t		sense_a;	/*  8 apogee continuity */ +	int16_t		sense_m;	/* 10 main continuity */ + +	int32_t		pres;		/* 12 Pa * 10 */ +	int16_t		temp;		/* 16 °C * 100 */ + +	int16_t         acceleration;   /* 18 m/s² * 16 */ +	int16_t         speed;          /* 20 m/s * 16 */ +	int16_t         height;         /* 22 m */ + +	int32_t		ground_pres;	/* 24 average pres on pad */ + +	int32_t		pad28;		/* 28 */ +	/* 32 */ +};  /* #define AO_SEND_ALL_BARO */ @@ -284,6 +308,7 @@ union ao_telemetry_all {  	struct ao_telemetry_mega_data		mega_data;  	struct ao_telemetry_metrum_sensor	metrum_sensor;  	struct ao_telemetry_metrum_data		metrum_data; +	struct ao_telemetry_mini		mini;  	struct ao_telemetry_baro		baro;  }; | 
