Merge branch 'master' of ssh://git.gag.com/scm/git/fw/altos
[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 uint16_t lco_box;
30 static uint8_t  lco_channels;
31 static uint16_t tick_offset;
32
33 static void
34 lco_args(void) 
35 {
36         lco_box = ao_cmd_decimal();
37         lco_channels = ao_cmd_hex();
38 }
39
40 static struct ao_pad_query      ao_pad_query;
41 static uint16_t                 tick_offset;
42
43 static int8_t
44 lco_query(void)
45 {
46         uint8_t i;
47         int8_t  r = AO_RADIO_CMAC_OK;
48
49         for (i = 0; i < 10; i++) {
50                 printf ("."); flush();
51                 r = ao_lco_query(lco_box, &ao_pad_query, &tick_offset);
52                 if (r == AO_RADIO_CMAC_OK)
53                         break;
54         }
55         printf("\n"); flush();
56         return r;
57 }
58
59 static void
60 lco_arm(void)
61 {
62         ao_lco_arm(lco_box, lco_channels, tick_offset);
63 }
64
65 static void
66 lco_ignite(uint8_t cmd)
67 {
68         ao_lco_ignite(cmd);
69 }
70
71 static void
72 lco_report_cmd(void) 
73 {
74         int8_t          r;
75         uint8_t         c;
76
77         lco_args();
78         if (ao_cmd_status != ao_cmd_success)
79                 return;
80         r = lco_query();
81         switch (r) {
82         case AO_RADIO_CMAC_OK:
83                 switch (ao_pad_query.arm_status) {
84                 case AO_PAD_ARM_STATUS_ARMED:
85                         printf ("Armed: ");
86                         break;
87                 case AO_PAD_ARM_STATUS_DISARMED:
88                         printf("Disarmed: ");
89                         break;
90                 case AO_PAD_ARM_STATUS_UNKNOWN:
91                 default:
92                         printf("Unknown: ");
93                         break;
94                 }
95                 for (c = 0; c < AO_PAD_MAX_CHANNELS; c++) {
96                         if (ao_pad_query.channels & (1 << c)) {
97                                 printf (" pad %d ", c);
98                                 switch (ao_pad_query.igniter_status[c]) {
99                                 default:
100                                         printf("unknown, ");
101                                         break;
102                                 case AO_PAD_IGNITER_STATUS_NO_IGNITER_RELAY_OPEN:
103                                         printf("bad-open, ");
104                                         break;
105                                 case AO_PAD_IGNITER_STATUS_GOOD_IGNITER_RELAY_OPEN:
106                                         printf("good-igniter, ");
107                                         break;
108                                 case AO_PAD_IGNITER_STATUS_NO_IGNITER_RELAY_CLOSED:
109                                         printf("bad-closed, ");
110                                         break;
111                                 }
112                         }
113                 }
114                 printf("Rssi: %d\n", ao_radio_cmac_rssi);
115                 break;
116         default:
117                 printf("Error %d\n", r);
118                 break;
119         }
120 }
121
122 static void
123 lco_fire_cmd(void) 
124 {
125         uint8_t         secs;
126         uint8_t         i;
127         int8_t          r;
128
129         lco_args();
130         secs = ao_cmd_decimal();
131         if (ao_cmd_status != ao_cmd_success)
132                 return;
133         r = lco_query();
134         if (r != AO_RADIO_CMAC_OK) {
135                 printf("query failed %d\n", r);
136                 return;
137         }
138
139         for (i = 0; i < 4; i++) {
140                 printf("arm %d\n", i); flush();
141                 lco_arm();
142         }
143
144         secs = secs * 10 - 5;
145         if (secs > 100)
146                 secs = 100;
147         for (i = 0; i < secs; i++) {
148                 printf("fire %d\n", i); flush();
149                 lco_ignite(AO_PAD_FIRE);
150                 ao_delay(AO_MS_TO_TICKS(100));
151         }
152 }
153
154 #if HAS_STATIC_TEST
155 static void
156 lco_static_cmd(void) 
157 {
158         uint8_t         secs;
159         uint8_t         i;
160         int8_t          r;
161
162         lco_args();
163         secs = ao_cmd_decimal();
164         if (ao_cmd_status != ao_cmd_success)
165                 return;
166         r = lco_query();
167         if (r != AO_RADIO_CMAC_OK) {
168                 printf("query failed %d\n", r);
169                 return;
170         }
171
172         for (i = 0; i < 4; i++) {
173                 printf("arm %d\n", i); flush();
174                 lco_arm();
175         }
176
177         secs = secs * 10 - 5;
178         if (secs > 100)
179                 secs = 100;
180         for (i = 0; i < secs; i++) {
181                 printf("fire %d\n", i); flush();
182                 lco_ignite(AO_PAD_STATIC);
183                 ao_delay(AO_MS_TO_TICKS(100));
184         }
185 }
186 #endif
187
188 static void
189 lco_arm_cmd(void) 
190 {
191         uint8_t i;
192         int8_t  r;
193         lco_args();
194         r = lco_query();
195         if (r != AO_RADIO_CMAC_OK) {
196                 printf("query failed %d\n", r);
197                 return;
198         }
199         for (i = 0; i < 4; i++)
200                 lco_arm();
201 }
202
203 static void
204 lco_ignite_cmd(void) 
205 {
206         uint8_t i;
207         lco_args();
208         for (i = 0; i < 4; i++)
209                 lco_ignite(AO_PAD_FIRE);
210 }
211
212
213 #if HAS_STATIC_TEST
214 static void
215 lco_endstatic_cmd(void) 
216 {
217         lco_ignite(AO_PAD_ENDSTATIC);
218 }
219 #endif
220
221 static const struct ao_cmds ao_lco_cmds[] = {
222         { lco_report_cmd,       "l <box> <channel>\0Get remote status" },
223         { lco_fire_cmd,         "F <box> <channel> <secs>\0Fire remote igniters" },
224 #if HAS_STATIC_TEST
225         { lco_static_cmd,       "S <box> <channel> <secs>\0Initiate static test" },
226         { lco_endstatic_cmd,    "D\0End static test (and download someday)" },
227 #endif
228         { lco_arm_cmd,          "a <box> <channel>\0Arm remote igniter" },
229         { lco_ignite_cmd,       "i <box> <channel>\0Pulse remote igniter" },
230         { 0, NULL },
231 };
232
233 void
234 ao_lco_cmd_init(void)
235 {
236         ao_cmd_register(&ao_lco_cmds[0]);
237 }