altos: Use AO_TICK_TYPE/AO_TICK_SIGNED for lco/pad code
[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
32 static void
33 lco_args(void) 
34 {
35         lco_box = ao_cmd_decimal();
36         lco_channels = ao_cmd_hex();
37 }
38
39 static struct ao_pad_query      ao_pad_query;
40 static uint16_t                 tick_offset;
41
42 static int8_t
43 lco_query(void)
44 {
45         uint8_t i;
46         int8_t  r = AO_RADIO_CMAC_OK;
47
48         for (i = 0; i < 10; i++) {
49                 printf ("."); flush();
50                 r = ao_lco_query(lco_box, &ao_pad_query, &tick_offset);
51                 if (r == AO_RADIO_CMAC_OK)
52                         break;
53         }
54         printf("\n"); flush();
55         return r;
56 }
57
58 static void
59 lco_arm(void)
60 {
61         ao_lco_arm(lco_box, lco_channels, tick_offset);
62 }
63
64 static void
65 lco_ignite(uint8_t cmd)
66 {
67         ao_lco_ignite(cmd);
68 }
69
70 static void
71 lco_report_cmd(void) 
72 {
73         int8_t          r;
74         uint8_t         c;
75
76         lco_args();
77         if (ao_cmd_status != ao_cmd_success)
78                 return;
79         r = lco_query();
80         switch (r) {
81         case AO_RADIO_CMAC_OK:
82                 switch (ao_pad_query.arm_status) {
83                 case AO_PAD_ARM_STATUS_ARMED:
84                         printf ("Armed: ");
85                         break;
86                 case AO_PAD_ARM_STATUS_DISARMED:
87                         printf("Disarmed: ");
88                         break;
89                 case AO_PAD_ARM_STATUS_UNKNOWN:
90                 default:
91                         printf("Unknown: ");
92                         break;
93                 }
94                 for (c = 0; c < AO_PAD_MAX_CHANNELS; c++) {
95                         if (ao_pad_query.channels & (1 << c)) {
96                                 printf (" pad %d ", c);
97                                 switch (ao_pad_query.igniter_status[c]) {
98                                 default:
99                                         printf("unknown, ");
100                                         break;
101                                 case AO_PAD_IGNITER_STATUS_NO_IGNITER_RELAY_OPEN:
102                                         printf("bad-open, ");
103                                         break;
104                                 case AO_PAD_IGNITER_STATUS_GOOD_IGNITER_RELAY_OPEN:
105                                         printf("good-igniter, ");
106                                         break;
107                                 case AO_PAD_IGNITER_STATUS_NO_IGNITER_RELAY_CLOSED:
108                                         printf("bad-closed, ");
109                                         break;
110                                 }
111                         }
112                 }
113                 printf("Rssi: %d\n", ao_radio_cmac_rssi);
114                 break;
115         default:
116                 printf("Error %d\n", r);
117                 break;
118         }
119 }
120
121 static void
122 lco_fire_cmd(void) 
123 {
124         uint8_t         secs;
125         uint8_t         i;
126         int8_t          r;
127
128         lco_args();
129         secs = ao_cmd_decimal();
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 #if HAS_STATIC_TEST
154 static void
155 lco_static_cmd(void) 
156 {
157         uint8_t         secs;
158         uint8_t         i;
159         int8_t          r;
160
161         lco_args();
162         secs = ao_cmd_decimal();
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 #endif
186
187 static void
188 lco_arm_cmd(void) 
189 {
190         uint8_t i;
191         int8_t  r;
192         lco_args();
193         r = lco_query();
194         if (r != AO_RADIO_CMAC_OK) {
195                 printf("query failed %d\n", r);
196                 return;
197         }
198         for (i = 0; i < 4; i++)
199                 lco_arm();
200 }
201
202 static void
203 lco_ignite_cmd(void) 
204 {
205         uint8_t i;
206         lco_args();
207         for (i = 0; i < 4; i++)
208                 lco_ignite(AO_PAD_FIRE);
209 }
210
211
212 #if HAS_STATIC_TEST
213 static void
214 lco_endstatic_cmd(void) 
215 {
216         lco_ignite(AO_PAD_ENDSTATIC);
217 }
218 #endif
219
220 static const struct ao_cmds ao_lco_cmds[] = {
221         { lco_report_cmd,       "l <box> <channel>\0Get remote status" },
222         { lco_fire_cmd,         "F <box> <channel> <secs>\0Fire remote igniters" },
223 #if HAS_STATIC_TEST
224         { lco_static_cmd,       "S <box> <channel> <secs>\0Initiate static test" },
225         { lco_endstatic_cmd,    "D\0End static test (and download someday)" },
226 #endif
227         { lco_arm_cmd,          "a <box> <channel>\0Arm remote igniter" },
228         { lco_ignite_cmd,       "i <box> <channel>\0Pulse remote igniter" },
229         { 0, NULL },
230 };
231
232 void
233 ao_lco_cmd_init(void)
234 {
235         ao_cmd_register(&ao_lco_cmds[0]);
236 }