2 * Copyright Droids Corporation (2011)
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 * Revision : $Id: commands.c,v 1.9 2009-11-08 17:24:33 zer0 Exp $
20 * Olivier MATZ <zer0@droids-corp.org>
28 #include <aversive/pgmspace.h>
29 #include <aversive/queue.h>
30 #include <aversive/endian.h>
31 #include <aversive/error.h>
32 #include <aversive/wait.h>
35 #include <parse_string.h>
36 #include <parse_num.h>
41 #include "parse_atcmd.h"
42 #include "parse_neighbor.h"
43 #include "parse_monitor.h"
45 #include "spi_servo.h"
50 #include "eeprom_config.h"
53 extern const parse_inst_t PROGMEM cmd_reset;
54 extern const parse_inst_t PROGMEM cmd_bootloader;
55 extern const parse_inst_t PROGMEM cmd_log;
56 extern const parse_inst_t PROGMEM cmd_log_show;
57 extern const parse_inst_t PROGMEM cmd_log_type;
58 extern const parse_inst_t PROGMEM cmd_stack_space;
59 extern const parse_inst_t PROGMEM cmd_scheduler;
61 static int monitor_period_ms = 1000;
62 static int monitor_running = 0;
63 static int monitor_count = 0;
64 static struct callout monitor_event;
65 struct monitor_reg *monitor_current;
67 static int range_period_ms = 1000;
68 static int range_powermask = 0x1F;
69 //static uint8_t range_power = 0;
70 static int range_running = 0;
71 static uint64_t range_dstaddr = 0xFFFF; /* broadcast by default */
72 static struct callout range_event;
73 static int range_count = 100;
74 static int range_cur_count = 0;
76 static void monitor_cb(struct callout_manager *cm,
77 struct callout *clt, void *dummy)
82 if (monitor_current == NULL)
83 monitor_current = LIST_FIRST(&xbee_monitor_list);
85 xbeeapp_send_atcmd(monitor_current->atcmd, NULL, 0, 0, NULL, NULL);
86 monitor_current = LIST_NEXT(monitor_current, next);
87 callout_reset(cm, &monitor_event,
88 monitor_period_ms / monitor_count,
89 SINGLE, monitor_cb, NULL);
92 static void range_cb(struct callout_manager *cm,
93 struct callout *clt, void *dummy)
100 struct rc_proto_range rangepkt;
107 /* get new xmit power */
108 for (i = 1; i <= 8; i++) {
109 mask = 1 << ((range_power + i) & 0x7);
110 if (mask & range_powermask)
113 range_power = ((range_power + i) & 0x7);
115 xbeeapp_send_atcmd("PL", &range_power, sizeof(range_power), 0, NULL, NULL);
117 rangepkt.type = RC_PROTO_TYPE_RANGE;
118 rangepkt.power_level = range_power;
120 xbeeapp_send_msg(range_dstaddr, &rangepkt, sizeof(rangepkt), 0);
122 if (range_cur_count == 0) {
127 callout_reset(cm, &range_event,
129 SINGLE, range_cb, NULL);
133 /* this structure is filled when cmd_help is parsed successfully */
134 struct cmd_help_result {
136 struct xbee_atcmd *cmd;
139 /* function called when cmd_help is parsed successfully */
140 static void cmd_help_parsed(void *parsed_result, void *data)
142 struct cmd_help_result *res = parsed_result;
143 struct xbee_atcmd cmdcopy;
148 memcpy_P(&cmdcopy, res->cmd, sizeof(cmdcopy));
149 type = (cmdcopy.flags & (XBEE_ATCMD_F_READ | XBEE_ATCMD_F_WRITE));
151 case XBEE_ATCMD_F_READ:
152 printf_P(PSTR("Read-only\r\n"));
154 case XBEE_ATCMD_F_WRITE:
155 printf_P(PSTR("Write-only\r\n"));
158 printf_P(PSTR("Read-write\r\n"));
161 if (cmdcopy.flags & XBEE_ATCMD_F_PARAM_NONE)
162 printf_P(PSTR("No argument\r\n"));
163 else if (cmdcopy.flags & XBEE_ATCMD_F_PARAM_U8)
164 printf_P(PSTR("Register is unsigned 8 bits\r\n"));
165 else if (cmdcopy.flags & XBEE_ATCMD_F_PARAM_U16)
166 printf_P(PSTR("Register is unsigned 16 bits\r\n"));
167 else if (cmdcopy.flags & XBEE_ATCMD_F_PARAM_U32)
168 printf_P(PSTR("Register is unsigned 32 bits\r\n"));
169 else if (cmdcopy.flags & XBEE_ATCMD_F_PARAM_S16)
170 printf_P(PSTR("Register is signed 16 bits\r\n"));
171 else if (cmdcopy.flags & XBEE_ATCMD_F_PARAM_STRING_20B)
172 printf_P(PSTR("Register is a 20 bytes string\r\n"));
174 printf_P(PSTR("Unknown argument\r\n"));
176 printf_P(PSTR("%S\r\n"), cmdcopy.help);
178 const char PROGMEM str_help_help[] = "help";
180 const parse_token_string_t PROGMEM cmd_help_help =
181 TOKEN_STRING_INITIALIZER(struct cmd_help_result, help, str_help_help);
183 const parse_token_atcmd_t PROGMEM cmd_help_atcmd =
184 TOKEN_ATCMD_INITIALIZER(struct cmd_help_result, cmd, &xbee_dev,
187 const char PROGMEM help_help[] = "Help a register using an AT command";
188 const parse_inst_t PROGMEM cmd_help = {
189 .f = cmd_help_parsed, /* function to call */
190 .data = NULL, /* 2nd arg of func */
191 .help_str = help_help,
192 .tokens = { /* token list, NULL terminated */
193 (PGM_P)&cmd_help_help,
194 (PGM_P)&cmd_help_atcmd,
201 struct cmd_neigh_del_result {
203 fixed_string_t action;
204 struct xbee_neigh *neigh;
207 static void cmd_neigh_del_parsed(void *parsed_result,
210 struct cmd_neigh_del_result *res = parsed_result;
213 xbee_neigh_del(xbee_dev, res->neigh);
216 const char PROGMEM str_neigh_del_neigh[] = "neigh";
217 const parse_token_string_t PROGMEM cmd_neigh_del_cmd =
218 TOKEN_STRING_INITIALIZER(struct cmd_neigh_del_result, cmd,
219 str_neigh_del_neigh);
220 const char PROGMEM str_neigh_del_del[] = "del";
221 const parse_token_string_t PROGMEM cmd_neigh_del_action =
222 TOKEN_STRING_INITIALIZER(struct cmd_neigh_del_result, action,
224 const parse_token_neighbor_t PROGMEM cmd_neigh_del_neigh =
225 TOKEN_NEIGHBOR_INITIALIZER(struct cmd_neigh_del_result, neigh,
228 const char PROGMEM help_neigh_del[] = "delete a neighbor";
229 const parse_inst_t PROGMEM cmd_neigh_del = {
230 .f = cmd_neigh_del_parsed, /* function to call */
231 .data = NULL, /* 2nd arg of func */
232 .help_str = help_neigh_del,
233 .tokens = { /* token list, NULL terminated */
234 (PGM_P)&cmd_neigh_del_cmd,
235 (PGM_P)&cmd_neigh_del_action,
236 (PGM_P)&cmd_neigh_del_neigh,
243 struct cmd_neigh_add_result {
245 fixed_string_t action;
250 static void cmd_neigh_add_parsed(void *parsed_result,
253 struct cmd_neigh_add_result *res = parsed_result;
256 if (xbee_neigh_add(xbee_dev, res->name, res->addr) == NULL)
257 printf_P(PSTR("name or addr already exist\r\n"));
260 const char PROGMEM str_neigh_add_neigh[] = "neigh";
261 const parse_token_string_t PROGMEM cmd_neigh_add_cmd =
262 TOKEN_STRING_INITIALIZER(struct cmd_neigh_add_result, cmd,
263 str_neigh_add_neigh);
264 const char PROGMEM str_neigh_add_add[] = "add";
265 const parse_token_string_t PROGMEM cmd_neigh_add_action =
266 TOKEN_STRING_INITIALIZER(struct cmd_neigh_add_result, action,
268 const parse_token_string_t PROGMEM cmd_neigh_add_name =
269 TOKEN_STRING_INITIALIZER(struct cmd_neigh_add_result, name, NULL);
270 const parse_token_num_t PROGMEM cmd_neigh_add_addr =
271 TOKEN_NUM_INITIALIZER(struct cmd_neigh_add_result, addr, UINT64);
273 const char PROGMEM help_neigh_add[] = "add a neighbor";
274 const parse_inst_t PROGMEM cmd_neigh_add = {
275 .f = cmd_neigh_add_parsed, /* function to call */
276 .data = NULL, /* 2nd arg of func */
277 .help_str = help_neigh_add,
278 .tokens = { /* token list, NULL terminated */
279 (PGM_P)&cmd_neigh_add_cmd,
280 (PGM_P)&cmd_neigh_add_action,
281 (PGM_P)&cmd_neigh_add_name,
282 (PGM_P)&cmd_neigh_add_addr,
289 struct cmd_neigh_list_result {
291 fixed_string_t action;
294 static void cmd_neigh_list_parsed(void *parsed_result,
297 struct xbee_neigh *neigh;
301 LIST_FOREACH(neigh, &xbee_dev->neigh_list, next) {
302 printf_P(PSTR(" %s: 0x%.8"PRIx32"%.8"PRIx32"\r\n"),
304 (uint32_t)(neigh->addr >> 32ULL),
305 (uint32_t)(neigh->addr & 0xFFFFFFFF));
309 const char PROGMEM str_neigh_list_neigh[] = "neigh";
310 const parse_token_string_t PROGMEM cmd_neigh_list_cmd =
311 TOKEN_STRING_INITIALIZER(struct cmd_neigh_list_result, cmd,
312 str_neigh_list_neigh);
313 const char PROGMEM str_neigh_list_list[] = "list";
314 const parse_token_string_t PROGMEM cmd_neigh_list_action =
315 TOKEN_STRING_INITIALIZER(struct cmd_neigh_list_result, action,
316 str_neigh_list_list);
318 const char PROGMEM help_neigh_list[] = "list all knwon neighbors";
319 const parse_inst_t PROGMEM cmd_neigh_list = {
320 .f = cmd_neigh_list_parsed, /* function to call */
321 .data = NULL, /* 2nd arg of func */
322 .help_str = help_neigh_list,
323 .tokens = { /* token list, NULL terminated */
324 (PGM_P)&cmd_neigh_list_cmd,
325 (PGM_P)&cmd_neigh_list_action,
335 /* this structure is filled when cmd_read is parsed successfully */
336 struct cmd_read_result {
338 struct xbee_atcmd *cmd;
341 /* function called when cmd_read is parsed successfully */
342 static void cmd_read_parsed(void *parsed_result,
345 struct cmd_read_result *res = parsed_result;
346 struct xbee_atcmd copy;
350 memcpy_P(©, res->cmd, sizeof(copy));
351 memcpy_P(&cmd, copy.name, 2);
353 xbeeapp_send_atcmd(cmd, NULL, 0, 1, NULL, NULL);
356 const char PROGMEM str_read_read[] = "read";
358 const parse_token_string_t PROGMEM cmd_read_read =
359 TOKEN_STRING_INITIALIZER(struct cmd_read_result, read,
362 const parse_token_atcmd_t PROGMEM cmd_read_atcmd =
363 TOKEN_ATCMD_INITIALIZER(struct cmd_read_result, cmd, &xbee_dev,
364 XBEE_ATCMD_F_READ, XBEE_ATCMD_F_READ);
366 const char PROGMEM help_read[] = "Read a register using an AT command";
367 const parse_inst_t PROGMEM cmd_read = {
368 .f = cmd_read_parsed, /* function to call */
369 .data = NULL, /* 2nd arg of func */
370 .help_str = help_read,
371 .tokens = { /* token list, NULL terminated */
372 (PGM_P)&cmd_read_read,
373 (PGM_P)&cmd_read_atcmd,
381 /* this structure is filled when cmd_write is parsed successfully */
382 struct cmd_write_result {
383 fixed_string_t write;
384 struct xbee_atcmd *cmd;
392 /* function called when cmd_write is parsed successfully */
393 static void cmd_write_parsed(void *parsed_result, void *data)
395 struct cmd_write_result *res = parsed_result;
396 struct xbee_atcmd copy;
402 memcpy_P(©, res->cmd, sizeof(copy));
404 if (copy.flags & XBEE_ATCMD_F_PARAM_NONE) {
408 else if (copy.flags & XBEE_ATCMD_F_PARAM_U8) {
409 len = sizeof(res->u8);
412 else if (copy.flags & XBEE_ATCMD_F_PARAM_U16) {
413 len = sizeof(res->u16);
414 res->u16 = htons(res->u16);
417 else if (copy.flags & XBEE_ATCMD_F_PARAM_U32) {
418 len = sizeof(res->u32);
419 res->u32 = htonl(res->u32);
423 printf_P(PSTR("Unknown argument type\r\n"));
426 memcpy_P(&cmd, copy.name, 2);
428 xbeeapp_send_atcmd(cmd, param, len, 1, NULL, NULL);
431 const char PROGMEM str_write_none[] = "write";
433 const parse_token_string_t PROGMEM cmd_write_write =
434 TOKEN_STRING_INITIALIZER(struct cmd_write_result, write,
437 const parse_token_atcmd_t PROGMEM cmd_write_none_atcmd =
438 TOKEN_ATCMD_INITIALIZER(struct cmd_write_result, cmd,
440 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_NONE,
441 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_NONE);
443 const char PROGMEM help_write_none[] = "Send an AT command (no argument)";
445 const parse_inst_t PROGMEM cmd_write_none = {
446 .f = cmd_write_parsed, /* function to call */
447 .data = NULL, /* 2nd arg of func */
448 .help_str = help_write_none,
449 .tokens = { /* token list, NULL terminated */
450 (PGM_P)&cmd_write_write,
451 (PGM_P)&cmd_write_none_atcmd,
456 const parse_token_atcmd_t PROGMEM cmd_write_u8_atcmd =
457 TOKEN_ATCMD_INITIALIZER(struct cmd_write_result, cmd,
459 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_U8,
460 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_U8);
462 const parse_token_num_t PROGMEM cmd_write_u8_u8 =
463 TOKEN_NUM_INITIALIZER(struct cmd_write_result, u8, UINT8);
465 const char PROGMEM help_write_u8[] = "Write a 8 bits register using an AT command";
467 const parse_inst_t PROGMEM cmd_write_u8 = {
468 .f = cmd_write_parsed, /* function to call */
469 .data = NULL, /* 2nd arg of func */
470 .help_str = help_write_u8,
471 .tokens = { /* token list, NULL terminated */
472 (PGM_P)&cmd_write_write,
473 (PGM_P)&cmd_write_u8_atcmd,
474 (PGM_P)&cmd_write_u8_u8,
479 const parse_token_atcmd_t PROGMEM cmd_write_u16_atcmd =
480 TOKEN_ATCMD_INITIALIZER(struct cmd_write_result, cmd,
482 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_U16,
483 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_U16);
485 const parse_token_num_t PROGMEM cmd_write_u16_u16 =
486 TOKEN_NUM_INITIALIZER(struct cmd_write_result, u16, UINT16);
488 const char PROGMEM help_write_u16[] = "Write a 16 bits register using an AT command";
490 const parse_inst_t PROGMEM cmd_write_u16 = {
491 .f = cmd_write_parsed, /* function to call */
492 .data = NULL, /* 2nd arg of func */
493 .help_str = help_write_u16,
494 .tokens = { /* token list, NULL terminated */
495 (PGM_P)&cmd_write_write,
496 (PGM_P)&cmd_write_u16_atcmd,
497 (PGM_P)&cmd_write_u16_u16,
502 const parse_token_atcmd_t PROGMEM cmd_write_u32_atcmd =
503 TOKEN_ATCMD_INITIALIZER(struct cmd_write_result, cmd,
505 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_U32,
506 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_U32);
508 const parse_token_num_t PROGMEM cmd_write_u32_u32 =
509 TOKEN_NUM_INITIALIZER(struct cmd_write_result, u32, UINT32);
511 const char PROGMEM help_write_u32[] = "Write a 32 bits register using an AT command";
513 const parse_inst_t PROGMEM cmd_write_u32 = {
514 .f = cmd_write_parsed, /* function to call */
515 .data = NULL, /* 2nd arg of func */
516 .help_str = help_write_u32,
517 .tokens = { /* token list, NULL terminated */
518 (PGM_P)&cmd_write_write,
519 (PGM_P)&cmd_write_u32_atcmd,
520 (PGM_P)&cmd_write_u32_u32,
528 /* this structure is filled when cmd_sendmsg is parsed successfully */
529 struct cmd_sendmsg_result {
530 fixed_string_t sendmsg;
535 /* function called when cmd_sendmsg is parsed successfully */
536 static void cmd_sendmsg_parsed(void *parsed_result, void *data)
538 struct cmd_sendmsg_result *res = parsed_result;
541 xbeeapp_send_msg(res->addr, res->data, strlen(res->data), 1);
544 const char PROGMEM str_sendmsg[] = "sendmsg";
546 const parse_token_string_t PROGMEM cmd_sendmsg_sendmsg =
547 TOKEN_STRING_INITIALIZER(struct cmd_sendmsg_result, sendmsg,
550 const parse_token_num_t PROGMEM cmd_sendmsg_addr =
551 TOKEN_NUM_INITIALIZER(struct cmd_sendmsg_result, addr, UINT64);
553 const parse_token_string_t PROGMEM cmd_sendmsg_data =
554 TOKEN_STRING_INITIALIZER(struct cmd_sendmsg_result, data, NULL);
556 const char PROGMEM help_sendmsg[] = "Send data to a node using its address";
558 const parse_inst_t PROGMEM cmd_sendmsg = {
559 .f = cmd_sendmsg_parsed, /* function to call */
560 .data = NULL, /* 2nd arg of func */
561 .help_str = help_sendmsg,
562 .tokens = { /* token list, NULL terminated */
563 (PGM_P)&cmd_sendmsg_sendmsg,
564 (PGM_P)&cmd_sendmsg_addr,
565 (PGM_P)&cmd_sendmsg_data,
572 /* this structure is filled when cmd_sendmsg_name is parsed successfully */
573 struct cmd_sendmsg_name_result {
574 fixed_string_t sendmsg_name;
575 struct xbee_neigh *neigh;
579 /* function called when cmd_sendmsg_name is parsed successfully */
580 static void cmd_sendmsg_name_parsed(void *parsed_result, void *data)
582 struct cmd_sendmsg_name_result *res = parsed_result;
585 xbeeapp_send_msg(res->neigh->addr, res->data, strlen(res->data), 1);
588 const parse_token_string_t PROGMEM cmd_sendmsg_name_sendmsg_name =
589 TOKEN_STRING_INITIALIZER(struct cmd_sendmsg_name_result, sendmsg_name,
592 const parse_token_neighbor_t PROGMEM cmd_sendmsg_name_neigh =
593 TOKEN_NEIGHBOR_INITIALIZER(struct cmd_sendmsg_name_result, neigh,
596 const parse_token_string_t PROGMEM cmd_sendmsg_name_data =
597 TOKEN_STRING_INITIALIZER(struct cmd_sendmsg_name_result, data, NULL);
599 const char PROGMEM help_sendmsg_name[] = "Send data to a node using its name";
601 const parse_inst_t PROGMEM cmd_sendmsg_name = {
602 .f = cmd_sendmsg_name_parsed, /* function to call */
603 .data = NULL, /* 2nd arg of func */
604 .help_str = help_sendmsg_name,
605 .tokens = { /* token list, NULL terminated */
606 (PGM_P)&cmd_sendmsg_name_sendmsg_name,
607 (PGM_P)&cmd_sendmsg_name_neigh,
608 (PGM_P)&cmd_sendmsg_name_data,
616 /* this structure is filled when cmd_range is parsed successfully */
617 struct cmd_range_result {
618 fixed_string_t range;
619 fixed_string_t action;
622 /* function called when cmd_range is parsed successfully */
623 static void cmd_range_parsed(void *parsed_result, void *data)
625 struct cmd_range_result *res = parsed_result;
628 if (!strcmp_P(res->action, PSTR("show"))) {
629 printf_P(PSTR("range infos:\r\n"));
630 printf_P(PSTR(" range period %d\r\n"), range_period_ms);
631 printf_P(PSTR(" range count %d\r\n"), range_count);
632 printf_P(PSTR(" range powermask 0x%x\r\n"), range_powermask);
633 printf_P(PSTR(" range dstaddr 0x%.8"PRIx32"%.8"PRIx32"\r\n"),
634 (uint32_t)(range_dstaddr >> 32ULL),
635 (uint32_t)(range_dstaddr & 0xFFFFFFFF));
638 printf_P(PSTR(" range test is running\r\n"));
640 printf_P(PSTR(" range test is not running\r\n"));
642 else if (!strcmp(res->action, "start")) {
644 printf_P(PSTR("already running\r\n"));
647 range_cur_count = range_count;
648 callout_init(&range_event);
649 callout_reset(&cm, &range_event, 0,
650 SINGLE, range_cb, NULL);
653 else if (!strcmp(res->action, "end")) {
654 if (range_running == 0) {
655 printf_P(PSTR("not running\r\n"));
659 callout_stop(&cm, &range_event);
663 const char PROGMEM str_range[] = "range";
664 const char PROGMEM str_range_tokens[] = "show#start#end";
666 const parse_token_string_t PROGMEM cmd_range_range =
667 TOKEN_STRING_INITIALIZER(struct cmd_range_result, range,
669 const parse_token_string_t PROGMEM cmd_range_action =
670 TOKEN_STRING_INITIALIZER(struct cmd_range_result, action,
673 const char PROGMEM help_range[] = "start/stop/show current rangeing";
675 const parse_inst_t PROGMEM cmd_range = {
676 .f = cmd_range_parsed, /* function to call */
677 .data = NULL, /* 2nd arg of func */
678 .help_str = help_range,
679 .tokens = { /* token list, NULL terminated */
680 (PGM_P)&cmd_range_range,
681 (PGM_P)&cmd_range_action,
688 /* this structure is filled when cmd_range_period is parsed successfully */
689 struct cmd_range_period_result {
690 fixed_string_t range;
691 fixed_string_t action;
695 /* function called when cmd_range_period is parsed successfully */
696 static void cmd_range_period_parsed(void *parsed_result, void *data)
698 struct cmd_range_period_result *res = parsed_result;
701 if (res->period < 10) {
702 printf_P(PSTR("error, minimum period is 10 ms\r\n"));
706 range_period_ms = res->period;
709 const char PROGMEM str_period[] = "period";
711 const parse_token_string_t PROGMEM cmd_range_period_range_period =
712 TOKEN_STRING_INITIALIZER(struct cmd_range_period_result, range,
714 const parse_token_string_t PROGMEM cmd_range_period_action =
715 TOKEN_STRING_INITIALIZER(struct cmd_range_period_result, action,
717 const parse_token_num_t PROGMEM cmd_range_period_period =
718 TOKEN_NUM_INITIALIZER(struct cmd_range_period_result, period, UINT32);
720 const char PROGMEM help_range_period[] = "set range test period";
722 const parse_inst_t PROGMEM cmd_range_period = {
723 .f = cmd_range_period_parsed, /* function to call */
724 .data = NULL, /* 2nd arg of func */
725 .help_str = help_range_period,
726 .tokens = { /* token list, NULL terminated */
727 (PGM_P)&cmd_range_period_range_period,
728 (PGM_P)&cmd_range_period_action,
729 (PGM_P)&cmd_range_period_period,
736 /* this structure is filled when cmd_range_count is parsed successfully */
737 struct cmd_range_count_result {
738 fixed_string_t range;
739 fixed_string_t action;
743 /* function called when cmd_range_count is parsed successfully */
744 static void cmd_range_count_parsed(void *parsed_result, void *data)
746 struct cmd_range_count_result *res = parsed_result;
749 range_count = res->count;
752 const char PROGMEM str_count[] = "count";
754 const parse_token_string_t PROGMEM cmd_range_count_range_count =
755 TOKEN_STRING_INITIALIZER(struct cmd_range_count_result, range,
757 const parse_token_string_t PROGMEM cmd_range_count_action =
758 TOKEN_STRING_INITIALIZER(struct cmd_range_count_result, action,
760 const parse_token_num_t PROGMEM cmd_range_count_count =
761 TOKEN_NUM_INITIALIZER(struct cmd_range_count_result, count, UINT32);
764 const char PROGMEM help_range_count[] = "set range test count";
766 const parse_inst_t PROGMEM cmd_range_count = {
767 .f = cmd_range_count_parsed, /* function to call */
768 .data = NULL, /* 2nd arg of func */
769 .help_str = help_range_count,
770 .tokens = { /* token list, NULL terminated */
771 (PGM_P)&cmd_range_count_range_count,
772 (PGM_P)&cmd_range_count_action,
773 (PGM_P)&cmd_range_count_count,
780 /* this structure is filled when cmd_range_powermask is parsed successfully */
781 struct cmd_range_powermask_result {
782 fixed_string_t range;
783 fixed_string_t action;
787 /* function called when cmd_range_powermask is parsed successfully */
788 static void cmd_range_powermask_parsed(void *parsed_result, void *data)
790 struct cmd_range_powermask_result *res = parsed_result;
793 range_powermask = res->powermask;
796 const char PROGMEM str_powermask[] = "powermask";
798 const parse_token_string_t PROGMEM cmd_range_powermask_range_powermask =
799 TOKEN_STRING_INITIALIZER(struct cmd_range_powermask_result, range,
801 const parse_token_string_t PROGMEM cmd_range_powermask_action =
802 TOKEN_STRING_INITIALIZER(struct cmd_range_powermask_result, action,
804 const parse_token_num_t PROGMEM cmd_range_powermask_powermask =
805 TOKEN_NUM_INITIALIZER(struct cmd_range_powermask_result, powermask,
809 const char PROGMEM help_range_powermask[] = "set range test powermask";
811 const parse_inst_t PROGMEM cmd_range_powermask = {
812 .f = cmd_range_powermask_parsed, /* function to call */
813 .data = NULL, /* 2nd arg of func */
814 .help_str = help_range_powermask,
815 .tokens = { /* token list, NULL terminated */
816 (PGM_P)&cmd_range_powermask_range_powermask,
817 (PGM_P)&cmd_range_powermask_action,
818 (PGM_P)&cmd_range_powermask_powermask,
825 /* this structure is filled when cmd_range_dstaddr is parsed successfully */
826 struct cmd_range_dstaddr_result {
827 fixed_string_t range;
828 fixed_string_t action;
832 /* function called when cmd_range_dstaddr is parsed successfully */
833 static void cmd_range_dstaddr_parsed(void *parsed_result, void *data)
835 struct cmd_range_dstaddr_result *res = parsed_result;
838 range_dstaddr = res->dstaddr;
841 const char PROGMEM str_dstaddr[] = "dstaddr";
843 const parse_token_string_t PROGMEM cmd_range_dstaddr_range_dstaddr =
844 TOKEN_STRING_INITIALIZER(struct cmd_range_dstaddr_result, range,
846 const parse_token_string_t PROGMEM cmd_range_dstaddr_action =
847 TOKEN_STRING_INITIALIZER(struct cmd_range_dstaddr_result, action,
849 const parse_token_num_t PROGMEM cmd_range_dstaddr_dstaddr =
850 TOKEN_NUM_INITIALIZER(struct cmd_range_dstaddr_result, dstaddr, UINT64);
853 const char PROGMEM help_range_dstaddr[] = "set register rangeing dstaddr";
855 const parse_inst_t PROGMEM cmd_range_dstaddr = {
856 .f = cmd_range_dstaddr_parsed, /* function to call */
857 .data = NULL, /* 2nd arg of func */
858 .help_str = help_range_dstaddr,
859 .tokens = { /* token list, NULL terminated */
860 (PGM_P)&cmd_range_dstaddr_range_dstaddr,
861 (PGM_P)&cmd_range_dstaddr_action,
862 (PGM_P)&cmd_range_dstaddr_dstaddr,
870 /* this structure is filled when cmd_monitor is parsed successfully */
871 struct cmd_monitor_result {
872 fixed_string_t monitor;
873 fixed_string_t action;
876 /* function called when cmd_monitor is parsed successfully */
877 static void cmd_monitor_parsed(void *parsed_result, void *data)
879 struct cmd_monitor_result *res = parsed_result;
880 struct monitor_reg *m;
883 if (!strcmp_P(res->action, PSTR("show"))) {
884 printf_P(PSTR("monitor period is %d ms, %d regs in list\r\n"),
885 monitor_period_ms, monitor_count);
886 LIST_FOREACH(m, &xbee_monitor_list, next)
887 printf_P(PSTR(" %S\r\n"), m->desc);
889 else if (!strcmp_P(res->action, PSTR("start"))) {
890 if (monitor_running) {
891 printf_P(PSTR("already running\r\n"));
894 if (monitor_count == 0) {
895 printf_P(PSTR("no regs to be monitored\r\n"));
898 callout_init(&monitor_event);
899 callout_reset(&cm, &monitor_event, 0, SINGLE, monitor_cb, NULL);
901 monitor_current = LIST_FIRST(&xbee_monitor_list);
902 printf_P(PSTR("monitor cb: %S %s\r\n"),
903 monitor_current->desc,
904 monitor_current->atcmd);
907 else if (!strcmp_P(res->action, PSTR("end"))) {
908 if (monitor_running == 0) {
909 printf_P(PSTR("not running\r\n"));
913 callout_stop(&cm, &monitor_event);
917 const char PROGMEM str_monitor[] = "monitor";
918 const char PROGMEM str_monitor_tokens[] = "show#start#end";
920 const parse_token_string_t PROGMEM cmd_monitor_monitor =
921 TOKEN_STRING_INITIALIZER(struct cmd_monitor_result, monitor,
923 const parse_token_string_t PROGMEM cmd_monitor_action =
924 TOKEN_STRING_INITIALIZER(struct cmd_monitor_result, action,
927 const char PROGMEM help_monitor[] = "start/stop/show current monitoring";
929 const parse_inst_t PROGMEM cmd_monitor = {
930 .f = cmd_monitor_parsed, /* function to call */
931 .data = NULL, /* 2nd arg of func */
932 .help_str = help_monitor,
933 .tokens = { /* token list, NULL terminated */
934 (PGM_P)&cmd_monitor_monitor,
935 (PGM_P)&cmd_monitor_action,
942 /* this structure is filled when cmd_monitor_add is parsed successfully */
943 struct cmd_monitor_add_result {
944 fixed_string_t monitor;
945 fixed_string_t action;
946 struct xbee_atcmd *cmd;
949 /* function called when cmd_monitor_add is parsed successfully */
950 static void cmd_monitor_add_parsed(void *parsed_result, void *data)
952 struct cmd_monitor_add_result *res = parsed_result;
953 struct monitor_reg *m;
954 struct xbee_atcmd copy;
957 memcpy_P(©, res->cmd, sizeof(copy));
958 LIST_FOREACH(m, &xbee_monitor_list, next) {
959 if (!strcmp_P(m->atcmd, copy.name))
964 printf_P(PSTR("already exist\r\n"));
968 m = malloc(sizeof(*m));
970 printf_P(PSTR("no mem\r\n"));
974 strcpy_P(m->atcmd, copy.name);
975 LIST_INSERT_HEAD(&xbee_monitor_list, m, next);
979 const char PROGMEM str_monitor_add[] = "add";
981 const parse_token_string_t PROGMEM cmd_monitor_add_monitor_add =
982 TOKEN_STRING_INITIALIZER(struct cmd_monitor_add_result, monitor,
984 const parse_token_string_t PROGMEM cmd_monitor_add_action =
985 TOKEN_STRING_INITIALIZER(struct cmd_monitor_add_result, action,
987 const parse_token_atcmd_t PROGMEM cmd_monitor_add_atcmd =
988 TOKEN_ATCMD_INITIALIZER(struct cmd_monitor_add_result, cmd, &xbee_dev,
989 XBEE_ATCMD_F_READ, XBEE_ATCMD_F_READ);
992 const char PROGMEM help_monitor_add[] = "add a register in monitor list";
994 const parse_inst_t PROGMEM cmd_monitor_add = {
995 .f = cmd_monitor_add_parsed, /* function to call */
996 .data = NULL, /* 2nd arg of func */
997 .help_str = help_monitor_add,
998 .tokens = { /* token list, NULL terminated */
999 (PGM_P)&cmd_monitor_add_monitor_add,
1000 (PGM_P)&cmd_monitor_add_action,
1001 (PGM_P)&cmd_monitor_add_atcmd,
1008 /* this structure is filled when cmd_monitor_period is parsed successfully */
1009 struct cmd_monitor_period_result {
1010 fixed_string_t monitor;
1011 fixed_string_t action;
1015 /* function called when cmd_monitor_period is parsed successfully */
1016 static void cmd_monitor_period_parsed(void *parsed_result, void *data)
1018 struct cmd_monitor_period_result *res = parsed_result;
1021 if (res->period < 100) {
1022 printf_P(PSTR("error, minimum period is 100 ms\r\n"));
1026 monitor_period_ms = res->period;
1029 const char PROGMEM str_monitor_period[] = "period";
1031 const parse_token_string_t PROGMEM cmd_monitor_period_monitor_period =
1032 TOKEN_STRING_INITIALIZER(struct cmd_monitor_period_result, monitor,
1034 const parse_token_string_t PROGMEM cmd_monitor_period_action =
1035 TOKEN_STRING_INITIALIZER(struct cmd_monitor_period_result, action,
1036 str_monitor_period);
1037 const parse_token_num_t PROGMEM cmd_monitor_period_period =
1038 TOKEN_NUM_INITIALIZER(struct cmd_monitor_period_result, period, UINT32);
1041 const char PROGMEM help_monitor_period[] = "set register monitoring period";
1043 const parse_inst_t PROGMEM cmd_monitor_period = {
1044 .f = cmd_monitor_period_parsed, /* function to call */
1045 .data = NULL, /* 2nd arg of func */
1046 .help_str = help_monitor_period,
1047 .tokens = { /* token list, NULL terminated */
1048 (PGM_P)&cmd_monitor_period_monitor_period,
1049 (PGM_P)&cmd_monitor_period_action,
1050 (PGM_P)&cmd_monitor_period_period,
1057 /* this structure is filled when cmd_monitor_del is parsed successfully */
1058 struct cmd_monitor_del_result {
1059 fixed_string_t monitor;
1060 fixed_string_t action;
1061 struct monitor_reg *m;
1064 /* function called when cmd_monitor_del is parsed successfully */
1065 static void cmd_monitor_del_parsed(void *parsed_result, void *data)
1067 struct cmd_monitor_del_result *res = parsed_result;
1070 monitor_current = LIST_NEXT(res->m, next);
1071 LIST_REMOVE(res->m, next);
1074 if (monitor_count == 0) {
1075 printf_P(PSTR("Disable monitoring, no more event\r\n"));
1076 callout_stop(&cm, &monitor_event);
1077 monitor_running = 0;
1082 const char PROGMEM str_monitor_del[] = "del";
1084 const parse_token_string_t PROGMEM cmd_monitor_del_monitor_del =
1085 TOKEN_STRING_INITIALIZER(struct cmd_monitor_del_result, monitor,
1087 const parse_token_string_t PROGMEM cmd_monitor_del_action =
1088 TOKEN_STRING_INITIALIZER(struct cmd_monitor_del_result, action,
1090 const parse_token_monitor_t PROGMEM cmd_monitor_del_atcmd =
1091 TOKEN_MONITOR_INITIALIZER(struct cmd_monitor_del_result, m);
1094 const char PROGMEM help_monitor_del[] = "del a register in monitor list";
1096 const parse_inst_t PROGMEM cmd_monitor_del = {
1097 .f = cmd_monitor_del_parsed, /* function to call */
1098 .data = NULL, /* 2nd arg of func */
1099 .help_str = help_monitor_del,
1100 .tokens = { /* token list, NULL terminated */
1101 (PGM_P)&cmd_monitor_del_monitor_del,
1102 (PGM_P)&cmd_monitor_del_action,
1103 (PGM_P)&cmd_monitor_del_atcmd,
1111 /* this structure is filled when cmd_ping is parsed successfully */
1112 struct cmd_ping_result {
1113 fixed_string_t ping;
1116 /* function called when cmd_ping is parsed successfully */
1117 static void cmd_ping_parsed(void *parsed_result, void *data)
1119 (void)parsed_result;
1121 xbeeapp_send_atcmd("VL", NULL, 0, 1, NULL, NULL);
1124 const char PROGMEM str_ping[] = "ping";
1126 const parse_token_string_t PROGMEM cmd_ping_ping =
1127 TOKEN_STRING_INITIALIZER(struct cmd_ping_result, ping,
1130 const char PROGMEM help_ping[] = "Send a ping to the xbee device";
1132 const parse_inst_t PROGMEM cmd_ping = {
1133 .f = cmd_ping_parsed, /* function to call */
1134 .data = NULL, /* 2nd arg of func */
1135 .help_str = help_ping,
1136 .tokens = { /* token list, NULL terminated */
1137 (PGM_P)&cmd_ping_ping,
1144 /* this structure is filled when cmd_raw is parsed successfully */
1145 struct cmd_raw_result {
1149 /* function called when cmd_raw is parsed successfully */
1150 static void cmd_raw_parsed(void *parsed_result, void *data)
1152 (void)parsed_result;
1154 printf_P(PSTR("switched to raw mode, CTRL-D to exit\r\n"));
1155 rdline_stop(&xbeeboard.rdl); /* don't display prompt when return */
1159 const char PROGMEM str_raw[] = "raw";
1161 const parse_token_string_t PROGMEM cmd_raw_raw =
1162 TOKEN_STRING_INITIALIZER(struct cmd_raw_result, raw,
1165 const char PROGMEM help_raw[] = "Switch to raw mode";
1167 const parse_inst_t PROGMEM cmd_raw = {
1168 .f = cmd_raw_parsed, /* function to call */
1169 .data = NULL, /* 2nd arg of func */
1170 .help_str = help_raw,
1171 .tokens = { /* token list, NULL terminated */
1172 (PGM_P)&cmd_raw_raw,
1179 /* this structure is filled when cmd_dump is parsed successfully */
1180 struct cmd_dump_result {
1181 fixed_string_t dump;
1182 fixed_string_t onoff;
1185 /* function called when cmd_dump is parsed successfully */
1186 static void cmd_dump_parsed(void *parsed_result, void *data)
1188 struct cmd_dump_result *res = parsed_result;
1191 if (!strcmp(res->onoff, "on"))
1197 const char PROGMEM str_dump[] = "dump";
1198 const char PROGMEM str_dump_onoff[] = "on#off";
1200 const parse_token_string_t PROGMEM cmd_dump_dump =
1201 TOKEN_STRING_INITIALIZER(struct cmd_dump_result, dump,
1204 const parse_token_string_t PROGMEM cmd_dump_onoff =
1205 TOKEN_STRING_INITIALIZER(struct cmd_dump_result, onoff,
1208 const char PROGMEM help_dump[] = "enable/disable hexdump of received packets";
1210 const parse_inst_t PROGMEM cmd_dump = {
1211 .f = cmd_dump_parsed, /* function to call */
1212 .data = NULL, /* 2nd arg of func */
1213 .help_str = help_dump,
1214 .tokens = { /* token list, NULL terminated */
1215 (PGM_P)&cmd_dump_dump,
1216 (PGM_P)&cmd_dump_onoff,
1223 /* this structure is filled when cmd_debug is parsed successfully */
1224 struct cmd_debug_result {
1225 fixed_string_t debug;
1226 fixed_string_t onoff;
1229 /* function called when cmd_debug is parsed successfully */
1230 static void cmd_debug_parsed(void *parsed_result, void *data)
1232 struct cmd_debug_result *res = parsed_result;
1235 if (!strcmp(res->onoff, "on"))
1241 const char PROGMEM str_debug[] = "debug";
1242 const char PROGMEM str_debug_onoff[] = "on#off";
1244 const parse_token_string_t PROGMEM cmd_debug_debug =
1245 TOKEN_STRING_INITIALIZER(struct cmd_debug_result, debug,
1248 const parse_token_string_t PROGMEM cmd_debug_onoff =
1249 TOKEN_STRING_INITIALIZER(struct cmd_debug_result, onoff,
1252 const char PROGMEM help_debug[] = "enable/disable additionnal debug";
1254 const parse_inst_t PROGMEM cmd_debug = {
1255 .f = cmd_debug_parsed, /* function to call */
1256 .data = NULL, /* 2nd arg of func */
1257 .help_str = help_debug,
1258 .tokens = { /* token list, NULL terminated */
1259 (PGM_P)&cmd_debug_debug,
1260 (PGM_P)&cmd_debug_onoff,
1265 /**********************************************************/
1267 /* this structure is filled when cmd_baudrate is parsed successfully */
1268 struct cmd_baudrate_result {
1269 fixed_string_t arg0;
1273 /* function called when cmd_baudrate is parsed successfully */
1274 static void cmd_baudrate_parsed(void * parsed_result, __attribute__((unused)) void *data)
1276 struct cmd_baudrate_result *res = parsed_result;
1277 struct uart_config c;
1279 uart_getconf(XBEE_UART, &c);
1280 c.baudrate = res->arg1;
1281 uart_setconf(XBEE_UART, &c);
1284 const char PROGMEM str_baudrate_arg0[] = "baudrate";
1285 const parse_token_string_t PROGMEM cmd_baudrate_arg0 =
1286 TOKEN_STRING_INITIALIZER(struct cmd_baudrate_result, arg0,
1288 const parse_token_num_t PROGMEM cmd_baudrate_arg1 =
1289 TOKEN_NUM_INITIALIZER(struct cmd_baudrate_result, arg1,
1292 const char PROGMEM help_baudrate[] = "Change xbee baudrate";
1293 const parse_inst_t PROGMEM cmd_baudrate = {
1294 .f = cmd_baudrate_parsed, /* function to call */
1295 .data = NULL, /* 2nd arg of func */
1296 .help_str = help_baudrate,
1297 .tokens = { /* token list, NULL terminated */
1298 (PGM_P)&cmd_baudrate_arg0,
1299 (PGM_P)&cmd_baudrate_arg1,
1305 /**********************************************************/
1307 /* this structure is filled when cmd_beep is parsed successfully */
1308 struct cmd_beep_result {
1309 fixed_string_t beep;
1312 /* function called when cmd_beep is parsed successfully */
1313 static void cmd_beep_parsed(void *parsed_result, void *data)
1315 (void)parsed_result;
1326 const char PROGMEM str_beep[] = "beep";
1327 const parse_token_string_t PROGMEM cmd_beep_beep =
1328 TOKEN_STRING_INITIALIZER(struct cmd_beep_result, beep,
1331 const char PROGMEM help_beep[] = "Send a beep";
1333 const parse_inst_t PROGMEM cmd_beep = {
1334 .f = cmd_beep_parsed, /* function to call */
1335 .data = NULL, /* 2nd arg of func */
1336 .help_str = help_beep,
1337 .tokens = { /* token list, NULL terminated */
1338 (PGM_P)&cmd_beep_beep,
1343 /**********************************************************/
1345 /* this structure is filled when cmd_servo is parsed successfully */
1346 struct cmd_servo_result {
1347 fixed_string_t arg0;
1348 fixed_string_t arg1;
1353 /* function called when cmd_servo is parsed successfully */
1354 static void cmd_servo_parsed(void * parsed_result, void *data)
1356 struct cmd_servo_result *res = parsed_result;
1360 if (!strcmp_P(res->arg1, PSTR("set"))) {
1361 if (res->num >= N_SERVO) {
1362 printf_P(PSTR("bad servo num\n"));
1365 if (res->val >= 1024) {
1366 printf_P(PSTR("bad servo val\n"));
1369 spi_servo_set(res->num, res->val);
1371 else if (!strcmp_P(res->arg1, PSTR("bypass"))) {
1372 spi_servo_set_bypass(!!res->val);
1374 else if (!strcmp_P(res->arg1, PSTR("ppm"))) {
1375 spi_servo_set_ppm(!!res->val);
1377 else if (!strcmp_P(res->arg1, PSTR("show"))) {
1382 const char PROGMEM str_servo_arg0[] = "servo";
1383 const parse_token_string_t PROGMEM cmd_servo_arg0 =
1384 TOKEN_STRING_INITIALIZER(struct cmd_servo_result, arg0,
1386 const char PROGMEM str_servo_arg1_set[] = "set";
1387 const parse_token_string_t PROGMEM cmd_servo_arg1_set =
1388 TOKEN_STRING_INITIALIZER(struct cmd_servo_result, arg1,
1389 str_servo_arg1_set);
1390 const parse_token_num_t PROGMEM cmd_servo_num =
1391 TOKEN_NUM_INITIALIZER(struct cmd_servo_result, num,
1393 const parse_token_num_t PROGMEM cmd_servo_val =
1394 TOKEN_NUM_INITIALIZER(struct cmd_servo_result, val,
1397 const char PROGMEM help_servo_set[] = "set servo value";
1398 const parse_inst_t PROGMEM cmd_servo_set = {
1399 .f = cmd_servo_parsed, /* function to call */
1400 .data = NULL, /* 2nd arg of func */
1401 .help_str = help_servo_set,
1402 .tokens = { /* token list, NULL terminated */
1403 (PGM_P)&cmd_servo_arg0,
1404 (PGM_P)&cmd_servo_arg1_set,
1405 (PGM_P)&cmd_servo_num,
1406 (PGM_P)&cmd_servo_val,
1411 const char PROGMEM str_servo_arg1_show[] = "show";
1412 const parse_token_string_t PROGMEM cmd_servo_arg1_show =
1413 TOKEN_STRING_INITIALIZER(struct cmd_servo_result, arg1,
1414 str_servo_arg1_show);
1416 const char PROGMEM help_servo_show[] = "read servo and config";
1417 const parse_inst_t PROGMEM cmd_servo_show = {
1418 .f = cmd_servo_parsed, /* function to call */
1419 .data = NULL, /* 2nd arg of func */
1420 .help_str = help_servo_show,
1421 .tokens = { /* token list, NULL terminated */
1422 (PGM_P)&cmd_servo_arg0,
1423 (PGM_P)&cmd_servo_arg1_show,
1428 const char PROGMEM str_servo_arg1_bypassppm[] = "bypass#ppm";
1429 const parse_token_string_t PROGMEM cmd_servo_arg1_bypassppm =
1430 TOKEN_STRING_INITIALIZER(struct cmd_servo_result, arg1,
1431 str_servo_arg1_bypassppm);
1433 const char PROGMEM help_servo_bypassppm[] = "change bypass/ppm";
1434 const parse_inst_t PROGMEM cmd_servo_bypassppm = {
1435 .f = cmd_servo_parsed, /* function to call */
1436 .data = NULL, /* 2nd arg of func */
1437 .help_str = help_servo_bypassppm,
1438 .tokens = { /* token list, NULL terminated */
1439 (PGM_P)&cmd_servo_arg0,
1440 (PGM_P)&cmd_servo_arg1_bypassppm,
1441 (PGM_P)&cmd_servo_val,
1446 /**********************************************************/
1448 /* this structure is filled when cmd_test_spi is parsed successfully */
1449 struct cmd_test_spi_result {
1450 fixed_string_t arg0;
1453 static void cmd_test_spi_parsed(void * parsed_result, void *data)
1455 uint8_t i, flags, wait_time = 0;
1458 (void)parsed_result;
1461 spi_servo_set_bypass(0);
1462 spi_servo_set_ppm(0);
1464 /* stress test: send many commands, no wait between each servo
1465 * of a series, and a variable delay between series */
1466 printf_P(PSTR("stress test\r\n"));
1467 while (!cmdline_keypressed()) {
1479 for (i = 0; i < 6; i++)
1480 spi_servo_set(i, val);
1483 printf_P(PSTR("%4.4d %4.4d %4.4d %4.4d %4.4d %4.4d\r\n"),
1484 spi_servo_get(0), spi_servo_get(1), spi_servo_get(2),
1485 spi_servo_get(3), spi_servo_get(4), spi_servo_get(5));
1488 printf_P(PSTR("bypass mode, with spi commands in background\r\n"));
1489 spi_servo_set_bypass(1);
1491 /* test bypass mode */
1492 while (!cmdline_keypressed()) {
1504 for (i = 0; i < 6; i++)
1505 spi_servo_set(i, val);
1508 printf_P(PSTR("%4.4d %4.4d %4.4d %4.4d %4.4d %4.4d\r\n"),
1509 spi_servo_get(0), spi_servo_get(1), spi_servo_get(2),
1510 spi_servo_get(3), spi_servo_get(4), spi_servo_get(5));
1513 printf_P(PSTR("PPM to servo\r\n"));
1514 spi_servo_set_bypass(0);
1515 spi_servo_set_ppm(0);
1517 /* test PPM to servo (bypass) mode */
1518 while (!cmdline_keypressed()) {
1519 for (i = 0; i < 6; i++) {
1520 val = spi_servo_get(i);
1521 spi_servo_set(i, val);
1525 printf_P(PSTR("PPM to (servo + PPM)\r\n"));
1526 spi_servo_set_bypass(0);
1527 spi_servo_set_ppm(1);
1529 /* test PPM to servo (bypass) mode */
1530 while (!cmdline_keypressed()) {
1531 for (i = 0; i < 6; i++) {
1532 val = spi_servo_get(i);
1533 spi_servo_set(i, val);
1538 const char PROGMEM str_test_spi_arg0[] = "test_spi";
1539 const parse_token_string_t PROGMEM cmd_test_spi_arg0 =
1540 TOKEN_STRING_INITIALIZER(struct cmd_test_spi_result, arg0,
1543 const char PROGMEM help_test_spi[] = "Test the spi";
1544 const parse_inst_t PROGMEM cmd_test_spi = {
1545 .f = cmd_test_spi_parsed, /* function to call */
1546 .data = NULL, /* 2nd arg of func */
1547 .help_str = help_test_spi,
1548 .tokens = { /* token list, NULL terminated */
1549 (PGM_P)&cmd_test_spi_arg0,
1554 /**********************************************************/
1556 /* this structure is filled when cmd_test_eeprom_config is parsed successfully */
1557 struct cmd_test_eeprom_config_result {
1558 fixed_string_t arg0;
1561 static void cmd_test_eeprom_config_parsed(void *parsed_result, void *data)
1563 (void)parsed_result;
1567 eeprom_append_cmd("salut1\n");
1569 eeprom_append_cmd("salut2\n");
1570 eeprom_append_cmd("salut3\n");
1571 eeprom_append_cmd("salut4\n");
1573 eeprom_insert_cmd_before("coin\n", 0);
1574 eeprom_insert_cmd_before("coin2\n", 2);
1576 eeprom_delete_cmd(2);
1577 eeprom_delete_cmd(0);
1581 const char PROGMEM str_test_eeprom_config_arg0[] = "test_eeprom_config";
1582 const parse_token_string_t PROGMEM cmd_test_eeprom_config_arg0 =
1583 TOKEN_STRING_INITIALIZER(struct cmd_test_eeprom_config_result, arg0,
1584 str_test_eeprom_config_arg0);
1586 const char PROGMEM help_test_eeprom_config[] = "Test the eeprom configuration";
1587 const parse_inst_t PROGMEM cmd_test_eeprom_config = {
1588 .f = cmd_test_eeprom_config_parsed, /* function to call */
1589 .data = NULL, /* 2nd arg of func */
1590 .help_str = help_test_eeprom_config,
1591 .tokens = { /* token list, NULL terminated */
1592 (PGM_P)&cmd_test_eeprom_config_arg0,
1599 struct cmd_eeprom_del_result {
1601 fixed_string_t action;
1605 static void cmd_eeprom_del_parsed(void *parsed_result,
1608 struct cmd_eeprom_del_result *res = parsed_result;
1611 if (eeprom_delete_cmd(res->n) < 0)
1612 printf_P(PSTR("cannot delete command\n"));
1616 const char PROGMEM str_eeprom_del_eeprom[] = "eeprom";
1617 const parse_token_string_t PROGMEM cmd_eeprom_del_cmd =
1618 TOKEN_STRING_INITIALIZER(struct cmd_eeprom_del_result, cmd,
1619 str_eeprom_del_eeprom);
1620 const char PROGMEM str_eeprom_del_del[] = "del";
1621 const parse_token_string_t PROGMEM cmd_eeprom_del_action =
1622 TOKEN_STRING_INITIALIZER(struct cmd_eeprom_del_result, action,
1623 str_eeprom_del_del);
1624 const parse_token_num_t PROGMEM cmd_eeprom_del_num =
1625 TOKEN_NUM_INITIALIZER(struct cmd_eeprom_del_result, n,
1628 const char PROGMEM help_eeprom_del[] = "delete an eeprom init command";
1629 const parse_inst_t PROGMEM cmd_eeprom_del = {
1630 .f = cmd_eeprom_del_parsed, /* function to call */
1631 .data = NULL, /* 2nd arg of func */
1632 .help_str = help_eeprom_del,
1633 .tokens = { /* token list, NULL terminated */
1634 (PGM_P)&cmd_eeprom_del_cmd,
1635 (PGM_P)&cmd_eeprom_del_action,
1636 (PGM_P)&cmd_eeprom_del_num,
1643 struct cmd_eeprom_add_result {
1645 fixed_string_t action;
1649 static void cmd_eeprom_add_parsed(void *parsed_result,
1652 struct cmd_eeprom_add_result *res = parsed_result;
1658 rdline_init(&rdl, cmdline_write_char, NULL, NULL);
1659 rdline_newline(&rdl, "> ");
1661 /* XXX bad: we should not block as we do not serve callout */
1663 c = cmdline_dev_recv(NULL);
1667 ret = rdline_char_in(&rdl, c);
1669 printf_P(PSTR("abort\n"));
1676 buffer = rdline_get_buffer(&rdl);
1678 eeprom_insert_cmd_before(buffer, res->n);
1680 eeprom_append_cmd(buffer);
1684 const char PROGMEM str_eeprom_add_eeprom[] = "eeprom";
1685 const parse_token_string_t PROGMEM cmd_eeprom_add_cmd =
1686 TOKEN_STRING_INITIALIZER(struct cmd_eeprom_add_result, cmd,
1687 str_eeprom_add_eeprom);
1688 const char PROGMEM str_eeprom_add_add[] = "add";
1689 const parse_token_string_t PROGMEM cmd_eeprom_add_action =
1690 TOKEN_STRING_INITIALIZER(struct cmd_eeprom_add_result, action,
1691 str_eeprom_add_add);
1692 const parse_token_num_t PROGMEM cmd_eeprom_add_num =
1693 TOKEN_NUM_INITIALIZER(struct cmd_eeprom_add_result, n,
1696 const char PROGMEM help_eeprom_add[] = "insert an eeprom init command";
1697 const parse_inst_t PROGMEM cmd_eeprom_add = {
1698 .f = cmd_eeprom_add_parsed, /* function to call */
1699 .data = NULL, /* 2nd arg of func */
1700 .help_str = help_eeprom_add,
1701 .tokens = { /* token list, NULL terminated */
1702 (PGM_P)&cmd_eeprom_add_cmd,
1703 (PGM_P)&cmd_eeprom_add_action,
1704 (PGM_P)&cmd_eeprom_add_num,
1709 const char PROGMEM help_eeprom_add2[] = "append an eeprom init command";
1710 const parse_inst_t PROGMEM cmd_eeprom_add2 = {
1711 .f = cmd_eeprom_add_parsed, /* function to call */
1712 .data = (void *)1, /* 2nd arg of func */
1713 .help_str = help_eeprom_add2,
1714 .tokens = { /* token list, NULL terminated */
1715 (PGM_P)&cmd_eeprom_add_cmd,
1716 (PGM_P)&cmd_eeprom_add_action,
1723 struct cmd_eeprom_list_result {
1725 fixed_string_t action;
1728 static void cmd_eeprom_list_parsed(void *parsed_result,
1731 (void)parsed_result;
1736 const char PROGMEM str_eeprom_list_eeprom[] = "eeprom";
1737 const parse_token_string_t PROGMEM cmd_eeprom_list_cmd =
1738 TOKEN_STRING_INITIALIZER(struct cmd_eeprom_list_result, cmd,
1739 str_eeprom_list_eeprom);
1740 const char PROGMEM str_eeprom_list_list[] = "list";
1741 const parse_token_string_t PROGMEM cmd_eeprom_list_action =
1742 TOKEN_STRING_INITIALIZER(struct cmd_eeprom_list_result, action,
1743 str_eeprom_list_list);
1745 const char PROGMEM help_eeprom_list[] = "list all eeprom init commands";
1746 const parse_inst_t PROGMEM cmd_eeprom_list = {
1747 .f = cmd_eeprom_list_parsed, /* function to call */
1748 .data = NULL, /* 2nd arg of func */
1749 .help_str = help_eeprom_list,
1750 .tokens = { /* token list, NULL terminated */
1751 (PGM_P)&cmd_eeprom_list_cmd,
1752 (PGM_P)&cmd_eeprom_list_action,
1761 const parse_ctx_t PROGMEM main_ctx[] = {
1763 /* commands_gen.c */
1785 &cmd_range_powermask,
1788 &cmd_monitor_period,
1798 &cmd_servo_bypassppm,
1801 &cmd_test_eeprom_config,