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>
39 #include "xbee_atcmd.h"
40 #include "xbee_neighbor.h"
41 #include "xbee_stats.h"
42 #include "xbee_proto.h"
46 #include "parse_atcmd.h"
47 #include "parse_neighbor.h"
48 #include "parse_monitor.h"
50 #include "spi_servo.h"
56 extern const parse_inst_t PROGMEM cmd_reset;
57 extern const parse_inst_t PROGMEM cmd_bootloader;
58 extern const parse_inst_t PROGMEM cmd_log;
59 extern const parse_inst_t PROGMEM cmd_log_show;
60 extern const parse_inst_t PROGMEM cmd_log_type;
61 extern const parse_inst_t PROGMEM cmd_stack_space;
62 extern const parse_inst_t PROGMEM cmd_scheduler;
64 static int monitor_period_ms = 1000;
65 static int monitor_running = 0;
66 static int monitor_count = 0;
67 static struct callout monitor_event;
68 struct monitor_reg *monitor_current;
70 static int range_period_ms = 1000;
71 static int range_powermask = 0x1F;
72 static uint8_t range_power = 0;
73 static int range_running = 0;
74 static uint64_t range_dstaddr = 0xFFFF; /* broadcast by default */
75 static struct callout range_event;
76 static int range_count = 100;
77 static int range_cur_count = 0;
79 static void monitor_cb(struct callout_manager *cm,
80 struct callout *clt, void *dummy)
85 if (monitor_current == NULL)
86 monitor_current = LIST_FIRST(&xbee_monitor_list);
88 xbeeapp_send_atcmd(monitor_current->atcmd, NULL, 0, 0, NULL, NULL);
89 monitor_current = LIST_NEXT(monitor_current, next);
90 callout_reset(cm, &monitor_event,
91 monitor_period_ms / monitor_count,
92 SINGLE, monitor_cb, NULL);
95 static void range_cb(struct callout_manager *cm,
96 struct callout *clt, void *dummy)
99 struct rc_proto_range rangepkt;
106 /* get new xmit power */
107 for (i = 1; i <= 8; i++) {
108 mask = 1 << ((range_power + i) & 0x7);
109 if (mask & range_powermask)
112 range_power = ((range_power + i) & 0x7);
114 xbeeapp_send_atcmd("PL", &range_power, sizeof(range_power), 0, NULL, NULL);
116 rangepkt.type = RC_PROTO_TYPE_RANGE;
117 rangepkt.power_level = range_power;
119 xbeeapp_send_msg(range_dstaddr, &rangepkt, sizeof(rangepkt), 0);
121 if (range_cur_count == 0) {
126 callout_reset(cm, &range_event,
128 SINGLE, range_cb, NULL);
131 /* this structure is filled when cmd_help is parsed successfully */
132 struct cmd_help_result {
134 struct xbee_atcmd *cmd;
137 /* function called when cmd_help is parsed successfully */
138 static void cmd_help_parsed(void *parsed_result, void *data)
140 struct cmd_help_result *res = parsed_result;
141 struct xbee_atcmd cmdcopy;
146 memcpy_P(&cmdcopy, res->cmd, sizeof(cmdcopy));
147 type = (cmdcopy.flags & (XBEE_ATCMD_F_READ | XBEE_ATCMD_F_WRITE));
149 case XBEE_ATCMD_F_READ:
150 printf_P(PSTR("Read-only\r\n"));
152 case XBEE_ATCMD_F_WRITE:
153 printf_P(PSTR("Write-only\r\n"));
156 printf_P(PSTR("Read-write\r\n"));
159 if (cmdcopy.flags & XBEE_ATCMD_F_PARAM_NONE)
160 printf_P(PSTR("No argument\r\n"));
161 else if (cmdcopy.flags & XBEE_ATCMD_F_PARAM_U8)
162 printf_P(PSTR("Register is unsigned 8 bits\r\n"));
163 else if (cmdcopy.flags & XBEE_ATCMD_F_PARAM_U16)
164 printf_P(PSTR("Register is unsigned 16 bits\r\n"));
165 else if (cmdcopy.flags & XBEE_ATCMD_F_PARAM_U32)
166 printf_P(PSTR("Register is unsigned 32 bits\r\n"));
167 else if (cmdcopy.flags & XBEE_ATCMD_F_PARAM_S16)
168 printf_P(PSTR("Register is signed 16 bits\r\n"));
169 else if (cmdcopy.flags & XBEE_ATCMD_F_PARAM_STRING_20B)
170 printf_P(PSTR("Register is a 20 bytes string\r\n"));
172 printf_P(PSTR("Unknown argument\r\n"));
174 printf_P(PSTR("%S\r\n"), cmdcopy.help);
176 const char PROGMEM str_help_help[] = "help";
178 const parse_token_string_t PROGMEM cmd_help_help =
179 TOKEN_STRING_INITIALIZER(struct cmd_help_result, help, str_help_help);
181 const parse_token_atcmd_t PROGMEM cmd_help_atcmd =
182 TOKEN_ATCMD_INITIALIZER(struct cmd_help_result, cmd, &xbee_dev,
185 const char PROGMEM help_help[] = "Help a register using an AT command";
186 const parse_inst_t PROGMEM cmd_help = {
187 .f = cmd_help_parsed, /* function to call */
188 .data = NULL, /* 2nd arg of func */
189 .help_str = help_help,
190 .tokens = { /* token list, NULL terminated */
191 (PGM_P)&cmd_help_help,
192 (PGM_P)&cmd_help_atcmd,
199 struct cmd_neigh_del_result {
201 fixed_string_t action;
202 struct xbee_neigh *neigh;
205 static void cmd_neigh_del_parsed(void *parsed_result,
208 struct cmd_neigh_del_result *res = parsed_result;
211 xbee_neigh_del(xbee_dev, res->neigh);
214 const char PROGMEM str_neigh_del_neigh[] = "neigh";
215 const parse_token_string_t PROGMEM cmd_neigh_del_cmd =
216 TOKEN_STRING_INITIALIZER(struct cmd_neigh_del_result, cmd,
217 str_neigh_del_neigh);
218 const char PROGMEM str_neigh_del_del[] = "del";
219 const parse_token_string_t PROGMEM cmd_neigh_del_action =
220 TOKEN_STRING_INITIALIZER(struct cmd_neigh_del_result, action,
222 const parse_token_neighbor_t PROGMEM cmd_neigh_del_neigh =
223 TOKEN_NEIGHBOR_INITIALIZER(struct cmd_neigh_del_result, neigh,
226 const char PROGMEM help_neigh_del[] = "delete a neighbor";
227 const parse_inst_t PROGMEM cmd_neigh_del = {
228 .f = cmd_neigh_del_parsed, /* function to call */
229 .data = NULL, /* 2nd arg of func */
230 .help_str = help_neigh_del,
231 .tokens = { /* token list, NULL terminated */
232 (PGM_P)&cmd_neigh_del_cmd,
233 (PGM_P)&cmd_neigh_del_action,
234 (PGM_P)&cmd_neigh_del_neigh,
241 struct cmd_neigh_add_result {
243 fixed_string_t action;
248 static void cmd_neigh_add_parsed(void *parsed_result,
251 struct cmd_neigh_add_result *res = parsed_result;
254 if (xbee_neigh_add(xbee_dev, res->name, res->addr) == NULL)
255 printf_P(PSTR("name or addr already exist\r\n"));
258 const char PROGMEM str_neigh_add_neigh[] = "neigh";
259 const parse_token_string_t PROGMEM cmd_neigh_add_cmd =
260 TOKEN_STRING_INITIALIZER(struct cmd_neigh_add_result, cmd,
261 str_neigh_add_neigh);
262 const char PROGMEM str_neigh_add_add[] = "add";
263 const parse_token_string_t PROGMEM cmd_neigh_add_action =
264 TOKEN_STRING_INITIALIZER(struct cmd_neigh_add_result, action,
266 const parse_token_string_t PROGMEM cmd_neigh_add_name =
267 TOKEN_STRING_INITIALIZER(struct cmd_neigh_add_result, name, NULL);
268 const parse_token_num_t PROGMEM cmd_neigh_add_addr =
269 TOKEN_NUM_INITIALIZER(struct cmd_neigh_add_result, addr, UINT64);
271 const char PROGMEM help_neigh_add[] = "add a neighbor";
272 const parse_inst_t PROGMEM cmd_neigh_add = {
273 .f = cmd_neigh_add_parsed, /* function to call */
274 .data = NULL, /* 2nd arg of func */
275 .help_str = help_neigh_add,
276 .tokens = { /* token list, NULL terminated */
277 (PGM_P)&cmd_neigh_add_cmd,
278 (PGM_P)&cmd_neigh_add_action,
279 (PGM_P)&cmd_neigh_add_name,
280 (PGM_P)&cmd_neigh_add_addr,
287 struct cmd_neigh_list_result {
289 fixed_string_t action;
292 static void cmd_neigh_list_parsed(void *parsed_result,
295 struct xbee_neigh *neigh;
299 LIST_FOREACH(neigh, &xbee_dev->neigh_list, next) {
300 printf_P(PSTR(" %s: 0x%.8"PRIx32"%.8"PRIx32"\r\n"),
302 (uint32_t)(neigh->addr >> 32ULL),
303 (uint32_t)(neigh->addr & 0xFFFFFFFF));
307 const char PROGMEM str_neigh_list_neigh[] = "neigh";
308 const parse_token_string_t PROGMEM cmd_neigh_list_cmd =
309 TOKEN_STRING_INITIALIZER(struct cmd_neigh_list_result, cmd,
310 str_neigh_list_neigh);
311 const char PROGMEM str_neigh_list_list[] = "list";
312 const parse_token_string_t PROGMEM cmd_neigh_list_action =
313 TOKEN_STRING_INITIALIZER(struct cmd_neigh_list_result, action,
314 str_neigh_list_list);
316 const char PROGMEM help_neigh_list[] = "list all knwon neighbors";
317 const parse_inst_t PROGMEM cmd_neigh_list = {
318 .f = cmd_neigh_list_parsed, /* function to call */
319 .data = NULL, /* 2nd arg of func */
320 .help_str = help_neigh_list,
321 .tokens = { /* token list, NULL terminated */
322 (PGM_P)&cmd_neigh_list_cmd,
323 (PGM_P)&cmd_neigh_list_action,
333 /* this structure is filled when cmd_read is parsed successfully */
334 struct cmd_read_result {
336 struct xbee_atcmd *cmd;
339 /* function called when cmd_read is parsed successfully */
340 static void cmd_read_parsed(void *parsed_result,
343 struct cmd_read_result *res = parsed_result;
344 struct xbee_atcmd copy;
348 memcpy_P(©, res->cmd, sizeof(copy));
349 memcpy_P(&cmd, copy.name, 2);
351 xbeeapp_send_atcmd(cmd, NULL, 0, 1, NULL, NULL);
354 const char PROGMEM str_read_read[] = "read";
356 const parse_token_string_t PROGMEM cmd_read_read =
357 TOKEN_STRING_INITIALIZER(struct cmd_read_result, read,
360 const parse_token_atcmd_t PROGMEM cmd_read_atcmd =
361 TOKEN_ATCMD_INITIALIZER(struct cmd_read_result, cmd, &xbee_dev,
362 XBEE_ATCMD_F_READ, XBEE_ATCMD_F_READ);
364 const char PROGMEM help_read[] = "Read a register using an AT command";
365 const parse_inst_t PROGMEM cmd_read = {
366 .f = cmd_read_parsed, /* function to call */
367 .data = NULL, /* 2nd arg of func */
368 .help_str = help_read,
369 .tokens = { /* token list, NULL terminated */
370 (PGM_P)&cmd_read_read,
371 (PGM_P)&cmd_read_atcmd,
379 /* this structure is filled when cmd_write is parsed successfully */
380 struct cmd_write_result {
381 fixed_string_t write;
382 struct xbee_atcmd *cmd;
390 /* function called when cmd_write is parsed successfully */
391 static void cmd_write_parsed(void *parsed_result, void *data)
393 struct cmd_write_result *res = parsed_result;
394 struct xbee_atcmd copy;
400 memcpy_P(©, res->cmd, sizeof(copy));
402 if (copy.flags & XBEE_ATCMD_F_PARAM_NONE) {
406 else if (copy.flags & XBEE_ATCMD_F_PARAM_U8) {
407 len = sizeof(res->u8);
410 else if (copy.flags & XBEE_ATCMD_F_PARAM_U16) {
411 len = sizeof(res->u16);
412 res->u16 = htons(res->u16);
415 else if (copy.flags & XBEE_ATCMD_F_PARAM_U32) {
416 len = sizeof(res->u32);
417 res->u32 = htonl(res->u32);
421 printf_P(PSTR("Unknown argument type\r\n"));
424 memcpy_P(&cmd, copy.name, 2);
426 xbeeapp_send_atcmd(cmd, param, len, 1, NULL, NULL);
429 const char PROGMEM str_write_none[] = "write";
431 const parse_token_string_t PROGMEM cmd_write_write =
432 TOKEN_STRING_INITIALIZER(struct cmd_write_result, write,
435 const parse_token_atcmd_t PROGMEM cmd_write_none_atcmd =
436 TOKEN_ATCMD_INITIALIZER(struct cmd_write_result, cmd,
438 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_NONE,
439 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_NONE);
441 const char PROGMEM help_write_none[] = "Send an AT command (no argument)";
443 const parse_inst_t PROGMEM cmd_write_none = {
444 .f = cmd_write_parsed, /* function to call */
445 .data = NULL, /* 2nd arg of func */
446 .help_str = help_write_none,
447 .tokens = { /* token list, NULL terminated */
448 (PGM_P)&cmd_write_write,
449 (PGM_P)&cmd_write_none_atcmd,
454 const parse_token_atcmd_t PROGMEM cmd_write_u8_atcmd =
455 TOKEN_ATCMD_INITIALIZER(struct cmd_write_result, cmd,
457 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_U8,
458 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_U8);
460 const parse_token_num_t PROGMEM cmd_write_u8_u8 =
461 TOKEN_NUM_INITIALIZER(struct cmd_write_result, u8, UINT8);
463 const char PROGMEM help_write_u8[] = "Write a 8 bits register using an AT command";
465 const parse_inst_t PROGMEM cmd_write_u8 = {
466 .f = cmd_write_parsed, /* function to call */
467 .data = NULL, /* 2nd arg of func */
468 .help_str = help_write_u8,
469 .tokens = { /* token list, NULL terminated */
470 (PGM_P)&cmd_write_write,
471 (PGM_P)&cmd_write_u8_atcmd,
472 (PGM_P)&cmd_write_u8_u8,
477 const parse_token_atcmd_t PROGMEM cmd_write_u16_atcmd =
478 TOKEN_ATCMD_INITIALIZER(struct cmd_write_result, cmd,
480 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_U16,
481 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_U16);
483 const parse_token_num_t PROGMEM cmd_write_u16_u16 =
484 TOKEN_NUM_INITIALIZER(struct cmd_write_result, u16, UINT16);
486 const char PROGMEM help_write_u16[] = "Write a 16 bits register using an AT command";
488 const parse_inst_t PROGMEM cmd_write_u16 = {
489 .f = cmd_write_parsed, /* function to call */
490 .data = NULL, /* 2nd arg of func */
491 .help_str = help_write_u16,
492 .tokens = { /* token list, NULL terminated */
493 (PGM_P)&cmd_write_write,
494 (PGM_P)&cmd_write_u16_atcmd,
495 (PGM_P)&cmd_write_u16_u16,
500 const parse_token_atcmd_t PROGMEM cmd_write_u32_atcmd =
501 TOKEN_ATCMD_INITIALIZER(struct cmd_write_result, cmd,
503 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_U32,
504 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_U32);
506 const parse_token_num_t PROGMEM cmd_write_u32_u32 =
507 TOKEN_NUM_INITIALIZER(struct cmd_write_result, u32, UINT32);
509 const char PROGMEM help_write_u32[] = "Write a 32 bits register using an AT command";
511 const parse_inst_t PROGMEM cmd_write_u32 = {
512 .f = cmd_write_parsed, /* function to call */
513 .data = NULL, /* 2nd arg of func */
514 .help_str = help_write_u32,
515 .tokens = { /* token list, NULL terminated */
516 (PGM_P)&cmd_write_write,
517 (PGM_P)&cmd_write_u32_atcmd,
518 (PGM_P)&cmd_write_u32_u32,
526 /* this structure is filled when cmd_sendmsg is parsed successfully */
527 struct cmd_sendmsg_result {
528 fixed_string_t sendmsg;
533 /* function called when cmd_sendmsg is parsed successfully */
534 static void cmd_sendmsg_parsed(void *parsed_result, void *data)
536 struct cmd_sendmsg_result *res = parsed_result;
539 xbeeapp_send_msg(res->addr, res->data, strlen(res->data), 1);
542 const char PROGMEM str_sendmsg[] = "sendmsg";
544 const parse_token_string_t PROGMEM cmd_sendmsg_sendmsg =
545 TOKEN_STRING_INITIALIZER(struct cmd_sendmsg_result, sendmsg,
548 const parse_token_num_t PROGMEM cmd_sendmsg_addr =
549 TOKEN_NUM_INITIALIZER(struct cmd_sendmsg_result, addr, UINT64);
551 const parse_token_string_t PROGMEM cmd_sendmsg_data =
552 TOKEN_STRING_INITIALIZER(struct cmd_sendmsg_result, data, NULL);
554 const char PROGMEM help_sendmsg[] = "Send data to a node using its address";
556 const parse_inst_t PROGMEM cmd_sendmsg = {
557 .f = cmd_sendmsg_parsed, /* function to call */
558 .data = NULL, /* 2nd arg of func */
559 .help_str = help_sendmsg,
560 .tokens = { /* token list, NULL terminated */
561 (PGM_P)&cmd_sendmsg_sendmsg,
562 (PGM_P)&cmd_sendmsg_addr,
563 (PGM_P)&cmd_sendmsg_data,
570 /* this structure is filled when cmd_sendmsg_name is parsed successfully */
571 struct cmd_sendmsg_name_result {
572 fixed_string_t sendmsg_name;
573 struct xbee_neigh *neigh;
577 /* function called when cmd_sendmsg_name is parsed successfully */
578 static void cmd_sendmsg_name_parsed(void *parsed_result, void *data)
580 struct cmd_sendmsg_name_result *res = parsed_result;
583 xbeeapp_send_msg(res->neigh->addr, res->data, strlen(res->data), 1);
586 const parse_token_string_t PROGMEM cmd_sendmsg_name_sendmsg_name =
587 TOKEN_STRING_INITIALIZER(struct cmd_sendmsg_name_result, sendmsg_name,
590 const parse_token_neighbor_t PROGMEM cmd_sendmsg_name_neigh =
591 TOKEN_NEIGHBOR_INITIALIZER(struct cmd_sendmsg_name_result, neigh,
594 const parse_token_string_t PROGMEM cmd_sendmsg_name_data =
595 TOKEN_STRING_INITIALIZER(struct cmd_sendmsg_name_result, data, NULL);
597 const char PROGMEM help_sendmsg_name[] = "Send data to a node using its name";
599 const parse_inst_t PROGMEM cmd_sendmsg_name = {
600 .f = cmd_sendmsg_name_parsed, /* function to call */
601 .data = NULL, /* 2nd arg of func */
602 .help_str = help_sendmsg_name,
603 .tokens = { /* token list, NULL terminated */
604 (PGM_P)&cmd_sendmsg_name_sendmsg_name,
605 (PGM_P)&cmd_sendmsg_name_neigh,
606 (PGM_P)&cmd_sendmsg_name_data,
614 /* this structure is filled when cmd_range is parsed successfully */
615 struct cmd_range_result {
616 fixed_string_t range;
617 fixed_string_t action;
620 /* function called when cmd_range is parsed successfully */
621 static void cmd_range_parsed(void *parsed_result, void *data)
623 struct cmd_range_result *res = parsed_result;
626 if (!strcmp_P(res->action, PSTR("show"))) {
627 printf_P(PSTR("range infos:\r\n"));
628 printf_P(PSTR(" range period %d\r\n"), range_period_ms);
629 printf_P(PSTR(" range count %d\r\n"), range_count);
630 printf_P(PSTR(" range powermask 0x%x\r\n"), range_powermask);
631 printf_P(PSTR(" range dstaddr 0x%.8"PRIx32"%.8"PRIx32"\r\n"),
632 (uint32_t)(range_dstaddr >> 32ULL),
633 (uint32_t)(range_dstaddr & 0xFFFFFFFF));
636 printf_P(PSTR(" range test is running\r\n"));
638 printf_P(PSTR(" range test is not running\r\n"));
640 else if (!strcmp(res->action, "start")) {
642 printf_P(PSTR("already running\r\n"));
645 range_cur_count = range_count;
646 callout_init(&range_event);
647 callout_reset(&cm, &range_event, 0,
648 SINGLE, range_cb, NULL);
651 else if (!strcmp(res->action, "end")) {
652 if (range_running == 0) {
653 printf_P(PSTR("not running\r\n"));
657 callout_stop(&cm, &range_event);
661 const char PROGMEM str_range[] = "range";
662 const char PROGMEM str_range_tokens[] = "show#start#end";
664 const parse_token_string_t PROGMEM cmd_range_range =
665 TOKEN_STRING_INITIALIZER(struct cmd_range_result, range,
667 const parse_token_string_t PROGMEM cmd_range_action =
668 TOKEN_STRING_INITIALIZER(struct cmd_range_result, action,
671 const char PROGMEM help_range[] = "start/stop/show current rangeing";
673 const parse_inst_t PROGMEM cmd_range = {
674 .f = cmd_range_parsed, /* function to call */
675 .data = NULL, /* 2nd arg of func */
676 .help_str = help_range,
677 .tokens = { /* token list, NULL terminated */
678 (PGM_P)&cmd_range_range,
679 (PGM_P)&cmd_range_action,
686 /* this structure is filled when cmd_range_period is parsed successfully */
687 struct cmd_range_period_result {
688 fixed_string_t range;
689 fixed_string_t action;
693 /* function called when cmd_range_period is parsed successfully */
694 static void cmd_range_period_parsed(void *parsed_result, void *data)
696 struct cmd_range_period_result *res = parsed_result;
699 if (res->period < 10) {
700 printf_P(PSTR("error, minimum period is 10 ms\r\n"));
704 range_period_ms = res->period;
707 const char PROGMEM str_period[] = "period";
709 const parse_token_string_t PROGMEM cmd_range_period_range_period =
710 TOKEN_STRING_INITIALIZER(struct cmd_range_period_result, range,
712 const parse_token_string_t PROGMEM cmd_range_period_action =
713 TOKEN_STRING_INITIALIZER(struct cmd_range_period_result, action,
715 const parse_token_num_t PROGMEM cmd_range_period_period =
716 TOKEN_NUM_INITIALIZER(struct cmd_range_period_result, period, UINT32);
718 const char PROGMEM help_range_period[] = "set range test period";
720 const parse_inst_t PROGMEM cmd_range_period = {
721 .f = cmd_range_period_parsed, /* function to call */
722 .data = NULL, /* 2nd arg of func */
723 .help_str = help_range_period,
724 .tokens = { /* token list, NULL terminated */
725 (PGM_P)&cmd_range_period_range_period,
726 (PGM_P)&cmd_range_period_action,
727 (PGM_P)&cmd_range_period_period,
734 /* this structure is filled when cmd_range_count is parsed successfully */
735 struct cmd_range_count_result {
736 fixed_string_t range;
737 fixed_string_t action;
741 /* function called when cmd_range_count is parsed successfully */
742 static void cmd_range_count_parsed(void *parsed_result, void *data)
744 struct cmd_range_count_result *res = parsed_result;
747 range_count = res->count;
750 const char PROGMEM str_count[] = "count";
752 const parse_token_string_t PROGMEM cmd_range_count_range_count =
753 TOKEN_STRING_INITIALIZER(struct cmd_range_count_result, range,
755 const parse_token_string_t PROGMEM cmd_range_count_action =
756 TOKEN_STRING_INITIALIZER(struct cmd_range_count_result, action,
758 const parse_token_num_t PROGMEM cmd_range_count_count =
759 TOKEN_NUM_INITIALIZER(struct cmd_range_count_result, count, UINT32);
762 const char PROGMEM help_range_count[] = "set range test count";
764 const parse_inst_t PROGMEM cmd_range_count = {
765 .f = cmd_range_count_parsed, /* function to call */
766 .data = NULL, /* 2nd arg of func */
767 .help_str = help_range_count,
768 .tokens = { /* token list, NULL terminated */
769 (PGM_P)&cmd_range_count_range_count,
770 (PGM_P)&cmd_range_count_action,
771 (PGM_P)&cmd_range_count_count,
778 /* this structure is filled when cmd_range_powermask is parsed successfully */
779 struct cmd_range_powermask_result {
780 fixed_string_t range;
781 fixed_string_t action;
785 /* function called when cmd_range_powermask is parsed successfully */
786 static void cmd_range_powermask_parsed(void *parsed_result, void *data)
788 struct cmd_range_powermask_result *res = parsed_result;
791 range_powermask = res->powermask;
794 const char PROGMEM str_powermask[] = "powermask";
796 const parse_token_string_t PROGMEM cmd_range_powermask_range_powermask =
797 TOKEN_STRING_INITIALIZER(struct cmd_range_powermask_result, range,
799 const parse_token_string_t PROGMEM cmd_range_powermask_action =
800 TOKEN_STRING_INITIALIZER(struct cmd_range_powermask_result, action,
802 const parse_token_num_t PROGMEM cmd_range_powermask_powermask =
803 TOKEN_NUM_INITIALIZER(struct cmd_range_powermask_result, powermask,
807 const char PROGMEM help_range_powermask[] = "set range test powermask";
809 const parse_inst_t PROGMEM cmd_range_powermask = {
810 .f = cmd_range_powermask_parsed, /* function to call */
811 .data = NULL, /* 2nd arg of func */
812 .help_str = help_range_powermask,
813 .tokens = { /* token list, NULL terminated */
814 (PGM_P)&cmd_range_powermask_range_powermask,
815 (PGM_P)&cmd_range_powermask_action,
816 (PGM_P)&cmd_range_powermask_powermask,
823 /* this structure is filled when cmd_range_dstaddr is parsed successfully */
824 struct cmd_range_dstaddr_result {
825 fixed_string_t range;
826 fixed_string_t action;
830 /* function called when cmd_range_dstaddr is parsed successfully */
831 static void cmd_range_dstaddr_parsed(void *parsed_result, void *data)
833 struct cmd_range_dstaddr_result *res = parsed_result;
836 range_dstaddr = res->dstaddr;
839 const char PROGMEM str_dstaddr[] = "dstaddr";
841 const parse_token_string_t PROGMEM cmd_range_dstaddr_range_dstaddr =
842 TOKEN_STRING_INITIALIZER(struct cmd_range_dstaddr_result, range,
844 const parse_token_string_t PROGMEM cmd_range_dstaddr_action =
845 TOKEN_STRING_INITIALIZER(struct cmd_range_dstaddr_result, action,
847 const parse_token_num_t PROGMEM cmd_range_dstaddr_dstaddr =
848 TOKEN_NUM_INITIALIZER(struct cmd_range_dstaddr_result, dstaddr, UINT64);
851 const char PROGMEM help_range_dstaddr[] = "set register rangeing dstaddr";
853 const parse_inst_t PROGMEM cmd_range_dstaddr = {
854 .f = cmd_range_dstaddr_parsed, /* function to call */
855 .data = NULL, /* 2nd arg of func */
856 .help_str = help_range_dstaddr,
857 .tokens = { /* token list, NULL terminated */
858 (PGM_P)&cmd_range_dstaddr_range_dstaddr,
859 (PGM_P)&cmd_range_dstaddr_action,
860 (PGM_P)&cmd_range_dstaddr_dstaddr,
868 /* this structure is filled when cmd_monitor is parsed successfully */
869 struct cmd_monitor_result {
870 fixed_string_t monitor;
871 fixed_string_t action;
874 /* function called when cmd_monitor is parsed successfully */
875 static void cmd_monitor_parsed(void *parsed_result, void *data)
877 struct cmd_monitor_result *res = parsed_result;
878 struct monitor_reg *m;
881 if (!strcmp_P(res->action, PSTR("show"))) {
882 printf_P(PSTR("monitor period is %d ms, %d regs in list\r\n"),
883 monitor_period_ms, monitor_count);
884 LIST_FOREACH(m, &xbee_monitor_list, next)
885 printf_P(PSTR(" %S\r\n"), m->desc);
887 else if (!strcmp_P(res->action, PSTR("start"))) {
888 if (monitor_running) {
889 printf_P(PSTR("already running\r\n"));
892 if (monitor_count == 0) {
893 printf_P(PSTR("no regs to be monitored\r\n"));
896 callout_init(&monitor_event);
897 callout_reset(&cm, &monitor_event, 0, SINGLE, monitor_cb, NULL);
899 monitor_current = LIST_FIRST(&xbee_monitor_list);
900 printf_P(PSTR("monitor cb: %S %s\r\n"),
901 monitor_current->desc,
902 monitor_current->atcmd);
905 else if (!strcmp_P(res->action, PSTR("end"))) {
906 if (monitor_running == 0) {
907 printf_P(PSTR("not running\r\n"));
911 callout_stop(&cm, &monitor_event);
915 const char PROGMEM str_monitor[] = "monitor";
916 const char PROGMEM str_monitor_tokens[] = "show#start#end";
918 const parse_token_string_t PROGMEM cmd_monitor_monitor =
919 TOKEN_STRING_INITIALIZER(struct cmd_monitor_result, monitor,
921 const parse_token_string_t PROGMEM cmd_monitor_action =
922 TOKEN_STRING_INITIALIZER(struct cmd_monitor_result, action,
925 const char PROGMEM help_monitor[] = "start/stop/show current monitoring";
927 const parse_inst_t PROGMEM cmd_monitor = {
928 .f = cmd_monitor_parsed, /* function to call */
929 .data = NULL, /* 2nd arg of func */
930 .help_str = help_monitor,
931 .tokens = { /* token list, NULL terminated */
932 (PGM_P)&cmd_monitor_monitor,
933 (PGM_P)&cmd_monitor_action,
940 /* this structure is filled when cmd_monitor_add is parsed successfully */
941 struct cmd_monitor_add_result {
942 fixed_string_t monitor;
943 fixed_string_t action;
944 struct xbee_atcmd *cmd;
947 /* function called when cmd_monitor_add is parsed successfully */
948 static void cmd_monitor_add_parsed(void *parsed_result, void *data)
950 struct cmd_monitor_add_result *res = parsed_result;
951 struct monitor_reg *m;
952 struct xbee_atcmd copy;
955 memcpy_P(©, res->cmd, sizeof(copy));
956 LIST_FOREACH(m, &xbee_monitor_list, next) {
957 if (!strcmp_P(m->atcmd, copy.name))
962 printf_P(PSTR("already exist\r\n"));
966 m = malloc(sizeof(*m));
968 printf_P(PSTR("no mem\r\n"));
972 strcpy_P(m->atcmd, copy.name);
973 LIST_INSERT_HEAD(&xbee_monitor_list, m, next);
977 const char PROGMEM str_monitor_add[] = "add";
979 const parse_token_string_t PROGMEM cmd_monitor_add_monitor_add =
980 TOKEN_STRING_INITIALIZER(struct cmd_monitor_add_result, monitor,
982 const parse_token_string_t PROGMEM cmd_monitor_add_action =
983 TOKEN_STRING_INITIALIZER(struct cmd_monitor_add_result, action,
985 const parse_token_atcmd_t PROGMEM cmd_monitor_add_atcmd =
986 TOKEN_ATCMD_INITIALIZER(struct cmd_monitor_add_result, cmd, &xbee_dev,
987 XBEE_ATCMD_F_READ, XBEE_ATCMD_F_READ);
990 const char PROGMEM help_monitor_add[] = "add a register in monitor list";
992 const parse_inst_t PROGMEM cmd_monitor_add = {
993 .f = cmd_monitor_add_parsed, /* function to call */
994 .data = NULL, /* 2nd arg of func */
995 .help_str = help_monitor_add,
996 .tokens = { /* token list, NULL terminated */
997 (PGM_P)&cmd_monitor_add_monitor_add,
998 (PGM_P)&cmd_monitor_add_action,
999 (PGM_P)&cmd_monitor_add_atcmd,
1006 /* this structure is filled when cmd_monitor_period is parsed successfully */
1007 struct cmd_monitor_period_result {
1008 fixed_string_t monitor;
1009 fixed_string_t action;
1013 /* function called when cmd_monitor_period is parsed successfully */
1014 static void cmd_monitor_period_parsed(void *parsed_result, void *data)
1016 struct cmd_monitor_period_result *res = parsed_result;
1019 if (res->period < 100) {
1020 printf_P(PSTR("error, minimum period is 100 ms\r\n"));
1024 monitor_period_ms = res->period;
1027 const char PROGMEM str_monitor_period[] = "period";
1029 const parse_token_string_t PROGMEM cmd_monitor_period_monitor_period =
1030 TOKEN_STRING_INITIALIZER(struct cmd_monitor_period_result, monitor,
1032 const parse_token_string_t PROGMEM cmd_monitor_period_action =
1033 TOKEN_STRING_INITIALIZER(struct cmd_monitor_period_result, action,
1034 str_monitor_period);
1035 const parse_token_num_t PROGMEM cmd_monitor_period_period =
1036 TOKEN_NUM_INITIALIZER(struct cmd_monitor_period_result, period, UINT32);
1039 const char PROGMEM help_monitor_period[] = "set register monitoring period";
1041 const parse_inst_t PROGMEM cmd_monitor_period = {
1042 .f = cmd_monitor_period_parsed, /* function to call */
1043 .data = NULL, /* 2nd arg of func */
1044 .help_str = help_monitor_period,
1045 .tokens = { /* token list, NULL terminated */
1046 (PGM_P)&cmd_monitor_period_monitor_period,
1047 (PGM_P)&cmd_monitor_period_action,
1048 (PGM_P)&cmd_monitor_period_period,
1055 /* this structure is filled when cmd_monitor_del is parsed successfully */
1056 struct cmd_monitor_del_result {
1057 fixed_string_t monitor;
1058 fixed_string_t action;
1059 struct monitor_reg *m;
1062 /* function called when cmd_monitor_del is parsed successfully */
1063 static void cmd_monitor_del_parsed(void *parsed_result, void *data)
1065 struct cmd_monitor_del_result *res = parsed_result;
1068 monitor_current = LIST_NEXT(res->m, next);
1069 LIST_REMOVE(res->m, next);
1072 if (monitor_count == 0) {
1073 printf_P(PSTR("Disable monitoring, no more event\r\n"));
1074 callout_stop(&cm, &monitor_event);
1075 monitor_running = 0;
1080 const char PROGMEM str_monitor_del[] = "del";
1082 const parse_token_string_t PROGMEM cmd_monitor_del_monitor_del =
1083 TOKEN_STRING_INITIALIZER(struct cmd_monitor_del_result, monitor,
1085 const parse_token_string_t PROGMEM cmd_monitor_del_action =
1086 TOKEN_STRING_INITIALIZER(struct cmd_monitor_del_result, action,
1088 const parse_token_monitor_t PROGMEM cmd_monitor_del_atcmd =
1089 TOKEN_MONITOR_INITIALIZER(struct cmd_monitor_del_result, m);
1092 const char PROGMEM help_monitor_del[] = "del a register in monitor list";
1094 const parse_inst_t PROGMEM cmd_monitor_del = {
1095 .f = cmd_monitor_del_parsed, /* function to call */
1096 .data = NULL, /* 2nd arg of func */
1097 .help_str = help_monitor_del,
1098 .tokens = { /* token list, NULL terminated */
1099 (PGM_P)&cmd_monitor_del_monitor_del,
1100 (PGM_P)&cmd_monitor_del_action,
1101 (PGM_P)&cmd_monitor_del_atcmd,
1109 /* this structure is filled when cmd_ping is parsed successfully */
1110 struct cmd_ping_result {
1111 fixed_string_t ping;
1114 /* function called when cmd_ping is parsed successfully */
1115 static void cmd_ping_parsed(void *parsed_result, void *data)
1117 (void)parsed_result;
1119 xbeeapp_send_atcmd("VL", NULL, 0, 1, NULL, NULL);
1122 const char PROGMEM str_ping[] = "ping";
1124 const parse_token_string_t PROGMEM cmd_ping_ping =
1125 TOKEN_STRING_INITIALIZER(struct cmd_ping_result, ping,
1128 const char PROGMEM help_ping[] = "Send a ping to the xbee device";
1130 const parse_inst_t PROGMEM cmd_ping = {
1131 .f = cmd_ping_parsed, /* function to call */
1132 .data = NULL, /* 2nd arg of func */
1133 .help_str = help_ping,
1134 .tokens = { /* token list, NULL terminated */
1135 (PGM_P)&cmd_ping_ping,
1142 /* this structure is filled when cmd_raw is parsed successfully */
1143 struct cmd_raw_result {
1147 /* function called when cmd_raw is parsed successfully */
1148 static void cmd_raw_parsed(void *parsed_result, void *data)
1150 (void)parsed_result;
1152 printf_P(PSTR("switched to raw mode, CTRL-D to exit\r\n"));
1153 rdline_stop(&xbeeboard.rdl); /* don't display prompt when return */
1157 const char PROGMEM str_raw[] = "raw";
1159 const parse_token_string_t PROGMEM cmd_raw_raw =
1160 TOKEN_STRING_INITIALIZER(struct cmd_raw_result, raw,
1163 const char PROGMEM help_raw[] = "Switch to raw mode";
1165 const parse_inst_t PROGMEM cmd_raw = {
1166 .f = cmd_raw_parsed, /* function to call */
1167 .data = NULL, /* 2nd arg of func */
1168 .help_str = help_raw,
1169 .tokens = { /* token list, NULL terminated */
1170 (PGM_P)&cmd_raw_raw,
1177 /* this structure is filled when cmd_dump is parsed successfully */
1178 struct cmd_dump_result {
1179 fixed_string_t dump;
1180 fixed_string_t onoff;
1183 /* function called when cmd_dump is parsed successfully */
1184 static void cmd_dump_parsed(void *parsed_result, void *data)
1186 struct cmd_dump_result *res = parsed_result;
1189 if (!strcmp(res->onoff, "on"))
1195 const char PROGMEM str_dump[] = "dump";
1196 const char PROGMEM str_dump_onoff[] = "on#off";
1198 const parse_token_string_t PROGMEM cmd_dump_dump =
1199 TOKEN_STRING_INITIALIZER(struct cmd_dump_result, dump,
1202 const parse_token_string_t PROGMEM cmd_dump_onoff =
1203 TOKEN_STRING_INITIALIZER(struct cmd_dump_result, onoff,
1206 const char PROGMEM help_dump[] = "enable/disable hexdump of received packets";
1208 const parse_inst_t PROGMEM cmd_dump = {
1209 .f = cmd_dump_parsed, /* function to call */
1210 .data = NULL, /* 2nd arg of func */
1211 .help_str = help_dump,
1212 .tokens = { /* token list, NULL terminated */
1213 (PGM_P)&cmd_dump_dump,
1214 (PGM_P)&cmd_dump_onoff,
1221 /* this structure is filled when cmd_debug is parsed successfully */
1222 struct cmd_debug_result {
1223 fixed_string_t debug;
1224 fixed_string_t onoff;
1227 /* function called when cmd_debug is parsed successfully */
1228 static void cmd_debug_parsed(void *parsed_result, void *data)
1230 struct cmd_debug_result *res = parsed_result;
1233 if (!strcmp(res->onoff, "on"))
1239 const char PROGMEM str_debug[] = "debug";
1240 const char PROGMEM str_debug_onoff[] = "on#off";
1242 const parse_token_string_t PROGMEM cmd_debug_debug =
1243 TOKEN_STRING_INITIALIZER(struct cmd_debug_result, debug,
1246 const parse_token_string_t PROGMEM cmd_debug_onoff =
1247 TOKEN_STRING_INITIALIZER(struct cmd_debug_result, onoff,
1250 const char PROGMEM help_debug[] = "enable/disable additionnal debug";
1252 const parse_inst_t PROGMEM cmd_debug = {
1253 .f = cmd_debug_parsed, /* function to call */
1254 .data = NULL, /* 2nd arg of func */
1255 .help_str = help_debug,
1256 .tokens = { /* token list, NULL terminated */
1257 (PGM_P)&cmd_debug_debug,
1258 (PGM_P)&cmd_debug_onoff,
1264 /**********************************************************/
1266 /* this structure is filled when cmd_baudrate is parsed successfully */
1267 struct cmd_baudrate_result {
1268 fixed_string_t arg0;
1272 /* function called when cmd_baudrate is parsed successfully */
1273 static void cmd_baudrate_parsed(void * parsed_result, __attribute__((unused)) void *data)
1275 struct cmd_baudrate_result *res = parsed_result;
1276 struct uart_config c;
1278 uart_getconf(XBEE_UART, &c);
1279 c.baudrate = res->arg1;
1280 uart_setconf(XBEE_UART, &c);
1283 const char PROGMEM str_baudrate_arg0[] = "baudrate";
1284 const parse_token_string_t PROGMEM cmd_baudrate_arg0 =
1285 TOKEN_STRING_INITIALIZER(struct cmd_baudrate_result, arg0,
1287 const parse_token_num_t PROGMEM cmd_baudrate_arg1 =
1288 TOKEN_NUM_INITIALIZER(struct cmd_baudrate_result, arg1,
1291 const char PROGMEM help_baudrate[] = "Change xbee baudrate";
1292 const parse_inst_t PROGMEM cmd_baudrate = {
1293 .f = cmd_baudrate_parsed, /* function to call */
1294 .data = NULL, /* 2nd arg of func */
1295 .help_str = help_baudrate,
1296 .tokens = { /* token list, NULL terminated */
1297 (PGM_P)&cmd_baudrate_arg0,
1298 (PGM_P)&cmd_baudrate_arg1,
1304 /* this structure is filled when cmd_test_spi is parsed successfully */
1305 struct cmd_test_spi_result {
1306 fixed_string_t arg0;
1309 static void cmd_test_spi_parsed(void * parsed_result, void *data)
1313 (void)parsed_result;
1317 for (i = 0; i < 50; i++) {
1318 spi_servo_set(0, 0);
1320 spi_servo_set(0, 500);
1324 spi_servo_bypass(1);
1326 spi_servo_bypass(0);
1331 const char PROGMEM str_test_spi_arg0[] = "test_spi";
1332 const parse_token_string_t PROGMEM cmd_test_spi_arg0 =
1333 TOKEN_STRING_INITIALIZER(struct cmd_test_spi_result, arg0,
1336 const char PROGMEM help_test_spi[] = "Test the spi";
1337 const parse_inst_t PROGMEM cmd_test_spi = {
1338 .f = cmd_test_spi_parsed, /* function to call */
1339 .data = NULL, /* 2nd arg of func */
1340 .help_str = help_test_spi,
1341 .tokens = { /* token list, NULL terminated */
1342 (PGM_P)&cmd_test_spi_arg0,
1348 const parse_ctx_t PROGMEM main_ctx[] = {
1350 /* commands_gen.c */
1372 &cmd_range_powermask,
1375 &cmd_monitor_period,