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