add ballboard commands on mainboard
[aversive.git] / projects / microb2010 / mainboard / commands_mainboard.c
1 /*
2  *  Copyright Droids Corporation (2009)
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_mainboard.c,v 1.9 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/eeprom.h>
30
31 #include <ax12.h>
32 #include <uart.h>
33 #include <pwm_ng.h>
34 #include <clock_time.h>
35 #include <spi.h>
36 #include <i2c.h>
37
38 #include <pid.h>
39 #include <quadramp.h>
40 #include <control_system_manager.h>
41 #include <trajectory_manager.h>
42 #include <vect_base.h>
43 #include <lines.h>
44 #include <polygon.h>
45 #include <obstacle_avoidance.h>
46 #include <blocking_detection_manager.h>
47 #include <robot_system.h>
48 #include <position_manager.h>
49
50 #include <rdline.h>
51 #include <parse.h>
52 #include <parse_string.h>
53 #include <parse_num.h>
54
55 #include "../common/i2c_commands.h"
56 #include "../common/eeprom_mapping.h"
57
58 #include "main.h"
59 #include "sensor.h"
60 #include "cmdline.h"
61 #include "strat.h"
62 #include "strat_utils.h"
63 #include "strat_base.h"
64 #include "i2c_protocol.h"
65 #include "actuator.h"
66
67 struct cmd_event_result {
68         fixed_string_t arg0;
69         fixed_string_t arg1;
70         fixed_string_t arg2;
71 };
72
73
74 /* function called when cmd_event is parsed successfully */
75 static void cmd_event_parsed(void *parsed_result, void *data)
76 {
77         u08 bit=0;
78
79         struct cmd_event_result * res = parsed_result;
80         
81         if (!strcmp_P(res->arg1, PSTR("all"))) {
82                 bit = DO_ENCODERS | DO_CS | DO_RS | DO_POS |
83                         DO_BD | DO_TIMER | DO_POWER;
84                 if (!strcmp_P(res->arg2, PSTR("on")))
85                         mainboard.flags |= bit;
86                 else if (!strcmp_P(res->arg2, PSTR("off")))
87                         mainboard.flags &= bit;
88                 else { /* show */
89                         printf_P(PSTR("encoders is %s\r\n"), 
90                                  (DO_ENCODERS & mainboard.flags) ? "on":"off");
91                         printf_P(PSTR("cs is %s\r\n"), 
92                                  (DO_CS & mainboard.flags) ? "on":"off");
93                         printf_P(PSTR("rs is %s\r\n"), 
94                                  (DO_RS & mainboard.flags) ? "on":"off");
95                         printf_P(PSTR("pos is %s\r\n"), 
96                                  (DO_POS & mainboard.flags) ? "on":"off");
97                         printf_P(PSTR("bd is %s\r\n"), 
98                                  (DO_BD & mainboard.flags) ? "on":"off");
99                         printf_P(PSTR("timer is %s\r\n"), 
100                                  (DO_TIMER & mainboard.flags) ? "on":"off");
101                         printf_P(PSTR("power is %s\r\n"), 
102                                  (DO_POWER & mainboard.flags) ? "on":"off");
103                 }
104                 return;
105         }
106
107         if (!strcmp_P(res->arg1, PSTR("encoders")))
108                 bit = DO_ENCODERS;
109         else if (!strcmp_P(res->arg1, PSTR("cs"))) {
110                 strat_hardstop();
111                 bit = DO_CS;
112         }
113         else if (!strcmp_P(res->arg1, PSTR("rs")))
114                 bit = DO_RS;
115         else if (!strcmp_P(res->arg1, PSTR("pos")))
116                 bit = DO_POS;
117         else if (!strcmp_P(res->arg1, PSTR("bd")))
118                 bit = DO_BD;
119         else if (!strcmp_P(res->arg1, PSTR("timer"))) {
120                 time_reset();
121                 bit = DO_TIMER;
122         }
123         else if (!strcmp_P(res->arg1, PSTR("power")))
124                 bit = DO_POWER;
125
126         if (!strcmp_P(res->arg2, PSTR("on")))
127                 mainboard.flags |= bit;
128         else if (!strcmp_P(res->arg2, PSTR("off"))) {
129                 if (!strcmp_P(res->arg1, PSTR("cs"))) {
130                         pwm_ng_set(LEFT_PWM, 0);
131                         pwm_ng_set(RIGHT_PWM, 0);
132                 }
133                 mainboard.flags &= (~bit);
134         }
135         printf_P(PSTR("%s is %s\r\n"), res->arg1, 
136                       (bit & mainboard.flags) ? "on":"off");
137 }
138
139 prog_char str_event_arg0[] = "event";
140 parse_pgm_token_string_t cmd_event_arg0 = TOKEN_STRING_INITIALIZER(struct cmd_event_result, arg0, str_event_arg0);
141 prog_char str_event_arg1[] = "all#encoders#cs#rs#pos#bd#timer#power";
142 parse_pgm_token_string_t cmd_event_arg1 = TOKEN_STRING_INITIALIZER(struct cmd_event_result, arg1, str_event_arg1);
143 prog_char str_event_arg2[] = "on#off#show";
144 parse_pgm_token_string_t cmd_event_arg2 = TOKEN_STRING_INITIALIZER(struct cmd_event_result, arg2, str_event_arg2);
145
146 prog_char help_event[] = "Enable/disable events";
147 parse_pgm_inst_t cmd_event = {
148         .f = cmd_event_parsed,  /* function to call */
149         .data = NULL,      /* 2nd arg of func */
150         .help_str = help_event,
151         .tokens = {        /* token list, NULL terminated */
152                 (prog_void *)&cmd_event_arg0, 
153                 (prog_void *)&cmd_event_arg1, 
154                 (prog_void *)&cmd_event_arg2, 
155                 NULL,
156         },
157 };
158
159
160 /**********************************************************/
161 /* Spi_Test */
162
163 /* this structure is filled when cmd_spi_test is parsed successfully */
164 struct cmd_spi_test_result {
165         fixed_string_t arg0;
166 };
167
168 /* function called when cmd_spi_test is parsed successfully */
169 static void cmd_spi_test_parsed(void * parsed_result, void * data)
170 {
171         uint16_t i = 0, ret = 0, ret2 = 0;
172         
173         if (mainboard.flags & DO_ENCODERS) {
174                 printf_P(PSTR("Disable encoder event first\r\n"));
175                 return;
176         }
177
178         do {
179                 spi_slave_select(0);
180                 ret = spi_send_and_receive_byte(i);
181                 ret2 = spi_send_and_receive_byte(i);
182                 spi_slave_deselect(0);
183
184                 if ((i & 0x7ff) == 0)
185                         printf_P(PSTR("Sent %.4x twice, received %x %x\r\n"),
186                                  i, ret, ret2);
187
188                 i++;
189         } while(!cmdline_keypressed());
190 }
191
192 prog_char str_spi_test_arg0[] = "spi_test";
193 parse_pgm_token_string_t cmd_spi_test_arg0 = TOKEN_STRING_INITIALIZER(struct cmd_spi_test_result, arg0, str_spi_test_arg0);
194
195 prog_char help_spi_test[] = "Test the SPI";
196 parse_pgm_inst_t cmd_spi_test = {
197         .f = cmd_spi_test_parsed,  /* function to call */
198         .data = NULL,      /* 2nd arg of func */
199         .help_str = help_spi_test,
200         .tokens = {        /* token list, NULL terminated */
201                 (prog_void *)&cmd_spi_test_arg0, 
202                 NULL,
203         },
204 };
205
206
207
208 /**********************************************************/
209 /* Opponent tests */
210
211 /* this structure is filled when cmd_opponent is parsed successfully */
212 struct cmd_opponent_result {
213         fixed_string_t arg0;
214         fixed_string_t arg1;
215         int32_t arg2;
216         int32_t arg3;
217 };
218
219 /* function called when cmd_opponent is parsed successfully */
220 static void cmd_opponent_parsed(void *parsed_result, void *data)
221 {
222         int16_t x,y,d,a;
223
224         if (get_opponent_xyda(&x, &y, &d, &a))
225                 printf_P(PSTR("No opponent\r\n"));
226         else
227                 printf_P(PSTR("x=%d y=%d, d=%d a=%d\r\n"), x, y, d, a);
228 }
229
230 prog_char str_opponent_arg0[] = "opponent";
231 parse_pgm_token_string_t cmd_opponent_arg0 = TOKEN_STRING_INITIALIZER(struct cmd_opponent_result, arg0, str_opponent_arg0);
232 prog_char str_opponent_arg1[] = "show";
233 parse_pgm_token_string_t cmd_opponent_arg1 = TOKEN_STRING_INITIALIZER(struct cmd_opponent_result, arg1, str_opponent_arg1);
234
235 prog_char help_opponent[] = "Show (x,y) opponent";
236 parse_pgm_inst_t cmd_opponent = {
237         .f = cmd_opponent_parsed,  /* function to call */
238         .data = NULL,      /* 2nd arg of func */
239         .help_str = help_opponent,
240         .tokens = {        /* token list, NULL terminated */
241                 (prog_void *)&cmd_opponent_arg0, 
242                 (prog_void *)&cmd_opponent_arg1, 
243                 NULL,
244         },
245 };
246
247
248 prog_char str_opponent_arg1_set[] = "set";
249 parse_pgm_token_string_t cmd_opponent_arg1_set = TOKEN_STRING_INITIALIZER(struct cmd_opponent_result, arg1, str_opponent_arg1_set);
250 parse_pgm_token_num_t cmd_opponent_arg2 = TOKEN_NUM_INITIALIZER(struct cmd_opponent_result, arg2, INT32);
251 parse_pgm_token_num_t cmd_opponent_arg3 = TOKEN_NUM_INITIALIZER(struct cmd_opponent_result, arg3, INT32);
252
253 prog_char help_opponent_set[] = "Set (x,y) opponent";
254 parse_pgm_inst_t cmd_opponent_set = {
255         .f = cmd_opponent_parsed,  /* function to call */
256         .data = NULL,      /* 2nd arg of func */
257         .help_str = help_opponent_set,
258         .tokens = {        /* token list, NULL terminated */
259                 (prog_void *)&cmd_opponent_arg0, 
260                 (prog_void *)&cmd_opponent_arg1_set,
261                 (prog_void *)&cmd_opponent_arg2, 
262                 (prog_void *)&cmd_opponent_arg3, 
263                 NULL,
264         },
265 };
266
267
268 /**********************************************************/
269 /* Start */
270
271 /* this structure is filled when cmd_start is parsed successfully */
272 struct cmd_start_result {
273         fixed_string_t arg0;
274         fixed_string_t color;
275         fixed_string_t debug;
276 };
277
278 /* function called when cmd_start is parsed successfully */
279 static void cmd_start_parsed(void *parsed_result, void *data)
280 {
281         struct cmd_start_result *res = parsed_result;
282         uint8_t old_level = gen.log_level;
283
284         gen.logs[NB_LOGS] = E_USER_STRAT;
285         if (!strcmp_P(res->debug, PSTR("debug"))) {
286                 strat_infos.dump_enabled = 1;
287                 gen.log_level = 5;
288         }
289         else {
290                 strat_infos.dump_enabled = 0;
291                 gen.log_level = 0;
292         }
293
294         if (!strcmp_P(res->color, PSTR("yellow"))) {
295                 mainboard.our_color = I2C_COLOR_YELLOW;
296                 i2c_set_color(I2C_COBBOARD_ADDR, I2C_COLOR_YELLOW);
297                 i2c_set_color(I2C_BALLBOARD_ADDR, I2C_COLOR_YELLOW);
298         }
299         else if (!strcmp_P(res->color, PSTR("blue"))) {
300                 mainboard.our_color = I2C_COLOR_BLUE;
301                 i2c_set_color(I2C_COBBOARD_ADDR, I2C_COLOR_BLUE);
302                 i2c_set_color(I2C_BALLBOARD_ADDR, I2C_COLOR_BLUE);
303         }
304
305         strat_start();
306
307         gen.logs[NB_LOGS] = 0;
308         gen.log_level = old_level;
309 }
310
311 prog_char str_start_arg0[] = "start";
312 parse_pgm_token_string_t cmd_start_arg0 = TOKEN_STRING_INITIALIZER(struct cmd_start_result, arg0, str_start_arg0);
313 prog_char str_start_color[] = "blue#yellow";
314 parse_pgm_token_string_t cmd_start_color = TOKEN_STRING_INITIALIZER(struct cmd_start_result, color, str_start_color);
315 prog_char str_start_debug[] = "debug#match";
316 parse_pgm_token_string_t cmd_start_debug = TOKEN_STRING_INITIALIZER(struct cmd_start_result, debug, str_start_debug);
317
318 prog_char help_start[] = "Start the robot";
319 parse_pgm_inst_t cmd_start = {
320         .f = cmd_start_parsed,  /* function to call */
321         .data = NULL,      /* 2nd arg of func */
322         .help_str = help_start,
323         .tokens = {        /* token list, NULL terminated */
324                 (prog_void *)&cmd_start_arg0, 
325                 (prog_void *)&cmd_start_color, 
326                 (prog_void *)&cmd_start_debug, 
327                 NULL,
328         },
329 };
330
331
332
333 /**********************************************************/
334 /* Interact */
335
336 /* this structure is filled when cmd_interact is parsed successfully */
337 struct cmd_interact_result {
338         fixed_string_t arg0;
339 };
340
341 static void print_cs(void)
342 {
343         printf_P(PSTR("cons_d=% .8ld cons_a=% .8ld fil_d=% .8ld fil_a=% .8ld "
344                       "err_d=% .8ld err_a=% .8ld out_d=% .8ld out_a=% .8ld\r\n"), 
345                  cs_get_consign(&mainboard.distance.cs),
346                  cs_get_consign(&mainboard.angle.cs),
347                  cs_get_filtered_consign(&mainboard.distance.cs),
348                  cs_get_filtered_consign(&mainboard.angle.cs),
349                  cs_get_error(&mainboard.distance.cs),
350                  cs_get_error(&mainboard.angle.cs),
351                  cs_get_out(&mainboard.distance.cs),
352                  cs_get_out(&mainboard.angle.cs));
353 }
354
355 static void print_pos(void)
356 {
357         printf_P(PSTR("x=% .8d y=% .8d a=% .8d\r\n"), 
358                  position_get_x_s16(&mainboard.pos),
359                  position_get_y_s16(&mainboard.pos),
360                  position_get_a_deg_s16(&mainboard.pos));
361 }
362
363 static void print_time(void)
364 {
365         printf_P(PSTR("time %d\r\n"),time_get_s());
366 }
367
368
369 static void print_sensors(void)
370 {
371 #ifdef notyet
372         if (sensor_start_switch())
373                 printf_P(PSTR("Start switch | "));
374         else
375                 printf_P(PSTR("             | "));
376
377         if (IR_DISP_SENSOR())
378                 printf_P(PSTR("IR disp | "));
379         else
380                 printf_P(PSTR("        | "));
381
382         printf_P(PSTR("\r\n"));
383 #endif
384 }
385
386 static void print_pid(void)
387 {
388         printf_P(PSTR("P=% .8ld I=% .8ld D=% .8ld out=% .8ld | "
389                       "P=% .8ld I=% .8ld D=% .8ld out=% .8ld\r\n"),
390                  pid_get_value_in(&mainboard.distance.pid) * pid_get_gain_P(&mainboard.distance.pid),
391                  pid_get_value_I(&mainboard.distance.pid) * pid_get_gain_I(&mainboard.distance.pid),
392                  pid_get_value_D(&mainboard.distance.pid) * pid_get_gain_D(&mainboard.distance.pid),
393                  pid_get_value_out(&mainboard.distance.pid),
394                  pid_get_value_in(&mainboard.angle.pid) * pid_get_gain_P(&mainboard.angle.pid),
395                  pid_get_value_I(&mainboard.angle.pid) * pid_get_gain_I(&mainboard.angle.pid),
396                  pid_get_value_D(&mainboard.angle.pid) * pid_get_gain_D(&mainboard.angle.pid),
397                  pid_get_value_out(&mainboard.angle.pid));
398 }
399
400 #define PRINT_POS       (1<<0)
401 #define PRINT_PID       (1<<1)
402 #define PRINT_CS        (1<<2)
403 #define PRINT_SENSORS   (1<<3)
404 #define PRINT_TIME      (1<<4)
405 #define PRINT_BLOCKING  (1<<5)
406
407 static void cmd_interact_parsed(void * parsed_result, void * data)
408 {
409         int c;
410         int8_t cmd;
411         uint8_t print = 0;
412         struct vt100 vt100;
413
414         vt100_init(&vt100);
415
416         printf_P(PSTR("Display debugs:\r\n"
417                       "  1:pos\r\n"
418                       "  2:pid\r\n"
419                       "  3:cs\r\n"
420                       "  4:sensors\r\n"
421                       "  5:time\r\n"
422                       /* "  6:blocking\r\n" */
423                       "Commands:\r\n"
424                       "  arrows:move\r\n"
425                       "  space:stop\r\n"
426                       "  q:quit\r\n"));
427
428         /* stop motors */
429         mainboard.flags &= (~DO_CS);
430         pwm_set_and_save(LEFT_PWM, 0);
431         pwm_set_and_save(RIGHT_PWM, 0);
432
433         while(1) {
434                 if (print & PRINT_POS) {
435                         print_pos();
436                 }
437
438                 if (print & PRINT_PID) {
439                         print_pid();
440                 }
441
442                 if (print & PRINT_CS) {
443                         print_cs();
444                 }
445
446                 if (print & PRINT_SENSORS) {
447                         print_sensors();
448                 }
449
450                 if (print & PRINT_TIME) {
451                         print_time();
452                 }
453 /*              if (print & PRINT_BLOCKING) { */
454 /*                      printf_P(PSTR("%s %s blocking=%d\r\n"),  */
455 /*                               mainboard.blocking ? "BLOCK1":"      ", */
456 /*                               rs_is_blocked(&mainboard.rs) ? "BLOCK2":"      ", */
457 /*                               rs_get_blocking(&mainboard.rs)); */
458 /*              } */
459
460                 c = cmdline_getchar();
461                 if (c == -1) {
462                         wait_ms(10);
463                         continue;
464                 }
465                 cmd = vt100_parser(&vt100, c);
466                 if (cmd == -2) {
467                         wait_ms(10);
468                         continue;
469                 }
470                 
471                 if (cmd == -1) {
472                         switch(c) {
473                         case '1': print ^= PRINT_POS; break;
474                         case '2': print ^= PRINT_PID; break;
475                         case '3': print ^= PRINT_CS; break;
476                         case '4': print ^= PRINT_SENSORS; break;
477                         case '5': print ^= PRINT_TIME; break;
478                         case '6': print ^= PRINT_BLOCKING; break;
479
480                         case 'q': 
481                                 if (mainboard.flags & DO_CS)
482                                         strat_hardstop();
483                                 pwm_set_and_save(LEFT_PWM, 0);
484                                 pwm_set_and_save(RIGHT_PWM, 0);
485                                 return;
486                         case ' ':
487                                 pwm_set_and_save(LEFT_PWM, 0);
488                                 pwm_set_and_save(RIGHT_PWM, 0);
489                                 break;
490                         default: 
491                                 break;
492                         }
493                 }
494                 else {
495                         switch(cmd) {
496                         case KEY_UP_ARR: 
497                                 pwm_set_and_save(LEFT_PWM, 1200);
498                                 pwm_set_and_save(RIGHT_PWM, 1200);
499                                 break;
500                         case KEY_LEFT_ARR: 
501                                 pwm_set_and_save(LEFT_PWM, -1200);
502                                 pwm_set_and_save(RIGHT_PWM, 1200);
503                                 break;
504                         case KEY_DOWN_ARR: 
505                                 pwm_set_and_save(LEFT_PWM, -1200);
506                                 pwm_set_and_save(RIGHT_PWM, -1200);
507                                 break;
508                         case KEY_RIGHT_ARR:
509                                 pwm_set_and_save(LEFT_PWM, 1200);
510                                 pwm_set_and_save(RIGHT_PWM, -1200);
511                                 break;
512                         }
513                 }
514                 wait_ms(10);
515         }
516 }
517
518 prog_char str_interact_arg0[] = "interact";
519 parse_pgm_token_string_t cmd_interact_arg0 = TOKEN_STRING_INITIALIZER(struct cmd_interact_result, arg0, str_interact_arg0);
520
521 prog_char help_interact[] = "Interactive mode";
522 parse_pgm_inst_t cmd_interact = {
523         .f = cmd_interact_parsed,  /* function to call */
524         .data = NULL,      /* 2nd arg of func */
525         .help_str = help_interact,
526         .tokens = {        /* token list, NULL terminated */
527                 (prog_void *)&cmd_interact_arg0, 
528                 NULL,
529         },
530 };
531
532
533 /**********************************************************/
534 /* Color */
535
536 /* this structure is filled when cmd_color is parsed successfully */
537 struct cmd_color_result {
538         fixed_string_t arg0;
539         fixed_string_t color;
540 };
541
542 /* function called when cmd_color is parsed successfully */
543 static void cmd_color_parsed(void *parsed_result, void *data)
544 {
545         struct cmd_color_result *res = (struct cmd_color_result *) parsed_result;
546         if (!strcmp_P(res->color, PSTR("yellow"))) {
547                 mainboard.our_color = I2C_COLOR_YELLOW;
548                 i2c_set_color(I2C_COBBOARD_ADDR, I2C_COLOR_YELLOW);
549                 i2c_set_color(I2C_BALLBOARD_ADDR, I2C_COLOR_YELLOW);
550         }
551         else if (!strcmp_P(res->color, PSTR("blue"))) {
552                 mainboard.our_color = I2C_COLOR_BLUE;
553                 i2c_set_color(I2C_COBBOARD_ADDR, I2C_COLOR_BLUE);
554                 i2c_set_color(I2C_BALLBOARD_ADDR, I2C_COLOR_BLUE);
555         }
556         printf_P(PSTR("Done\r\n"));
557 }
558
559 prog_char str_color_arg0[] = "color";
560 parse_pgm_token_string_t cmd_color_arg0 = TOKEN_STRING_INITIALIZER(struct cmd_color_result, arg0, str_color_arg0);
561 prog_char str_color_color[] = "blue#yellow";
562 parse_pgm_token_string_t cmd_color_color = TOKEN_STRING_INITIALIZER(struct cmd_color_result, color, str_color_color);
563
564 prog_char help_color[] = "Set our color";
565 parse_pgm_inst_t cmd_color = {
566         .f = cmd_color_parsed,  /* function to call */
567         .data = NULL,      /* 2nd arg of func */
568         .help_str = help_color,
569         .tokens = {        /* token list, NULL terminated */
570                 (prog_void *)&cmd_color_arg0, 
571                 (prog_void *)&cmd_color_color, 
572                 NULL,
573         },
574 };
575
576
577 /**********************************************************/
578 /* Rs tests */
579
580 /* this structure is filled when cmd_rs is parsed successfully */
581 struct cmd_rs_result {
582         fixed_string_t arg0;
583         fixed_string_t arg1;
584 };
585
586 /* function called when cmd_rs is parsed successfully */
587 static void cmd_rs_parsed(void *parsed_result, void *data)
588 {
589         //      struct cmd_rs_result *res = parsed_result;
590         do {
591                 printf_P(PSTR("angle cons=% .6ld in=% .6ld out=% .6ld / "), 
592                          cs_get_consign(&mainboard.angle.cs),
593                          cs_get_filtered_feedback(&mainboard.angle.cs),
594                          cs_get_out(&mainboard.angle.cs));
595                 printf_P(PSTR("distance cons=% .6ld in=% .6ld out=% .6ld / "), 
596                          cs_get_consign(&mainboard.distance.cs),
597                          cs_get_filtered_feedback(&mainboard.distance.cs),
598                          cs_get_out(&mainboard.distance.cs));
599                 printf_P(PSTR("l=% .4ld r=% .4ld\r\n"), mainboard.pwm_l,
600                          mainboard.pwm_r);
601                 wait_ms(100);
602         } while(!cmdline_keypressed());
603 }
604
605 prog_char str_rs_arg0[] = "rs";
606 parse_pgm_token_string_t cmd_rs_arg0 = TOKEN_STRING_INITIALIZER(struct cmd_rs_result, arg0, str_rs_arg0);
607 prog_char str_rs_arg1[] = "show";
608 parse_pgm_token_string_t cmd_rs_arg1 = TOKEN_STRING_INITIALIZER(struct cmd_rs_result, arg1, str_rs_arg1);
609
610 prog_char help_rs[] = "Show rs (robot system) values";
611 parse_pgm_inst_t cmd_rs = {
612         .f = cmd_rs_parsed,  /* function to call */
613         .data = NULL,      /* 2nd arg of func */
614         .help_str = help_rs,
615         .tokens = {        /* token list, NULL terminated */
616                 (prog_void *)&cmd_rs_arg0, 
617                 (prog_void *)&cmd_rs_arg1, 
618                 NULL,
619         },
620 };
621
622 /**********************************************************/
623 /* I2cdebug */
624
625 /* this structure is filled when cmd_i2cdebug is parsed successfully */
626 struct cmd_i2cdebug_result {
627         fixed_string_t arg0;
628 };
629
630 /* function called when cmd_i2cdebug is parsed successfully */
631 static void cmd_i2cdebug_parsed(void * parsed_result, void * data)
632 {
633         i2c_debug();
634         i2c_protocol_debug();
635 }
636
637 prog_char str_i2cdebug_arg0[] = "i2cdebug";
638 parse_pgm_token_string_t cmd_i2cdebug_arg0 = TOKEN_STRING_INITIALIZER(struct cmd_i2cdebug_result, arg0, str_i2cdebug_arg0);
639
640 prog_char help_i2cdebug[] = "I2c debug infos";
641 parse_pgm_inst_t cmd_i2cdebug = {
642         .f = cmd_i2cdebug_parsed,  /* function to call */
643         .data = NULL,      /* 2nd arg of func */
644         .help_str = help_i2cdebug,
645         .tokens = {        /* token list, NULL terminated */
646                 (prog_void *)&cmd_i2cdebug_arg0, 
647                 NULL,
648         },
649 };
650
651 /**********************************************************/
652 /* Cobboard_Show */
653
654 /* this structure is filled when cmd_cobboard_show is parsed successfully */
655 struct cmd_cobboard_show_result {
656         fixed_string_t arg0;
657         fixed_string_t arg1;
658 };
659
660 /* function called when cmd_cobboard_show is parsed successfully */
661 static void cmd_cobboard_show_parsed(void * parsed_result, void * data)
662 {
663         printf_P(PSTR("mode = %x\r\n"), cobboard.mode);
664         printf_P(PSTR("status = %x\r\n"), cobboard.status);
665         printf_P(PSTR("cob_count = %x\r\n"), cobboard.cob_count);
666         printf_P(PSTR("left_cobroller_speed = %d\r\n"), cobboard.left_cobroller_speed);
667         printf_P(PSTR("right_cobroller_speed = %d\r\n"), cobboard.right_cobroller_speed);
668 }
669
670 prog_char str_cobboard_show_arg0[] = "cobboard";
671 parse_pgm_token_string_t cmd_cobboard_show_arg0 = TOKEN_STRING_INITIALIZER(struct cmd_cobboard_show_result, arg0, str_cobboard_show_arg0);
672 prog_char str_cobboard_show_arg1[] = "show";
673 parse_pgm_token_string_t cmd_cobboard_show_arg1 = TOKEN_STRING_INITIALIZER(struct cmd_cobboard_show_result, arg1, str_cobboard_show_arg1);
674
675 prog_char help_cobboard_show[] = "show cobboard status";
676 parse_pgm_inst_t cmd_cobboard_show = {
677         .f = cmd_cobboard_show_parsed,  /* function to call */
678         .data = NULL,      /* 2nd arg of func */
679         .help_str = help_cobboard_show,
680         .tokens = {        /* token list, NULL terminated */
681                 (prog_void *)&cmd_cobboard_show_arg0, 
682                 (prog_void *)&cmd_cobboard_show_arg1, 
683                 NULL,
684         },
685 };
686
687 /**********************************************************/
688 /* Cobboard_Setmode1 */
689
690 /* this structure is filled when cmd_cobboard_setmode1 is parsed successfully */
691 struct cmd_cobboard_setmode1_result {
692         fixed_string_t arg0;
693         fixed_string_t arg1;
694 };
695
696 /* function called when cmd_cobboard_setmode1 is parsed successfully */
697 static void cmd_cobboard_setmode1_parsed(void *parsed_result, void *data)
698 {
699         struct cmd_cobboard_setmode1_result *res = parsed_result;
700
701         if (!strcmp_P(res->arg1, PSTR("init")))
702                 i2c_cobboard_mode_init();
703         else if (!strcmp_P(res->arg1, PSTR("eject")))
704                 i2c_cobboard_mode_eject();
705 }
706
707 prog_char str_cobboard_setmode1_arg0[] = "cobboard";
708 parse_pgm_token_string_t cmd_cobboard_setmode1_arg0 = TOKEN_STRING_INITIALIZER(struct cmd_cobboard_setmode1_result, arg0, str_cobboard_setmode1_arg0);
709 prog_char str_cobboard_setmode1_arg1[] = "init#eject";
710 parse_pgm_token_string_t cmd_cobboard_setmode1_arg1 = TOKEN_STRING_INITIALIZER(struct cmd_cobboard_setmode1_result, arg1, str_cobboard_setmode1_arg1);
711
712 prog_char help_cobboard_setmode1[] = "set cobboard mode (mode)";
713 parse_pgm_inst_t cmd_cobboard_setmode1 = {
714         .f = cmd_cobboard_setmode1_parsed,  /* function to call */
715         .data = NULL,      /* 2nd arg of func */
716         .help_str = help_cobboard_setmode1,
717         .tokens = {        /* token list, NULL terminated */
718                 (prog_void *)&cmd_cobboard_setmode1_arg0, 
719                 (prog_void *)&cmd_cobboard_setmode1_arg1, 
720                 NULL,
721         },
722 };
723
724 /**********************************************************/
725 /* Cobboard_Setmode2 */
726
727 /* this structure is filled when cmd_cobboard_setmode2 is parsed successfully */
728 struct cmd_cobboard_setmode2_result {
729         fixed_string_t arg0;
730         fixed_string_t arg1;
731         fixed_string_t arg2;
732 };
733
734 /* function called when cmd_cobboard_setmode2 is parsed successfully */
735 static void cmd_cobboard_setmode2_parsed(void * parsed_result, void * data)
736 {
737         struct cmd_cobboard_setmode2_result *res = parsed_result;
738         uint8_t side = I2C_LEFT_SIDE;
739
740         if (!strcmp_P(res->arg2, PSTR("left")))
741                 side = I2C_LEFT_SIDE;
742         else if (!strcmp_P(res->arg2, PSTR("right")))
743                 side = I2C_RIGHT_SIDE;
744
745         if (!strcmp_P(res->arg1, PSTR("deploy")))
746                 i2c_cobboard_mode_deploy(side);
747         else if (!strcmp_P(res->arg1, PSTR("harvest")))
748                 i2c_cobboard_mode_harvest(side);
749         else if (!strcmp_P(res->arg1, PSTR("pack")))
750                 i2c_cobboard_mode_pack(side);
751 }
752
753 prog_char str_cobboard_setmode2_arg0[] = "cobboard";
754 parse_pgm_token_string_t cmd_cobboard_setmode2_arg0 = TOKEN_STRING_INITIALIZER(struct cmd_cobboard_setmode2_result, arg0, str_cobboard_setmode2_arg0);
755 prog_char str_cobboard_setmode2_arg1[] = "harvest#deploy#pack";
756 parse_pgm_token_string_t cmd_cobboard_setmode2_arg1 = TOKEN_STRING_INITIALIZER(struct cmd_cobboard_setmode2_result, arg1, str_cobboard_setmode2_arg1);
757 prog_char str_cobboard_setmode2_arg2[] = "left#right";
758 parse_pgm_token_string_t cmd_cobboard_setmode2_arg2 = TOKEN_STRING_INITIALIZER(struct cmd_cobboard_setmode2_result, arg2, str_cobboard_setmode2_arg2);
759
760 prog_char help_cobboard_setmode2[] = "set cobboard mode (mode, side)";
761 parse_pgm_inst_t cmd_cobboard_setmode2 = {
762         .f = cmd_cobboard_setmode2_parsed,  /* function to call */
763         .data = NULL,      /* 2nd arg of func */
764         .help_str = help_cobboard_setmode2,
765         .tokens = {        /* token list, NULL terminated */
766                 (prog_void *)&cmd_cobboard_setmode2_arg0, 
767                 (prog_void *)&cmd_cobboard_setmode2_arg1, 
768                 (prog_void *)&cmd_cobboard_setmode2_arg2, 
769                 NULL,
770         },
771 };
772
773 /**********************************************************/
774 /* Cobboard_Setmode3 */
775
776 /* this structure is filled when cmd_cobboard_setmode3 is parsed successfully */
777 struct cmd_cobboard_setmode3_result {
778         fixed_string_t arg0;
779         fixed_string_t arg1;
780         uint8_t level;
781 };
782
783 /* function called when cmd_cobboard_setmode3 is parsed successfully */
784 static void cmd_cobboard_setmode3_parsed(void *parsed_result, void *data)
785 {
786         struct cmd_cobboard_setmode3_result *res = parsed_result;
787         if (!strcmp_P(res->arg1, PSTR("xxx")))
788                 printf("faux\r\n");
789 }
790
791 prog_char str_cobboard_setmode3_arg0[] = "cobboard";
792 parse_pgm_token_string_t cmd_cobboard_setmode3_arg0 = TOKEN_STRING_INITIALIZER(struct cmd_cobboard_setmode3_result, arg0, str_cobboard_setmode3_arg0);
793 prog_char str_cobboard_setmode3_arg1[] = "xxx";
794 parse_pgm_token_string_t cmd_cobboard_setmode3_arg1 = TOKEN_STRING_INITIALIZER(struct cmd_cobboard_setmode3_result, arg1, str_cobboard_setmode3_arg1);
795 parse_pgm_token_num_t cmd_cobboard_setmode3_arg2 = TOKEN_NUM_INITIALIZER(struct cmd_cobboard_setmode3_result, level, UINT8);
796
797 prog_char help_cobboard_setmode3[] = "set cobboard mode (mode, level)";
798 parse_pgm_inst_t cmd_cobboard_setmode3 = {
799         .f = cmd_cobboard_setmode3_parsed,  /* function to call */
800         .data = NULL,      /* 2nd arg of func */
801         .help_str = help_cobboard_setmode3,
802         .tokens = {        /* token list, NULL terminated */
803                 (prog_void *)&cmd_cobboard_setmode3_arg0, 
804                 (prog_void *)&cmd_cobboard_setmode3_arg1, 
805                 (prog_void *)&cmd_cobboard_setmode3_arg2, 
806                 NULL,
807         },
808 };
809
810 /**********************************************************/
811 /* Ballboard_Show */
812
813 /* this structure is filled when cmd_ballboard_show is parsed successfully */
814 struct cmd_ballboard_show_result {
815         fixed_string_t arg0;
816         fixed_string_t arg1;
817 };
818
819 /* function called when cmd_ballboard_show is parsed successfully */
820 static void cmd_ballboard_show_parsed(void * parsed_result, void * data)
821 {
822         printf_P(PSTR("mode = %x\r\n"), ballboard.mode);
823         printf_P(PSTR("status = %x\r\n"), ballboard.status);
824         printf_P(PSTR("ball_count = %d\r\n"), ballboard.ball_count);
825 }
826
827 prog_char str_ballboard_show_arg0[] = "ballboard";
828 parse_pgm_token_string_t cmd_ballboard_show_arg0 = TOKEN_STRING_INITIALIZER(struct cmd_ballboard_show_result, arg0, str_ballboard_show_arg0);
829 prog_char str_ballboard_show_arg1[] = "show";
830 parse_pgm_token_string_t cmd_ballboard_show_arg1 = TOKEN_STRING_INITIALIZER(struct cmd_ballboard_show_result, arg1, str_ballboard_show_arg1);
831
832 prog_char help_ballboard_show[] = "show ballboard status";
833 parse_pgm_inst_t cmd_ballboard_show = {
834         .f = cmd_ballboard_show_parsed,  /* function to call */
835         .data = NULL,      /* 2nd arg of func */
836         .help_str = help_ballboard_show,
837         .tokens = {        /* token list, NULL terminated */
838                 (prog_void *)&cmd_ballboard_show_arg0, 
839                 (prog_void *)&cmd_ballboard_show_arg1, 
840                 NULL,
841         },
842 };
843
844 /**********************************************************/
845 /* Ballboard_Setmode1 */
846
847 /* this structure is filled when cmd_ballboard_setmode1 is parsed successfully */
848 struct cmd_ballboard_setmode1_result {
849         fixed_string_t arg0;
850         fixed_string_t arg1;
851 };
852
853 /* function called when cmd_ballboard_setmode1 is parsed successfully */
854 static void cmd_ballboard_setmode1_parsed(void *parsed_result, void *data)
855 {
856         struct cmd_ballboard_setmode1_result *res = parsed_result;
857
858         if (!strcmp_P(res->arg1, PSTR("init")))
859                 i2c_ballboard_set_mode(I2C_BALLBOARD_MODE_INIT);
860         else if (!strcmp_P(res->arg1, PSTR("off")))
861                 i2c_ballboard_set_mode(I2C_BALLBOARD_MODE_OFF);
862         else if (!strcmp_P(res->arg1, PSTR("eject")))
863                 i2c_ballboard_set_mode(I2C_BALLBOARD_MODE_EJECT);
864         else if (!strcmp_P(res->arg1, PSTR("harvest")))
865                 i2c_ballboard_set_mode(I2C_BALLBOARD_MODE_HARVEST);
866
867         /* other commands */
868 }
869
870 prog_char str_ballboard_setmode1_arg0[] = "ballboard";
871 parse_pgm_token_string_t cmd_ballboard_setmode1_arg0 = TOKEN_STRING_INITIALIZER(struct cmd_ballboard_setmode1_result, arg0, str_ballboard_setmode1_arg0);
872 prog_char str_ballboard_setmode1_arg1[] = "init#eject#harvest#off";
873 parse_pgm_token_string_t cmd_ballboard_setmode1_arg1 = TOKEN_STRING_INITIALIZER(struct cmd_ballboard_setmode1_result, arg1, str_ballboard_setmode1_arg1);
874
875 prog_char help_ballboard_setmode1[] = "set ballboard mode (mode)";
876 parse_pgm_inst_t cmd_ballboard_setmode1 = {
877         .f = cmd_ballboard_setmode1_parsed,  /* function to call */
878         .data = NULL,      /* 2nd arg of func */
879         .help_str = help_ballboard_setmode1,
880         .tokens = {        /* token list, NULL terminated */
881                 (prog_void *)&cmd_ballboard_setmode1_arg0, 
882                 (prog_void *)&cmd_ballboard_setmode1_arg1, 
883                 NULL,
884         },
885 };
886
887 /**********************************************************/
888 /* Ballboard_Setmode2 */
889
890 /* this structure is filled when cmd_ballboard_setmode2 is parsed successfully */
891 struct cmd_ballboard_setmode2_result {
892         fixed_string_t arg0;
893         fixed_string_t arg1;
894         fixed_string_t arg2;
895 };
896
897 /* function called when cmd_ballboard_setmode2 is parsed successfully */
898 static void cmd_ballboard_setmode2_parsed(void * parsed_result, void * data)
899 {
900         struct cmd_ballboard_setmode2_result *res = parsed_result;
901         uint8_t mode = I2C_BALLBOARD_MODE_INIT;
902
903         if (!strcmp_P(res->arg2, PSTR("left"))) {
904                 if (!strcmp_P(res->arg1, PSTR("prepare")))
905                         mode = I2C_BALLBOARD_MODE_PREP_L_FORK;
906                 else if (!strcmp_P(res->arg1, PSTR("take")))
907                         mode = I2C_BALLBOARD_MODE_TAKE_L_FORK;
908         }
909         else {
910                 if (!strcmp_P(res->arg1, PSTR("prepare")))
911                         mode = I2C_BALLBOARD_MODE_PREP_R_FORK;
912                 else if (!strcmp_P(res->arg1, PSTR("take")))
913                         mode = I2C_BALLBOARD_MODE_TAKE_R_FORK;
914         }
915         i2c_ballboard_set_mode(mode);
916 }
917
918 prog_char str_ballboard_setmode2_arg0[] = "ballboard";
919 parse_pgm_token_string_t cmd_ballboard_setmode2_arg0 = TOKEN_STRING_INITIALIZER(struct cmd_ballboard_setmode2_result, arg0, str_ballboard_setmode2_arg0);
920 prog_char str_ballboard_setmode2_arg1[] = "prepare#take";
921 parse_pgm_token_string_t cmd_ballboard_setmode2_arg1 = TOKEN_STRING_INITIALIZER(struct cmd_ballboard_setmode2_result, arg1, str_ballboard_setmode2_arg1);
922 prog_char str_ballboard_setmode2_arg2[] = "left#right";
923 parse_pgm_token_string_t cmd_ballboard_setmode2_arg2 = TOKEN_STRING_INITIALIZER(struct cmd_ballboard_setmode2_result, arg2, str_ballboard_setmode2_arg2);
924
925 prog_char help_ballboard_setmode2[] = "set ballboard mode (mode, side)";
926 parse_pgm_inst_t cmd_ballboard_setmode2 = {
927         .f = cmd_ballboard_setmode2_parsed,  /* function to call */
928         .data = NULL,      /* 2nd arg of func */
929         .help_str = help_ballboard_setmode2,
930         .tokens = {        /* token list, NULL terminated */
931                 (prog_void *)&cmd_ballboard_setmode2_arg0, 
932                 (prog_void *)&cmd_ballboard_setmode2_arg1, 
933                 (prog_void *)&cmd_ballboard_setmode2_arg2, 
934                 NULL,
935         },
936 };
937
938 /**********************************************************/
939 /* Ballboard_Setmode3 */
940
941 /* this structure is filled when cmd_ballboard_setmode3 is parsed successfully */
942 struct cmd_ballboard_setmode3_result {
943         fixed_string_t arg0;
944         fixed_string_t arg1;
945         uint8_t level;
946 };
947
948 /* function called when cmd_ballboard_setmode3 is parsed successfully */
949 static void cmd_ballboard_setmode3_parsed(void *parsed_result, void *data)
950 {
951         struct cmd_ballboard_setmode3_result *res = parsed_result;
952         if (!strcmp_P(res->arg1, PSTR("xxx")))
953                 printf("faux\r\n");
954 }
955
956 prog_char str_ballboard_setmode3_arg0[] = "ballboard";
957 parse_pgm_token_string_t cmd_ballboard_setmode3_arg0 = TOKEN_STRING_INITIALIZER(struct cmd_ballboard_setmode3_result, arg0, str_ballboard_setmode3_arg0);
958 prog_char str_ballboard_setmode3_arg1[] = "xxx";
959 parse_pgm_token_string_t cmd_ballboard_setmode3_arg1 = TOKEN_STRING_INITIALIZER(struct cmd_ballboard_setmode3_result, arg1, str_ballboard_setmode3_arg1);
960 parse_pgm_token_num_t cmd_ballboard_setmode3_arg2 = TOKEN_NUM_INITIALIZER(struct cmd_ballboard_setmode3_result, level, UINT8);
961
962 prog_char help_ballboard_setmode3[] = "set ballboard mode (mode, level)";
963 parse_pgm_inst_t cmd_ballboard_setmode3 = {
964         .f = cmd_ballboard_setmode3_parsed,  /* function to call */
965         .data = NULL,      /* 2nd arg of func */
966         .help_str = help_ballboard_setmode3,
967         .tokens = {        /* token list, NULL terminated */
968                 (prog_void *)&cmd_ballboard_setmode3_arg0, 
969                 (prog_void *)&cmd_ballboard_setmode3_arg1, 
970                 (prog_void *)&cmd_ballboard_setmode3_arg2, 
971                 NULL,
972         },
973 };
974
975 /**********************************************************/
976 /* Servo_Balls */
977
978 /* this structure is filled when cmd_servo_balls is parsed successfully */
979 struct cmd_servo_balls_result {
980         fixed_string_t arg0;
981         fixed_string_t arg1;
982 };
983
984 /* function called when cmd_servo_balls is parsed successfully */
985 static void cmd_servo_balls_parsed(void *parsed_result,
986                                    __attribute__((unused)) void *data)
987 {
988         struct cmd_servo_balls_result *res = parsed_result;
989
990         if (!strcmp_P(res->arg1, PSTR("deploy")))
991                 support_balls_deploy();
992         else if (!strcmp_P(res->arg1, PSTR("pack")))
993                 support_balls_pack();
994 }
995
996 prog_char str_servo_balls_arg0[] = "support_balls";
997 parse_pgm_token_string_t cmd_servo_balls_arg0 =
998         TOKEN_STRING_INITIALIZER(struct cmd_servo_balls_result, arg0, str_servo_balls_arg0);
999 prog_char str_servo_balls_arg1[] = "deploy#pack";
1000 parse_pgm_token_string_t cmd_servo_balls_arg1 =
1001         TOKEN_STRING_INITIALIZER(struct cmd_servo_balls_result, arg1, str_servo_balls_arg1);
1002
1003 prog_char help_servo_balls[] = "control support balls";
1004 parse_pgm_inst_t cmd_servo_balls = {
1005         .f = cmd_servo_balls_parsed,  /* function to call */
1006         .data = NULL,      /* 2nd arg of func */
1007         .help_str = help_servo_balls,
1008         .tokens = {        /* token list, NULL terminated */
1009                 (prog_void *)&cmd_servo_balls_arg0, 
1010                 (prog_void *)&cmd_servo_balls_arg1, 
1011                 NULL,
1012         },
1013 };
1014
1015 /**********************************************************/
1016 /* Test */
1017
1018 /* this structure is filled when cmd_test is parsed successfully */
1019 struct cmd_test_result {
1020         fixed_string_t arg0;
1021         int32_t radius;
1022 };
1023
1024 /* function called when cmd_test is parsed successfully */
1025 static void cmd_test_parsed(void *parsed_result, void *data)
1026 {
1027 }
1028
1029 prog_char str_test_arg0[] = "test";
1030 parse_pgm_token_string_t cmd_test_arg0 = TOKEN_STRING_INITIALIZER(struct cmd_test_result, arg0, str_test_arg0);
1031 parse_pgm_token_num_t cmd_test_arg1 = TOKEN_NUM_INITIALIZER(struct cmd_test_result, radius, INT32);
1032
1033 prog_char help_test[] = "Test function";
1034 parse_pgm_inst_t cmd_test = {
1035         .f = cmd_test_parsed,  /* function to call */
1036         .data = NULL,      /* 2nd arg of func */
1037         .help_str = help_test,
1038         .tokens = {        /* token list, NULL terminated */
1039                 (prog_void *)&cmd_test_arg0,
1040                 (prog_void *)&cmd_test_arg1,
1041                 NULL,
1042         },
1043 };