lock irq when retrieving time
[protos/xbee-avr.git] / commands_gen.c
1 /*
2  *  Copyright Droids Corporation (2011)
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,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *  GNU General Public License for more details.
13  *
14  *  You should have received a copy of the GNU General Public License
15  *  along with this program; if not, write to the Free Software
16  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17  *
18  *  Revision : $Id: commands_gen.c,v 1.8 2009-11-08 17:24:33 zer0 Exp $
19  *
20  *  Olivier MATZ <zer0@droids-corp.org>
21  */
22
23 #include <stdio.h>
24 #include <string.h>
25
26 #include <aversive/pgmspace.h>
27 #include <aversive/wait.h>
28 #include <aversive/error.h>
29 #include <aversive/queue.h>
30
31 #include <uart.h>
32
33 #include <rdline.h>
34 #include <parse.h>
35 #include <parse_string.h>
36 #include <parse_num.h>
37
38 #include <diagnostic.h>
39
40 #include "callout.h"
41 #include "main.h"
42 #include "cmdline.h"
43
44 /**********************************************************/
45 /* Reset */
46
47 /* this structure is filled when cmd_reset is parsed successfully */
48 struct cmd_reset_result {
49         fixed_string_t arg0;
50 };
51
52 /* function called when cmd_reset is parsed successfully */
53 static void cmd_reset_parsed(void * parsed_result, void * data)
54 {
55         (void)parsed_result;
56         (void)data;
57 #ifdef HOST_VERSION
58         hostsim_exit();
59 #endif
60         reset();
61 }
62
63 const char PROGMEM str_reset_arg0[] = "reset";
64 const parse_token_string_t PROGMEM cmd_reset_arg0 = TOKEN_STRING_INITIALIZER(struct cmd_reset_result, arg0, str_reset_arg0);
65
66 const char PROGMEM help_reset[] = "Reset the board";
67 const parse_inst_t PROGMEM cmd_reset = {
68         .f = cmd_reset_parsed,  /* function to call */
69         .data = NULL,      /* 2nd arg of func */
70         .help_str = help_reset,
71         .tokens = {        /* token list, NULL terminated */
72                 (PGM_P)&cmd_reset_arg0,
73                 NULL,
74         },
75 };
76
77 /**********************************************************/
78 /* Bootloader */
79
80 /* this structure is filled when cmd_bootloader is parsed successfully */
81 struct cmd_bootloader_result {
82         fixed_string_t arg0;
83 };
84
85 /* function called when cmd_bootloader is parsed successfully */
86 static void cmd_bootloader_parsed(void *parsed_result, void *data)
87 {
88         (void)parsed_result;
89         (void)data;
90 #ifndef HOST_VERSION
91         bootloader();
92 #else
93         printf("not implemented\n");
94 #endif
95 }
96
97 const char PROGMEM str_bootloader_arg0[] = "bootloader";
98 const parse_token_string_t PROGMEM cmd_bootloader_arg0 = TOKEN_STRING_INITIALIZER(struct cmd_bootloader_result, arg0, str_bootloader_arg0);
99
100 const char PROGMEM help_bootloader[] = "Launch the bootloader";
101 const parse_inst_t PROGMEM cmd_bootloader = {
102         .f = cmd_bootloader_parsed,  /* function to call */
103         .data = NULL,      /* 2nd arg of func */
104         .help_str = help_bootloader,
105         .tokens = {        /* token list, NULL terminated */
106                 (PGM_P)&cmd_bootloader_arg0,
107                 NULL,
108         },
109 };
110
111 /**********************************************************/
112 /* Callout show */
113
114 /* this structure is filled when cmd_callout is parsed successfully */
115 struct cmd_callout_result {
116         fixed_string_t arg0;
117         fixed_string_t arg1;
118 };
119
120 /* function called when cmd_callout is parsed successfully */
121 static void cmd_callout_parsed(void *parsed_result, void *data)
122 {
123         (void)parsed_result;
124         (void)data;
125         printf_P(PSTR("intr_cm:\n"));
126         callout_dump_stats(&xbeeboard.intr_cm);
127         printf_P(PSTR("mainloop_cm:\n"));
128         callout_dump_stats(&xbeeboard.mainloop_cm);
129 }
130
131 const char PROGMEM str_callout_arg0[] = "callout";
132 const parse_token_string_t PROGMEM cmd_callout_arg0 = TOKEN_STRING_INITIALIZER(struct cmd_callout_result, arg0, str_callout_arg0);
133 const char PROGMEM str_callout_arg1[] = "show";
134 const parse_token_string_t PROGMEM cmd_callout_arg1 = TOKEN_STRING_INITIALIZER(struct cmd_callout_result, arg1, str_callout_arg1);
135
136 const char PROGMEM help_callout[] = "Show callout events";
137 const parse_inst_t PROGMEM cmd_callout = {
138         .f = cmd_callout_parsed,  /* function to call */
139         .data = NULL,      /* 2nd arg of func */
140         .help_str = help_callout,
141         .tokens = {        /* token list, NULL terminated */
142                 (PGM_P)&cmd_callout_arg0,
143                 (PGM_P)&cmd_callout_arg1,
144                 NULL,
145         },
146 };
147
148 /**********************************************************/
149 /* Log */
150
151 /* this structure is filled when cmd_log is parsed successfully */
152 struct cmd_log_result {
153         fixed_string_t arg0;
154         fixed_string_t arg1;
155         uint8_t arg2;
156         fixed_string_t arg3;
157 };
158
159 /* keep it sync with string choice */
160 static const char PROGMEM uart_log[] = "uart";
161 static const char PROGMEM i2c_log[] = "i2c";
162 static const char PROGMEM default_log[] = "default";
163
164 struct log_name_and_num {
165         const char *name;
166         uint8_t num;
167 };
168
169 static const struct log_name_and_num log_name_and_num[] = {
170         { uart_log, E_UART },
171         { i2c_log, E_I2C },
172         { default_log, E_USER_DEFAULT },
173 };
174
175 static uint8_t
176 log_name2num(const char * s)
177 {
178         uint8_t i;
179
180         for (i=0; i<sizeof(log_name_and_num)/sizeof(struct log_name_and_num); i++) {
181                 if (!strcmp_P(s, log_name_and_num[i].name)) {
182                         return log_name_and_num[i].num;
183                 }
184         }
185         return 0;
186 }
187
188 const char *
189 log_num2name(uint8_t num)
190 {
191         uint8_t i;
192
193         for (i=0; i<sizeof(log_name_and_num)/sizeof(struct log_name_and_num); i++) {
194                 if (num ==  log_name_and_num[i].num) {
195                         return log_name_and_num[i].name;
196                 }
197         }
198         return NULL;
199 }
200
201 /* function called when cmd_log is parsed successfully */
202 static void cmd_log_do_show(void)
203 {
204         uint8_t i, empty=1;
205         const char *name;
206
207         printf_P(PSTR("log level is %d\r\n"), xbeeboard.log_level);
208         for (i=0; i<NB_LOGS; i++) {
209                 name = log_num2name(xbeeboard.logs[i]);
210                 if (name) {
211 #ifdef HOST_VERSION
212                         printf_P(PSTR("log type %s is on\r\n"), name);
213 #else
214                         printf_P(PSTR("log type %S is on\r\n"), name);
215 #endif
216                         empty = 0;
217                 }
218         }
219         if (empty)
220                 printf_P(PSTR("no log configured\r\n"));
221 }
222
223 /* function called when cmd_log is parsed successfully */
224 static void cmd_log_parsed(void * parsed_result, void *data)
225 {
226         struct cmd_log_result *res = (struct cmd_log_result *) parsed_result;
227
228         (void)data;
229         if (!strcmp_P(res->arg1, PSTR("level"))) {
230                 xbeeboard.log_level = res->arg2;
231         }
232
233         /* else it is a show */
234         cmd_log_do_show();
235 }
236
237 const char PROGMEM str_log_arg0[] = "log";
238 const parse_token_string_t PROGMEM cmd_log_arg0 = TOKEN_STRING_INITIALIZER(struct cmd_log_result, arg0, str_log_arg0);
239 const char PROGMEM str_log_arg1[] = "level";
240 const parse_token_string_t PROGMEM cmd_log_arg1 = TOKEN_STRING_INITIALIZER(struct cmd_log_result, arg1, str_log_arg1);
241 const parse_token_num_t PROGMEM cmd_log_arg2 = TOKEN_NUM_INITIALIZER(struct cmd_log_result, arg2, INT8);
242
243 const char PROGMEM help_log[] = "Set log options: level (0 -> 5)";
244 const parse_inst_t PROGMEM cmd_log = {
245         .f = cmd_log_parsed,  /* function to call */
246         .data = NULL,      /* 2nd arg of func */
247         .help_str = help_log,
248         .tokens = {        /* token list, NULL terminated */
249                 (PGM_P)&cmd_log_arg0,
250                 (PGM_P)&cmd_log_arg1,
251                 (PGM_P)&cmd_log_arg2,
252                 NULL,
253         },
254 };
255
256 const char PROGMEM str_log_arg1_show[] = "show";
257 const parse_token_string_t PROGMEM cmd_log_arg1_show = TOKEN_STRING_INITIALIZER(struct cmd_log_result, arg1, str_log_arg1_show);
258
259 const char PROGMEM help_log_show[] = "Show configured logs";
260 const parse_inst_t PROGMEM cmd_log_show = {
261         .f = cmd_log_parsed,  /* function to call */
262         .data = NULL,      /* 2nd arg of func */
263         .help_str = help_log_show,
264         .tokens = {        /* token list, NULL terminated */
265                 (PGM_P)&cmd_log_arg0,
266                 (PGM_P)&cmd_log_arg1_show,
267                 NULL,
268         },
269 };
270
271 /* this structure is filled when cmd_log is parsed successfully */
272 struct cmd_log_type_result {
273         fixed_string_t arg0;
274         fixed_string_t arg1;
275         fixed_string_t arg2;
276         fixed_string_t arg3;
277 };
278
279 /* function called when cmd_log is parsed successfully */
280 static void cmd_log_type_parsed(void * parsed_result, void *data)
281 {
282         struct cmd_log_type_result *res = (struct cmd_log_type_result *) parsed_result;
283         uint8_t lognum;
284         uint8_t i;
285
286         (void)data;
287
288         lognum = log_name2num(res->arg2);
289         if (lognum == 0) {
290                 printf_P(PSTR("Cannot find log num\r\n"));
291                 return;
292         }
293
294         if (!strcmp_P(res->arg3, PSTR("on"))) {
295                 for (i=0; i<NB_LOGS; i++) {
296                         if (xbeeboard.logs[i] == lognum) {
297                                 printf_P(PSTR("Already on\r\n"));
298                                 return;
299                         }
300                 }
301                 for (i=0; i<NB_LOGS; i++) {
302                         if (xbeeboard.logs[i] == 0) {
303                                 xbeeboard.logs[i] = lognum;
304                                 break;
305                         }
306                 }
307                 if (i==NB_LOGS) {
308                         printf_P(PSTR("no more room\r\n"));
309                 }
310         }
311         else if (!strcmp_P(res->arg3, PSTR("off"))) {
312                 for (i=0; i<NB_LOGS; i++) {
313                         if (xbeeboard.logs[i] == lognum) {
314                                 xbeeboard.logs[i] = 0;
315                                 break;
316                         }
317                 }
318                 if (i==NB_LOGS) {
319                         printf_P(PSTR("already off\r\n"));
320                 }
321         }
322         cmd_log_do_show();
323 }
324
325 const char PROGMEM str_log_arg1_type[] = "type";
326 const parse_token_string_t PROGMEM cmd_log_arg1_type = TOKEN_STRING_INITIALIZER(struct cmd_log_type_result, arg1, str_log_arg1_type);
327 /* keep it sync with log_name_and_num above */
328 const char PROGMEM str_log_arg2_type[] = "uart#rs#servo#traj#i2c#oa#strat#i2cproto#ext#sensor#bd#cs";
329 const parse_token_string_t PROGMEM cmd_log_arg2_type = TOKEN_STRING_INITIALIZER(struct cmd_log_type_result, arg2, str_log_arg2_type);
330 const char PROGMEM str_log_arg3[] = "on#off";
331 const parse_token_string_t PROGMEM cmd_log_arg3 = TOKEN_STRING_INITIALIZER(struct cmd_log_type_result, arg3, str_log_arg3);
332
333 const char PROGMEM help_log_type[] = "Set log type";
334 const parse_inst_t PROGMEM cmd_log_type = {
335         .f = cmd_log_type_parsed,  /* function to call */
336         .data = NULL,      /* 2nd arg of func */
337         .help_str = help_log_type,
338         .tokens = {        /* token list, NULL terminated */
339                 (PGM_P)&cmd_log_arg0,
340                 (PGM_P)&cmd_log_arg1_type,
341                 (PGM_P)&cmd_log_arg2_type,
342                 (PGM_P)&cmd_log_arg3,
343                 NULL,
344         },
345 };
346
347
348 /**********************************************************/
349 /* Stack_Space */
350
351 /* this structure is filled when cmd_stack_space is parsed successfully */
352 struct cmd_stack_space_result {
353         fixed_string_t arg0;
354 };
355
356 /* function called when cmd_stack_space is parsed successfully */
357 static void cmd_stack_space_parsed(void *parsed_result, void *data)
358 {
359         (void)parsed_result;
360         (void)data;
361 #ifdef HOST_VERSION
362         printf("not implemented\n");
363 #else
364         printf("res stack: %d\r\n", min_stack_space_available());
365 #endif
366 }
367
368 const char PROGMEM str_stack_space_arg0[] = "stack_space";
369 const parse_token_string_t PROGMEM cmd_stack_space_arg0 = TOKEN_STRING_INITIALIZER(struct cmd_stack_space_result, arg0, str_stack_space_arg0);
370
371 const char PROGMEM help_stack_space[] = "Display remaining stack space";
372 const parse_inst_t PROGMEM cmd_stack_space = {
373         .f = cmd_stack_space_parsed,  /* function to call */
374         .data = NULL,      /* 2nd arg of func */
375         .help_str = help_stack_space,
376         .tokens = {        /* token list, NULL terminated */
377                 (PGM_P)&cmd_stack_space_arg0,
378                 NULL,
379         },
380 };