2 * Copyright © 2012 Keith Packard <keithp@keithp.com>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 2 of the License.
8 * This program is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * General Public License for more details.
13 * You should have received a copy of the GNU General Public License along
14 * with this program; if not, write to the Free Software Foundation, Inc.,
15 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
21 #include <ao_seven_segment.h>
22 #include <ao_quadrature.h>
23 #include <ao_lco_func.h>
24 #include <ao_radio_cmac.h>
27 #define PRINTD(...) do { printf ("\r%5u %s: ", ao_tick_count, __func__); printf(__VA_ARGS__); flush(); } while(0)
32 #define AO_LCO_PAD_DIGIT 0
33 #define AO_LCO_BOX_DIGIT_1 1
34 #define AO_LCO_BOX_DIGIT_10 2
38 static uint8_t ao_lco_mutex;
39 static uint8_t ao_lco_pad;
40 static uint8_t ao_lco_box;
41 static uint8_t ao_lco_armed;
42 static uint8_t ao_lco_firing;
43 static uint8_t ao_lco_valid;
48 ao_seven_segment_set(AO_LCO_PAD_DIGIT, ao_lco_pad);
54 ao_seven_segment_set(AO_LCO_BOX_DIGIT_1, ao_lco_box % 10);
55 ao_seven_segment_set(AO_LCO_BOX_DIGIT_10, ao_lco_box / 10);
61 static struct ao_event event;
67 PRINTD("event type %d unit %d value %d\n",
68 event.type, event.unit, event.value);
70 case AO_EVENT_QUADRATURE:
72 case AO_QUADRATURE_PAD:
74 ao_lco_pad = event.value & 3;
76 ao_quadrature_count[AO_QUADRATURE_PAD] = ao_lco_pad;
80 case AO_QUADRATURE_BOX:
82 ao_lco_box = event.value;
84 while (ao_lco_box >= AO_NUM_BOX)
85 ao_lco_box -= AO_NUM_BOX;
86 while (ao_lco_box < 0)
87 ao_lco_box += AO_NUM_BOX;
88 ao_quadrature_count[AO_QUADRATURE_PAD] = ao_lco_box;
97 ao_lco_armed = event.value;
98 PRINTD("Armed %d\n", ao_lco_armed);
99 ao_wakeup(&ao_lco_armed);
103 ao_lco_firing = event.value;
104 PRINTD("Firing %d\n", ao_lco_firing);
105 ao_wakeup(&ao_lco_armed);
114 static AO_LED_TYPE continuity_led[AO_LED_CONTINUITY_NUM] = {
115 #ifdef AO_LED_CONTINUITY_0
118 #ifdef AO_LED_CONTINUITY_1
121 #ifdef AO_LED_CONTINUITY_2
124 #ifdef AO_LED_CONTINUITY_3
127 #ifdef AO_LED_CONTINUITY_4
130 #ifdef AO_LED_CONTINUITY_5
133 #ifdef AO_LED_CONTINUITY_6
136 #ifdef AO_LED_CONTINUITY_7
141 static uint16_t ao_lco_tick_offset;
148 struct ao_pad_query query;
150 r = ao_lco_query(ao_lco_box, &query, &ao_lco_tick_offset);
151 if (r != AO_RADIO_CMAC_OK) {
152 PRINTD("lco_query return %d\n", r);
157 PRINTD("lco_query success arm_status %d i0 %d i1 %d i2 %d i3 %d\n",
159 query.igniter_status[0],
160 query.igniter_status[1],
161 query.igniter_status[2],
162 query.igniter_status[3]);
166 if (query.arm_status)
167 ao_led_on(AO_LED_REMOTE_ARM);
169 ao_led_off(AO_LED_REMOTE_ARM);
170 for (c = 0; c < AO_LED_CONTINUITY_NUM; c++) {
173 if (query.channels & (1 << c))
174 status = query.igniter_status[c];
176 status = AO_PAD_IGNITER_STATUS_NO_IGNITER_RELAY_OPEN;
177 if (status == AO_PAD_IGNITER_STATUS_GOOD_IGNITER_RELAY_OPEN)
178 ao_led_on(continuity_led[c]);
180 ao_led_off(continuity_led[c]);
190 if (ao_lco_armed && ao_lco_firing) {
191 PRINTD("Firing box %d pad %d: valid %d\n",
192 ao_lco_box, ao_lco_pad, ao_lco_valid);
196 ao_lco_ignite(ao_lco_box, ao_lco_pad, ao_lco_tick_offset);
200 if (ao_lco_armed && ao_lco_firing)
201 delay = AO_MS_TO_TICKS(100);
203 delay = AO_SEC_TO_TICKS(1);
205 ao_sleep(&ao_lco_armed);
211 ao_lco_arm_warn(void)
214 while (!ao_lco_armed)
215 ao_sleep(&ao_lco_armed);
216 ao_beep_for(AO_BEEP_MID, AO_MS_TO_TICKS(200));
217 ao_delay(AO_MS_TO_TICKS(200));
221 static struct ao_task ao_lco_input_task;
222 static struct ao_task ao_lco_monitor_task;
223 static struct ao_task ao_lco_arm_warn_task;
228 ao_add_task(&ao_lco_input_task, ao_lco_input, "lco input");
229 ao_add_task(&ao_lco_monitor_task, ao_lco_monitor, "lco monitor");
230 ao_add_task(&ao_lco_arm_warn_task, ao_lco_arm_warn, "lco arm warn");