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)
95 struct rc_proto_power_probe power_probe;
104 /* get new xmit power */
105 for (i = 1; i <= 8; i++) {
106 mask = 1 << ((range_power + i) & 0x7);
107 if (mask & range_powermask)
110 range_power = ((range_power + i) & 0x7);
112 xbeeapp_send_atcmd("PL", &range_power, sizeof(range_power), NULL, NULL);
114 power_probe.type = RC_PROTO_POWER_PROBE;
115 power_probe.power_level = range_power;
118 msg.iov[0].buf = &power_probe;
119 msg.iov[0].len = sizeof(power_probe);
121 xbeeapp_send_msg(range_dstaddr, &msg, NULL, NULL);
123 if (range_cur_count == 0) {
125 callout_stop(cm, clt);
129 callout_reschedule(cm, clt, range_period_ms);
132 /* callback invoked when a xbee_send is done */
133 static int8_t send_msg_cb(int8_t retcode, void *frame, unsigned len,
136 struct xbee_xmit_status_hdr *recvframe = frame;
140 if (retcode == XBEE_USER_RETCODE_TIMEOUT) {
141 printf_P(PSTR("timeout\r\n"));
144 if (retcode == XBEE_USER_RETCODE_BAD_FRAME ||
145 len != sizeof(*recvframe)) {
146 printf_P(PSTR("invalid frame\r\n"));
147 return XBEE_USER_RETCODE_BAD_FRAME;
150 printf_P(PSTR("ok\r\n"));
151 return XBEE_USER_RETCODE_OK;
154 /* callback invoked to dump the response to AT command */
155 static int8_t dump_xbee_atresp_cb(int8_t retcode, void *frame, unsigned len,
158 struct xbee_atresp_hdr *recvframe = frame;
164 if (retcode == XBEE_USER_RETCODE_TIMEOUT) {
165 printf_P(PSTR("timeout\r\n"));
168 if (retcode == XBEE_USER_RETCODE_BAD_FRAME ||
169 len < sizeof(*recvframe)) {
170 printf_P(PSTR("invalid frame\r\n"));
171 return XBEE_USER_RETCODE_BAD_FRAME;
174 /* get AT command from frame */
175 memcpy(atcmd_str, &recvframe->cmd, 2);
178 atresp_to_str(buf, sizeof(buf), frame, len);
179 len -= sizeof(*recvframe);
180 printf_P(PSTR("status ok, len=%d, %s\n"), len, buf);
181 return XBEE_USER_RETCODE_OK;
184 /* this structure is filled when cmd_help is parsed successfully */
185 struct cmd_help_result {
187 struct xbee_atcmd *cmd;
190 /* function called when cmd_help is parsed successfully */
191 static void cmd_help_parsed(void *parsed_result, void *data)
193 struct cmd_help_result *res = parsed_result;
194 struct xbee_atcmd cmdcopy;
199 memcpy_P(&cmdcopy, res->cmd, sizeof(cmdcopy));
200 type = (cmdcopy.flags & (XBEE_ATCMD_F_READ | XBEE_ATCMD_F_WRITE));
202 case XBEE_ATCMD_F_READ:
203 printf_P(PSTR("Read-only\r\n"));
205 case XBEE_ATCMD_F_WRITE:
206 printf_P(PSTR("Write-only\r\n"));
209 printf_P(PSTR("Read-write\r\n"));
212 if (cmdcopy.flags & XBEE_ATCMD_F_PARAM_NONE)
213 printf_P(PSTR("No argument\r\n"));
214 else if (cmdcopy.flags & XBEE_ATCMD_F_PARAM_U8)
215 printf_P(PSTR("Register is unsigned 8 bits\r\n"));
216 else if (cmdcopy.flags & XBEE_ATCMD_F_PARAM_U16)
217 printf_P(PSTR("Register is unsigned 16 bits\r\n"));
218 else if (cmdcopy.flags & XBEE_ATCMD_F_PARAM_U32)
219 printf_P(PSTR("Register is unsigned 32 bits\r\n"));
220 else if (cmdcopy.flags & XBEE_ATCMD_F_PARAM_S16)
221 printf_P(PSTR("Register is signed 16 bits\r\n"));
222 else if (cmdcopy.flags & XBEE_ATCMD_F_PARAM_STRING_20B)
223 printf_P(PSTR("Register is a 20 bytes string\r\n"));
225 printf_P(PSTR("Unknown argument\r\n"));
227 printf_P(PSTR("%S\r\n"), cmdcopy.help);
229 const char PROGMEM str_help_help[] = "help";
231 const parse_token_string_t PROGMEM cmd_help_help =
232 TOKEN_STRING_INITIALIZER(struct cmd_help_result, help, str_help_help);
234 const parse_token_atcmd_t PROGMEM cmd_help_atcmd =
235 TOKEN_ATCMD_INITIALIZER(struct cmd_help_result, cmd, &xbee_dev,
238 const char PROGMEM help_help[] = "Help a register using an AT command";
239 const parse_inst_t PROGMEM cmd_help = {
240 .f = cmd_help_parsed, /* function to call */
241 .data = NULL, /* 2nd arg of func */
242 .help_str = help_help,
243 .tokens = { /* token list, NULL terminated */
244 (PGM_P)&cmd_help_help,
245 (PGM_P)&cmd_help_atcmd,
252 struct cmd_neigh_del_result {
254 fixed_string_t action;
255 struct xbee_neigh *neigh;
258 static void cmd_neigh_del_parsed(void *parsed_result,
261 struct cmd_neigh_del_result *res = parsed_result;
264 xbee_neigh_del(xbee_dev, res->neigh);
267 const char PROGMEM str_neigh_del_neigh[] = "neigh";
268 const parse_token_string_t PROGMEM cmd_neigh_del_cmd =
269 TOKEN_STRING_INITIALIZER(struct cmd_neigh_del_result, cmd,
270 str_neigh_del_neigh);
271 const char PROGMEM str_neigh_del_del[] = "del";
272 const parse_token_string_t PROGMEM cmd_neigh_del_action =
273 TOKEN_STRING_INITIALIZER(struct cmd_neigh_del_result, action,
275 const parse_token_neighbor_t PROGMEM cmd_neigh_del_neigh =
276 TOKEN_NEIGHBOR_INITIALIZER(struct cmd_neigh_del_result, neigh,
279 const char PROGMEM help_neigh_del[] = "delete a neighbor";
280 const parse_inst_t PROGMEM cmd_neigh_del = {
281 .f = cmd_neigh_del_parsed, /* function to call */
282 .data = NULL, /* 2nd arg of func */
283 .help_str = help_neigh_del,
284 .tokens = { /* token list, NULL terminated */
285 (PGM_P)&cmd_neigh_del_cmd,
286 (PGM_P)&cmd_neigh_del_action,
287 (PGM_P)&cmd_neigh_del_neigh,
294 struct cmd_neigh_add_result {
296 fixed_string_t action;
301 static void cmd_neigh_add_parsed(void *parsed_result,
304 struct cmd_neigh_add_result *res = parsed_result;
307 if (xbee_neigh_add(xbee_dev, res->name, res->addr) == NULL)
308 printf_P(PSTR("name or addr already exist\r\n"));
311 const char PROGMEM str_neigh_add_neigh[] = "neigh";
312 const parse_token_string_t PROGMEM cmd_neigh_add_cmd =
313 TOKEN_STRING_INITIALIZER(struct cmd_neigh_add_result, cmd,
314 str_neigh_add_neigh);
315 const char PROGMEM str_neigh_add_add[] = "add";
316 const parse_token_string_t PROGMEM cmd_neigh_add_action =
317 TOKEN_STRING_INITIALIZER(struct cmd_neigh_add_result, action,
319 const parse_token_string_t PROGMEM cmd_neigh_add_name =
320 TOKEN_STRING_INITIALIZER(struct cmd_neigh_add_result, name, NULL);
321 const parse_token_num_t PROGMEM cmd_neigh_add_addr =
322 TOKEN_NUM_INITIALIZER(struct cmd_neigh_add_result, addr, UINT64);
324 const char PROGMEM help_neigh_add[] = "add a neighbor";
325 const parse_inst_t PROGMEM cmd_neigh_add = {
326 .f = cmd_neigh_add_parsed, /* function to call */
327 .data = NULL, /* 2nd arg of func */
328 .help_str = help_neigh_add,
329 .tokens = { /* token list, NULL terminated */
330 (PGM_P)&cmd_neigh_add_cmd,
331 (PGM_P)&cmd_neigh_add_action,
332 (PGM_P)&cmd_neigh_add_name,
333 (PGM_P)&cmd_neigh_add_addr,
340 struct cmd_neigh_list_result {
342 fixed_string_t action;
345 static void cmd_neigh_list_parsed(void *parsed_result,
348 struct xbee_neigh *neigh;
352 LIST_FOREACH(neigh, &xbee_dev->neigh_list, next) {
353 printf_P(PSTR(" %s: 0x%.8"PRIx32"%.8"PRIx32"\r\n"),
355 (uint32_t)(neigh->addr >> 32ULL),
356 (uint32_t)(neigh->addr & 0xFFFFFFFF));
360 const char PROGMEM str_neigh_list_neigh[] = "neigh";
361 const parse_token_string_t PROGMEM cmd_neigh_list_cmd =
362 TOKEN_STRING_INITIALIZER(struct cmd_neigh_list_result, cmd,
363 str_neigh_list_neigh);
364 const char PROGMEM str_neigh_list_list[] = "list";
365 const parse_token_string_t PROGMEM cmd_neigh_list_action =
366 TOKEN_STRING_INITIALIZER(struct cmd_neigh_list_result, action,
367 str_neigh_list_list);
369 const char PROGMEM help_neigh_list[] = "list all knwon neighbors";
370 const parse_inst_t PROGMEM cmd_neigh_list = {
371 .f = cmd_neigh_list_parsed, /* function to call */
372 .data = NULL, /* 2nd arg of func */
373 .help_str = help_neigh_list,
374 .tokens = { /* token list, NULL terminated */
375 (PGM_P)&cmd_neigh_list_cmd,
376 (PGM_P)&cmd_neigh_list_action,
383 /* this structure is filled when cmd_read is parsed successfully */
384 struct cmd_read_result {
386 struct xbee_atcmd *cmd;
389 /* function called when cmd_read is parsed successfully */
390 static void cmd_read_parsed(void *parsed_result,
393 struct cmd_read_result *res = parsed_result;
394 struct xbee_atcmd copy;
396 volatile uint8_t done = 0;
399 memcpy_P(©, res->cmd, sizeof(copy));
400 memcpy_P(&cmd, copy.name, 2);
402 xbeeapp_send_atcmd(cmd, NULL, 0, dump_xbee_atresp_cb, (void *)&done);
406 const char PROGMEM str_read_read[] = "read";
408 const parse_token_string_t PROGMEM cmd_read_read =
409 TOKEN_STRING_INITIALIZER(struct cmd_read_result, read,
412 const parse_token_atcmd_t PROGMEM cmd_read_atcmd =
413 TOKEN_ATCMD_INITIALIZER(struct cmd_read_result, cmd, &xbee_dev,
414 XBEE_ATCMD_F_READ, XBEE_ATCMD_F_READ);
416 const char PROGMEM help_read[] = "Read a register using an AT command";
417 const parse_inst_t PROGMEM cmd_read = {
418 .f = cmd_read_parsed, /* function to call */
419 .data = NULL, /* 2nd arg of func */
420 .help_str = help_read,
421 .tokens = { /* token list, NULL terminated */
422 (PGM_P)&cmd_read_read,
423 (PGM_P)&cmd_read_atcmd,
431 /* this structure is filled when cmd_write is parsed successfully */
432 struct cmd_write_result {
433 fixed_string_t write;
434 struct xbee_atcmd *cmd;
442 /* function called when cmd_write is parsed successfully */
443 static void cmd_write_parsed(void *parsed_result, void *data)
445 struct cmd_write_result *res = parsed_result;
446 struct xbee_atcmd copy;
450 volatile uint8_t done = 0;
453 memcpy_P(©, res->cmd, sizeof(copy));
455 if (copy.flags & XBEE_ATCMD_F_PARAM_NONE) {
459 else if (copy.flags & XBEE_ATCMD_F_PARAM_U8) {
460 len = sizeof(res->u8);
463 else if (copy.flags & XBEE_ATCMD_F_PARAM_U16) {
464 len = sizeof(res->u16);
465 res->u16 = htons(res->u16);
468 else if (copy.flags & XBEE_ATCMD_F_PARAM_U32) {
469 len = sizeof(res->u32);
470 res->u32 = htonl(res->u32);
474 printf_P(PSTR("Unknown argument type\r\n"));
477 memcpy_P(&cmd, copy.name, 2);
479 xbeeapp_send_atcmd(cmd, param, len, dump_xbee_atresp_cb, (void *)&done);
483 const char PROGMEM str_write_none[] = "write";
485 const parse_token_string_t PROGMEM cmd_write_write =
486 TOKEN_STRING_INITIALIZER(struct cmd_write_result, write,
489 const parse_token_atcmd_t PROGMEM cmd_write_none_atcmd =
490 TOKEN_ATCMD_INITIALIZER(struct cmd_write_result, cmd,
492 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_NONE,
493 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_NONE);
495 const char PROGMEM help_write_none[] = "Send an AT command (no argument)";
497 const parse_inst_t PROGMEM cmd_write_none = {
498 .f = cmd_write_parsed, /* function to call */
499 .data = NULL, /* 2nd arg of func */
500 .help_str = help_write_none,
501 .tokens = { /* token list, NULL terminated */
502 (PGM_P)&cmd_write_write,
503 (PGM_P)&cmd_write_none_atcmd,
508 const parse_token_atcmd_t PROGMEM cmd_write_u8_atcmd =
509 TOKEN_ATCMD_INITIALIZER(struct cmd_write_result, cmd,
511 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_U8,
512 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_U8);
514 const parse_token_num_t PROGMEM cmd_write_u8_u8 =
515 TOKEN_NUM_INITIALIZER(struct cmd_write_result, u8, UINT8);
517 const char PROGMEM help_write_u8[] = "Write a 8 bits register using an AT command";
519 const parse_inst_t PROGMEM cmd_write_u8 = {
520 .f = cmd_write_parsed, /* function to call */
521 .data = NULL, /* 2nd arg of func */
522 .help_str = help_write_u8,
523 .tokens = { /* token list, NULL terminated */
524 (PGM_P)&cmd_write_write,
525 (PGM_P)&cmd_write_u8_atcmd,
526 (PGM_P)&cmd_write_u8_u8,
531 const parse_token_atcmd_t PROGMEM cmd_write_u16_atcmd =
532 TOKEN_ATCMD_INITIALIZER(struct cmd_write_result, cmd,
534 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_U16,
535 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_U16);
537 const parse_token_num_t PROGMEM cmd_write_u16_u16 =
538 TOKEN_NUM_INITIALIZER(struct cmd_write_result, u16, UINT16);
540 const char PROGMEM help_write_u16[] = "Write a 16 bits register using an AT command";
542 const parse_inst_t PROGMEM cmd_write_u16 = {
543 .f = cmd_write_parsed, /* function to call */
544 .data = NULL, /* 2nd arg of func */
545 .help_str = help_write_u16,
546 .tokens = { /* token list, NULL terminated */
547 (PGM_P)&cmd_write_write,
548 (PGM_P)&cmd_write_u16_atcmd,
549 (PGM_P)&cmd_write_u16_u16,
554 const parse_token_atcmd_t PROGMEM cmd_write_u32_atcmd =
555 TOKEN_ATCMD_INITIALIZER(struct cmd_write_result, cmd,
557 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_U32,
558 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_U32);
560 const parse_token_num_t PROGMEM cmd_write_u32_u32 =
561 TOKEN_NUM_INITIALIZER(struct cmd_write_result, u32, UINT32);
563 const char PROGMEM help_write_u32[] = "Write a 32 bits register using an AT command";
565 const parse_inst_t PROGMEM cmd_write_u32 = {
566 .f = cmd_write_parsed, /* function to call */
567 .data = NULL, /* 2nd arg of func */
568 .help_str = help_write_u32,
569 .tokens = { /* token list, NULL terminated */
570 (PGM_P)&cmd_write_write,
571 (PGM_P)&cmd_write_u32_atcmd,
572 (PGM_P)&cmd_write_u32_u32,
580 /* this structure is filled when cmd_sendmsg is parsed successfully */
581 struct cmd_sendmsg_result {
582 fixed_string_t sendmsg;
587 /* function called when cmd_sendmsg is parsed successfully */
588 static void cmd_sendmsg_parsed(void *parsed_result, void *data)
590 struct cmd_sendmsg_result *res = parsed_result;
592 volatile uint8_t done = 0;
597 msg.iov[0].buf = res->data;
598 msg.iov[0].len = strlen(res->data);
600 xbeeapp_send_msg(res->addr, &msg, send_msg_cb, (void *)&done);
604 const char PROGMEM str_sendmsg[] = "sendmsg";
606 const parse_token_string_t PROGMEM cmd_sendmsg_sendmsg =
607 TOKEN_STRING_INITIALIZER(struct cmd_sendmsg_result, sendmsg,
610 const parse_token_num_t PROGMEM cmd_sendmsg_addr =
611 TOKEN_NUM_INITIALIZER(struct cmd_sendmsg_result, addr, UINT64);
613 const parse_token_string_t PROGMEM cmd_sendmsg_data =
614 TOKEN_STRING_INITIALIZER(struct cmd_sendmsg_result, data, NULL);
616 const char PROGMEM help_sendmsg[] = "Send data to a node using its address";
618 const parse_inst_t PROGMEM cmd_sendmsg = {
619 .f = cmd_sendmsg_parsed, /* function to call */
620 .data = NULL, /* 2nd arg of func */
621 .help_str = help_sendmsg,
622 .tokens = { /* token list, NULL terminated */
623 (PGM_P)&cmd_sendmsg_sendmsg,
624 (PGM_P)&cmd_sendmsg_addr,
625 (PGM_P)&cmd_sendmsg_data,
632 /* this structure is filled when cmd_sendmsg_name is parsed successfully */
633 struct cmd_sendmsg_name_result {
634 fixed_string_t sendmsg_name;
635 struct xbee_neigh *neigh;
639 /* function called when cmd_sendmsg_name is parsed successfully */
640 static void cmd_sendmsg_name_parsed(void *parsed_result, void *data)
642 struct cmd_sendmsg_name_result *res = parsed_result;
644 volatile uint8_t done = 0;
649 msg.iov[0].buf = res->data;
650 msg.iov[0].len = strlen(res->data);
652 xbeeapp_send_msg(res->neigh->addr, &msg, send_msg_cb, (void *)&done);
656 const parse_token_string_t PROGMEM cmd_sendmsg_name_sendmsg_name =
657 TOKEN_STRING_INITIALIZER(struct cmd_sendmsg_name_result, sendmsg_name,
660 const parse_token_neighbor_t PROGMEM cmd_sendmsg_name_neigh =
661 TOKEN_NEIGHBOR_INITIALIZER(struct cmd_sendmsg_name_result, neigh,
664 const parse_token_string_t PROGMEM cmd_sendmsg_name_data =
665 TOKEN_STRING_INITIALIZER(struct cmd_sendmsg_name_result, data, NULL);
667 const char PROGMEM help_sendmsg_name[] = "Send data to a node using its name";
669 const parse_inst_t PROGMEM cmd_sendmsg_name = {
670 .f = cmd_sendmsg_name_parsed, /* function to call */
671 .data = NULL, /* 2nd arg of func */
672 .help_str = help_sendmsg_name,
673 .tokens = { /* token list, NULL terminated */
674 (PGM_P)&cmd_sendmsg_name_sendmsg_name,
675 (PGM_P)&cmd_sendmsg_name_neigh,
676 (PGM_P)&cmd_sendmsg_name_data,
684 /* this structure is filled when cmd_range is parsed successfully */
685 struct cmd_range_result {
686 fixed_string_t range;
687 fixed_string_t action;
690 /* function called when cmd_range is parsed successfully */
691 static void cmd_range_parsed(void *parsed_result, void *data)
693 struct cmd_range_result *res = parsed_result;
696 if (!strcmp_P(res->action, PSTR("show"))) {
697 printf_P(PSTR("range infos:\r\n"));
698 printf_P(PSTR(" range period %d\r\n"), range_period_ms);
699 printf_P(PSTR(" range count %d\r\n"), range_count);
700 printf_P(PSTR(" range powermask 0x%x\r\n"), range_powermask);
701 printf_P(PSTR(" range dstaddr 0x%.8"PRIx32"%.8"PRIx32"\r\n"),
702 (uint32_t)(range_dstaddr >> 32ULL),
703 (uint32_t)(range_dstaddr & 0xFFFFFFFF));
706 printf_P(PSTR(" range test is running\r\n"));
708 printf_P(PSTR(" range test is not running\r\n"));
710 else if (!strcmp(res->action, "start")) {
712 printf_P(PSTR("already running\r\n"));
715 range_cur_count = range_count;
716 callout_init(&range_event, range_cb, NULL, LOW_PRIO);
718 callout_schedule(&xbeeboard.intr_cm,
719 &range_event, 0); /* immediate */
721 else if (!strcmp(res->action, "end")) {
722 if (range_running == 0) {
723 printf_P(PSTR("not running\r\n"));
726 callout_stop(&xbeeboard.intr_cm, &range_event);
731 const char PROGMEM str_range[] = "range";
732 const char PROGMEM str_range_tokens[] = "show#start#end";
734 const parse_token_string_t PROGMEM cmd_range_range =
735 TOKEN_STRING_INITIALIZER(struct cmd_range_result, range,
737 const parse_token_string_t PROGMEM cmd_range_action =
738 TOKEN_STRING_INITIALIZER(struct cmd_range_result, action,
741 const char PROGMEM help_range[] = "start/stop/show current rangeing";
743 const parse_inst_t PROGMEM cmd_range = {
744 .f = cmd_range_parsed, /* function to call */
745 .data = NULL, /* 2nd arg of func */
746 .help_str = help_range,
747 .tokens = { /* token list, NULL terminated */
748 (PGM_P)&cmd_range_range,
749 (PGM_P)&cmd_range_action,
756 /* this structure is filled when cmd_range_period is parsed successfully */
757 struct cmd_range_period_result {
758 fixed_string_t range;
759 fixed_string_t action;
763 /* function called when cmd_range_period is parsed successfully */
764 static void cmd_range_period_parsed(void *parsed_result, void *data)
766 struct cmd_range_period_result *res = parsed_result;
769 if (res->period < 10) {
770 printf_P(PSTR("error, minimum period is 10 ms\r\n"));
774 range_period_ms = res->period;
777 const char PROGMEM str_period[] = "period";
779 const parse_token_string_t PROGMEM cmd_range_period_range_period =
780 TOKEN_STRING_INITIALIZER(struct cmd_range_period_result, range,
782 const parse_token_string_t PROGMEM cmd_range_period_action =
783 TOKEN_STRING_INITIALIZER(struct cmd_range_period_result, action,
785 const parse_token_num_t PROGMEM cmd_range_period_period =
786 TOKEN_NUM_INITIALIZER(struct cmd_range_period_result, period, UINT32);
788 const char PROGMEM help_range_period[] = "set range test period";
790 const parse_inst_t PROGMEM cmd_range_period = {
791 .f = cmd_range_period_parsed, /* function to call */
792 .data = NULL, /* 2nd arg of func */
793 .help_str = help_range_period,
794 .tokens = { /* token list, NULL terminated */
795 (PGM_P)&cmd_range_period_range_period,
796 (PGM_P)&cmd_range_period_action,
797 (PGM_P)&cmd_range_period_period,
804 /* this structure is filled when cmd_range_count is parsed successfully */
805 struct cmd_range_count_result {
806 fixed_string_t range;
807 fixed_string_t action;
811 /* function called when cmd_range_count is parsed successfully */
812 static void cmd_range_count_parsed(void *parsed_result, void *data)
814 struct cmd_range_count_result *res = parsed_result;
817 range_count = res->count;
820 const char PROGMEM str_count[] = "count";
822 const parse_token_string_t PROGMEM cmd_range_count_range_count =
823 TOKEN_STRING_INITIALIZER(struct cmd_range_count_result, range,
825 const parse_token_string_t PROGMEM cmd_range_count_action =
826 TOKEN_STRING_INITIALIZER(struct cmd_range_count_result, action,
828 const parse_token_num_t PROGMEM cmd_range_count_count =
829 TOKEN_NUM_INITIALIZER(struct cmd_range_count_result, count, UINT32);
832 const char PROGMEM help_range_count[] = "set range test count";
834 const parse_inst_t PROGMEM cmd_range_count = {
835 .f = cmd_range_count_parsed, /* function to call */
836 .data = NULL, /* 2nd arg of func */
837 .help_str = help_range_count,
838 .tokens = { /* token list, NULL terminated */
839 (PGM_P)&cmd_range_count_range_count,
840 (PGM_P)&cmd_range_count_action,
841 (PGM_P)&cmd_range_count_count,
848 /* this structure is filled when cmd_range_powermask is parsed successfully */
849 struct cmd_range_powermask_result {
850 fixed_string_t range;
851 fixed_string_t action;
855 /* function called when cmd_range_powermask is parsed successfully */
856 static void cmd_range_powermask_parsed(void *parsed_result, void *data)
858 struct cmd_range_powermask_result *res = parsed_result;
861 range_powermask = res->powermask;
864 const char PROGMEM str_powermask[] = "powermask";
866 const parse_token_string_t PROGMEM cmd_range_powermask_range_powermask =
867 TOKEN_STRING_INITIALIZER(struct cmd_range_powermask_result, range,
869 const parse_token_string_t PROGMEM cmd_range_powermask_action =
870 TOKEN_STRING_INITIALIZER(struct cmd_range_powermask_result, action,
872 const parse_token_num_t PROGMEM cmd_range_powermask_powermask =
873 TOKEN_NUM_INITIALIZER(struct cmd_range_powermask_result, powermask,
877 const char PROGMEM help_range_powermask[] = "set range test powermask";
879 const parse_inst_t PROGMEM cmd_range_powermask = {
880 .f = cmd_range_powermask_parsed, /* function to call */
881 .data = NULL, /* 2nd arg of func */
882 .help_str = help_range_powermask,
883 .tokens = { /* token list, NULL terminated */
884 (PGM_P)&cmd_range_powermask_range_powermask,
885 (PGM_P)&cmd_range_powermask_action,
886 (PGM_P)&cmd_range_powermask_powermask,
893 /* this structure is filled when cmd_range_dstaddr is parsed successfully */
894 struct cmd_range_dstaddr_result {
895 fixed_string_t range;
896 fixed_string_t action;
900 /* function called when cmd_range_dstaddr is parsed successfully */
901 static void cmd_range_dstaddr_parsed(void *parsed_result, void *data)
903 struct cmd_range_dstaddr_result *res = parsed_result;
906 range_dstaddr = res->dstaddr;
909 const char PROGMEM str_dstaddr[] = "dstaddr";
911 const parse_token_string_t PROGMEM cmd_range_dstaddr_range_dstaddr =
912 TOKEN_STRING_INITIALIZER(struct cmd_range_dstaddr_result, range,
914 const parse_token_string_t PROGMEM cmd_range_dstaddr_action =
915 TOKEN_STRING_INITIALIZER(struct cmd_range_dstaddr_result, action,
917 const parse_token_num_t PROGMEM cmd_range_dstaddr_dstaddr =
918 TOKEN_NUM_INITIALIZER(struct cmd_range_dstaddr_result, dstaddr, UINT64);
921 const char PROGMEM help_range_dstaddr[] = "set register rangeing dstaddr";
923 const parse_inst_t PROGMEM cmd_range_dstaddr = {
924 .f = cmd_range_dstaddr_parsed, /* function to call */
925 .data = NULL, /* 2nd arg of func */
926 .help_str = help_range_dstaddr,
927 .tokens = { /* token list, NULL terminated */
928 (PGM_P)&cmd_range_dstaddr_range_dstaddr,
929 (PGM_P)&cmd_range_dstaddr_action,
930 (PGM_P)&cmd_range_dstaddr_dstaddr,
938 /* this structure is filled when cmd_monitor is parsed successfully */
939 struct cmd_monitor_result {
940 fixed_string_t monitor;
941 fixed_string_t action;
944 /* function called when cmd_monitor is parsed successfully */
945 static void cmd_monitor_parsed(void *parsed_result, void *data)
947 struct cmd_monitor_result *res = parsed_result;
948 struct monitor_reg *m;
951 if (!strcmp_P(res->action, PSTR("show"))) {
952 printf_P(PSTR("monitor period is %d ms, %d regs in list\r\n"),
953 monitor_period_ms, monitor_count);
954 LIST_FOREACH(m, &xbee_monitor_list, next)
955 printf_P(PSTR(" %S\r\n"), m->desc);
957 else if (!strcmp_P(res->action, PSTR("start"))) {
958 if (monitor_running) {
959 printf_P(PSTR("already running\r\n"));
962 if (monitor_count == 0) {
963 printf_P(PSTR("no regs to be monitored\r\n"));
966 callout_init(&monitor_event, monitor_cb, NULL, 1);
968 monitor_current = LIST_FIRST(&xbee_monitor_list);
969 callout_schedule(&xbeeboard.intr_cm,
970 &monitor_event, 0); /* immediate */
971 printf_P(PSTR("monitor cb: %S %s\r\n"),
972 monitor_current->desc,
973 monitor_current->atcmd);
976 else if (!strcmp_P(res->action, PSTR("end"))) {
977 if (monitor_running == 0) {
978 printf_P(PSTR("not running\r\n"));
981 callout_stop(&xbeeboard.intr_cm, &monitor_event);
986 const char PROGMEM str_monitor[] = "monitor";
987 const char PROGMEM str_monitor_tokens[] = "show#start#end";
989 const parse_token_string_t PROGMEM cmd_monitor_monitor =
990 TOKEN_STRING_INITIALIZER(struct cmd_monitor_result, monitor,
992 const parse_token_string_t PROGMEM cmd_monitor_action =
993 TOKEN_STRING_INITIALIZER(struct cmd_monitor_result, action,
996 const char PROGMEM help_monitor[] = "start/stop/show current monitoring";
998 const parse_inst_t PROGMEM cmd_monitor = {
999 .f = cmd_monitor_parsed, /* function to call */
1000 .data = NULL, /* 2nd arg of func */
1001 .help_str = help_monitor,
1002 .tokens = { /* token list, NULL terminated */
1003 (PGM_P)&cmd_monitor_monitor,
1004 (PGM_P)&cmd_monitor_action,
1011 /* this structure is filled when cmd_monitor_add is parsed successfully */
1012 struct cmd_monitor_add_result {
1013 fixed_string_t monitor;
1014 fixed_string_t action;
1015 struct xbee_atcmd *cmd;
1018 /* function called when cmd_monitor_add is parsed successfully */
1019 static void cmd_monitor_add_parsed(void *parsed_result, void *data)
1021 struct cmd_monitor_add_result *res = parsed_result;
1022 struct monitor_reg *m;
1023 struct xbee_atcmd copy;
1026 memcpy_P(©, res->cmd, sizeof(copy));
1027 LIST_FOREACH(m, &xbee_monitor_list, next) {
1028 if (!strcmp_P(m->atcmd, copy.name))
1033 printf_P(PSTR("already exist\r\n"));
1037 m = malloc(sizeof(*m));
1039 printf_P(PSTR("no mem\r\n"));
1042 m->desc = copy.desc;
1043 strcpy_P(m->atcmd, copy.name);
1044 LIST_INSERT_HEAD(&xbee_monitor_list, m, next);
1048 const char PROGMEM str_monitor_add[] = "add";
1050 const parse_token_string_t PROGMEM cmd_monitor_add_monitor_add =
1051 TOKEN_STRING_INITIALIZER(struct cmd_monitor_add_result, monitor,
1053 const parse_token_string_t PROGMEM cmd_monitor_add_action =
1054 TOKEN_STRING_INITIALIZER(struct cmd_monitor_add_result, action,
1056 const parse_token_atcmd_t PROGMEM cmd_monitor_add_atcmd =
1057 TOKEN_ATCMD_INITIALIZER(struct cmd_monitor_add_result, cmd, &xbee_dev,
1058 XBEE_ATCMD_F_READ, XBEE_ATCMD_F_READ);
1061 const char PROGMEM help_monitor_add[] = "add a register in monitor list";
1063 const parse_inst_t PROGMEM cmd_monitor_add = {
1064 .f = cmd_monitor_add_parsed, /* function to call */
1065 .data = NULL, /* 2nd arg of func */
1066 .help_str = help_monitor_add,
1067 .tokens = { /* token list, NULL terminated */
1068 (PGM_P)&cmd_monitor_add_monitor_add,
1069 (PGM_P)&cmd_monitor_add_action,
1070 (PGM_P)&cmd_monitor_add_atcmd,
1077 /* this structure is filled when cmd_monitor_period is parsed successfully */
1078 struct cmd_monitor_period_result {
1079 fixed_string_t monitor;
1080 fixed_string_t action;
1084 /* function called when cmd_monitor_period is parsed successfully */
1085 static void cmd_monitor_period_parsed(void *parsed_result, void *data)
1087 struct cmd_monitor_period_result *res = parsed_result;
1090 if (res->period < 100) {
1091 printf_P(PSTR("error, minimum period is 100 ms\r\n"));
1095 monitor_period_ms = res->period;
1098 const char PROGMEM str_monitor_period[] = "period";
1100 const parse_token_string_t PROGMEM cmd_monitor_period_monitor_period =
1101 TOKEN_STRING_INITIALIZER(struct cmd_monitor_period_result, monitor,
1103 const parse_token_string_t PROGMEM cmd_monitor_period_action =
1104 TOKEN_STRING_INITIALIZER(struct cmd_monitor_period_result, action,
1105 str_monitor_period);
1106 const parse_token_num_t PROGMEM cmd_monitor_period_period =
1107 TOKEN_NUM_INITIALIZER(struct cmd_monitor_period_result, period, UINT32);
1110 const char PROGMEM help_monitor_period[] = "set register monitoring period";
1112 const parse_inst_t PROGMEM cmd_monitor_period = {
1113 .f = cmd_monitor_period_parsed, /* function to call */
1114 .data = NULL, /* 2nd arg of func */
1115 .help_str = help_monitor_period,
1116 .tokens = { /* token list, NULL terminated */
1117 (PGM_P)&cmd_monitor_period_monitor_period,
1118 (PGM_P)&cmd_monitor_period_action,
1119 (PGM_P)&cmd_monitor_period_period,
1126 /* this structure is filled when cmd_monitor_del is parsed successfully */
1127 struct cmd_monitor_del_result {
1128 fixed_string_t monitor;
1129 fixed_string_t action;
1130 struct monitor_reg *m;
1133 /* function called when cmd_monitor_del is parsed successfully */
1134 static void cmd_monitor_del_parsed(void *parsed_result, void *data)
1136 struct cmd_monitor_del_result *res = parsed_result;
1139 monitor_current = LIST_NEXT(res->m, next);
1140 LIST_REMOVE(res->m, next);
1143 if (monitor_count == 0) {
1144 printf_P(PSTR("Disable monitoring, no more event\r\n"));
1145 callout_stop(&xbeeboard.intr_cm, &monitor_event);
1146 monitor_running = 0;
1151 const char PROGMEM str_monitor_del[] = "del";
1153 const parse_token_string_t PROGMEM cmd_monitor_del_monitor_del =
1154 TOKEN_STRING_INITIALIZER(struct cmd_monitor_del_result, monitor,
1156 const parse_token_string_t PROGMEM cmd_monitor_del_action =
1157 TOKEN_STRING_INITIALIZER(struct cmd_monitor_del_result, action,
1159 const parse_token_monitor_t PROGMEM cmd_monitor_del_atcmd =
1160 TOKEN_MONITOR_INITIALIZER(struct cmd_monitor_del_result, m);
1163 const char PROGMEM help_monitor_del[] = "del a register in monitor list";
1165 const parse_inst_t PROGMEM cmd_monitor_del = {
1166 .f = cmd_monitor_del_parsed, /* function to call */
1167 .data = NULL, /* 2nd arg of func */
1168 .help_str = help_monitor_del,
1169 .tokens = { /* token list, NULL terminated */
1170 (PGM_P)&cmd_monitor_del_monitor_del,
1171 (PGM_P)&cmd_monitor_del_action,
1172 (PGM_P)&cmd_monitor_del_atcmd,
1180 /* this structure is filled when cmd_ping is parsed successfully */
1181 struct cmd_ping_result {
1182 fixed_string_t ping;
1185 /* function called when cmd_ping is parsed successfully */
1186 static void cmd_ping_parsed(void *parsed_result, void *data)
1188 volatile uint8_t done = 0;
1190 (void)parsed_result;
1192 xbeeapp_send_atcmd("VL", NULL, 0, dump_xbee_atresp_cb, (void *)&done);
1196 const char PROGMEM str_ping[] = "ping";
1198 const parse_token_string_t PROGMEM cmd_ping_ping =
1199 TOKEN_STRING_INITIALIZER(struct cmd_ping_result, ping,
1202 const char PROGMEM help_ping[] = "Send a ping to the xbee device";
1204 const parse_inst_t PROGMEM cmd_ping = {
1205 .f = cmd_ping_parsed, /* function to call */
1206 .data = NULL, /* 2nd arg of func */
1207 .help_str = help_ping,
1208 .tokens = { /* token list, NULL terminated */
1209 (PGM_P)&cmd_ping_ping,
1216 /* this structure is filled when cmd_raw is parsed successfully */
1217 struct cmd_raw_result {
1221 /* function called when cmd_raw is parsed successfully */
1222 static void cmd_raw_parsed(void *parsed_result, void *data)
1224 (void)parsed_result;
1227 if (range_running || monitor_running) {
1228 printf_P(PSTR("stop running range or monitor first\r\n"));
1231 printf_P(PSTR("switched to raw mode, CTRL-D to exit\r\n"));
1232 rdline_stop(&xbeeboard.rdl); /* don't display prompt when return */
1236 const char PROGMEM str_raw[] = "raw";
1238 const parse_token_string_t PROGMEM cmd_raw_raw =
1239 TOKEN_STRING_INITIALIZER(struct cmd_raw_result, raw,
1242 const char PROGMEM help_raw[] = "Switch to raw mode";
1244 const parse_inst_t PROGMEM cmd_raw = {
1245 .f = cmd_raw_parsed, /* function to call */
1246 .data = NULL, /* 2nd arg of func */
1247 .help_str = help_raw,
1248 .tokens = { /* token list, NULL terminated */
1249 (PGM_P)&cmd_raw_raw,
1254 /**********************************************************/
1256 /* this structure is filled when cmd_baudrate is parsed successfully */
1257 struct cmd_baudrate_result {
1258 fixed_string_t arg0;
1262 /* function called when cmd_baudrate is parsed successfully */
1263 static void cmd_baudrate_parsed(void * parsed_result, __attribute__((unused)) void *data)
1265 struct cmd_baudrate_result *res = parsed_result;
1266 struct uart_config c;
1268 uart_getconf(XBEE_UART, &c);
1269 c.baudrate = res->arg1;
1270 uart_setconf(XBEE_UART, &c);
1273 const char PROGMEM str_baudrate_arg0[] = "baudrate";
1274 const parse_token_string_t PROGMEM cmd_baudrate_arg0 =
1275 TOKEN_STRING_INITIALIZER(struct cmd_baudrate_result, arg0,
1277 const parse_token_num_t PROGMEM cmd_baudrate_arg1 =
1278 TOKEN_NUM_INITIALIZER(struct cmd_baudrate_result, arg1,
1281 const char PROGMEM help_baudrate[] = "Change xbee baudrate";
1282 const parse_inst_t PROGMEM cmd_baudrate = {
1283 .f = cmd_baudrate_parsed, /* function to call */
1284 .data = NULL, /* 2nd arg of func */
1285 .help_str = help_baudrate,
1286 .tokens = { /* token list, NULL terminated */
1287 (PGM_P)&cmd_baudrate_arg0,
1288 (PGM_P)&cmd_baudrate_arg1,
1294 /**********************************************************/
1296 /* this structure is filled when cmd_beep is parsed successfully */
1297 struct cmd_beep_result {
1298 fixed_string_t beep;
1301 /* function called when cmd_beep is parsed successfully */
1302 static void cmd_beep_parsed(void *parsed_result, void *data)
1304 (void)parsed_result;
1315 const char PROGMEM str_beep[] = "beep";
1316 const parse_token_string_t PROGMEM cmd_beep_beep =
1317 TOKEN_STRING_INITIALIZER(struct cmd_beep_result, beep,
1320 const char PROGMEM help_beep[] = "Send a beep";
1322 const parse_inst_t PROGMEM cmd_beep = {
1323 .f = cmd_beep_parsed, /* function to call */
1324 .data = NULL, /* 2nd arg of func */
1325 .help_str = help_beep,
1326 .tokens = { /* token list, NULL terminated */
1327 (PGM_P)&cmd_beep_beep,
1332 /**********************************************************/
1334 /* this structure is filled when cmd_servo is parsed successfully */
1335 struct cmd_servo_result {
1336 fixed_string_t arg0;
1337 fixed_string_t arg1;
1342 /* function called when cmd_servo is parsed successfully */
1343 static void cmd_servo_parsed(void * parsed_result, void *data)
1345 struct cmd_servo_result *res = parsed_result;
1349 if (!strcmp_P(res->arg1, PSTR("set"))) {
1350 if (res->num >= N_SERVO) {
1351 printf_P(PSTR("bad servo num\n"));
1354 if (res->val >= 1024) {
1355 printf_P(PSTR("bad servo val\n"));
1358 spi_servo_set(res->num, res->val);
1360 else if (!strcmp_P(res->arg1, PSTR("bypass"))) {
1361 spi_servo_set_bypass(!!res->val);
1363 else if (!strcmp_P(res->arg1, PSTR("ppm"))) {
1364 spi_servo_set_ppm(!!res->val);
1366 else if (!strcmp_P(res->arg1, PSTR("show"))) {
1371 const char PROGMEM str_servo_arg0[] = "servo";
1372 const parse_token_string_t PROGMEM cmd_servo_arg0 =
1373 TOKEN_STRING_INITIALIZER(struct cmd_servo_result, arg0,
1375 const char PROGMEM str_servo_arg1_set[] = "set";
1376 const parse_token_string_t PROGMEM cmd_servo_arg1_set =
1377 TOKEN_STRING_INITIALIZER(struct cmd_servo_result, arg1,
1378 str_servo_arg1_set);
1379 const parse_token_num_t PROGMEM cmd_servo_num =
1380 TOKEN_NUM_INITIALIZER(struct cmd_servo_result, num,
1382 const parse_token_num_t PROGMEM cmd_servo_val =
1383 TOKEN_NUM_INITIALIZER(struct cmd_servo_result, val,
1386 const char PROGMEM help_servo_set[] = "set servo value";
1387 const parse_inst_t PROGMEM cmd_servo_set = {
1388 .f = cmd_servo_parsed, /* function to call */
1389 .data = NULL, /* 2nd arg of func */
1390 .help_str = help_servo_set,
1391 .tokens = { /* token list, NULL terminated */
1392 (PGM_P)&cmd_servo_arg0,
1393 (PGM_P)&cmd_servo_arg1_set,
1394 (PGM_P)&cmd_servo_num,
1395 (PGM_P)&cmd_servo_val,
1400 const char PROGMEM str_servo_arg1_show[] = "show";
1401 const parse_token_string_t PROGMEM cmd_servo_arg1_show =
1402 TOKEN_STRING_INITIALIZER(struct cmd_servo_result, arg1,
1403 str_servo_arg1_show);
1405 const char PROGMEM help_servo_show[] = "read servo and config";
1406 const parse_inst_t PROGMEM cmd_servo_show = {
1407 .f = cmd_servo_parsed, /* function to call */
1408 .data = NULL, /* 2nd arg of func */
1409 .help_str = help_servo_show,
1410 .tokens = { /* token list, NULL terminated */
1411 (PGM_P)&cmd_servo_arg0,
1412 (PGM_P)&cmd_servo_arg1_show,
1417 const char PROGMEM str_servo_arg1_bypassppm[] = "bypass#ppm";
1418 const parse_token_string_t PROGMEM cmd_servo_arg1_bypassppm =
1419 TOKEN_STRING_INITIALIZER(struct cmd_servo_result, arg1,
1420 str_servo_arg1_bypassppm);
1422 const char PROGMEM help_servo_bypassppm[] = "change bypass/ppm";
1423 const parse_inst_t PROGMEM cmd_servo_bypassppm = {
1424 .f = cmd_servo_parsed, /* function to call */
1425 .data = NULL, /* 2nd arg of func */
1426 .help_str = help_servo_bypassppm,
1427 .tokens = { /* token list, NULL terminated */
1428 (PGM_P)&cmd_servo_arg0,
1429 (PGM_P)&cmd_servo_arg1_bypassppm,
1430 (PGM_P)&cmd_servo_val,
1435 /**********************************************************/
1437 /* this structure is filled when cmd_test_spi is parsed successfully */
1438 struct cmd_test_spi_result {
1439 fixed_string_t arg0;
1442 static void cmd_test_spi_parsed(void * parsed_result, void *data)
1444 uint8_t i, flags, wait_time = 0;
1447 (void)parsed_result;
1450 spi_servo_set_bypass(0);
1451 spi_servo_set_ppm(0);
1453 /* stress test: send many commands, no wait between each servo
1454 * of a series, and a variable delay between series */
1455 printf_P(PSTR("stress test\r\n"));
1456 while (!cmdline_keypressed()) {
1468 for (i = 0; i < 6; i++)
1469 spi_servo_set(i, val);
1472 printf_P(PSTR("%4.4d %4.4d %4.4d %4.4d %4.4d %4.4d\r\n"),
1473 spi_servo_get(0), spi_servo_get(1), spi_servo_get(2),
1474 spi_servo_get(3), spi_servo_get(4), spi_servo_get(5));
1477 printf_P(PSTR("bypass mode, with spi commands in background\r\n"));
1478 spi_servo_set_bypass(1);
1480 /* test bypass mode */
1481 while (!cmdline_keypressed()) {
1493 for (i = 0; i < 6; i++)
1494 spi_servo_set(i, val);
1497 printf_P(PSTR("%4.4d %4.4d %4.4d %4.4d %4.4d %4.4d\r\n"),
1498 spi_servo_get(0), spi_servo_get(1), spi_servo_get(2),
1499 spi_servo_get(3), spi_servo_get(4), spi_servo_get(5));
1502 printf_P(PSTR("PPM to servo\r\n"));
1503 spi_servo_set_bypass(0);
1504 spi_servo_set_ppm(0);
1506 /* test PPM to servo (bypass) mode */
1507 while (!cmdline_keypressed()) {
1508 for (i = 0; i < 6; i++) {
1509 val = spi_servo_get(i);
1510 spi_servo_set(i, val);
1514 printf_P(PSTR("PPM to (servo + PPM)\r\n"));
1515 spi_servo_set_bypass(0);
1516 spi_servo_set_ppm(1);
1518 /* test PPM to servo (bypass) mode */
1519 while (!cmdline_keypressed()) {
1520 for (i = 0; i < 6; i++) {
1521 val = spi_servo_get(i);
1522 spi_servo_set(i, val);
1527 const char PROGMEM str_test_spi_arg0[] = "test_spi";
1528 const parse_token_string_t PROGMEM cmd_test_spi_arg0 =
1529 TOKEN_STRING_INITIALIZER(struct cmd_test_spi_result, arg0,
1532 const char PROGMEM help_test_spi[] = "Test the spi";
1533 const parse_inst_t PROGMEM cmd_test_spi = {
1534 .f = cmd_test_spi_parsed, /* function to call */
1535 .data = NULL, /* 2nd arg of func */
1536 .help_str = help_test_spi,
1537 .tokens = { /* token list, NULL terminated */
1538 (PGM_P)&cmd_test_spi_arg0,
1543 /**********************************************************/
1545 /* this structure is filled when cmd_dump_xbee_stats is parsed successfully */
1546 struct cmd_dump_xbee_stats_result {
1547 fixed_string_t arg0;
1550 static void cmd_dump_xbee_stats_parsed(void *parsed_result, void *data)
1552 (void)parsed_result;
1555 xbee_dump_stats(xbee_dev);
1558 const char PROGMEM str_dump_xbee_stats_arg0[] = "dump_xbee_stats";
1559 const parse_token_string_t PROGMEM cmd_dump_xbee_stats_arg0 =
1560 TOKEN_STRING_INITIALIZER(struct cmd_dump_xbee_stats_result, arg0,
1561 str_dump_xbee_stats_arg0);
1563 const char PROGMEM help_dump_xbee_stats[] = "Test the spi";
1564 const parse_inst_t PROGMEM cmd_dump_xbee_stats = {
1565 .f = cmd_dump_xbee_stats_parsed, /* function to call */
1566 .data = NULL, /* 2nd arg of func */
1567 .help_str = help_dump_xbee_stats,
1568 .tokens = { /* token list, NULL terminated */
1569 (PGM_P)&cmd_dump_xbee_stats_arg0,
1574 /**********************************************************/
1576 /* this structure is filled when cmd_rc_proto_stats is parsed successfully */
1577 struct cmd_rc_proto_stats_result {
1578 fixed_string_t arg0;
1579 fixed_string_t arg1;
1582 static void cmd_rc_proto_stats_parsed(void *parsed_result, void *data)
1584 struct cmd_rc_proto_stats_result *res = parsed_result;
1587 if (!strcmp(res->arg1, "show"))
1588 rc_proto_dump_stats();
1590 rc_proto_reset_stats();
1593 const char PROGMEM str_rc_proto_stats_arg0[] = "rc_proto_stats";
1594 const parse_token_string_t PROGMEM cmd_rc_proto_stats_arg0 =
1595 TOKEN_STRING_INITIALIZER(struct cmd_rc_proto_stats_result, arg0,
1596 str_rc_proto_stats_arg0);
1597 const char PROGMEM str_rc_proto_stats_arg1[] = "show#reset";
1598 const parse_token_string_t PROGMEM cmd_rc_proto_stats_arg1 =
1599 TOKEN_STRING_INITIALIZER(struct cmd_rc_proto_stats_result, arg1,
1600 str_rc_proto_stats_arg1);
1602 const char PROGMEM help_rc_proto_stats[] = "dump rc_proto stats";
1603 const parse_inst_t PROGMEM cmd_rc_proto_stats = {
1604 .f = cmd_rc_proto_stats_parsed, /* function to call */
1605 .data = NULL, /* 2nd arg of func */
1606 .help_str = help_rc_proto_stats,
1607 .tokens = { /* token list, NULL terminated */
1608 (PGM_P)&cmd_rc_proto_stats_arg0,
1609 (PGM_P)&cmd_rc_proto_stats_arg1,
1614 /**********************************************************/
1616 /* this structure is filled when cmd_rc_proto_timers is parsed successfully */
1617 struct cmd_rc_proto_timers_result {
1618 fixed_string_t arg0;
1619 fixed_string_t arg1;
1622 uint16_t power_probe;
1623 uint16_t autobypass;
1626 static void cmd_rc_proto_timers_parsed(void *parsed_result, void *data)
1628 struct cmd_rc_proto_timers_result *res = parsed_result;
1631 if (!strcmp_P(res->arg1, PSTR("set"))) {
1632 rc_proto_timers.send_servo_min_ms = res->servo_min;
1633 rc_proto_timers.send_servo_max_ms = res->servo_max;
1634 rc_proto_timers.send_power_probe_ms = res->power_probe;
1635 rc_proto_timers.autobypass_ms = res->autobypass;
1638 printf_P(PSTR("rc_proto_timers: min=%d, max=%d, "
1639 "power_probe=%d autobypass=%d\n"),
1640 rc_proto_timers.send_servo_min_ms,
1641 rc_proto_timers.send_servo_max_ms,
1642 rc_proto_timers.send_power_probe_ms,
1643 rc_proto_timers.autobypass_ms);
1646 const char PROGMEM str_rc_proto_timers_arg0[] = "rc_proto_timers";
1647 const parse_token_string_t PROGMEM cmd_rc_proto_timers_arg0 =
1648 TOKEN_STRING_INITIALIZER(struct cmd_rc_proto_timers_result, arg0,
1649 str_rc_proto_timers_arg0);
1650 const char PROGMEM str_rc_proto_timers_arg1[] = "set";
1651 const parse_token_string_t PROGMEM cmd_rc_proto_timers_arg1 =
1652 TOKEN_STRING_INITIALIZER(struct cmd_rc_proto_timers_result, arg1,
1653 str_rc_proto_timers_arg1);
1654 const parse_token_num_t PROGMEM cmd_rc_proto_timers_servo_min =
1655 TOKEN_NUM_INITIALIZER(struct cmd_rc_proto_timers_result, servo_min,
1657 const parse_token_num_t PROGMEM cmd_rc_proto_timers_servo_max =
1658 TOKEN_NUM_INITIALIZER(struct cmd_rc_proto_timers_result, servo_max,
1660 const parse_token_num_t PROGMEM cmd_rc_proto_timers_power_probe =
1661 TOKEN_NUM_INITIALIZER(struct cmd_rc_proto_timers_result, power_probe,
1663 const parse_token_num_t PROGMEM cmd_rc_proto_timers_autobypass =
1664 TOKEN_NUM_INITIALIZER(struct cmd_rc_proto_timers_result, autobypass,
1667 const char PROGMEM help_rc_proto_timers[] = "set rc_proto_timers (servo_min, "
1668 "servo_max, pow_probe, autobypass)";
1669 const parse_inst_t PROGMEM cmd_rc_proto_timers = {
1670 .f = cmd_rc_proto_timers_parsed, /* function to call */
1671 .data = NULL, /* 2nd arg of func */
1672 .help_str = help_rc_proto_timers,
1673 .tokens = { /* token list, NULL terminated */
1674 (PGM_P)&cmd_rc_proto_timers_arg0,
1675 (PGM_P)&cmd_rc_proto_timers_arg1,
1676 (PGM_P)&cmd_rc_proto_timers_servo_min,
1677 (PGM_P)&cmd_rc_proto_timers_servo_max,
1678 (PGM_P)&cmd_rc_proto_timers_power_probe,
1679 (PGM_P)&cmd_rc_proto_timers_autobypass,
1684 const char PROGMEM str_rc_proto_timers_show_arg1[] = "show";
1685 const parse_token_string_t PROGMEM cmd_rc_proto_timers_show_arg1 =
1686 TOKEN_STRING_INITIALIZER(struct cmd_rc_proto_timers_result, arg1,
1687 str_rc_proto_timers_show_arg1);
1689 const char PROGMEM help_rc_proto_timers_show[] = "show rc_proto timers value";
1690 const parse_inst_t PROGMEM cmd_rc_proto_timers_show = {
1691 .f = cmd_rc_proto_timers_parsed, /* function to call */
1692 .data = NULL, /* 2nd arg of func */
1693 .help_str = help_rc_proto_timers_show,
1694 .tokens = { /* token list, NULL terminated */
1695 (PGM_P)&cmd_rc_proto_timers_arg0,
1696 (PGM_P)&cmd_rc_proto_timers_show_arg1,
1701 /**********************************************************/
1703 /* this structure is filled when cmd_rc_proto_mode is parsed successfully */
1704 struct cmd_rc_proto_mode_result {
1705 fixed_string_t arg0;
1710 static void cmd_rc_proto_mode_parsed(void *parsed_result, void *data)
1712 struct cmd_rc_proto_mode_result *res = parsed_result;
1717 flags = rc_proto_get_mode();
1718 if (!strcmp_P(res->val, PSTR("on")))
1721 if (!strcmp_P(res->cmd, PSTR("rx_copy_spi"))) {
1723 flags |= RC_PROTO_FLAGS_RX_COPY_SPI;
1725 flags &= ~RC_PROTO_FLAGS_RX_COPY_SPI;
1727 else if (!strcmp_P(res->cmd, PSTR("rx_autobypass"))) {
1729 flags |= RC_PROTO_FLAGS_RX_AUTOBYPASS;
1731 flags &= ~RC_PROTO_FLAGS_RX_AUTOBYPASS;
1733 else if (!strcmp_P(res->cmd, PSTR("tx_stats"))) {
1735 flags |= RC_PROTO_FLAGS_TX_STATS;
1737 flags &= ~RC_PROTO_FLAGS_TX_STATS;
1739 else if (!strcmp_P(res->cmd, PSTR("tx_power_probe"))) {
1741 flags |= RC_PROTO_FLAGS_TX_POW_PROBE;
1743 flags &= ~RC_PROTO_FLAGS_TX_POW_PROBE;
1745 else if (!strcmp_P(res->cmd, PSTR("compute_best_pow"))) {
1747 flags |= RC_PROTO_FLAGS_COMPUTE_BEST_POW;
1749 flags &= ~RC_PROTO_FLAGS_COMPUTE_BEST_POW;
1751 else if (!strcmp_P(res->cmd, PSTR("tx"))) {
1752 flags &= ~RC_PROTO_FLAGS_TX_MASK;
1753 if (!strcmp_P(res->val, PSTR("bypass")))
1754 flags |= RC_PROTO_FLAGS_TX_BYPASS;
1755 else if (!strcmp_P(res->val, PSTR("copy_spi")))
1756 flags |= RC_PROTO_FLAGS_TX_COPY_SPI;
1758 rc_proto_set_mode(flags);
1761 if ((flags & RC_PROTO_FLAGS_TX_MASK) == RC_PROTO_FLAGS_TX_OFF)
1762 printf_P(PSTR("rc_proto_mode tx off\n"));
1763 else if ((flags & RC_PROTO_FLAGS_TX_MASK) == RC_PROTO_FLAGS_TX_BYPASS)
1764 printf_P(PSTR("rc_proto_mode tx bypass\n"));
1765 else if ((flags & RC_PROTO_FLAGS_TX_MASK) == RC_PROTO_FLAGS_TX_COPY_SPI)
1766 printf_P(PSTR("rc_proto_mode tx copy_spi\n"));
1767 printf_P(PSTR("rc_proto_mode rx_copy_spi %s\n"),
1768 (flags & RC_PROTO_FLAGS_RX_COPY_SPI) ? "on" : "off");
1769 printf_P(PSTR("rc_proto_mode rx_autobypass %s\n"),
1770 (flags & RC_PROTO_FLAGS_RX_AUTOBYPASS) ? "on" : "off");
1771 printf_P(PSTR("rc_proto_mode tx_stats %s\n"),
1772 (flags & RC_PROTO_FLAGS_TX_STATS) ? "on" : "off");
1773 printf_P(PSTR("rc_proto_mode tx_power_probe %s\n"),
1774 (flags & RC_PROTO_FLAGS_TX_POW_PROBE) ? "on" : "off");
1775 printf_P(PSTR("rc_proto_mode compute_best_pow %s\n"),
1776 (flags & RC_PROTO_FLAGS_COMPUTE_BEST_POW) ? "on" : "off");
1779 const char PROGMEM str_rc_proto_mode_arg0[] = "rc_proto_mode";
1780 const parse_token_string_t PROGMEM cmd_rc_proto_mode_arg0 =
1781 TOKEN_STRING_INITIALIZER(struct cmd_rc_proto_mode_result, arg0,
1782 str_rc_proto_mode_arg0);
1784 const char PROGMEM str_rc_proto_mode_cmd[] =
1785 "rx_copy_spi#rx_autobypass#tx_stats#tx_power_probe#compute_best_pow";
1786 const parse_token_string_t PROGMEM cmd_rc_proto_mode_cmd =
1787 TOKEN_STRING_INITIALIZER(struct cmd_rc_proto_mode_result, cmd,
1788 str_rc_proto_mode_cmd);
1790 const char PROGMEM str_rc_proto_mode_onoff[] = "on#off";
1791 const parse_token_string_t PROGMEM cmd_rc_proto_mode_onoff =
1792 TOKEN_STRING_INITIALIZER(struct cmd_rc_proto_mode_result, val,
1793 str_rc_proto_mode_onoff);
1795 const char PROGMEM help_rc_proto_mode[] = "Set rc proto behavior";
1796 const parse_inst_t PROGMEM cmd_rc_proto_mode = {
1797 .f = cmd_rc_proto_mode_parsed, /* function to call */
1798 .data = NULL, /* 2nd arg of func */
1799 .help_str = help_rc_proto_mode,
1800 .tokens = { /* token list, NULL terminated */
1801 (PGM_P)&cmd_rc_proto_mode_arg0,
1802 (PGM_P)&cmd_rc_proto_mode_cmd,
1803 (PGM_P)&cmd_rc_proto_mode_onoff,
1808 const char PROGMEM str_rc_proto_mode_cmd2[] = "tx";
1809 const parse_token_string_t PROGMEM cmd_rc_proto_mode_cmd2 =
1810 TOKEN_STRING_INITIALIZER(struct cmd_rc_proto_mode_result, cmd,
1811 str_rc_proto_mode_cmd2);
1813 const char PROGMEM str_rc_proto_mode_val[] = "off#bypass#copy_spi";
1814 const parse_token_string_t PROGMEM cmd_rc_proto_mode_val =
1815 TOKEN_STRING_INITIALIZER(struct cmd_rc_proto_mode_result, val,
1816 str_rc_proto_mode_val);
1818 const parse_inst_t PROGMEM cmd_rc_proto_mode2 = {
1819 .f = cmd_rc_proto_mode_parsed, /* function to call */
1820 .data = NULL, /* 2nd arg of func */
1821 .help_str = help_rc_proto_mode,
1822 .tokens = { /* token list, NULL terminated */
1823 (PGM_P)&cmd_rc_proto_mode_arg0,
1824 (PGM_P)&cmd_rc_proto_mode_cmd2,
1825 (PGM_P)&cmd_rc_proto_mode_val,
1830 const char PROGMEM str_rc_proto_mode_cmd3[] = "show";
1831 const parse_token_string_t PROGMEM cmd_rc_proto_mode_cmd3 =
1832 TOKEN_STRING_INITIALIZER(struct cmd_rc_proto_mode_result, cmd,
1833 str_rc_proto_mode_cmd3);
1835 const parse_inst_t PROGMEM cmd_rc_proto_mode3 = {
1836 .f = cmd_rc_proto_mode_parsed, /* function to call */
1837 .data = NULL, /* 2nd arg of func */
1838 .help_str = help_rc_proto_mode,
1839 .tokens = { /* token list, NULL terminated */
1840 (PGM_P)&cmd_rc_proto_mode_arg0,
1841 (PGM_P)&cmd_rc_proto_mode_cmd3,
1846 /**********************************************************/
1848 /* this structure is filled when cmd_rc_proto_hello is parsed successfully */
1849 struct cmd_rc_proto_hello_result {
1850 fixed_string_t rc_proto_hello;
1852 struct xbee_neigh *neigh;
1855 fixed_string_t data;
1858 /* function called when cmd_rc_proto_hello is parsed successfully */
1859 static void cmd_rc_proto_hello_parsed(void *parsed_result, void *use_neigh)
1861 struct cmd_rc_proto_hello_result *res = parsed_result;
1862 uint16_t now, next, diff;
1867 addr = res->neigh->addr;
1877 while (!cmdline_keypressed() && res->count != 0) {
1883 if (diff < res->period)
1886 rc_proto_send_hello(addr, res->data, strlen(res->data), -1);
1887 next += res->period;
1892 const char PROGMEM str_rc_proto_hello[] = "rc_proto_hello";
1894 const parse_token_string_t PROGMEM cmd_rc_proto_hello_rc_proto_hello =
1895 TOKEN_STRING_INITIALIZER(struct cmd_rc_proto_hello_result, rc_proto_hello,
1896 str_rc_proto_hello);
1898 const parse_token_num_t PROGMEM cmd_rc_proto_hello_addr =
1899 TOKEN_NUM_INITIALIZER(struct cmd_rc_proto_hello_result, addr, UINT64);
1901 const parse_token_num_t PROGMEM cmd_rc_proto_hello_period =
1902 TOKEN_NUM_INITIALIZER(struct cmd_rc_proto_hello_result, period, UINT16);
1904 const parse_token_num_t PROGMEM cmd_rc_proto_hello_count =
1905 TOKEN_NUM_INITIALIZER(struct cmd_rc_proto_hello_result, count, UINT16);
1907 const parse_token_string_t PROGMEM cmd_rc_proto_hello_data =
1908 TOKEN_STRING_INITIALIZER(struct cmd_rc_proto_hello_result, data, NULL);
1910 const char PROGMEM help_rc_proto_hello[] =
1911 "Send hello msg to a node: addr, period_ms, count, str";
1913 const parse_inst_t PROGMEM cmd_rc_proto_hello = {
1914 .f = cmd_rc_proto_hello_parsed, /* function to call */
1915 .data = NULL, /* 2nd arg of func */
1916 .help_str = help_rc_proto_hello,
1917 .tokens = { /* token list, NULL terminated */
1918 (PGM_P)&cmd_rc_proto_hello_rc_proto_hello,
1919 (PGM_P)&cmd_rc_proto_hello_addr,
1920 (PGM_P)&cmd_rc_proto_hello_period,
1921 (PGM_P)&cmd_rc_proto_hello_count,
1922 (PGM_P)&cmd_rc_proto_hello_data,
1927 const parse_token_neighbor_t PROGMEM cmd_rc_proto_hello_neigh =
1928 TOKEN_NEIGHBOR_INITIALIZER(struct cmd_rc_proto_hello_result, neigh,
1931 const parse_inst_t PROGMEM cmd_rc_proto_hello_name = {
1932 .f = cmd_rc_proto_hello_parsed, /* function to call */
1933 .data = (void *)1, /* 2nd arg of func */
1934 .help_str = help_rc_proto_hello,
1935 .tokens = { /* token list, NULL terminated */
1936 (PGM_P)&cmd_rc_proto_hello_rc_proto_hello,
1937 (PGM_P)&cmd_rc_proto_hello_neigh,
1938 (PGM_P)&cmd_rc_proto_hello_period,
1939 (PGM_P)&cmd_rc_proto_hello_count,
1940 (PGM_P)&cmd_rc_proto_hello_data,
1945 /**********************************************************/
1947 /* this structure is filled when cmd_rc_proto_echo is parsed successfully */
1948 struct cmd_rc_proto_echo_result {
1949 fixed_string_t rc_proto_echo;
1951 struct xbee_neigh *neigh;
1954 fixed_string_t data;
1957 /* function called when cmd_rc_proto_echo is parsed successfully */
1958 static void cmd_rc_proto_echo_parsed(void *parsed_result, void *use_neigh)
1960 struct cmd_rc_proto_echo_result *res = parsed_result;
1961 uint16_t now, next, diff;
1966 addr = res->neigh->addr;
1976 while (!cmdline_keypressed() && res->count != 0) {
1982 if (diff < res->period)
1985 rc_proto_send_echo_req(addr, res->data, strlen(res->data), -1);
1986 next += res->period;
1991 const char PROGMEM str_rc_proto_echo[] = "rc_proto_echo";
1993 const parse_token_string_t PROGMEM cmd_rc_proto_echo_rc_proto_echo =
1994 TOKEN_STRING_INITIALIZER(struct cmd_rc_proto_echo_result, rc_proto_echo,
1997 const parse_token_num_t PROGMEM cmd_rc_proto_echo_addr =
1998 TOKEN_NUM_INITIALIZER(struct cmd_rc_proto_echo_result, addr, UINT64);
2000 const parse_token_num_t PROGMEM cmd_rc_proto_echo_period =
2001 TOKEN_NUM_INITIALIZER(struct cmd_rc_proto_echo_result, period, UINT16);
2003 const parse_token_num_t PROGMEM cmd_rc_proto_echo_count =
2004 TOKEN_NUM_INITIALIZER(struct cmd_rc_proto_echo_result, count, UINT16);
2006 const parse_token_string_t PROGMEM cmd_rc_proto_echo_data =
2007 TOKEN_STRING_INITIALIZER(struct cmd_rc_proto_echo_result, data, NULL);
2009 const char PROGMEM help_rc_proto_echo[] =
2010 "Send echo msg to a node: addr, period_ms, count, str";
2012 const parse_inst_t PROGMEM cmd_rc_proto_echo = {
2013 .f = cmd_rc_proto_echo_parsed, /* function to call */
2014 .data = NULL, /* 2nd arg of func */
2015 .help_str = help_rc_proto_echo,
2016 .tokens = { /* token list, NULL terminated */
2017 (PGM_P)&cmd_rc_proto_echo_rc_proto_echo,
2018 (PGM_P)&cmd_rc_proto_echo_addr,
2019 (PGM_P)&cmd_rc_proto_echo_period,
2020 (PGM_P)&cmd_rc_proto_echo_count,
2021 (PGM_P)&cmd_rc_proto_echo_data,
2026 const parse_token_neighbor_t PROGMEM cmd_rc_proto_echo_neigh =
2027 TOKEN_NEIGHBOR_INITIALIZER(struct cmd_rc_proto_echo_result, neigh,
2030 const parse_inst_t PROGMEM cmd_rc_proto_echo_name = {
2031 .f = cmd_rc_proto_echo_parsed, /* function to call */
2032 .data = (void *)1, /* 2nd arg of func */
2033 .help_str = help_rc_proto_echo,
2034 .tokens = { /* token list, NULL terminated */
2035 (PGM_P)&cmd_rc_proto_echo_rc_proto_echo,
2036 (PGM_P)&cmd_rc_proto_echo_neigh,
2037 (PGM_P)&cmd_rc_proto_echo_period,
2038 (PGM_P)&cmd_rc_proto_echo_count,
2039 (PGM_P)&cmd_rc_proto_echo_data,
2044 /**********************************************************/
2046 /* this structure is filled when cmd_test_eeprom_config is parsed successfully */
2047 struct cmd_test_eeprom_config_result {
2048 fixed_string_t arg0;
2051 static void cmd_test_eeprom_config_parsed(void *parsed_result, void *data)
2053 (void)parsed_result;
2057 eeprom_append_cmd("salut1\n");
2059 eeprom_append_cmd("salut2\n");
2060 eeprom_append_cmd("salut3\n");
2061 eeprom_append_cmd("salut4\n");
2063 eeprom_insert_cmd_before("coin\n", 0);
2064 eeprom_insert_cmd_before("coin2\n", 2);
2066 eeprom_delete_cmd(2);
2067 eeprom_delete_cmd(0);
2071 const char PROGMEM str_test_eeprom_config_arg0[] = "test_eeprom_config";
2072 const parse_token_string_t PROGMEM cmd_test_eeprom_config_arg0 =
2073 TOKEN_STRING_INITIALIZER(struct cmd_test_eeprom_config_result, arg0,
2074 str_test_eeprom_config_arg0);
2076 const char PROGMEM help_test_eeprom_config[] = "Test the eeprom configuration";
2077 const parse_inst_t PROGMEM cmd_test_eeprom_config = {
2078 .f = cmd_test_eeprom_config_parsed, /* function to call */
2079 .data = NULL, /* 2nd arg of func */
2080 .help_str = help_test_eeprom_config,
2081 .tokens = { /* token list, NULL terminated */
2082 (PGM_P)&cmd_test_eeprom_config_arg0,
2089 struct cmd_eeprom_del_result {
2091 fixed_string_t action;
2095 static void cmd_eeprom_del_parsed(void *parsed_result,
2098 struct cmd_eeprom_del_result *res = parsed_result;
2101 if (eeprom_delete_cmd(res->n) < 0)
2102 printf_P(PSTR("cannot delete command\n"));
2106 const char PROGMEM str_eeprom_del_eeprom[] = "eeprom";
2107 const parse_token_string_t PROGMEM cmd_eeprom_del_cmd =
2108 TOKEN_STRING_INITIALIZER(struct cmd_eeprom_del_result, cmd,
2109 str_eeprom_del_eeprom);
2110 const char PROGMEM str_eeprom_del_del[] = "del";
2111 const parse_token_string_t PROGMEM cmd_eeprom_del_action =
2112 TOKEN_STRING_INITIALIZER(struct cmd_eeprom_del_result, action,
2113 str_eeprom_del_del);
2114 const parse_token_num_t PROGMEM cmd_eeprom_del_num =
2115 TOKEN_NUM_INITIALIZER(struct cmd_eeprom_del_result, n,
2118 const char PROGMEM help_eeprom_del[] = "delete an eeprom init command";
2119 const parse_inst_t PROGMEM cmd_eeprom_del = {
2120 .f = cmd_eeprom_del_parsed, /* function to call */
2121 .data = NULL, /* 2nd arg of func */
2122 .help_str = help_eeprom_del,
2123 .tokens = { /* token list, NULL terminated */
2124 (PGM_P)&cmd_eeprom_del_cmd,
2125 (PGM_P)&cmd_eeprom_del_action,
2126 (PGM_P)&cmd_eeprom_del_num,
2133 struct cmd_eeprom_add_result {
2135 fixed_string_t action;
2139 static void cmd_eeprom_add_parsed(void *parsed_result,
2142 struct cmd_eeprom_add_result *res = parsed_result;
2148 rdline_init(&rdl, cmdline_write_char, NULL, NULL);
2149 rdline_newline(&rdl, "> ");
2152 c = cmdline_dev_recv(NULL);
2156 ret = rdline_char_in(&rdl, c);
2158 printf_P(PSTR("abort\n"));
2165 buffer = rdline_get_buffer(&rdl);
2167 eeprom_insert_cmd_before(buffer, res->n);
2169 eeprom_append_cmd(buffer);
2173 const char PROGMEM str_eeprom_add_eeprom[] = "eeprom";
2174 const parse_token_string_t PROGMEM cmd_eeprom_add_cmd =
2175 TOKEN_STRING_INITIALIZER(struct cmd_eeprom_add_result, cmd,
2176 str_eeprom_add_eeprom);
2177 const char PROGMEM str_eeprom_add_add[] = "add";
2178 const parse_token_string_t PROGMEM cmd_eeprom_add_action =
2179 TOKEN_STRING_INITIALIZER(struct cmd_eeprom_add_result, action,
2180 str_eeprom_add_add);
2181 const parse_token_num_t PROGMEM cmd_eeprom_add_num =
2182 TOKEN_NUM_INITIALIZER(struct cmd_eeprom_add_result, n,
2185 const char PROGMEM help_eeprom_add[] = "insert an eeprom init command";
2186 const parse_inst_t PROGMEM cmd_eeprom_add = {
2187 .f = cmd_eeprom_add_parsed, /* function to call */
2188 .data = NULL, /* 2nd arg of func */
2189 .help_str = help_eeprom_add,
2190 .tokens = { /* token list, NULL terminated */
2191 (PGM_P)&cmd_eeprom_add_cmd,
2192 (PGM_P)&cmd_eeprom_add_action,
2193 (PGM_P)&cmd_eeprom_add_num,
2198 const char PROGMEM help_eeprom_add2[] = "append an eeprom init command";
2199 const parse_inst_t PROGMEM cmd_eeprom_add2 = {
2200 .f = cmd_eeprom_add_parsed, /* function to call */
2201 .data = (void *)1, /* 2nd arg of func */
2202 .help_str = help_eeprom_add2,
2203 .tokens = { /* token list, NULL terminated */
2204 (PGM_P)&cmd_eeprom_add_cmd,
2205 (PGM_P)&cmd_eeprom_add_action,
2212 struct cmd_eeprom_list_result {
2214 fixed_string_t action;
2217 static void cmd_eeprom_list_parsed(void *parsed_result,
2220 (void)parsed_result;
2225 const char PROGMEM str_eeprom_list_eeprom[] = "eeprom";
2226 const parse_token_string_t PROGMEM cmd_eeprom_list_cmd =
2227 TOKEN_STRING_INITIALIZER(struct cmd_eeprom_list_result, cmd,
2228 str_eeprom_list_eeprom);
2229 const char PROGMEM str_eeprom_list_list[] = "list";
2230 const parse_token_string_t PROGMEM cmd_eeprom_list_action =
2231 TOKEN_STRING_INITIALIZER(struct cmd_eeprom_list_result, action,
2232 str_eeprom_list_list);
2234 const char PROGMEM help_eeprom_list[] = "list all eeprom init commands";
2235 const parse_inst_t PROGMEM cmd_eeprom_list = {
2236 .f = cmd_eeprom_list_parsed, /* function to call */
2237 .data = NULL, /* 2nd arg of func */
2238 .help_str = help_eeprom_list,
2239 .tokens = { /* token list, NULL terminated */
2240 (PGM_P)&cmd_eeprom_list_cmd,
2241 (PGM_P)&cmd_eeprom_list_action,
2250 const parse_ctx_t PROGMEM main_ctx[] = {
2252 /* commands_gen.c */
2274 &cmd_range_powermask,
2277 &cmd_monitor_period,
2285 &cmd_servo_bypassppm,
2288 &cmd_dump_xbee_stats,
2289 &cmd_rc_proto_stats,
2290 &cmd_rc_proto_timers,
2291 &cmd_rc_proto_timers_show,
2293 &cmd_rc_proto_mode2,
2294 &cmd_rc_proto_mode3,
2295 &cmd_rc_proto_hello,
2296 &cmd_rc_proto_hello_name,
2298 &cmd_rc_proto_echo_name,
2299 &cmd_test_eeprom_config,