9c35b3240e92e651dbbc51502046cc6e6a137274
[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; version 2 of the License.
7  *
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.
12  *
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.
16  */
17
18 #include <ao.h>
19 #include <ao_pad.h>
20 #include <ao_lco_cmd.h>
21 #include <ao_lco_func.h>
22 #include <ao_radio_cmac.h>
23
24 static __pdata uint16_t lco_box;
25 static __pdata uint8_t  lco_channels;
26 static __pdata uint16_t tick_offset;
27
28 static void
29 lco_args(void) __reentrant
30 {
31         ao_cmd_decimal();
32         lco_box = ao_cmd_lex_i;
33         ao_cmd_hex();
34         lco_channels = ao_cmd_lex_i;
35 }
36
37 static struct ao_pad_query      ao_pad_query;
38 static uint16_t                 tick_offset;
39
40 static int8_t
41 lco_query(void)
42 {
43         uint8_t i;
44         int8_t  r = AO_RADIO_CMAC_OK;
45
46         for (i = 0; i < 10; i++) {
47                 printf ("."); flush();
48                 r = ao_lco_query(lco_box, &ao_pad_query, &tick_offset);
49                 if (r == AO_RADIO_CMAC_OK)
50                         break;
51         }
52         printf("\n"); flush();
53         return r;
54 }
55
56 static void
57 lco_arm(void)
58 {
59         ao_lco_arm(lco_box, lco_channels, tick_offset);
60 }
61
62 static void
63 lco_ignite(void)
64 {
65         ao_lco_ignite(lco_box, lco_channels, tick_offset);
66 }
67
68 static void
69 lco_report_cmd(void) __reentrant
70 {
71         int8_t          r;
72         uint8_t         c;
73
74         lco_args();
75         if (ao_cmd_status != ao_cmd_success)
76                 return;
77         r = lco_query();
78         switch (r) {
79         case AO_RADIO_CMAC_OK:
80                 switch (ao_pad_query.arm_status) {
81                 case AO_PAD_ARM_STATUS_ARMED:
82                         printf ("Armed: ");
83                         break;
84                 case AO_PAD_ARM_STATUS_DISARMED:
85                         printf("Disarmed: ");
86                         break;
87                 case AO_PAD_ARM_STATUS_UNKNOWN:
88                 default:
89                         printf("Unknown: ");
90                         break;
91                 }
92                 for (c = 0; c < AO_PAD_MAX_CHANNELS; c++) {
93                         if (ao_pad_query.channels & (1 << c)) {
94                                 printf (" pad %d ", c);
95                                 switch (ao_pad_query.igniter_status[c]) {
96                                 default:
97                                         printf("unknown, ");
98                                         break;
99                                 case AO_PAD_IGNITER_STATUS_NO_IGNITER_RELAY_OPEN:
100                                         printf("bad-open, ");
101                                         break;
102                                 case AO_PAD_IGNITER_STATUS_GOOD_IGNITER_RELAY_OPEN:
103                                         printf("good-igniter, ");
104                                         break;
105                                 case AO_PAD_IGNITER_STATUS_NO_IGNITER_RELAY_CLOSED:
106                                         printf("bad-closed, ");
107                                         break;
108                                 }
109                         }
110                 }
111                 printf("Rssi: %d\n", ao_radio_cmac_rssi);
112                 break;
113         default:
114                 printf("Error %d\n", r);
115                 break;
116         }
117 }
118
119 static void
120 lco_fire_cmd(void) __reentrant
121 {
122         static __xdata struct ao_pad_command    command;
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();
149                 ao_delay(AO_MS_TO_TICKS(100));
150         }
151 }
152
153 static void
154 lco_arm_cmd(void) __reentrant
155 {
156         uint8_t i;
157         int8_t  r;
158         lco_args();
159         r = lco_query();
160         if (r != AO_RADIO_CMAC_OK) {
161                 printf("query failed %d\n", r);
162                 return;
163         }
164         for (i = 0; i < 4; i++)
165                 lco_arm();
166 }
167
168 static void
169 lco_ignite_cmd(void) __reentrant
170 {
171         uint8_t i;
172         lco_args();
173         for (i = 0; i < 4; i++)
174                 lco_ignite();
175 }
176
177 static __code struct ao_cmds ao_lco_cmds[] = {
178         { lco_report_cmd,       "l <box> <channel>\0Get remote status" },
179         { lco_fire_cmd,         "F <box> <channel> <secs>\0Fire remote igniters" },
180         { lco_arm_cmd,          "a <box> <channel>\0Arm remote igniter" },
181         { lco_ignite_cmd,       "i <box> <channel>\0Pulse remote igniter" },
182         { 0, NULL },
183 };
184
185 void
186 ao_lco_cmd_init(void)
187 {
188         ao_cmd_register(&ao_lco_cmds[0]);
189 }