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_recv_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 len -= sizeof(*recvframe);
179 atresp_to_str(buf, sizeof(buf), frame);
180 NOTICE(E_USER_XBEE, "status ok, len=%d, %s", 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_send_hello is parsed successfully */
633 struct cmd_send_hello_result {
634 fixed_string_t send_hello;
636 struct xbee_neigh *neigh;
642 /* function called when cmd_send_hello is parsed successfully */
643 static void cmd_send_hello_parsed(void *parsed_result, void *use_neigh)
645 struct cmd_send_hello_result *res = parsed_result;
646 uint16_t now, next, diff;
651 addr = res->neigh->addr;
661 while (!cmdline_keypressed() && res->count != 0) {
667 if (diff < res->period)
670 rc_proto_send_hello(addr, res->data, strlen(res->data));
676 const char PROGMEM str_send_hello[] = "send_hello";
678 const parse_token_string_t PROGMEM cmd_send_hello_send_hello =
679 TOKEN_STRING_INITIALIZER(struct cmd_send_hello_result, send_hello,
682 const parse_token_num_t PROGMEM cmd_send_hello_addr =
683 TOKEN_NUM_INITIALIZER(struct cmd_send_hello_result, addr, UINT64);
685 const parse_token_num_t PROGMEM cmd_send_hello_period =
686 TOKEN_NUM_INITIALIZER(struct cmd_send_hello_result, period, UINT16);
688 const parse_token_num_t PROGMEM cmd_send_hello_count =
689 TOKEN_NUM_INITIALIZER(struct cmd_send_hello_result, count, UINT16);
691 const parse_token_string_t PROGMEM cmd_send_hello_data =
692 TOKEN_STRING_INITIALIZER(struct cmd_send_hello_result, data, NULL);
694 const char PROGMEM help_send_hello[] =
695 "Send hello msg to a node: addr, period_ms, count, str";
697 const parse_inst_t PROGMEM cmd_send_hello = {
698 .f = cmd_send_hello_parsed, /* function to call */
699 .data = NULL, /* 2nd arg of func */
700 .help_str = help_send_hello,
701 .tokens = { /* token list, NULL terminated */
702 (PGM_P)&cmd_send_hello_send_hello,
703 (PGM_P)&cmd_send_hello_addr,
704 (PGM_P)&cmd_send_hello_period,
705 (PGM_P)&cmd_send_hello_count,
706 (PGM_P)&cmd_send_hello_data,
711 const parse_token_neighbor_t PROGMEM cmd_send_hello_neigh =
712 TOKEN_NEIGHBOR_INITIALIZER(struct cmd_send_hello_result, neigh,
715 const parse_inst_t PROGMEM cmd_send_hello_name = {
716 .f = cmd_send_hello_parsed, /* function to call */
717 .data = (void *)1, /* 2nd arg of func */
718 .help_str = help_send_hello,
719 .tokens = { /* token list, NULL terminated */
720 (PGM_P)&cmd_send_hello_send_hello,
721 (PGM_P)&cmd_send_hello_neigh,
722 (PGM_P)&cmd_send_hello_period,
723 (PGM_P)&cmd_send_hello_count,
724 (PGM_P)&cmd_send_hello_data,
731 /* this structure is filled when cmd_sendmsg_name is parsed successfully */
732 struct cmd_sendmsg_name_result {
733 fixed_string_t sendmsg_name;
734 struct xbee_neigh *neigh;
738 /* function called when cmd_sendmsg_name is parsed successfully */
739 static void cmd_sendmsg_name_parsed(void *parsed_result, void *data)
741 struct cmd_sendmsg_name_result *res = parsed_result;
743 volatile uint8_t done = 0;
748 msg.iov[0].buf = res->data;
749 msg.iov[0].len = strlen(res->data);
751 xbeeapp_send_msg(res->neigh->addr, &msg, send_msg_cb, (void *)&done);
755 const parse_token_string_t PROGMEM cmd_sendmsg_name_sendmsg_name =
756 TOKEN_STRING_INITIALIZER(struct cmd_sendmsg_name_result, sendmsg_name,
759 const parse_token_neighbor_t PROGMEM cmd_sendmsg_name_neigh =
760 TOKEN_NEIGHBOR_INITIALIZER(struct cmd_sendmsg_name_result, neigh,
763 const parse_token_string_t PROGMEM cmd_sendmsg_name_data =
764 TOKEN_STRING_INITIALIZER(struct cmd_sendmsg_name_result, data, NULL);
766 const char PROGMEM help_sendmsg_name[] = "Send data to a node using its name";
768 const parse_inst_t PROGMEM cmd_sendmsg_name = {
769 .f = cmd_sendmsg_name_parsed, /* function to call */
770 .data = NULL, /* 2nd arg of func */
771 .help_str = help_sendmsg_name,
772 .tokens = { /* token list, NULL terminated */
773 (PGM_P)&cmd_sendmsg_name_sendmsg_name,
774 (PGM_P)&cmd_sendmsg_name_neigh,
775 (PGM_P)&cmd_sendmsg_name_data,
783 /* this structure is filled when cmd_range is parsed successfully */
784 struct cmd_range_result {
785 fixed_string_t range;
786 fixed_string_t action;
789 /* function called when cmd_range is parsed successfully */
790 static void cmd_range_parsed(void *parsed_result, void *data)
792 struct cmd_range_result *res = parsed_result;
795 if (!strcmp_P(res->action, PSTR("show"))) {
796 printf_P(PSTR("range infos:\r\n"));
797 printf_P(PSTR(" range period %d\r\n"), range_period_ms);
798 printf_P(PSTR(" range count %d\r\n"), range_count);
799 printf_P(PSTR(" range powermask 0x%x\r\n"), range_powermask);
800 printf_P(PSTR(" range dstaddr 0x%.8"PRIx32"%.8"PRIx32"\r\n"),
801 (uint32_t)(range_dstaddr >> 32ULL),
802 (uint32_t)(range_dstaddr & 0xFFFFFFFF));
805 printf_P(PSTR(" range test is running\r\n"));
807 printf_P(PSTR(" range test is not running\r\n"));
809 else if (!strcmp(res->action, "start")) {
811 printf_P(PSTR("already running\r\n"));
814 range_cur_count = range_count;
815 callout_init(&range_event, range_cb, NULL, LOW_PRIO);
817 callout_schedule(&xbeeboard.intr_cm,
818 &range_event, 0); /* immediate */
820 else if (!strcmp(res->action, "end")) {
821 if (range_running == 0) {
822 printf_P(PSTR("not running\r\n"));
825 callout_stop(&xbeeboard.intr_cm, &range_event);
830 const char PROGMEM str_range[] = "range";
831 const char PROGMEM str_range_tokens[] = "show#start#end";
833 const parse_token_string_t PROGMEM cmd_range_range =
834 TOKEN_STRING_INITIALIZER(struct cmd_range_result, range,
836 const parse_token_string_t PROGMEM cmd_range_action =
837 TOKEN_STRING_INITIALIZER(struct cmd_range_result, action,
840 const char PROGMEM help_range[] = "start/stop/show current rangeing";
842 const parse_inst_t PROGMEM cmd_range = {
843 .f = cmd_range_parsed, /* function to call */
844 .data = NULL, /* 2nd arg of func */
845 .help_str = help_range,
846 .tokens = { /* token list, NULL terminated */
847 (PGM_P)&cmd_range_range,
848 (PGM_P)&cmd_range_action,
855 /* this structure is filled when cmd_range_period is parsed successfully */
856 struct cmd_range_period_result {
857 fixed_string_t range;
858 fixed_string_t action;
862 /* function called when cmd_range_period is parsed successfully */
863 static void cmd_range_period_parsed(void *parsed_result, void *data)
865 struct cmd_range_period_result *res = parsed_result;
868 if (res->period < 10) {
869 printf_P(PSTR("error, minimum period is 10 ms\r\n"));
873 range_period_ms = res->period;
876 const char PROGMEM str_period[] = "period";
878 const parse_token_string_t PROGMEM cmd_range_period_range_period =
879 TOKEN_STRING_INITIALIZER(struct cmd_range_period_result, range,
881 const parse_token_string_t PROGMEM cmd_range_period_action =
882 TOKEN_STRING_INITIALIZER(struct cmd_range_period_result, action,
884 const parse_token_num_t PROGMEM cmd_range_period_period =
885 TOKEN_NUM_INITIALIZER(struct cmd_range_period_result, period, UINT32);
887 const char PROGMEM help_range_period[] = "set range test period";
889 const parse_inst_t PROGMEM cmd_range_period = {
890 .f = cmd_range_period_parsed, /* function to call */
891 .data = NULL, /* 2nd arg of func */
892 .help_str = help_range_period,
893 .tokens = { /* token list, NULL terminated */
894 (PGM_P)&cmd_range_period_range_period,
895 (PGM_P)&cmd_range_period_action,
896 (PGM_P)&cmd_range_period_period,
903 /* this structure is filled when cmd_range_count is parsed successfully */
904 struct cmd_range_count_result {
905 fixed_string_t range;
906 fixed_string_t action;
910 /* function called when cmd_range_count is parsed successfully */
911 static void cmd_range_count_parsed(void *parsed_result, void *data)
913 struct cmd_range_count_result *res = parsed_result;
916 range_count = res->count;
919 const char PROGMEM str_count[] = "count";
921 const parse_token_string_t PROGMEM cmd_range_count_range_count =
922 TOKEN_STRING_INITIALIZER(struct cmd_range_count_result, range,
924 const parse_token_string_t PROGMEM cmd_range_count_action =
925 TOKEN_STRING_INITIALIZER(struct cmd_range_count_result, action,
927 const parse_token_num_t PROGMEM cmd_range_count_count =
928 TOKEN_NUM_INITIALIZER(struct cmd_range_count_result, count, UINT32);
931 const char PROGMEM help_range_count[] = "set range test count";
933 const parse_inst_t PROGMEM cmd_range_count = {
934 .f = cmd_range_count_parsed, /* function to call */
935 .data = NULL, /* 2nd arg of func */
936 .help_str = help_range_count,
937 .tokens = { /* token list, NULL terminated */
938 (PGM_P)&cmd_range_count_range_count,
939 (PGM_P)&cmd_range_count_action,
940 (PGM_P)&cmd_range_count_count,
947 /* this structure is filled when cmd_range_powermask is parsed successfully */
948 struct cmd_range_powermask_result {
949 fixed_string_t range;
950 fixed_string_t action;
954 /* function called when cmd_range_powermask is parsed successfully */
955 static void cmd_range_powermask_parsed(void *parsed_result, void *data)
957 struct cmd_range_powermask_result *res = parsed_result;
960 range_powermask = res->powermask;
963 const char PROGMEM str_powermask[] = "powermask";
965 const parse_token_string_t PROGMEM cmd_range_powermask_range_powermask =
966 TOKEN_STRING_INITIALIZER(struct cmd_range_powermask_result, range,
968 const parse_token_string_t PROGMEM cmd_range_powermask_action =
969 TOKEN_STRING_INITIALIZER(struct cmd_range_powermask_result, action,
971 const parse_token_num_t PROGMEM cmd_range_powermask_powermask =
972 TOKEN_NUM_INITIALIZER(struct cmd_range_powermask_result, powermask,
976 const char PROGMEM help_range_powermask[] = "set range test powermask";
978 const parse_inst_t PROGMEM cmd_range_powermask = {
979 .f = cmd_range_powermask_parsed, /* function to call */
980 .data = NULL, /* 2nd arg of func */
981 .help_str = help_range_powermask,
982 .tokens = { /* token list, NULL terminated */
983 (PGM_P)&cmd_range_powermask_range_powermask,
984 (PGM_P)&cmd_range_powermask_action,
985 (PGM_P)&cmd_range_powermask_powermask,
992 /* this structure is filled when cmd_range_dstaddr is parsed successfully */
993 struct cmd_range_dstaddr_result {
994 fixed_string_t range;
995 fixed_string_t action;
999 /* function called when cmd_range_dstaddr is parsed successfully */
1000 static void cmd_range_dstaddr_parsed(void *parsed_result, void *data)
1002 struct cmd_range_dstaddr_result *res = parsed_result;
1005 range_dstaddr = res->dstaddr;
1008 const char PROGMEM str_dstaddr[] = "dstaddr";
1010 const parse_token_string_t PROGMEM cmd_range_dstaddr_range_dstaddr =
1011 TOKEN_STRING_INITIALIZER(struct cmd_range_dstaddr_result, range,
1013 const parse_token_string_t PROGMEM cmd_range_dstaddr_action =
1014 TOKEN_STRING_INITIALIZER(struct cmd_range_dstaddr_result, action,
1016 const parse_token_num_t PROGMEM cmd_range_dstaddr_dstaddr =
1017 TOKEN_NUM_INITIALIZER(struct cmd_range_dstaddr_result, dstaddr, UINT64);
1020 const char PROGMEM help_range_dstaddr[] = "set register rangeing dstaddr";
1022 const parse_inst_t PROGMEM cmd_range_dstaddr = {
1023 .f = cmd_range_dstaddr_parsed, /* function to call */
1024 .data = NULL, /* 2nd arg of func */
1025 .help_str = help_range_dstaddr,
1026 .tokens = { /* token list, NULL terminated */
1027 (PGM_P)&cmd_range_dstaddr_range_dstaddr,
1028 (PGM_P)&cmd_range_dstaddr_action,
1029 (PGM_P)&cmd_range_dstaddr_dstaddr,
1037 /* this structure is filled when cmd_monitor is parsed successfully */
1038 struct cmd_monitor_result {
1039 fixed_string_t monitor;
1040 fixed_string_t action;
1043 /* function called when cmd_monitor is parsed successfully */
1044 static void cmd_monitor_parsed(void *parsed_result, void *data)
1046 struct cmd_monitor_result *res = parsed_result;
1047 struct monitor_reg *m;
1050 if (!strcmp_P(res->action, PSTR("show"))) {
1051 printf_P(PSTR("monitor period is %d ms, %d regs in list\r\n"),
1052 monitor_period_ms, monitor_count);
1053 LIST_FOREACH(m, &xbee_monitor_list, next)
1054 printf_P(PSTR(" %S\r\n"), m->desc);
1056 else if (!strcmp_P(res->action, PSTR("start"))) {
1057 if (monitor_running) {
1058 printf_P(PSTR("already running\r\n"));
1061 if (monitor_count == 0) {
1062 printf_P(PSTR("no regs to be monitored\r\n"));
1065 callout_init(&monitor_event, monitor_cb, NULL, 1);
1066 monitor_running = 1;
1067 monitor_current = LIST_FIRST(&xbee_monitor_list);
1068 callout_schedule(&xbeeboard.intr_cm,
1069 &monitor_event, 0); /* immediate */
1070 printf_P(PSTR("monitor cb: %S %s\r\n"),
1071 monitor_current->desc,
1072 monitor_current->atcmd);
1075 else if (!strcmp_P(res->action, PSTR("end"))) {
1076 if (monitor_running == 0) {
1077 printf_P(PSTR("not running\r\n"));
1080 callout_stop(&xbeeboard.intr_cm, &monitor_event);
1081 monitor_running = 0;
1085 const char PROGMEM str_monitor[] = "monitor";
1086 const char PROGMEM str_monitor_tokens[] = "show#start#end";
1088 const parse_token_string_t PROGMEM cmd_monitor_monitor =
1089 TOKEN_STRING_INITIALIZER(struct cmd_monitor_result, monitor,
1091 const parse_token_string_t PROGMEM cmd_monitor_action =
1092 TOKEN_STRING_INITIALIZER(struct cmd_monitor_result, action,
1093 str_monitor_tokens);
1095 const char PROGMEM help_monitor[] = "start/stop/show current monitoring";
1097 const parse_inst_t PROGMEM cmd_monitor = {
1098 .f = cmd_monitor_parsed, /* function to call */
1099 .data = NULL, /* 2nd arg of func */
1100 .help_str = help_monitor,
1101 .tokens = { /* token list, NULL terminated */
1102 (PGM_P)&cmd_monitor_monitor,
1103 (PGM_P)&cmd_monitor_action,
1110 /* this structure is filled when cmd_monitor_add is parsed successfully */
1111 struct cmd_monitor_add_result {
1112 fixed_string_t monitor;
1113 fixed_string_t action;
1114 struct xbee_atcmd *cmd;
1117 /* function called when cmd_monitor_add is parsed successfully */
1118 static void cmd_monitor_add_parsed(void *parsed_result, void *data)
1120 struct cmd_monitor_add_result *res = parsed_result;
1121 struct monitor_reg *m;
1122 struct xbee_atcmd copy;
1125 memcpy_P(©, res->cmd, sizeof(copy));
1126 LIST_FOREACH(m, &xbee_monitor_list, next) {
1127 if (!strcmp_P(m->atcmd, copy.name))
1132 printf_P(PSTR("already exist\r\n"));
1136 m = malloc(sizeof(*m));
1138 printf_P(PSTR("no mem\r\n"));
1141 m->desc = copy.desc;
1142 strcpy_P(m->atcmd, copy.name);
1143 LIST_INSERT_HEAD(&xbee_monitor_list, m, next);
1147 const char PROGMEM str_monitor_add[] = "add";
1149 const parse_token_string_t PROGMEM cmd_monitor_add_monitor_add =
1150 TOKEN_STRING_INITIALIZER(struct cmd_monitor_add_result, monitor,
1152 const parse_token_string_t PROGMEM cmd_monitor_add_action =
1153 TOKEN_STRING_INITIALIZER(struct cmd_monitor_add_result, action,
1155 const parse_token_atcmd_t PROGMEM cmd_monitor_add_atcmd =
1156 TOKEN_ATCMD_INITIALIZER(struct cmd_monitor_add_result, cmd, &xbee_dev,
1157 XBEE_ATCMD_F_READ, XBEE_ATCMD_F_READ);
1160 const char PROGMEM help_monitor_add[] = "add a register in monitor list";
1162 const parse_inst_t PROGMEM cmd_monitor_add = {
1163 .f = cmd_monitor_add_parsed, /* function to call */
1164 .data = NULL, /* 2nd arg of func */
1165 .help_str = help_monitor_add,
1166 .tokens = { /* token list, NULL terminated */
1167 (PGM_P)&cmd_monitor_add_monitor_add,
1168 (PGM_P)&cmd_monitor_add_action,
1169 (PGM_P)&cmd_monitor_add_atcmd,
1176 /* this structure is filled when cmd_monitor_period is parsed successfully */
1177 struct cmd_monitor_period_result {
1178 fixed_string_t monitor;
1179 fixed_string_t action;
1183 /* function called when cmd_monitor_period is parsed successfully */
1184 static void cmd_monitor_period_parsed(void *parsed_result, void *data)
1186 struct cmd_monitor_period_result *res = parsed_result;
1189 if (res->period < 100) {
1190 printf_P(PSTR("error, minimum period is 100 ms\r\n"));
1194 monitor_period_ms = res->period;
1197 const char PROGMEM str_monitor_period[] = "period";
1199 const parse_token_string_t PROGMEM cmd_monitor_period_monitor_period =
1200 TOKEN_STRING_INITIALIZER(struct cmd_monitor_period_result, monitor,
1202 const parse_token_string_t PROGMEM cmd_monitor_period_action =
1203 TOKEN_STRING_INITIALIZER(struct cmd_monitor_period_result, action,
1204 str_monitor_period);
1205 const parse_token_num_t PROGMEM cmd_monitor_period_period =
1206 TOKEN_NUM_INITIALIZER(struct cmd_monitor_period_result, period, UINT32);
1209 const char PROGMEM help_monitor_period[] = "set register monitoring period";
1211 const parse_inst_t PROGMEM cmd_monitor_period = {
1212 .f = cmd_monitor_period_parsed, /* function to call */
1213 .data = NULL, /* 2nd arg of func */
1214 .help_str = help_monitor_period,
1215 .tokens = { /* token list, NULL terminated */
1216 (PGM_P)&cmd_monitor_period_monitor_period,
1217 (PGM_P)&cmd_monitor_period_action,
1218 (PGM_P)&cmd_monitor_period_period,
1225 /* this structure is filled when cmd_monitor_del is parsed successfully */
1226 struct cmd_monitor_del_result {
1227 fixed_string_t monitor;
1228 fixed_string_t action;
1229 struct monitor_reg *m;
1232 /* function called when cmd_monitor_del is parsed successfully */
1233 static void cmd_monitor_del_parsed(void *parsed_result, void *data)
1235 struct cmd_monitor_del_result *res = parsed_result;
1238 monitor_current = LIST_NEXT(res->m, next);
1239 LIST_REMOVE(res->m, next);
1242 if (monitor_count == 0) {
1243 printf_P(PSTR("Disable monitoring, no more event\r\n"));
1244 callout_stop(&xbeeboard.intr_cm, &monitor_event);
1245 monitor_running = 0;
1250 const char PROGMEM str_monitor_del[] = "del";
1252 const parse_token_string_t PROGMEM cmd_monitor_del_monitor_del =
1253 TOKEN_STRING_INITIALIZER(struct cmd_monitor_del_result, monitor,
1255 const parse_token_string_t PROGMEM cmd_monitor_del_action =
1256 TOKEN_STRING_INITIALIZER(struct cmd_monitor_del_result, action,
1258 const parse_token_monitor_t PROGMEM cmd_monitor_del_atcmd =
1259 TOKEN_MONITOR_INITIALIZER(struct cmd_monitor_del_result, m);
1262 const char PROGMEM help_monitor_del[] = "del a register in monitor list";
1264 const parse_inst_t PROGMEM cmd_monitor_del = {
1265 .f = cmd_monitor_del_parsed, /* function to call */
1266 .data = NULL, /* 2nd arg of func */
1267 .help_str = help_monitor_del,
1268 .tokens = { /* token list, NULL terminated */
1269 (PGM_P)&cmd_monitor_del_monitor_del,
1270 (PGM_P)&cmd_monitor_del_action,
1271 (PGM_P)&cmd_monitor_del_atcmd,
1279 /* this structure is filled when cmd_ping is parsed successfully */
1280 struct cmd_ping_result {
1281 fixed_string_t ping;
1284 /* function called when cmd_ping is parsed successfully */
1285 static void cmd_ping_parsed(void *parsed_result, void *data)
1287 volatile uint8_t done = 0;
1289 (void)parsed_result;
1291 xbeeapp_send_atcmd("VL", NULL, 0, dump_xbee_atresp_cb, (void *)&done);
1295 const char PROGMEM str_ping[] = "ping";
1297 const parse_token_string_t PROGMEM cmd_ping_ping =
1298 TOKEN_STRING_INITIALIZER(struct cmd_ping_result, ping,
1301 const char PROGMEM help_ping[] = "Send a ping to the xbee device";
1303 const parse_inst_t PROGMEM cmd_ping = {
1304 .f = cmd_ping_parsed, /* function to call */
1305 .data = NULL, /* 2nd arg of func */
1306 .help_str = help_ping,
1307 .tokens = { /* token list, NULL terminated */
1308 (PGM_P)&cmd_ping_ping,
1315 /* this structure is filled when cmd_raw is parsed successfully */
1316 struct cmd_raw_result {
1320 /* function called when cmd_raw is parsed successfully */
1321 static void cmd_raw_parsed(void *parsed_result, void *data)
1323 (void)parsed_result;
1326 if (range_running || monitor_running) {
1327 printf_P(PSTR("stop running range or monitor first\r\n"));
1330 printf_P(PSTR("switched to raw mode, CTRL-D to exit\r\n"));
1331 rdline_stop(&xbeeboard.rdl); /* don't display prompt when return */
1335 const char PROGMEM str_raw[] = "raw";
1337 const parse_token_string_t PROGMEM cmd_raw_raw =
1338 TOKEN_STRING_INITIALIZER(struct cmd_raw_result, raw,
1341 const char PROGMEM help_raw[] = "Switch to raw mode";
1343 const parse_inst_t PROGMEM cmd_raw = {
1344 .f = cmd_raw_parsed, /* function to call */
1345 .data = NULL, /* 2nd arg of func */
1346 .help_str = help_raw,
1347 .tokens = { /* token list, NULL terminated */
1348 (PGM_P)&cmd_raw_raw,
1353 /**********************************************************/
1355 /* this structure is filled when cmd_baudrate is parsed successfully */
1356 struct cmd_baudrate_result {
1357 fixed_string_t arg0;
1361 /* function called when cmd_baudrate is parsed successfully */
1362 static void cmd_baudrate_parsed(void * parsed_result, __attribute__((unused)) void *data)
1364 struct cmd_baudrate_result *res = parsed_result;
1365 struct uart_config c;
1367 uart_getconf(XBEE_UART, &c);
1368 c.baudrate = res->arg1;
1369 uart_setconf(XBEE_UART, &c);
1372 const char PROGMEM str_baudrate_arg0[] = "baudrate";
1373 const parse_token_string_t PROGMEM cmd_baudrate_arg0 =
1374 TOKEN_STRING_INITIALIZER(struct cmd_baudrate_result, arg0,
1376 const parse_token_num_t PROGMEM cmd_baudrate_arg1 =
1377 TOKEN_NUM_INITIALIZER(struct cmd_baudrate_result, arg1,
1380 const char PROGMEM help_baudrate[] = "Change xbee baudrate";
1381 const parse_inst_t PROGMEM cmd_baudrate = {
1382 .f = cmd_baudrate_parsed, /* function to call */
1383 .data = NULL, /* 2nd arg of func */
1384 .help_str = help_baudrate,
1385 .tokens = { /* token list, NULL terminated */
1386 (PGM_P)&cmd_baudrate_arg0,
1387 (PGM_P)&cmd_baudrate_arg1,
1393 /**********************************************************/
1395 /* this structure is filled when cmd_beep is parsed successfully */
1396 struct cmd_beep_result {
1397 fixed_string_t beep;
1400 /* function called when cmd_beep is parsed successfully */
1401 static void cmd_beep_parsed(void *parsed_result, void *data)
1403 (void)parsed_result;
1414 const char PROGMEM str_beep[] = "beep";
1415 const parse_token_string_t PROGMEM cmd_beep_beep =
1416 TOKEN_STRING_INITIALIZER(struct cmd_beep_result, beep,
1419 const char PROGMEM help_beep[] = "Send a beep";
1421 const parse_inst_t PROGMEM cmd_beep = {
1422 .f = cmd_beep_parsed, /* function to call */
1423 .data = NULL, /* 2nd arg of func */
1424 .help_str = help_beep,
1425 .tokens = { /* token list, NULL terminated */
1426 (PGM_P)&cmd_beep_beep,
1431 /**********************************************************/
1433 /* this structure is filled when cmd_servo is parsed successfully */
1434 struct cmd_servo_result {
1435 fixed_string_t arg0;
1436 fixed_string_t arg1;
1441 /* function called when cmd_servo is parsed successfully */
1442 static void cmd_servo_parsed(void * parsed_result, void *data)
1444 struct cmd_servo_result *res = parsed_result;
1448 if (!strcmp_P(res->arg1, PSTR("set"))) {
1449 if (res->num >= N_SERVO) {
1450 printf_P(PSTR("bad servo num\n"));
1453 if (res->val >= 1024) {
1454 printf_P(PSTR("bad servo val\n"));
1457 spi_servo_set(res->num, res->val);
1459 else if (!strcmp_P(res->arg1, PSTR("bypass"))) {
1460 spi_servo_set_bypass(!!res->val);
1462 else if (!strcmp_P(res->arg1, PSTR("ppm"))) {
1463 spi_servo_set_ppm(!!res->val);
1465 else if (!strcmp_P(res->arg1, PSTR("show"))) {
1470 const char PROGMEM str_servo_arg0[] = "servo";
1471 const parse_token_string_t PROGMEM cmd_servo_arg0 =
1472 TOKEN_STRING_INITIALIZER(struct cmd_servo_result, arg0,
1474 const char PROGMEM str_servo_arg1_set[] = "set";
1475 const parse_token_string_t PROGMEM cmd_servo_arg1_set =
1476 TOKEN_STRING_INITIALIZER(struct cmd_servo_result, arg1,
1477 str_servo_arg1_set);
1478 const parse_token_num_t PROGMEM cmd_servo_num =
1479 TOKEN_NUM_INITIALIZER(struct cmd_servo_result, num,
1481 const parse_token_num_t PROGMEM cmd_servo_val =
1482 TOKEN_NUM_INITIALIZER(struct cmd_servo_result, val,
1485 const char PROGMEM help_servo_set[] = "set servo value";
1486 const parse_inst_t PROGMEM cmd_servo_set = {
1487 .f = cmd_servo_parsed, /* function to call */
1488 .data = NULL, /* 2nd arg of func */
1489 .help_str = help_servo_set,
1490 .tokens = { /* token list, NULL terminated */
1491 (PGM_P)&cmd_servo_arg0,
1492 (PGM_P)&cmd_servo_arg1_set,
1493 (PGM_P)&cmd_servo_num,
1494 (PGM_P)&cmd_servo_val,
1499 const char PROGMEM str_servo_arg1_show[] = "show";
1500 const parse_token_string_t PROGMEM cmd_servo_arg1_show =
1501 TOKEN_STRING_INITIALIZER(struct cmd_servo_result, arg1,
1502 str_servo_arg1_show);
1504 const char PROGMEM help_servo_show[] = "read servo and config";
1505 const parse_inst_t PROGMEM cmd_servo_show = {
1506 .f = cmd_servo_parsed, /* function to call */
1507 .data = NULL, /* 2nd arg of func */
1508 .help_str = help_servo_show,
1509 .tokens = { /* token list, NULL terminated */
1510 (PGM_P)&cmd_servo_arg0,
1511 (PGM_P)&cmd_servo_arg1_show,
1516 const char PROGMEM str_servo_arg1_bypassppm[] = "bypass#ppm";
1517 const parse_token_string_t PROGMEM cmd_servo_arg1_bypassppm =
1518 TOKEN_STRING_INITIALIZER(struct cmd_servo_result, arg1,
1519 str_servo_arg1_bypassppm);
1521 const char PROGMEM help_servo_bypassppm[] = "change bypass/ppm";
1522 const parse_inst_t PROGMEM cmd_servo_bypassppm = {
1523 .f = cmd_servo_parsed, /* function to call */
1524 .data = NULL, /* 2nd arg of func */
1525 .help_str = help_servo_bypassppm,
1526 .tokens = { /* token list, NULL terminated */
1527 (PGM_P)&cmd_servo_arg0,
1528 (PGM_P)&cmd_servo_arg1_bypassppm,
1529 (PGM_P)&cmd_servo_val,
1534 /**********************************************************/
1536 /* this structure is filled when cmd_test_spi is parsed successfully */
1537 struct cmd_test_spi_result {
1538 fixed_string_t arg0;
1541 static void cmd_test_spi_parsed(void * parsed_result, void *data)
1543 uint8_t i, flags, wait_time = 0;
1546 (void)parsed_result;
1549 spi_servo_set_bypass(0);
1550 spi_servo_set_ppm(0);
1552 /* stress test: send many commands, no wait between each servo
1553 * of a series, and a variable delay between series */
1554 printf_P(PSTR("stress test\r\n"));
1555 while (!cmdline_keypressed()) {
1567 for (i = 0; i < 6; i++)
1568 spi_servo_set(i, val);
1571 printf_P(PSTR("%4.4d %4.4d %4.4d %4.4d %4.4d %4.4d\r\n"),
1572 spi_servo_get(0), spi_servo_get(1), spi_servo_get(2),
1573 spi_servo_get(3), spi_servo_get(4), spi_servo_get(5));
1576 printf_P(PSTR("bypass mode, with spi commands in background\r\n"));
1577 spi_servo_set_bypass(1);
1579 /* test bypass mode */
1580 while (!cmdline_keypressed()) {
1592 for (i = 0; i < 6; i++)
1593 spi_servo_set(i, val);
1596 printf_P(PSTR("%4.4d %4.4d %4.4d %4.4d %4.4d %4.4d\r\n"),
1597 spi_servo_get(0), spi_servo_get(1), spi_servo_get(2),
1598 spi_servo_get(3), spi_servo_get(4), spi_servo_get(5));
1601 printf_P(PSTR("PPM to servo\r\n"));
1602 spi_servo_set_bypass(0);
1603 spi_servo_set_ppm(0);
1605 /* test PPM to servo (bypass) mode */
1606 while (!cmdline_keypressed()) {
1607 for (i = 0; i < 6; i++) {
1608 val = spi_servo_get(i);
1609 spi_servo_set(i, val);
1613 printf_P(PSTR("PPM to (servo + PPM)\r\n"));
1614 spi_servo_set_bypass(0);
1615 spi_servo_set_ppm(1);
1617 /* test PPM to servo (bypass) mode */
1618 while (!cmdline_keypressed()) {
1619 for (i = 0; i < 6; i++) {
1620 val = spi_servo_get(i);
1621 spi_servo_set(i, val);
1626 const char PROGMEM str_test_spi_arg0[] = "test_spi";
1627 const parse_token_string_t PROGMEM cmd_test_spi_arg0 =
1628 TOKEN_STRING_INITIALIZER(struct cmd_test_spi_result, arg0,
1631 const char PROGMEM help_test_spi[] = "Test the spi";
1632 const parse_inst_t PROGMEM cmd_test_spi = {
1633 .f = cmd_test_spi_parsed, /* function to call */
1634 .data = NULL, /* 2nd arg of func */
1635 .help_str = help_test_spi,
1636 .tokens = { /* token list, NULL terminated */
1637 (PGM_P)&cmd_test_spi_arg0,
1642 /**********************************************************/
1644 /* this structure is filled when cmd_dump_xbee_stats is parsed successfully */
1645 struct cmd_dump_xbee_stats_result {
1646 fixed_string_t arg0;
1649 static void cmd_dump_xbee_stats_parsed(void *parsed_result, void *data)
1651 (void)parsed_result;
1654 xbee_dump_stats(xbee_dev);
1657 const char PROGMEM str_dump_xbee_stats_arg0[] = "dump_xbee_stats";
1658 const parse_token_string_t PROGMEM cmd_dump_xbee_stats_arg0 =
1659 TOKEN_STRING_INITIALIZER(struct cmd_dump_xbee_stats_result, arg0,
1660 str_dump_xbee_stats_arg0);
1662 const char PROGMEM help_dump_xbee_stats[] = "Test the spi";
1663 const parse_inst_t PROGMEM cmd_dump_xbee_stats = {
1664 .f = cmd_dump_xbee_stats_parsed, /* function to call */
1665 .data = NULL, /* 2nd arg of func */
1666 .help_str = help_dump_xbee_stats,
1667 .tokens = { /* token list, NULL terminated */
1668 (PGM_P)&cmd_dump_xbee_stats_arg0,
1673 /**********************************************************/
1675 /* this structure is filled when cmd_test_eeprom_config is parsed successfully */
1676 struct cmd_test_eeprom_config_result {
1677 fixed_string_t arg0;
1680 static void cmd_test_eeprom_config_parsed(void *parsed_result, void *data)
1682 (void)parsed_result;
1686 eeprom_append_cmd("salut1\n");
1688 eeprom_append_cmd("salut2\n");
1689 eeprom_append_cmd("salut3\n");
1690 eeprom_append_cmd("salut4\n");
1692 eeprom_insert_cmd_before("coin\n", 0);
1693 eeprom_insert_cmd_before("coin2\n", 2);
1695 eeprom_delete_cmd(2);
1696 eeprom_delete_cmd(0);
1700 const char PROGMEM str_test_eeprom_config_arg0[] = "test_eeprom_config";
1701 const parse_token_string_t PROGMEM cmd_test_eeprom_config_arg0 =
1702 TOKEN_STRING_INITIALIZER(struct cmd_test_eeprom_config_result, arg0,
1703 str_test_eeprom_config_arg0);
1705 const char PROGMEM help_test_eeprom_config[] = "Test the eeprom configuration";
1706 const parse_inst_t PROGMEM cmd_test_eeprom_config = {
1707 .f = cmd_test_eeprom_config_parsed, /* function to call */
1708 .data = NULL, /* 2nd arg of func */
1709 .help_str = help_test_eeprom_config,
1710 .tokens = { /* token list, NULL terminated */
1711 (PGM_P)&cmd_test_eeprom_config_arg0,
1718 struct cmd_eeprom_del_result {
1720 fixed_string_t action;
1724 static void cmd_eeprom_del_parsed(void *parsed_result,
1727 struct cmd_eeprom_del_result *res = parsed_result;
1730 if (eeprom_delete_cmd(res->n) < 0)
1731 printf_P(PSTR("cannot delete command\n"));
1735 const char PROGMEM str_eeprom_del_eeprom[] = "eeprom";
1736 const parse_token_string_t PROGMEM cmd_eeprom_del_cmd =
1737 TOKEN_STRING_INITIALIZER(struct cmd_eeprom_del_result, cmd,
1738 str_eeprom_del_eeprom);
1739 const char PROGMEM str_eeprom_del_del[] = "del";
1740 const parse_token_string_t PROGMEM cmd_eeprom_del_action =
1741 TOKEN_STRING_INITIALIZER(struct cmd_eeprom_del_result, action,
1742 str_eeprom_del_del);
1743 const parse_token_num_t PROGMEM cmd_eeprom_del_num =
1744 TOKEN_NUM_INITIALIZER(struct cmd_eeprom_del_result, n,
1747 const char PROGMEM help_eeprom_del[] = "delete an eeprom init command";
1748 const parse_inst_t PROGMEM cmd_eeprom_del = {
1749 .f = cmd_eeprom_del_parsed, /* function to call */
1750 .data = NULL, /* 2nd arg of func */
1751 .help_str = help_eeprom_del,
1752 .tokens = { /* token list, NULL terminated */
1753 (PGM_P)&cmd_eeprom_del_cmd,
1754 (PGM_P)&cmd_eeprom_del_action,
1755 (PGM_P)&cmd_eeprom_del_num,
1762 struct cmd_eeprom_add_result {
1764 fixed_string_t action;
1768 static void cmd_eeprom_add_parsed(void *parsed_result,
1771 struct cmd_eeprom_add_result *res = parsed_result;
1777 rdline_init(&rdl, cmdline_write_char, NULL, NULL);
1778 rdline_newline(&rdl, "> ");
1780 /* XXX bad: we should not block as we do not serve callout */
1782 c = cmdline_dev_recv(NULL);
1786 ret = rdline_char_in(&rdl, c);
1788 printf_P(PSTR("abort\n"));
1795 buffer = rdline_get_buffer(&rdl);
1797 eeprom_insert_cmd_before(buffer, res->n);
1799 eeprom_append_cmd(buffer);
1803 const char PROGMEM str_eeprom_add_eeprom[] = "eeprom";
1804 const parse_token_string_t PROGMEM cmd_eeprom_add_cmd =
1805 TOKEN_STRING_INITIALIZER(struct cmd_eeprom_add_result, cmd,
1806 str_eeprom_add_eeprom);
1807 const char PROGMEM str_eeprom_add_add[] = "add";
1808 const parse_token_string_t PROGMEM cmd_eeprom_add_action =
1809 TOKEN_STRING_INITIALIZER(struct cmd_eeprom_add_result, action,
1810 str_eeprom_add_add);
1811 const parse_token_num_t PROGMEM cmd_eeprom_add_num =
1812 TOKEN_NUM_INITIALIZER(struct cmd_eeprom_add_result, n,
1815 const char PROGMEM help_eeprom_add[] = "insert an eeprom init command";
1816 const parse_inst_t PROGMEM cmd_eeprom_add = {
1817 .f = cmd_eeprom_add_parsed, /* function to call */
1818 .data = NULL, /* 2nd arg of func */
1819 .help_str = help_eeprom_add,
1820 .tokens = { /* token list, NULL terminated */
1821 (PGM_P)&cmd_eeprom_add_cmd,
1822 (PGM_P)&cmd_eeprom_add_action,
1823 (PGM_P)&cmd_eeprom_add_num,
1828 const char PROGMEM help_eeprom_add2[] = "append an eeprom init command";
1829 const parse_inst_t PROGMEM cmd_eeprom_add2 = {
1830 .f = cmd_eeprom_add_parsed, /* function to call */
1831 .data = (void *)1, /* 2nd arg of func */
1832 .help_str = help_eeprom_add2,
1833 .tokens = { /* token list, NULL terminated */
1834 (PGM_P)&cmd_eeprom_add_cmd,
1835 (PGM_P)&cmd_eeprom_add_action,
1842 struct cmd_eeprom_list_result {
1844 fixed_string_t action;
1847 static void cmd_eeprom_list_parsed(void *parsed_result,
1850 (void)parsed_result;
1855 const char PROGMEM str_eeprom_list_eeprom[] = "eeprom";
1856 const parse_token_string_t PROGMEM cmd_eeprom_list_cmd =
1857 TOKEN_STRING_INITIALIZER(struct cmd_eeprom_list_result, cmd,
1858 str_eeprom_list_eeprom);
1859 const char PROGMEM str_eeprom_list_list[] = "list";
1860 const parse_token_string_t PROGMEM cmd_eeprom_list_action =
1861 TOKEN_STRING_INITIALIZER(struct cmd_eeprom_list_result, action,
1862 str_eeprom_list_list);
1864 const char PROGMEM help_eeprom_list[] = "list all eeprom init commands";
1865 const parse_inst_t PROGMEM cmd_eeprom_list = {
1866 .f = cmd_eeprom_list_parsed, /* function to call */
1867 .data = NULL, /* 2nd arg of func */
1868 .help_str = help_eeprom_list,
1869 .tokens = { /* token list, NULL terminated */
1870 (PGM_P)&cmd_eeprom_list_cmd,
1871 (PGM_P)&cmd_eeprom_list_action,
1880 const parse_ctx_t PROGMEM main_ctx[] = {
1882 /* commands_gen.c */
1901 &cmd_send_hello_name,
1906 &cmd_range_powermask,
1909 &cmd_monitor_period,
1917 &cmd_servo_bypassppm,
1920 &cmd_dump_xbee_stats,
1921 &cmd_test_eeprom_config,