altos: Move radio_cmac test funcs from ao_lco_cmd.c to new file
[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_lco_cmd.h>
20 #include <ao_radio_cmac.h>
21
22 static __xdata struct ao_launch_command command;
23 static __xdata struct ao_launch_query   query;
24 static __pdata uint16_t launch_serial;
25 static __pdata uint8_t  launch_channel;
26 static __pdata uint16_t tick_offset;
27
28 static void
29 launch_args(void) __reentrant
30 {
31         ao_cmd_decimal();
32         launch_serial = ao_cmd_lex_i;
33         ao_cmd_decimal();
34         launch_channel = ao_cmd_lex_i;
35 }
36
37 static int8_t
38 launch_query(void)
39 {
40         uint8_t i;
41         int8_t  r = AO_RADIO_CMAC_OK;
42
43         tick_offset = ao_time();
44         for (i = 0; i < 10; i++) {
45                 printf ("."); flush();
46                 command.tick = ao_time();
47                 command.serial = launch_serial;
48                 command.cmd = AO_LAUNCH_QUERY;
49                 command.channel = launch_channel;
50                 ao_radio_cmac_send(&command, sizeof (command));
51                 r = ao_radio_cmac_recv(&query, sizeof (query), AO_MS_TO_TICKS(500));
52                 if (r == AO_RADIO_CMAC_OK)
53                         break;
54         }
55         tick_offset -= query.tick;
56         printf("\n"); flush();
57         return r;
58 }
59
60 static void
61 launch_report_cmd(void) __reentrant
62 {
63         int8_t          r;
64
65         launch_args();
66         if (ao_cmd_status != ao_cmd_success)
67                 return;
68         r = launch_query();
69         switch (r) {
70         case AO_RADIO_CMAC_OK:
71                 if (query.valid) {
72                         switch (query.arm_status) {
73                         case ao_igniter_ready:
74                         case ao_igniter_active:
75                                 printf ("Armed: ");
76                                 break;
77                         default:
78                                 printf("Disarmed: ");
79                         }
80                         switch (query.igniter_status) {
81                         default:
82                                 printf("unknown\n");
83                                 break;
84                         case ao_igniter_ready:
85                                 printf("igniter good\n");
86                                 break;
87                         case ao_igniter_open:
88                                 printf("igniter bad\n");
89                                 break;
90                         }
91                 } else {
92                         printf("Invalid channel %d\n", launch_channel);
93                 }
94                 printf("Rssi: %d\n", ao_radio_cmac_rssi);
95                 break;
96         default:
97                 printf("Error %d\n", r);
98                 break;
99         }
100 }
101
102 static void
103 launch_arm(void) __reentrant
104 {
105         command.tick = ao_time() - tick_offset;
106         command.serial = launch_serial;
107         command.cmd = AO_LAUNCH_ARM;
108         command.channel = launch_channel;
109         ao_radio_cmac_send(&command, sizeof (command));
110 }
111
112 static void
113 launch_ignite(void) __reentrant
114 {
115         command.tick = ao_time() - tick_offset;
116         command.serial = launch_serial;
117         command.cmd = AO_LAUNCH_FIRE;
118         command.channel = 0;
119         ao_radio_cmac_send(&command, sizeof (command));
120 }
121
122 static void
123 launch_fire_cmd(void) __reentrant
124 {
125         static __xdata struct ao_launch_command command;
126         uint8_t         secs;
127         uint8_t         i;
128         int8_t          r;
129
130         launch_args();
131         ao_cmd_decimal();
132         secs = ao_cmd_lex_i;
133         if (ao_cmd_status != ao_cmd_success)
134                 return;
135         r = launch_query();
136         if (r != AO_RADIO_CMAC_OK) {
137                 printf("query failed %d\n", r);
138                 return;
139         }
140
141         for (i = 0; i < 4; i++) {
142                 printf("arm %d\n", i); flush();
143                 launch_arm();
144         }
145
146         secs = secs * 10 - 5;
147         if (secs > 100)
148                 secs = 100;
149         for (i = 0; i < secs; i++) {
150                 printf("fire %d\n", i); flush();
151                 launch_ignite();
152                 ao_delay(AO_MS_TO_TICKS(100));
153         }
154 }
155
156 static void
157 launch_arm_cmd(void) __reentrant
158 {
159         uint8_t i;
160         int8_t  r;
161         launch_args();
162         r = launch_query();
163         if (r != AO_RADIO_CMAC_OK) {
164                 printf("query failed %d\n", r);
165                 return;
166         }
167         for (i = 0; i < 4; i++)
168                 launch_arm();
169 }
170
171 static void
172 launch_ignite_cmd(void) __reentrant
173 {
174         uint8_t i;
175         launch_args();
176         for (i = 0; i < 4; i++)
177                 launch_ignite();
178 }
179
180 static __code struct ao_cmds ao_lco_cmds[] = {
181         { launch_report_cmd,    "l <serial> <channel>\0Get remote launch status" },
182         { launch_fire_cmd,      "f <serial> <channel> <secs>\0Fire remote igniter" },
183         { launch_arm_cmd,       "a <serial> <channel>\0Arm remote igniter" },
184         { launch_ignite_cmd,    "i <serial> <channel>\0Pulse remote igniter" },
185         { 0, NULL },
186 };
187
188 void
189 ao_lco_cmd_init(void)
190 {
191         ao_cmd_register(&ao_lco_cmds[0]);
192 }