X-Git-Url: https://git.gag.com/?p=fw%2Faltos;a=blobdiff_plain;f=src%2Fdrivers%2Fao_lco_two.c;h=e2f867454c5183e1f63cb30d212681093110c438;hp=0fd8e3626d45b8e709d0cc344f753937ca95d8a0;hb=d75351c5a07241bcbb951758796b4f639ace6b1f;hpb=4c2a7503373c0584de77f9b0e5632a58ab8bbd1f diff --git a/src/drivers/ao_lco_two.c b/src/drivers/ao_lco_two.c index 0fd8e362..e2f86745 100644 --- a/src/drivers/ao_lco_two.c +++ b/src/drivers/ao_lco_two.c @@ -3,7 +3,8 @@ * * 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 @@ -18,6 +19,7 @@ #include #include #include +#include #include #include @@ -29,13 +31,13 @@ static uint8_t ao_lco_debug; #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; @@ -43,56 +45,87 @@ 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); @@ -154,14 +187,22 @@ ao_lco_igniter_status(void) 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 { @@ -173,15 +214,28 @@ ao_lco_igniter_status(void) 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]); @@ -195,6 +249,8 @@ ao_lco_arm_warn(void) { 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++) { @@ -215,33 +271,39 @@ ao_lco_monitor(void) { 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); if (ao_lco_armed && ao_lco_firing) { - ao_lco_ignite(); + ao_lco_ignite(AO_PAD_FIRE); } 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); } }