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_send_hello is parsed successfully */
573 struct cmd_send_hello_result {
574 fixed_string_t send_hello;
576 struct xbee_neigh *neigh;
582 /* function called when cmd_send_hello is parsed successfully */
583 static void cmd_send_hello_parsed(void *parsed_result, void *use_neigh)
585 struct cmd_send_hello_result *res = parsed_result;
586 uint16_t now, next, diff;
591 addr = res->neigh->addr;
601 while (!cmdline_keypressed() && res->count != 0) {
607 if (diff < res->period)
610 rc_proto_send_hello(addr, res->data, strlen(res->data));
616 const char PROGMEM str_send_hello[] = "send_hello";
618 const parse_token_string_t PROGMEM cmd_send_hello_send_hello =
619 TOKEN_STRING_INITIALIZER(struct cmd_send_hello_result, send_hello,
622 const parse_token_num_t PROGMEM cmd_send_hello_addr =
623 TOKEN_NUM_INITIALIZER(struct cmd_send_hello_result, addr, UINT64);
625 const parse_token_num_t PROGMEM cmd_send_hello_period =
626 TOKEN_NUM_INITIALIZER(struct cmd_send_hello_result, period, UINT16);
628 const parse_token_num_t PROGMEM cmd_send_hello_count =
629 TOKEN_NUM_INITIALIZER(struct cmd_send_hello_result, count, UINT16);
631 const parse_token_string_t PROGMEM cmd_send_hello_data =
632 TOKEN_STRING_INITIALIZER(struct cmd_send_hello_result, data, NULL);
634 const char PROGMEM help_send_hello[] =
635 "Send hello msg to a node: addr, period_ms, count, str";
637 const parse_inst_t PROGMEM cmd_send_hello = {
638 .f = cmd_send_hello_parsed, /* function to call */
639 .data = NULL, /* 2nd arg of func */
640 .help_str = help_send_hello,
641 .tokens = { /* token list, NULL terminated */
642 (PGM_P)&cmd_send_hello_send_hello,
643 (PGM_P)&cmd_send_hello_addr,
644 (PGM_P)&cmd_send_hello_period,
645 (PGM_P)&cmd_send_hello_count,
646 (PGM_P)&cmd_send_hello_data,
651 const parse_token_neighbor_t PROGMEM cmd_send_hello_neigh =
652 TOKEN_NEIGHBOR_INITIALIZER(struct cmd_send_hello_result, neigh,
655 const parse_inst_t PROGMEM cmd_send_hello_name = {
656 .f = cmd_send_hello_parsed, /* function to call */
657 .data = (void *)1, /* 2nd arg of func */
658 .help_str = help_send_hello,
659 .tokens = { /* token list, NULL terminated */
660 (PGM_P)&cmd_send_hello_send_hello,
661 (PGM_P)&cmd_send_hello_neigh,
662 (PGM_P)&cmd_send_hello_period,
663 (PGM_P)&cmd_send_hello_count,
664 (PGM_P)&cmd_send_hello_data,
671 /* this structure is filled when cmd_sendmsg_name is parsed successfully */
672 struct cmd_sendmsg_name_result {
673 fixed_string_t sendmsg_name;
674 struct xbee_neigh *neigh;
678 /* function called when cmd_sendmsg_name is parsed successfully */
679 static void cmd_sendmsg_name_parsed(void *parsed_result, void *data)
681 struct cmd_sendmsg_name_result *res = parsed_result;
684 xbeeapp_send_msg(res->neigh->addr, res->data, strlen(res->data), 1);
687 const parse_token_string_t PROGMEM cmd_sendmsg_name_sendmsg_name =
688 TOKEN_STRING_INITIALIZER(struct cmd_sendmsg_name_result, sendmsg_name,
691 const parse_token_neighbor_t PROGMEM cmd_sendmsg_name_neigh =
692 TOKEN_NEIGHBOR_INITIALIZER(struct cmd_sendmsg_name_result, neigh,
695 const parse_token_string_t PROGMEM cmd_sendmsg_name_data =
696 TOKEN_STRING_INITIALIZER(struct cmd_sendmsg_name_result, data, NULL);
698 const char PROGMEM help_sendmsg_name[] = "Send data to a node using its name";
700 const parse_inst_t PROGMEM cmd_sendmsg_name = {
701 .f = cmd_sendmsg_name_parsed, /* function to call */
702 .data = NULL, /* 2nd arg of func */
703 .help_str = help_sendmsg_name,
704 .tokens = { /* token list, NULL terminated */
705 (PGM_P)&cmd_sendmsg_name_sendmsg_name,
706 (PGM_P)&cmd_sendmsg_name_neigh,
707 (PGM_P)&cmd_sendmsg_name_data,
715 /* this structure is filled when cmd_range is parsed successfully */
716 struct cmd_range_result {
717 fixed_string_t range;
718 fixed_string_t action;
721 /* function called when cmd_range is parsed successfully */
722 static void cmd_range_parsed(void *parsed_result, void *data)
724 struct cmd_range_result *res = parsed_result;
727 if (!strcmp_P(res->action, PSTR("show"))) {
728 printf_P(PSTR("range infos:\r\n"));
729 printf_P(PSTR(" range period %d\r\n"), range_period_ms);
730 printf_P(PSTR(" range count %d\r\n"), range_count);
731 printf_P(PSTR(" range powermask 0x%x\r\n"), range_powermask);
732 printf_P(PSTR(" range dstaddr 0x%.8"PRIx32"%.8"PRIx32"\r\n"),
733 (uint32_t)(range_dstaddr >> 32ULL),
734 (uint32_t)(range_dstaddr & 0xFFFFFFFF));
737 printf_P(PSTR(" range test is running\r\n"));
739 printf_P(PSTR(" range test is not running\r\n"));
741 else if (!strcmp(res->action, "start")) {
743 printf_P(PSTR("already running\r\n"));
746 range_cur_count = range_count;
747 callout_init(&range_event);
748 callout_reset(&cm, &range_event, 0,
749 SINGLE, range_cb, NULL);
752 else if (!strcmp(res->action, "end")) {
753 if (range_running == 0) {
754 printf_P(PSTR("not running\r\n"));
758 callout_stop(&cm, &range_event);
762 const char PROGMEM str_range[] = "range";
763 const char PROGMEM str_range_tokens[] = "show#start#end";
765 const parse_token_string_t PROGMEM cmd_range_range =
766 TOKEN_STRING_INITIALIZER(struct cmd_range_result, range,
768 const parse_token_string_t PROGMEM cmd_range_action =
769 TOKEN_STRING_INITIALIZER(struct cmd_range_result, action,
772 const char PROGMEM help_range[] = "start/stop/show current rangeing";
774 const parse_inst_t PROGMEM cmd_range = {
775 .f = cmd_range_parsed, /* function to call */
776 .data = NULL, /* 2nd arg of func */
777 .help_str = help_range,
778 .tokens = { /* token list, NULL terminated */
779 (PGM_P)&cmd_range_range,
780 (PGM_P)&cmd_range_action,
787 /* this structure is filled when cmd_range_period is parsed successfully */
788 struct cmd_range_period_result {
789 fixed_string_t range;
790 fixed_string_t action;
794 /* function called when cmd_range_period is parsed successfully */
795 static void cmd_range_period_parsed(void *parsed_result, void *data)
797 struct cmd_range_period_result *res = parsed_result;
800 if (res->period < 10) {
801 printf_P(PSTR("error, minimum period is 10 ms\r\n"));
805 range_period_ms = res->period;
808 const char PROGMEM str_period[] = "period";
810 const parse_token_string_t PROGMEM cmd_range_period_range_period =
811 TOKEN_STRING_INITIALIZER(struct cmd_range_period_result, range,
813 const parse_token_string_t PROGMEM cmd_range_period_action =
814 TOKEN_STRING_INITIALIZER(struct cmd_range_period_result, action,
816 const parse_token_num_t PROGMEM cmd_range_period_period =
817 TOKEN_NUM_INITIALIZER(struct cmd_range_period_result, period, UINT32);
819 const char PROGMEM help_range_period[] = "set range test period";
821 const parse_inst_t PROGMEM cmd_range_period = {
822 .f = cmd_range_period_parsed, /* function to call */
823 .data = NULL, /* 2nd arg of func */
824 .help_str = help_range_period,
825 .tokens = { /* token list, NULL terminated */
826 (PGM_P)&cmd_range_period_range_period,
827 (PGM_P)&cmd_range_period_action,
828 (PGM_P)&cmd_range_period_period,
835 /* this structure is filled when cmd_range_count is parsed successfully */
836 struct cmd_range_count_result {
837 fixed_string_t range;
838 fixed_string_t action;
842 /* function called when cmd_range_count is parsed successfully */
843 static void cmd_range_count_parsed(void *parsed_result, void *data)
845 struct cmd_range_count_result *res = parsed_result;
848 range_count = res->count;
851 const char PROGMEM str_count[] = "count";
853 const parse_token_string_t PROGMEM cmd_range_count_range_count =
854 TOKEN_STRING_INITIALIZER(struct cmd_range_count_result, range,
856 const parse_token_string_t PROGMEM cmd_range_count_action =
857 TOKEN_STRING_INITIALIZER(struct cmd_range_count_result, action,
859 const parse_token_num_t PROGMEM cmd_range_count_count =
860 TOKEN_NUM_INITIALIZER(struct cmd_range_count_result, count, UINT32);
863 const char PROGMEM help_range_count[] = "set range test count";
865 const parse_inst_t PROGMEM cmd_range_count = {
866 .f = cmd_range_count_parsed, /* function to call */
867 .data = NULL, /* 2nd arg of func */
868 .help_str = help_range_count,
869 .tokens = { /* token list, NULL terminated */
870 (PGM_P)&cmd_range_count_range_count,
871 (PGM_P)&cmd_range_count_action,
872 (PGM_P)&cmd_range_count_count,
879 /* this structure is filled when cmd_range_powermask is parsed successfully */
880 struct cmd_range_powermask_result {
881 fixed_string_t range;
882 fixed_string_t action;
886 /* function called when cmd_range_powermask is parsed successfully */
887 static void cmd_range_powermask_parsed(void *parsed_result, void *data)
889 struct cmd_range_powermask_result *res = parsed_result;
892 range_powermask = res->powermask;
895 const char PROGMEM str_powermask[] = "powermask";
897 const parse_token_string_t PROGMEM cmd_range_powermask_range_powermask =
898 TOKEN_STRING_INITIALIZER(struct cmd_range_powermask_result, range,
900 const parse_token_string_t PROGMEM cmd_range_powermask_action =
901 TOKEN_STRING_INITIALIZER(struct cmd_range_powermask_result, action,
903 const parse_token_num_t PROGMEM cmd_range_powermask_powermask =
904 TOKEN_NUM_INITIALIZER(struct cmd_range_powermask_result, powermask,
908 const char PROGMEM help_range_powermask[] = "set range test powermask";
910 const parse_inst_t PROGMEM cmd_range_powermask = {
911 .f = cmd_range_powermask_parsed, /* function to call */
912 .data = NULL, /* 2nd arg of func */
913 .help_str = help_range_powermask,
914 .tokens = { /* token list, NULL terminated */
915 (PGM_P)&cmd_range_powermask_range_powermask,
916 (PGM_P)&cmd_range_powermask_action,
917 (PGM_P)&cmd_range_powermask_powermask,
924 /* this structure is filled when cmd_range_dstaddr is parsed successfully */
925 struct cmd_range_dstaddr_result {
926 fixed_string_t range;
927 fixed_string_t action;
931 /* function called when cmd_range_dstaddr is parsed successfully */
932 static void cmd_range_dstaddr_parsed(void *parsed_result, void *data)
934 struct cmd_range_dstaddr_result *res = parsed_result;
937 range_dstaddr = res->dstaddr;
940 const char PROGMEM str_dstaddr[] = "dstaddr";
942 const parse_token_string_t PROGMEM cmd_range_dstaddr_range_dstaddr =
943 TOKEN_STRING_INITIALIZER(struct cmd_range_dstaddr_result, range,
945 const parse_token_string_t PROGMEM cmd_range_dstaddr_action =
946 TOKEN_STRING_INITIALIZER(struct cmd_range_dstaddr_result, action,
948 const parse_token_num_t PROGMEM cmd_range_dstaddr_dstaddr =
949 TOKEN_NUM_INITIALIZER(struct cmd_range_dstaddr_result, dstaddr, UINT64);
952 const char PROGMEM help_range_dstaddr[] = "set register rangeing dstaddr";
954 const parse_inst_t PROGMEM cmd_range_dstaddr = {
955 .f = cmd_range_dstaddr_parsed, /* function to call */
956 .data = NULL, /* 2nd arg of func */
957 .help_str = help_range_dstaddr,
958 .tokens = { /* token list, NULL terminated */
959 (PGM_P)&cmd_range_dstaddr_range_dstaddr,
960 (PGM_P)&cmd_range_dstaddr_action,
961 (PGM_P)&cmd_range_dstaddr_dstaddr,
969 /* this structure is filled when cmd_monitor is parsed successfully */
970 struct cmd_monitor_result {
971 fixed_string_t monitor;
972 fixed_string_t action;
975 /* function called when cmd_monitor is parsed successfully */
976 static void cmd_monitor_parsed(void *parsed_result, void *data)
978 struct cmd_monitor_result *res = parsed_result;
979 struct monitor_reg *m;
982 if (!strcmp_P(res->action, PSTR("show"))) {
983 printf_P(PSTR("monitor period is %d ms, %d regs in list\r\n"),
984 monitor_period_ms, monitor_count);
985 LIST_FOREACH(m, &xbee_monitor_list, next)
986 printf_P(PSTR(" %S\r\n"), m->desc);
988 else if (!strcmp_P(res->action, PSTR("start"))) {
989 if (monitor_running) {
990 printf_P(PSTR("already running\r\n"));
993 if (monitor_count == 0) {
994 printf_P(PSTR("no regs to be monitored\r\n"));
997 callout_init(&monitor_event);
998 callout_reset(&cm, &monitor_event, 0, SINGLE, monitor_cb, NULL);
1000 monitor_current = LIST_FIRST(&xbee_monitor_list);
1001 printf_P(PSTR("monitor cb: %S %s\r\n"),
1002 monitor_current->desc,
1003 monitor_current->atcmd);
1006 else if (!strcmp_P(res->action, PSTR("end"))) {
1007 if (monitor_running == 0) {
1008 printf_P(PSTR("not running\r\n"));
1011 monitor_running = 0;
1012 callout_stop(&cm, &monitor_event);
1016 const char PROGMEM str_monitor[] = "monitor";
1017 const char PROGMEM str_monitor_tokens[] = "show#start#end";
1019 const parse_token_string_t PROGMEM cmd_monitor_monitor =
1020 TOKEN_STRING_INITIALIZER(struct cmd_monitor_result, monitor,
1022 const parse_token_string_t PROGMEM cmd_monitor_action =
1023 TOKEN_STRING_INITIALIZER(struct cmd_monitor_result, action,
1024 str_monitor_tokens);
1026 const char PROGMEM help_monitor[] = "start/stop/show current monitoring";
1028 const parse_inst_t PROGMEM cmd_monitor = {
1029 .f = cmd_monitor_parsed, /* function to call */
1030 .data = NULL, /* 2nd arg of func */
1031 .help_str = help_monitor,
1032 .tokens = { /* token list, NULL terminated */
1033 (PGM_P)&cmd_monitor_monitor,
1034 (PGM_P)&cmd_monitor_action,
1041 /* this structure is filled when cmd_monitor_add is parsed successfully */
1042 struct cmd_monitor_add_result {
1043 fixed_string_t monitor;
1044 fixed_string_t action;
1045 struct xbee_atcmd *cmd;
1048 /* function called when cmd_monitor_add is parsed successfully */
1049 static void cmd_monitor_add_parsed(void *parsed_result, void *data)
1051 struct cmd_monitor_add_result *res = parsed_result;
1052 struct monitor_reg *m;
1053 struct xbee_atcmd copy;
1056 memcpy_P(©, res->cmd, sizeof(copy));
1057 LIST_FOREACH(m, &xbee_monitor_list, next) {
1058 if (!strcmp_P(m->atcmd, copy.name))
1063 printf_P(PSTR("already exist\r\n"));
1067 m = malloc(sizeof(*m));
1069 printf_P(PSTR("no mem\r\n"));
1072 m->desc = copy.desc;
1073 strcpy_P(m->atcmd, copy.name);
1074 LIST_INSERT_HEAD(&xbee_monitor_list, m, next);
1078 const char PROGMEM str_monitor_add[] = "add";
1080 const parse_token_string_t PROGMEM cmd_monitor_add_monitor_add =
1081 TOKEN_STRING_INITIALIZER(struct cmd_monitor_add_result, monitor,
1083 const parse_token_string_t PROGMEM cmd_monitor_add_action =
1084 TOKEN_STRING_INITIALIZER(struct cmd_monitor_add_result, action,
1086 const parse_token_atcmd_t PROGMEM cmd_monitor_add_atcmd =
1087 TOKEN_ATCMD_INITIALIZER(struct cmd_monitor_add_result, cmd, &xbee_dev,
1088 XBEE_ATCMD_F_READ, XBEE_ATCMD_F_READ);
1091 const char PROGMEM help_monitor_add[] = "add a register in monitor list";
1093 const parse_inst_t PROGMEM cmd_monitor_add = {
1094 .f = cmd_monitor_add_parsed, /* function to call */
1095 .data = NULL, /* 2nd arg of func */
1096 .help_str = help_monitor_add,
1097 .tokens = { /* token list, NULL terminated */
1098 (PGM_P)&cmd_monitor_add_monitor_add,
1099 (PGM_P)&cmd_monitor_add_action,
1100 (PGM_P)&cmd_monitor_add_atcmd,
1107 /* this structure is filled when cmd_monitor_period is parsed successfully */
1108 struct cmd_monitor_period_result {
1109 fixed_string_t monitor;
1110 fixed_string_t action;
1114 /* function called when cmd_monitor_period is parsed successfully */
1115 static void cmd_monitor_period_parsed(void *parsed_result, void *data)
1117 struct cmd_monitor_period_result *res = parsed_result;
1120 if (res->period < 100) {
1121 printf_P(PSTR("error, minimum period is 100 ms\r\n"));
1125 monitor_period_ms = res->period;
1128 const char PROGMEM str_monitor_period[] = "period";
1130 const parse_token_string_t PROGMEM cmd_monitor_period_monitor_period =
1131 TOKEN_STRING_INITIALIZER(struct cmd_monitor_period_result, monitor,
1133 const parse_token_string_t PROGMEM cmd_monitor_period_action =
1134 TOKEN_STRING_INITIALIZER(struct cmd_monitor_period_result, action,
1135 str_monitor_period);
1136 const parse_token_num_t PROGMEM cmd_monitor_period_period =
1137 TOKEN_NUM_INITIALIZER(struct cmd_monitor_period_result, period, UINT32);
1140 const char PROGMEM help_monitor_period[] = "set register monitoring period";
1142 const parse_inst_t PROGMEM cmd_monitor_period = {
1143 .f = cmd_monitor_period_parsed, /* function to call */
1144 .data = NULL, /* 2nd arg of func */
1145 .help_str = help_monitor_period,
1146 .tokens = { /* token list, NULL terminated */
1147 (PGM_P)&cmd_monitor_period_monitor_period,
1148 (PGM_P)&cmd_monitor_period_action,
1149 (PGM_P)&cmd_monitor_period_period,
1156 /* this structure is filled when cmd_monitor_del is parsed successfully */
1157 struct cmd_monitor_del_result {
1158 fixed_string_t monitor;
1159 fixed_string_t action;
1160 struct monitor_reg *m;
1163 /* function called when cmd_monitor_del is parsed successfully */
1164 static void cmd_monitor_del_parsed(void *parsed_result, void *data)
1166 struct cmd_monitor_del_result *res = parsed_result;
1169 monitor_current = LIST_NEXT(res->m, next);
1170 LIST_REMOVE(res->m, next);
1173 if (monitor_count == 0) {
1174 printf_P(PSTR("Disable monitoring, no more event\r\n"));
1175 callout_stop(&cm, &monitor_event);
1176 monitor_running = 0;
1181 const char PROGMEM str_monitor_del[] = "del";
1183 const parse_token_string_t PROGMEM cmd_monitor_del_monitor_del =
1184 TOKEN_STRING_INITIALIZER(struct cmd_monitor_del_result, monitor,
1186 const parse_token_string_t PROGMEM cmd_monitor_del_action =
1187 TOKEN_STRING_INITIALIZER(struct cmd_monitor_del_result, action,
1189 const parse_token_monitor_t PROGMEM cmd_monitor_del_atcmd =
1190 TOKEN_MONITOR_INITIALIZER(struct cmd_monitor_del_result, m);
1193 const char PROGMEM help_monitor_del[] = "del a register in monitor list";
1195 const parse_inst_t PROGMEM cmd_monitor_del = {
1196 .f = cmd_monitor_del_parsed, /* function to call */
1197 .data = NULL, /* 2nd arg of func */
1198 .help_str = help_monitor_del,
1199 .tokens = { /* token list, NULL terminated */
1200 (PGM_P)&cmd_monitor_del_monitor_del,
1201 (PGM_P)&cmd_monitor_del_action,
1202 (PGM_P)&cmd_monitor_del_atcmd,
1210 /* this structure is filled when cmd_ping is parsed successfully */
1211 struct cmd_ping_result {
1212 fixed_string_t ping;
1215 /* function called when cmd_ping is parsed successfully */
1216 static void cmd_ping_parsed(void *parsed_result, void *data)
1218 (void)parsed_result;
1220 xbeeapp_send_atcmd("VL", NULL, 0, 1, NULL, NULL);
1223 const char PROGMEM str_ping[] = "ping";
1225 const parse_token_string_t PROGMEM cmd_ping_ping =
1226 TOKEN_STRING_INITIALIZER(struct cmd_ping_result, ping,
1229 const char PROGMEM help_ping[] = "Send a ping to the xbee device";
1231 const parse_inst_t PROGMEM cmd_ping = {
1232 .f = cmd_ping_parsed, /* function to call */
1233 .data = NULL, /* 2nd arg of func */
1234 .help_str = help_ping,
1235 .tokens = { /* token list, NULL terminated */
1236 (PGM_P)&cmd_ping_ping,
1243 /* this structure is filled when cmd_raw is parsed successfully */
1244 struct cmd_raw_result {
1248 /* function called when cmd_raw is parsed successfully */
1249 static void cmd_raw_parsed(void *parsed_result, void *data)
1251 (void)parsed_result;
1253 printf_P(PSTR("switched to raw mode, CTRL-D to exit\r\n"));
1254 rdline_stop(&xbeeboard.rdl); /* don't display prompt when return */
1258 const char PROGMEM str_raw[] = "raw";
1260 const parse_token_string_t PROGMEM cmd_raw_raw =
1261 TOKEN_STRING_INITIALIZER(struct cmd_raw_result, raw,
1264 const char PROGMEM help_raw[] = "Switch to raw mode";
1266 const parse_inst_t PROGMEM cmd_raw = {
1267 .f = cmd_raw_parsed, /* function to call */
1268 .data = NULL, /* 2nd arg of func */
1269 .help_str = help_raw,
1270 .tokens = { /* token list, NULL terminated */
1271 (PGM_P)&cmd_raw_raw,
1278 /* this structure is filled when cmd_dump is parsed successfully */
1279 struct cmd_dump_result {
1280 fixed_string_t dump;
1281 fixed_string_t onoff;
1284 /* function called when cmd_dump is parsed successfully */
1285 static void cmd_dump_parsed(void *parsed_result, void *data)
1287 struct cmd_dump_result *res = parsed_result;
1290 if (!strcmp(res->onoff, "on"))
1296 const char PROGMEM str_dump[] = "dump";
1297 const char PROGMEM str_dump_onoff[] = "on#off";
1299 const parse_token_string_t PROGMEM cmd_dump_dump =
1300 TOKEN_STRING_INITIALIZER(struct cmd_dump_result, dump,
1303 const parse_token_string_t PROGMEM cmd_dump_onoff =
1304 TOKEN_STRING_INITIALIZER(struct cmd_dump_result, onoff,
1307 const char PROGMEM help_dump[] = "enable/disable hexdump of received packets";
1309 const parse_inst_t PROGMEM cmd_dump = {
1310 .f = cmd_dump_parsed, /* function to call */
1311 .data = NULL, /* 2nd arg of func */
1312 .help_str = help_dump,
1313 .tokens = { /* token list, NULL terminated */
1314 (PGM_P)&cmd_dump_dump,
1315 (PGM_P)&cmd_dump_onoff,
1322 /* this structure is filled when cmd_debug is parsed successfully */
1323 struct cmd_debug_result {
1324 fixed_string_t debug;
1325 fixed_string_t onoff;
1328 /* function called when cmd_debug is parsed successfully */
1329 static void cmd_debug_parsed(void *parsed_result, void *data)
1331 struct cmd_debug_result *res = parsed_result;
1334 if (!strcmp(res->onoff, "on"))
1340 const char PROGMEM str_debug[] = "debug";
1341 const char PROGMEM str_debug_onoff[] = "on#off";
1343 const parse_token_string_t PROGMEM cmd_debug_debug =
1344 TOKEN_STRING_INITIALIZER(struct cmd_debug_result, debug,
1347 const parse_token_string_t PROGMEM cmd_debug_onoff =
1348 TOKEN_STRING_INITIALIZER(struct cmd_debug_result, onoff,
1351 const char PROGMEM help_debug[] = "enable/disable additionnal debug";
1353 const parse_inst_t PROGMEM cmd_debug = {
1354 .f = cmd_debug_parsed, /* function to call */
1355 .data = NULL, /* 2nd arg of func */
1356 .help_str = help_debug,
1357 .tokens = { /* token list, NULL terminated */
1358 (PGM_P)&cmd_debug_debug,
1359 (PGM_P)&cmd_debug_onoff,
1364 /**********************************************************/
1366 /* this structure is filled when cmd_baudrate is parsed successfully */
1367 struct cmd_baudrate_result {
1368 fixed_string_t arg0;
1372 /* function called when cmd_baudrate is parsed successfully */
1373 static void cmd_baudrate_parsed(void * parsed_result, __attribute__((unused)) void *data)
1375 struct cmd_baudrate_result *res = parsed_result;
1376 struct uart_config c;
1378 uart_getconf(XBEE_UART, &c);
1379 c.baudrate = res->arg1;
1380 uart_setconf(XBEE_UART, &c);
1383 const char PROGMEM str_baudrate_arg0[] = "baudrate";
1384 const parse_token_string_t PROGMEM cmd_baudrate_arg0 =
1385 TOKEN_STRING_INITIALIZER(struct cmd_baudrate_result, arg0,
1387 const parse_token_num_t PROGMEM cmd_baudrate_arg1 =
1388 TOKEN_NUM_INITIALIZER(struct cmd_baudrate_result, arg1,
1391 const char PROGMEM help_baudrate[] = "Change xbee baudrate";
1392 const parse_inst_t PROGMEM cmd_baudrate = {
1393 .f = cmd_baudrate_parsed, /* function to call */
1394 .data = NULL, /* 2nd arg of func */
1395 .help_str = help_baudrate,
1396 .tokens = { /* token list, NULL terminated */
1397 (PGM_P)&cmd_baudrate_arg0,
1398 (PGM_P)&cmd_baudrate_arg1,
1404 /**********************************************************/
1406 /* this structure is filled when cmd_beep is parsed successfully */
1407 struct cmd_beep_result {
1408 fixed_string_t beep;
1411 /* function called when cmd_beep is parsed successfully */
1412 static void cmd_beep_parsed(void *parsed_result, void *data)
1414 (void)parsed_result;
1425 const char PROGMEM str_beep[] = "beep";
1426 const parse_token_string_t PROGMEM cmd_beep_beep =
1427 TOKEN_STRING_INITIALIZER(struct cmd_beep_result, beep,
1430 const char PROGMEM help_beep[] = "Send a beep";
1432 const parse_inst_t PROGMEM cmd_beep = {
1433 .f = cmd_beep_parsed, /* function to call */
1434 .data = NULL, /* 2nd arg of func */
1435 .help_str = help_beep,
1436 .tokens = { /* token list, NULL terminated */
1437 (PGM_P)&cmd_beep_beep,
1442 /**********************************************************/
1444 /* this structure is filled when cmd_servo is parsed successfully */
1445 struct cmd_servo_result {
1446 fixed_string_t arg0;
1447 fixed_string_t arg1;
1452 /* function called when cmd_servo is parsed successfully */
1453 static void cmd_servo_parsed(void * parsed_result, void *data)
1455 struct cmd_servo_result *res = parsed_result;
1459 if (!strcmp_P(res->arg1, PSTR("set"))) {
1460 if (res->num >= N_SERVO) {
1461 printf_P(PSTR("bad servo num\n"));
1464 if (res->val >= 1024) {
1465 printf_P(PSTR("bad servo val\n"));
1468 spi_servo_set(res->num, res->val);
1470 else if (!strcmp_P(res->arg1, PSTR("bypass"))) {
1471 spi_servo_set_bypass(!!res->val);
1473 else if (!strcmp_P(res->arg1, PSTR("ppm"))) {
1474 spi_servo_set_ppm(!!res->val);
1476 else if (!strcmp_P(res->arg1, PSTR("show"))) {
1481 const char PROGMEM str_servo_arg0[] = "servo";
1482 const parse_token_string_t PROGMEM cmd_servo_arg0 =
1483 TOKEN_STRING_INITIALIZER(struct cmd_servo_result, arg0,
1485 const char PROGMEM str_servo_arg1_set[] = "set";
1486 const parse_token_string_t PROGMEM cmd_servo_arg1_set =
1487 TOKEN_STRING_INITIALIZER(struct cmd_servo_result, arg1,
1488 str_servo_arg1_set);
1489 const parse_token_num_t PROGMEM cmd_servo_num =
1490 TOKEN_NUM_INITIALIZER(struct cmd_servo_result, num,
1492 const parse_token_num_t PROGMEM cmd_servo_val =
1493 TOKEN_NUM_INITIALIZER(struct cmd_servo_result, val,
1496 const char PROGMEM help_servo_set[] = "set servo value";
1497 const parse_inst_t PROGMEM cmd_servo_set = {
1498 .f = cmd_servo_parsed, /* function to call */
1499 .data = NULL, /* 2nd arg of func */
1500 .help_str = help_servo_set,
1501 .tokens = { /* token list, NULL terminated */
1502 (PGM_P)&cmd_servo_arg0,
1503 (PGM_P)&cmd_servo_arg1_set,
1504 (PGM_P)&cmd_servo_num,
1505 (PGM_P)&cmd_servo_val,
1510 const char PROGMEM str_servo_arg1_show[] = "show";
1511 const parse_token_string_t PROGMEM cmd_servo_arg1_show =
1512 TOKEN_STRING_INITIALIZER(struct cmd_servo_result, arg1,
1513 str_servo_arg1_show);
1515 const char PROGMEM help_servo_show[] = "read servo and config";
1516 const parse_inst_t PROGMEM cmd_servo_show = {
1517 .f = cmd_servo_parsed, /* function to call */
1518 .data = NULL, /* 2nd arg of func */
1519 .help_str = help_servo_show,
1520 .tokens = { /* token list, NULL terminated */
1521 (PGM_P)&cmd_servo_arg0,
1522 (PGM_P)&cmd_servo_arg1_show,
1527 const char PROGMEM str_servo_arg1_bypassppm[] = "bypass#ppm";
1528 const parse_token_string_t PROGMEM cmd_servo_arg1_bypassppm =
1529 TOKEN_STRING_INITIALIZER(struct cmd_servo_result, arg1,
1530 str_servo_arg1_bypassppm);
1532 const char PROGMEM help_servo_bypassppm[] = "change bypass/ppm";
1533 const parse_inst_t PROGMEM cmd_servo_bypassppm = {
1534 .f = cmd_servo_parsed, /* function to call */
1535 .data = NULL, /* 2nd arg of func */
1536 .help_str = help_servo_bypassppm,
1537 .tokens = { /* token list, NULL terminated */
1538 (PGM_P)&cmd_servo_arg0,
1539 (PGM_P)&cmd_servo_arg1_bypassppm,
1540 (PGM_P)&cmd_servo_val,
1545 /**********************************************************/
1547 /* this structure is filled when cmd_test_spi is parsed successfully */
1548 struct cmd_test_spi_result {
1549 fixed_string_t arg0;
1552 static void cmd_test_spi_parsed(void * parsed_result, void *data)
1554 uint8_t i, flags, wait_time = 0;
1557 (void)parsed_result;
1560 spi_servo_set_bypass(0);
1561 spi_servo_set_ppm(0);
1563 /* stress test: send many commands, no wait between each servo
1564 * of a series, and a variable delay between series */
1565 printf_P(PSTR("stress test\r\n"));
1566 while (!cmdline_keypressed()) {
1578 for (i = 0; i < 6; i++)
1579 spi_servo_set(i, val);
1582 printf_P(PSTR("%4.4d %4.4d %4.4d %4.4d %4.4d %4.4d\r\n"),
1583 spi_servo_get(0), spi_servo_get(1), spi_servo_get(2),
1584 spi_servo_get(3), spi_servo_get(4), spi_servo_get(5));
1587 printf_P(PSTR("bypass mode, with spi commands in background\r\n"));
1588 spi_servo_set_bypass(1);
1590 /* test bypass mode */
1591 while (!cmdline_keypressed()) {
1603 for (i = 0; i < 6; i++)
1604 spi_servo_set(i, val);
1607 printf_P(PSTR("%4.4d %4.4d %4.4d %4.4d %4.4d %4.4d\r\n"),
1608 spi_servo_get(0), spi_servo_get(1), spi_servo_get(2),
1609 spi_servo_get(3), spi_servo_get(4), spi_servo_get(5));
1612 printf_P(PSTR("PPM to servo\r\n"));
1613 spi_servo_set_bypass(0);
1614 spi_servo_set_ppm(0);
1616 /* test PPM to servo (bypass) mode */
1617 while (!cmdline_keypressed()) {
1618 for (i = 0; i < 6; i++) {
1619 val = spi_servo_get(i);
1620 spi_servo_set(i, val);
1624 printf_P(PSTR("PPM to (servo + PPM)\r\n"));
1625 spi_servo_set_bypass(0);
1626 spi_servo_set_ppm(1);
1628 /* test PPM to servo (bypass) mode */
1629 while (!cmdline_keypressed()) {
1630 for (i = 0; i < 6; i++) {
1631 val = spi_servo_get(i);
1632 spi_servo_set(i, val);
1637 const char PROGMEM str_test_spi_arg0[] = "test_spi";
1638 const parse_token_string_t PROGMEM cmd_test_spi_arg0 =
1639 TOKEN_STRING_INITIALIZER(struct cmd_test_spi_result, arg0,
1642 const char PROGMEM help_test_spi[] = "Test the spi";
1643 const parse_inst_t PROGMEM cmd_test_spi = {
1644 .f = cmd_test_spi_parsed, /* function to call */
1645 .data = NULL, /* 2nd arg of func */
1646 .help_str = help_test_spi,
1647 .tokens = { /* token list, NULL terminated */
1648 (PGM_P)&cmd_test_spi_arg0,
1653 /**********************************************************/
1655 /* this structure is filled when cmd_dump_xbee_stats is parsed successfully */
1656 struct cmd_dump_xbee_stats_result {
1657 fixed_string_t arg0;
1660 static void cmd_dump_xbee_stats_parsed(void *parsed_result, void *data)
1662 (void)parsed_result;
1665 xbee_dump_stats(xbee_dev);
1668 const char PROGMEM str_dump_xbee_stats_arg0[] = "dump_xbee_stats";
1669 const parse_token_string_t PROGMEM cmd_dump_xbee_stats_arg0 =
1670 TOKEN_STRING_INITIALIZER(struct cmd_dump_xbee_stats_result, arg0,
1671 str_dump_xbee_stats_arg0);
1673 const char PROGMEM help_dump_xbee_stats[] = "Test the spi";
1674 const parse_inst_t PROGMEM cmd_dump_xbee_stats = {
1675 .f = cmd_dump_xbee_stats_parsed, /* function to call */
1676 .data = NULL, /* 2nd arg of func */
1677 .help_str = help_dump_xbee_stats,
1678 .tokens = { /* token list, NULL terminated */
1679 (PGM_P)&cmd_dump_xbee_stats_arg0,
1684 /**********************************************************/
1686 /* this structure is filled when cmd_test_eeprom_config is parsed successfully */
1687 struct cmd_test_eeprom_config_result {
1688 fixed_string_t arg0;
1691 static void cmd_test_eeprom_config_parsed(void *parsed_result, void *data)
1693 (void)parsed_result;
1697 eeprom_append_cmd("salut1\n");
1699 eeprom_append_cmd("salut2\n");
1700 eeprom_append_cmd("salut3\n");
1701 eeprom_append_cmd("salut4\n");
1703 eeprom_insert_cmd_before("coin\n", 0);
1704 eeprom_insert_cmd_before("coin2\n", 2);
1706 eeprom_delete_cmd(2);
1707 eeprom_delete_cmd(0);
1711 const char PROGMEM str_test_eeprom_config_arg0[] = "test_eeprom_config";
1712 const parse_token_string_t PROGMEM cmd_test_eeprom_config_arg0 =
1713 TOKEN_STRING_INITIALIZER(struct cmd_test_eeprom_config_result, arg0,
1714 str_test_eeprom_config_arg0);
1716 const char PROGMEM help_test_eeprom_config[] = "Test the eeprom configuration";
1717 const parse_inst_t PROGMEM cmd_test_eeprom_config = {
1718 .f = cmd_test_eeprom_config_parsed, /* function to call */
1719 .data = NULL, /* 2nd arg of func */
1720 .help_str = help_test_eeprom_config,
1721 .tokens = { /* token list, NULL terminated */
1722 (PGM_P)&cmd_test_eeprom_config_arg0,
1729 struct cmd_eeprom_del_result {
1731 fixed_string_t action;
1735 static void cmd_eeprom_del_parsed(void *parsed_result,
1738 struct cmd_eeprom_del_result *res = parsed_result;
1741 if (eeprom_delete_cmd(res->n) < 0)
1742 printf_P(PSTR("cannot delete command\n"));
1746 const char PROGMEM str_eeprom_del_eeprom[] = "eeprom";
1747 const parse_token_string_t PROGMEM cmd_eeprom_del_cmd =
1748 TOKEN_STRING_INITIALIZER(struct cmd_eeprom_del_result, cmd,
1749 str_eeprom_del_eeprom);
1750 const char PROGMEM str_eeprom_del_del[] = "del";
1751 const parse_token_string_t PROGMEM cmd_eeprom_del_action =
1752 TOKEN_STRING_INITIALIZER(struct cmd_eeprom_del_result, action,
1753 str_eeprom_del_del);
1754 const parse_token_num_t PROGMEM cmd_eeprom_del_num =
1755 TOKEN_NUM_INITIALIZER(struct cmd_eeprom_del_result, n,
1758 const char PROGMEM help_eeprom_del[] = "delete an eeprom init command";
1759 const parse_inst_t PROGMEM cmd_eeprom_del = {
1760 .f = cmd_eeprom_del_parsed, /* function to call */
1761 .data = NULL, /* 2nd arg of func */
1762 .help_str = help_eeprom_del,
1763 .tokens = { /* token list, NULL terminated */
1764 (PGM_P)&cmd_eeprom_del_cmd,
1765 (PGM_P)&cmd_eeprom_del_action,
1766 (PGM_P)&cmd_eeprom_del_num,
1773 struct cmd_eeprom_add_result {
1775 fixed_string_t action;
1779 static void cmd_eeprom_add_parsed(void *parsed_result,
1782 struct cmd_eeprom_add_result *res = parsed_result;
1788 rdline_init(&rdl, cmdline_write_char, NULL, NULL);
1789 rdline_newline(&rdl, "> ");
1791 /* XXX bad: we should not block as we do not serve callout */
1793 c = cmdline_dev_recv(NULL);
1797 ret = rdline_char_in(&rdl, c);
1799 printf_P(PSTR("abort\n"));
1806 buffer = rdline_get_buffer(&rdl);
1808 eeprom_insert_cmd_before(buffer, res->n);
1810 eeprom_append_cmd(buffer);
1814 const char PROGMEM str_eeprom_add_eeprom[] = "eeprom";
1815 const parse_token_string_t PROGMEM cmd_eeprom_add_cmd =
1816 TOKEN_STRING_INITIALIZER(struct cmd_eeprom_add_result, cmd,
1817 str_eeprom_add_eeprom);
1818 const char PROGMEM str_eeprom_add_add[] = "add";
1819 const parse_token_string_t PROGMEM cmd_eeprom_add_action =
1820 TOKEN_STRING_INITIALIZER(struct cmd_eeprom_add_result, action,
1821 str_eeprom_add_add);
1822 const parse_token_num_t PROGMEM cmd_eeprom_add_num =
1823 TOKEN_NUM_INITIALIZER(struct cmd_eeprom_add_result, n,
1826 const char PROGMEM help_eeprom_add[] = "insert an eeprom init command";
1827 const parse_inst_t PROGMEM cmd_eeprom_add = {
1828 .f = cmd_eeprom_add_parsed, /* function to call */
1829 .data = NULL, /* 2nd arg of func */
1830 .help_str = help_eeprom_add,
1831 .tokens = { /* token list, NULL terminated */
1832 (PGM_P)&cmd_eeprom_add_cmd,
1833 (PGM_P)&cmd_eeprom_add_action,
1834 (PGM_P)&cmd_eeprom_add_num,
1839 const char PROGMEM help_eeprom_add2[] = "append an eeprom init command";
1840 const parse_inst_t PROGMEM cmd_eeprom_add2 = {
1841 .f = cmd_eeprom_add_parsed, /* function to call */
1842 .data = (void *)1, /* 2nd arg of func */
1843 .help_str = help_eeprom_add2,
1844 .tokens = { /* token list, NULL terminated */
1845 (PGM_P)&cmd_eeprom_add_cmd,
1846 (PGM_P)&cmd_eeprom_add_action,
1853 struct cmd_eeprom_list_result {
1855 fixed_string_t action;
1858 static void cmd_eeprom_list_parsed(void *parsed_result,
1861 (void)parsed_result;
1866 const char PROGMEM str_eeprom_list_eeprom[] = "eeprom";
1867 const parse_token_string_t PROGMEM cmd_eeprom_list_cmd =
1868 TOKEN_STRING_INITIALIZER(struct cmd_eeprom_list_result, cmd,
1869 str_eeprom_list_eeprom);
1870 const char PROGMEM str_eeprom_list_list[] = "list";
1871 const parse_token_string_t PROGMEM cmd_eeprom_list_action =
1872 TOKEN_STRING_INITIALIZER(struct cmd_eeprom_list_result, action,
1873 str_eeprom_list_list);
1875 const char PROGMEM help_eeprom_list[] = "list all eeprom init commands";
1876 const parse_inst_t PROGMEM cmd_eeprom_list = {
1877 .f = cmd_eeprom_list_parsed, /* function to call */
1878 .data = NULL, /* 2nd arg of func */
1879 .help_str = help_eeprom_list,
1880 .tokens = { /* token list, NULL terminated */
1881 (PGM_P)&cmd_eeprom_list_cmd,
1882 (PGM_P)&cmd_eeprom_list_action,
1891 const parse_ctx_t PROGMEM main_ctx[] = {
1893 /* commands_gen.c */
1912 &cmd_send_hello_name,
1917 &cmd_range_powermask,
1920 &cmd_monitor_period,
1930 &cmd_servo_bypassppm,
1933 &cmd_dump_xbee_stats,
1934 &cmd_test_eeprom_config,