2 * Copyright Droids Corporation (2008)
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.
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.
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
18 * Revision : $Id: commands_gen.c,v 1.5 2009-11-08 17:25:00 zer0 Exp $
20 * Olivier MATZ <zer0@droids-corp.org>
26 #include <aversive/pgmspace.h>
27 #include <aversive/wait.h>
28 #include <aversive/error.h>
33 #include <clock_time.h>
34 #include <encoders_spi.h>
37 #include <scheduler.h>
40 #include <control_system_manager.h>
41 #include <blocking_detection_manager.h>
45 #include <parse_string.h>
46 #include <parse_num.h>
48 #include <diagnostic.h>
54 /**********************************************************/
57 /* this structure is filled when cmd_reset is parsed successfully */
58 struct cmd_reset_result {
62 /* function called when cmd_reset is parsed successfully */
63 static void cmd_reset_parsed(__attribute__((unused)) void *parsed_result,
64 __attribute__((unused)) void *data)
69 prog_char str_reset_arg0[] = "reset";
70 parse_pgm_token_string_t cmd_reset_arg0 = TOKEN_STRING_INITIALIZER(struct cmd_reset_result, arg0, str_reset_arg0);
72 prog_char help_reset[] = "Reset the board";
73 parse_pgm_inst_t cmd_reset = {
74 .f = cmd_reset_parsed, /* function to call */
75 .data = NULL, /* 2nd arg of func */
76 .help_str = help_reset,
77 .tokens = { /* token list, NULL terminated */
78 (prog_void *)&cmd_reset_arg0,
83 /**********************************************************/
86 /* this structure is filled when cmd_bootloader is parsed successfully */
87 struct cmd_bootloader_result {
91 /* function called when cmd_bootloader is parsed successfully */
92 static void cmd_bootloader_parsed(__attribute__((unused)) void *parsed_result,
93 __attribute__((unused)) void *data)
98 prog_char str_bootloader_arg0[] = "bootloader";
99 parse_pgm_token_string_t cmd_bootloader_arg0 = TOKEN_STRING_INITIALIZER(struct cmd_bootloader_result, arg0, str_bootloader_arg0);
101 prog_char help_bootloader[] = "Launch the bootloader";
102 parse_pgm_inst_t cmd_bootloader = {
103 .f = cmd_bootloader_parsed, /* function to call */
104 .data = NULL, /* 2nd arg of func */
105 .help_str = help_bootloader,
106 .tokens = { /* token list, NULL terminated */
107 (prog_void *)&cmd_bootloader_arg0,
112 /**********************************************************/
115 /* this structure is filled when cmd_encoders is parsed successfully */
116 struct cmd_encoders_result {
121 /* function called when cmd_encoders is parsed successfully */
122 static void cmd_encoders_parsed(void *parsed_result, __attribute__((unused)) void *data)
124 struct cmd_encoders_result *res = parsed_result;
126 if (!strcmp_P(res->arg1, PSTR("reset"))) {
127 encoders_spi_set_value((void *)0, 0);
128 encoders_spi_set_value((void *)1, 0);
129 encoders_spi_set_value((void *)2, 0);
130 encoders_spi_set_value((void *)3, 0);
135 while(!cmdline_keypressed()) {
136 printf_P(PSTR("% .8ld % .8ld % .8ld % .8ld\r\n"),
137 encoders_spi_get_value((void *)0),
138 encoders_spi_get_value((void *)1),
139 encoders_spi_get_value((void *)2),
140 encoders_spi_get_value((void *)3));
145 prog_char str_encoders_arg0[] = "encoders";
146 parse_pgm_token_string_t cmd_encoders_arg0 = TOKEN_STRING_INITIALIZER(struct cmd_encoders_result, arg0, str_encoders_arg0);
147 prog_char str_encoders_arg1[] = "show#reset";
148 parse_pgm_token_string_t cmd_encoders_arg1 = TOKEN_STRING_INITIALIZER(struct cmd_encoders_result, arg1, str_encoders_arg1);
150 prog_char help_encoders[] = "Show encoders values";
151 parse_pgm_inst_t cmd_encoders = {
152 .f = cmd_encoders_parsed, /* function to call */
153 .data = NULL, /* 2nd arg of func */
154 .help_str = help_encoders,
155 .tokens = { /* token list, NULL terminated */
156 (prog_void *)&cmd_encoders_arg0,
157 (prog_void *)&cmd_encoders_arg1,
162 /**********************************************************/
165 /* this structure is filled when cmd_scheduler is parsed successfully */
166 struct cmd_scheduler_result {
171 /* function called when cmd_scheduler is parsed successfully */
172 static void cmd_scheduler_parsed( __attribute__((unused)) void *parsed_result,
173 __attribute__((unused)) void *data)
175 scheduler_dump_events();
178 prog_char str_scheduler_arg0[] = "scheduler";
179 parse_pgm_token_string_t cmd_scheduler_arg0 = TOKEN_STRING_INITIALIZER(struct cmd_scheduler_result, arg0, str_scheduler_arg0);
180 prog_char str_scheduler_arg1[] = "show";
181 parse_pgm_token_string_t cmd_scheduler_arg1 = TOKEN_STRING_INITIALIZER(struct cmd_scheduler_result, arg1, str_scheduler_arg1);
183 prog_char help_scheduler[] = "Show scheduler events";
184 parse_pgm_inst_t cmd_scheduler = {
185 .f = cmd_scheduler_parsed, /* function to call */
186 .data = NULL, /* 2nd arg of func */
187 .help_str = help_scheduler,
188 .tokens = { /* token list, NULL terminated */
189 (prog_void *)&cmd_scheduler_arg0,
190 (prog_void *)&cmd_scheduler_arg1,
195 /**********************************************************/
198 /* this structure is filled when cmd_pwm is parsed successfully */
199 struct cmd_pwm_result {
205 /* function called when cmd_pwm is parsed successfully */
206 static void cmd_pwm_parsed(void * parsed_result, __attribute__((unused)) void *data)
208 void * pwm_ptr = NULL;
209 struct cmd_pwm_result * res = parsed_result;
211 if (!strcmp_P(res->arg1, PSTR("1(4A)")))
212 pwm_ptr = &gen.pwm1_4A;
213 else if (!strcmp_P(res->arg1, PSTR("2(4B)")))
214 pwm_ptr = &gen.pwm2_4B;
215 else if (!strcmp_P(res->arg1, PSTR("3(1A)")))
216 pwm_ptr = &gen.pwm3_1A;
217 else if (!strcmp_P(res->arg1, PSTR("4(1B)")))
218 pwm_ptr = &gen.pwm4_1B;
220 else if (!strcmp_P(res->arg1, PSTR("s1(3C)")))
221 pwm_ptr = &gen.servo1;
222 else if (!strcmp_P(res->arg1, PSTR("s2(5A)")))
223 pwm_ptr = &gen.servo2;
224 else if (!strcmp_P(res->arg1, PSTR("s3(5B)")))
225 pwm_ptr = &gen.servo3;
226 else if (!strcmp_P(res->arg1, PSTR("s3(5C)")))
227 pwm_ptr = &gen.servo4;
230 pwm_ng_set(pwm_ptr, res->arg2);
232 printf_P(PSTR("done\r\n"));
235 prog_char str_pwm_arg0[] = "pwm";
236 parse_pgm_token_string_t cmd_pwm_arg0 = TOKEN_STRING_INITIALIZER(struct cmd_pwm_result, arg0, str_pwm_arg0);
237 prog_char str_pwm_arg1[] = "1(4A)#2(4B)#3(1A)#4(1B)#s1(3C)#s2(5A)#s3(5B)#s4(5C)";
238 parse_pgm_token_string_t cmd_pwm_arg1 = TOKEN_STRING_INITIALIZER(struct cmd_pwm_result, arg1, str_pwm_arg1);
239 parse_pgm_token_num_t cmd_pwm_arg2 = TOKEN_NUM_INITIALIZER(struct cmd_pwm_result, arg2, INT16);
241 prog_char help_pwm[] = "Set pwm values [-4096 ; 4095]";
242 parse_pgm_inst_t cmd_pwm = {
243 .f = cmd_pwm_parsed, /* function to call */
244 .data = NULL, /* 2nd arg of func */
245 .help_str = help_pwm,
246 .tokens = { /* token list, NULL terminated */
247 (prog_void *)&cmd_pwm_arg0,
248 (prog_void *)&cmd_pwm_arg1,
249 (prog_void *)&cmd_pwm_arg2,
254 /**********************************************************/
257 /* this structure is filled when cmd_adc is parsed successfully */
258 struct cmd_adc_result {
263 /* function called when cmd_adc is parsed successfully */
264 static void cmd_adc_parsed(void *parsed_result, __attribute__((unused)) void *data)
266 struct cmd_adc_result *res = parsed_result;
269 if (!strcmp_P(res->arg1, PSTR("loop_show")))
273 printf_P(PSTR("ADC values: "));
274 for (i=0; i<ADC_MAX; i++) {
275 printf_P(PSTR("%.4d "), sensor_get_adc(i));
277 printf_P(PSTR("\r\n"));
279 } while (loop && !cmdline_keypressed());
282 prog_char str_adc_arg0[] = "adc";
283 parse_pgm_token_string_t cmd_adc_arg0 = TOKEN_STRING_INITIALIZER(struct cmd_adc_result, arg0, str_adc_arg0);
284 prog_char str_adc_arg1[] = "show#loop_show";
285 parse_pgm_token_string_t cmd_adc_arg1 = TOKEN_STRING_INITIALIZER(struct cmd_adc_result, arg1, str_adc_arg1);
287 prog_char help_adc[] = "Show adc values";
288 parse_pgm_inst_t cmd_adc = {
289 .f = cmd_adc_parsed, /* function to call */
290 .data = NULL, /* 2nd arg of func */
291 .help_str = help_adc,
292 .tokens = { /* token list, NULL terminated */
293 (prog_void *)&cmd_adc_arg0,
294 (prog_void *)&cmd_adc_arg1,
300 /**********************************************************/
303 /* this structure is filled when cmd_sensor is parsed successfully */
304 struct cmd_sensor_result {
309 /* function called when cmd_sensor is parsed successfully */
310 static void cmd_sensor_parsed(void *parsed_result, __attribute__((unused)) void *data)
312 struct cmd_sensor_result *res = parsed_result;
315 if (!strcmp_P(res->arg1, PSTR("loop_show")))
319 printf_P(PSTR("SENSOR values: "));
320 for (i=0; i<SENSOR_MAX; i++) {
321 printf_P(PSTR("%d "), !!sensor_get(i));
323 printf_P(PSTR("\r\n"));
325 } while (loop && !cmdline_keypressed());
328 prog_char str_sensor_arg0[] = "sensor";
329 parse_pgm_token_string_t cmd_sensor_arg0 = TOKEN_STRING_INITIALIZER(struct cmd_sensor_result, arg0, str_sensor_arg0);
330 prog_char str_sensor_arg1[] = "show#loop_show";
331 parse_pgm_token_string_t cmd_sensor_arg1 = TOKEN_STRING_INITIALIZER(struct cmd_sensor_result, arg1, str_sensor_arg1);
333 prog_char help_sensor[] = "Show sensor values";
334 parse_pgm_inst_t cmd_sensor = {
335 .f = cmd_sensor_parsed, /* function to call */
336 .data = NULL, /* 2nd arg of func */
337 .help_str = help_sensor,
338 .tokens = { /* token list, NULL terminated */
339 (prog_void *)&cmd_sensor_arg0,
340 (prog_void *)&cmd_sensor_arg1,
346 /**********************************************************/
349 /* this structure is filled when cmd_log is parsed successfully */
350 struct cmd_log_result {
357 /* keep it sync with string choice */
358 static const prog_char uart_log[] = "uart";
359 static const prog_char i2c_log[] = "i2c";
360 static const prog_char i2cproto_log[] = "i2cproto";
361 static const prog_char sensor_log[] = "sensor";
362 static const prog_char block_log[] = "bd";
363 static const prog_char state_log[] = "state";
364 static const prog_char ax12_log[] = "ax12";
366 struct log_name_and_num {
367 const prog_char * name;
371 static const struct log_name_and_num log_name_and_num[] = {
372 { uart_log, E_UART },
374 { i2cproto_log, E_USER_I2C_PROTO },
375 { sensor_log, E_USER_SENSOR },
376 { block_log, E_BLOCKING_DETECTION_MANAGER },
377 { state_log, E_USER_ST_MACH },
378 { ax12_log, E_USER_AX12 },
382 log_name2num(const char * s)
386 for (i=0; i<sizeof(log_name_and_num)/sizeof(struct log_name_and_num); i++) {
387 if (!strcmp_P(s, log_name_and_num[i].name)) {
388 return log_name_and_num[i].num;
395 log_num2name(uint8_t num)
399 for (i=0; i<sizeof(log_name_and_num)/sizeof(struct log_name_and_num); i++) {
400 if (num == log_name_and_num[i].num) {
401 return log_name_and_num[i].name;
407 /* function called when cmd_log is parsed successfully */
408 static void cmd_log_do_show(void)
411 const prog_char * name;
413 printf_P(PSTR("log level is %d\r\n"), gen.log_level);
414 for (i=0; i<NB_LOGS; i++) {
415 name = log_num2name(gen.logs[i]);
417 printf_P(PSTR("log type %S is on\r\n"), name);
422 printf_P(PSTR("no log configured\r\n"), gen.logs[i]);
425 /* function called when cmd_log is parsed successfully */
426 static void cmd_log_parsed(void * parsed_result, __attribute__((unused)) void *data)
428 struct cmd_log_result *res = (struct cmd_log_result *) parsed_result;
430 if (!strcmp_P(res->arg1, PSTR("level"))) {
431 gen.log_level = res->arg2;
434 /* else it is a show */
438 prog_char str_log_arg0[] = "log";
439 parse_pgm_token_string_t cmd_log_arg0 = TOKEN_STRING_INITIALIZER(struct cmd_log_result, arg0, str_log_arg0);
440 prog_char str_log_arg1[] = "level";
441 parse_pgm_token_string_t cmd_log_arg1 = TOKEN_STRING_INITIALIZER(struct cmd_log_result, arg1, str_log_arg1);
442 parse_pgm_token_num_t cmd_log_arg2 = TOKEN_NUM_INITIALIZER(struct cmd_log_result, arg2, INT32);
444 prog_char help_log[] = "Set log options: level (0 -> 5)";
445 parse_pgm_inst_t cmd_log = {
446 .f = cmd_log_parsed, /* function to call */
447 .data = NULL, /* 2nd arg of func */
448 .help_str = help_log,
449 .tokens = { /* token list, NULL terminated */
450 (prog_void *)&cmd_log_arg0,
451 (prog_void *)&cmd_log_arg1,
452 (prog_void *)&cmd_log_arg2,
457 prog_char str_log_arg1_show[] = "show";
458 parse_pgm_token_string_t cmd_log_arg1_show = TOKEN_STRING_INITIALIZER(struct cmd_log_result, arg1, str_log_arg1_show);
460 prog_char help_log_show[] = "Show configured logs";
461 parse_pgm_inst_t cmd_log_show = {
462 .f = cmd_log_parsed, /* function to call */
463 .data = NULL, /* 2nd arg of func */
464 .help_str = help_log_show,
465 .tokens = { /* token list, NULL terminated */
466 (prog_void *)&cmd_log_arg0,
467 (prog_void *)&cmd_log_arg1_show,
472 /* this structure is filled when cmd_log is parsed successfully */
473 struct cmd_log_type_result {
480 /* function called when cmd_log is parsed successfully */
481 static void cmd_log_type_parsed(void * parsed_result, __attribute__((unused)) void *data)
483 struct cmd_log_type_result *res = (struct cmd_log_type_result *) parsed_result;
487 lognum = log_name2num(res->arg2);
489 printf_P(PSTR("Cannot find log num\r\n"));
493 if (!strcmp_P(res->arg3, PSTR("on"))) {
494 for (i=0; i<NB_LOGS; i++) {
495 if (gen.logs[i] == lognum) {
496 printf_P(PSTR("Already on\r\n"));
500 for (i=0; i<NB_LOGS; i++) {
501 if (gen.logs[i] == 0) {
502 gen.logs[i] = lognum;
507 printf_P(PSTR("no more room\r\n"));
510 else if (!strcmp_P(res->arg3, PSTR("off"))) {
511 for (i=0; i<NB_LOGS; i++) {
512 if (gen.logs[i] == lognum) {
518 printf_P(PSTR("already off\r\n"));
524 prog_char str_log_arg1_type[] = "type";
525 parse_pgm_token_string_t cmd_log_arg1_type = TOKEN_STRING_INITIALIZER(struct cmd_log_type_result, arg1, str_log_arg1_type);
526 /* keep it sync with log_name_and_num above */
527 prog_char str_log_arg2_type[] = "uart#i2c#i2cproto#sensor#bd##state#ax12";
528 parse_pgm_token_string_t cmd_log_arg2_type = TOKEN_STRING_INITIALIZER(struct cmd_log_type_result, arg2, str_log_arg2_type);
529 prog_char str_log_arg3[] = "on#off";
530 parse_pgm_token_string_t cmd_log_arg3 = TOKEN_STRING_INITIALIZER(struct cmd_log_type_result, arg3, str_log_arg3);
532 prog_char help_log_type[] = "Set log type";
533 parse_pgm_inst_t cmd_log_type = {
534 .f = cmd_log_type_parsed, /* function to call */
535 .data = NULL, /* 2nd arg of func */
536 .help_str = help_log_type,
537 .tokens = { /* token list, NULL terminated */
538 (prog_void *)&cmd_log_arg0,
539 (prog_void *)&cmd_log_arg1_type,
540 (prog_void *)&cmd_log_arg2_type,
541 (prog_void *)&cmd_log_arg3,
547 /**********************************************************/
550 /* this structure is filled when cmd_stack_space is parsed successfully */
551 struct cmd_stack_space_result {
555 /* function called when cmd_stack_space is parsed successfully */
556 static void cmd_stack_space_parsed(__attribute__((unused)) void *parsed_result,
557 __attribute__((unused)) void *data)
559 printf("res stack: %d\r\n", min_stack_space_available());
563 prog_char str_stack_space_arg0[] = "stack_space";
564 parse_pgm_token_string_t cmd_stack_space_arg0 = TOKEN_STRING_INITIALIZER(struct cmd_stack_space_result, arg0, str_stack_space_arg0);
566 prog_char help_stack_space[] = "Display remaining stack space";
567 parse_pgm_inst_t cmd_stack_space = {
568 .f = cmd_stack_space_parsed, /* function to call */
569 .data = NULL, /* 2nd arg of func */
570 .help_str = help_stack_space,
571 .tokens = { /* token list, NULL terminated */
572 (prog_void *)&cmd_stack_space_arg0,