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