microb 2010
[aversive.git] / projects / microb2010 / tests / test_board2008 / commands_gen.c
1 /*
2  *  Copyright Droids Corporation (2008)
3  * 
4  *  This program is free software; you can redistribute it and/or modify
5  *  it under the terms of the GNU General Public License as published by
6  *  the Free Software Foundation; either version 2 of the License, or
7  *  (at your option) any later version.
8  *
9  *  This program is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *  GNU General Public License for more details.
13  *
14  *  You should have received a copy of the GNU General Public License
15  *  along with this program; if not, write to the Free Software
16  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17  *
18  *  Revision : $Id: commands_gen.c,v 1.6 2009-05-02 10:08:09 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 <uart.h>
31 #include <pwm_ng.h>
32 #include <time.h>
33 #include <encoders_microb.h>
34 #include <adc.h>
35
36 #include <scheduler.h>
37 #include <scheduler_stats.h>
38 #include <pid.h>
39 #include <quadramp.h>
40 #include <control_system_manager.h>
41 #include <trajectory_manager.h>
42 #include <blocking_detection_manager.h>
43 #include <robot_system.h>
44 #include <position_manager.h>
45
46 #include <rdline.h>
47 #include <parse.h>
48 #include <parse_string.h>
49 #include <parse_num.h>
50
51 #include <diagnostic.h>
52
53 #include "main.h"
54 #include "cmdline.h"
55 #include "sensor.h"
56
57 #include "action.h"
58
59 /**********************************************************/
60 /* Reset */
61
62 /* this structure is filled when cmd_reset is parsed successfully */
63 struct cmd_reset_result {
64         fixed_string_t arg0;
65 };
66
67 /* function called when cmd_reset is parsed successfully */
68 static void cmd_reset_parsed(void * parsed_result, void * data)
69 {
70         reset();
71 }
72
73 prog_char str_reset_arg0[] = "reset";
74 parse_pgm_token_string_t cmd_reset_arg0 = TOKEN_STRING_INITIALIZER(struct cmd_reset_result, arg0, str_reset_arg0);
75
76 prog_char help_reset[] = "Reset the board";
77 parse_pgm_inst_t cmd_reset = {
78         .f = cmd_reset_parsed,  /* function to call */
79         .data = NULL,      /* 2nd arg of func */
80         .help_str = help_reset,
81         .tokens = {        /* token list, NULL terminated */
82                 (prog_void *)&cmd_reset_arg0, 
83                 NULL,
84         },
85 };
86
87 /**********************************************************/
88 /* Bootloader */
89
90 /* this structure is filled when cmd_bootloader is parsed successfully */
91 struct cmd_bootloader_result {
92         fixed_string_t arg0;
93 };
94
95 /* function called when cmd_bootloader is parsed successfully */
96 static void cmd_bootloader_parsed(void *parsed_result, void *data)
97 {
98         //bootloader();
99 }
100
101 prog_char str_bootloader_arg0[] = "bootloader";
102 parse_pgm_token_string_t cmd_bootloader_arg0 = TOKEN_STRING_INITIALIZER(struct cmd_bootloader_result, arg0, str_bootloader_arg0);
103
104 prog_char help_bootloader[] = "Launch the bootloader";
105 parse_pgm_inst_t cmd_bootloader = {
106         .f = cmd_bootloader_parsed,  /* function to call */
107         .data = NULL,      /* 2nd arg of func */
108         .help_str = help_bootloader,
109         .tokens = {        /* token list, NULL terminated */
110                 (prog_void *)&cmd_bootloader_arg0, 
111                 NULL,
112         },
113 };
114
115 /**********************************************************/
116 /* Encoders tests */
117
118 /* this structure is filled when cmd_encoders is parsed successfully */
119 struct cmd_encoders_result {
120         fixed_string_t arg0;
121         fixed_string_t arg1;
122 };
123
124 /* function called when cmd_encoders is parsed successfully */
125 static void cmd_encoders_parsed(void *parsed_result, void *data)
126 {
127         struct cmd_encoders_result *res = parsed_result;
128
129         if (!strcmp_P(res->arg1, PSTR("reset"))) {
130                 encoders_microb_set_value((void *)0, 0);
131                 encoders_microb_set_value((void *)1, 0);
132                 encoders_microb_set_value((void *)2, 0);
133                 encoders_microb_set_value((void *)3, 0);
134                 return;
135         }
136
137         /* show */
138         while(!cmdline_keypressed()) {
139                 printf_P(PSTR("% .8ld % .8ld % .8ld % .8ld\r\n"), 
140                          encoders_microb_get_value((void *)0),
141                          encoders_microb_get_value((void *)1),
142                          encoders_microb_get_value((void *)2),
143                          encoders_microb_get_value((void *)3));
144                 wait_ms(100);
145         }
146 }
147
148 prog_char str_encoders_arg0[] = "encoders";
149 parse_pgm_token_string_t cmd_encoders_arg0 = TOKEN_STRING_INITIALIZER(struct cmd_encoders_result, arg0, str_encoders_arg0);
150 prog_char str_encoders_arg1[] = "show#reset";
151 parse_pgm_token_string_t cmd_encoders_arg1 = TOKEN_STRING_INITIALIZER(struct cmd_encoders_result, arg1, str_encoders_arg1);
152
153 prog_char help_encoders[] = "Show encoders values";
154 parse_pgm_inst_t cmd_encoders = {
155         .f = cmd_encoders_parsed,  /* function to call */
156         .data = NULL,      /* 2nd arg of func */
157         .help_str = help_encoders,
158         .tokens = {        /* token list, NULL terminated */
159                 (prog_void *)&cmd_encoders_arg0, 
160                 (prog_void *)&cmd_encoders_arg1, 
161                 NULL,
162         },
163 };
164
165 /**********************************************************/
166 /* Scheduler show */
167
168 /* this structure is filled when cmd_scheduler is parsed successfully */
169 struct cmd_scheduler_result {
170         fixed_string_t arg0;
171         fixed_string_t arg1;
172 };
173
174 /* function called when cmd_scheduler is parsed successfully */
175 static void cmd_scheduler_parsed(void *parsed_result, void *data)
176 {
177         scheduler_dump_events();
178         scheduler_stats_dump();
179 }
180
181 prog_char str_scheduler_arg0[] = "scheduler";
182 parse_pgm_token_string_t cmd_scheduler_arg0 = TOKEN_STRING_INITIALIZER(struct cmd_scheduler_result, arg0, str_scheduler_arg0);
183 prog_char str_scheduler_arg1[] = "show";
184 parse_pgm_token_string_t cmd_scheduler_arg1 = TOKEN_STRING_INITIALIZER(struct cmd_scheduler_result, arg1, str_scheduler_arg1);
185
186 prog_char help_scheduler[] = "Show scheduler events";
187 parse_pgm_inst_t cmd_scheduler = {
188         .f = cmd_scheduler_parsed,  /* function to call */
189         .data = NULL,      /* 2nd arg of func */
190         .help_str = help_scheduler,
191         .tokens = {        /* token list, NULL terminated */
192                 (prog_void *)&cmd_scheduler_arg0, 
193                 (prog_void *)&cmd_scheduler_arg1, 
194                 NULL,
195         },
196 };
197
198 /**********************************************************/
199 /* Pwms tests */
200
201 /* this structure is filled when cmd_pwm is parsed successfully */
202 struct cmd_pwm_result {
203         fixed_string_t arg0;
204         fixed_string_t arg1;
205         int16_t arg2;
206 };
207
208 /* function called when cmd_pwm is parsed successfully */
209 static void cmd_pwm_parsed(void * parsed_result, void * data)
210 {
211         void * pwm_ptr = NULL;
212         struct cmd_pwm_result * res = parsed_result;
213         
214         if (!strcmp_P(res->arg1, PSTR("1(1A)")))
215                 pwm_ptr = &gen.pwm1_1A;
216         else if (!strcmp_P(res->arg1, PSTR("2(1B)")))
217                 pwm_ptr = &gen.pwm2_1B;
218         else if (!strcmp_P(res->arg1, PSTR("3(3A)")))
219                 pwm_ptr = &gen.pwm3_3A;
220         else if (!strcmp_P(res->arg1, PSTR("4(3B)")))
221                 pwm_ptr = &gen.pwm4_3B;
222
223         if (pwm_ptr)
224                 pwm_ng_set(pwm_ptr, res->arg2);
225
226         printf_P(PSTR("done %p\r\n"), pwm_ptr);
227 }
228
229 prog_char str_pwm_arg0[] = "pwm";
230 parse_pgm_token_string_t cmd_pwm_arg0 = TOKEN_STRING_INITIALIZER(struct cmd_pwm_result, arg0, str_pwm_arg0);
231 prog_char str_pwm_arg1[] = "1(1A)#2(1B)#3(3A)#4(3B)";
232 parse_pgm_token_string_t cmd_pwm_arg1 = TOKEN_STRING_INITIALIZER(struct cmd_pwm_result, arg1, str_pwm_arg1);
233 parse_pgm_token_num_t cmd_pwm_arg2 = TOKEN_NUM_INITIALIZER(struct cmd_pwm_result, arg2, INT16);
234
235 prog_char help_pwm[] = "Set pwm values [-4096 ; 4095]";
236 parse_pgm_inst_t cmd_pwm = {
237         .f = cmd_pwm_parsed,  /* function to call */
238         .data = NULL,      /* 2nd arg of func */
239         .help_str = help_pwm,
240         .tokens = {        /* token list, NULL terminated */
241                 (prog_void *)&cmd_pwm_arg0, 
242                 (prog_void *)&cmd_pwm_arg1, 
243                 (prog_void *)&cmd_pwm_arg2, 
244                 NULL,
245         },
246 };
247
248 /**********************************************************/
249 /* Adcs tests */
250
251 /* this structure is filled when cmd_adc is parsed successfully */
252 struct cmd_adc_result {
253         fixed_string_t arg0;
254         fixed_string_t arg1;
255 };
256
257 /* function called when cmd_adc is parsed successfully */
258 static void cmd_adc_parsed(void *parsed_result, void *data)
259 {
260         struct cmd_adc_result *res = parsed_result;
261         uint8_t i, loop = 0;
262
263         if (!strcmp_P(res->arg1, PSTR("loop_show")))
264                 loop = 1;
265         
266         do {
267                 printf_P(PSTR("ADC values: "));
268                 for (i=0; i<ADC_MAX; i++) {
269                         printf_P(PSTR("%.4d "), sensor_get_adc(i));
270                 }
271                 printf_P(PSTR("\r\n"));
272                 wait_ms(100);
273         } while (loop && !cmdline_keypressed());
274 }
275
276 prog_char str_adc_arg0[] = "adc";
277 parse_pgm_token_string_t cmd_adc_arg0 = TOKEN_STRING_INITIALIZER(struct cmd_adc_result, arg0, str_adc_arg0);
278 prog_char str_adc_arg1[] = "show#loop_show";
279 parse_pgm_token_string_t cmd_adc_arg1 = TOKEN_STRING_INITIALIZER(struct cmd_adc_result, arg1, str_adc_arg1);
280
281 prog_char help_adc[] = "Show adc values";
282 parse_pgm_inst_t cmd_adc = {
283         .f = cmd_adc_parsed,  /* function to call */
284         .data = NULL,      /* 2nd arg of func */
285         .help_str = help_adc,
286         .tokens = {        /* token list, NULL terminated */
287                 (prog_void *)&cmd_adc_arg0, 
288                 (prog_void *)&cmd_adc_arg1, 
289                 NULL,
290         },
291 };
292
293
294 /**********************************************************/
295 /* Sensors tests */
296
297 /* this structure is filled when cmd_sensor is parsed successfully */
298 struct cmd_sensor_result {
299         fixed_string_t arg0;
300         fixed_string_t arg1;
301 };
302
303 /* function called when cmd_sensor is parsed successfully */
304 static void cmd_sensor_parsed(void *parsed_result, void *data)
305 {
306         struct cmd_sensor_result *res = parsed_result;
307         uint8_t i, loop = 0;
308
309         if (!strcmp_P(res->arg1, PSTR("loop_show")))
310                 loop = 1;
311         
312         do {
313                 printf_P(PSTR("SENSOR values: "));
314                 for (i=0; i<SENSOR_MAX; i++) {
315                         printf_P(PSTR("%d "), !!sensor_get(i));
316                 }
317                 printf_P(PSTR("\r\n"));
318                 wait_ms(100);
319         } while (loop && !cmdline_keypressed());
320 }
321
322 prog_char str_sensor_arg0[] = "sensor";
323 parse_pgm_token_string_t cmd_sensor_arg0 = TOKEN_STRING_INITIALIZER(struct cmd_sensor_result, arg0, str_sensor_arg0);
324 prog_char str_sensor_arg1[] = "show#loop_show";
325 parse_pgm_token_string_t cmd_sensor_arg1 = TOKEN_STRING_INITIALIZER(struct cmd_sensor_result, arg1, str_sensor_arg1);
326
327 prog_char help_sensor[] = "Show sensor values";
328 parse_pgm_inst_t cmd_sensor = {
329         .f = cmd_sensor_parsed,  /* function to call */
330         .data = NULL,      /* 2nd arg of func */
331         .help_str = help_sensor,
332         .tokens = {        /* token list, NULL terminated */
333                 (prog_void *)&cmd_sensor_arg0, 
334                 (prog_void *)&cmd_sensor_arg1, 
335                 NULL,
336         },
337 };
338
339
340 /**********************************************************/
341 /* Log */
342
343 /* this structure is filled when cmd_log is parsed successfully */
344 struct cmd_log_result {
345         fixed_string_t arg0;
346         fixed_string_t arg1;
347         uint8_t arg2;
348         fixed_string_t arg3;
349 };
350
351 /* keep it sync with string choice */
352 static const prog_char uart_log[] = "uart";
353 static const prog_char rs_log[] = "rs";
354 static const prog_char traj_log[] = "traj";
355 static const prog_char i2c_log[] = "i2c";
356 static const prog_char oa_log[] = "oa";
357 static const prog_char strat_log[] = "strat";
358 static const prog_char i2cproto_log[] = "i2cproto";
359 static const prog_char sensor_log[] = "sensor";
360 static const prog_char block_log[] = "bd";
361 static const prog_char cs_log[] = "cs";
362
363 struct log_name_and_num {
364         const prog_char * name;
365         uint8_t num;
366 };
367
368 static const struct log_name_and_num log_name_and_num[] = {
369         { uart_log, E_UART },
370         { rs_log, E_ROBOT_SYSTEM },
371         { traj_log, E_TRAJECTORY },
372         { i2c_log, E_I2C },
373         { oa_log, E_OA },
374         { strat_log, E_USER_STRAT },
375         { i2cproto_log, E_USER_I2C_PROTO },
376         { sensor_log, E_USER_SENSOR },
377         { block_log, E_BLOCKING_DETECTION_MANAGER },
378         { cs_log, E_USER_CS },
379 };
380
381 static uint8_t
382 log_name2num(const char * s)
383 {
384         uint8_t i;
385         
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;
389                 }
390         }
391         return 0;
392 }
393
394 const prog_char *
395 log_num2name(uint8_t num)
396 {
397         uint8_t i;
398         
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;
402                 }
403         }
404         return NULL;
405 }
406
407 /* function called when cmd_log is parsed successfully */
408 static void cmd_log_do_show(void)
409 {
410         uint8_t i, empty=1;
411         const prog_char * name;
412
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]);
416                 if (name) {
417                         printf_P(PSTR("log type %S is on\r\n"), name);
418                         empty = 0;
419                 }
420         }
421         if (empty)
422                 printf_P(PSTR("no log configured\r\n"), gen.logs[i]);
423 }
424
425 /* function called when cmd_log is parsed successfully */
426 static void cmd_log_parsed(void * parsed_result, void * data)
427 {
428         struct cmd_log_result *res = (struct cmd_log_result *) parsed_result;
429
430         if (!strcmp_P(res->arg1, PSTR("level"))) {
431                 gen.log_level = res->arg2;
432         }
433
434         /* else it is a show */
435         cmd_log_do_show();
436 }
437
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);
443
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, 
453                 NULL,
454         },
455 };
456
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);
459
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, 
468                 NULL,
469         },
470 };
471
472 /* this structure is filled when cmd_log is parsed successfully */
473 struct cmd_log_type_result {
474         fixed_string_t arg0;
475         fixed_string_t arg1;
476         fixed_string_t arg2;
477         fixed_string_t arg3;
478 };
479
480 /* function called when cmd_log is parsed successfully */
481 static void cmd_log_type_parsed(void * parsed_result, void * data)
482 {
483         struct cmd_log_type_result *res = (struct cmd_log_type_result *) parsed_result;
484         uint8_t lognum;
485         uint8_t i;
486         
487         lognum = log_name2num(res->arg2);
488         if (lognum == 0) {
489                 printf_P(PSTR("Cannot find log num\r\n"));
490                 return;
491         }
492
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"));
497                                 return;
498                         }
499                 }
500                 for (i=0; i<NB_LOGS; i++) {
501                         if (gen.logs[i] == 0) {
502                                 gen.logs[i] = lognum;
503                                 break;
504                         }
505                 }
506                 if (i==NB_LOGS) {
507                         printf_P(PSTR("no more room\r\n"));
508                 }
509         }
510         else if (!strcmp_P(res->arg3, PSTR("off"))) {
511                 for (i=0; i<NB_LOGS; i++) {
512                         if (gen.logs[i] == lognum) {
513                                 gen.logs[i] = 0;
514                                 break;
515                         }
516                 }
517                 if (i==NB_LOGS) {
518                         printf_P(PSTR("already off\r\n"));
519                 }
520         }
521         cmd_log_do_show();
522 }
523
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#rs#servo#traj#i2c#oa#strat#i2cproto#ext#sensor#bd#cs";
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);
531
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,
542                 NULL,
543         },
544 };
545
546
547 /**********************************************************/
548 /* Stack_Space */
549
550 /* this structure is filled when cmd_stack_space is parsed successfully */
551 struct cmd_stack_space_result {
552         fixed_string_t arg0;
553 };
554
555 /* function called when cmd_stack_space is parsed successfully */
556 static void cmd_stack_space_parsed(void *parsed_result, void *data)
557 {
558         printf("res stack: %d\r\n", min_stack_space_available());
559         
560 }
561
562 prog_char str_stack_space_arg0[] = "stack_space";
563 parse_pgm_token_string_t cmd_stack_space_arg0 = TOKEN_STRING_INITIALIZER(struct cmd_stack_space_result, arg0, str_stack_space_arg0);
564
565 prog_char help_stack_space[] = "Display remaining stack space";
566 parse_pgm_inst_t cmd_stack_space = {
567         .f = cmd_stack_space_parsed,  /* function to call */
568         .data = NULL,      /* 2nd arg of func */
569         .help_str = help_stack_space,
570         .tokens = {        /* token list, NULL terminated */
571                 (prog_void *)&cmd_stack_space_arg0, 
572                 NULL,
573         },
574 };
575
576 #if 0
577 /**********************************************************/
578 /* Servo */
579
580
581 /* this structure is filled when cmd_servo is parsed successfully */
582 struct cmd_servo_result {
583         fixed_string_t arg0;
584         uint8_t num;
585         uint16_t us;
586 };
587
588 /* function called when cmd_servo is parsed successfully */
589 static void cmd_servo_parsed(void * parsed_result, void * data)
590 {
591         struct cmd_servo_result *res = (struct cmd_servo_result *) parsed_result;
592         action_servo_set(res->num, res->us);
593 }
594
595 prog_char str_servo_arg0[] = "servo";
596 parse_pgm_token_string_t cmd_servo_arg0 = TOKEN_STRING_INITIALIZER(struct cmd_servo_result, arg0, str_servo_arg0);
597 parse_pgm_token_num_t cmd_servo_num = TOKEN_NUM_INITIALIZER(struct cmd_servo_result, num, UINT8);
598 parse_pgm_token_num_t cmd_servo_us = TOKEN_NUM_INITIALIZER(struct cmd_servo_result, us, UINT16);
599
600 prog_char help_servo[] = "Set servo position/speed";
601 parse_pgm_inst_t cmd_servo = {
602         .f = cmd_servo_parsed,  /* function to call */
603         .data = NULL,      /* 2nd arg of func */
604         .help_str = help_servo,
605         .tokens = {        /* token list, NULL terminated */
606                 (prog_void *)&cmd_servo_arg0, 
607                 (prog_void *)&cmd_servo_num, 
608                 (prog_void *)&cmd_servo_us, 
609                 NULL,
610         },
611 };
612 #endif