*
* 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.
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
#include <ao.h>
#include <ao_lco.h>
#include <ao_event.h>
+#include <ao_button.h>
#include <ao_lco_func.h>
#include <ao_radio_cmac.h>
#define DEBUG_STATUS 2
#define PRINTD(l, ...) do { if (!(ao_lco_debug & l)) break; printf ("\r%5u %s: ", ao_tick_count, __func__); printf(__VA_ARGS__); flush(); } while(0)
#else
-#define PRINTD(l,...)
+#define PRINTD(l,...)
#endif
#define AO_LCO_VALID_LAST 1
#define AO_LCO_VALID_EVER 2
-static uint8_t ao_lco_selected;
+static uint8_t ao_lco_suspended;
static uint8_t ao_lco_valid;
static uint8_t ao_lco_channels;
static uint16_t ao_lco_tick_offset;
/* UI values */
static uint8_t ao_lco_armed;
static uint8_t ao_lco_firing;
-static uint8_t ao_lco_fire_down;
-
-#define ao_lco_box (ao_config.pad_box)
+static uint8_t ao_lco_box;
static struct ao_pad_query ao_pad_query;
-#define MASK_SIZE(n) (((n) + 7) >> 3)
-#define MASK_ID(n) ((n) >> 3)
-#define MASK_SHIFT(n) ((n) & 7)
+/* TeleFireTwo boxes have a single pad */
+#define ao_lco_pad 0
+
+static void
+ao_lco_set_box(int box)
+{
+ ao_lco_box = ao_config.pad_box + box;
+ ao_lco_valid = 0;
+ ao_lco_armed = 0;
+ ao_wakeup(&ao_lco_armed);
+}
static void
-ao_lco_set_armed(int pad, int armed)
+ao_lco_set_armed(int armed)
{
- uint8_t bit = (1 << pad);
+ uint8_t bit = (1 << ao_lco_pad);
if (armed) {
- ao_lco_selected |= bit;
- ao_lco_armed |= bit;
+ ao_lco_armed = bit;
} else {
- ao_lco_selected &= ~bit;
- ao_lco_armed &= ~bit;
+ ao_lco_armed = 0;
}
- PRINTD(DEBUG_EVENT, "pad %d bit 0x%x armed %d ao_lco_selected 0x%x ao_lco_armed 0x%x\n",
- pad, bit, armed, ao_lco_selected, ao_lco_armed);
+ PRINTD(DEBUG_EVENT, "pad %d bit 0x%x armed %d ao_lco_armed 0x%x\n",
+ ao_lco_pad, bit, armed, ao_lco_armed);
ao_wakeup(&ao_lco_armed);
}
+static void
+ao_lco_suspend(void)
+{
+ if (!ao_lco_suspended) {
+ PRINTD(DEBUG_EVENT, "suspend\n");
+ ao_lco_suspended = 1;
+ ao_lco_armed = 0;
+ ao_wakeup(&ao_pad_query);
+ }
+}
+
+static void
+ao_lco_wakeup(void)
+{
+ if (ao_lco_suspended) {
+ ao_lco_suspended = 0;
+ ao_wakeup(&ao_lco_suspended);
+ }
+}
+
static void
ao_lco_input(void)
{
static struct ao_event event;
+ uint8_t timeout;
for (;;) {
- ao_event_get(&event);
+ if (ao_config.pad_idle && !ao_lco_suspended) {
+ timeout = ao_event_get_for(&event, AO_SEC_TO_TICKS(ao_config.pad_idle));
+ if (timeout) {
+ ao_lco_suspend();
+ continue;
+ }
+ } else {
+ ao_event_get(&event);
+ }
+ ao_lco_wakeup();
PRINTD(DEBUG_EVENT, "event type %d unit %d value %d\n",
event.type, event.unit, event.value);
switch (event.type) {
case AO_EVENT_BUTTON:
switch (event.unit) {
- case AO_BUTTON_ARM_0:
- ao_lco_set_armed(0, event.value);
+ case AO_BUTTON_BOX:
+ ao_lco_set_box(event.value);
break;
-#if AO_BUTTON_ARM_NUM > 1
- case AO_BUTTON_ARM_1:
- ao_lco_set_armed(1, event.value);
+ case AO_BUTTON_ARM:
+ ao_lco_set_armed(event.value);
break;
-#endif
case AO_BUTTON_FIRE:
if (ao_lco_armed) {
- ao_lco_fire_down = 0;
ao_lco_firing = event.value;
PRINTD(DEBUG_EVENT, "Firing %d\n", ao_lco_firing);
ao_wakeup(&ao_lco_armed);
uint8_t t = 0;
for (;;) {
+ uint8_t all_status;
ao_sleep(&ao_pad_query);
- PRINTD(DEBUG_STATUS, "RSSI %d VALID %d\n", ao_radio_cmac_rssi, ao_lco_valid);
+ while (ao_lco_suspended) {
+ ao_led_off(AO_LED_GREEN|AO_LED_AMBER|AO_LED_RED|AO_LED_REMOTE_ARM);
+ for (c = 0; c < AO_LED_CONTINUITY_NUM; c++)
+ ao_led_off(continuity_led[c]);
+ ao_sleep(&ao_lco_suspended);
+ }
+ PRINTD(DEBUG_STATUS, "RSSI %d VALID %d channels %d arm_status %d\n",
+ ao_radio_cmac_rssi, ao_lco_valid,
+ ao_lco_channels, ao_pad_query.arm_status);
if (!(ao_lco_valid & AO_LCO_VALID_LAST)) {
ao_led_on(AO_LED_RED);
ao_led_off(AO_LED_GREEN|AO_LED_AMBER);
- continue;
- }
- if (ao_radio_cmac_rssi < -90) {
+ memset(&ao_pad_query, '\0', sizeof (ao_pad_query));
+ } else if (ao_radio_cmac_rssi < -90) {
ao_led_on(AO_LED_AMBER);
ao_led_off(AO_LED_RED|AO_LED_GREEN);
} else {
else
ao_led_off(AO_LED_REMOTE_ARM);
+ all_status = AO_PAD_IGNITER_STATUS_NO_IGNITER_RELAY_OPEN;
+ for (c = 0; c < 8; c++) {
+ if (ao_pad_query.channels & (1 << c)) {
+ uint8_t status = ao_pad_query.igniter_status[c];
+ if (status > all_status)
+ all_status = status;
+ PRINTD(DEBUG_STATUS, "\tchannel %d status %d\n", c, status);
+ }
+ }
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;
- PRINTD(DEBUG_STATUS, "\tchannel %d status %d\n", c, status);
- if (status == AO_PAD_IGNITER_STATUS_GOOD_IGNITER_RELAY_OPEN)
+ uint8_t on = 0;
+ if (c == (ao_lco_box - ao_config.pad_box) % AO_LED_CONTINUITY_NUM) {
+ switch (all_status) {
+ case AO_PAD_IGNITER_STATUS_GOOD_IGNITER_RELAY_OPEN:
+ on = 1;
+ break;
+ case AO_PAD_IGNITER_STATUS_NO_IGNITER_RELAY_CLOSED:
+ case AO_PAD_IGNITER_STATUS_UNKNOWN:
+ on = t & 1;
+ }
+ }
+ if (on)
ao_led_on(continuity_led[c]);
else
ao_led_off(continuity_led[c]);
{
int i;
for (;;) {
+ while (ao_lco_suspended)
+ ao_sleep(&ao_lco_suspended);
while (!ao_lco_armed)
ao_sleep(&ao_lco_armed);
for (i = 0; i < ao_lco_armed; i++) {
{
uint16_t delay;
+ ao_config_get();
+ ao_lco_set_box(ao_button_get(AO_BUTTON_BOX));
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_led_on(~0);
ao_beep_for(AO_BEEP_MID, AO_MS_TO_TICKS(200));
+ ao_led_off(~0);
for (;;) {
+ while (ao_lco_suspended)
+ ao_sleep(&ao_lco_suspended);
+
PRINTD(DEBUG_STATUS, "monitor armed %d firing %d\n",
ao_lco_armed, ao_lco_firing);
} else {
ao_lco_get_channels();
if (ao_lco_armed) {
- if (ao_lco_selected) {
- PRINTD(DEBUG_STATUS, "Arming pads %x\n",
- ao_lco_selected);
- if (ao_lco_valid & AO_LCO_VALID_EVER) {
- ao_lco_arm(ao_lco_box, ao_lco_selected, ao_lco_tick_offset);
- ao_delay(AO_MS_TO_TICKS(10));
- }
+ PRINTD(DEBUG_STATUS, "Arming pads %x\n",
+ ao_lco_armed);
+ if (ao_lco_valid & AO_LCO_VALID_EVER) {
+ ao_lco_arm(ao_lco_box, ao_lco_armed, ao_lco_tick_offset);
+ ao_delay(AO_MS_TO_TICKS(10));
}
}
}
if (ao_lco_armed && ao_lco_firing)
delay = AO_MS_TO_TICKS(100);
- else
+ else {
delay = AO_SEC_TO_TICKS(1);
+ }
ao_sleep_for(&ao_lco_armed, delay);
}
}