linear interpolation, prepare multi TSOP
[aversive.git] / projects / microb2010 / mechboard / commands_mechboard.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_mechboard.c,v 1.6 2009-11-08 17:25:00 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
30 #include <ax12.h>
31 #include <uart.h>
32 #include <pwm_ng.h>
33 #include <time.h>
34 #include <spi.h>
35
36 #include <pid.h>
37 #include <quadramp.h>
38 #include <control_system_manager.h>
39 #include <blocking_detection_manager.h>
40
41 #include <rdline.h>
42 #include <parse.h>
43 #include <parse_string.h>
44 #include <parse_num.h>
45
46 #include "../common/i2c_commands.h"
47 #include "main.h"
48 #include "sensor.h"
49 #include "cmdline.h"
50 #include "state.h"
51 #include "i2c_protocol.h"
52 #include "actuator.h"
53 #include "arm_xy.h"
54 #include "arm_highlevel.h"
55 #include "actuator.h"
56
57 extern uint16_t state_debug;
58
59 struct cmd_event_result {
60         fixed_string_t arg0;
61         fixed_string_t arg1;
62         fixed_string_t arg2;
63 };
64
65
66 /* function called when cmd_event is parsed successfully */
67 static void cmd_event_parsed(void *parsed_result, __attribute__((unused)) void *data)
68 {
69         u08 bit=0;
70
71         struct cmd_event_result * res = parsed_result;
72         
73         if (!strcmp_P(res->arg1, PSTR("all"))) {
74                 bit = DO_ENCODERS | DO_CS | DO_BD | DO_POWER;
75                 if (!strcmp_P(res->arg2, PSTR("on")))
76                         mechboard.flags |= bit;
77                 else if (!strcmp_P(res->arg2, PSTR("off")))
78                         mechboard.flags &= bit;
79                 else { /* show */
80                         printf_P(PSTR("encoders is %s\r\n"), 
81                                  (DO_ENCODERS & mechboard.flags) ? "on":"off");
82                         printf_P(PSTR("cs is %s\r\n"), 
83                                  (DO_CS & mechboard.flags) ? "on":"off");
84                         printf_P(PSTR("bd is %s\r\n"), 
85                                  (DO_BD & mechboard.flags) ? "on":"off");
86                         printf_P(PSTR("power is %s\r\n"), 
87                                  (DO_POWER & mechboard.flags) ? "on":"off");
88                 }
89                 return;
90         }
91
92         if (!strcmp_P(res->arg1, PSTR("encoders")))
93                 bit = DO_ENCODERS;
94         else if (!strcmp_P(res->arg1, PSTR("cs"))) {
95                 if (!strcmp_P(res->arg2, PSTR("on")))
96                         arm_calibrate();
97                 bit = DO_CS;
98         }
99         else if (!strcmp_P(res->arg1, PSTR("bd")))
100                 bit = DO_BD;
101         else if (!strcmp_P(res->arg1, PSTR("power")))
102                 bit = DO_POWER;
103
104
105         if (!strcmp_P(res->arg2, PSTR("on")))
106                 mechboard.flags |= bit;
107         else if (!strcmp_P(res->arg2, PSTR("off"))) {
108                 if (!strcmp_P(res->arg1, PSTR("cs"))) {
109                         pwm_ng_set(LEFT_ARM_PWM, 0);
110                         pwm_ng_set(RIGHT_ARM_PWM, 0);
111                 }
112                 mechboard.flags &= (~bit);
113         }
114         printf_P(PSTR("%s is %s\r\n"), res->arg1, 
115                       (bit & mechboard.flags) ? "on":"off");
116 }
117
118 prog_char str_event_arg0[] = "event";
119 parse_pgm_token_string_t cmd_event_arg0 = TOKEN_STRING_INITIALIZER(struct cmd_event_result, arg0, str_event_arg0);
120 prog_char str_event_arg1[] = "all#encoders#cs#bd#power";
121 parse_pgm_token_string_t cmd_event_arg1 = TOKEN_STRING_INITIALIZER(struct cmd_event_result, arg1, str_event_arg1);
122 prog_char str_event_arg2[] = "on#off#show";
123 parse_pgm_token_string_t cmd_event_arg2 = TOKEN_STRING_INITIALIZER(struct cmd_event_result, arg2, str_event_arg2);
124
125 prog_char help_event[] = "Enable/disable events";
126 parse_pgm_inst_t cmd_event = {
127         .f = cmd_event_parsed,  /* function to call */
128         .data = NULL,      /* 2nd arg of func */
129         .help_str = help_event,
130         .tokens = {        /* token list, NULL terminated */
131                 (prog_void *)&cmd_event_arg0, 
132                 (prog_void *)&cmd_event_arg1, 
133                 (prog_void *)&cmd_event_arg2, 
134                 NULL,
135         },
136 };
137
138 /**********************************************************/
139 /* Color */
140
141 /* this structure is filled when cmd_color is parsed successfully */
142 struct cmd_color_result {
143         fixed_string_t arg0;
144         fixed_string_t color;
145 };
146
147 /* function called when cmd_color is parsed successfully */
148 static void cmd_color_parsed(void *parsed_result, __attribute__((unused)) void *data)
149 {
150         struct cmd_color_result *res = (struct cmd_color_result *) parsed_result;
151         if (!strcmp_P(res->color, PSTR("red"))) {
152                 mechboard.our_color = I2C_COLOR_RED;
153         }
154         else if (!strcmp_P(res->color, PSTR("green"))) {
155                 mechboard.our_color = I2C_COLOR_GREEN;
156         }
157         printf_P(PSTR("Done\r\n"));
158 }
159
160 prog_char str_color_arg0[] = "color";
161 parse_pgm_token_string_t cmd_color_arg0 = TOKEN_STRING_INITIALIZER(struct cmd_color_result, arg0, str_color_arg0);
162 prog_char str_color_color[] = "green#red";
163 parse_pgm_token_string_t cmd_color_color = TOKEN_STRING_INITIALIZER(struct cmd_color_result, color, str_color_color);
164
165 prog_char help_color[] = "Set our color";
166 parse_pgm_inst_t cmd_color = {
167         .f = cmd_color_parsed,  /* function to call */
168         .data = NULL,      /* 2nd arg of func */
169         .help_str = help_color,
170         .tokens = {        /* token list, NULL terminated */
171                 (prog_void *)&cmd_color_arg0, 
172                 (prog_void *)&cmd_color_color, 
173                 NULL,
174         },
175 };
176
177 /**********************************************************/
178 /* arm_show */
179
180 /* this structure is filled when cmd_arm_show is parsed successfully */
181 struct cmd_arm_show_result {
182         fixed_string_t arg0;
183         fixed_string_t arg1;
184         fixed_string_t arg2;
185 };
186
187 /* function called when cmd_arm_show is parsed successfully */
188 static void cmd_arm_show_parsed(void *parsed_result, __attribute__((unused)) void *data)
189 {
190         struct cmd_arm_show_result *res = parsed_result;
191
192         if (strcmp_P(res->arg1, PSTR("left")) == 0)
193                 arm_dump(&left_arm);
194         else if (strcmp_P(res->arg1, PSTR("right")) == 0)
195                 arm_dump(&right_arm);
196         else {
197                 arm_dump(&left_arm);
198                 arm_dump(&right_arm);
199         }
200 }
201
202 prog_char str_arm_show_arg0[] = "arm";
203 parse_pgm_token_string_t cmd_arm_show_arg0 = TOKEN_STRING_INITIALIZER(struct cmd_arm_show_result, arg0, str_arm_show_arg0);
204 prog_char str_arm_show_arg1[] = "left#right#both";
205 parse_pgm_token_string_t cmd_arm_show_arg1 = TOKEN_STRING_INITIALIZER(struct cmd_arm_show_result, arg1, str_arm_show_arg1);
206 prog_char str_arm_show_arg2[] = "show";
207 parse_pgm_token_string_t cmd_arm_show_arg2 = TOKEN_STRING_INITIALIZER(struct cmd_arm_show_result, arg2, str_arm_show_arg2);
208
209 prog_char help_arm_show[] = "Show arm status";
210 parse_pgm_inst_t cmd_arm_show = {
211         .f = cmd_arm_show_parsed,  /* function to call */
212         .data = NULL,      /* 2nd arg of func */
213         .help_str = help_arm_show,
214         .tokens = {        /* token list, NULL terminated */
215                 (prog_void *)&cmd_arm_show_arg0,
216                 (prog_void *)&cmd_arm_show_arg1,
217                 (prog_void *)&cmd_arm_show_arg2,
218                 NULL,
219         },
220 };
221
222 /**********************************************************/
223 /* arm_goto */
224
225 /* this structure is filled when cmd_arm_goto is parsed successfully */
226 struct cmd_arm_goto_result {
227         fixed_string_t arg0;
228         fixed_string_t arg1;
229         int16_t arg2;
230         int16_t arg3;
231         int16_t arg4;
232 };
233
234 /* function called when cmd_arm_goto is parsed successfully */
235 static void cmd_arm_goto_parsed(void *parsed_result, __attribute__((unused)) void *data)
236 {
237         struct cmd_arm_goto_result *res = parsed_result;
238         uint8_t err;
239
240         if (strcmp_P(res->arg1, PSTR("left")) == 0) {
241                 arm_do_xy(&left_arm, res->arg2, res->arg3, res->arg4);
242                 err = arm_wait_traj_end(&left_arm, ARM_TRAJ_ALL);
243                 if (err != ARM_TRAJ_END)
244                         printf_P(PSTR("err %x\r\n"), err);
245         }
246         else if (strcmp_P(res->arg1, PSTR("right")) == 0) {
247                 arm_do_xy(&right_arm, res->arg2, res->arg3, res->arg4);
248                 err = arm_wait_traj_end(&right_arm, ARM_TRAJ_ALL);
249                 if (err != ARM_TRAJ_END)
250                         printf_P(PSTR("err %x\r\n"), err);
251         }
252         else {
253                 arm_do_xy(&left_arm, res->arg2, res->arg3, res->arg4);
254                 arm_do_xy(&right_arm, res->arg2, res->arg3, res->arg4);
255                 err = arm_wait_traj_end(&left_arm, ARM_TRAJ_ALL);
256                 if (err != ARM_TRAJ_END)
257                         printf_P(PSTR("left err %x\r\n"), err);
258                 err = arm_wait_traj_end(&right_arm, ARM_TRAJ_ALL);
259                 if (err != ARM_TRAJ_END)
260                         printf_P(PSTR("right err %x\r\n"), err);
261         }
262 }
263
264 prog_char str_arm_goto_arg0[] = "arm";
265 parse_pgm_token_string_t cmd_arm_goto_arg0 = TOKEN_STRING_INITIALIZER(struct cmd_arm_goto_result, arg0, str_arm_goto_arg0);
266 prog_char str_arm_goto_arg1[] = "left#right#both";
267 parse_pgm_token_string_t cmd_arm_goto_arg1 = TOKEN_STRING_INITIALIZER(struct cmd_arm_goto_result, arg1, str_arm_goto_arg1);
268 parse_pgm_token_num_t cmd_arm_goto_arg2 = TOKEN_NUM_INITIALIZER(struct cmd_arm_goto_result, arg2, INT16);
269 parse_pgm_token_num_t cmd_arm_goto_arg3 = TOKEN_NUM_INITIALIZER(struct cmd_arm_goto_result, arg3, INT16);
270 parse_pgm_token_num_t cmd_arm_goto_arg4 = TOKEN_NUM_INITIALIZER(struct cmd_arm_goto_result, arg4, INT16);
271
272 prog_char help_arm_goto[] = "Arm goto d_mm,h_mm,w_deg";
273 parse_pgm_inst_t cmd_arm_goto = {
274         .f = cmd_arm_goto_parsed,  /* function to call */
275         .data = NULL,      /* 2nd arg of func */
276         .help_str = help_arm_goto,
277         .tokens = {        /* token list, NULL terminated */
278                 (prog_void *)&cmd_arm_goto_arg0,
279                 (prog_void *)&cmd_arm_goto_arg1,
280                 (prog_void *)&cmd_arm_goto_arg2,
281                 (prog_void *)&cmd_arm_goto_arg3,
282                 (prog_void *)&cmd_arm_goto_arg4,
283                 NULL,
284         },
285 };
286
287 /**********************************************************/
288 /* arm_goto_fixed */
289
290 /* this structure is filled when cmd_arm_goto_fixed is parsed successfully */
291 struct cmd_arm_goto_fixed_result {
292         fixed_string_t arg0;
293         fixed_string_t arg1;
294         fixed_string_t arg2;
295         fixed_string_t arg3;
296 };
297
298 /* function called when cmd_arm_goto_fixed is parsed successfully */
299 static void cmd_arm_goto_fixed_parsed(void *parsed_result, __attribute__((unused)) void *data)
300 {
301         struct cmd_arm_goto_fixed_result *res = parsed_result;
302         void (*f)(uint8_t, uint8_t) = NULL;
303         uint8_t err, pump_num = 0;
304
305         if (strcmp_P(res->arg2, PSTR("prepare")) == 0)
306                 f = arm_goto_prepare_get;
307         else if (strcmp_P(res->arg2, PSTR("get")) == 0)
308                 f = arm_goto_get_column;
309         else if (strcmp_P(res->arg2, PSTR("inter")) == 0)
310                 f = arm_goto_intermediate_get;
311         else if (strcmp_P(res->arg2, PSTR("inter")) == 0)
312                 f = arm_goto_straight;
313
314         if (f == NULL)
315                 return;
316
317         /* no matter if it's left or right here */
318         if (strcmp_P(res->arg3, PSTR("p1")) == 0)
319                 pump_num = PUMP_LEFT1_NUM;
320         if (strcmp_P(res->arg3, PSTR("p2")) == 0)
321                 pump_num = PUMP_LEFT2_NUM;
322
323         /* /!\ strcmp() inverted logic do handle "both" case */
324         if (strcmp_P(res->arg1, PSTR("right")))
325                 f(ARM_LEFT_NUM, pump_num);
326         if (strcmp_P(res->arg1, PSTR("left")))
327                 f(ARM_RIGHT_NUM, pump_num);
328
329         if (strcmp_P(res->arg1, PSTR("right"))) {
330                 err = arm_wait_traj_end(&left_arm, ARM_TRAJ_ALL);
331                 if (err != ARM_TRAJ_END)
332                         printf_P(PSTR("left err %x\r\n"), err);
333         }
334         if (strcmp_P(res->arg1, PSTR("left"))) {
335                 err = arm_wait_traj_end(&right_arm, ARM_TRAJ_ALL);
336                 if (err != ARM_TRAJ_END)
337                         printf_P(PSTR("right err %x\r\n"), err);
338         }
339 }
340
341 prog_char str_arm_goto_fixed_arg0[] = "arm";
342 parse_pgm_token_string_t cmd_arm_goto_fixed_arg0 = TOKEN_STRING_INITIALIZER(struct cmd_arm_goto_fixed_result, arg0, str_arm_goto_fixed_arg0);
343 prog_char str_arm_goto_fixed_arg1[] = "left#right#both";
344 parse_pgm_token_string_t cmd_arm_goto_fixed_arg1 = TOKEN_STRING_INITIALIZER(struct cmd_arm_goto_fixed_result, arg1, str_arm_goto_fixed_arg1);
345 prog_char str_arm_goto_fixed_arg2[] = "prepare#get#inter#straight";
346 parse_pgm_token_string_t cmd_arm_goto_fixed_arg2 = TOKEN_STRING_INITIALIZER(struct cmd_arm_goto_fixed_result, arg2, str_arm_goto_fixed_arg2);
347 prog_char str_arm_goto_fixed_arg3[] = "p1#p2";
348 parse_pgm_token_string_t cmd_arm_goto_fixed_arg3 = TOKEN_STRING_INITIALIZER(struct cmd_arm_goto_fixed_result, arg3, str_arm_goto_fixed_arg3);
349
350 prog_char help_arm_goto_fixed[] = "Goto fixed positions";
351 parse_pgm_inst_t cmd_arm_goto_fixed = {
352         .f = cmd_arm_goto_fixed_parsed,  /* function to call */
353         .data = NULL,      /* 2nd arg of func */
354         .help_str = help_arm_goto_fixed,
355         .tokens = {        /* token list, NULL terminated */
356                 (prog_void *)&cmd_arm_goto_fixed_arg0,
357                 (prog_void *)&cmd_arm_goto_fixed_arg1,
358                 (prog_void *)&cmd_arm_goto_fixed_arg2,
359                 (prog_void *)&cmd_arm_goto_fixed_arg3,
360                 NULL,
361         },
362 };
363
364 /**********************************************************/
365 /* arm_simulate */
366
367 /* this structure is filled when cmd_arm_simulate is parsed successfully */
368 struct cmd_arm_simulate_result {
369         fixed_string_t arg0;
370         fixed_string_t arg1;
371         fixed_string_t arg2;
372 };
373
374 /* function called when cmd_arm_simulate is parsed successfully */
375 static void cmd_arm_simulate_parsed(void *parsed_result, __attribute__((unused)) void *data)
376 {
377         struct cmd_arm_simulate_result *res = parsed_result;
378         uint8_t val;
379
380         if (strcmp_P(res->arg2, PSTR("simulate")) == 0)
381                 val = 1;
382         else
383                 val = 0;
384
385         if (strcmp_P(res->arg1, PSTR("left")) == 0)
386                 left_arm.config.simulate = 1;
387         else if (strcmp_P(res->arg1, PSTR("right")) == 0)
388                 right_arm.config.simulate = 1;
389         else {
390                 left_arm.config.simulate = 1;
391                 right_arm.config.simulate = 1;
392         }
393 }
394
395 prog_char str_arm_simulate_arg0[] = "arm";
396 parse_pgm_token_string_t cmd_arm_simulate_arg0 = TOKEN_STRING_INITIALIZER(struct cmd_arm_simulate_result, arg0, str_arm_simulate_arg0);
397 prog_char str_arm_simulate_arg1[] = "left#right#both";
398 parse_pgm_token_string_t cmd_arm_simulate_arg1 = TOKEN_STRING_INITIALIZER(struct cmd_arm_simulate_result, arg1, str_arm_simulate_arg1);
399 prog_char str_arm_simulate_arg2[] = "simulate#real";
400 parse_pgm_token_string_t cmd_arm_simulate_arg2 = TOKEN_STRING_INITIALIZER(struct cmd_arm_simulate_result, arg2, str_arm_simulate_arg2);
401
402 prog_char help_arm_simulate[] = "Simulation or real for arm";
403 parse_pgm_inst_t cmd_arm_simulate = {
404         .f = cmd_arm_simulate_parsed,  /* function to call */
405         .data = NULL,      /* 2nd arg of func */
406         .help_str = help_arm_simulate,
407         .tokens = {        /* token list, NULL terminated */
408                 (prog_void *)&cmd_arm_simulate_arg0,
409                 (prog_void *)&cmd_arm_simulate_arg1,
410                 (prog_void *)&cmd_arm_simulate_arg2,
411                 NULL,
412         },
413 };
414
415 /**********************************************************/
416 /* finger */
417
418 /* this structure is filled when cmd_finger is parsed successfully */
419 struct cmd_finger_result {
420         fixed_string_t arg0;
421         fixed_string_t arg1;
422 };
423
424 /* function called when cmd_finger is parsed successfully */
425 static void cmd_finger_parsed(void *parsed_result, __attribute__((unused)) void *data)
426 {
427         struct cmd_finger_result *res = parsed_result;
428         uint16_t dest = 0;
429
430         if (strcmp_P(res->arg1, PSTR("left")) == 0)
431                 dest = FINGER_LEFT;
432         else if (strcmp_P(res->arg1, PSTR("right")) == 0)
433                 dest = FINGER_RIGHT;
434         else if (strcmp_P(res->arg1, PSTR("center")) == 0)
435                 dest = FINGER_CENTER;
436         finger_goto(dest);
437 }
438
439 prog_char str_finger_arg0[] = "finger";
440 parse_pgm_token_string_t cmd_finger_arg0 = TOKEN_STRING_INITIALIZER(struct cmd_finger_result, arg0, str_finger_arg0);
441 prog_char str_finger_arg1[] = "left#right#center";
442 parse_pgm_token_string_t cmd_finger_arg1 = TOKEN_STRING_INITIALIZER(struct cmd_finger_result, arg1, str_finger_arg1);
443
444 prog_char help_finger[] = "Move finger";
445 parse_pgm_inst_t cmd_finger = {
446         .f = cmd_finger_parsed,  /* function to call */
447         .data = NULL,      /* 2nd arg of func */
448         .help_str = help_finger,
449         .tokens = {        /* token list, NULL terminated */
450                 (prog_void *)&cmd_finger_arg0,
451                 (prog_void *)&cmd_finger_arg1,
452                 NULL,
453         },
454 };
455
456 /**********************************************************/
457 /* pump */
458
459 /* this structure is filled when cmd_pump is parsed successfully */
460 struct cmd_pump_result {
461         fixed_string_t arg0;
462         fixed_string_t arg1;
463         fixed_string_t arg2;
464 };
465
466 /* function called when cmd_pump is parsed successfully */
467 static void cmd_pump_parsed(void *parsed_result, 
468                             __attribute__((unused)) void *data)
469 {
470         struct cmd_pump_result *res = parsed_result;
471         int8_t pump_num = 0;
472         int16_t val = 0;
473
474         if (strcmp_P(res->arg1, PSTR("left1")) == 0)
475                 pump_num = PUMP_LEFT1_NUM;
476         else if (strcmp_P(res->arg1, PSTR("right1")) == 0)
477                 pump_num = PUMP_RIGHT1_NUM;
478         else if (strcmp_P(res->arg1, PSTR("left2")) == 0)
479                 pump_num = PUMP_LEFT2_NUM;
480         else if (strcmp_P(res->arg1, PSTR("right2")) == 0)
481                 pump_num = PUMP_RIGHT2_NUM;
482
483         if (strcmp_P(res->arg2, PSTR("on")) == 0)
484                 val = PUMP_ON;
485         else if (strcmp_P(res->arg2, PSTR("off")) == 0)
486                 val = PUMP_OFF;
487         else if (strcmp_P(res->arg2, PSTR("reverse")) == 0)
488                 val = PUMP_REVERSE;
489
490         pump_set(pump_num, val);
491 }
492
493 prog_char str_pump_arg0[] = "pump";
494 parse_pgm_token_string_t cmd_pump_arg0 = TOKEN_STRING_INITIALIZER(struct cmd_pump_result, arg0, str_pump_arg0);
495 prog_char str_pump_arg1[] = "left1#left2#right1#right2";
496 parse_pgm_token_string_t cmd_pump_arg1 = TOKEN_STRING_INITIALIZER(struct cmd_pump_result, arg1, str_pump_arg1);
497 prog_char str_pump_arg2[] = "on#off#reverse";
498 parse_pgm_token_string_t cmd_pump_arg2 = TOKEN_STRING_INITIALIZER(struct cmd_pump_result, arg2, str_pump_arg2);
499
500 prog_char help_pump[] = "activate pump";
501 parse_pgm_inst_t cmd_pump = {
502         .f = cmd_pump_parsed,  /* function to call */
503         .data = NULL,      /* 2nd arg of func */
504         .help_str = help_pump,
505         .tokens = {        /* token list, NULL terminated */
506                 (prog_void *)&cmd_pump_arg0,
507                 (prog_void *)&cmd_pump_arg1,
508                 (prog_void *)&cmd_pump_arg2,
509                 NULL,
510         },
511 };
512
513 /**********************************************************/
514 /* State1 */
515
516 /* this structure is filled when cmd_state1 is parsed successfully */
517 struct cmd_state1_result {
518         fixed_string_t arg0;
519         fixed_string_t arg1;
520 };
521
522 /* function called when cmd_state1 is parsed successfully */
523 static void cmd_state1_parsed(void *parsed_result,
524                               __attribute__((unused)) void *data)
525 {
526         struct cmd_state1_result *res = parsed_result;
527         struct i2c_cmd_mechboard_set_mode command;
528
529         if (!strcmp_P(res->arg1, PSTR("init"))) {
530                 state_init();
531                 return;
532         }
533
534         if (!strcmp_P(res->arg1, PSTR("manual")))
535                 command.mode = I2C_MECHBOARD_MODE_MANUAL;
536         else if (!strcmp_P(res->arg1, PSTR("harvest")))
537                 command.mode = I2C_MECHBOARD_MODE_HARVEST;
538         else if (!strcmp_P(res->arg1, PSTR("lazy_harvest")))
539                 command.mode = I2C_MECHBOARD_MODE_LAZY_HARVEST;
540         else if (!strcmp_P(res->arg1, PSTR("pickup")))
541                 command.mode = I2C_MECHBOARD_MODE_PICKUP;
542         else if (!strcmp_P(res->arg1, PSTR("prepare_get_lintel")))
543                 command.mode = I2C_MECHBOARD_MODE_PREPARE_GET_LINTEL;
544         else if (!strcmp_P(res->arg1, PSTR("get_lintel")))
545                 command.mode = I2C_MECHBOARD_MODE_GET_LINTEL;
546         else if (!strcmp_P(res->arg1, PSTR("put_lintel")))
547                 command.mode = I2C_MECHBOARD_MODE_PUT_LINTEL;
548         else if (!strcmp_P(res->arg1, PSTR("clear")))
549                 command.mode = I2C_MECHBOARD_MODE_CLEAR;
550         else if (!strcmp_P(res->arg1, PSTR("loaded")))
551                 command.mode = I2C_MECHBOARD_MODE_LOADED;
552         else if (!strcmp_P(res->arg1, PSTR("store")))
553                 command.mode = I2C_MECHBOARD_MODE_STORE;
554         else if (!strcmp_P(res->arg1, PSTR("lazy_pickup")))
555                 command.mode = I2C_MECHBOARD_MODE_LAZY_PICKUP;
556         state_set_mode(&command);
557 }
558
559 prog_char str_state1_arg0[] = "mechboard";
560 parse_pgm_token_string_t cmd_state1_arg0 = TOKEN_STRING_INITIALIZER(struct cmd_state1_result, arg0, str_state1_arg0);
561 prog_char str_state1_arg1[] = "init#manual#pickup#prepare_get_lintel#get_lintel#put_lintel#clear#lazy_harvest#harvest#loaded#store#lazy_pickup";
562 parse_pgm_token_string_t cmd_state1_arg1 = TOKEN_STRING_INITIALIZER(struct cmd_state1_result, arg1, str_state1_arg1);
563
564 prog_char help_state1[] = "set mechboard mode";
565 parse_pgm_inst_t cmd_state1 = {
566         .f = cmd_state1_parsed,  /* function to call */
567         .data = NULL,      /* 2nd arg of func */
568         .help_str = help_state1,
569         .tokens = {        /* token list, NULL terminated */
570                 (prog_void *)&cmd_state1_arg0, 
571                 (prog_void *)&cmd_state1_arg1, 
572                 NULL,
573         },
574 };
575
576 /**********************************************************/
577 /* State2 */
578
579 /* this structure is filled when cmd_state2 is parsed successfully */
580 struct cmd_state2_result {
581         fixed_string_t arg0;
582         fixed_string_t arg1;
583         fixed_string_t arg2;
584 };
585
586 /* function called when cmd_state2 is parsed successfully */
587 static void cmd_state2_parsed(void *parsed_result,
588                               __attribute__((unused)) void *data)
589 {
590         struct cmd_state2_result *res = parsed_result;
591         struct i2c_cmd_mechboard_set_mode command;
592         uint8_t side;
593
594         if (!strcmp_P(res->arg2, PSTR("left")))
595                 side = I2C_LEFT_SIDE;
596         else if (!strcmp_P(res->arg2, PSTR("right")))
597                 side = I2C_RIGHT_SIDE;
598         else if (!strcmp_P(res->arg2, PSTR("center")))
599                 side = I2C_CENTER_SIDE;
600         else
601                 side = I2C_AUTO_SIDE;
602
603         if (!strcmp_P(res->arg1, PSTR("prepare_pickup"))) {
604                 command.mode = I2C_MECHBOARD_MODE_PREPARE_PICKUP;
605                 command.prep_pickup.side = side;
606                 command.prep_pickup.next_mode = I2C_MECHBOARD_MODE_PREPARE_PICKUP;
607         }
608         else if (!strcmp_P(res->arg1, PSTR("push_temple_disc"))) {
609                 command.mode = I2C_MECHBOARD_MODE_PUSH_TEMPLE_DISC;
610                 command.push_temple_disc.side = side;
611         }
612
613
614         state_set_mode(&command);
615 }
616
617 prog_char str_state2_arg0[] = "mechboard";
618 parse_pgm_token_string_t cmd_state2_arg0 = TOKEN_STRING_INITIALIZER(struct cmd_state2_result, arg0, str_state2_arg0);
619 prog_char str_state2_arg1[] = "prepare_pickup#push_temple_disc";
620 parse_pgm_token_string_t cmd_state2_arg1 = TOKEN_STRING_INITIALIZER(struct cmd_state2_result, arg1, str_state2_arg1);
621 prog_char str_state2_arg2[] = "left#right#auto#center";
622 parse_pgm_token_string_t cmd_state2_arg2 = TOKEN_STRING_INITIALIZER(struct cmd_state2_result, arg2, str_state2_arg2);
623
624 prog_char help_state2[] = "set mechboard mode";
625 parse_pgm_inst_t cmd_state2 = {
626         .f = cmd_state2_parsed,  /* function to call */
627         .data = NULL,      /* 2nd arg of func */
628         .help_str = help_state2,
629         .tokens = {        /* token list, NULL terminated */
630                 (prog_void *)&cmd_state2_arg0, 
631                 (prog_void *)&cmd_state2_arg1, 
632                 (prog_void *)&cmd_state2_arg2, 
633                 NULL,
634         },
635 };
636
637 /**********************************************************/
638 /* State3 */
639
640 /* this structure is filled when cmd_state3 is parsed successfully */
641 struct cmd_state3_result {
642         fixed_string_t arg0;
643         fixed_string_t arg1;
644         uint8_t level;
645 };
646
647 /* function called when cmd_state3 is parsed successfully */
648 static void cmd_state3_parsed(void *parsed_result, 
649                               __attribute__((unused)) void *data)
650 {
651         struct cmd_state3_result *res = parsed_result;
652         struct i2c_cmd_mechboard_set_mode command;
653
654         if (!strcmp_P(res->arg1, PSTR("prepare_build"))) {
655                 command.mode = I2C_MECHBOARD_MODE_PREPARE_BUILD;
656                 command.prep_build.level_l = res->level;
657                 command.prep_build.level_r = res->level;
658         }
659         else if (!strcmp_P(res->arg1, PSTR("prepare_inside"))) {
660                 command.mode = I2C_MECHBOARD_MODE_PREPARE_INSIDE;
661                 command.prep_inside.level_l = res->level;
662                 command.prep_inside.level_r = res->level;
663         }
664         else if (!strcmp_P(res->arg1, PSTR("autobuild"))) {
665                 command.mode = I2C_MECHBOARD_MODE_AUTOBUILD;
666                 command.autobuild.level_left = res->level;
667                 command.autobuild.level_right = res->level;
668                 command.autobuild.count_left = 2;
669                 command.autobuild.count_right = 2;
670                 command.autobuild.distance_left = I2C_AUTOBUILD_DEFAULT_DIST;
671                 command.autobuild.distance_right = I2C_AUTOBUILD_DEFAULT_DIST;
672                 command.autobuild.do_lintel = 1;
673         }
674         else if (!strcmp_P(res->arg1, PSTR("push_temple"))) {
675                 command.mode = I2C_MECHBOARD_MODE_PUSH_TEMPLE;
676                 command.push_temple.level = res->level;
677         }
678         state_set_mode(&command);
679 }
680
681 prog_char str_state3_arg0[] = "mechboard";
682 parse_pgm_token_string_t cmd_state3_arg0 = TOKEN_STRING_INITIALIZER(struct cmd_state3_result, arg0, str_state3_arg0);
683 prog_char str_state3_arg1[] = "prepare_build#autobuild#prepare_inside";
684 parse_pgm_token_string_t cmd_state3_arg1 = TOKEN_STRING_INITIALIZER(struct cmd_state3_result, arg1, str_state3_arg1);
685 parse_pgm_token_num_t cmd_state3_arg2 = TOKEN_NUM_INITIALIZER(struct cmd_state3_result, level, UINT8);
686
687 prog_char help_state3[] = "set mechboard mode";
688 parse_pgm_inst_t cmd_state3 = {
689         .f = cmd_state3_parsed,  /* function to call */
690         .data = NULL,      /* 2nd arg of func */
691         .help_str = help_state3,
692         .tokens = {        /* token list, NULL terminated */
693                 (prog_void *)&cmd_state3_arg0, 
694                 (prog_void *)&cmd_state3_arg1, 
695                 (prog_void *)&cmd_state3_arg2, 
696                 NULL,
697         },
698 };
699
700 /**********************************************************/
701 /* State4 */
702
703 /* this structure is filled when cmd_state4 is parsed successfully */
704 struct cmd_state4_result {
705         fixed_string_t arg0;
706         fixed_string_t arg1;
707         uint8_t level_l;
708         uint8_t count_l;
709         uint8_t dist_l;
710         uint8_t level_r;
711         uint8_t count_r;
712         uint8_t dist_r;
713         uint8_t do_lintel;
714 };
715
716 /* function called when cmd_state4 is parsed successfully */
717 static void cmd_state4_parsed(void *parsed_result, 
718                               __attribute__((unused)) void *data)
719 {
720         struct cmd_state4_result *res = parsed_result;
721         struct i2c_cmd_mechboard_set_mode command;
722
723         if (!strcmp_P(res->arg1, PSTR("autobuild"))) {
724                 command.mode = I2C_MECHBOARD_MODE_AUTOBUILD;
725                 command.autobuild.distance_left = res->dist_l;
726                 command.autobuild.distance_right = res->dist_r;
727                 command.autobuild.level_left = res->level_l;
728                 command.autobuild.level_right = res->level_r;
729                 command.autobuild.count_left = res->count_l;
730                 command.autobuild.count_right = res->count_r;
731                 command.autobuild.do_lintel = res->do_lintel;
732         }
733         state_set_mode(&command);
734 }
735
736 prog_char str_state4_arg0[] = "mechboard";
737 parse_pgm_token_string_t cmd_state4_arg0 = TOKEN_STRING_INITIALIZER(struct cmd_state4_result, arg0, str_state4_arg0);
738 prog_char str_state4_arg1[] = "autobuild";
739 parse_pgm_token_string_t cmd_state4_arg1 = TOKEN_STRING_INITIALIZER(struct cmd_state4_result, arg1, str_state4_arg1);
740 parse_pgm_token_num_t cmd_state4_arg2 = TOKEN_NUM_INITIALIZER(struct cmd_state4_result, level_l, UINT8);
741 parse_pgm_token_num_t cmd_state4_arg3 = TOKEN_NUM_INITIALIZER(struct cmd_state4_result, count_l, UINT8);
742 parse_pgm_token_num_t cmd_state4_arg4 = TOKEN_NUM_INITIALIZER(struct cmd_state4_result, dist_l, UINT8);
743 parse_pgm_token_num_t cmd_state4_arg5 = TOKEN_NUM_INITIALIZER(struct cmd_state4_result, level_r, UINT8);
744 parse_pgm_token_num_t cmd_state4_arg6 = TOKEN_NUM_INITIALIZER(struct cmd_state4_result, count_r, UINT8);
745 parse_pgm_token_num_t cmd_state4_arg7 = TOKEN_NUM_INITIALIZER(struct cmd_state4_result, dist_r, UINT8);
746 parse_pgm_token_num_t cmd_state4_arg8 = TOKEN_NUM_INITIALIZER(struct cmd_state4_result, do_lintel, UINT8);
747
748 prog_char help_state4[] = "set mechboard mode (autobuild level_l count_l dist_l level_r count_r dist_r lintel)";
749 parse_pgm_inst_t cmd_state4 = {
750         .f = cmd_state4_parsed,  /* function to call */
751         .data = NULL,      /* 2nd arg of func */
752         .help_str = help_state4,
753         .tokens = {        /* token list, NULL terminated */
754                 (prog_void *)&cmd_state4_arg0, 
755                 (prog_void *)&cmd_state4_arg1, 
756                 (prog_void *)&cmd_state4_arg2, 
757                 (prog_void *)&cmd_state4_arg3, 
758                 (prog_void *)&cmd_state4_arg4, 
759                 (prog_void *)&cmd_state4_arg5, 
760                 (prog_void *)&cmd_state4_arg6, 
761                 (prog_void *)&cmd_state4_arg7, 
762                 (prog_void *)&cmd_state4_arg8, 
763                 NULL,
764         },
765 };
766
767 /**********************************************************/
768 /* State5 */
769
770 /* this structure is filled when cmd_state5 is parsed successfully */
771 struct cmd_state5_result {
772         fixed_string_t arg0;
773         fixed_string_t arg1;
774         fixed_string_t arg2;
775         fixed_string_t arg3;
776 };
777
778 /* function called when cmd_state5 is parsed successfully */
779 static void cmd_state5_parsed(void *parsed_result,
780                               __attribute__((unused)) void *data)
781 {
782         struct cmd_state5_result *res = parsed_result;
783         struct i2c_cmd_mechboard_set_mode command;
784         uint8_t side;
785
786         if (!strcmp_P(res->arg2, PSTR("left")))
787                 side = I2C_LEFT_SIDE;
788         else if (!strcmp_P(res->arg2, PSTR("right")))
789                 side = I2C_RIGHT_SIDE;
790         else if (!strcmp_P(res->arg2, PSTR("center")))
791                 side = I2C_CENTER_SIDE;
792         else
793                 side = I2C_AUTO_SIDE;
794
795         command.mode = I2C_MECHBOARD_MODE_PREPARE_PICKUP;
796         command.prep_pickup.side = side;
797
798         if (!strcmp_P(res->arg3, PSTR("harvest")))
799                 command.prep_pickup.next_mode = I2C_MECHBOARD_MODE_HARVEST;
800         else if (!strcmp_P(res->arg3, PSTR("lazy_harvest")))
801                 command.prep_pickup.next_mode = I2C_MECHBOARD_MODE_LAZY_HARVEST;
802         else if (!strcmp_P(res->arg3, PSTR("pickup")))
803                 command.prep_pickup.next_mode = I2C_MECHBOARD_MODE_PICKUP;
804         else if (!strcmp_P(res->arg3, PSTR("clear")))
805                 command.prep_pickup.next_mode = I2C_MECHBOARD_MODE_CLEAR;
806         else if (!strcmp_P(res->arg3, PSTR("store")))
807                 command.prep_pickup.next_mode = I2C_MECHBOARD_MODE_STORE;
808         else if (!strcmp_P(res->arg3, PSTR("lazy_pickup")))
809                 command.prep_pickup.next_mode = I2C_MECHBOARD_MODE_LAZY_PICKUP;
810
811         state_set_mode(&command);
812 }
813
814 prog_char str_state5_arg0[] = "mechboard";
815 parse_pgm_token_string_t cmd_state5_arg0 = TOKEN_STRING_INITIALIZER(struct cmd_state5_result, arg0, str_state5_arg0);
816 prog_char str_state5_arg1[] = "prepare_pickup";
817 parse_pgm_token_string_t cmd_state5_arg1 = TOKEN_STRING_INITIALIZER(struct cmd_state5_result, arg1, str_state5_arg1);
818 prog_char str_state5_arg2[] = "left#right#auto#center";
819 parse_pgm_token_string_t cmd_state5_arg2 = TOKEN_STRING_INITIALIZER(struct cmd_state5_result, arg2, str_state5_arg2);
820 prog_char str_state5_arg3[] = "harvest#pickup#store#lazy_harvest#lazy_pickup#clear";
821 parse_pgm_token_string_t cmd_state5_arg3 = TOKEN_STRING_INITIALIZER(struct cmd_state5_result, arg3, str_state5_arg3);
822
823 prog_char help_state5[] = "set mechboard mode 2";
824 parse_pgm_inst_t cmd_state5 = {
825         .f = cmd_state5_parsed,  /* function to call */
826         .data = NULL,      /* 2nd arg of func */
827         .help_str = help_state5,
828         .tokens = {        /* token list, NULL terminated */
829                 (prog_void *)&cmd_state5_arg0, 
830                 (prog_void *)&cmd_state5_arg1, 
831                 (prog_void *)&cmd_state5_arg2, 
832                 (prog_void *)&cmd_state5_arg3, 
833                 NULL,
834         },
835 };
836
837 /**********************************************************/
838 /* State_Machine */
839
840 /* this structure is filled when cmd_state_machine is parsed successfully */
841 struct cmd_state_machine_result {
842         fixed_string_t arg0;
843 };
844
845 /* function called when cmd_state_machine is parsed successfully */
846 static void cmd_state_machine_parsed(__attribute__((unused)) void *parsed_result,
847                                      __attribute__((unused)) void *data)
848 {
849         state_machine();
850 }
851
852 prog_char str_state_machine_arg0[] = "state_machine";
853 parse_pgm_token_string_t cmd_state_machine_arg0 = TOKEN_STRING_INITIALIZER(struct cmd_state_machine_result, arg0, str_state_machine_arg0);
854
855 prog_char help_state_machine[] = "launch state machine";
856 parse_pgm_inst_t cmd_state_machine = {
857         .f = cmd_state_machine_parsed,  /* function to call */
858         .data = NULL,      /* 2nd arg of func */
859         .help_str = help_state_machine,
860         .tokens = {        /* token list, NULL terminated */
861                 (prog_void *)&cmd_state_machine_arg0, 
862                 NULL,
863         },
864 };
865
866 /**********************************************************/
867 /* State_Debug */
868
869 /* this structure is filled when cmd_state_debug is parsed successfully */
870 struct cmd_state_debug_result {
871         fixed_string_t arg0;
872         uint8_t on;
873 };
874
875 /* function called when cmd_state_debug is parsed successfully */
876 static void cmd_state_debug_parsed(void *parsed_result,
877                                    __attribute__((unused)) void *data)
878 {
879         struct cmd_state_debug_result *res = parsed_result;
880         state_debug = res->on;
881 }
882
883 prog_char str_state_debug_arg0[] = "state_debug";
884 parse_pgm_token_string_t cmd_state_debug_arg0 = TOKEN_STRING_INITIALIZER(struct cmd_state_debug_result, arg0, str_state_debug_arg0);
885 parse_pgm_token_num_t cmd_state_debug_on = TOKEN_NUM_INITIALIZER(struct cmd_state_debug_result, on, UINT8);
886
887 prog_char help_state_debug[] = "Set debug timer for state machine";
888 parse_pgm_inst_t cmd_state_debug = {
889         .f = cmd_state_debug_parsed,  /* function to call */
890         .data = NULL,      /* 2nd arg of func */
891         .help_str = help_state_debug,
892         .tokens = {        /* token list, NULL terminated */
893                 (prog_void *)&cmd_state_debug_arg0, 
894                 (prog_void *)&cmd_state_debug_on, 
895                 NULL,
896         },
897 };
898
899 /**********************************************************/
900 /* Servo_Lintel */
901
902 /* this structure is filled when cmd_servo_lintel is parsed successfully */
903 struct cmd_servo_lintel_result {
904         fixed_string_t arg0;
905         fixed_string_t arg1;
906 };
907
908 /* function called when cmd_servo_lintel is parsed successfully */
909 static void cmd_servo_lintel_parsed(void *parsed_result,
910                                     __attribute__((unused)) void *data)
911 {
912         struct cmd_servo_lintel_result *res = parsed_result;
913         if (!strcmp_P(res->arg1, PSTR("out")))
914                 servo_lintel_out();
915         else if (!strcmp_P(res->arg1, PSTR("1lin")))
916                 servo_lintel_1lin();
917         else if (!strcmp_P(res->arg1, PSTR("2lin")))
918                 servo_lintel_2lin();
919         
920 }
921
922 prog_char str_servo_lintel_arg0[] = "servo_lintel";
923 parse_pgm_token_string_t cmd_servo_lintel_arg0 = TOKEN_STRING_INITIALIZER(struct cmd_servo_lintel_result, arg0, str_servo_lintel_arg0);
924 prog_char str_servo_lintel_arg1[] = "out#1lin#2lin";
925 parse_pgm_token_string_t cmd_servo_lintel_arg1 = TOKEN_STRING_INITIALIZER(struct cmd_servo_lintel_result, arg1, str_servo_lintel_arg1);
926
927 prog_char help_servo_lintel[] = "Servo_Lintel function";
928 parse_pgm_inst_t cmd_servo_lintel = {
929         .f = cmd_servo_lintel_parsed,  /* function to call */
930         .data = NULL,      /* 2nd arg of func */
931         .help_str = help_servo_lintel,
932         .tokens = {        /* token list, NULL terminated */
933                 (prog_void *)&cmd_servo_lintel_arg0, 
934                 (prog_void *)&cmd_servo_lintel_arg1, 
935                 NULL,
936         },
937 };
938
939 /**********************************************************/
940 /* Pump_Current */
941
942 /* this structure is filled when cmd_pump_current is parsed successfully */
943 struct cmd_pump_current_result {
944         fixed_string_t arg0;
945         fixed_string_t arg1;
946 };
947
948 /* function called when cmd_pump_current is parsed successfully */
949 static void cmd_pump_current_parsed(__attribute__((unused)) void *parsed_result,
950                                     __attribute__((unused)) void *data)
951 {
952         printf_P(PSTR("l1=%d l2=%d r1=%d r2=%d\r\n"),
953                  mechboard.pump_left1_current, mechboard.pump_left2_current,
954                  sensor_get_adc(ADC_CSENSE3), sensor_get_adc(ADC_CSENSE4));
955 }
956
957 prog_char str_pump_current_arg0[] = "pump_current";
958 parse_pgm_token_string_t cmd_pump_current_arg0 = TOKEN_STRING_INITIALIZER(struct cmd_pump_current_result, arg0, str_pump_current_arg0);
959 prog_char str_pump_current_arg1[] = "show";
960 parse_pgm_token_string_t cmd_pump_current_arg1 = TOKEN_STRING_INITIALIZER(struct cmd_pump_current_result, arg1, str_pump_current_arg1);
961
962 prog_char help_pump_current[] = "dump pump current";
963 parse_pgm_inst_t cmd_pump_current = {
964         .f = cmd_pump_current_parsed,  /* function to call */
965         .data = NULL,      /* 2nd arg of func */
966         .help_str = help_pump_current,
967         .tokens = {        /* token list, NULL terminated */
968                 (prog_void *)&cmd_pump_current_arg0, 
969                 (prog_void *)&cmd_pump_current_arg1, 
970                 NULL,
971         },
972 };
973
974 /**********************************************************/
975 /* Manivelle */
976
977 /* this structure is filled when cmd_manivelle is parsed successfully */
978 struct cmd_manivelle_result {
979         fixed_string_t arg0;
980         uint8_t step;
981 };
982
983 /* function called when cmd_manivelle is parsed successfully */
984 static void cmd_manivelle_parsed(__attribute__((unused)) void *parsed_result,
985                                  __attribute__((unused)) void *data)
986 {
987         struct cmd_manivelle_result *res = parsed_result;
988         state_manivelle(res->step);
989 }
990
991 prog_char str_manivelle_arg0[] = "manivelle";
992 parse_pgm_token_string_t cmd_manivelle_arg0 = TOKEN_STRING_INITIALIZER(struct cmd_manivelle_result, arg0, str_manivelle_arg0);
993 parse_pgm_token_num_t cmd_manivelle_arg1 = TOKEN_NUM_INITIALIZER(struct cmd_manivelle_result, step, UINT8);
994
995 prog_char help_manivelle[] = "Manivelle function";
996 parse_pgm_inst_t cmd_manivelle = {
997         .f = cmd_manivelle_parsed,  /* function to call */
998         .data = NULL,      /* 2nd arg of func */
999         .help_str = help_manivelle,
1000         .tokens = {        /* token list, NULL terminated */
1001                 (prog_void *)&cmd_manivelle_arg0, 
1002                 (prog_void *)&cmd_manivelle_arg1, 
1003                 NULL,
1004         },
1005 };
1006
1007 /**********************************************************/
1008 /* Test */
1009
1010 /* this structure is filled when cmd_test is parsed successfully */
1011 struct cmd_test_result {
1012         fixed_string_t arg0;
1013 };
1014
1015 /* function called when cmd_test is parsed successfully */
1016 static void cmd_test_parsed(__attribute__((unused)) void *parsed_result,
1017                             __attribute__((unused)) void *data)
1018 {
1019 }
1020
1021 prog_char str_test_arg0[] = "test";
1022 parse_pgm_token_string_t cmd_test_arg0 = TOKEN_STRING_INITIALIZER(struct cmd_test_result, arg0, str_test_arg0);
1023
1024 prog_char help_test[] = "Test function";
1025 parse_pgm_inst_t cmd_test = {
1026         .f = cmd_test_parsed,  /* function to call */
1027         .data = NULL,      /* 2nd arg of func */
1028         .help_str = help_test,
1029         .tokens = {        /* token list, NULL terminated */
1030                 (prog_void *)&cmd_test_arg0, 
1031                 NULL,
1032         },
1033 };