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"
47 #include "xbee_user.h"
51 #include "eeprom_config.h"
54 extern const parse_inst_t PROGMEM cmd_reset;
55 extern const parse_inst_t PROGMEM cmd_bootloader;
56 extern const parse_inst_t PROGMEM cmd_log;
57 extern const parse_inst_t PROGMEM cmd_log_show;
58 extern const parse_inst_t PROGMEM cmd_log_type;
59 extern const parse_inst_t PROGMEM cmd_stack_space;
60 extern const parse_inst_t PROGMEM cmd_callout;
62 static int monitor_period_ms = 1000;
63 static int monitor_running = 0;
64 static int monitor_count = 0;
65 static struct callout monitor_event;
66 struct monitor_reg *monitor_current;
68 static int range_period_ms = 1000;
69 static int range_powermask = 0x1F;
70 //static uint8_t range_power = 0;
71 static int range_running = 0;
72 static uint64_t range_dstaddr = 0xFFFF; /* broadcast by default */
73 static struct callout range_event;
74 static int range_count = 100;
75 static int range_cur_count = 0;
77 static void monitor_cb(struct callout_mgr *cm,
78 struct callout *clt, void *dummy)
83 if (monitor_current == NULL)
84 monitor_current = LIST_FIRST(&xbee_monitor_list);
86 xbeeapp_send_atcmd(monitor_current->atcmd, NULL, 0, 0, NULL, NULL);
87 monitor_current = LIST_NEXT(monitor_current, next);
88 callout_reschedule(cm, clt, monitor_period_ms / monitor_count);
91 static void range_cb(struct callout_mgr *cm,
92 struct callout *clt, void *dummy)
99 struct rc_proto_range rangepkt;
106 /* get new xmit power */
107 for (i = 1; i <= 8; i++) {
108 mask = 1 << ((range_power + i) & 0x7);
109 if (mask & range_powermask)
112 range_power = ((range_power + i) & 0x7);
114 xbeeapp_send_atcmd("PL", &range_power, sizeof(range_power), 0, NULL, NULL);
116 rangepkt.type = RC_PROTO_TYPE_RANGE;
117 rangepkt.power_level = range_power;
119 xbeeapp_send_msg(range_dstaddr, &rangepkt, sizeof(rangepkt), 0);
121 if (range_cur_count == 0) {
123 callout_stop(cm, clt);
126 callout_reschedule(cm, clt, range_period_ms);
130 /* this structure is filled when cmd_help is parsed successfully */
131 struct cmd_help_result {
133 struct xbee_atcmd *cmd;
136 /* function called when cmd_help is parsed successfully */
137 static void cmd_help_parsed(void *parsed_result, void *data)
139 struct cmd_help_result *res = parsed_result;
140 struct xbee_atcmd cmdcopy;
145 memcpy_P(&cmdcopy, res->cmd, sizeof(cmdcopy));
146 type = (cmdcopy.flags & (XBEE_ATCMD_F_READ | XBEE_ATCMD_F_WRITE));
148 case XBEE_ATCMD_F_READ:
149 printf_P(PSTR("Read-only\r\n"));
151 case XBEE_ATCMD_F_WRITE:
152 printf_P(PSTR("Write-only\r\n"));
155 printf_P(PSTR("Read-write\r\n"));
158 if (cmdcopy.flags & XBEE_ATCMD_F_PARAM_NONE)
159 printf_P(PSTR("No argument\r\n"));
160 else if (cmdcopy.flags & XBEE_ATCMD_F_PARAM_U8)
161 printf_P(PSTR("Register is unsigned 8 bits\r\n"));
162 else if (cmdcopy.flags & XBEE_ATCMD_F_PARAM_U16)
163 printf_P(PSTR("Register is unsigned 16 bits\r\n"));
164 else if (cmdcopy.flags & XBEE_ATCMD_F_PARAM_U32)
165 printf_P(PSTR("Register is unsigned 32 bits\r\n"));
166 else if (cmdcopy.flags & XBEE_ATCMD_F_PARAM_S16)
167 printf_P(PSTR("Register is signed 16 bits\r\n"));
168 else if (cmdcopy.flags & XBEE_ATCMD_F_PARAM_STRING_20B)
169 printf_P(PSTR("Register is a 20 bytes string\r\n"));
171 printf_P(PSTR("Unknown argument\r\n"));
173 printf_P(PSTR("%S\r\n"), cmdcopy.help);
175 const char PROGMEM str_help_help[] = "help";
177 const parse_token_string_t PROGMEM cmd_help_help =
178 TOKEN_STRING_INITIALIZER(struct cmd_help_result, help, str_help_help);
180 const parse_token_atcmd_t PROGMEM cmd_help_atcmd =
181 TOKEN_ATCMD_INITIALIZER(struct cmd_help_result, cmd, &xbee_dev,
184 const char PROGMEM help_help[] = "Help a register using an AT command";
185 const parse_inst_t PROGMEM cmd_help = {
186 .f = cmd_help_parsed, /* function to call */
187 .data = NULL, /* 2nd arg of func */
188 .help_str = help_help,
189 .tokens = { /* token list, NULL terminated */
190 (PGM_P)&cmd_help_help,
191 (PGM_P)&cmd_help_atcmd,
198 struct cmd_neigh_del_result {
200 fixed_string_t action;
201 struct xbee_neigh *neigh;
204 static void cmd_neigh_del_parsed(void *parsed_result,
207 struct cmd_neigh_del_result *res = parsed_result;
210 xbee_neigh_del(xbee_dev, res->neigh);
213 const char PROGMEM str_neigh_del_neigh[] = "neigh";
214 const parse_token_string_t PROGMEM cmd_neigh_del_cmd =
215 TOKEN_STRING_INITIALIZER(struct cmd_neigh_del_result, cmd,
216 str_neigh_del_neigh);
217 const char PROGMEM str_neigh_del_del[] = "del";
218 const parse_token_string_t PROGMEM cmd_neigh_del_action =
219 TOKEN_STRING_INITIALIZER(struct cmd_neigh_del_result, action,
221 const parse_token_neighbor_t PROGMEM cmd_neigh_del_neigh =
222 TOKEN_NEIGHBOR_INITIALIZER(struct cmd_neigh_del_result, neigh,
225 const char PROGMEM help_neigh_del[] = "delete a neighbor";
226 const parse_inst_t PROGMEM cmd_neigh_del = {
227 .f = cmd_neigh_del_parsed, /* function to call */
228 .data = NULL, /* 2nd arg of func */
229 .help_str = help_neigh_del,
230 .tokens = { /* token list, NULL terminated */
231 (PGM_P)&cmd_neigh_del_cmd,
232 (PGM_P)&cmd_neigh_del_action,
233 (PGM_P)&cmd_neigh_del_neigh,
240 struct cmd_neigh_add_result {
242 fixed_string_t action;
247 static void cmd_neigh_add_parsed(void *parsed_result,
250 struct cmd_neigh_add_result *res = parsed_result;
253 if (xbee_neigh_add(xbee_dev, res->name, res->addr) == NULL)
254 printf_P(PSTR("name or addr already exist\r\n"));
257 const char PROGMEM str_neigh_add_neigh[] = "neigh";
258 const parse_token_string_t PROGMEM cmd_neigh_add_cmd =
259 TOKEN_STRING_INITIALIZER(struct cmd_neigh_add_result, cmd,
260 str_neigh_add_neigh);
261 const char PROGMEM str_neigh_add_add[] = "add";
262 const parse_token_string_t PROGMEM cmd_neigh_add_action =
263 TOKEN_STRING_INITIALIZER(struct cmd_neigh_add_result, action,
265 const parse_token_string_t PROGMEM cmd_neigh_add_name =
266 TOKEN_STRING_INITIALIZER(struct cmd_neigh_add_result, name, NULL);
267 const parse_token_num_t PROGMEM cmd_neigh_add_addr =
268 TOKEN_NUM_INITIALIZER(struct cmd_neigh_add_result, addr, UINT64);
270 const char PROGMEM help_neigh_add[] = "add a neighbor";
271 const parse_inst_t PROGMEM cmd_neigh_add = {
272 .f = cmd_neigh_add_parsed, /* function to call */
273 .data = NULL, /* 2nd arg of func */
274 .help_str = help_neigh_add,
275 .tokens = { /* token list, NULL terminated */
276 (PGM_P)&cmd_neigh_add_cmd,
277 (PGM_P)&cmd_neigh_add_action,
278 (PGM_P)&cmd_neigh_add_name,
279 (PGM_P)&cmd_neigh_add_addr,
286 struct cmd_neigh_list_result {
288 fixed_string_t action;
291 static void cmd_neigh_list_parsed(void *parsed_result,
294 struct xbee_neigh *neigh;
298 LIST_FOREACH(neigh, &xbee_dev->neigh_list, next) {
299 printf_P(PSTR(" %s: 0x%.8"PRIx32"%.8"PRIx32"\r\n"),
301 (uint32_t)(neigh->addr >> 32ULL),
302 (uint32_t)(neigh->addr & 0xFFFFFFFF));
306 const char PROGMEM str_neigh_list_neigh[] = "neigh";
307 const parse_token_string_t PROGMEM cmd_neigh_list_cmd =
308 TOKEN_STRING_INITIALIZER(struct cmd_neigh_list_result, cmd,
309 str_neigh_list_neigh);
310 const char PROGMEM str_neigh_list_list[] = "list";
311 const parse_token_string_t PROGMEM cmd_neigh_list_action =
312 TOKEN_STRING_INITIALIZER(struct cmd_neigh_list_result, action,
313 str_neigh_list_list);
315 const char PROGMEM help_neigh_list[] = "list all knwon neighbors";
316 const parse_inst_t PROGMEM cmd_neigh_list = {
317 .f = cmd_neigh_list_parsed, /* function to call */
318 .data = NULL, /* 2nd arg of func */
319 .help_str = help_neigh_list,
320 .tokens = { /* token list, NULL terminated */
321 (PGM_P)&cmd_neigh_list_cmd,
322 (PGM_P)&cmd_neigh_list_action,
332 /* this structure is filled when cmd_read is parsed successfully */
333 struct cmd_read_result {
335 struct xbee_atcmd *cmd;
338 /* function called when cmd_read is parsed successfully */
339 static void cmd_read_parsed(void *parsed_result,
342 struct cmd_read_result *res = parsed_result;
343 struct xbee_atcmd copy;
347 memcpy_P(©, res->cmd, sizeof(copy));
348 memcpy_P(&cmd, copy.name, 2);
350 xbeeapp_send_atcmd(cmd, NULL, 0, 1, NULL, NULL);
353 const char PROGMEM str_read_read[] = "read";
355 const parse_token_string_t PROGMEM cmd_read_read =
356 TOKEN_STRING_INITIALIZER(struct cmd_read_result, read,
359 const parse_token_atcmd_t PROGMEM cmd_read_atcmd =
360 TOKEN_ATCMD_INITIALIZER(struct cmd_read_result, cmd, &xbee_dev,
361 XBEE_ATCMD_F_READ, XBEE_ATCMD_F_READ);
363 const char PROGMEM help_read[] = "Read a register using an AT command";
364 const parse_inst_t PROGMEM cmd_read = {
365 .f = cmd_read_parsed, /* function to call */
366 .data = NULL, /* 2nd arg of func */
367 .help_str = help_read,
368 .tokens = { /* token list, NULL terminated */
369 (PGM_P)&cmd_read_read,
370 (PGM_P)&cmd_read_atcmd,
378 /* this structure is filled when cmd_write is parsed successfully */
379 struct cmd_write_result {
380 fixed_string_t write;
381 struct xbee_atcmd *cmd;
389 /* function called when cmd_write is parsed successfully */
390 static void cmd_write_parsed(void *parsed_result, void *data)
392 struct cmd_write_result *res = parsed_result;
393 struct xbee_atcmd copy;
399 memcpy_P(©, res->cmd, sizeof(copy));
401 if (copy.flags & XBEE_ATCMD_F_PARAM_NONE) {
405 else if (copy.flags & XBEE_ATCMD_F_PARAM_U8) {
406 len = sizeof(res->u8);
409 else if (copy.flags & XBEE_ATCMD_F_PARAM_U16) {
410 len = sizeof(res->u16);
411 res->u16 = htons(res->u16);
414 else if (copy.flags & XBEE_ATCMD_F_PARAM_U32) {
415 len = sizeof(res->u32);
416 res->u32 = htonl(res->u32);
420 printf_P(PSTR("Unknown argument type\r\n"));
423 memcpy_P(&cmd, copy.name, 2);
425 xbeeapp_send_atcmd(cmd, param, len, 1, NULL, NULL);
428 const char PROGMEM str_write_none[] = "write";
430 const parse_token_string_t PROGMEM cmd_write_write =
431 TOKEN_STRING_INITIALIZER(struct cmd_write_result, write,
434 const parse_token_atcmd_t PROGMEM cmd_write_none_atcmd =
435 TOKEN_ATCMD_INITIALIZER(struct cmd_write_result, cmd,
437 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_NONE,
438 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_NONE);
440 const char PROGMEM help_write_none[] = "Send an AT command (no argument)";
442 const parse_inst_t PROGMEM cmd_write_none = {
443 .f = cmd_write_parsed, /* function to call */
444 .data = NULL, /* 2nd arg of func */
445 .help_str = help_write_none,
446 .tokens = { /* token list, NULL terminated */
447 (PGM_P)&cmd_write_write,
448 (PGM_P)&cmd_write_none_atcmd,
453 const parse_token_atcmd_t PROGMEM cmd_write_u8_atcmd =
454 TOKEN_ATCMD_INITIALIZER(struct cmd_write_result, cmd,
456 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_U8,
457 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_U8);
459 const parse_token_num_t PROGMEM cmd_write_u8_u8 =
460 TOKEN_NUM_INITIALIZER(struct cmd_write_result, u8, UINT8);
462 const char PROGMEM help_write_u8[] = "Write a 8 bits register using an AT command";
464 const parse_inst_t PROGMEM cmd_write_u8 = {
465 .f = cmd_write_parsed, /* function to call */
466 .data = NULL, /* 2nd arg of func */
467 .help_str = help_write_u8,
468 .tokens = { /* token list, NULL terminated */
469 (PGM_P)&cmd_write_write,
470 (PGM_P)&cmd_write_u8_atcmd,
471 (PGM_P)&cmd_write_u8_u8,
476 const parse_token_atcmd_t PROGMEM cmd_write_u16_atcmd =
477 TOKEN_ATCMD_INITIALIZER(struct cmd_write_result, cmd,
479 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_U16,
480 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_U16);
482 const parse_token_num_t PROGMEM cmd_write_u16_u16 =
483 TOKEN_NUM_INITIALIZER(struct cmd_write_result, u16, UINT16);
485 const char PROGMEM help_write_u16[] = "Write a 16 bits register using an AT command";
487 const parse_inst_t PROGMEM cmd_write_u16 = {
488 .f = cmd_write_parsed, /* function to call */
489 .data = NULL, /* 2nd arg of func */
490 .help_str = help_write_u16,
491 .tokens = { /* token list, NULL terminated */
492 (PGM_P)&cmd_write_write,
493 (PGM_P)&cmd_write_u16_atcmd,
494 (PGM_P)&cmd_write_u16_u16,
499 const parse_token_atcmd_t PROGMEM cmd_write_u32_atcmd =
500 TOKEN_ATCMD_INITIALIZER(struct cmd_write_result, cmd,
502 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_U32,
503 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_U32);
505 const parse_token_num_t PROGMEM cmd_write_u32_u32 =
506 TOKEN_NUM_INITIALIZER(struct cmd_write_result, u32, UINT32);
508 const char PROGMEM help_write_u32[] = "Write a 32 bits register using an AT command";
510 const parse_inst_t PROGMEM cmd_write_u32 = {
511 .f = cmd_write_parsed, /* function to call */
512 .data = NULL, /* 2nd arg of func */
513 .help_str = help_write_u32,
514 .tokens = { /* token list, NULL terminated */
515 (PGM_P)&cmd_write_write,
516 (PGM_P)&cmd_write_u32_atcmd,
517 (PGM_P)&cmd_write_u32_u32,
525 /* this structure is filled when cmd_sendmsg is parsed successfully */
526 struct cmd_sendmsg_result {
527 fixed_string_t sendmsg;
532 /* function called when cmd_sendmsg is parsed successfully */
533 static void cmd_sendmsg_parsed(void *parsed_result, void *data)
535 struct cmd_sendmsg_result *res = parsed_result;
541 msg.iov[0].buf = res->data;
542 msg.iov[0].len = strlen(res->data);
544 xbeeapp_send_msg(res->addr, &msg, 1);
547 const char PROGMEM str_sendmsg[] = "sendmsg";
549 const parse_token_string_t PROGMEM cmd_sendmsg_sendmsg =
550 TOKEN_STRING_INITIALIZER(struct cmd_sendmsg_result, sendmsg,
553 const parse_token_num_t PROGMEM cmd_sendmsg_addr =
554 TOKEN_NUM_INITIALIZER(struct cmd_sendmsg_result, addr, UINT64);
556 const parse_token_string_t PROGMEM cmd_sendmsg_data =
557 TOKEN_STRING_INITIALIZER(struct cmd_sendmsg_result, data, NULL);
559 const char PROGMEM help_sendmsg[] = "Send data to a node using its address";
561 const parse_inst_t PROGMEM cmd_sendmsg = {
562 .f = cmd_sendmsg_parsed, /* function to call */
563 .data = NULL, /* 2nd arg of func */
564 .help_str = help_sendmsg,
565 .tokens = { /* token list, NULL terminated */
566 (PGM_P)&cmd_sendmsg_sendmsg,
567 (PGM_P)&cmd_sendmsg_addr,
568 (PGM_P)&cmd_sendmsg_data,
575 /* this structure is filled when cmd_send_hello is parsed successfully */
576 struct cmd_send_hello_result {
577 fixed_string_t send_hello;
579 struct xbee_neigh *neigh;
585 /* function called when cmd_send_hello is parsed successfully */
586 static void cmd_send_hello_parsed(void *parsed_result, void *use_neigh)
588 struct cmd_send_hello_result *res = parsed_result;
589 uint16_t now, next, diff;
594 addr = res->neigh->addr;
604 while (!cmdline_keypressed() && res->count != 0) {
610 if (diff < res->period)
613 rc_proto_send_hello(addr, res->data, strlen(res->data));
619 const char PROGMEM str_send_hello[] = "send_hello";
621 const parse_token_string_t PROGMEM cmd_send_hello_send_hello =
622 TOKEN_STRING_INITIALIZER(struct cmd_send_hello_result, send_hello,
625 const parse_token_num_t PROGMEM cmd_send_hello_addr =
626 TOKEN_NUM_INITIALIZER(struct cmd_send_hello_result, addr, UINT64);
628 const parse_token_num_t PROGMEM cmd_send_hello_period =
629 TOKEN_NUM_INITIALIZER(struct cmd_send_hello_result, period, UINT16);
631 const parse_token_num_t PROGMEM cmd_send_hello_count =
632 TOKEN_NUM_INITIALIZER(struct cmd_send_hello_result, count, UINT16);
634 const parse_token_string_t PROGMEM cmd_send_hello_data =
635 TOKEN_STRING_INITIALIZER(struct cmd_send_hello_result, data, NULL);
637 const char PROGMEM help_send_hello[] =
638 "Send hello msg to a node: addr, period_ms, count, str";
640 const parse_inst_t PROGMEM cmd_send_hello = {
641 .f = cmd_send_hello_parsed, /* function to call */
642 .data = NULL, /* 2nd arg of func */
643 .help_str = help_send_hello,
644 .tokens = { /* token list, NULL terminated */
645 (PGM_P)&cmd_send_hello_send_hello,
646 (PGM_P)&cmd_send_hello_addr,
647 (PGM_P)&cmd_send_hello_period,
648 (PGM_P)&cmd_send_hello_count,
649 (PGM_P)&cmd_send_hello_data,
654 const parse_token_neighbor_t PROGMEM cmd_send_hello_neigh =
655 TOKEN_NEIGHBOR_INITIALIZER(struct cmd_send_hello_result, neigh,
658 const parse_inst_t PROGMEM cmd_send_hello_name = {
659 .f = cmd_send_hello_parsed, /* function to call */
660 .data = (void *)1, /* 2nd arg of func */
661 .help_str = help_send_hello,
662 .tokens = { /* token list, NULL terminated */
663 (PGM_P)&cmd_send_hello_send_hello,
664 (PGM_P)&cmd_send_hello_neigh,
665 (PGM_P)&cmd_send_hello_period,
666 (PGM_P)&cmd_send_hello_count,
667 (PGM_P)&cmd_send_hello_data,
674 /* this structure is filled when cmd_sendmsg_name is parsed successfully */
675 struct cmd_sendmsg_name_result {
676 fixed_string_t sendmsg_name;
677 struct xbee_neigh *neigh;
681 /* function called when cmd_sendmsg_name is parsed successfully */
682 static void cmd_sendmsg_name_parsed(void *parsed_result, void *data)
684 struct cmd_sendmsg_name_result *res = parsed_result;
690 msg.iov[0].buf = res->data;
691 msg.iov[0].len = strlen(res->data);
693 xbeeapp_send_msg(res->neigh->addr, &msg, 1);
696 const parse_token_string_t PROGMEM cmd_sendmsg_name_sendmsg_name =
697 TOKEN_STRING_INITIALIZER(struct cmd_sendmsg_name_result, sendmsg_name,
700 const parse_token_neighbor_t PROGMEM cmd_sendmsg_name_neigh =
701 TOKEN_NEIGHBOR_INITIALIZER(struct cmd_sendmsg_name_result, neigh,
704 const parse_token_string_t PROGMEM cmd_sendmsg_name_data =
705 TOKEN_STRING_INITIALIZER(struct cmd_sendmsg_name_result, data, NULL);
707 const char PROGMEM help_sendmsg_name[] = "Send data to a node using its name";
709 const parse_inst_t PROGMEM cmd_sendmsg_name = {
710 .f = cmd_sendmsg_name_parsed, /* function to call */
711 .data = NULL, /* 2nd arg of func */
712 .help_str = help_sendmsg_name,
713 .tokens = { /* token list, NULL terminated */
714 (PGM_P)&cmd_sendmsg_name_sendmsg_name,
715 (PGM_P)&cmd_sendmsg_name_neigh,
716 (PGM_P)&cmd_sendmsg_name_data,
724 /* this structure is filled when cmd_range is parsed successfully */
725 struct cmd_range_result {
726 fixed_string_t range;
727 fixed_string_t action;
730 /* function called when cmd_range is parsed successfully */
731 static void cmd_range_parsed(void *parsed_result, void *data)
733 struct cmd_range_result *res = parsed_result;
736 if (!strcmp_P(res->action, PSTR("show"))) {
737 printf_P(PSTR("range infos:\r\n"));
738 printf_P(PSTR(" range period %d\r\n"), range_period_ms);
739 printf_P(PSTR(" range count %d\r\n"), range_count);
740 printf_P(PSTR(" range powermask 0x%x\r\n"), range_powermask);
741 printf_P(PSTR(" range dstaddr 0x%.8"PRIx32"%.8"PRIx32"\r\n"),
742 (uint32_t)(range_dstaddr >> 32ULL),
743 (uint32_t)(range_dstaddr & 0xFFFFFFFF));
746 printf_P(PSTR(" range test is running\r\n"));
748 printf_P(PSTR(" range test is not running\r\n"));
750 else if (!strcmp(res->action, "start")) {
752 printf_P(PSTR("already running\r\n"));
755 range_cur_count = range_count;
756 callout_init(&range_event, range_cb, NULL, 0);
757 callout_schedule(&xbeeboard.mainloop_cm,
758 &range_event, 0); /* immediate */
761 else if (!strcmp(res->action, "end")) {
762 if (range_running == 0) {
763 printf_P(PSTR("not running\r\n"));
767 callout_stop(&xbeeboard.mainloop_cm, &range_event);
771 const char PROGMEM str_range[] = "range";
772 const char PROGMEM str_range_tokens[] = "show#start#end";
774 const parse_token_string_t PROGMEM cmd_range_range =
775 TOKEN_STRING_INITIALIZER(struct cmd_range_result, range,
777 const parse_token_string_t PROGMEM cmd_range_action =
778 TOKEN_STRING_INITIALIZER(struct cmd_range_result, action,
781 const char PROGMEM help_range[] = "start/stop/show current rangeing";
783 const parse_inst_t PROGMEM cmd_range = {
784 .f = cmd_range_parsed, /* function to call */
785 .data = NULL, /* 2nd arg of func */
786 .help_str = help_range,
787 .tokens = { /* token list, NULL terminated */
788 (PGM_P)&cmd_range_range,
789 (PGM_P)&cmd_range_action,
796 /* this structure is filled when cmd_range_period is parsed successfully */
797 struct cmd_range_period_result {
798 fixed_string_t range;
799 fixed_string_t action;
803 /* function called when cmd_range_period is parsed successfully */
804 static void cmd_range_period_parsed(void *parsed_result, void *data)
806 struct cmd_range_period_result *res = parsed_result;
809 if (res->period < 10) {
810 printf_P(PSTR("error, minimum period is 10 ms\r\n"));
814 range_period_ms = res->period;
817 const char PROGMEM str_period[] = "period";
819 const parse_token_string_t PROGMEM cmd_range_period_range_period =
820 TOKEN_STRING_INITIALIZER(struct cmd_range_period_result, range,
822 const parse_token_string_t PROGMEM cmd_range_period_action =
823 TOKEN_STRING_INITIALIZER(struct cmd_range_period_result, action,
825 const parse_token_num_t PROGMEM cmd_range_period_period =
826 TOKEN_NUM_INITIALIZER(struct cmd_range_period_result, period, UINT32);
828 const char PROGMEM help_range_period[] = "set range test period";
830 const parse_inst_t PROGMEM cmd_range_period = {
831 .f = cmd_range_period_parsed, /* function to call */
832 .data = NULL, /* 2nd arg of func */
833 .help_str = help_range_period,
834 .tokens = { /* token list, NULL terminated */
835 (PGM_P)&cmd_range_period_range_period,
836 (PGM_P)&cmd_range_period_action,
837 (PGM_P)&cmd_range_period_period,
844 /* this structure is filled when cmd_range_count is parsed successfully */
845 struct cmd_range_count_result {
846 fixed_string_t range;
847 fixed_string_t action;
851 /* function called when cmd_range_count is parsed successfully */
852 static void cmd_range_count_parsed(void *parsed_result, void *data)
854 struct cmd_range_count_result *res = parsed_result;
857 range_count = res->count;
860 const char PROGMEM str_count[] = "count";
862 const parse_token_string_t PROGMEM cmd_range_count_range_count =
863 TOKEN_STRING_INITIALIZER(struct cmd_range_count_result, range,
865 const parse_token_string_t PROGMEM cmd_range_count_action =
866 TOKEN_STRING_INITIALIZER(struct cmd_range_count_result, action,
868 const parse_token_num_t PROGMEM cmd_range_count_count =
869 TOKEN_NUM_INITIALIZER(struct cmd_range_count_result, count, UINT32);
872 const char PROGMEM help_range_count[] = "set range test count";
874 const parse_inst_t PROGMEM cmd_range_count = {
875 .f = cmd_range_count_parsed, /* function to call */
876 .data = NULL, /* 2nd arg of func */
877 .help_str = help_range_count,
878 .tokens = { /* token list, NULL terminated */
879 (PGM_P)&cmd_range_count_range_count,
880 (PGM_P)&cmd_range_count_action,
881 (PGM_P)&cmd_range_count_count,
888 /* this structure is filled when cmd_range_powermask is parsed successfully */
889 struct cmd_range_powermask_result {
890 fixed_string_t range;
891 fixed_string_t action;
895 /* function called when cmd_range_powermask is parsed successfully */
896 static void cmd_range_powermask_parsed(void *parsed_result, void *data)
898 struct cmd_range_powermask_result *res = parsed_result;
901 range_powermask = res->powermask;
904 const char PROGMEM str_powermask[] = "powermask";
906 const parse_token_string_t PROGMEM cmd_range_powermask_range_powermask =
907 TOKEN_STRING_INITIALIZER(struct cmd_range_powermask_result, range,
909 const parse_token_string_t PROGMEM cmd_range_powermask_action =
910 TOKEN_STRING_INITIALIZER(struct cmd_range_powermask_result, action,
912 const parse_token_num_t PROGMEM cmd_range_powermask_powermask =
913 TOKEN_NUM_INITIALIZER(struct cmd_range_powermask_result, powermask,
917 const char PROGMEM help_range_powermask[] = "set range test powermask";
919 const parse_inst_t PROGMEM cmd_range_powermask = {
920 .f = cmd_range_powermask_parsed, /* function to call */
921 .data = NULL, /* 2nd arg of func */
922 .help_str = help_range_powermask,
923 .tokens = { /* token list, NULL terminated */
924 (PGM_P)&cmd_range_powermask_range_powermask,
925 (PGM_P)&cmd_range_powermask_action,
926 (PGM_P)&cmd_range_powermask_powermask,
933 /* this structure is filled when cmd_range_dstaddr is parsed successfully */
934 struct cmd_range_dstaddr_result {
935 fixed_string_t range;
936 fixed_string_t action;
940 /* function called when cmd_range_dstaddr is parsed successfully */
941 static void cmd_range_dstaddr_parsed(void *parsed_result, void *data)
943 struct cmd_range_dstaddr_result *res = parsed_result;
946 range_dstaddr = res->dstaddr;
949 const char PROGMEM str_dstaddr[] = "dstaddr";
951 const parse_token_string_t PROGMEM cmd_range_dstaddr_range_dstaddr =
952 TOKEN_STRING_INITIALIZER(struct cmd_range_dstaddr_result, range,
954 const parse_token_string_t PROGMEM cmd_range_dstaddr_action =
955 TOKEN_STRING_INITIALIZER(struct cmd_range_dstaddr_result, action,
957 const parse_token_num_t PROGMEM cmd_range_dstaddr_dstaddr =
958 TOKEN_NUM_INITIALIZER(struct cmd_range_dstaddr_result, dstaddr, UINT64);
961 const char PROGMEM help_range_dstaddr[] = "set register rangeing dstaddr";
963 const parse_inst_t PROGMEM cmd_range_dstaddr = {
964 .f = cmd_range_dstaddr_parsed, /* function to call */
965 .data = NULL, /* 2nd arg of func */
966 .help_str = help_range_dstaddr,
967 .tokens = { /* token list, NULL terminated */
968 (PGM_P)&cmd_range_dstaddr_range_dstaddr,
969 (PGM_P)&cmd_range_dstaddr_action,
970 (PGM_P)&cmd_range_dstaddr_dstaddr,
978 /* this structure is filled when cmd_monitor is parsed successfully */
979 struct cmd_monitor_result {
980 fixed_string_t monitor;
981 fixed_string_t action;
984 /* function called when cmd_monitor is parsed successfully */
985 static void cmd_monitor_parsed(void *parsed_result, void *data)
987 struct cmd_monitor_result *res = parsed_result;
988 struct monitor_reg *m;
991 if (!strcmp_P(res->action, PSTR("show"))) {
992 printf_P(PSTR("monitor period is %d ms, %d regs in list\r\n"),
993 monitor_period_ms, monitor_count);
994 LIST_FOREACH(m, &xbee_monitor_list, next)
995 printf_P(PSTR(" %S\r\n"), m->desc);
997 else if (!strcmp_P(res->action, PSTR("start"))) {
998 if (monitor_running) {
999 printf_P(PSTR("already running\r\n"));
1002 if (monitor_count == 0) {
1003 printf_P(PSTR("no regs to be monitored\r\n"));
1006 callout_init(&monitor_event, monitor_cb, NULL, 0);
1007 callout_schedule(&xbeeboard.mainloop_cm,
1008 &monitor_event, 0); /* immediate */
1009 monitor_running = 1;
1010 monitor_current = LIST_FIRST(&xbee_monitor_list);
1011 printf_P(PSTR("monitor cb: %S %s\r\n"),
1012 monitor_current->desc,
1013 monitor_current->atcmd);
1016 else if (!strcmp_P(res->action, PSTR("end"))) {
1017 if (monitor_running == 0) {
1018 printf_P(PSTR("not running\r\n"));
1021 monitor_running = 0;
1022 callout_stop(&xbeeboard.mainloop_cm, &monitor_event);
1026 const char PROGMEM str_monitor[] = "monitor";
1027 const char PROGMEM str_monitor_tokens[] = "show#start#end";
1029 const parse_token_string_t PROGMEM cmd_monitor_monitor =
1030 TOKEN_STRING_INITIALIZER(struct cmd_monitor_result, monitor,
1032 const parse_token_string_t PROGMEM cmd_monitor_action =
1033 TOKEN_STRING_INITIALIZER(struct cmd_monitor_result, action,
1034 str_monitor_tokens);
1036 const char PROGMEM help_monitor[] = "start/stop/show current monitoring";
1038 const parse_inst_t PROGMEM cmd_monitor = {
1039 .f = cmd_monitor_parsed, /* function to call */
1040 .data = NULL, /* 2nd arg of func */
1041 .help_str = help_monitor,
1042 .tokens = { /* token list, NULL terminated */
1043 (PGM_P)&cmd_monitor_monitor,
1044 (PGM_P)&cmd_monitor_action,
1051 /* this structure is filled when cmd_monitor_add is parsed successfully */
1052 struct cmd_monitor_add_result {
1053 fixed_string_t monitor;
1054 fixed_string_t action;
1055 struct xbee_atcmd *cmd;
1058 /* function called when cmd_monitor_add is parsed successfully */
1059 static void cmd_monitor_add_parsed(void *parsed_result, void *data)
1061 struct cmd_monitor_add_result *res = parsed_result;
1062 struct monitor_reg *m;
1063 struct xbee_atcmd copy;
1066 memcpy_P(©, res->cmd, sizeof(copy));
1067 LIST_FOREACH(m, &xbee_monitor_list, next) {
1068 if (!strcmp_P(m->atcmd, copy.name))
1073 printf_P(PSTR("already exist\r\n"));
1077 m = malloc(sizeof(*m));
1079 printf_P(PSTR("no mem\r\n"));
1082 m->desc = copy.desc;
1083 strcpy_P(m->atcmd, copy.name);
1084 LIST_INSERT_HEAD(&xbee_monitor_list, m, next);
1088 const char PROGMEM str_monitor_add[] = "add";
1090 const parse_token_string_t PROGMEM cmd_monitor_add_monitor_add =
1091 TOKEN_STRING_INITIALIZER(struct cmd_monitor_add_result, monitor,
1093 const parse_token_string_t PROGMEM cmd_monitor_add_action =
1094 TOKEN_STRING_INITIALIZER(struct cmd_monitor_add_result, action,
1096 const parse_token_atcmd_t PROGMEM cmd_monitor_add_atcmd =
1097 TOKEN_ATCMD_INITIALIZER(struct cmd_monitor_add_result, cmd, &xbee_dev,
1098 XBEE_ATCMD_F_READ, XBEE_ATCMD_F_READ);
1101 const char PROGMEM help_monitor_add[] = "add a register in monitor list";
1103 const parse_inst_t PROGMEM cmd_monitor_add = {
1104 .f = cmd_monitor_add_parsed, /* function to call */
1105 .data = NULL, /* 2nd arg of func */
1106 .help_str = help_monitor_add,
1107 .tokens = { /* token list, NULL terminated */
1108 (PGM_P)&cmd_monitor_add_monitor_add,
1109 (PGM_P)&cmd_monitor_add_action,
1110 (PGM_P)&cmd_monitor_add_atcmd,
1117 /* this structure is filled when cmd_monitor_period is parsed successfully */
1118 struct cmd_monitor_period_result {
1119 fixed_string_t monitor;
1120 fixed_string_t action;
1124 /* function called when cmd_monitor_period is parsed successfully */
1125 static void cmd_monitor_period_parsed(void *parsed_result, void *data)
1127 struct cmd_monitor_period_result *res = parsed_result;
1130 if (res->period < 100) {
1131 printf_P(PSTR("error, minimum period is 100 ms\r\n"));
1135 monitor_period_ms = res->period;
1138 const char PROGMEM str_monitor_period[] = "period";
1140 const parse_token_string_t PROGMEM cmd_monitor_period_monitor_period =
1141 TOKEN_STRING_INITIALIZER(struct cmd_monitor_period_result, monitor,
1143 const parse_token_string_t PROGMEM cmd_monitor_period_action =
1144 TOKEN_STRING_INITIALIZER(struct cmd_monitor_period_result, action,
1145 str_monitor_period);
1146 const parse_token_num_t PROGMEM cmd_monitor_period_period =
1147 TOKEN_NUM_INITIALIZER(struct cmd_monitor_period_result, period, UINT32);
1150 const char PROGMEM help_monitor_period[] = "set register monitoring period";
1152 const parse_inst_t PROGMEM cmd_monitor_period = {
1153 .f = cmd_monitor_period_parsed, /* function to call */
1154 .data = NULL, /* 2nd arg of func */
1155 .help_str = help_monitor_period,
1156 .tokens = { /* token list, NULL terminated */
1157 (PGM_P)&cmd_monitor_period_monitor_period,
1158 (PGM_P)&cmd_monitor_period_action,
1159 (PGM_P)&cmd_monitor_period_period,
1166 /* this structure is filled when cmd_monitor_del is parsed successfully */
1167 struct cmd_monitor_del_result {
1168 fixed_string_t monitor;
1169 fixed_string_t action;
1170 struct monitor_reg *m;
1173 /* function called when cmd_monitor_del is parsed successfully */
1174 static void cmd_monitor_del_parsed(void *parsed_result, void *data)
1176 struct cmd_monitor_del_result *res = parsed_result;
1179 monitor_current = LIST_NEXT(res->m, next);
1180 LIST_REMOVE(res->m, next);
1183 if (monitor_count == 0) {
1184 printf_P(PSTR("Disable monitoring, no more event\r\n"));
1185 callout_stop(&xbeeboard.mainloop_cm, &monitor_event);
1186 monitor_running = 0;
1191 const char PROGMEM str_monitor_del[] = "del";
1193 const parse_token_string_t PROGMEM cmd_monitor_del_monitor_del =
1194 TOKEN_STRING_INITIALIZER(struct cmd_monitor_del_result, monitor,
1196 const parse_token_string_t PROGMEM cmd_monitor_del_action =
1197 TOKEN_STRING_INITIALIZER(struct cmd_monitor_del_result, action,
1199 const parse_token_monitor_t PROGMEM cmd_monitor_del_atcmd =
1200 TOKEN_MONITOR_INITIALIZER(struct cmd_monitor_del_result, m);
1203 const char PROGMEM help_monitor_del[] = "del a register in monitor list";
1205 const parse_inst_t PROGMEM cmd_monitor_del = {
1206 .f = cmd_monitor_del_parsed, /* function to call */
1207 .data = NULL, /* 2nd arg of func */
1208 .help_str = help_monitor_del,
1209 .tokens = { /* token list, NULL terminated */
1210 (PGM_P)&cmd_monitor_del_monitor_del,
1211 (PGM_P)&cmd_monitor_del_action,
1212 (PGM_P)&cmd_monitor_del_atcmd,
1220 /* this structure is filled when cmd_ping is parsed successfully */
1221 struct cmd_ping_result {
1222 fixed_string_t ping;
1225 /* function called when cmd_ping is parsed successfully */
1226 static void cmd_ping_parsed(void *parsed_result, void *data)
1228 (void)parsed_result;
1230 xbeeapp_send_atcmd("VL", NULL, 0, 1, NULL, NULL);
1233 const char PROGMEM str_ping[] = "ping";
1235 const parse_token_string_t PROGMEM cmd_ping_ping =
1236 TOKEN_STRING_INITIALIZER(struct cmd_ping_result, ping,
1239 const char PROGMEM help_ping[] = "Send a ping to the xbee device";
1241 const parse_inst_t PROGMEM cmd_ping = {
1242 .f = cmd_ping_parsed, /* function to call */
1243 .data = NULL, /* 2nd arg of func */
1244 .help_str = help_ping,
1245 .tokens = { /* token list, NULL terminated */
1246 (PGM_P)&cmd_ping_ping,
1253 /* this structure is filled when cmd_raw is parsed successfully */
1254 struct cmd_raw_result {
1258 /* function called when cmd_raw is parsed successfully */
1259 static void cmd_raw_parsed(void *parsed_result, void *data)
1261 (void)parsed_result;
1264 if (range_running || monitor_running) {
1265 printf_P(PSTR("stop running range or monitor first\r\n"));
1268 printf_P(PSTR("switched to raw mode, CTRL-D to exit\r\n"));
1269 rdline_stop(&xbeeboard.rdl); /* don't display prompt when return */
1273 const char PROGMEM str_raw[] = "raw";
1275 const parse_token_string_t PROGMEM cmd_raw_raw =
1276 TOKEN_STRING_INITIALIZER(struct cmd_raw_result, raw,
1279 const char PROGMEM help_raw[] = "Switch to raw mode";
1281 const parse_inst_t PROGMEM cmd_raw = {
1282 .f = cmd_raw_parsed, /* function to call */
1283 .data = NULL, /* 2nd arg of func */
1284 .help_str = help_raw,
1285 .tokens = { /* token list, NULL terminated */
1286 (PGM_P)&cmd_raw_raw,
1293 /* this structure is filled when cmd_dump is parsed successfully */
1294 struct cmd_dump_result {
1295 fixed_string_t dump;
1296 fixed_string_t onoff;
1299 /* function called when cmd_dump is parsed successfully */
1300 static void cmd_dump_parsed(void *parsed_result, void *data)
1302 struct cmd_dump_result *res = parsed_result;
1305 if (!strcmp(res->onoff, "on"))
1311 const char PROGMEM str_dump[] = "dump";
1312 const char PROGMEM str_dump_onoff[] = "on#off";
1314 const parse_token_string_t PROGMEM cmd_dump_dump =
1315 TOKEN_STRING_INITIALIZER(struct cmd_dump_result, dump,
1318 const parse_token_string_t PROGMEM cmd_dump_onoff =
1319 TOKEN_STRING_INITIALIZER(struct cmd_dump_result, onoff,
1322 const char PROGMEM help_dump[] = "enable/disable hexdump of received packets";
1324 const parse_inst_t PROGMEM cmd_dump = {
1325 .f = cmd_dump_parsed, /* function to call */
1326 .data = NULL, /* 2nd arg of func */
1327 .help_str = help_dump,
1328 .tokens = { /* token list, NULL terminated */
1329 (PGM_P)&cmd_dump_dump,
1330 (PGM_P)&cmd_dump_onoff,
1337 /* this structure is filled when cmd_debug is parsed successfully */
1338 struct cmd_debug_result {
1339 fixed_string_t debug;
1340 fixed_string_t onoff;
1343 /* function called when cmd_debug is parsed successfully */
1344 static void cmd_debug_parsed(void *parsed_result, void *data)
1346 struct cmd_debug_result *res = parsed_result;
1349 if (!strcmp(res->onoff, "on"))
1355 const char PROGMEM str_debug[] = "debug";
1356 const char PROGMEM str_debug_onoff[] = "on#off";
1358 const parse_token_string_t PROGMEM cmd_debug_debug =
1359 TOKEN_STRING_INITIALIZER(struct cmd_debug_result, debug,
1362 const parse_token_string_t PROGMEM cmd_debug_onoff =
1363 TOKEN_STRING_INITIALIZER(struct cmd_debug_result, onoff,
1366 const char PROGMEM help_debug[] = "enable/disable additionnal debug";
1368 const parse_inst_t PROGMEM cmd_debug = {
1369 .f = cmd_debug_parsed, /* function to call */
1370 .data = NULL, /* 2nd arg of func */
1371 .help_str = help_debug,
1372 .tokens = { /* token list, NULL terminated */
1373 (PGM_P)&cmd_debug_debug,
1374 (PGM_P)&cmd_debug_onoff,
1379 /**********************************************************/
1381 /* this structure is filled when cmd_baudrate is parsed successfully */
1382 struct cmd_baudrate_result {
1383 fixed_string_t arg0;
1387 /* function called when cmd_baudrate is parsed successfully */
1388 static void cmd_baudrate_parsed(void * parsed_result, __attribute__((unused)) void *data)
1390 struct cmd_baudrate_result *res = parsed_result;
1391 struct uart_config c;
1393 uart_getconf(XBEE_UART, &c);
1394 c.baudrate = res->arg1;
1395 uart_setconf(XBEE_UART, &c);
1398 const char PROGMEM str_baudrate_arg0[] = "baudrate";
1399 const parse_token_string_t PROGMEM cmd_baudrate_arg0 =
1400 TOKEN_STRING_INITIALIZER(struct cmd_baudrate_result, arg0,
1402 const parse_token_num_t PROGMEM cmd_baudrate_arg1 =
1403 TOKEN_NUM_INITIALIZER(struct cmd_baudrate_result, arg1,
1406 const char PROGMEM help_baudrate[] = "Change xbee baudrate";
1407 const parse_inst_t PROGMEM cmd_baudrate = {
1408 .f = cmd_baudrate_parsed, /* function to call */
1409 .data = NULL, /* 2nd arg of func */
1410 .help_str = help_baudrate,
1411 .tokens = { /* token list, NULL terminated */
1412 (PGM_P)&cmd_baudrate_arg0,
1413 (PGM_P)&cmd_baudrate_arg1,
1419 /**********************************************************/
1421 /* this structure is filled when cmd_beep is parsed successfully */
1422 struct cmd_beep_result {
1423 fixed_string_t beep;
1426 /* function called when cmd_beep is parsed successfully */
1427 static void cmd_beep_parsed(void *parsed_result, void *data)
1429 (void)parsed_result;
1440 const char PROGMEM str_beep[] = "beep";
1441 const parse_token_string_t PROGMEM cmd_beep_beep =
1442 TOKEN_STRING_INITIALIZER(struct cmd_beep_result, beep,
1445 const char PROGMEM help_beep[] = "Send a beep";
1447 const parse_inst_t PROGMEM cmd_beep = {
1448 .f = cmd_beep_parsed, /* function to call */
1449 .data = NULL, /* 2nd arg of func */
1450 .help_str = help_beep,
1451 .tokens = { /* token list, NULL terminated */
1452 (PGM_P)&cmd_beep_beep,
1457 /**********************************************************/
1459 /* this structure is filled when cmd_servo is parsed successfully */
1460 struct cmd_servo_result {
1461 fixed_string_t arg0;
1462 fixed_string_t arg1;
1467 /* function called when cmd_servo is parsed successfully */
1468 static void cmd_servo_parsed(void * parsed_result, void *data)
1470 struct cmd_servo_result *res = parsed_result;
1474 if (!strcmp_P(res->arg1, PSTR("set"))) {
1475 if (res->num >= N_SERVO) {
1476 printf_P(PSTR("bad servo num\n"));
1479 if (res->val >= 1024) {
1480 printf_P(PSTR("bad servo val\n"));
1483 spi_servo_set(res->num, res->val);
1485 else if (!strcmp_P(res->arg1, PSTR("bypass"))) {
1486 spi_servo_set_bypass(!!res->val);
1488 else if (!strcmp_P(res->arg1, PSTR("ppm"))) {
1489 spi_servo_set_ppm(!!res->val);
1491 else if (!strcmp_P(res->arg1, PSTR("show"))) {
1496 const char PROGMEM str_servo_arg0[] = "servo";
1497 const parse_token_string_t PROGMEM cmd_servo_arg0 =
1498 TOKEN_STRING_INITIALIZER(struct cmd_servo_result, arg0,
1500 const char PROGMEM str_servo_arg1_set[] = "set";
1501 const parse_token_string_t PROGMEM cmd_servo_arg1_set =
1502 TOKEN_STRING_INITIALIZER(struct cmd_servo_result, arg1,
1503 str_servo_arg1_set);
1504 const parse_token_num_t PROGMEM cmd_servo_num =
1505 TOKEN_NUM_INITIALIZER(struct cmd_servo_result, num,
1507 const parse_token_num_t PROGMEM cmd_servo_val =
1508 TOKEN_NUM_INITIALIZER(struct cmd_servo_result, val,
1511 const char PROGMEM help_servo_set[] = "set servo value";
1512 const parse_inst_t PROGMEM cmd_servo_set = {
1513 .f = cmd_servo_parsed, /* function to call */
1514 .data = NULL, /* 2nd arg of func */
1515 .help_str = help_servo_set,
1516 .tokens = { /* token list, NULL terminated */
1517 (PGM_P)&cmd_servo_arg0,
1518 (PGM_P)&cmd_servo_arg1_set,
1519 (PGM_P)&cmd_servo_num,
1520 (PGM_P)&cmd_servo_val,
1525 const char PROGMEM str_servo_arg1_show[] = "show";
1526 const parse_token_string_t PROGMEM cmd_servo_arg1_show =
1527 TOKEN_STRING_INITIALIZER(struct cmd_servo_result, arg1,
1528 str_servo_arg1_show);
1530 const char PROGMEM help_servo_show[] = "read servo and config";
1531 const parse_inst_t PROGMEM cmd_servo_show = {
1532 .f = cmd_servo_parsed, /* function to call */
1533 .data = NULL, /* 2nd arg of func */
1534 .help_str = help_servo_show,
1535 .tokens = { /* token list, NULL terminated */
1536 (PGM_P)&cmd_servo_arg0,
1537 (PGM_P)&cmd_servo_arg1_show,
1542 const char PROGMEM str_servo_arg1_bypassppm[] = "bypass#ppm";
1543 const parse_token_string_t PROGMEM cmd_servo_arg1_bypassppm =
1544 TOKEN_STRING_INITIALIZER(struct cmd_servo_result, arg1,
1545 str_servo_arg1_bypassppm);
1547 const char PROGMEM help_servo_bypassppm[] = "change bypass/ppm";
1548 const parse_inst_t PROGMEM cmd_servo_bypassppm = {
1549 .f = cmd_servo_parsed, /* function to call */
1550 .data = NULL, /* 2nd arg of func */
1551 .help_str = help_servo_bypassppm,
1552 .tokens = { /* token list, NULL terminated */
1553 (PGM_P)&cmd_servo_arg0,
1554 (PGM_P)&cmd_servo_arg1_bypassppm,
1555 (PGM_P)&cmd_servo_val,
1560 /**********************************************************/
1562 /* this structure is filled when cmd_test_spi is parsed successfully */
1563 struct cmd_test_spi_result {
1564 fixed_string_t arg0;
1567 static void cmd_test_spi_parsed(void * parsed_result, void *data)
1569 uint8_t i, flags, wait_time = 0;
1572 (void)parsed_result;
1575 spi_servo_set_bypass(0);
1576 spi_servo_set_ppm(0);
1578 /* stress test: send many commands, no wait between each servo
1579 * of a series, and a variable delay between series */
1580 printf_P(PSTR("stress test\r\n"));
1581 while (!cmdline_keypressed()) {
1593 for (i = 0; i < 6; i++)
1594 spi_servo_set(i, val);
1597 printf_P(PSTR("%4.4d %4.4d %4.4d %4.4d %4.4d %4.4d\r\n"),
1598 spi_servo_get(0), spi_servo_get(1), spi_servo_get(2),
1599 spi_servo_get(3), spi_servo_get(4), spi_servo_get(5));
1602 printf_P(PSTR("bypass mode, with spi commands in background\r\n"));
1603 spi_servo_set_bypass(1);
1605 /* test bypass mode */
1606 while (!cmdline_keypressed()) {
1618 for (i = 0; i < 6; i++)
1619 spi_servo_set(i, val);
1622 printf_P(PSTR("%4.4d %4.4d %4.4d %4.4d %4.4d %4.4d\r\n"),
1623 spi_servo_get(0), spi_servo_get(1), spi_servo_get(2),
1624 spi_servo_get(3), spi_servo_get(4), spi_servo_get(5));
1627 printf_P(PSTR("PPM to servo\r\n"));
1628 spi_servo_set_bypass(0);
1629 spi_servo_set_ppm(0);
1631 /* test PPM to servo (bypass) mode */
1632 while (!cmdline_keypressed()) {
1633 for (i = 0; i < 6; i++) {
1634 val = spi_servo_get(i);
1635 spi_servo_set(i, val);
1639 printf_P(PSTR("PPM to (servo + PPM)\r\n"));
1640 spi_servo_set_bypass(0);
1641 spi_servo_set_ppm(1);
1643 /* test PPM to servo (bypass) mode */
1644 while (!cmdline_keypressed()) {
1645 for (i = 0; i < 6; i++) {
1646 val = spi_servo_get(i);
1647 spi_servo_set(i, val);
1652 const char PROGMEM str_test_spi_arg0[] = "test_spi";
1653 const parse_token_string_t PROGMEM cmd_test_spi_arg0 =
1654 TOKEN_STRING_INITIALIZER(struct cmd_test_spi_result, arg0,
1657 const char PROGMEM help_test_spi[] = "Test the spi";
1658 const parse_inst_t PROGMEM cmd_test_spi = {
1659 .f = cmd_test_spi_parsed, /* function to call */
1660 .data = NULL, /* 2nd arg of func */
1661 .help_str = help_test_spi,
1662 .tokens = { /* token list, NULL terminated */
1663 (PGM_P)&cmd_test_spi_arg0,
1668 /**********************************************************/
1670 /* this structure is filled when cmd_dump_xbee_stats is parsed successfully */
1671 struct cmd_dump_xbee_stats_result {
1672 fixed_string_t arg0;
1675 static void cmd_dump_xbee_stats_parsed(void *parsed_result, void *data)
1677 (void)parsed_result;
1680 xbee_dump_stats(xbee_dev);
1683 const char PROGMEM str_dump_xbee_stats_arg0[] = "dump_xbee_stats";
1684 const parse_token_string_t PROGMEM cmd_dump_xbee_stats_arg0 =
1685 TOKEN_STRING_INITIALIZER(struct cmd_dump_xbee_stats_result, arg0,
1686 str_dump_xbee_stats_arg0);
1688 const char PROGMEM help_dump_xbee_stats[] = "Test the spi";
1689 const parse_inst_t PROGMEM cmd_dump_xbee_stats = {
1690 .f = cmd_dump_xbee_stats_parsed, /* function to call */
1691 .data = NULL, /* 2nd arg of func */
1692 .help_str = help_dump_xbee_stats,
1693 .tokens = { /* token list, NULL terminated */
1694 (PGM_P)&cmd_dump_xbee_stats_arg0,
1699 /**********************************************************/
1701 /* this structure is filled when cmd_test_eeprom_config is parsed successfully */
1702 struct cmd_test_eeprom_config_result {
1703 fixed_string_t arg0;
1706 static void cmd_test_eeprom_config_parsed(void *parsed_result, void *data)
1708 (void)parsed_result;
1712 eeprom_append_cmd("salut1\n");
1714 eeprom_append_cmd("salut2\n");
1715 eeprom_append_cmd("salut3\n");
1716 eeprom_append_cmd("salut4\n");
1718 eeprom_insert_cmd_before("coin\n", 0);
1719 eeprom_insert_cmd_before("coin2\n", 2);
1721 eeprom_delete_cmd(2);
1722 eeprom_delete_cmd(0);
1726 const char PROGMEM str_test_eeprom_config_arg0[] = "test_eeprom_config";
1727 const parse_token_string_t PROGMEM cmd_test_eeprom_config_arg0 =
1728 TOKEN_STRING_INITIALIZER(struct cmd_test_eeprom_config_result, arg0,
1729 str_test_eeprom_config_arg0);
1731 const char PROGMEM help_test_eeprom_config[] = "Test the eeprom configuration";
1732 const parse_inst_t PROGMEM cmd_test_eeprom_config = {
1733 .f = cmd_test_eeprom_config_parsed, /* function to call */
1734 .data = NULL, /* 2nd arg of func */
1735 .help_str = help_test_eeprom_config,
1736 .tokens = { /* token list, NULL terminated */
1737 (PGM_P)&cmd_test_eeprom_config_arg0,
1744 struct cmd_eeprom_del_result {
1746 fixed_string_t action;
1750 static void cmd_eeprom_del_parsed(void *parsed_result,
1753 struct cmd_eeprom_del_result *res = parsed_result;
1756 if (eeprom_delete_cmd(res->n) < 0)
1757 printf_P(PSTR("cannot delete command\n"));
1761 const char PROGMEM str_eeprom_del_eeprom[] = "eeprom";
1762 const parse_token_string_t PROGMEM cmd_eeprom_del_cmd =
1763 TOKEN_STRING_INITIALIZER(struct cmd_eeprom_del_result, cmd,
1764 str_eeprom_del_eeprom);
1765 const char PROGMEM str_eeprom_del_del[] = "del";
1766 const parse_token_string_t PROGMEM cmd_eeprom_del_action =
1767 TOKEN_STRING_INITIALIZER(struct cmd_eeprom_del_result, action,
1768 str_eeprom_del_del);
1769 const parse_token_num_t PROGMEM cmd_eeprom_del_num =
1770 TOKEN_NUM_INITIALIZER(struct cmd_eeprom_del_result, n,
1773 const char PROGMEM help_eeprom_del[] = "delete an eeprom init command";
1774 const parse_inst_t PROGMEM cmd_eeprom_del = {
1775 .f = cmd_eeprom_del_parsed, /* function to call */
1776 .data = NULL, /* 2nd arg of func */
1777 .help_str = help_eeprom_del,
1778 .tokens = { /* token list, NULL terminated */
1779 (PGM_P)&cmd_eeprom_del_cmd,
1780 (PGM_P)&cmd_eeprom_del_action,
1781 (PGM_P)&cmd_eeprom_del_num,
1788 struct cmd_eeprom_add_result {
1790 fixed_string_t action;
1794 static void cmd_eeprom_add_parsed(void *parsed_result,
1797 struct cmd_eeprom_add_result *res = parsed_result;
1803 rdline_init(&rdl, cmdline_write_char, NULL, NULL);
1804 rdline_newline(&rdl, "> ");
1806 /* XXX bad: we should not block as we do not serve callout */
1808 c = cmdline_dev_recv(NULL);
1812 ret = rdline_char_in(&rdl, c);
1814 printf_P(PSTR("abort\n"));
1821 buffer = rdline_get_buffer(&rdl);
1823 eeprom_insert_cmd_before(buffer, res->n);
1825 eeprom_append_cmd(buffer);
1829 const char PROGMEM str_eeprom_add_eeprom[] = "eeprom";
1830 const parse_token_string_t PROGMEM cmd_eeprom_add_cmd =
1831 TOKEN_STRING_INITIALIZER(struct cmd_eeprom_add_result, cmd,
1832 str_eeprom_add_eeprom);
1833 const char PROGMEM str_eeprom_add_add[] = "add";
1834 const parse_token_string_t PROGMEM cmd_eeprom_add_action =
1835 TOKEN_STRING_INITIALIZER(struct cmd_eeprom_add_result, action,
1836 str_eeprom_add_add);
1837 const parse_token_num_t PROGMEM cmd_eeprom_add_num =
1838 TOKEN_NUM_INITIALIZER(struct cmd_eeprom_add_result, n,
1841 const char PROGMEM help_eeprom_add[] = "insert an eeprom init command";
1842 const parse_inst_t PROGMEM cmd_eeprom_add = {
1843 .f = cmd_eeprom_add_parsed, /* function to call */
1844 .data = NULL, /* 2nd arg of func */
1845 .help_str = help_eeprom_add,
1846 .tokens = { /* token list, NULL terminated */
1847 (PGM_P)&cmd_eeprom_add_cmd,
1848 (PGM_P)&cmd_eeprom_add_action,
1849 (PGM_P)&cmd_eeprom_add_num,
1854 const char PROGMEM help_eeprom_add2[] = "append an eeprom init command";
1855 const parse_inst_t PROGMEM cmd_eeprom_add2 = {
1856 .f = cmd_eeprom_add_parsed, /* function to call */
1857 .data = (void *)1, /* 2nd arg of func */
1858 .help_str = help_eeprom_add2,
1859 .tokens = { /* token list, NULL terminated */
1860 (PGM_P)&cmd_eeprom_add_cmd,
1861 (PGM_P)&cmd_eeprom_add_action,
1868 struct cmd_eeprom_list_result {
1870 fixed_string_t action;
1873 static void cmd_eeprom_list_parsed(void *parsed_result,
1876 (void)parsed_result;
1881 const char PROGMEM str_eeprom_list_eeprom[] = "eeprom";
1882 const parse_token_string_t PROGMEM cmd_eeprom_list_cmd =
1883 TOKEN_STRING_INITIALIZER(struct cmd_eeprom_list_result, cmd,
1884 str_eeprom_list_eeprom);
1885 const char PROGMEM str_eeprom_list_list[] = "list";
1886 const parse_token_string_t PROGMEM cmd_eeprom_list_action =
1887 TOKEN_STRING_INITIALIZER(struct cmd_eeprom_list_result, action,
1888 str_eeprom_list_list);
1890 const char PROGMEM help_eeprom_list[] = "list all eeprom init commands";
1891 const parse_inst_t PROGMEM cmd_eeprom_list = {
1892 .f = cmd_eeprom_list_parsed, /* function to call */
1893 .data = NULL, /* 2nd arg of func */
1894 .help_str = help_eeprom_list,
1895 .tokens = { /* token list, NULL terminated */
1896 (PGM_P)&cmd_eeprom_list_cmd,
1897 (PGM_P)&cmd_eeprom_list_action,
1906 const parse_ctx_t PROGMEM main_ctx[] = {
1908 /* commands_gen.c */
1927 &cmd_send_hello_name,
1932 &cmd_range_powermask,
1935 &cmd_monitor_period,
1945 &cmd_servo_bypassppm,
1948 &cmd_dump_xbee_stats,
1949 &cmd_test_eeprom_config,