summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2013-08-28 22:52:58 -0600
committerKeith Packard <keithp@keithp.com>2013-08-28 22:52:58 -0600
commitdcc51bb18985c24fa35bce0dd42ea3d847b960bf (patch)
tree652c06c900b01b3c43f674e0f121109cc54b1120 /src/core
parent7c82acc1c1c5b7b4da7c7ecb3b2fd90140e4c703 (diff)
parenta73b02518fcbc9fc0807ed8e141d3a06e8ad8214 (diff)
Merge remote-tracking branch 'origin/telemini'
Signed-off-by: Keith Packard <keithp@keithp.com> Conflicts: src/core/ao_telemetry.c src/core/ao_telemetry.h Added both Mini and Metrum telemetry defines
Diffstat (limited to 'src/core')
-rw-r--r--src/core/ao.h2
-rw-r--r--src/core/ao_cmd.c4
-rw-r--r--src/core/ao_data.c2
-rw-r--r--src/core/ao_data.h2
-rw-r--r--src/core/ao_int64.c158
-rw-r--r--src/core/ao_int64.h48
-rw-r--r--src/core/ao_kalman.c4
-rw-r--r--src/core/ao_log_mini.c1
-rw-r--r--src/core/ao_log_telem.c2
-rw-r--r--src/core/ao_sample.h4
-rw-r--r--src/core/ao_task.c2
-rw-r--r--src/core/ao_task.h5
-rw-r--r--src/core/ao_telemetry.c66
-rw-r--r--src/core/ao_telemetry.h25
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 = &ap;
+ ++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 = &ap;
+ 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;
};