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