dba9a76aedcc344bc0b819f38405d86259690b34
[fw/altos] / src / drivers / ao_lco_cmd.c
1 /*
2  * Copyright © 2012 Keith Packard <keithp@keithp.com>
3  *
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; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License along
15  * with this program; if not, write to the Free Software Foundation, Inc.,
16  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
17  */
18
19 #include <ao.h>
20 #include <ao_pad.h>
21 #include <ao_lco_cmd.h>
22 #include <ao_lco_func.h>
23 #include <ao_radio_cmac.h>
24
25 #ifndef HAS_STATIC_TEST
26 #define HAS_STATIC_TEST 1
27 #endif
28
29 static __pdata uint16_t lco_box;
30 static __pdata uint8_t  lco_channels;
31 static __pdata uint16_t tick_offset;
32
33 static void
34 lco_args(void) __reentrant
35 {
36         ao_cmd_decimal();
37         lco_box = ao_cmd_lex_i;
38         ao_cmd_hex();
39         lco_channels = ao_cmd_lex_i;
40 }
41
42 static struct ao_pad_query      ao_pad_query;
43 static uint16_t                 tick_offset;
44
45 static int8_t
46 lco_query(void)
47 {
48         uint8_t i;
49         int8_t  r = AO_RADIO_CMAC_OK;
50
51         for (i = 0; i < 10; i++) {
52                 printf ("."); flush();
53                 r = ao_lco_query(lco_box, &ao_pad_query, &tick_offset);
54                 if (r == AO_RADIO_CMAC_OK)
55                         break;
56         }
57         printf("\n"); flush();
58         return r;
59 }
60
61 static void
62 lco_arm(void)
63 {
64         ao_lco_arm(lco_box, lco_channels, tick_offset);
65 }
66
67 static void
68 lco_ignite(uint8_t cmd)
69 {
70         ao_lco_ignite(cmd);
71 }
72
73 static void
74 lco_report_cmd(void) __reentrant
75 {
76         int8_t          r;
77         uint8_t         c;
78
79         lco_args();
80         if (ao_cmd_status != ao_cmd_success)
81                 return;
82         r = lco_query();
83         switch (r) {
84         case AO_RADIO_CMAC_OK:
85                 switch (ao_pad_query.arm_status) {
86                 case AO_PAD_ARM_STATUS_ARMED:
87                         printf ("Armed: ");
88                         break;
89                 case AO_PAD_ARM_STATUS_DISARMED:
90                         printf("Disarmed: ");
91                         break;
92                 case AO_PAD_ARM_STATUS_UNKNOWN:
93                 default:
94                         printf("Unknown: ");
95                         break;
96                 }
97                 for (c = 0; c < AO_PAD_MAX_CHANNELS; c++) {
98                         if (ao_pad_query.channels & (1 << c)) {
99                                 printf (" pad %d ", c);
100                                 switch (ao_pad_query.igniter_status[c]) {
101                                 default:
102                                         printf("unknown, ");
103                                         break;
104                                 case AO_PAD_IGNITER_STATUS_NO_IGNITER_RELAY_OPEN:
105                                         printf("bad-open, ");
106                                         break;
107                                 case AO_PAD_IGNITER_STATUS_GOOD_IGNITER_RELAY_OPEN:
108                                         printf("good-igniter, ");
109                                         break;
110                                 case AO_PAD_IGNITER_STATUS_NO_IGNITER_RELAY_CLOSED:
111                                         printf("bad-closed, ");
112                                         break;
113                                 }
114                         }
115                 }
116                 printf("Rssi: %d\n", ao_radio_cmac_rssi);
117                 break;
118         default:
119                 printf("Error %d\n", r);
120                 break;
121         }
122 }
123
124 static void
125 lco_fire_cmd(void) __reentrant
126 {
127         uint8_t         secs;
128         uint8_t         i;
129         int8_t          r;
130
131         lco_args();
132         ao_cmd_decimal();
133         secs = ao_cmd_lex_i;
134         if (ao_cmd_status != ao_cmd_success)
135                 return;
136         r = lco_query();
137         if (r != AO_RADIO_CMAC_OK) {
138                 printf("query failed %d\n", r);
139                 return;
140         }
141
142         for (i = 0; i < 4; i++) {
143                 printf("arm %d\n", i); flush();
144                 lco_arm();
145         }
146
147         secs = secs * 10 - 5;
148         if (secs > 100)
149                 secs = 100;
150         for (i = 0; i < secs; i++) {
151                 printf("fire %d\n", i); flush();
152                 lco_ignite(AO_PAD_FIRE);
153                 ao_delay(AO_MS_TO_TICKS(100));
154         }
155 }
156
157 #if HAS_STATIC_TEST
158 static void
159 lco_static_cmd(void) __reentrant
160 {
161         uint8_t         secs;
162         uint8_t         i;
163         int8_t          r;
164
165         lco_args();
166         ao_cmd_decimal();
167         secs = ao_cmd_lex_i;
168         if (ao_cmd_status != ao_cmd_success)
169                 return;
170         r = lco_query();
171         if (r != AO_RADIO_CMAC_OK) {
172                 printf("query failed %d\n", r);
173                 return;
174         }
175
176         for (i = 0; i < 4; i++) {
177                 printf("arm %d\n", i); flush();
178                 lco_arm();
179         }
180
181         secs = secs * 10 - 5;
182         if (secs > 100)
183                 secs = 100;
184         for (i = 0; i < secs; i++) {
185                 printf("fire %d\n", i); flush();
186                 lco_ignite(AO_PAD_STATIC);
187                 ao_delay(AO_MS_TO_TICKS(100));
188         }
189 }
190 #endif
191
192 static void
193 lco_arm_cmd(void) __reentrant
194 {
195         uint8_t i;
196         int8_t  r;
197         lco_args();
198         r = lco_query();
199         if (r != AO_RADIO_CMAC_OK) {
200                 printf("query failed %d\n", r);
201                 return;
202         }
203         for (i = 0; i < 4; i++)
204                 lco_arm();
205 }
206
207 static void
208 lco_ignite_cmd(void) __reentrant
209 {
210         uint8_t i;
211         lco_args();
212         for (i = 0; i < 4; i++)
213                 lco_ignite(AO_PAD_FIRE);
214 }
215
216
217 #if HAS_STATIC_TEST
218 static void
219 lco_endstatic_cmd(void) __reentrant
220 {
221         lco_ignite(AO_PAD_ENDSTATIC);
222 }
223 #endif
224
225 static __code struct ao_cmds ao_lco_cmds[] = {
226         { lco_report_cmd,       "l <box> <channel>\0Get remote status" },
227         { lco_fire_cmd,         "F <box> <channel> <secs>\0Fire remote igniters" },
228 #if HAS_STATIC_TEST
229         { lco_static_cmd,       "S <box> <channel> <secs>\0Initiate static test" },
230         { lco_endstatic_cmd,    "D\0End static test (and download someday)" },
231 #endif
232         { lco_arm_cmd,          "a <box> <channel>\0Arm remote igniter" },
233         { lco_ignite_cmd,       "i <box> <channel>\0Pulse remote igniter" },
234         { 0, NULL },
235 };
236
237 void
238 ao_lco_cmd_init(void)
239 {
240         ao_cmd_register(&ao_lco_cmds[0]);
241 }