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 /* no rx_cb given: the user must check the monitored values in logs */
87 xbeeapp_send_atcmd(monitor_current->atcmd, NULL, 0, NULL, NULL);
88 monitor_current = LIST_NEXT(monitor_current, next);
89 callout_reschedule(cm, clt, monitor_period_ms / monitor_count);
92 static void range_cb(struct callout_mgr *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) {
124 callout_stop(cm, clt);
127 callout_reschedule(cm, clt, range_period_ms);
129 /* callback invoked when a xbee_send is done */
130 static int8_t send_msg_cb(int8_t retcode, void *frame, unsigned len,
133 struct xbee_recv_hdr *recvframe = frame;
137 if (retcode == XBEE_USER_RETCODE_TIMEOUT) {
138 printf_P(PSTR("timeout\r\n"));
141 if (retcode == XBEE_USER_RETCODE_BAD_FRAME ||
142 len < sizeof(*recvframe)) {
143 printf_P(PSTR("invalid frame\r\n"));
144 return XBEE_USER_RETCODE_BAD_FRAME;
147 printf_P(PSTR("ok\r\n"));
148 return XBEE_USER_RETCODE_OK;
151 /* callback invoked to dump the response to AT command */
152 static int8_t dump_xbee_atresp_cb(int8_t retcode, void *frame, unsigned len,
155 struct xbee_atresp_hdr *recvframe = frame;
161 if (retcode == XBEE_USER_RETCODE_TIMEOUT) {
162 printf_P(PSTR("timeout\r\n"));
165 if (retcode == XBEE_USER_RETCODE_BAD_FRAME ||
166 len < sizeof(*recvframe)) {
167 printf_P(PSTR("invalid frame\r\n"));
168 return XBEE_USER_RETCODE_BAD_FRAME;
171 /* get AT command from frame */
172 memcpy(atcmd_str, &recvframe->cmd, 2);
175 len -= sizeof(*recvframe);
176 atresp_to_str(buf, sizeof(buf), frame);
177 NOTICE(E_USER_XBEE, "status ok, len=%d, %s", len, buf);
178 return XBEE_USER_RETCODE_OK;
181 /* this structure is filled when cmd_help is parsed successfully */
182 struct cmd_help_result {
184 struct xbee_atcmd *cmd;
187 /* function called when cmd_help is parsed successfully */
188 static void cmd_help_parsed(void *parsed_result, void *data)
190 struct cmd_help_result *res = parsed_result;
191 struct xbee_atcmd cmdcopy;
196 memcpy_P(&cmdcopy, res->cmd, sizeof(cmdcopy));
197 type = (cmdcopy.flags & (XBEE_ATCMD_F_READ | XBEE_ATCMD_F_WRITE));
199 case XBEE_ATCMD_F_READ:
200 printf_P(PSTR("Read-only\r\n"));
202 case XBEE_ATCMD_F_WRITE:
203 printf_P(PSTR("Write-only\r\n"));
206 printf_P(PSTR("Read-write\r\n"));
209 if (cmdcopy.flags & XBEE_ATCMD_F_PARAM_NONE)
210 printf_P(PSTR("No argument\r\n"));
211 else if (cmdcopy.flags & XBEE_ATCMD_F_PARAM_U8)
212 printf_P(PSTR("Register is unsigned 8 bits\r\n"));
213 else if (cmdcopy.flags & XBEE_ATCMD_F_PARAM_U16)
214 printf_P(PSTR("Register is unsigned 16 bits\r\n"));
215 else if (cmdcopy.flags & XBEE_ATCMD_F_PARAM_U32)
216 printf_P(PSTR("Register is unsigned 32 bits\r\n"));
217 else if (cmdcopy.flags & XBEE_ATCMD_F_PARAM_S16)
218 printf_P(PSTR("Register is signed 16 bits\r\n"));
219 else if (cmdcopy.flags & XBEE_ATCMD_F_PARAM_STRING_20B)
220 printf_P(PSTR("Register is a 20 bytes string\r\n"));
222 printf_P(PSTR("Unknown argument\r\n"));
224 printf_P(PSTR("%S\r\n"), cmdcopy.help);
226 const char PROGMEM str_help_help[] = "help";
228 const parse_token_string_t PROGMEM cmd_help_help =
229 TOKEN_STRING_INITIALIZER(struct cmd_help_result, help, str_help_help);
231 const parse_token_atcmd_t PROGMEM cmd_help_atcmd =
232 TOKEN_ATCMD_INITIALIZER(struct cmd_help_result, cmd, &xbee_dev,
235 const char PROGMEM help_help[] = "Help a register using an AT command";
236 const parse_inst_t PROGMEM cmd_help = {
237 .f = cmd_help_parsed, /* function to call */
238 .data = NULL, /* 2nd arg of func */
239 .help_str = help_help,
240 .tokens = { /* token list, NULL terminated */
241 (PGM_P)&cmd_help_help,
242 (PGM_P)&cmd_help_atcmd,
249 struct cmd_neigh_del_result {
251 fixed_string_t action;
252 struct xbee_neigh *neigh;
255 static void cmd_neigh_del_parsed(void *parsed_result,
258 struct cmd_neigh_del_result *res = parsed_result;
261 xbee_neigh_del(xbee_dev, res->neigh);
264 const char PROGMEM str_neigh_del_neigh[] = "neigh";
265 const parse_token_string_t PROGMEM cmd_neigh_del_cmd =
266 TOKEN_STRING_INITIALIZER(struct cmd_neigh_del_result, cmd,
267 str_neigh_del_neigh);
268 const char PROGMEM str_neigh_del_del[] = "del";
269 const parse_token_string_t PROGMEM cmd_neigh_del_action =
270 TOKEN_STRING_INITIALIZER(struct cmd_neigh_del_result, action,
272 const parse_token_neighbor_t PROGMEM cmd_neigh_del_neigh =
273 TOKEN_NEIGHBOR_INITIALIZER(struct cmd_neigh_del_result, neigh,
276 const char PROGMEM help_neigh_del[] = "delete a neighbor";
277 const parse_inst_t PROGMEM cmd_neigh_del = {
278 .f = cmd_neigh_del_parsed, /* function to call */
279 .data = NULL, /* 2nd arg of func */
280 .help_str = help_neigh_del,
281 .tokens = { /* token list, NULL terminated */
282 (PGM_P)&cmd_neigh_del_cmd,
283 (PGM_P)&cmd_neigh_del_action,
284 (PGM_P)&cmd_neigh_del_neigh,
291 struct cmd_neigh_add_result {
293 fixed_string_t action;
298 static void cmd_neigh_add_parsed(void *parsed_result,
301 struct cmd_neigh_add_result *res = parsed_result;
304 if (xbee_neigh_add(xbee_dev, res->name, res->addr) == NULL)
305 printf_P(PSTR("name or addr already exist\r\n"));
308 const char PROGMEM str_neigh_add_neigh[] = "neigh";
309 const parse_token_string_t PROGMEM cmd_neigh_add_cmd =
310 TOKEN_STRING_INITIALIZER(struct cmd_neigh_add_result, cmd,
311 str_neigh_add_neigh);
312 const char PROGMEM str_neigh_add_add[] = "add";
313 const parse_token_string_t PROGMEM cmd_neigh_add_action =
314 TOKEN_STRING_INITIALIZER(struct cmd_neigh_add_result, action,
316 const parse_token_string_t PROGMEM cmd_neigh_add_name =
317 TOKEN_STRING_INITIALIZER(struct cmd_neigh_add_result, name, NULL);
318 const parse_token_num_t PROGMEM cmd_neigh_add_addr =
319 TOKEN_NUM_INITIALIZER(struct cmd_neigh_add_result, addr, UINT64);
321 const char PROGMEM help_neigh_add[] = "add a neighbor";
322 const parse_inst_t PROGMEM cmd_neigh_add = {
323 .f = cmd_neigh_add_parsed, /* function to call */
324 .data = NULL, /* 2nd arg of func */
325 .help_str = help_neigh_add,
326 .tokens = { /* token list, NULL terminated */
327 (PGM_P)&cmd_neigh_add_cmd,
328 (PGM_P)&cmd_neigh_add_action,
329 (PGM_P)&cmd_neigh_add_name,
330 (PGM_P)&cmd_neigh_add_addr,
337 struct cmd_neigh_list_result {
339 fixed_string_t action;
342 static void cmd_neigh_list_parsed(void *parsed_result,
345 struct xbee_neigh *neigh;
349 LIST_FOREACH(neigh, &xbee_dev->neigh_list, next) {
350 printf_P(PSTR(" %s: 0x%.8"PRIx32"%.8"PRIx32"\r\n"),
352 (uint32_t)(neigh->addr >> 32ULL),
353 (uint32_t)(neigh->addr & 0xFFFFFFFF));
357 const char PROGMEM str_neigh_list_neigh[] = "neigh";
358 const parse_token_string_t PROGMEM cmd_neigh_list_cmd =
359 TOKEN_STRING_INITIALIZER(struct cmd_neigh_list_result, cmd,
360 str_neigh_list_neigh);
361 const char PROGMEM str_neigh_list_list[] = "list";
362 const parse_token_string_t PROGMEM cmd_neigh_list_action =
363 TOKEN_STRING_INITIALIZER(struct cmd_neigh_list_result, action,
364 str_neigh_list_list);
366 const char PROGMEM help_neigh_list[] = "list all knwon neighbors";
367 const parse_inst_t PROGMEM cmd_neigh_list = {
368 .f = cmd_neigh_list_parsed, /* function to call */
369 .data = NULL, /* 2nd arg of func */
370 .help_str = help_neigh_list,
371 .tokens = { /* token list, NULL terminated */
372 (PGM_P)&cmd_neigh_list_cmd,
373 (PGM_P)&cmd_neigh_list_action,
380 /* this structure is filled when cmd_read is parsed successfully */
381 struct cmd_read_result {
383 struct xbee_atcmd *cmd;
386 /* function called when cmd_read is parsed successfully */
387 static void cmd_read_parsed(void *parsed_result,
390 struct cmd_read_result *res = parsed_result;
391 struct xbee_atcmd copy;
393 volatile uint8_t done = 0;
396 memcpy_P(©, res->cmd, sizeof(copy));
397 memcpy_P(&cmd, copy.name, 2);
399 xbeeapp_send_atcmd(cmd, NULL, 0, dump_xbee_atresp_cb, (void *)&done);
403 const char PROGMEM str_read_read[] = "read";
405 const parse_token_string_t PROGMEM cmd_read_read =
406 TOKEN_STRING_INITIALIZER(struct cmd_read_result, read,
409 const parse_token_atcmd_t PROGMEM cmd_read_atcmd =
410 TOKEN_ATCMD_INITIALIZER(struct cmd_read_result, cmd, &xbee_dev,
411 XBEE_ATCMD_F_READ, XBEE_ATCMD_F_READ);
413 const char PROGMEM help_read[] = "Read a register using an AT command";
414 const parse_inst_t PROGMEM cmd_read = {
415 .f = cmd_read_parsed, /* function to call */
416 .data = NULL, /* 2nd arg of func */
417 .help_str = help_read,
418 .tokens = { /* token list, NULL terminated */
419 (PGM_P)&cmd_read_read,
420 (PGM_P)&cmd_read_atcmd,
428 /* this structure is filled when cmd_write is parsed successfully */
429 struct cmd_write_result {
430 fixed_string_t write;
431 struct xbee_atcmd *cmd;
439 /* function called when cmd_write is parsed successfully */
440 static void cmd_write_parsed(void *parsed_result, void *data)
442 struct cmd_write_result *res = parsed_result;
443 struct xbee_atcmd copy;
447 volatile uint8_t done = 0;
450 memcpy_P(©, res->cmd, sizeof(copy));
452 if (copy.flags & XBEE_ATCMD_F_PARAM_NONE) {
456 else if (copy.flags & XBEE_ATCMD_F_PARAM_U8) {
457 len = sizeof(res->u8);
460 else if (copy.flags & XBEE_ATCMD_F_PARAM_U16) {
461 len = sizeof(res->u16);
462 res->u16 = htons(res->u16);
465 else if (copy.flags & XBEE_ATCMD_F_PARAM_U32) {
466 len = sizeof(res->u32);
467 res->u32 = htonl(res->u32);
471 printf_P(PSTR("Unknown argument type\r\n"));
474 memcpy_P(&cmd, copy.name, 2);
476 xbeeapp_send_atcmd(cmd, param, len, dump_xbee_atresp_cb, (void *)&done);
480 const char PROGMEM str_write_none[] = "write";
482 const parse_token_string_t PROGMEM cmd_write_write =
483 TOKEN_STRING_INITIALIZER(struct cmd_write_result, write,
486 const parse_token_atcmd_t PROGMEM cmd_write_none_atcmd =
487 TOKEN_ATCMD_INITIALIZER(struct cmd_write_result, cmd,
489 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_NONE,
490 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_NONE);
492 const char PROGMEM help_write_none[] = "Send an AT command (no argument)";
494 const parse_inst_t PROGMEM cmd_write_none = {
495 .f = cmd_write_parsed, /* function to call */
496 .data = NULL, /* 2nd arg of func */
497 .help_str = help_write_none,
498 .tokens = { /* token list, NULL terminated */
499 (PGM_P)&cmd_write_write,
500 (PGM_P)&cmd_write_none_atcmd,
505 const parse_token_atcmd_t PROGMEM cmd_write_u8_atcmd =
506 TOKEN_ATCMD_INITIALIZER(struct cmd_write_result, cmd,
508 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_U8,
509 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_U8);
511 const parse_token_num_t PROGMEM cmd_write_u8_u8 =
512 TOKEN_NUM_INITIALIZER(struct cmd_write_result, u8, UINT8);
514 const char PROGMEM help_write_u8[] = "Write a 8 bits register using an AT command";
516 const parse_inst_t PROGMEM cmd_write_u8 = {
517 .f = cmd_write_parsed, /* function to call */
518 .data = NULL, /* 2nd arg of func */
519 .help_str = help_write_u8,
520 .tokens = { /* token list, NULL terminated */
521 (PGM_P)&cmd_write_write,
522 (PGM_P)&cmd_write_u8_atcmd,
523 (PGM_P)&cmd_write_u8_u8,
528 const parse_token_atcmd_t PROGMEM cmd_write_u16_atcmd =
529 TOKEN_ATCMD_INITIALIZER(struct cmd_write_result, cmd,
531 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_U16,
532 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_U16);
534 const parse_token_num_t PROGMEM cmd_write_u16_u16 =
535 TOKEN_NUM_INITIALIZER(struct cmd_write_result, u16, UINT16);
537 const char PROGMEM help_write_u16[] = "Write a 16 bits register using an AT command";
539 const parse_inst_t PROGMEM cmd_write_u16 = {
540 .f = cmd_write_parsed, /* function to call */
541 .data = NULL, /* 2nd arg of func */
542 .help_str = help_write_u16,
543 .tokens = { /* token list, NULL terminated */
544 (PGM_P)&cmd_write_write,
545 (PGM_P)&cmd_write_u16_atcmd,
546 (PGM_P)&cmd_write_u16_u16,
551 const parse_token_atcmd_t PROGMEM cmd_write_u32_atcmd =
552 TOKEN_ATCMD_INITIALIZER(struct cmd_write_result, cmd,
554 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_U32,
555 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_U32);
557 const parse_token_num_t PROGMEM cmd_write_u32_u32 =
558 TOKEN_NUM_INITIALIZER(struct cmd_write_result, u32, UINT32);
560 const char PROGMEM help_write_u32[] = "Write a 32 bits register using an AT command";
562 const parse_inst_t PROGMEM cmd_write_u32 = {
563 .f = cmd_write_parsed, /* function to call */
564 .data = NULL, /* 2nd arg of func */
565 .help_str = help_write_u32,
566 .tokens = { /* token list, NULL terminated */
567 (PGM_P)&cmd_write_write,
568 (PGM_P)&cmd_write_u32_atcmd,
569 (PGM_P)&cmd_write_u32_u32,
577 /* this structure is filled when cmd_sendmsg is parsed successfully */
578 struct cmd_sendmsg_result {
579 fixed_string_t sendmsg;
584 /* function called when cmd_sendmsg is parsed successfully */
585 static void cmd_sendmsg_parsed(void *parsed_result, void *data)
587 struct cmd_sendmsg_result *res = parsed_result;
589 volatile uint8_t done = 0;
594 msg.iov[0].buf = res->data;
595 msg.iov[0].len = strlen(res->data);
597 xbeeapp_send_msg(res->addr, &msg, send_msg_cb, (void *)&done);
601 const char PROGMEM str_sendmsg[] = "sendmsg";
603 const parse_token_string_t PROGMEM cmd_sendmsg_sendmsg =
604 TOKEN_STRING_INITIALIZER(struct cmd_sendmsg_result, sendmsg,
607 const parse_token_num_t PROGMEM cmd_sendmsg_addr =
608 TOKEN_NUM_INITIALIZER(struct cmd_sendmsg_result, addr, UINT64);
610 const parse_token_string_t PROGMEM cmd_sendmsg_data =
611 TOKEN_STRING_INITIALIZER(struct cmd_sendmsg_result, data, NULL);
613 const char PROGMEM help_sendmsg[] = "Send data to a node using its address";
615 const parse_inst_t PROGMEM cmd_sendmsg = {
616 .f = cmd_sendmsg_parsed, /* function to call */
617 .data = NULL, /* 2nd arg of func */
618 .help_str = help_sendmsg,
619 .tokens = { /* token list, NULL terminated */
620 (PGM_P)&cmd_sendmsg_sendmsg,
621 (PGM_P)&cmd_sendmsg_addr,
622 (PGM_P)&cmd_sendmsg_data,
629 /* this structure is filled when cmd_send_hello is parsed successfully */
630 struct cmd_send_hello_result {
631 fixed_string_t send_hello;
633 struct xbee_neigh *neigh;
639 /* function called when cmd_send_hello is parsed successfully */
640 static void cmd_send_hello_parsed(void *parsed_result, void *use_neigh)
642 struct cmd_send_hello_result *res = parsed_result;
643 uint16_t now, next, diff;
648 addr = res->neigh->addr;
658 while (!cmdline_keypressed() && res->count != 0) {
664 if (diff < res->period)
667 rc_proto_send_hello(addr, res->data, strlen(res->data));
673 const char PROGMEM str_send_hello[] = "send_hello";
675 const parse_token_string_t PROGMEM cmd_send_hello_send_hello =
676 TOKEN_STRING_INITIALIZER(struct cmd_send_hello_result, send_hello,
679 const parse_token_num_t PROGMEM cmd_send_hello_addr =
680 TOKEN_NUM_INITIALIZER(struct cmd_send_hello_result, addr, UINT64);
682 const parse_token_num_t PROGMEM cmd_send_hello_period =
683 TOKEN_NUM_INITIALIZER(struct cmd_send_hello_result, period, UINT16);
685 const parse_token_num_t PROGMEM cmd_send_hello_count =
686 TOKEN_NUM_INITIALIZER(struct cmd_send_hello_result, count, UINT16);
688 const parse_token_string_t PROGMEM cmd_send_hello_data =
689 TOKEN_STRING_INITIALIZER(struct cmd_send_hello_result, data, NULL);
691 const char PROGMEM help_send_hello[] =
692 "Send hello msg to a node: addr, period_ms, count, str";
694 const parse_inst_t PROGMEM cmd_send_hello = {
695 .f = cmd_send_hello_parsed, /* function to call */
696 .data = NULL, /* 2nd arg of func */
697 .help_str = help_send_hello,
698 .tokens = { /* token list, NULL terminated */
699 (PGM_P)&cmd_send_hello_send_hello,
700 (PGM_P)&cmd_send_hello_addr,
701 (PGM_P)&cmd_send_hello_period,
702 (PGM_P)&cmd_send_hello_count,
703 (PGM_P)&cmd_send_hello_data,
708 const parse_token_neighbor_t PROGMEM cmd_send_hello_neigh =
709 TOKEN_NEIGHBOR_INITIALIZER(struct cmd_send_hello_result, neigh,
712 const parse_inst_t PROGMEM cmd_send_hello_name = {
713 .f = cmd_send_hello_parsed, /* function to call */
714 .data = (void *)1, /* 2nd arg of func */
715 .help_str = help_send_hello,
716 .tokens = { /* token list, NULL terminated */
717 (PGM_P)&cmd_send_hello_send_hello,
718 (PGM_P)&cmd_send_hello_neigh,
719 (PGM_P)&cmd_send_hello_period,
720 (PGM_P)&cmd_send_hello_count,
721 (PGM_P)&cmd_send_hello_data,
728 /* this structure is filled when cmd_sendmsg_name is parsed successfully */
729 struct cmd_sendmsg_name_result {
730 fixed_string_t sendmsg_name;
731 struct xbee_neigh *neigh;
735 /* function called when cmd_sendmsg_name is parsed successfully */
736 static void cmd_sendmsg_name_parsed(void *parsed_result, void *data)
738 struct cmd_sendmsg_name_result *res = parsed_result;
740 volatile uint8_t done = 0;
745 msg.iov[0].buf = res->data;
746 msg.iov[0].len = strlen(res->data);
748 xbeeapp_send_msg(res->neigh->addr, &msg, send_msg_cb, (void *)&done);
752 const parse_token_string_t PROGMEM cmd_sendmsg_name_sendmsg_name =
753 TOKEN_STRING_INITIALIZER(struct cmd_sendmsg_name_result, sendmsg_name,
756 const parse_token_neighbor_t PROGMEM cmd_sendmsg_name_neigh =
757 TOKEN_NEIGHBOR_INITIALIZER(struct cmd_sendmsg_name_result, neigh,
760 const parse_token_string_t PROGMEM cmd_sendmsg_name_data =
761 TOKEN_STRING_INITIALIZER(struct cmd_sendmsg_name_result, data, NULL);
763 const char PROGMEM help_sendmsg_name[] = "Send data to a node using its name";
765 const parse_inst_t PROGMEM cmd_sendmsg_name = {
766 .f = cmd_sendmsg_name_parsed, /* function to call */
767 .data = NULL, /* 2nd arg of func */
768 .help_str = help_sendmsg_name,
769 .tokens = { /* token list, NULL terminated */
770 (PGM_P)&cmd_sendmsg_name_sendmsg_name,
771 (PGM_P)&cmd_sendmsg_name_neigh,
772 (PGM_P)&cmd_sendmsg_name_data,
780 /* this structure is filled when cmd_range is parsed successfully */
781 struct cmd_range_result {
782 fixed_string_t range;
783 fixed_string_t action;
786 /* function called when cmd_range is parsed successfully */
787 static void cmd_range_parsed(void *parsed_result, void *data)
789 struct cmd_range_result *res = parsed_result;
792 if (!strcmp_P(res->action, PSTR("show"))) {
793 printf_P(PSTR("range infos:\r\n"));
794 printf_P(PSTR(" range period %d\r\n"), range_period_ms);
795 printf_P(PSTR(" range count %d\r\n"), range_count);
796 printf_P(PSTR(" range powermask 0x%x\r\n"), range_powermask);
797 printf_P(PSTR(" range dstaddr 0x%.8"PRIx32"%.8"PRIx32"\r\n"),
798 (uint32_t)(range_dstaddr >> 32ULL),
799 (uint32_t)(range_dstaddr & 0xFFFFFFFF));
802 printf_P(PSTR(" range test is running\r\n"));
804 printf_P(PSTR(" range test is not running\r\n"));
806 else if (!strcmp(res->action, "start")) {
808 printf_P(PSTR("already running\r\n"));
811 range_cur_count = range_count;
812 callout_init(&range_event, range_cb, NULL, LOW_PRIO);
814 callout_schedule(&xbeeboard.intr_cm,
815 &range_event, 0); /* immediate */
817 else if (!strcmp(res->action, "end")) {
818 if (range_running == 0) {
819 printf_P(PSTR("not running\r\n"));
822 callout_stop(&xbeeboard.intr_cm, &range_event);
827 const char PROGMEM str_range[] = "range";
828 const char PROGMEM str_range_tokens[] = "show#start#end";
830 const parse_token_string_t PROGMEM cmd_range_range =
831 TOKEN_STRING_INITIALIZER(struct cmd_range_result, range,
833 const parse_token_string_t PROGMEM cmd_range_action =
834 TOKEN_STRING_INITIALIZER(struct cmd_range_result, action,
837 const char PROGMEM help_range[] = "start/stop/show current rangeing";
839 const parse_inst_t PROGMEM cmd_range = {
840 .f = cmd_range_parsed, /* function to call */
841 .data = NULL, /* 2nd arg of func */
842 .help_str = help_range,
843 .tokens = { /* token list, NULL terminated */
844 (PGM_P)&cmd_range_range,
845 (PGM_P)&cmd_range_action,
852 /* this structure is filled when cmd_range_period is parsed successfully */
853 struct cmd_range_period_result {
854 fixed_string_t range;
855 fixed_string_t action;
859 /* function called when cmd_range_period is parsed successfully */
860 static void cmd_range_period_parsed(void *parsed_result, void *data)
862 struct cmd_range_period_result *res = parsed_result;
865 if (res->period < 10) {
866 printf_P(PSTR("error, minimum period is 10 ms\r\n"));
870 range_period_ms = res->period;
873 const char PROGMEM str_period[] = "period";
875 const parse_token_string_t PROGMEM cmd_range_period_range_period =
876 TOKEN_STRING_INITIALIZER(struct cmd_range_period_result, range,
878 const parse_token_string_t PROGMEM cmd_range_period_action =
879 TOKEN_STRING_INITIALIZER(struct cmd_range_period_result, action,
881 const parse_token_num_t PROGMEM cmd_range_period_period =
882 TOKEN_NUM_INITIALIZER(struct cmd_range_period_result, period, UINT32);
884 const char PROGMEM help_range_period[] = "set range test period";
886 const parse_inst_t PROGMEM cmd_range_period = {
887 .f = cmd_range_period_parsed, /* function to call */
888 .data = NULL, /* 2nd arg of func */
889 .help_str = help_range_period,
890 .tokens = { /* token list, NULL terminated */
891 (PGM_P)&cmd_range_period_range_period,
892 (PGM_P)&cmd_range_period_action,
893 (PGM_P)&cmd_range_period_period,
900 /* this structure is filled when cmd_range_count is parsed successfully */
901 struct cmd_range_count_result {
902 fixed_string_t range;
903 fixed_string_t action;
907 /* function called when cmd_range_count is parsed successfully */
908 static void cmd_range_count_parsed(void *parsed_result, void *data)
910 struct cmd_range_count_result *res = parsed_result;
913 range_count = res->count;
916 const char PROGMEM str_count[] = "count";
918 const parse_token_string_t PROGMEM cmd_range_count_range_count =
919 TOKEN_STRING_INITIALIZER(struct cmd_range_count_result, range,
921 const parse_token_string_t PROGMEM cmd_range_count_action =
922 TOKEN_STRING_INITIALIZER(struct cmd_range_count_result, action,
924 const parse_token_num_t PROGMEM cmd_range_count_count =
925 TOKEN_NUM_INITIALIZER(struct cmd_range_count_result, count, UINT32);
928 const char PROGMEM help_range_count[] = "set range test count";
930 const parse_inst_t PROGMEM cmd_range_count = {
931 .f = cmd_range_count_parsed, /* function to call */
932 .data = NULL, /* 2nd arg of func */
933 .help_str = help_range_count,
934 .tokens = { /* token list, NULL terminated */
935 (PGM_P)&cmd_range_count_range_count,
936 (PGM_P)&cmd_range_count_action,
937 (PGM_P)&cmd_range_count_count,
944 /* this structure is filled when cmd_range_powermask is parsed successfully */
945 struct cmd_range_powermask_result {
946 fixed_string_t range;
947 fixed_string_t action;
951 /* function called when cmd_range_powermask is parsed successfully */
952 static void cmd_range_powermask_parsed(void *parsed_result, void *data)
954 struct cmd_range_powermask_result *res = parsed_result;
957 range_powermask = res->powermask;
960 const char PROGMEM str_powermask[] = "powermask";
962 const parse_token_string_t PROGMEM cmd_range_powermask_range_powermask =
963 TOKEN_STRING_INITIALIZER(struct cmd_range_powermask_result, range,
965 const parse_token_string_t PROGMEM cmd_range_powermask_action =
966 TOKEN_STRING_INITIALIZER(struct cmd_range_powermask_result, action,
968 const parse_token_num_t PROGMEM cmd_range_powermask_powermask =
969 TOKEN_NUM_INITIALIZER(struct cmd_range_powermask_result, powermask,
973 const char PROGMEM help_range_powermask[] = "set range test powermask";
975 const parse_inst_t PROGMEM cmd_range_powermask = {
976 .f = cmd_range_powermask_parsed, /* function to call */
977 .data = NULL, /* 2nd arg of func */
978 .help_str = help_range_powermask,
979 .tokens = { /* token list, NULL terminated */
980 (PGM_P)&cmd_range_powermask_range_powermask,
981 (PGM_P)&cmd_range_powermask_action,
982 (PGM_P)&cmd_range_powermask_powermask,
989 /* this structure is filled when cmd_range_dstaddr is parsed successfully */
990 struct cmd_range_dstaddr_result {
991 fixed_string_t range;
992 fixed_string_t action;
996 /* function called when cmd_range_dstaddr is parsed successfully */
997 static void cmd_range_dstaddr_parsed(void *parsed_result, void *data)
999 struct cmd_range_dstaddr_result *res = parsed_result;
1002 range_dstaddr = res->dstaddr;
1005 const char PROGMEM str_dstaddr[] = "dstaddr";
1007 const parse_token_string_t PROGMEM cmd_range_dstaddr_range_dstaddr =
1008 TOKEN_STRING_INITIALIZER(struct cmd_range_dstaddr_result, range,
1010 const parse_token_string_t PROGMEM cmd_range_dstaddr_action =
1011 TOKEN_STRING_INITIALIZER(struct cmd_range_dstaddr_result, action,
1013 const parse_token_num_t PROGMEM cmd_range_dstaddr_dstaddr =
1014 TOKEN_NUM_INITIALIZER(struct cmd_range_dstaddr_result, dstaddr, UINT64);
1017 const char PROGMEM help_range_dstaddr[] = "set register rangeing dstaddr";
1019 const parse_inst_t PROGMEM cmd_range_dstaddr = {
1020 .f = cmd_range_dstaddr_parsed, /* function to call */
1021 .data = NULL, /* 2nd arg of func */
1022 .help_str = help_range_dstaddr,
1023 .tokens = { /* token list, NULL terminated */
1024 (PGM_P)&cmd_range_dstaddr_range_dstaddr,
1025 (PGM_P)&cmd_range_dstaddr_action,
1026 (PGM_P)&cmd_range_dstaddr_dstaddr,
1034 /* this structure is filled when cmd_monitor is parsed successfully */
1035 struct cmd_monitor_result {
1036 fixed_string_t monitor;
1037 fixed_string_t action;
1040 /* function called when cmd_monitor is parsed successfully */
1041 static void cmd_monitor_parsed(void *parsed_result, void *data)
1043 struct cmd_monitor_result *res = parsed_result;
1044 struct monitor_reg *m;
1047 if (!strcmp_P(res->action, PSTR("show"))) {
1048 printf_P(PSTR("monitor period is %d ms, %d regs in list\r\n"),
1049 monitor_period_ms, monitor_count);
1050 LIST_FOREACH(m, &xbee_monitor_list, next)
1051 printf_P(PSTR(" %S\r\n"), m->desc);
1053 else if (!strcmp_P(res->action, PSTR("start"))) {
1054 if (monitor_running) {
1055 printf_P(PSTR("already running\r\n"));
1058 if (monitor_count == 0) {
1059 printf_P(PSTR("no regs to be monitored\r\n"));
1062 callout_init(&monitor_event, monitor_cb, NULL, 1);
1063 monitor_running = 1;
1064 monitor_current = LIST_FIRST(&xbee_monitor_list);
1065 callout_schedule(&xbeeboard.intr_cm,
1066 &monitor_event, 0); /* immediate */
1067 printf_P(PSTR("monitor cb: %S %s\r\n"),
1068 monitor_current->desc,
1069 monitor_current->atcmd);
1072 else if (!strcmp_P(res->action, PSTR("end"))) {
1073 if (monitor_running == 0) {
1074 printf_P(PSTR("not running\r\n"));
1077 callout_stop(&xbeeboard.intr_cm, &monitor_event);
1078 monitor_running = 0;
1082 const char PROGMEM str_monitor[] = "monitor";
1083 const char PROGMEM str_monitor_tokens[] = "show#start#end";
1085 const parse_token_string_t PROGMEM cmd_monitor_monitor =
1086 TOKEN_STRING_INITIALIZER(struct cmd_monitor_result, monitor,
1088 const parse_token_string_t PROGMEM cmd_monitor_action =
1089 TOKEN_STRING_INITIALIZER(struct cmd_monitor_result, action,
1090 str_monitor_tokens);
1092 const char PROGMEM help_monitor[] = "start/stop/show current monitoring";
1094 const parse_inst_t PROGMEM cmd_monitor = {
1095 .f = cmd_monitor_parsed, /* function to call */
1096 .data = NULL, /* 2nd arg of func */
1097 .help_str = help_monitor,
1098 .tokens = { /* token list, NULL terminated */
1099 (PGM_P)&cmd_monitor_monitor,
1100 (PGM_P)&cmd_monitor_action,
1107 /* this structure is filled when cmd_monitor_add is parsed successfully */
1108 struct cmd_monitor_add_result {
1109 fixed_string_t monitor;
1110 fixed_string_t action;
1111 struct xbee_atcmd *cmd;
1114 /* function called when cmd_monitor_add is parsed successfully */
1115 static void cmd_monitor_add_parsed(void *parsed_result, void *data)
1117 struct cmd_monitor_add_result *res = parsed_result;
1118 struct monitor_reg *m;
1119 struct xbee_atcmd copy;
1122 memcpy_P(©, res->cmd, sizeof(copy));
1123 LIST_FOREACH(m, &xbee_monitor_list, next) {
1124 if (!strcmp_P(m->atcmd, copy.name))
1129 printf_P(PSTR("already exist\r\n"));
1133 m = malloc(sizeof(*m));
1135 printf_P(PSTR("no mem\r\n"));
1138 m->desc = copy.desc;
1139 strcpy_P(m->atcmd, copy.name);
1140 LIST_INSERT_HEAD(&xbee_monitor_list, m, next);
1144 const char PROGMEM str_monitor_add[] = "add";
1146 const parse_token_string_t PROGMEM cmd_monitor_add_monitor_add =
1147 TOKEN_STRING_INITIALIZER(struct cmd_monitor_add_result, monitor,
1149 const parse_token_string_t PROGMEM cmd_monitor_add_action =
1150 TOKEN_STRING_INITIALIZER(struct cmd_monitor_add_result, action,
1152 const parse_token_atcmd_t PROGMEM cmd_monitor_add_atcmd =
1153 TOKEN_ATCMD_INITIALIZER(struct cmd_monitor_add_result, cmd, &xbee_dev,
1154 XBEE_ATCMD_F_READ, XBEE_ATCMD_F_READ);
1157 const char PROGMEM help_monitor_add[] = "add a register in monitor list";
1159 const parse_inst_t PROGMEM cmd_monitor_add = {
1160 .f = cmd_monitor_add_parsed, /* function to call */
1161 .data = NULL, /* 2nd arg of func */
1162 .help_str = help_monitor_add,
1163 .tokens = { /* token list, NULL terminated */
1164 (PGM_P)&cmd_monitor_add_monitor_add,
1165 (PGM_P)&cmd_monitor_add_action,
1166 (PGM_P)&cmd_monitor_add_atcmd,
1173 /* this structure is filled when cmd_monitor_period is parsed successfully */
1174 struct cmd_monitor_period_result {
1175 fixed_string_t monitor;
1176 fixed_string_t action;
1180 /* function called when cmd_monitor_period is parsed successfully */
1181 static void cmd_monitor_period_parsed(void *parsed_result, void *data)
1183 struct cmd_monitor_period_result *res = parsed_result;
1186 if (res->period < 100) {
1187 printf_P(PSTR("error, minimum period is 100 ms\r\n"));
1191 monitor_period_ms = res->period;
1194 const char PROGMEM str_monitor_period[] = "period";
1196 const parse_token_string_t PROGMEM cmd_monitor_period_monitor_period =
1197 TOKEN_STRING_INITIALIZER(struct cmd_monitor_period_result, monitor,
1199 const parse_token_string_t PROGMEM cmd_monitor_period_action =
1200 TOKEN_STRING_INITIALIZER(struct cmd_monitor_period_result, action,
1201 str_monitor_period);
1202 const parse_token_num_t PROGMEM cmd_monitor_period_period =
1203 TOKEN_NUM_INITIALIZER(struct cmd_monitor_period_result, period, UINT32);
1206 const char PROGMEM help_monitor_period[] = "set register monitoring period";
1208 const parse_inst_t PROGMEM cmd_monitor_period = {
1209 .f = cmd_monitor_period_parsed, /* function to call */
1210 .data = NULL, /* 2nd arg of func */
1211 .help_str = help_monitor_period,
1212 .tokens = { /* token list, NULL terminated */
1213 (PGM_P)&cmd_monitor_period_monitor_period,
1214 (PGM_P)&cmd_monitor_period_action,
1215 (PGM_P)&cmd_monitor_period_period,
1222 /* this structure is filled when cmd_monitor_del is parsed successfully */
1223 struct cmd_monitor_del_result {
1224 fixed_string_t monitor;
1225 fixed_string_t action;
1226 struct monitor_reg *m;
1229 /* function called when cmd_monitor_del is parsed successfully */
1230 static void cmd_monitor_del_parsed(void *parsed_result, void *data)
1232 struct cmd_monitor_del_result *res = parsed_result;
1235 monitor_current = LIST_NEXT(res->m, next);
1236 LIST_REMOVE(res->m, next);
1239 if (monitor_count == 0) {
1240 printf_P(PSTR("Disable monitoring, no more event\r\n"));
1241 callout_stop(&xbeeboard.intr_cm, &monitor_event);
1242 monitor_running = 0;
1247 const char PROGMEM str_monitor_del[] = "del";
1249 const parse_token_string_t PROGMEM cmd_monitor_del_monitor_del =
1250 TOKEN_STRING_INITIALIZER(struct cmd_monitor_del_result, monitor,
1252 const parse_token_string_t PROGMEM cmd_monitor_del_action =
1253 TOKEN_STRING_INITIALIZER(struct cmd_monitor_del_result, action,
1255 const parse_token_monitor_t PROGMEM cmd_monitor_del_atcmd =
1256 TOKEN_MONITOR_INITIALIZER(struct cmd_monitor_del_result, m);
1259 const char PROGMEM help_monitor_del[] = "del a register in monitor list";
1261 const parse_inst_t PROGMEM cmd_monitor_del = {
1262 .f = cmd_monitor_del_parsed, /* function to call */
1263 .data = NULL, /* 2nd arg of func */
1264 .help_str = help_monitor_del,
1265 .tokens = { /* token list, NULL terminated */
1266 (PGM_P)&cmd_monitor_del_monitor_del,
1267 (PGM_P)&cmd_monitor_del_action,
1268 (PGM_P)&cmd_monitor_del_atcmd,
1276 /* this structure is filled when cmd_ping is parsed successfully */
1277 struct cmd_ping_result {
1278 fixed_string_t ping;
1281 /* function called when cmd_ping is parsed successfully */
1282 static void cmd_ping_parsed(void *parsed_result, void *data)
1284 volatile uint8_t done = 0;
1286 (void)parsed_result;
1288 xbeeapp_send_atcmd("VL", NULL, 0, dump_xbee_atresp_cb, (void *)&done);
1292 const char PROGMEM str_ping[] = "ping";
1294 const parse_token_string_t PROGMEM cmd_ping_ping =
1295 TOKEN_STRING_INITIALIZER(struct cmd_ping_result, ping,
1298 const char PROGMEM help_ping[] = "Send a ping to the xbee device";
1300 const parse_inst_t PROGMEM cmd_ping = {
1301 .f = cmd_ping_parsed, /* function to call */
1302 .data = NULL, /* 2nd arg of func */
1303 .help_str = help_ping,
1304 .tokens = { /* token list, NULL terminated */
1305 (PGM_P)&cmd_ping_ping,
1312 /* this structure is filled when cmd_raw is parsed successfully */
1313 struct cmd_raw_result {
1317 /* function called when cmd_raw is parsed successfully */
1318 static void cmd_raw_parsed(void *parsed_result, void *data)
1320 (void)parsed_result;
1323 if (range_running || monitor_running) {
1324 printf_P(PSTR("stop running range or monitor first\r\n"));
1327 printf_P(PSTR("switched to raw mode, CTRL-D to exit\r\n"));
1328 rdline_stop(&xbeeboard.rdl); /* don't display prompt when return */
1332 const char PROGMEM str_raw[] = "raw";
1334 const parse_token_string_t PROGMEM cmd_raw_raw =
1335 TOKEN_STRING_INITIALIZER(struct cmd_raw_result, raw,
1338 const char PROGMEM help_raw[] = "Switch to raw mode";
1340 const parse_inst_t PROGMEM cmd_raw = {
1341 .f = cmd_raw_parsed, /* function to call */
1342 .data = NULL, /* 2nd arg of func */
1343 .help_str = help_raw,
1344 .tokens = { /* token list, NULL terminated */
1345 (PGM_P)&cmd_raw_raw,
1350 /**********************************************************/
1352 /* this structure is filled when cmd_baudrate is parsed successfully */
1353 struct cmd_baudrate_result {
1354 fixed_string_t arg0;
1358 /* function called when cmd_baudrate is parsed successfully */
1359 static void cmd_baudrate_parsed(void * parsed_result, __attribute__((unused)) void *data)
1361 struct cmd_baudrate_result *res = parsed_result;
1362 struct uart_config c;
1364 uart_getconf(XBEE_UART, &c);
1365 c.baudrate = res->arg1;
1366 uart_setconf(XBEE_UART, &c);
1369 const char PROGMEM str_baudrate_arg0[] = "baudrate";
1370 const parse_token_string_t PROGMEM cmd_baudrate_arg0 =
1371 TOKEN_STRING_INITIALIZER(struct cmd_baudrate_result, arg0,
1373 const parse_token_num_t PROGMEM cmd_baudrate_arg1 =
1374 TOKEN_NUM_INITIALIZER(struct cmd_baudrate_result, arg1,
1377 const char PROGMEM help_baudrate[] = "Change xbee baudrate";
1378 const parse_inst_t PROGMEM cmd_baudrate = {
1379 .f = cmd_baudrate_parsed, /* function to call */
1380 .data = NULL, /* 2nd arg of func */
1381 .help_str = help_baudrate,
1382 .tokens = { /* token list, NULL terminated */
1383 (PGM_P)&cmd_baudrate_arg0,
1384 (PGM_P)&cmd_baudrate_arg1,
1390 /**********************************************************/
1392 /* this structure is filled when cmd_beep is parsed successfully */
1393 struct cmd_beep_result {
1394 fixed_string_t beep;
1397 /* function called when cmd_beep is parsed successfully */
1398 static void cmd_beep_parsed(void *parsed_result, void *data)
1400 (void)parsed_result;
1411 const char PROGMEM str_beep[] = "beep";
1412 const parse_token_string_t PROGMEM cmd_beep_beep =
1413 TOKEN_STRING_INITIALIZER(struct cmd_beep_result, beep,
1416 const char PROGMEM help_beep[] = "Send a beep";
1418 const parse_inst_t PROGMEM cmd_beep = {
1419 .f = cmd_beep_parsed, /* function to call */
1420 .data = NULL, /* 2nd arg of func */
1421 .help_str = help_beep,
1422 .tokens = { /* token list, NULL terminated */
1423 (PGM_P)&cmd_beep_beep,
1428 /**********************************************************/
1430 /* this structure is filled when cmd_servo is parsed successfully */
1431 struct cmd_servo_result {
1432 fixed_string_t arg0;
1433 fixed_string_t arg1;
1438 /* function called when cmd_servo is parsed successfully */
1439 static void cmd_servo_parsed(void * parsed_result, void *data)
1441 struct cmd_servo_result *res = parsed_result;
1445 if (!strcmp_P(res->arg1, PSTR("set"))) {
1446 if (res->num >= N_SERVO) {
1447 printf_P(PSTR("bad servo num\n"));
1450 if (res->val >= 1024) {
1451 printf_P(PSTR("bad servo val\n"));
1454 spi_servo_set(res->num, res->val);
1456 else if (!strcmp_P(res->arg1, PSTR("bypass"))) {
1457 spi_servo_set_bypass(!!res->val);
1459 else if (!strcmp_P(res->arg1, PSTR("ppm"))) {
1460 spi_servo_set_ppm(!!res->val);
1462 else if (!strcmp_P(res->arg1, PSTR("show"))) {
1467 const char PROGMEM str_servo_arg0[] = "servo";
1468 const parse_token_string_t PROGMEM cmd_servo_arg0 =
1469 TOKEN_STRING_INITIALIZER(struct cmd_servo_result, arg0,
1471 const char PROGMEM str_servo_arg1_set[] = "set";
1472 const parse_token_string_t PROGMEM cmd_servo_arg1_set =
1473 TOKEN_STRING_INITIALIZER(struct cmd_servo_result, arg1,
1474 str_servo_arg1_set);
1475 const parse_token_num_t PROGMEM cmd_servo_num =
1476 TOKEN_NUM_INITIALIZER(struct cmd_servo_result, num,
1478 const parse_token_num_t PROGMEM cmd_servo_val =
1479 TOKEN_NUM_INITIALIZER(struct cmd_servo_result, val,
1482 const char PROGMEM help_servo_set[] = "set servo value";
1483 const parse_inst_t PROGMEM cmd_servo_set = {
1484 .f = cmd_servo_parsed, /* function to call */
1485 .data = NULL, /* 2nd arg of func */
1486 .help_str = help_servo_set,
1487 .tokens = { /* token list, NULL terminated */
1488 (PGM_P)&cmd_servo_arg0,
1489 (PGM_P)&cmd_servo_arg1_set,
1490 (PGM_P)&cmd_servo_num,
1491 (PGM_P)&cmd_servo_val,
1496 const char PROGMEM str_servo_arg1_show[] = "show";
1497 const parse_token_string_t PROGMEM cmd_servo_arg1_show =
1498 TOKEN_STRING_INITIALIZER(struct cmd_servo_result, arg1,
1499 str_servo_arg1_show);
1501 const char PROGMEM help_servo_show[] = "read servo and config";
1502 const parse_inst_t PROGMEM cmd_servo_show = {
1503 .f = cmd_servo_parsed, /* function to call */
1504 .data = NULL, /* 2nd arg of func */
1505 .help_str = help_servo_show,
1506 .tokens = { /* token list, NULL terminated */
1507 (PGM_P)&cmd_servo_arg0,
1508 (PGM_P)&cmd_servo_arg1_show,
1513 const char PROGMEM str_servo_arg1_bypassppm[] = "bypass#ppm";
1514 const parse_token_string_t PROGMEM cmd_servo_arg1_bypassppm =
1515 TOKEN_STRING_INITIALIZER(struct cmd_servo_result, arg1,
1516 str_servo_arg1_bypassppm);
1518 const char PROGMEM help_servo_bypassppm[] = "change bypass/ppm";
1519 const parse_inst_t PROGMEM cmd_servo_bypassppm = {
1520 .f = cmd_servo_parsed, /* function to call */
1521 .data = NULL, /* 2nd arg of func */
1522 .help_str = help_servo_bypassppm,
1523 .tokens = { /* token list, NULL terminated */
1524 (PGM_P)&cmd_servo_arg0,
1525 (PGM_P)&cmd_servo_arg1_bypassppm,
1526 (PGM_P)&cmd_servo_val,
1531 /**********************************************************/
1533 /* this structure is filled when cmd_test_spi is parsed successfully */
1534 struct cmd_test_spi_result {
1535 fixed_string_t arg0;
1538 static void cmd_test_spi_parsed(void * parsed_result, void *data)
1540 uint8_t i, flags, wait_time = 0;
1543 (void)parsed_result;
1546 spi_servo_set_bypass(0);
1547 spi_servo_set_ppm(0);
1549 /* stress test: send many commands, no wait between each servo
1550 * of a series, and a variable delay between series */
1551 printf_P(PSTR("stress test\r\n"));
1552 while (!cmdline_keypressed()) {
1564 for (i = 0; i < 6; i++)
1565 spi_servo_set(i, val);
1568 printf_P(PSTR("%4.4d %4.4d %4.4d %4.4d %4.4d %4.4d\r\n"),
1569 spi_servo_get(0), spi_servo_get(1), spi_servo_get(2),
1570 spi_servo_get(3), spi_servo_get(4), spi_servo_get(5));
1573 printf_P(PSTR("bypass mode, with spi commands in background\r\n"));
1574 spi_servo_set_bypass(1);
1576 /* test bypass mode */
1577 while (!cmdline_keypressed()) {
1589 for (i = 0; i < 6; i++)
1590 spi_servo_set(i, val);
1593 printf_P(PSTR("%4.4d %4.4d %4.4d %4.4d %4.4d %4.4d\r\n"),
1594 spi_servo_get(0), spi_servo_get(1), spi_servo_get(2),
1595 spi_servo_get(3), spi_servo_get(4), spi_servo_get(5));
1598 printf_P(PSTR("PPM to servo\r\n"));
1599 spi_servo_set_bypass(0);
1600 spi_servo_set_ppm(0);
1602 /* test PPM to servo (bypass) mode */
1603 while (!cmdline_keypressed()) {
1604 for (i = 0; i < 6; i++) {
1605 val = spi_servo_get(i);
1606 spi_servo_set(i, val);
1610 printf_P(PSTR("PPM to (servo + PPM)\r\n"));
1611 spi_servo_set_bypass(0);
1612 spi_servo_set_ppm(1);
1614 /* test PPM to servo (bypass) mode */
1615 while (!cmdline_keypressed()) {
1616 for (i = 0; i < 6; i++) {
1617 val = spi_servo_get(i);
1618 spi_servo_set(i, val);
1623 const char PROGMEM str_test_spi_arg0[] = "test_spi";
1624 const parse_token_string_t PROGMEM cmd_test_spi_arg0 =
1625 TOKEN_STRING_INITIALIZER(struct cmd_test_spi_result, arg0,
1628 const char PROGMEM help_test_spi[] = "Test the spi";
1629 const parse_inst_t PROGMEM cmd_test_spi = {
1630 .f = cmd_test_spi_parsed, /* function to call */
1631 .data = NULL, /* 2nd arg of func */
1632 .help_str = help_test_spi,
1633 .tokens = { /* token list, NULL terminated */
1634 (PGM_P)&cmd_test_spi_arg0,
1639 /**********************************************************/
1641 /* this structure is filled when cmd_dump_xbee_stats is parsed successfully */
1642 struct cmd_dump_xbee_stats_result {
1643 fixed_string_t arg0;
1646 static void cmd_dump_xbee_stats_parsed(void *parsed_result, void *data)
1648 (void)parsed_result;
1651 xbee_dump_stats(xbee_dev);
1654 const char PROGMEM str_dump_xbee_stats_arg0[] = "dump_xbee_stats";
1655 const parse_token_string_t PROGMEM cmd_dump_xbee_stats_arg0 =
1656 TOKEN_STRING_INITIALIZER(struct cmd_dump_xbee_stats_result, arg0,
1657 str_dump_xbee_stats_arg0);
1659 const char PROGMEM help_dump_xbee_stats[] = "Test the spi";
1660 const parse_inst_t PROGMEM cmd_dump_xbee_stats = {
1661 .f = cmd_dump_xbee_stats_parsed, /* function to call */
1662 .data = NULL, /* 2nd arg of func */
1663 .help_str = help_dump_xbee_stats,
1664 .tokens = { /* token list, NULL terminated */
1665 (PGM_P)&cmd_dump_xbee_stats_arg0,
1670 /**********************************************************/
1672 /* this structure is filled when cmd_test_eeprom_config is parsed successfully */
1673 struct cmd_test_eeprom_config_result {
1674 fixed_string_t arg0;
1677 static void cmd_test_eeprom_config_parsed(void *parsed_result, void *data)
1679 (void)parsed_result;
1683 eeprom_append_cmd("salut1\n");
1685 eeprom_append_cmd("salut2\n");
1686 eeprom_append_cmd("salut3\n");
1687 eeprom_append_cmd("salut4\n");
1689 eeprom_insert_cmd_before("coin\n", 0);
1690 eeprom_insert_cmd_before("coin2\n", 2);
1692 eeprom_delete_cmd(2);
1693 eeprom_delete_cmd(0);
1697 const char PROGMEM str_test_eeprom_config_arg0[] = "test_eeprom_config";
1698 const parse_token_string_t PROGMEM cmd_test_eeprom_config_arg0 =
1699 TOKEN_STRING_INITIALIZER(struct cmd_test_eeprom_config_result, arg0,
1700 str_test_eeprom_config_arg0);
1702 const char PROGMEM help_test_eeprom_config[] = "Test the eeprom configuration";
1703 const parse_inst_t PROGMEM cmd_test_eeprom_config = {
1704 .f = cmd_test_eeprom_config_parsed, /* function to call */
1705 .data = NULL, /* 2nd arg of func */
1706 .help_str = help_test_eeprom_config,
1707 .tokens = { /* token list, NULL terminated */
1708 (PGM_P)&cmd_test_eeprom_config_arg0,
1715 struct cmd_eeprom_del_result {
1717 fixed_string_t action;
1721 static void cmd_eeprom_del_parsed(void *parsed_result,
1724 struct cmd_eeprom_del_result *res = parsed_result;
1727 if (eeprom_delete_cmd(res->n) < 0)
1728 printf_P(PSTR("cannot delete command\n"));
1732 const char PROGMEM str_eeprom_del_eeprom[] = "eeprom";
1733 const parse_token_string_t PROGMEM cmd_eeprom_del_cmd =
1734 TOKEN_STRING_INITIALIZER(struct cmd_eeprom_del_result, cmd,
1735 str_eeprom_del_eeprom);
1736 const char PROGMEM str_eeprom_del_del[] = "del";
1737 const parse_token_string_t PROGMEM cmd_eeprom_del_action =
1738 TOKEN_STRING_INITIALIZER(struct cmd_eeprom_del_result, action,
1739 str_eeprom_del_del);
1740 const parse_token_num_t PROGMEM cmd_eeprom_del_num =
1741 TOKEN_NUM_INITIALIZER(struct cmd_eeprom_del_result, n,
1744 const char PROGMEM help_eeprom_del[] = "delete an eeprom init command";
1745 const parse_inst_t PROGMEM cmd_eeprom_del = {
1746 .f = cmd_eeprom_del_parsed, /* function to call */
1747 .data = NULL, /* 2nd arg of func */
1748 .help_str = help_eeprom_del,
1749 .tokens = { /* token list, NULL terminated */
1750 (PGM_P)&cmd_eeprom_del_cmd,
1751 (PGM_P)&cmd_eeprom_del_action,
1752 (PGM_P)&cmd_eeprom_del_num,
1759 struct cmd_eeprom_add_result {
1761 fixed_string_t action;
1765 static void cmd_eeprom_add_parsed(void *parsed_result,
1768 struct cmd_eeprom_add_result *res = parsed_result;
1774 rdline_init(&rdl, cmdline_write_char, NULL, NULL);
1775 rdline_newline(&rdl, "> ");
1777 /* XXX bad: we should not block as we do not serve callout */
1779 c = cmdline_dev_recv(NULL);
1783 ret = rdline_char_in(&rdl, c);
1785 printf_P(PSTR("abort\n"));
1792 buffer = rdline_get_buffer(&rdl);
1794 eeprom_insert_cmd_before(buffer, res->n);
1796 eeprom_append_cmd(buffer);
1800 const char PROGMEM str_eeprom_add_eeprom[] = "eeprom";
1801 const parse_token_string_t PROGMEM cmd_eeprom_add_cmd =
1802 TOKEN_STRING_INITIALIZER(struct cmd_eeprom_add_result, cmd,
1803 str_eeprom_add_eeprom);
1804 const char PROGMEM str_eeprom_add_add[] = "add";
1805 const parse_token_string_t PROGMEM cmd_eeprom_add_action =
1806 TOKEN_STRING_INITIALIZER(struct cmd_eeprom_add_result, action,
1807 str_eeprom_add_add);
1808 const parse_token_num_t PROGMEM cmd_eeprom_add_num =
1809 TOKEN_NUM_INITIALIZER(struct cmd_eeprom_add_result, n,
1812 const char PROGMEM help_eeprom_add[] = "insert an eeprom init command";
1813 const parse_inst_t PROGMEM cmd_eeprom_add = {
1814 .f = cmd_eeprom_add_parsed, /* function to call */
1815 .data = NULL, /* 2nd arg of func */
1816 .help_str = help_eeprom_add,
1817 .tokens = { /* token list, NULL terminated */
1818 (PGM_P)&cmd_eeprom_add_cmd,
1819 (PGM_P)&cmd_eeprom_add_action,
1820 (PGM_P)&cmd_eeprom_add_num,
1825 const char PROGMEM help_eeprom_add2[] = "append an eeprom init command";
1826 const parse_inst_t PROGMEM cmd_eeprom_add2 = {
1827 .f = cmd_eeprom_add_parsed, /* function to call */
1828 .data = (void *)1, /* 2nd arg of func */
1829 .help_str = help_eeprom_add2,
1830 .tokens = { /* token list, NULL terminated */
1831 (PGM_P)&cmd_eeprom_add_cmd,
1832 (PGM_P)&cmd_eeprom_add_action,
1839 struct cmd_eeprom_list_result {
1841 fixed_string_t action;
1844 static void cmd_eeprom_list_parsed(void *parsed_result,
1847 (void)parsed_result;
1852 const char PROGMEM str_eeprom_list_eeprom[] = "eeprom";
1853 const parse_token_string_t PROGMEM cmd_eeprom_list_cmd =
1854 TOKEN_STRING_INITIALIZER(struct cmd_eeprom_list_result, cmd,
1855 str_eeprom_list_eeprom);
1856 const char PROGMEM str_eeprom_list_list[] = "list";
1857 const parse_token_string_t PROGMEM cmd_eeprom_list_action =
1858 TOKEN_STRING_INITIALIZER(struct cmd_eeprom_list_result, action,
1859 str_eeprom_list_list);
1861 const char PROGMEM help_eeprom_list[] = "list all eeprom init commands";
1862 const parse_inst_t PROGMEM cmd_eeprom_list = {
1863 .f = cmd_eeprom_list_parsed, /* function to call */
1864 .data = NULL, /* 2nd arg of func */
1865 .help_str = help_eeprom_list,
1866 .tokens = { /* token list, NULL terminated */
1867 (PGM_P)&cmd_eeprom_list_cmd,
1868 (PGM_P)&cmd_eeprom_list_action,
1877 const parse_ctx_t PROGMEM main_ctx[] = {
1879 /* commands_gen.c */
1898 &cmd_send_hello_name,
1903 &cmd_range_powermask,
1906 &cmd_monitor_period,
1914 &cmd_servo_bypassppm,
1917 &cmd_dump_xbee_stats,
1918 &cmd_test_eeprom_config,