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 parse_pgm_inst_t cmd_reset;
57 extern parse_pgm_inst_t cmd_bootloader;
58 extern parse_pgm_inst_t cmd_log;
59 extern parse_pgm_inst_t cmd_log_show;
60 extern parse_pgm_inst_t cmd_log_type;
61 extern parse_pgm_inst_t cmd_stack_space;
62 extern parse_pgm_inst_t 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)
82 if (monitor_current == NULL)
83 monitor_current = LIST_FIRST(&xbee_monitor_list);
85 xbeeapp_send_atcmd(monitor_current->atcmd, NULL, 0, 0, NULL, NULL);
86 monitor_current = LIST_NEXT(monitor_current, next);
87 callout_reset(cm, &monitor_event,
88 monitor_period_ms / monitor_count,
89 SINGLE, monitor_cb, NULL);
92 static void range_cb(struct callout_manager *cm,
93 struct callout *clt, void *dummy)
96 struct rc_proto_range rangepkt;
100 /* get new xmit power */
101 for (i = 1; i <= 8; i++) {
102 mask = 1 << ((range_power + i) & 0x7);
103 if (mask & range_powermask)
106 range_power = ((range_power + i) & 0x7);
108 xbeeapp_send_atcmd("PL", &range_power, sizeof(range_power), 0, NULL, NULL);
110 rangepkt.type = RC_PROTO_TYPE_RANGE;
111 rangepkt.power_level = range_power;
113 xbeeapp_send_msg(range_dstaddr, &rangepkt, sizeof(rangepkt), 0);
115 if (range_cur_count == 0) {
120 callout_reset(cm, &range_event,
122 SINGLE, range_cb, NULL);
125 /* this structure is filled when cmd_help is parsed successfully */
126 struct cmd_help_result {
128 struct xbee_atcmd_pgm *cmd;
131 /* function called when cmd_help is parsed successfully */
132 static void cmd_help_parsed(void *parsed_result, void *data)
134 struct cmd_help_result *res = parsed_result;
135 struct xbee_atcmd cmdcopy;
137 memcpy_P(&cmdcopy, res->cmd, sizeof(cmdcopy));
138 type = (cmdcopy.flags & (XBEE_ATCMD_F_READ | XBEE_ATCMD_F_WRITE));
140 case XBEE_ATCMD_F_READ:
141 printf_P(PSTR("Read-only\r\n"));
143 case XBEE_ATCMD_F_WRITE:
144 printf_P(PSTR("Write-only\r\n"));
147 printf_P(PSTR("Read-write\r\n"));
150 if (cmdcopy.flags & XBEE_ATCMD_F_PARAM_NONE)
151 printf_P(PSTR("No argument\r\n"));
152 else if (cmdcopy.flags & XBEE_ATCMD_F_PARAM_U8)
153 printf_P(PSTR("Register is unsigned 8 bits\r\n"));
154 else if (cmdcopy.flags & XBEE_ATCMD_F_PARAM_U16)
155 printf_P(PSTR("Register is unsigned 16 bits\r\n"));
156 else if (cmdcopy.flags & XBEE_ATCMD_F_PARAM_U32)
157 printf_P(PSTR("Register is unsigned 32 bits\r\n"));
158 else if (cmdcopy.flags & XBEE_ATCMD_F_PARAM_S16)
159 printf_P(PSTR("Register is signed 16 bits\r\n"));
160 else if (cmdcopy.flags & XBEE_ATCMD_F_PARAM_STRING_20B)
161 printf_P(PSTR("Register is a 20 bytes string\r\n"));
163 printf_P(PSTR("Unknown argument\r\n"));
165 printf_P(PSTR("%S\r\n"), cmdcopy.help);
167 prog_char str_help_help[] = "help";
169 parse_pgm_token_string_t cmd_help_help =
170 TOKEN_STRING_INITIALIZER(struct cmd_help_result, help, str_help_help);
172 parse_pgm_token_atcmd_t cmd_help_atcmd =
173 TOKEN_ATCMD_INITIALIZER(struct cmd_help_result, cmd, &xbee_dev,
176 prog_char help_help[] = "Help a register using an AT command";
177 parse_pgm_inst_t cmd_help = {
178 .f = cmd_help_parsed, /* function to call */
179 .data = NULL, /* 2nd arg of func */
180 .help_str = help_help,
181 .tokens = { /* token list, NULL terminated */
182 (prog_void *)&cmd_help_help,
183 (prog_void *)&cmd_help_atcmd,
190 struct cmd_neigh_del_result {
192 fixed_string_t action;
193 struct xbee_neigh *neigh;
196 static void cmd_neigh_del_parsed(void *parsed_result,
199 struct cmd_neigh_del_result *res = parsed_result;
200 xbee_neigh_del(xbee_dev, res->neigh);
203 prog_char str_neigh_del_neigh[] = "neigh";
204 parse_pgm_token_string_t cmd_neigh_del_cmd =
205 TOKEN_STRING_INITIALIZER(struct cmd_neigh_del_result, cmd,
206 str_neigh_del_neigh);
207 prog_char str_neigh_del_del[] = "del";
208 parse_pgm_token_string_t cmd_neigh_del_action =
209 TOKEN_STRING_INITIALIZER(struct cmd_neigh_del_result, action,
211 parse_pgm_token_neighbor_t cmd_neigh_del_neigh =
212 TOKEN_NEIGHBOR_INITIALIZER(struct cmd_neigh_del_result, neigh,
215 prog_char help_neigh_del[] = "delete a neighbor";
216 parse_pgm_inst_t cmd_neigh_del = {
217 .f = cmd_neigh_del_parsed, /* function to call */
218 .data = NULL, /* 2nd arg of func */
219 .help_str = help_neigh_del,
220 .tokens = { /* token list, NULL terminated */
221 (prog_void *)&cmd_neigh_del_cmd,
222 (prog_void *)&cmd_neigh_del_action,
223 (prog_void *)&cmd_neigh_del_neigh,
230 struct cmd_neigh_add_result {
232 fixed_string_t action;
237 static void cmd_neigh_add_parsed(void *parsed_result,
240 struct cmd_neigh_add_result *res = parsed_result;
241 if (xbee_neigh_add(xbee_dev, res->name, res->addr) == NULL)
242 printf_P(PSTR("name or addr already exist\r\n"));
245 prog_char str_neigh_add_neigh[] = "neigh";
246 parse_pgm_token_string_t cmd_neigh_add_cmd =
247 TOKEN_STRING_INITIALIZER(struct cmd_neigh_add_result, cmd,
248 str_neigh_add_neigh);
249 prog_char str_neigh_add_add[] = "add";
250 parse_pgm_token_string_t cmd_neigh_add_action =
251 TOKEN_STRING_INITIALIZER(struct cmd_neigh_add_result, action,
253 parse_pgm_token_string_t cmd_neigh_add_name =
254 TOKEN_STRING_INITIALIZER(struct cmd_neigh_add_result, name, NULL);
255 parse_pgm_token_num_t cmd_neigh_add_addr =
256 TOKEN_NUM_INITIALIZER(struct cmd_neigh_add_result, addr, UINT64);
258 prog_char help_neigh_add[] = "add a neighbor";
259 parse_pgm_inst_t cmd_neigh_add = {
260 .f = cmd_neigh_add_parsed, /* function to call */
261 .data = NULL, /* 2nd arg of func */
262 .help_str = help_neigh_add,
263 .tokens = { /* token list, NULL terminated */
264 (prog_void *)&cmd_neigh_add_cmd,
265 (prog_void *)&cmd_neigh_add_action,
266 (prog_void *)&cmd_neigh_add_name,
267 (prog_void *)&cmd_neigh_add_addr,
274 struct cmd_neigh_list_result {
276 fixed_string_t action;
279 static void cmd_neigh_list_parsed(void *parsed_result,
282 struct xbee_neigh *neigh;
284 LIST_FOREACH(neigh, &xbee_dev->neigh_list, next) {
285 printf_P(PSTR(" %s: 0x%.8"PRIx32"%.8"PRIx32"\r\n"),
287 (uint32_t)(neigh->addr >> 32ULL),
288 (uint32_t)(neigh->addr & 0xFFFFFFFF));
292 prog_char str_neigh_list_neigh[] = "neigh";
293 parse_pgm_token_string_t cmd_neigh_list_cmd =
294 TOKEN_STRING_INITIALIZER(struct cmd_neigh_list_result, cmd,
295 str_neigh_list_neigh);
296 prog_char str_neigh_list_list[] = "list";
297 parse_pgm_token_string_t cmd_neigh_list_action =
298 TOKEN_STRING_INITIALIZER(struct cmd_neigh_list_result, action,
299 str_neigh_list_list);
301 prog_char help_neigh_list[] = "list all knwon neighbors";
302 parse_pgm_inst_t cmd_neigh_list = {
303 .f = cmd_neigh_list_parsed, /* function to call */
304 .data = NULL, /* 2nd arg of func */
305 .help_str = help_neigh_list,
306 .tokens = { /* token list, NULL terminated */
307 (prog_void *)&cmd_neigh_list_cmd,
308 (prog_void *)&cmd_neigh_list_action,
318 /* this structure is filled when cmd_read is parsed successfully */
319 struct cmd_read_result {
321 struct xbee_atcmd_pgm *cmd;
324 /* function called when cmd_read is parsed successfully */
325 static void cmd_read_parsed(void *parsed_result,
328 struct cmd_read_result *res = parsed_result;
329 struct xbee_atcmd copy;
332 memcpy_P(©, res->cmd, sizeof(copy));
333 memcpy_P(&cmd, copy.name, 2);
335 xbeeapp_send_atcmd(cmd, NULL, 0, 1, NULL, NULL);
338 prog_char str_read_read[] = "read";
340 parse_pgm_token_string_t cmd_read_read =
341 TOKEN_STRING_INITIALIZER(struct cmd_read_result, read,
344 parse_pgm_token_atcmd_t cmd_read_atcmd =
345 TOKEN_ATCMD_INITIALIZER(struct cmd_read_result, cmd, &xbee_dev,
346 XBEE_ATCMD_F_READ, XBEE_ATCMD_F_READ);
348 prog_char help_read[] = "Read a register using an AT command";
349 parse_pgm_inst_t cmd_read = {
350 .f = cmd_read_parsed, /* function to call */
351 .data = NULL, /* 2nd arg of func */
352 .help_str = help_read,
353 .tokens = { /* token list, NULL terminated */
354 (prog_void *)&cmd_read_read,
355 (prog_void *)&cmd_read_atcmd,
363 /* this structure is filled when cmd_write is parsed successfully */
364 struct cmd_write_result {
365 fixed_string_t write;
366 struct xbee_atcmd_pgm *cmd;
374 /* function called when cmd_write is parsed successfully */
375 static void cmd_write_parsed(void *parsed_result, void *data)
377 struct cmd_write_result *res = parsed_result;
378 struct xbee_atcmd copy;
383 memcpy_P(©, res->cmd, sizeof(copy));
385 if (copy.flags & XBEE_ATCMD_F_PARAM_NONE) {
389 else if (copy.flags & XBEE_ATCMD_F_PARAM_U8) {
390 len = sizeof(res->u8);
393 else if (copy.flags & XBEE_ATCMD_F_PARAM_U16) {
394 len = sizeof(res->u16);
395 res->u16 = htons(res->u16);
398 else if (copy.flags & XBEE_ATCMD_F_PARAM_U32) {
399 len = sizeof(res->u32);
400 res->u32 = htonl(res->u32);
404 printf_P(PSTR("Unknown argument type\r\n"));
407 memcpy_P(&cmd, copy.name, 2);
409 xbeeapp_send_atcmd(cmd, param, len, 1, NULL, NULL);
412 prog_char str_write_none[] = "write";
414 parse_pgm_token_string_t cmd_write_write =
415 TOKEN_STRING_INITIALIZER(struct cmd_write_result, write,
418 parse_pgm_token_atcmd_t cmd_write_none_atcmd =
419 TOKEN_ATCMD_INITIALIZER(struct cmd_write_result, cmd,
421 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_NONE,
422 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_NONE);
424 prog_char help_write_none[] = "Send an AT command (no argument)";
426 parse_pgm_inst_t cmd_write_none = {
427 .f = cmd_write_parsed, /* function to call */
428 .data = NULL, /* 2nd arg of func */
429 .help_str = help_write_none,
430 .tokens = { /* token list, NULL terminated */
431 (prog_void *)&cmd_write_write,
432 (prog_void *)&cmd_write_none_atcmd,
437 parse_pgm_token_atcmd_t cmd_write_u8_atcmd =
438 TOKEN_ATCMD_INITIALIZER(struct cmd_write_result, cmd,
440 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_U8,
441 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_U8);
443 parse_pgm_token_num_t cmd_write_u8_u8 =
444 TOKEN_NUM_INITIALIZER(struct cmd_write_result, u8, UINT8);
446 prog_char help_write_u8[] = "Write a 8 bits register using an AT command";
448 parse_pgm_inst_t cmd_write_u8 = {
449 .f = cmd_write_parsed, /* function to call */
450 .data = NULL, /* 2nd arg of func */
451 .help_str = help_write_u8,
452 .tokens = { /* token list, NULL terminated */
453 (prog_void *)&cmd_write_write,
454 (prog_void *)&cmd_write_u8_atcmd,
455 (prog_void *)&cmd_write_u8_u8,
460 parse_pgm_token_atcmd_t cmd_write_u16_atcmd =
461 TOKEN_ATCMD_INITIALIZER(struct cmd_write_result, cmd,
463 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_U16,
464 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_U16);
466 parse_pgm_token_num_t cmd_write_u16_u16 =
467 TOKEN_NUM_INITIALIZER(struct cmd_write_result, u16, UINT16);
469 prog_char help_write_u16[] = "Write a 16 bits register using an AT command";
471 parse_pgm_inst_t cmd_write_u16 = {
472 .f = cmd_write_parsed, /* function to call */
473 .data = NULL, /* 2nd arg of func */
474 .help_str = help_write_u16,
475 .tokens = { /* token list, NULL terminated */
476 (prog_void *)&cmd_write_write,
477 (prog_void *)&cmd_write_u16_atcmd,
478 (prog_void *)&cmd_write_u16_u16,
483 parse_pgm_token_atcmd_t cmd_write_u32_atcmd =
484 TOKEN_ATCMD_INITIALIZER(struct cmd_write_result, cmd,
486 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_U32,
487 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_U32);
489 parse_pgm_token_num_t cmd_write_u32_u32 =
490 TOKEN_NUM_INITIALIZER(struct cmd_write_result, u32, UINT32);
492 prog_char help_write_u32[] = "Write a 32 bits register using an AT command";
494 parse_pgm_inst_t cmd_write_u32 = {
495 .f = cmd_write_parsed, /* function to call */
496 .data = NULL, /* 2nd arg of func */
497 .help_str = help_write_u32,
498 .tokens = { /* token list, NULL terminated */
499 (prog_void *)&cmd_write_write,
500 (prog_void *)&cmd_write_u32_atcmd,
501 (prog_void *)&cmd_write_u32_u32,
509 /* this structure is filled when cmd_sendmsg is parsed successfully */
510 struct cmd_sendmsg_result {
511 fixed_string_t sendmsg;
516 /* function called when cmd_sendmsg is parsed successfully */
517 static void cmd_sendmsg_parsed(void *parsed_result, void *data)
519 struct cmd_sendmsg_result *res = parsed_result;
520 xbeeapp_send_msg(res->addr, res->data, strlen(res->data), 1);
523 prog_char str_sendmsg[] = "sendmsg";
525 parse_pgm_token_string_t cmd_sendmsg_sendmsg =
526 TOKEN_STRING_INITIALIZER(struct cmd_sendmsg_result, sendmsg,
529 parse_pgm_token_num_t cmd_sendmsg_addr =
530 TOKEN_NUM_INITIALIZER(struct cmd_sendmsg_result, addr, UINT64);
532 parse_pgm_token_string_t cmd_sendmsg_data =
533 TOKEN_STRING_INITIALIZER(struct cmd_sendmsg_result, data, NULL);
535 prog_char help_sendmsg[] = "Send data to a node using its address";
537 parse_pgm_inst_t cmd_sendmsg = {
538 .f = cmd_sendmsg_parsed, /* function to call */
539 .data = NULL, /* 2nd arg of func */
540 .help_str = help_sendmsg,
541 .tokens = { /* token list, NULL terminated */
542 (prog_void *)&cmd_sendmsg_sendmsg,
543 (prog_void *)&cmd_sendmsg_addr,
544 (prog_void *)&cmd_sendmsg_data,
551 /* this structure is filled when cmd_sendmsg_name is parsed successfully */
552 struct cmd_sendmsg_name_result {
553 fixed_string_t sendmsg_name;
554 struct xbee_neigh *neigh;
558 /* function called when cmd_sendmsg_name is parsed successfully */
559 static void cmd_sendmsg_name_parsed(void *parsed_result, void *data)
561 struct cmd_sendmsg_name_result *res = parsed_result;
562 xbeeapp_send_msg(res->neigh->addr, res->data, strlen(res->data), 1);
565 parse_pgm_token_string_t cmd_sendmsg_name_sendmsg_name =
566 TOKEN_STRING_INITIALIZER(struct cmd_sendmsg_name_result, sendmsg_name,
569 parse_pgm_token_neighbor_t cmd_sendmsg_name_neigh =
570 TOKEN_NEIGHBOR_INITIALIZER(struct cmd_sendmsg_name_result, neigh,
573 parse_pgm_token_string_t cmd_sendmsg_name_data =
574 TOKEN_STRING_INITIALIZER(struct cmd_sendmsg_name_result, data, NULL);
576 prog_char help_sendmsg_name[] = "Send data to a node using its name";
578 parse_pgm_inst_t cmd_sendmsg_name = {
579 .f = cmd_sendmsg_name_parsed, /* function to call */
580 .data = NULL, /* 2nd arg of func */
581 .help_str = help_sendmsg_name,
582 .tokens = { /* token list, NULL terminated */
583 (prog_void *)&cmd_sendmsg_name_sendmsg_name,
584 (prog_void *)&cmd_sendmsg_name_neigh,
585 (prog_void *)&cmd_sendmsg_name_data,
593 /* this structure is filled when cmd_range is parsed successfully */
594 struct cmd_range_result {
595 fixed_string_t range;
596 fixed_string_t action;
599 /* function called when cmd_range is parsed successfully */
600 static void cmd_range_parsed(void *parsed_result, void *data)
602 struct cmd_range_result *res = parsed_result;
604 if (!strcmp_P(res->action, PSTR("show"))) {
605 printf_P(PSTR("range infos:\r\n"));
606 printf_P(PSTR(" range period %d\r\n"), range_period_ms);
607 printf_P(PSTR(" range count %d\r\n"), range_count);
608 printf_P(PSTR(" range powermask 0x%x\r\n"), range_powermask);
609 printf_P(PSTR(" range dstaddr 0x%.8"PRIx32"%.8"PRIx32"\r\n"),
610 (uint32_t)(range_dstaddr >> 32ULL),
611 (uint32_t)(range_dstaddr & 0xFFFFFFFF));
614 printf_P(PSTR(" range test is running\r\n"));
616 printf_P(PSTR(" range test is not running\r\n"));
618 else if (!strcmp(res->action, "start")) {
620 printf_P(PSTR("already running\r\n"));
623 range_cur_count = range_count;
624 callout_init(&range_event);
625 callout_reset(&cm, &range_event, 0,
626 SINGLE, range_cb, NULL);
629 else if (!strcmp(res->action, "end")) {
630 if (range_running == 0) {
631 printf_P(PSTR("not running\r\n"));
635 callout_stop(&cm, &range_event);
639 prog_char str_range[] = "range";
640 prog_char str_range_tokens[] = "show#start#end";
642 parse_pgm_token_string_t cmd_range_range =
643 TOKEN_STRING_INITIALIZER(struct cmd_range_result, range,
645 parse_pgm_token_string_t cmd_range_action =
646 TOKEN_STRING_INITIALIZER(struct cmd_range_result, action,
649 prog_char help_range[] = "start/stop/show current rangeing";
651 parse_pgm_inst_t cmd_range = {
652 .f = cmd_range_parsed, /* function to call */
653 .data = NULL, /* 2nd arg of func */
654 .help_str = help_range,
655 .tokens = { /* token list, NULL terminated */
656 (prog_void *)&cmd_range_range,
657 (prog_void *)&cmd_range_action,
664 /* this structure is filled when cmd_range_period is parsed successfully */
665 struct cmd_range_period_result {
666 fixed_string_t range;
667 fixed_string_t action;
671 /* function called when cmd_range_period is parsed successfully */
672 static void cmd_range_period_parsed(void *parsed_result, void *data)
674 struct cmd_range_period_result *res = parsed_result;
676 if (res->period < 10) {
677 printf_P(PSTR("error, minimum period is 10 ms\r\n"));
681 range_period_ms = res->period;
684 prog_char str_period[] = "period";
686 parse_pgm_token_string_t cmd_range_period_range_period =
687 TOKEN_STRING_INITIALIZER(struct cmd_range_period_result, range,
689 parse_pgm_token_string_t cmd_range_period_action =
690 TOKEN_STRING_INITIALIZER(struct cmd_range_period_result, action,
692 parse_pgm_token_num_t cmd_range_period_period =
693 TOKEN_NUM_INITIALIZER(struct cmd_range_period_result, period, UINT32);
695 prog_char help_range_period[] = "set range test period";
697 parse_pgm_inst_t cmd_range_period = {
698 .f = cmd_range_period_parsed, /* function to call */
699 .data = NULL, /* 2nd arg of func */
700 .help_str = help_range_period,
701 .tokens = { /* token list, NULL terminated */
702 (prog_void *)&cmd_range_period_range_period,
703 (prog_void *)&cmd_range_period_action,
704 (prog_void *)&cmd_range_period_period,
711 /* this structure is filled when cmd_range_count is parsed successfully */
712 struct cmd_range_count_result {
713 fixed_string_t range;
714 fixed_string_t action;
718 /* function called when cmd_range_count is parsed successfully */
719 static void cmd_range_count_parsed(void *parsed_result, void *data)
721 struct cmd_range_count_result *res = parsed_result;
722 range_count = res->count;
725 prog_char str_count[] = "count";
727 parse_pgm_token_string_t cmd_range_count_range_count =
728 TOKEN_STRING_INITIALIZER(struct cmd_range_count_result, range,
730 parse_pgm_token_string_t cmd_range_count_action =
731 TOKEN_STRING_INITIALIZER(struct cmd_range_count_result, action,
733 parse_pgm_token_num_t cmd_range_count_count =
734 TOKEN_NUM_INITIALIZER(struct cmd_range_count_result, count, UINT32);
737 prog_char help_range_count[] = "set range test count";
739 parse_pgm_inst_t cmd_range_count = {
740 .f = cmd_range_count_parsed, /* function to call */
741 .data = NULL, /* 2nd arg of func */
742 .help_str = help_range_count,
743 .tokens = { /* token list, NULL terminated */
744 (prog_void *)&cmd_range_count_range_count,
745 (prog_void *)&cmd_range_count_action,
746 (prog_void *)&cmd_range_count_count,
753 /* this structure is filled when cmd_range_powermask is parsed successfully */
754 struct cmd_range_powermask_result {
755 fixed_string_t range;
756 fixed_string_t action;
760 /* function called when cmd_range_powermask is parsed successfully */
761 static void cmd_range_powermask_parsed(void *parsed_result, void *data)
763 struct cmd_range_powermask_result *res = parsed_result;
764 range_powermask = res->powermask;
767 prog_char str_powermask[] = "powermask";
769 parse_pgm_token_string_t cmd_range_powermask_range_powermask =
770 TOKEN_STRING_INITIALIZER(struct cmd_range_powermask_result, range,
772 parse_pgm_token_string_t cmd_range_powermask_action =
773 TOKEN_STRING_INITIALIZER(struct cmd_range_powermask_result, action,
775 parse_pgm_token_num_t cmd_range_powermask_powermask =
776 TOKEN_NUM_INITIALIZER(struct cmd_range_powermask_result, powermask,
780 prog_char help_range_powermask[] = "set range test powermask";
782 parse_pgm_inst_t cmd_range_powermask = {
783 .f = cmd_range_powermask_parsed, /* function to call */
784 .data = NULL, /* 2nd arg of func */
785 .help_str = help_range_powermask,
786 .tokens = { /* token list, NULL terminated */
787 (prog_void *)&cmd_range_powermask_range_powermask,
788 (prog_void *)&cmd_range_powermask_action,
789 (prog_void *)&cmd_range_powermask_powermask,
796 /* this structure is filled when cmd_range_dstaddr is parsed successfully */
797 struct cmd_range_dstaddr_result {
798 fixed_string_t range;
799 fixed_string_t action;
803 /* function called when cmd_range_dstaddr is parsed successfully */
804 static void cmd_range_dstaddr_parsed(void *parsed_result, void *data)
806 struct cmd_range_dstaddr_result *res = parsed_result;
807 range_dstaddr = res->dstaddr;
810 prog_char str_dstaddr[] = "dstaddr";
812 parse_pgm_token_string_t cmd_range_dstaddr_range_dstaddr =
813 TOKEN_STRING_INITIALIZER(struct cmd_range_dstaddr_result, range,
815 parse_pgm_token_string_t cmd_range_dstaddr_action =
816 TOKEN_STRING_INITIALIZER(struct cmd_range_dstaddr_result, action,
818 parse_pgm_token_num_t cmd_range_dstaddr_dstaddr =
819 TOKEN_NUM_INITIALIZER(struct cmd_range_dstaddr_result, dstaddr, UINT64);
822 prog_char help_range_dstaddr[] = "set register rangeing dstaddr";
824 parse_pgm_inst_t cmd_range_dstaddr = {
825 .f = cmd_range_dstaddr_parsed, /* function to call */
826 .data = NULL, /* 2nd arg of func */
827 .help_str = help_range_dstaddr,
828 .tokens = { /* token list, NULL terminated */
829 (prog_void *)&cmd_range_dstaddr_range_dstaddr,
830 (prog_void *)&cmd_range_dstaddr_action,
831 (prog_void *)&cmd_range_dstaddr_dstaddr,
839 /* this structure is filled when cmd_monitor is parsed successfully */
840 struct cmd_monitor_result {
841 fixed_string_t monitor;
842 fixed_string_t action;
845 /* function called when cmd_monitor is parsed successfully */
846 static void cmd_monitor_parsed(void *parsed_result, void *data)
848 struct cmd_monitor_result *res = parsed_result;
849 struct monitor_reg *m;
851 if (!strcmp_P(res->action, PSTR("show"))) {
852 printf_P(PSTR("monitor period is %d ms, %d regs in list\r\n"),
853 monitor_period_ms, monitor_count);
854 LIST_FOREACH(m, &xbee_monitor_list, next)
855 printf_P(PSTR(" %S\r\n"), m->desc);
857 else if (!strcmp_P(res->action, PSTR("start"))) {
858 if (monitor_running) {
859 printf_P(PSTR("already running\r\n"));
862 if (monitor_count == 0) {
863 printf_P(PSTR("no regs to be monitored\r\n"));
866 callout_init(&monitor_event);
867 callout_reset(&cm, &monitor_event, 0, SINGLE, monitor_cb, NULL);
869 monitor_current = LIST_FIRST(&xbee_monitor_list);
870 printf_P(PSTR("monitor cb: %S %s\r\n"),
871 monitor_current->desc,
872 monitor_current->atcmd);
875 else if (!strcmp_P(res->action, PSTR("end"))) {
876 if (monitor_running == 0) {
877 printf_P(PSTR("not running\r\n"));
881 callout_stop(&cm, &monitor_event);
885 prog_char str_monitor[] = "monitor";
886 prog_char str_monitor_tokens[] = "show#start#end";
888 parse_pgm_token_string_t cmd_monitor_monitor =
889 TOKEN_STRING_INITIALIZER(struct cmd_monitor_result, monitor,
891 parse_pgm_token_string_t cmd_monitor_action =
892 TOKEN_STRING_INITIALIZER(struct cmd_monitor_result, action,
895 prog_char help_monitor[] = "start/stop/show current monitoring";
897 parse_pgm_inst_t cmd_monitor = {
898 .f = cmd_monitor_parsed, /* function to call */
899 .data = NULL, /* 2nd arg of func */
900 .help_str = help_monitor,
901 .tokens = { /* token list, NULL terminated */
902 (prog_void *)&cmd_monitor_monitor,
903 (prog_void *)&cmd_monitor_action,
910 /* this structure is filled when cmd_monitor_add is parsed successfully */
911 struct cmd_monitor_add_result {
912 fixed_string_t monitor;
913 fixed_string_t action;
914 struct xbee_atcmd_pgm *cmd;
917 /* function called when cmd_monitor_add is parsed successfully */
918 static void cmd_monitor_add_parsed(void *parsed_result, void *data)
920 struct cmd_monitor_add_result *res = parsed_result;
921 struct monitor_reg *m;
922 struct xbee_atcmd copy;
924 memcpy_P(©, res->cmd, sizeof(copy));
925 LIST_FOREACH(m, &xbee_monitor_list, next) {
926 if (!strcmp_P(m->atcmd, copy.name))
931 printf_P(PSTR("already exist\r\n"));
935 m = malloc(sizeof(*m));
937 printf_P(PSTR("no mem\r\n"));
941 strcpy_P(m->atcmd, copy.name);
942 LIST_INSERT_HEAD(&xbee_monitor_list, m, next);
946 prog_char str_monitor_add[] = "add";
948 parse_pgm_token_string_t cmd_monitor_add_monitor_add =
949 TOKEN_STRING_INITIALIZER(struct cmd_monitor_add_result, monitor,
951 parse_pgm_token_string_t cmd_monitor_add_action =
952 TOKEN_STRING_INITIALIZER(struct cmd_monitor_add_result, action,
954 parse_pgm_token_atcmd_t cmd_monitor_add_atcmd =
955 TOKEN_ATCMD_INITIALIZER(struct cmd_monitor_add_result, cmd, &xbee_dev,
956 XBEE_ATCMD_F_READ, XBEE_ATCMD_F_READ);
959 prog_char help_monitor_add[] = "add a register in monitor list";
961 parse_pgm_inst_t cmd_monitor_add = {
962 .f = cmd_monitor_add_parsed, /* function to call */
963 .data = NULL, /* 2nd arg of func */
964 .help_str = help_monitor_add,
965 .tokens = { /* token list, NULL terminated */
966 (prog_void *)&cmd_monitor_add_monitor_add,
967 (prog_void *)&cmd_monitor_add_action,
968 (prog_void *)&cmd_monitor_add_atcmd,
975 /* this structure is filled when cmd_monitor_period is parsed successfully */
976 struct cmd_monitor_period_result {
977 fixed_string_t monitor;
978 fixed_string_t action;
982 /* function called when cmd_monitor_period is parsed successfully */
983 static void cmd_monitor_period_parsed(void *parsed_result, void *data)
985 struct cmd_monitor_period_result *res = parsed_result;
987 if (res->period < 100) {
988 printf_P(PSTR("error, minimum period is 100 ms\r\n"));
992 monitor_period_ms = res->period;
995 prog_char str_monitor_period[] = "period";
997 parse_pgm_token_string_t cmd_monitor_period_monitor_period =
998 TOKEN_STRING_INITIALIZER(struct cmd_monitor_period_result, monitor,
1000 parse_pgm_token_string_t cmd_monitor_period_action =
1001 TOKEN_STRING_INITIALIZER(struct cmd_monitor_period_result, action,
1002 str_monitor_period);
1003 parse_pgm_token_num_t cmd_monitor_period_period =
1004 TOKEN_NUM_INITIALIZER(struct cmd_monitor_period_result, period, UINT32);
1007 prog_char help_monitor_period[] = "set register monitoring period";
1009 parse_pgm_inst_t cmd_monitor_period = {
1010 .f = cmd_monitor_period_parsed, /* function to call */
1011 .data = NULL, /* 2nd arg of func */
1012 .help_str = help_monitor_period,
1013 .tokens = { /* token list, NULL terminated */
1014 (prog_void *)&cmd_monitor_period_monitor_period,
1015 (prog_void *)&cmd_monitor_period_action,
1016 (prog_void *)&cmd_monitor_period_period,
1023 /* this structure is filled when cmd_monitor_del is parsed successfully */
1024 struct cmd_monitor_del_result {
1025 fixed_string_t monitor;
1026 fixed_string_t action;
1027 struct monitor_reg *m;
1030 /* function called when cmd_monitor_del is parsed successfully */
1031 static void cmd_monitor_del_parsed(void *parsed_result, void *data)
1033 struct cmd_monitor_del_result *res = parsed_result;
1035 monitor_current = LIST_NEXT(res->m, next);
1036 LIST_REMOVE(res->m, next);
1039 if (monitor_count == 0) {
1040 printf_P(PSTR("Disable monitoring, no more event\r\n"));
1041 callout_stop(&cm, &monitor_event);
1042 monitor_running = 0;
1047 prog_char str_monitor_del[] = "del";
1049 parse_pgm_token_string_t cmd_monitor_del_monitor_del =
1050 TOKEN_STRING_INITIALIZER(struct cmd_monitor_del_result, monitor,
1052 parse_pgm_token_string_t cmd_monitor_del_action =
1053 TOKEN_STRING_INITIALIZER(struct cmd_monitor_del_result, action,
1055 parse_pgm_token_monitor_t cmd_monitor_del_atcmd =
1056 TOKEN_MONITOR_INITIALIZER(struct cmd_monitor_del_result, m);
1059 prog_char help_monitor_del[] = "del a register in monitor list";
1061 parse_pgm_inst_t cmd_monitor_del = {
1062 .f = cmd_monitor_del_parsed, /* function to call */
1063 .data = NULL, /* 2nd arg of func */
1064 .help_str = help_monitor_del,
1065 .tokens = { /* token list, NULL terminated */
1066 (prog_void *)&cmd_monitor_del_monitor_del,
1067 (prog_void *)&cmd_monitor_del_action,
1068 (prog_void *)&cmd_monitor_del_atcmd,
1076 /* this structure is filled when cmd_ping is parsed successfully */
1077 struct cmd_ping_result {
1078 fixed_string_t ping;
1081 /* function called when cmd_ping is parsed successfully */
1082 static void cmd_ping_parsed(void *parsed_result, void *data)
1084 xbeeapp_send_atcmd("VL", NULL, 0, 1, NULL, NULL);
1087 prog_char str_ping[] = "ping";
1089 parse_pgm_token_string_t cmd_ping_ping =
1090 TOKEN_STRING_INITIALIZER(struct cmd_ping_result, ping,
1093 prog_char help_ping[] = "Send a ping to the xbee device";
1095 parse_pgm_inst_t cmd_ping = {
1096 .f = cmd_ping_parsed, /* function to call */
1097 .data = NULL, /* 2nd arg of func */
1098 .help_str = help_ping,
1099 .tokens = { /* token list, NULL terminated */
1100 (prog_void *)&cmd_ping_ping,
1107 /* this structure is filled when cmd_raw is parsed successfully */
1108 struct cmd_raw_result {
1112 /* function called when cmd_raw is parsed successfully */
1113 static void cmd_raw_parsed(void *parsed_result, void *data)
1115 printf_P(PSTR("switched to raw mode, CTRL-D to exit\r\n"));
1116 rdline_stop(&xbeeboard.rdl); /* don't display prompt when return */
1120 prog_char str_raw[] = "raw";
1122 parse_pgm_token_string_t cmd_raw_raw =
1123 TOKEN_STRING_INITIALIZER(struct cmd_raw_result, raw,
1126 prog_char help_raw[] = "Switch to raw mode";
1128 parse_pgm_inst_t cmd_raw = {
1129 .f = cmd_raw_parsed, /* function to call */
1130 .data = NULL, /* 2nd arg of func */
1131 .help_str = help_raw,
1132 .tokens = { /* token list, NULL terminated */
1133 (prog_void *)&cmd_raw_raw,
1140 /* this structure is filled when cmd_dump is parsed successfully */
1141 struct cmd_dump_result {
1142 fixed_string_t dump;
1143 fixed_string_t onoff;
1146 /* function called when cmd_dump is parsed successfully */
1147 static void cmd_dump_parsed(void *parsed_result, void *data)
1149 struct cmd_dump_result *res = parsed_result;
1150 if (!strcmp(res->onoff, "on"))
1156 prog_char str_dump[] = "dump";
1157 prog_char str_dump_onoff[] = "on#off";
1159 parse_pgm_token_string_t cmd_dump_dump =
1160 TOKEN_STRING_INITIALIZER(struct cmd_dump_result, dump,
1163 parse_pgm_token_string_t cmd_dump_onoff =
1164 TOKEN_STRING_INITIALIZER(struct cmd_dump_result, onoff,
1167 prog_char help_dump[] = "enable/disable hexdump of received packets";
1169 parse_pgm_inst_t cmd_dump = {
1170 .f = cmd_dump_parsed, /* function to call */
1171 .data = NULL, /* 2nd arg of func */
1172 .help_str = help_dump,
1173 .tokens = { /* token list, NULL terminated */
1174 (prog_void *)&cmd_dump_dump,
1175 (prog_void *)&cmd_dump_onoff,
1182 /* this structure is filled when cmd_debug is parsed successfully */
1183 struct cmd_debug_result {
1184 fixed_string_t debug;
1185 fixed_string_t onoff;
1188 /* function called when cmd_debug is parsed successfully */
1189 static void cmd_debug_parsed(void *parsed_result, void *data)
1191 struct cmd_debug_result *res = parsed_result;
1192 if (!strcmp(res->onoff, "on"))
1198 prog_char str_debug[] = "debug";
1199 prog_char str_debug_onoff[] = "on#off";
1201 parse_pgm_token_string_t cmd_debug_debug =
1202 TOKEN_STRING_INITIALIZER(struct cmd_debug_result, debug,
1205 parse_pgm_token_string_t cmd_debug_onoff =
1206 TOKEN_STRING_INITIALIZER(struct cmd_debug_result, onoff,
1209 prog_char help_debug[] = "enable/disable additionnal debug";
1211 parse_pgm_inst_t cmd_debug = {
1212 .f = cmd_debug_parsed, /* function to call */
1213 .data = NULL, /* 2nd arg of func */
1214 .help_str = help_debug,
1215 .tokens = { /* token list, NULL terminated */
1216 (prog_void *)&cmd_debug_debug,
1217 (prog_void *)&cmd_debug_onoff,
1223 /**********************************************************/
1225 /* this structure is filled when cmd_baudrate is parsed successfully */
1226 struct cmd_baudrate_result {
1227 fixed_string_t arg0;
1231 /* function called when cmd_baudrate is parsed successfully */
1232 static void cmd_baudrate_parsed(void * parsed_result, __attribute__((unused)) void *data)
1234 struct cmd_baudrate_result *res = parsed_result;
1235 struct uart_config c;
1237 uart_getconf(XBEE_UART, &c);
1238 c.baudrate = res->arg1;
1239 uart_setconf(XBEE_UART, &c);
1242 prog_char str_baudrate_arg0[] = "baudrate";
1243 parse_pgm_token_string_t cmd_baudrate_arg0 =
1244 TOKEN_STRING_INITIALIZER(struct cmd_baudrate_result, arg0,
1246 parse_pgm_token_num_t cmd_baudrate_arg1 =
1247 TOKEN_NUM_INITIALIZER(struct cmd_baudrate_result, arg1,
1250 prog_char help_baudrate[] = "Change xbee baudrate";
1251 parse_pgm_inst_t cmd_baudrate = {
1252 .f = cmd_baudrate_parsed, /* function to call */
1253 .data = NULL, /* 2nd arg of func */
1254 .help_str = help_baudrate,
1255 .tokens = { /* token list, NULL terminated */
1256 (prog_void *)&cmd_baudrate_arg0,
1257 (prog_void *)&cmd_baudrate_arg1,
1263 /* this structure is filled when cmd_test_spi is parsed successfully */
1264 struct cmd_test_spi_result {
1265 fixed_string_t arg0;
1268 static void cmd_test_spi_parsed(void * parsed_result,
1269 __attribute__((unused)) void *data)
1275 for (i = 0; i < 50; i++) {
1276 spi_servo_set(0, 0);
1278 spi_servo_set(0, 500);
1282 spi_servo_bypass(1);
1284 spi_servo_bypass(0);
1289 prog_char str_test_spi_arg0[] = "test_spi";
1290 parse_pgm_token_string_t cmd_test_spi_arg0 =
1291 TOKEN_STRING_INITIALIZER(struct cmd_test_spi_result, arg0,
1294 prog_char help_test_spi[] = "Test the spi";
1295 parse_pgm_inst_t cmd_test_spi = {
1296 .f = cmd_test_spi_parsed, /* function to call */
1297 .data = NULL, /* 2nd arg of func */
1298 .help_str = help_test_spi,
1299 .tokens = { /* token list, NULL terminated */
1300 (prog_void *)&cmd_test_spi_arg0,
1306 parse_pgm_ctx_t main_ctx[] = {
1308 /* commands_gen.c */
1309 (parse_pgm_inst_t *)&cmd_reset,
1310 (parse_pgm_inst_t *)&cmd_bootloader,
1311 (parse_pgm_inst_t *)&cmd_log,
1312 (parse_pgm_inst_t *)&cmd_log_show,
1313 (parse_pgm_inst_t *)&cmd_log_type,
1314 (parse_pgm_inst_t *)&cmd_stack_space,
1315 (parse_pgm_inst_t *)&cmd_scheduler,
1316 (parse_pgm_inst_t *)&cmd_help,
1317 (parse_pgm_inst_t *)&cmd_neigh_del,
1318 (parse_pgm_inst_t *)&cmd_neigh_add,
1319 (parse_pgm_inst_t *)&cmd_neigh_list,
1320 (parse_pgm_inst_t *)&cmd_read,
1321 (parse_pgm_inst_t *)&cmd_write_none,
1322 (parse_pgm_inst_t *)&cmd_write_u8,
1323 (parse_pgm_inst_t *)&cmd_write_u16,
1324 (parse_pgm_inst_t *)&cmd_write_u32,
1325 (parse_pgm_inst_t *)&cmd_sendmsg,
1326 (parse_pgm_inst_t *)&cmd_sendmsg_name,
1327 (parse_pgm_inst_t *)&cmd_range,
1328 (parse_pgm_inst_t *)&cmd_range_period,
1329 (parse_pgm_inst_t *)&cmd_range_count,
1330 (parse_pgm_inst_t *)&cmd_range_powermask,
1331 (parse_pgm_inst_t *)&cmd_range_dstaddr,
1332 (parse_pgm_inst_t *)&cmd_monitor,
1333 (parse_pgm_inst_t *)&cmd_monitor_period,
1334 (parse_pgm_inst_t *)&cmd_monitor_add,
1335 (parse_pgm_inst_t *)&cmd_monitor_del,
1336 (parse_pgm_inst_t *)&cmd_ping,
1337 (parse_pgm_inst_t *)&cmd_raw,
1338 (parse_pgm_inst_t *)&cmd_dump,
1339 (parse_pgm_inst_t *)&cmd_debug,
1341 (parse_pgm_inst_t *)&cmd_baudrate,
1343 (parse_pgm_inst_t *)&cmd_test_spi,