summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBdale Garbee <bdale@gag.com>2015-09-29 00:46:42 -0600
committerBdale Garbee <bdale@gag.com>2015-09-29 00:46:42 -0600
commit7064bc685aebeef07711e525dea4d5fbe33d235b (patch)
tree90b7c046fef47ecd2c68c1acafa042871435e24e
parentea1d24151cf76ae8f2368673317b66958e2508c4 (diff)
parentdda3f459eaff8d4e41cb44584c8ef77b8e2b3b1c (diff)
Merge branch 'master' of ssh://git.gag.com/scm/git/fw/altos
-rw-r--r--altoslib/AltosState.java5
-rw-r--r--altoslib/AltosTelemetryCompanion.java54
-rw-r--r--altoslib/AltosTelemetryStandard.java2
-rw-r--r--altoslib/Makefile.am1
-rw-r--r--ao-tools/ao-telem/ao-telem.c11
-rw-r--r--src/drivers/ao_companion.c4
-rw-r--r--src/drivers/ao_lco.c405
-rw-r--r--src/drivers/ao_lco_cmd.c2
-rw-r--r--src/drivers/ao_lco_func.c11
-rw-r--r--src/drivers/ao_lco_func.h2
-rw-r--r--src/drivers/ao_pad.c10
-rw-r--r--src/drivers/ao_seven_segment.c17
-rw-r--r--src/drivers/ao_seven_segment.h3
-rw-r--r--src/easymega-v1.0/ao_pins.h1
-rw-r--r--src/teleballoon-v2.0/ao_pins.h1
-rw-r--r--src/telemega-v0.1/ao_pins.h1
-rw-r--r--src/telemega-v1.0/ao_pins.h1
-rw-r--r--src/telemetrum-v2.0/ao_pins.h1
18 files changed, 433 insertions, 99 deletions
diff --git a/altoslib/AltosState.java b/altoslib/AltosState.java
index 4edae54a..cf4fb9b0 100644
--- a/altoslib/AltosState.java
+++ b/altoslib/AltosState.java
@@ -1358,11 +1358,6 @@ public class AltosState implements Cloneable, Serializable {
}
}
- public void make_companion (int nchannels) {
- if (companion == null)
- companion = new AltosCompanion(nchannels);
- }
-
public void set_companion(AltosCompanion companion) {
this.companion = companion;
}
diff --git a/altoslib/AltosTelemetryCompanion.java b/altoslib/AltosTelemetryCompanion.java
new file mode 100644
index 00000000..96125aca
--- /dev/null
+++ b/altoslib/AltosTelemetryCompanion.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright © 2015 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.
+ */
+
+package org.altusmetrum.altoslib_8;
+
+public class AltosTelemetryCompanion extends AltosTelemetryStandard {
+ AltosCompanion companion;
+
+ static final public int max_channels = 12;
+
+ public AltosTelemetryCompanion(int[] bytes) {
+ super(bytes);
+
+ int channels = uint8(7);
+
+ if (channels > max_channels)
+ channels = max_channels;
+
+ companion = new AltosCompanion(channels);
+
+ companion.tick = tick;
+ companion.board_id = uint8(5);
+ companion.update_period = uint8(6);
+
+ if (channels == 0)
+ companion.companion_data = null;
+ else {
+ companion.companion_data = new int[channels];
+
+ for (int i = 0; i < channels; i++)
+ companion.companion_data[i] = uint16(8 + i * 2);
+ }
+ }
+
+ public void update_state(AltosState state) {
+ super.update_state(state);
+
+ state.set_companion(companion);
+ }
+}
diff --git a/altoslib/AltosTelemetryStandard.java b/altoslib/AltosTelemetryStandard.java
index 27561826..c2a5ab3c 100644
--- a/altoslib/AltosTelemetryStandard.java
+++ b/altoslib/AltosTelemetryStandard.java
@@ -68,11 +68,9 @@ public abstract class AltosTelemetryStandard extends AltosTelemetry {
case packet_type_satellite:
telem = new AltosTelemetrySatellite(bytes);
break;
-/*
case packet_type_companion:
telem = new AltosTelemetryCompanion(bytes);
break;
-*/
case packet_type_mega_sensor:
telem = new AltosTelemetryMegaSensor(bytes);
break;
diff --git a/altoslib/Makefile.am b/altoslib/Makefile.am
index a6b178fa..d1f8f265 100644
--- a/altoslib/Makefile.am
+++ b/altoslib/Makefile.am
@@ -96,6 +96,7 @@ altoslib_JAVA = \
AltosStateUpdate.java \
AltosTelemetry.java \
AltosTelemetryConfiguration.java \
+ AltosTelemetryCompanion.java \
AltosTelemetryFile.java \
AltosTelemetryIterable.java \
AltosTelemetryLegacy.java \
diff --git a/ao-tools/ao-telem/ao-telem.c b/ao-tools/ao-telem/ao-telem.c
index da873838..05a69542 100644
--- a/ao-tools/ao-telem/ao-telem.c
+++ b/ao-tools/ao-telem/ao-telem.c
@@ -173,6 +173,15 @@ main (int argc, char **argv)
telem.mega_sensor.mag_y,
telem.mega_sensor.mag_z);
break;
+ case AO_TELEMETRY_COMPANION:
+ printf("board_id %3d update_period %3d channels %2d",
+ telem.companion.board_id,
+ telem.companion.update_period,
+ telem.companion.channels);
+ for (c = 0; c < telem.companion.channels; c++)
+ printf(" %6d", telem.companion.companion_data[c]);
+ printf("\n");
+ break;
case AO_TELEMETRY_MEGA_DATA:
printf ("state %1d v_batt %5d v_pyro %5d ",
telem.mega_data.state,
@@ -182,7 +191,7 @@ main (int argc, char **argv)
printf ("s%1d %5d ", c,
telem.mega_data.sense[c] |
(telem.mega_data.sense[c] << 8));
-
+
printf ("ground_pres %5d ground_accel %5d accel_plus %5d accel_minus %5d ",
telem.mega_data.ground_pres,
telem.mega_data.ground_accel,
diff --git a/src/drivers/ao_companion.c b/src/drivers/ao_companion.c
index 7e02939b..5f07e8b0 100644
--- a/src/drivers/ao_companion.c
+++ b/src/drivers/ao_companion.c
@@ -23,6 +23,10 @@
#define ao_spi_fast(b)
#endif
+#if !HAS_COMPANION
+#error HAS_COMPANION not set in ao_companion.c
+#endif
+
#define COMPANION_SELECT() do { \
ao_spi_get_bit(AO_COMPANION_CS_PORT, \
AO_COMPANION_CS_PIN, \
diff --git a/src/drivers/ao_lco.c b/src/drivers/ao_lco.c
index b8698a80..8180c49d 100644
--- a/src/drivers/ao_lco.c
+++ b/src/drivers/ao_lco.c
@@ -36,28 +36,42 @@ static uint8_t ao_lco_debug;
#define AO_LCO_BOX_DIGIT_1 1
#define AO_LCO_BOX_DIGIT_10 2
+#define AO_LCO_DRAG_RACE_START_TIME AO_SEC_TO_TICKS(5)
+#define AO_LCO_DRAG_RACE_STOP_TIME AO_SEC_TO_TICKS(2)
+
static uint8_t ao_lco_min_box, ao_lco_max_box;
-static uint8_t ao_lco_pad;
-static uint8_t ao_lco_box;
+static uint8_t ao_lco_selected[AO_PAD_MAX_BOXES];
+static uint8_t ao_lco_valid[AO_PAD_MAX_BOXES];
+static uint8_t ao_lco_channels[AO_PAD_MAX_BOXES];
+static uint16_t ao_lco_tick_offset[AO_PAD_MAX_BOXES];
+
+/* UI values */
static uint8_t ao_lco_armed;
static uint8_t ao_lco_firing;
-static uint8_t ao_lco_valid;
-static uint8_t ao_lco_got_channels;
-static uint16_t ao_lco_tick_offset;
-
+static uint16_t ao_lco_fire_tick;
+static uint8_t ao_lco_fire_down;
+static uint8_t ao_lco_drag_race;
+static uint8_t ao_lco_pad;
+static uint8_t ao_lco_box;
static struct ao_pad_query ao_pad_query;
+static uint8_t ao_lco_display_mutex;
+
static void
ao_lco_set_pad(uint8_t pad)
{
- ao_seven_segment_set(AO_LCO_PAD_DIGIT, pad);
+ ao_mutex_get(&ao_lco_display_mutex);
+ ao_seven_segment_set(AO_LCO_PAD_DIGIT, pad | (ao_lco_drag_race << 4));
+ ao_mutex_put(&ao_lco_display_mutex);
}
static void
ao_lco_set_box(uint8_t box)
{
- ao_seven_segment_set(AO_LCO_BOX_DIGIT_1, box % 10);
- ao_seven_segment_set(AO_LCO_BOX_DIGIT_10, box / 10);
+ ao_mutex_get(&ao_lco_display_mutex);
+ ao_seven_segment_set(AO_LCO_BOX_DIGIT_1, box % 10 | (ao_lco_drag_race << 4));
+ ao_seven_segment_set(AO_LCO_BOX_DIGIT_10, box / 10 | (ao_lco_drag_race << 4));
+ ao_mutex_put(&ao_lco_display_mutex);
}
static void
@@ -68,9 +82,11 @@ ao_lco_set_voltage(uint16_t decivolts)
tenths = decivolts % 10;
ones = (decivolts / 10) % 10;
tens = (decivolts / 100) % 10;
+ ao_mutex_get(&ao_lco_display_mutex);
ao_seven_segment_set(AO_LCO_PAD_DIGIT, tenths);
ao_seven_segment_set(AO_LCO_BOX_DIGIT_1, ones | 0x10);
ao_seven_segment_set(AO_LCO_BOX_DIGIT_10, tens);
+ ao_mutex_put(&ao_lco_display_mutex);
}
static void
@@ -84,6 +100,33 @@ ao_lco_set_display(void)
}
}
+#define SEVEN_SEGMENT_d ((0 << 0) | \
+ (0 << 1) | \
+ (1 << 2) | \
+ (1 << 3) | \
+ (1 << 4) | \
+ (1 << 5) | \
+ (1 << 6))
+
+
+#define SEVEN_SEGMENT_r ((0 << 0) | \
+ (0 << 1) | \
+ (0 << 2) | \
+ (1 << 3) | \
+ (1 << 4) | \
+ (0 << 5) | \
+ (0 << 6))
+
+static void
+ao_lco_set_display_drag(void)
+{
+ ao_mutex_get(&ao_lco_display_mutex);
+ ao_seven_segment_direct(AO_LCO_BOX_DIGIT_10, SEVEN_SEGMENT_d | 0x80);
+ ao_seven_segment_direct(AO_LCO_BOX_DIGIT_1, SEVEN_SEGMENT_r | 0x80);
+ ao_mutex_put(&ao_lco_display_mutex);
+ ao_lco_set_pad(ao_lco_pad);
+}
+
#define MASK_SIZE(n) (((n) + 7) >> 3)
#define MASK_ID(n) ((n) >> 3)
#define MASK_SHIFT(n) ((n) & 7)
@@ -99,29 +142,211 @@ ao_lco_box_present(uint8_t box)
}
static uint8_t
-ao_lco_pad_present(uint8_t pad)
+ao_lco_pad_present(uint8_t box, uint8_t pad)
{
- if (!ao_lco_got_channels || !ao_pad_query.channels)
- return pad == 0;
/* voltage measurement is always valid */
if (pad == 0)
return 1;
+ if (!ao_lco_channels[box])
+ return 0;
if (pad > AO_PAD_MAX_CHANNELS)
return 0;
- return (ao_pad_query.channels >> (pad - 1)) & 1;
+ return (ao_lco_channels[box] >> (pad - 1)) & 1;
}
static uint8_t
-ao_lco_pad_first(void)
+ao_lco_pad_first(uint8_t box)
{
uint8_t pad;
for (pad = 1; pad <= AO_PAD_MAX_CHANNELS; pad++)
- if (ao_lco_pad_present(pad))
+ if (ao_lco_pad_present(box, pad))
return pad;
return 0;
}
+static struct ao_task ao_lco_drag_task;
+static uint8_t ao_lco_drag_active;
+static uint8_t ao_lco_drag_beep_count;
+static uint8_t ao_lco_drag_beep_on;
+static uint16_t ao_lco_drag_beep_time;
+static uint16_t ao_lco_drag_warn_time;
+static uint16_t ao_lco_drag_display_time;
+static uint8_t ao_lco_drag_display_on;
+
+#define AO_LCO_DRAG_BEEP_TIME AO_MS_TO_TICKS(50)
+#define AO_LCO_DRAG_WARN_TIME AO_SEC_TO_TICKS(5)
+
+static void
+ao_lco_drag_beep_start(void)
+{
+ ao_beep(AO_BEEP_HIGH);
+ PRINTD("beep start\n");
+ ao_lco_drag_beep_on = 1;
+ ao_lco_drag_beep_time = ao_time() + AO_LCO_DRAG_BEEP_TIME;
+}
+
+static void
+ao_lco_drag_beep_stop(void)
+{
+ ao_beep(0);
+ PRINTD("beep stop\n");
+ ao_lco_drag_beep_on = 0;
+ if (ao_lco_drag_beep_count) {
+ --ao_lco_drag_beep_count;
+ if (ao_lco_drag_beep_count)
+ ao_lco_drag_beep_time = ao_time() + AO_LCO_DRAG_BEEP_TIME;
+ }
+}
+
+static void
+ao_lco_drag_beep(uint8_t beeps)
+{
+ PRINTD("beep %d\n", beeps);
+ if (!ao_lco_drag_beep_count)
+ ao_lco_drag_beep_start();
+ ao_lco_drag_beep_count += beeps;
+}
+
+static uint16_t
+ao_lco_drag_beep_check(uint16_t now, uint16_t delay)
+{
+ PRINTD("beep check count %d delta %d\n",
+ ao_lco_drag_beep_count,
+ (int16_t) (now - ao_lco_drag_beep_time));
+ if (ao_lco_drag_beep_count) {
+ if ((int16_t) (now - ao_lco_drag_beep_time) >= 0) {
+ if (ao_lco_drag_beep_on)
+ ao_lco_drag_beep_stop();
+ else
+ ao_lco_drag_beep_start();
+ }
+ }
+
+ if (ao_lco_drag_beep_count) {
+ if (delay > AO_LCO_DRAG_BEEP_TIME)
+ delay = AO_LCO_DRAG_BEEP_TIME;
+ }
+ return delay;
+}
+
+static void
+ao_lco_drag_enable(void)
+{
+ PRINTD("Drag enable\n");
+ ao_lco_drag_race = 1;
+ memset(ao_lco_selected, 0, sizeof (ao_lco_selected));
+ ao_lco_drag_beep(5);
+ ao_lco_set_display_drag();
+ ao_lco_fire_down = 0;
+ ao_lco_drag_display_on = 1;
+ ao_lco_drag_display_time = ao_time() + AO_SEC_TO_TICKS(5);
+}
+
+static void
+ao_lco_drag_disable(void)
+{
+ PRINTD("Drag disable\n");
+ ao_lco_drag_race = 0;
+ memset(ao_lco_selected, 0, sizeof (ao_lco_selected));
+ ao_lco_drag_beep(2);
+ ao_lco_set_display();
+ ao_lco_fire_down = 0;
+}
+
+static uint16_t
+ao_lco_drag_button_check(uint16_t now, uint16_t delay)
+{
+ uint16_t button_delay = ~0;
+
+ /*
+ * Check to see if the button has been held down long enough
+ * to switch in/out of drag race mode
+ */
+ if (ao_lco_fire_down) {
+ if (ao_lco_drag_race) {
+ if ((int16_t) (now - ao_lco_fire_tick) >= AO_LCO_DRAG_RACE_STOP_TIME)
+ ao_lco_drag_disable();
+ else
+ button_delay = ao_lco_fire_tick + AO_LCO_DRAG_RACE_STOP_TIME - now;
+ } else {
+ if ((int16_t) (now - ao_lco_fire_tick) >= AO_LCO_DRAG_RACE_START_TIME)
+ ao_lco_drag_enable();
+ else
+ button_delay = ao_lco_fire_tick + AO_LCO_DRAG_RACE_START_TIME - now;
+ }
+ if (delay > button_delay)
+ delay = button_delay;
+ }
+ return delay;
+}
+
+static uint16_t
+ao_lco_drag_warn_check(uint16_t now, uint16_t delay)
+{
+ uint16_t warn_delay = ~0;
+
+ if (ao_lco_drag_race) {
+ if ((int16_t) (now - ao_lco_drag_warn_time) >= 0) {
+ ao_lco_drag_beep(1);
+ ao_lco_drag_warn_time = now + AO_LCO_DRAG_WARN_TIME;
+ }
+ warn_delay = ao_lco_drag_warn_time - now;
+ }
+ if (delay > warn_delay)
+ delay = warn_delay;
+ return delay;
+}
+
+static uint16_t
+ao_lco_drag_display_check(uint16_t now, uint16_t delay)
+{
+ uint16_t display_delay;
+
+ if (ao_lco_drag_display_on) {
+ if ((int16_t) (now - ao_lco_drag_display_time) >= 0) {
+ ao_lco_drag_display_on = 0;
+ ao_lco_set_display();
+ } else {
+ display_delay = ao_lco_drag_display_time - now;
+ if (delay > display_delay)
+ delay = display_delay;
+ }
+ }
+ return delay;
+}
+
+static void
+ao_lco_drag_monitor(void)
+{
+ uint16_t delay = ~0;
+ uint16_t now;
+
+ for (;;) {
+ PRINTD("Drag monitor active %d delay %d\n", ao_lco_drag_active, delay);
+ if (delay == (uint16_t) ~0)
+ ao_sleep(&ao_lco_drag_active);
+ else
+ ao_sleep_for(&ao_lco_drag_active, delay);
+
+ delay = ~0;
+ if (!ao_lco_drag_active)
+ continue;
+
+ now = ao_time();
+ delay = ao_lco_drag_button_check(now, delay);
+ delay = ao_lco_drag_warn_check(now, delay);
+ delay = ao_lco_drag_beep_check(now, delay);
+ delay = ao_lco_drag_display_check(now, delay);
+
+ /* check to see if there's anything left to do here */
+ if (!ao_lco_fire_down && !ao_lco_drag_race && !ao_lco_drag_beep_count) {
+ delay = ~0;
+ ao_lco_drag_active = 0;
+ }
+ }
+}
+
static void
ao_lco_input(void)
{
@@ -148,7 +373,7 @@ ao_lco_input(void)
new_pad = AO_PAD_MAX_CHANNELS;
if (new_pad == ao_lco_pad)
break;
- } while (!ao_lco_pad_present(new_pad));
+ } while (!ao_lco_pad_present(ao_lco_box, new_pad));
if (new_pad != ao_lco_pad) {
ao_lco_pad = new_pad;
ao_lco_set_display();
@@ -171,7 +396,7 @@ ao_lco_input(void)
if (ao_lco_box != new_box) {
ao_lco_box = new_box;
ao_lco_pad = 1;
- ao_lco_got_channels = 0;
+ ao_lco_channels[ao_lco_box] = 0;
ao_lco_set_display();
}
}
@@ -183,13 +408,49 @@ ao_lco_input(void)
case AO_BUTTON_ARM:
ao_lco_armed = event.value;
PRINTD("Armed %d\n", ao_lco_armed);
+ if (ao_lco_armed) {
+ if (ao_lco_drag_race) {
+ uint8_t box;
+
+ for (box = ao_lco_min_box; box <= ao_lco_max_box; box++) {
+ if (ao_lco_selected[box]) {
+ ao_wakeup(&ao_lco_armed);
+ break;
+ }
+ }
+ } else if (ao_lco_pad != 0) {
+ memset(ao_lco_selected, 0, sizeof (ao_lco_selected));
+ ao_lco_selected[ao_lco_box] = (1 << (ao_lco_pad - 1));
+ }
+ }
ao_wakeup(&ao_lco_armed);
break;
case AO_BUTTON_FIRE:
if (ao_lco_armed) {
+ ao_lco_fire_down = 0;
ao_lco_firing = event.value;
PRINTD("Firing %d\n", ao_lco_firing);
ao_wakeup(&ao_lco_armed);
+ } else {
+ if (event.value) {
+ ao_lco_fire_down = 1;
+ ao_lco_fire_tick = ao_time();
+ ao_lco_drag_active = 1;
+ /* ao_lco_fire_down will already be off if we just enabled drag mode */
+ if (ao_lco_fire_down && ao_lco_drag_race) {
+ if (ao_lco_pad != 0) {
+ ao_lco_selected[ao_lco_box] ^= (1 << (ao_lco_pad - 1));
+ PRINTD("Toggle box %d pad %d (pads now %x) to drag race\n",
+ ao_lco_pad, ao_lco_box, ao_lco_selected[ao_lco_box]);
+ ao_lco_drag_beep(ao_lco_pad);
+ }
+ }
+ ao_wakeup(&ao_lco_drag_active);
+ } else {
+ ao_lco_fire_down = 0;
+ if (ao_lco_drag_active)
+ ao_wakeup(&ao_lco_drag_active);
+ }
}
break;
}
@@ -225,37 +486,36 @@ static AO_LED_TYPE continuity_led[AO_LED_CONTINUITY_NUM] = {
#endif
};
-static void
-ao_lco_update(void)
+static uint8_t
+ao_lco_get_channels(uint8_t box, struct ao_pad_query *query)
{
int8_t r;
- uint8_t c;
- r = ao_lco_query(ao_lco_box, &ao_pad_query, &ao_lco_tick_offset);
+ r = ao_lco_query(box, query, &ao_lco_tick_offset[box]);
if (r == AO_RADIO_CMAC_OK) {
- c = ao_lco_got_channels;
- ao_lco_got_channels = 1;
- ao_lco_valid = 1;
- if (!c) {
+ ao_lco_channels[box] = query->channels;
+ ao_lco_valid[box] = 1;
+ } else
+ ao_lco_valid[box] = 0;
+ PRINTD("ao_lco_get_channels(%d) rssi %d valid %d ret %d\n", box, ao_radio_cmac_rssi, ao_lco_valid[box], r);
+ ao_wakeup(&ao_pad_query);
+ return ao_lco_valid[box];
+}
+
+static void
+ao_lco_update(void)
+{
+ uint8_t previous_valid = ao_lco_valid[ao_lco_box];
+
+ if (ao_lco_get_channels(ao_lco_box, &ao_pad_query)) {
+ if (!previous_valid) {
if (ao_lco_pad != 0)
- ao_lco_pad = ao_lco_pad_first();
+ ao_lco_pad = ao_lco_pad_first(ao_lco_box);
ao_lco_set_display();
}
if (ao_lco_pad == 0)
ao_lco_set_display();
- } else
- ao_lco_valid = 0;
-
-#if 0
- PRINTD("lco_query success arm_status %d i0 %d i1 %d i2 %d i3 %d\n",
- query.arm_status,
- query.igniter_status[0],
- query.igniter_status[1],
- query.igniter_status[2],
- query.igniter_status[3]);
-#endif
- PRINTD("ao_lco_update valid %d\n", ao_lco_valid);
- ao_wakeup(&ao_pad_query);
+ }
}
static void
@@ -309,8 +569,8 @@ ao_lco_search(void)
ao_lco_box = ao_lco_min_box;
else
ao_lco_min_box = ao_lco_max_box = ao_lco_box = 0;
- ao_lco_valid = 0;
- ao_lco_got_channels = 0;
+ memset(ao_lco_valid, 0, sizeof (ao_lco_valid));
+ memset(ao_lco_channels, 0, sizeof (ao_lco_channels));
ao_lco_pad = 1;
ao_lco_set_display();
}
@@ -319,11 +579,12 @@ static void
ao_lco_igniter_status(void)
{
uint8_t c;
+ uint8_t t = 0;
for (;;) {
ao_sleep(&ao_pad_query);
- PRINTD("RSSI %d VALID %d\n", ao_radio_cmac_rssi, ao_lco_valid);
- if (!ao_lco_valid) {
+ PRINTD("RSSI %d VALID %d\n", ao_radio_cmac_rssi, ao_lco_valid[ao_lco_box]);
+ if (!ao_lco_valid[ao_lco_box]) {
ao_led_on(AO_LED_RED);
ao_led_off(AO_LED_GREEN|AO_LED_AMBER);
continue;
@@ -339,18 +600,27 @@ ao_lco_igniter_status(void)
ao_led_on(AO_LED_REMOTE_ARM);
else
ao_led_off(AO_LED_REMOTE_ARM);
+
for (c = 0; c < AO_LED_CONTINUITY_NUM; c++) {
uint8_t status;
- if (ao_pad_query.channels & (1 << c))
- status = ao_pad_query.igniter_status[c];
- else
- status = AO_PAD_IGNITER_STATUS_NO_IGNITER_RELAY_OPEN;
- if (status == AO_PAD_IGNITER_STATUS_GOOD_IGNITER_RELAY_OPEN)
- ao_led_on(continuity_led[c]);
- else
- ao_led_off(continuity_led[c]);
+ if (ao_lco_drag_race) {
+ if (ao_lco_selected[ao_lco_box] & (1 << c) && t)
+ ao_led_on(continuity_led[c]);
+ else
+ ao_led_off(continuity_led[c]);
+ } else {
+ if (ao_pad_query.channels & (1 << c))
+ status = ao_pad_query.igniter_status[c];
+ else
+ status = AO_PAD_IGNITER_STATUS_NO_IGNITER_RELAY_OPEN;
+ if (status == AO_PAD_IGNITER_STATUS_GOOD_IGNITER_RELAY_OPEN)
+ ao_led_on(continuity_led[c]);
+ else
+ ao_led_off(continuity_led[c]);
+ }
}
+ t = 1-t;
}
}
@@ -374,34 +644,31 @@ static void
ao_lco_monitor(void)
{
uint16_t delay;
+ uint8_t box;
ao_lco_search();
ao_add_task(&ao_lco_input_task, ao_lco_input, "lco input");
ao_add_task(&ao_lco_arm_warn_task, ao_lco_arm_warn, "lco arm warn");
ao_add_task(&ao_lco_igniter_status_task, ao_lco_igniter_status, "lco igniter status");
+ ao_add_task(&ao_lco_drag_task, ao_lco_drag_monitor, "drag race");
for (;;) {
- PRINTD("monitor armed %d firing %d offset %d\n",
- ao_lco_armed, ao_lco_firing, ao_lco_tick_offset);
+ PRINTD("monitor armed %d firing %d\n",
+ ao_lco_armed, ao_lco_firing);
if (ao_lco_armed && ao_lco_firing) {
- PRINTD("Firing box %d pad %d: valid %d\n",
- ao_lco_box, ao_lco_pad, ao_lco_valid);
- if (!ao_lco_valid)
- ao_lco_update();
- if (ao_lco_valid && ao_lco_pad)
- ao_lco_ignite(ao_lco_box, 1 << (ao_lco_pad - 1), ao_lco_tick_offset);
- } else if (ao_lco_armed) {
- PRINTD("Arming box %d pad %d\n",
- ao_lco_box, ao_lco_pad);
- if (!ao_lco_valid)
- ao_lco_update();
- if (ao_lco_pad) {
- ao_lco_arm(ao_lco_box, 1 << (ao_lco_pad - 1), ao_lco_tick_offset);
- ao_delay(AO_MS_TO_TICKS(30));
- ao_lco_update();
- }
+ ao_lco_ignite();
} else {
ao_lco_update();
+ if (ao_lco_armed) {
+ for (box = ao_lco_min_box; box <= ao_lco_max_box; box++) {
+ if (ao_lco_selected[box]) {
+ PRINTD("Arming box %d pads %x\n",
+ box, ao_lco_selected[box]);
+ if (ao_lco_valid[box])
+ ao_lco_arm(box, ao_lco_selected[box], ao_lco_tick_offset[ao_lco_box]);
+ }
+ }
+ }
}
if (ao_lco_armed && ao_lco_firing)
delay = AO_MS_TO_TICKS(100);
diff --git a/src/drivers/ao_lco_cmd.c b/src/drivers/ao_lco_cmd.c
index acbf589a..6a365687 100644
--- a/src/drivers/ao_lco_cmd.c
+++ b/src/drivers/ao_lco_cmd.c
@@ -62,7 +62,7 @@ lco_arm(void)
static void
lco_ignite(void)
{
- ao_lco_ignite(lco_box, lco_channels, tick_offset);
+ ao_lco_ignite();
}
static void
diff --git a/src/drivers/ao_lco_func.c b/src/drivers/ao_lco_func.c
index 32c00068..08d45467 100644
--- a/src/drivers/ao_lco_func.c
+++ b/src/drivers/ao_lco_func.c
@@ -44,7 +44,7 @@ ao_lco_query(uint16_t box, struct ao_pad_query *query, uint16_t *tick_offset)
}
#endif
ao_mutex_get(&ao_lco_mutex);
- command.tick = ao_time() - *tick_offset;
+ command.tick = ao_time();
command.box = box;
command.cmd = AO_LAUNCH_QUERY;
command.channels = 0;
@@ -70,14 +70,13 @@ ao_lco_arm(uint16_t box, uint8_t channels, uint16_t tick_offset)
}
void
-ao_lco_ignite(uint16_t box, uint8_t channels, uint16_t tick_offset)
+ao_lco_ignite(void)
{
ao_mutex_get(&ao_lco_mutex);
- command.tick = ao_time() - tick_offset;
- command.box = box;
+ command.tick = 0;
+ command.box = 0;
command.cmd = AO_LAUNCH_FIRE;
- command.channels = channels;
+ command.channels = 0;
ao_radio_cmac_send(&command, sizeof (command));
ao_mutex_put(&ao_lco_mutex);
}
-
diff --git a/src/drivers/ao_lco_func.h b/src/drivers/ao_lco_func.h
index dccf602a..42754352 100644
--- a/src/drivers/ao_lco_func.h
+++ b/src/drivers/ao_lco_func.h
@@ -27,6 +27,6 @@ void
ao_lco_arm(uint16_t box, uint8_t channels, uint16_t tick_offset);
void
-ao_lco_ignite(uint16_t box, uint8_t channels, uint16_t tick_offset);
+ao_lco_ignite(void);
#endif /* _AO_LCO_FUNC_H_ */
diff --git a/src/drivers/ao_pad.c b/src/drivers/ao_pad.c
index ffe46c68..419ea8d3 100644
--- a/src/drivers/ao_pad.c
+++ b/src/drivers/ao_pad.c
@@ -288,8 +288,7 @@ ao_pad(void)
PRINTD ("armed\n");
ao_pad_armed = command.channels;
ao_pad_arm_time = ao_time();
-
- /* fall through ... */
+ break;
case AO_LAUNCH_QUERY:
if (command.box != ao_pad_box) {
@@ -320,13 +319,6 @@ ao_pad(void)
ao_pad_arm_time, ao_time());
break;
}
- time_difference = command.tick - ao_time();
- if (time_difference < 0)
- time_difference = -time_difference;
- if (time_difference > 10) {
- PRINTD ("time different too large %d\n", time_difference);
- break;
- }
PRINTD ("ignite\n");
ao_pad_ignite = ao_pad_armed;
ao_pad_arm_time = ao_time();
diff --git a/src/drivers/ao_seven_segment.c b/src/drivers/ao_seven_segment.c
index 961fbb84..f1339ee5 100644
--- a/src/drivers/ao_seven_segment.c
+++ b/src/drivers/ao_seven_segment.c
@@ -168,10 +168,20 @@ static const uint8_t ao_segments[] = {
(0 << 6), /* F */
};
+
void
-ao_seven_segment_set(uint8_t digit, uint8_t value)
+ao_seven_segment_direct(uint8_t digit, uint8_t segments)
{
uint8_t s;
+
+ for (s = 0; s <= 7; s++)
+ ao_lcd_set(digit, s, !!(segments & (1 << s)));
+ ao_lcd_flush();
+}
+
+void
+ao_seven_segment_set(uint8_t digit, uint8_t value)
+{
uint8_t segments;
if (value == AO_SEVEN_SEGMENT_CLEAR)
@@ -183,10 +193,7 @@ ao_seven_segment_set(uint8_t digit, uint8_t value)
if (value & 0x10)
segments |= (1 << 7);
}
-
- for (s = 0; s <= 7; s++)
- ao_lcd_set(digit, s, !!(segments & (1 << s)));
- ao_lcd_flush();
+ ao_seven_segment_direct(digit, segments);
}
void
diff --git a/src/drivers/ao_seven_segment.h b/src/drivers/ao_seven_segment.h
index 5b29deaf..f997f3b5 100644
--- a/src/drivers/ao_seven_segment.h
+++ b/src/drivers/ao_seven_segment.h
@@ -23,6 +23,9 @@
#define AO_SEVEN_SEGMENT_CLEAR 0xff
void
+ao_seven_segment_direct(uint8_t digit, uint8_t segments);
+
+void
ao_seven_segment_set(uint8_t digit, uint8_t value);
void
diff --git a/src/easymega-v1.0/ao_pins.h b/src/easymega-v1.0/ao_pins.h
index d6490ba5..a5e55638 100644
--- a/src/easymega-v1.0/ao_pins.h
+++ b/src/easymega-v1.0/ao_pins.h
@@ -78,6 +78,7 @@
#define HAS_RADIO 0
#define HAS_TELEMETRY 0
#define HAS_APRS 0
+#define HAS_COMPANION 1
#define HAS_SPI_1 1
#define SPI_1_PA5_PA6_PA7 1 /* Barometer */
diff --git a/src/teleballoon-v2.0/ao_pins.h b/src/teleballoon-v2.0/ao_pins.h
index a369070f..b62b5580 100644
--- a/src/teleballoon-v2.0/ao_pins.h
+++ b/src/teleballoon-v2.0/ao_pins.h
@@ -75,6 +75,7 @@
#define HAS_RADIO 1
#define HAS_TELEMETRY 1
#define HAS_APRS 1
+#define HAS_COMPANION 1
#define HAS_SPI_1 1
#define SPI_1_PA5_PA6_PA7 1 /* Barometer */
diff --git a/src/telemega-v0.1/ao_pins.h b/src/telemega-v0.1/ao_pins.h
index 2616e906..7ccc6085 100644
--- a/src/telemega-v0.1/ao_pins.h
+++ b/src/telemega-v0.1/ao_pins.h
@@ -79,6 +79,7 @@
#define HAS_RADIO 1
#define HAS_TELEMETRY 1
#define HAS_APRS 1
+#define HAS_COMPANION 1
#define HAS_SPI_1 1
#define SPI_1_PA5_PA6_PA7 1 /* Barometer */
diff --git a/src/telemega-v1.0/ao_pins.h b/src/telemega-v1.0/ao_pins.h
index 77b753d1..664546c2 100644
--- a/src/telemega-v1.0/ao_pins.h
+++ b/src/telemega-v1.0/ao_pins.h
@@ -79,6 +79,7 @@
#define HAS_RADIO 1
#define HAS_TELEMETRY 1
#define HAS_APRS 1
+#define HAS_COMPANION 1
#define HAS_SPI_1 1
#define SPI_1_PA5_PA6_PA7 1 /* Barometer */
diff --git a/src/telemetrum-v2.0/ao_pins.h b/src/telemetrum-v2.0/ao_pins.h
index a9a4b243..fbb38df2 100644
--- a/src/telemetrum-v2.0/ao_pins.h
+++ b/src/telemetrum-v2.0/ao_pins.h
@@ -75,6 +75,7 @@
#define HAS_RADIO 1
#define HAS_TELEMETRY 1
#define HAS_APRS 1
+#define HAS_COMPANION 1
#define HAS_SPI_1 1
#define SPI_1_PA5_PA6_PA7 1 /* Barometer */