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"
50 #include "eeprom_config.h"
53 extern const parse_inst_t PROGMEM cmd_reset;
54 extern const parse_inst_t PROGMEM cmd_bootloader;
55 extern const parse_inst_t PROGMEM cmd_log;
56 extern const parse_inst_t PROGMEM cmd_log_show;
57 extern const parse_inst_t PROGMEM cmd_log_type;
58 extern const parse_inst_t PROGMEM cmd_stack_space;
59 extern const parse_inst_t PROGMEM cmd_scheduler;
61 static int monitor_period_ms = 1000;
62 static int monitor_running = 0;
63 static int monitor_count = 0;
64 static struct callout monitor_event;
65 struct monitor_reg *monitor_current;
67 static int range_period_ms = 1000;
68 static int range_powermask = 0x1F;
69 //static uint8_t range_power = 0;
70 static int range_running = 0;
71 static uint64_t range_dstaddr = 0xFFFF; /* broadcast by default */
72 static struct callout range_event;
73 static int range_count = 100;
74 static int range_cur_count = 0;
76 static void monitor_cb(struct callout_mgr *cm,
77 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_reschedule(cm, clt, monitor_period_ms / monitor_count);
90 static void range_cb(struct callout_mgr *cm,
91 struct callout *clt, void *dummy)
98 struct rc_proto_range rangepkt;
105 /* get new xmit power */
106 for (i = 1; i <= 8; i++) {
107 mask = 1 << ((range_power + i) & 0x7);
108 if (mask & range_powermask)
111 range_power = ((range_power + i) & 0x7);
113 xbeeapp_send_atcmd("PL", &range_power, sizeof(range_power), 0, NULL, NULL);
115 rangepkt.type = RC_PROTO_TYPE_RANGE;
116 rangepkt.power_level = range_power;
118 xbeeapp_send_msg(range_dstaddr, &rangepkt, sizeof(rangepkt), 0);
120 if (range_cur_count == 0) {
125 callout_reschedule(cm, clt, range_period_ms);
129 /* this structure is filled when cmd_help is parsed successfully */
130 struct cmd_help_result {
132 struct xbee_atcmd *cmd;
135 /* function called when cmd_help is parsed successfully */
136 static void cmd_help_parsed(void *parsed_result, void *data)
138 struct cmd_help_result *res = parsed_result;
139 struct xbee_atcmd cmdcopy;
144 memcpy_P(&cmdcopy, res->cmd, sizeof(cmdcopy));
145 type = (cmdcopy.flags & (XBEE_ATCMD_F_READ | XBEE_ATCMD_F_WRITE));
147 case XBEE_ATCMD_F_READ:
148 printf_P(PSTR("Read-only\r\n"));
150 case XBEE_ATCMD_F_WRITE:
151 printf_P(PSTR("Write-only\r\n"));
154 printf_P(PSTR("Read-write\r\n"));
157 if (cmdcopy.flags & XBEE_ATCMD_F_PARAM_NONE)
158 printf_P(PSTR("No argument\r\n"));
159 else if (cmdcopy.flags & XBEE_ATCMD_F_PARAM_U8)
160 printf_P(PSTR("Register is unsigned 8 bits\r\n"));
161 else if (cmdcopy.flags & XBEE_ATCMD_F_PARAM_U16)
162 printf_P(PSTR("Register is unsigned 16 bits\r\n"));
163 else if (cmdcopy.flags & XBEE_ATCMD_F_PARAM_U32)
164 printf_P(PSTR("Register is unsigned 32 bits\r\n"));
165 else if (cmdcopy.flags & XBEE_ATCMD_F_PARAM_S16)
166 printf_P(PSTR("Register is signed 16 bits\r\n"));
167 else if (cmdcopy.flags & XBEE_ATCMD_F_PARAM_STRING_20B)
168 printf_P(PSTR("Register is a 20 bytes string\r\n"));
170 printf_P(PSTR("Unknown argument\r\n"));
172 printf_P(PSTR("%S\r\n"), cmdcopy.help);
174 const char PROGMEM str_help_help[] = "help";
176 const parse_token_string_t PROGMEM cmd_help_help =
177 TOKEN_STRING_INITIALIZER(struct cmd_help_result, help, str_help_help);
179 const parse_token_atcmd_t PROGMEM cmd_help_atcmd =
180 TOKEN_ATCMD_INITIALIZER(struct cmd_help_result, cmd, &xbee_dev,
183 const char PROGMEM help_help[] = "Help a register using an AT command";
184 const parse_inst_t PROGMEM cmd_help = {
185 .f = cmd_help_parsed, /* function to call */
186 .data = NULL, /* 2nd arg of func */
187 .help_str = help_help,
188 .tokens = { /* token list, NULL terminated */
189 (PGM_P)&cmd_help_help,
190 (PGM_P)&cmd_help_atcmd,
197 struct cmd_neigh_del_result {
199 fixed_string_t action;
200 struct xbee_neigh *neigh;
203 static void cmd_neigh_del_parsed(void *parsed_result,
206 struct cmd_neigh_del_result *res = parsed_result;
209 xbee_neigh_del(xbee_dev, res->neigh);
212 const char PROGMEM str_neigh_del_neigh[] = "neigh";
213 const parse_token_string_t PROGMEM cmd_neigh_del_cmd =
214 TOKEN_STRING_INITIALIZER(struct cmd_neigh_del_result, cmd,
215 str_neigh_del_neigh);
216 const char PROGMEM str_neigh_del_del[] = "del";
217 const parse_token_string_t PROGMEM cmd_neigh_del_action =
218 TOKEN_STRING_INITIALIZER(struct cmd_neigh_del_result, action,
220 const parse_token_neighbor_t PROGMEM cmd_neigh_del_neigh =
221 TOKEN_NEIGHBOR_INITIALIZER(struct cmd_neigh_del_result, neigh,
224 const char PROGMEM help_neigh_del[] = "delete a neighbor";
225 const parse_inst_t PROGMEM cmd_neigh_del = {
226 .f = cmd_neigh_del_parsed, /* function to call */
227 .data = NULL, /* 2nd arg of func */
228 .help_str = help_neigh_del,
229 .tokens = { /* token list, NULL terminated */
230 (PGM_P)&cmd_neigh_del_cmd,
231 (PGM_P)&cmd_neigh_del_action,
232 (PGM_P)&cmd_neigh_del_neigh,
239 struct cmd_neigh_add_result {
241 fixed_string_t action;
246 static void cmd_neigh_add_parsed(void *parsed_result,
249 struct cmd_neigh_add_result *res = parsed_result;
252 if (xbee_neigh_add(xbee_dev, res->name, res->addr) == NULL)
253 printf_P(PSTR("name or addr already exist\r\n"));
256 const char PROGMEM str_neigh_add_neigh[] = "neigh";
257 const parse_token_string_t PROGMEM cmd_neigh_add_cmd =
258 TOKEN_STRING_INITIALIZER(struct cmd_neigh_add_result, cmd,
259 str_neigh_add_neigh);
260 const char PROGMEM str_neigh_add_add[] = "add";
261 const parse_token_string_t PROGMEM cmd_neigh_add_action =
262 TOKEN_STRING_INITIALIZER(struct cmd_neigh_add_result, action,
264 const parse_token_string_t PROGMEM cmd_neigh_add_name =
265 TOKEN_STRING_INITIALIZER(struct cmd_neigh_add_result, name, NULL);
266 const parse_token_num_t PROGMEM cmd_neigh_add_addr =
267 TOKEN_NUM_INITIALIZER(struct cmd_neigh_add_result, addr, UINT64);
269 const char PROGMEM help_neigh_add[] = "add a neighbor";
270 const parse_inst_t PROGMEM cmd_neigh_add = {
271 .f = cmd_neigh_add_parsed, /* function to call */
272 .data = NULL, /* 2nd arg of func */
273 .help_str = help_neigh_add,
274 .tokens = { /* token list, NULL terminated */
275 (PGM_P)&cmd_neigh_add_cmd,
276 (PGM_P)&cmd_neigh_add_action,
277 (PGM_P)&cmd_neigh_add_name,
278 (PGM_P)&cmd_neigh_add_addr,
285 struct cmd_neigh_list_result {
287 fixed_string_t action;
290 static void cmd_neigh_list_parsed(void *parsed_result,
293 struct xbee_neigh *neigh;
297 LIST_FOREACH(neigh, &xbee_dev->neigh_list, next) {
298 printf_P(PSTR(" %s: 0x%.8"PRIx32"%.8"PRIx32"\r\n"),
300 (uint32_t)(neigh->addr >> 32ULL),
301 (uint32_t)(neigh->addr & 0xFFFFFFFF));
305 const char PROGMEM str_neigh_list_neigh[] = "neigh";
306 const parse_token_string_t PROGMEM cmd_neigh_list_cmd =
307 TOKEN_STRING_INITIALIZER(struct cmd_neigh_list_result, cmd,
308 str_neigh_list_neigh);
309 const char PROGMEM str_neigh_list_list[] = "list";
310 const parse_token_string_t PROGMEM cmd_neigh_list_action =
311 TOKEN_STRING_INITIALIZER(struct cmd_neigh_list_result, action,
312 str_neigh_list_list);
314 const char PROGMEM help_neigh_list[] = "list all knwon neighbors";
315 const parse_inst_t PROGMEM cmd_neigh_list = {
316 .f = cmd_neigh_list_parsed, /* function to call */
317 .data = NULL, /* 2nd arg of func */
318 .help_str = help_neigh_list,
319 .tokens = { /* token list, NULL terminated */
320 (PGM_P)&cmd_neigh_list_cmd,
321 (PGM_P)&cmd_neigh_list_action,
331 /* this structure is filled when cmd_read is parsed successfully */
332 struct cmd_read_result {
334 struct xbee_atcmd *cmd;
337 /* function called when cmd_read is parsed successfully */
338 static void cmd_read_parsed(void *parsed_result,
341 struct cmd_read_result *res = parsed_result;
342 struct xbee_atcmd copy;
346 memcpy_P(©, res->cmd, sizeof(copy));
347 memcpy_P(&cmd, copy.name, 2);
349 xbeeapp_send_atcmd(cmd, NULL, 0, 1, NULL, NULL);
352 const char PROGMEM str_read_read[] = "read";
354 const parse_token_string_t PROGMEM cmd_read_read =
355 TOKEN_STRING_INITIALIZER(struct cmd_read_result, read,
358 const parse_token_atcmd_t PROGMEM cmd_read_atcmd =
359 TOKEN_ATCMD_INITIALIZER(struct cmd_read_result, cmd, &xbee_dev,
360 XBEE_ATCMD_F_READ, XBEE_ATCMD_F_READ);
362 const char PROGMEM help_read[] = "Read a register using an AT command";
363 const parse_inst_t PROGMEM cmd_read = {
364 .f = cmd_read_parsed, /* function to call */
365 .data = NULL, /* 2nd arg of func */
366 .help_str = help_read,
367 .tokens = { /* token list, NULL terminated */
368 (PGM_P)&cmd_read_read,
369 (PGM_P)&cmd_read_atcmd,
377 /* this structure is filled when cmd_write is parsed successfully */
378 struct cmd_write_result {
379 fixed_string_t write;
380 struct xbee_atcmd *cmd;
388 /* function called when cmd_write is parsed successfully */
389 static void cmd_write_parsed(void *parsed_result, void *data)
391 struct cmd_write_result *res = parsed_result;
392 struct xbee_atcmd copy;
398 memcpy_P(©, res->cmd, sizeof(copy));
400 if (copy.flags & XBEE_ATCMD_F_PARAM_NONE) {
404 else if (copy.flags & XBEE_ATCMD_F_PARAM_U8) {
405 len = sizeof(res->u8);
408 else if (copy.flags & XBEE_ATCMD_F_PARAM_U16) {
409 len = sizeof(res->u16);
410 res->u16 = htons(res->u16);
413 else if (copy.flags & XBEE_ATCMD_F_PARAM_U32) {
414 len = sizeof(res->u32);
415 res->u32 = htonl(res->u32);
419 printf_P(PSTR("Unknown argument type\r\n"));
422 memcpy_P(&cmd, copy.name, 2);
424 xbeeapp_send_atcmd(cmd, param, len, 1, NULL, NULL);
427 const char PROGMEM str_write_none[] = "write";
429 const parse_token_string_t PROGMEM cmd_write_write =
430 TOKEN_STRING_INITIALIZER(struct cmd_write_result, write,
433 const parse_token_atcmd_t PROGMEM cmd_write_none_atcmd =
434 TOKEN_ATCMD_INITIALIZER(struct cmd_write_result, cmd,
436 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_NONE,
437 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_NONE);
439 const char PROGMEM help_write_none[] = "Send an AT command (no argument)";
441 const parse_inst_t PROGMEM cmd_write_none = {
442 .f = cmd_write_parsed, /* function to call */
443 .data = NULL, /* 2nd arg of func */
444 .help_str = help_write_none,
445 .tokens = { /* token list, NULL terminated */
446 (PGM_P)&cmd_write_write,
447 (PGM_P)&cmd_write_none_atcmd,
452 const parse_token_atcmd_t PROGMEM cmd_write_u8_atcmd =
453 TOKEN_ATCMD_INITIALIZER(struct cmd_write_result, cmd,
455 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_U8,
456 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_U8);
458 const parse_token_num_t PROGMEM cmd_write_u8_u8 =
459 TOKEN_NUM_INITIALIZER(struct cmd_write_result, u8, UINT8);
461 const char PROGMEM help_write_u8[] = "Write a 8 bits register using an AT command";
463 const parse_inst_t PROGMEM cmd_write_u8 = {
464 .f = cmd_write_parsed, /* function to call */
465 .data = NULL, /* 2nd arg of func */
466 .help_str = help_write_u8,
467 .tokens = { /* token list, NULL terminated */
468 (PGM_P)&cmd_write_write,
469 (PGM_P)&cmd_write_u8_atcmd,
470 (PGM_P)&cmd_write_u8_u8,
475 const parse_token_atcmd_t PROGMEM cmd_write_u16_atcmd =
476 TOKEN_ATCMD_INITIALIZER(struct cmd_write_result, cmd,
478 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_U16,
479 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_U16);
481 const parse_token_num_t PROGMEM cmd_write_u16_u16 =
482 TOKEN_NUM_INITIALIZER(struct cmd_write_result, u16, UINT16);
484 const char PROGMEM help_write_u16[] = "Write a 16 bits register using an AT command";
486 const parse_inst_t PROGMEM cmd_write_u16 = {
487 .f = cmd_write_parsed, /* function to call */
488 .data = NULL, /* 2nd arg of func */
489 .help_str = help_write_u16,
490 .tokens = { /* token list, NULL terminated */
491 (PGM_P)&cmd_write_write,
492 (PGM_P)&cmd_write_u16_atcmd,
493 (PGM_P)&cmd_write_u16_u16,
498 const parse_token_atcmd_t PROGMEM cmd_write_u32_atcmd =
499 TOKEN_ATCMD_INITIALIZER(struct cmd_write_result, cmd,
501 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_U32,
502 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_U32);
504 const parse_token_num_t PROGMEM cmd_write_u32_u32 =
505 TOKEN_NUM_INITIALIZER(struct cmd_write_result, u32, UINT32);
507 const char PROGMEM help_write_u32[] = "Write a 32 bits register using an AT command";
509 const parse_inst_t PROGMEM cmd_write_u32 = {
510 .f = cmd_write_parsed, /* function to call */
511 .data = NULL, /* 2nd arg of func */
512 .help_str = help_write_u32,
513 .tokens = { /* token list, NULL terminated */
514 (PGM_P)&cmd_write_write,
515 (PGM_P)&cmd_write_u32_atcmd,
516 (PGM_P)&cmd_write_u32_u32,
524 /* this structure is filled when cmd_sendmsg is parsed successfully */
525 struct cmd_sendmsg_result {
526 fixed_string_t sendmsg;
531 /* function called when cmd_sendmsg is parsed successfully */
532 static void cmd_sendmsg_parsed(void *parsed_result, void *data)
534 struct cmd_sendmsg_result *res = parsed_result;
537 xbeeapp_send_msg(res->addr, res->data, strlen(res->data), 1);
540 const char PROGMEM str_sendmsg[] = "sendmsg";
542 const parse_token_string_t PROGMEM cmd_sendmsg_sendmsg =
543 TOKEN_STRING_INITIALIZER(struct cmd_sendmsg_result, sendmsg,
546 const parse_token_num_t PROGMEM cmd_sendmsg_addr =
547 TOKEN_NUM_INITIALIZER(struct cmd_sendmsg_result, addr, UINT64);
549 const parse_token_string_t PROGMEM cmd_sendmsg_data =
550 TOKEN_STRING_INITIALIZER(struct cmd_sendmsg_result, data, NULL);
552 const char PROGMEM help_sendmsg[] = "Send data to a node using its address";
554 const parse_inst_t PROGMEM cmd_sendmsg = {
555 .f = cmd_sendmsg_parsed, /* function to call */
556 .data = NULL, /* 2nd arg of func */
557 .help_str = help_sendmsg,
558 .tokens = { /* token list, NULL terminated */
559 (PGM_P)&cmd_sendmsg_sendmsg,
560 (PGM_P)&cmd_sendmsg_addr,
561 (PGM_P)&cmd_sendmsg_data,
568 /* this structure is filled when cmd_send_hello is parsed successfully */
569 struct cmd_send_hello_result {
570 fixed_string_t send_hello;
572 struct xbee_neigh *neigh;
578 /* function called when cmd_send_hello is parsed successfully */
579 static void cmd_send_hello_parsed(void *parsed_result, void *use_neigh)
581 struct cmd_send_hello_result *res = parsed_result;
582 uint16_t now, next, diff;
587 addr = res->neigh->addr;
597 while (!cmdline_keypressed() && res->count != 0) {
603 if (diff < res->period)
606 rc_proto_send_hello(addr, res->data, strlen(res->data));
612 const char PROGMEM str_send_hello[] = "send_hello";
614 const parse_token_string_t PROGMEM cmd_send_hello_send_hello =
615 TOKEN_STRING_INITIALIZER(struct cmd_send_hello_result, send_hello,
618 const parse_token_num_t PROGMEM cmd_send_hello_addr =
619 TOKEN_NUM_INITIALIZER(struct cmd_send_hello_result, addr, UINT64);
621 const parse_token_num_t PROGMEM cmd_send_hello_period =
622 TOKEN_NUM_INITIALIZER(struct cmd_send_hello_result, period, UINT16);
624 const parse_token_num_t PROGMEM cmd_send_hello_count =
625 TOKEN_NUM_INITIALIZER(struct cmd_send_hello_result, count, UINT16);
627 const parse_token_string_t PROGMEM cmd_send_hello_data =
628 TOKEN_STRING_INITIALIZER(struct cmd_send_hello_result, data, NULL);
630 const char PROGMEM help_send_hello[] =
631 "Send hello msg to a node: addr, period_ms, count, str";
633 const parse_inst_t PROGMEM cmd_send_hello = {
634 .f = cmd_send_hello_parsed, /* function to call */
635 .data = NULL, /* 2nd arg of func */
636 .help_str = help_send_hello,
637 .tokens = { /* token list, NULL terminated */
638 (PGM_P)&cmd_send_hello_send_hello,
639 (PGM_P)&cmd_send_hello_addr,
640 (PGM_P)&cmd_send_hello_period,
641 (PGM_P)&cmd_send_hello_count,
642 (PGM_P)&cmd_send_hello_data,
647 const parse_token_neighbor_t PROGMEM cmd_send_hello_neigh =
648 TOKEN_NEIGHBOR_INITIALIZER(struct cmd_send_hello_result, neigh,
651 const parse_inst_t PROGMEM cmd_send_hello_name = {
652 .f = cmd_send_hello_parsed, /* function to call */
653 .data = (void *)1, /* 2nd arg of func */
654 .help_str = help_send_hello,
655 .tokens = { /* token list, NULL terminated */
656 (PGM_P)&cmd_send_hello_send_hello,
657 (PGM_P)&cmd_send_hello_neigh,
658 (PGM_P)&cmd_send_hello_period,
659 (PGM_P)&cmd_send_hello_count,
660 (PGM_P)&cmd_send_hello_data,
667 /* this structure is filled when cmd_sendmsg_name is parsed successfully */
668 struct cmd_sendmsg_name_result {
669 fixed_string_t sendmsg_name;
670 struct xbee_neigh *neigh;
674 /* function called when cmd_sendmsg_name is parsed successfully */
675 static void cmd_sendmsg_name_parsed(void *parsed_result, void *data)
677 struct cmd_sendmsg_name_result *res = parsed_result;
680 xbeeapp_send_msg(res->neigh->addr, res->data, strlen(res->data), 1);
683 const parse_token_string_t PROGMEM cmd_sendmsg_name_sendmsg_name =
684 TOKEN_STRING_INITIALIZER(struct cmd_sendmsg_name_result, sendmsg_name,
687 const parse_token_neighbor_t PROGMEM cmd_sendmsg_name_neigh =
688 TOKEN_NEIGHBOR_INITIALIZER(struct cmd_sendmsg_name_result, neigh,
691 const parse_token_string_t PROGMEM cmd_sendmsg_name_data =
692 TOKEN_STRING_INITIALIZER(struct cmd_sendmsg_name_result, data, NULL);
694 const char PROGMEM help_sendmsg_name[] = "Send data to a node using its name";
696 const parse_inst_t PROGMEM cmd_sendmsg_name = {
697 .f = cmd_sendmsg_name_parsed, /* function to call */
698 .data = NULL, /* 2nd arg of func */
699 .help_str = help_sendmsg_name,
700 .tokens = { /* token list, NULL terminated */
701 (PGM_P)&cmd_sendmsg_name_sendmsg_name,
702 (PGM_P)&cmd_sendmsg_name_neigh,
703 (PGM_P)&cmd_sendmsg_name_data,
711 /* this structure is filled when cmd_range is parsed successfully */
712 struct cmd_range_result {
713 fixed_string_t range;
714 fixed_string_t action;
717 /* function called when cmd_range is parsed successfully */
718 static void cmd_range_parsed(void *parsed_result, void *data)
720 struct cmd_range_result *res = parsed_result;
723 if (!strcmp_P(res->action, PSTR("show"))) {
724 printf_P(PSTR("range infos:\r\n"));
725 printf_P(PSTR(" range period %d\r\n"), range_period_ms);
726 printf_P(PSTR(" range count %d\r\n"), range_count);
727 printf_P(PSTR(" range powermask 0x%x\r\n"), range_powermask);
728 printf_P(PSTR(" range dstaddr 0x%.8"PRIx32"%.8"PRIx32"\r\n"),
729 (uint32_t)(range_dstaddr >> 32ULL),
730 (uint32_t)(range_dstaddr & 0xFFFFFFFF));
733 printf_P(PSTR(" range test is running\r\n"));
735 printf_P(PSTR(" range test is not running\r\n"));
737 else if (!strcmp(res->action, "start")) {
739 printf_P(PSTR("already running\r\n"));
742 range_cur_count = range_count;
743 callout_init(&range_event, range_cb, NULL, 0);
744 callout_schedule(&cm, &range_event, 0); /* immediate */
747 else if (!strcmp(res->action, "end")) {
748 if (range_running == 0) {
749 printf_P(PSTR("not running\r\n"));
753 callout_stop(&cm, &range_event);
757 const char PROGMEM str_range[] = "range";
758 const char PROGMEM str_range_tokens[] = "show#start#end";
760 const parse_token_string_t PROGMEM cmd_range_range =
761 TOKEN_STRING_INITIALIZER(struct cmd_range_result, range,
763 const parse_token_string_t PROGMEM cmd_range_action =
764 TOKEN_STRING_INITIALIZER(struct cmd_range_result, action,
767 const char PROGMEM help_range[] = "start/stop/show current rangeing";
769 const parse_inst_t PROGMEM cmd_range = {
770 .f = cmd_range_parsed, /* function to call */
771 .data = NULL, /* 2nd arg of func */
772 .help_str = help_range,
773 .tokens = { /* token list, NULL terminated */
774 (PGM_P)&cmd_range_range,
775 (PGM_P)&cmd_range_action,
782 /* this structure is filled when cmd_range_period is parsed successfully */
783 struct cmd_range_period_result {
784 fixed_string_t range;
785 fixed_string_t action;
789 /* function called when cmd_range_period is parsed successfully */
790 static void cmd_range_period_parsed(void *parsed_result, void *data)
792 struct cmd_range_period_result *res = parsed_result;
795 if (res->period < 10) {
796 printf_P(PSTR("error, minimum period is 10 ms\r\n"));
800 range_period_ms = res->period;
803 const char PROGMEM str_period[] = "period";
805 const parse_token_string_t PROGMEM cmd_range_period_range_period =
806 TOKEN_STRING_INITIALIZER(struct cmd_range_period_result, range,
808 const parse_token_string_t PROGMEM cmd_range_period_action =
809 TOKEN_STRING_INITIALIZER(struct cmd_range_period_result, action,
811 const parse_token_num_t PROGMEM cmd_range_period_period =
812 TOKEN_NUM_INITIALIZER(struct cmd_range_period_result, period, UINT32);
814 const char PROGMEM help_range_period[] = "set range test period";
816 const parse_inst_t PROGMEM cmd_range_period = {
817 .f = cmd_range_period_parsed, /* function to call */
818 .data = NULL, /* 2nd arg of func */
819 .help_str = help_range_period,
820 .tokens = { /* token list, NULL terminated */
821 (PGM_P)&cmd_range_period_range_period,
822 (PGM_P)&cmd_range_period_action,
823 (PGM_P)&cmd_range_period_period,
830 /* this structure is filled when cmd_range_count is parsed successfully */
831 struct cmd_range_count_result {
832 fixed_string_t range;
833 fixed_string_t action;
837 /* function called when cmd_range_count is parsed successfully */
838 static void cmd_range_count_parsed(void *parsed_result, void *data)
840 struct cmd_range_count_result *res = parsed_result;
843 range_count = res->count;
846 const char PROGMEM str_count[] = "count";
848 const parse_token_string_t PROGMEM cmd_range_count_range_count =
849 TOKEN_STRING_INITIALIZER(struct cmd_range_count_result, range,
851 const parse_token_string_t PROGMEM cmd_range_count_action =
852 TOKEN_STRING_INITIALIZER(struct cmd_range_count_result, action,
854 const parse_token_num_t PROGMEM cmd_range_count_count =
855 TOKEN_NUM_INITIALIZER(struct cmd_range_count_result, count, UINT32);
858 const char PROGMEM help_range_count[] = "set range test count";
860 const parse_inst_t PROGMEM cmd_range_count = {
861 .f = cmd_range_count_parsed, /* function to call */
862 .data = NULL, /* 2nd arg of func */
863 .help_str = help_range_count,
864 .tokens = { /* token list, NULL terminated */
865 (PGM_P)&cmd_range_count_range_count,
866 (PGM_P)&cmd_range_count_action,
867 (PGM_P)&cmd_range_count_count,
874 /* this structure is filled when cmd_range_powermask is parsed successfully */
875 struct cmd_range_powermask_result {
876 fixed_string_t range;
877 fixed_string_t action;
881 /* function called when cmd_range_powermask is parsed successfully */
882 static void cmd_range_powermask_parsed(void *parsed_result, void *data)
884 struct cmd_range_powermask_result *res = parsed_result;
887 range_powermask = res->powermask;
890 const char PROGMEM str_powermask[] = "powermask";
892 const parse_token_string_t PROGMEM cmd_range_powermask_range_powermask =
893 TOKEN_STRING_INITIALIZER(struct cmd_range_powermask_result, range,
895 const parse_token_string_t PROGMEM cmd_range_powermask_action =
896 TOKEN_STRING_INITIALIZER(struct cmd_range_powermask_result, action,
898 const parse_token_num_t PROGMEM cmd_range_powermask_powermask =
899 TOKEN_NUM_INITIALIZER(struct cmd_range_powermask_result, powermask,
903 const char PROGMEM help_range_powermask[] = "set range test powermask";
905 const parse_inst_t PROGMEM cmd_range_powermask = {
906 .f = cmd_range_powermask_parsed, /* function to call */
907 .data = NULL, /* 2nd arg of func */
908 .help_str = help_range_powermask,
909 .tokens = { /* token list, NULL terminated */
910 (PGM_P)&cmd_range_powermask_range_powermask,
911 (PGM_P)&cmd_range_powermask_action,
912 (PGM_P)&cmd_range_powermask_powermask,
919 /* this structure is filled when cmd_range_dstaddr is parsed successfully */
920 struct cmd_range_dstaddr_result {
921 fixed_string_t range;
922 fixed_string_t action;
926 /* function called when cmd_range_dstaddr is parsed successfully */
927 static void cmd_range_dstaddr_parsed(void *parsed_result, void *data)
929 struct cmd_range_dstaddr_result *res = parsed_result;
932 range_dstaddr = res->dstaddr;
935 const char PROGMEM str_dstaddr[] = "dstaddr";
937 const parse_token_string_t PROGMEM cmd_range_dstaddr_range_dstaddr =
938 TOKEN_STRING_INITIALIZER(struct cmd_range_dstaddr_result, range,
940 const parse_token_string_t PROGMEM cmd_range_dstaddr_action =
941 TOKEN_STRING_INITIALIZER(struct cmd_range_dstaddr_result, action,
943 const parse_token_num_t PROGMEM cmd_range_dstaddr_dstaddr =
944 TOKEN_NUM_INITIALIZER(struct cmd_range_dstaddr_result, dstaddr, UINT64);
947 const char PROGMEM help_range_dstaddr[] = "set register rangeing dstaddr";
949 const parse_inst_t PROGMEM cmd_range_dstaddr = {
950 .f = cmd_range_dstaddr_parsed, /* function to call */
951 .data = NULL, /* 2nd arg of func */
952 .help_str = help_range_dstaddr,
953 .tokens = { /* token list, NULL terminated */
954 (PGM_P)&cmd_range_dstaddr_range_dstaddr,
955 (PGM_P)&cmd_range_dstaddr_action,
956 (PGM_P)&cmd_range_dstaddr_dstaddr,
964 /* this structure is filled when cmd_monitor is parsed successfully */
965 struct cmd_monitor_result {
966 fixed_string_t monitor;
967 fixed_string_t action;
970 /* function called when cmd_monitor is parsed successfully */
971 static void cmd_monitor_parsed(void *parsed_result, void *data)
973 struct cmd_monitor_result *res = parsed_result;
974 struct monitor_reg *m;
977 if (!strcmp_P(res->action, PSTR("show"))) {
978 printf_P(PSTR("monitor period is %d ms, %d regs in list\r\n"),
979 monitor_period_ms, monitor_count);
980 LIST_FOREACH(m, &xbee_monitor_list, next)
981 printf_P(PSTR(" %S\r\n"), m->desc);
983 else if (!strcmp_P(res->action, PSTR("start"))) {
984 if (monitor_running) {
985 printf_P(PSTR("already running\r\n"));
988 if (monitor_count == 0) {
989 printf_P(PSTR("no regs to be monitored\r\n"));
992 callout_init(&monitor_event, monitor_cb, NULL, 0);
993 callout_schedule(&cm, &monitor_event, 0); /* immediate */
995 monitor_current = LIST_FIRST(&xbee_monitor_list);
996 printf_P(PSTR("monitor cb: %S %s\r\n"),
997 monitor_current->desc,
998 monitor_current->atcmd);
1001 else if (!strcmp_P(res->action, PSTR("end"))) {
1002 if (monitor_running == 0) {
1003 printf_P(PSTR("not running\r\n"));
1006 monitor_running = 0;
1007 callout_stop(&cm, &monitor_event);
1011 const char PROGMEM str_monitor[] = "monitor";
1012 const char PROGMEM str_monitor_tokens[] = "show#start#end";
1014 const parse_token_string_t PROGMEM cmd_monitor_monitor =
1015 TOKEN_STRING_INITIALIZER(struct cmd_monitor_result, monitor,
1017 const parse_token_string_t PROGMEM cmd_monitor_action =
1018 TOKEN_STRING_INITIALIZER(struct cmd_monitor_result, action,
1019 str_monitor_tokens);
1021 const char PROGMEM help_monitor[] = "start/stop/show current monitoring";
1023 const parse_inst_t PROGMEM cmd_monitor = {
1024 .f = cmd_monitor_parsed, /* function to call */
1025 .data = NULL, /* 2nd arg of func */
1026 .help_str = help_monitor,
1027 .tokens = { /* token list, NULL terminated */
1028 (PGM_P)&cmd_monitor_monitor,
1029 (PGM_P)&cmd_monitor_action,
1036 /* this structure is filled when cmd_monitor_add is parsed successfully */
1037 struct cmd_monitor_add_result {
1038 fixed_string_t monitor;
1039 fixed_string_t action;
1040 struct xbee_atcmd *cmd;
1043 /* function called when cmd_monitor_add is parsed successfully */
1044 static void cmd_monitor_add_parsed(void *parsed_result, void *data)
1046 struct cmd_monitor_add_result *res = parsed_result;
1047 struct monitor_reg *m;
1048 struct xbee_atcmd copy;
1051 memcpy_P(©, res->cmd, sizeof(copy));
1052 LIST_FOREACH(m, &xbee_monitor_list, next) {
1053 if (!strcmp_P(m->atcmd, copy.name))
1058 printf_P(PSTR("already exist\r\n"));
1062 m = malloc(sizeof(*m));
1064 printf_P(PSTR("no mem\r\n"));
1067 m->desc = copy.desc;
1068 strcpy_P(m->atcmd, copy.name);
1069 LIST_INSERT_HEAD(&xbee_monitor_list, m, next);
1073 const char PROGMEM str_monitor_add[] = "add";
1075 const parse_token_string_t PROGMEM cmd_monitor_add_monitor_add =
1076 TOKEN_STRING_INITIALIZER(struct cmd_monitor_add_result, monitor,
1078 const parse_token_string_t PROGMEM cmd_monitor_add_action =
1079 TOKEN_STRING_INITIALIZER(struct cmd_monitor_add_result, action,
1081 const parse_token_atcmd_t PROGMEM cmd_monitor_add_atcmd =
1082 TOKEN_ATCMD_INITIALIZER(struct cmd_monitor_add_result, cmd, &xbee_dev,
1083 XBEE_ATCMD_F_READ, XBEE_ATCMD_F_READ);
1086 const char PROGMEM help_monitor_add[] = "add a register in monitor list";
1088 const parse_inst_t PROGMEM cmd_monitor_add = {
1089 .f = cmd_monitor_add_parsed, /* function to call */
1090 .data = NULL, /* 2nd arg of func */
1091 .help_str = help_monitor_add,
1092 .tokens = { /* token list, NULL terminated */
1093 (PGM_P)&cmd_monitor_add_monitor_add,
1094 (PGM_P)&cmd_monitor_add_action,
1095 (PGM_P)&cmd_monitor_add_atcmd,
1102 /* this structure is filled when cmd_monitor_period is parsed successfully */
1103 struct cmd_monitor_period_result {
1104 fixed_string_t monitor;
1105 fixed_string_t action;
1109 /* function called when cmd_monitor_period is parsed successfully */
1110 static void cmd_monitor_period_parsed(void *parsed_result, void *data)
1112 struct cmd_monitor_period_result *res = parsed_result;
1115 if (res->period < 100) {
1116 printf_P(PSTR("error, minimum period is 100 ms\r\n"));
1120 monitor_period_ms = res->period;
1123 const char PROGMEM str_monitor_period[] = "period";
1125 const parse_token_string_t PROGMEM cmd_monitor_period_monitor_period =
1126 TOKEN_STRING_INITIALIZER(struct cmd_monitor_period_result, monitor,
1128 const parse_token_string_t PROGMEM cmd_monitor_period_action =
1129 TOKEN_STRING_INITIALIZER(struct cmd_monitor_period_result, action,
1130 str_monitor_period);
1131 const parse_token_num_t PROGMEM cmd_monitor_period_period =
1132 TOKEN_NUM_INITIALIZER(struct cmd_monitor_period_result, period, UINT32);
1135 const char PROGMEM help_monitor_period[] = "set register monitoring period";
1137 const parse_inst_t PROGMEM cmd_monitor_period = {
1138 .f = cmd_monitor_period_parsed, /* function to call */
1139 .data = NULL, /* 2nd arg of func */
1140 .help_str = help_monitor_period,
1141 .tokens = { /* token list, NULL terminated */
1142 (PGM_P)&cmd_monitor_period_monitor_period,
1143 (PGM_P)&cmd_monitor_period_action,
1144 (PGM_P)&cmd_monitor_period_period,
1151 /* this structure is filled when cmd_monitor_del is parsed successfully */
1152 struct cmd_monitor_del_result {
1153 fixed_string_t monitor;
1154 fixed_string_t action;
1155 struct monitor_reg *m;
1158 /* function called when cmd_monitor_del is parsed successfully */
1159 static void cmd_monitor_del_parsed(void *parsed_result, void *data)
1161 struct cmd_monitor_del_result *res = parsed_result;
1164 monitor_current = LIST_NEXT(res->m, next);
1165 LIST_REMOVE(res->m, next);
1168 if (monitor_count == 0) {
1169 printf_P(PSTR("Disable monitoring, no more event\r\n"));
1170 callout_stop(&cm, &monitor_event);
1171 monitor_running = 0;
1176 const char PROGMEM str_monitor_del[] = "del";
1178 const parse_token_string_t PROGMEM cmd_monitor_del_monitor_del =
1179 TOKEN_STRING_INITIALIZER(struct cmd_monitor_del_result, monitor,
1181 const parse_token_string_t PROGMEM cmd_monitor_del_action =
1182 TOKEN_STRING_INITIALIZER(struct cmd_monitor_del_result, action,
1184 const parse_token_monitor_t PROGMEM cmd_monitor_del_atcmd =
1185 TOKEN_MONITOR_INITIALIZER(struct cmd_monitor_del_result, m);
1188 const char PROGMEM help_monitor_del[] = "del a register in monitor list";
1190 const parse_inst_t PROGMEM cmd_monitor_del = {
1191 .f = cmd_monitor_del_parsed, /* function to call */
1192 .data = NULL, /* 2nd arg of func */
1193 .help_str = help_monitor_del,
1194 .tokens = { /* token list, NULL terminated */
1195 (PGM_P)&cmd_monitor_del_monitor_del,
1196 (PGM_P)&cmd_monitor_del_action,
1197 (PGM_P)&cmd_monitor_del_atcmd,
1205 /* this structure is filled when cmd_ping is parsed successfully */
1206 struct cmd_ping_result {
1207 fixed_string_t ping;
1210 /* function called when cmd_ping is parsed successfully */
1211 static void cmd_ping_parsed(void *parsed_result, void *data)
1213 (void)parsed_result;
1215 xbeeapp_send_atcmd("VL", NULL, 0, 1, NULL, NULL);
1218 const char PROGMEM str_ping[] = "ping";
1220 const parse_token_string_t PROGMEM cmd_ping_ping =
1221 TOKEN_STRING_INITIALIZER(struct cmd_ping_result, ping,
1224 const char PROGMEM help_ping[] = "Send a ping to the xbee device";
1226 const parse_inst_t PROGMEM cmd_ping = {
1227 .f = cmd_ping_parsed, /* function to call */
1228 .data = NULL, /* 2nd arg of func */
1229 .help_str = help_ping,
1230 .tokens = { /* token list, NULL terminated */
1231 (PGM_P)&cmd_ping_ping,
1238 /* this structure is filled when cmd_raw is parsed successfully */
1239 struct cmd_raw_result {
1243 /* function called when cmd_raw is parsed successfully */
1244 static void cmd_raw_parsed(void *parsed_result, void *data)
1246 (void)parsed_result;
1248 printf_P(PSTR("switched to raw mode, CTRL-D to exit\r\n"));
1249 rdline_stop(&xbeeboard.rdl); /* don't display prompt when return */
1253 const char PROGMEM str_raw[] = "raw";
1255 const parse_token_string_t PROGMEM cmd_raw_raw =
1256 TOKEN_STRING_INITIALIZER(struct cmd_raw_result, raw,
1259 const char PROGMEM help_raw[] = "Switch to raw mode";
1261 const parse_inst_t PROGMEM cmd_raw = {
1262 .f = cmd_raw_parsed, /* function to call */
1263 .data = NULL, /* 2nd arg of func */
1264 .help_str = help_raw,
1265 .tokens = { /* token list, NULL terminated */
1266 (PGM_P)&cmd_raw_raw,
1273 /* this structure is filled when cmd_dump is parsed successfully */
1274 struct cmd_dump_result {
1275 fixed_string_t dump;
1276 fixed_string_t onoff;
1279 /* function called when cmd_dump is parsed successfully */
1280 static void cmd_dump_parsed(void *parsed_result, void *data)
1282 struct cmd_dump_result *res = parsed_result;
1285 if (!strcmp(res->onoff, "on"))
1291 const char PROGMEM str_dump[] = "dump";
1292 const char PROGMEM str_dump_onoff[] = "on#off";
1294 const parse_token_string_t PROGMEM cmd_dump_dump =
1295 TOKEN_STRING_INITIALIZER(struct cmd_dump_result, dump,
1298 const parse_token_string_t PROGMEM cmd_dump_onoff =
1299 TOKEN_STRING_INITIALIZER(struct cmd_dump_result, onoff,
1302 const char PROGMEM help_dump[] = "enable/disable hexdump of received packets";
1304 const parse_inst_t PROGMEM cmd_dump = {
1305 .f = cmd_dump_parsed, /* function to call */
1306 .data = NULL, /* 2nd arg of func */
1307 .help_str = help_dump,
1308 .tokens = { /* token list, NULL terminated */
1309 (PGM_P)&cmd_dump_dump,
1310 (PGM_P)&cmd_dump_onoff,
1317 /* this structure is filled when cmd_debug is parsed successfully */
1318 struct cmd_debug_result {
1319 fixed_string_t debug;
1320 fixed_string_t onoff;
1323 /* function called when cmd_debug is parsed successfully */
1324 static void cmd_debug_parsed(void *parsed_result, void *data)
1326 struct cmd_debug_result *res = parsed_result;
1329 if (!strcmp(res->onoff, "on"))
1335 const char PROGMEM str_debug[] = "debug";
1336 const char PROGMEM str_debug_onoff[] = "on#off";
1338 const parse_token_string_t PROGMEM cmd_debug_debug =
1339 TOKEN_STRING_INITIALIZER(struct cmd_debug_result, debug,
1342 const parse_token_string_t PROGMEM cmd_debug_onoff =
1343 TOKEN_STRING_INITIALIZER(struct cmd_debug_result, onoff,
1346 const char PROGMEM help_debug[] = "enable/disable additionnal debug";
1348 const parse_inst_t PROGMEM cmd_debug = {
1349 .f = cmd_debug_parsed, /* function to call */
1350 .data = NULL, /* 2nd arg of func */
1351 .help_str = help_debug,
1352 .tokens = { /* token list, NULL terminated */
1353 (PGM_P)&cmd_debug_debug,
1354 (PGM_P)&cmd_debug_onoff,
1359 /**********************************************************/
1361 /* this structure is filled when cmd_baudrate is parsed successfully */
1362 struct cmd_baudrate_result {
1363 fixed_string_t arg0;
1367 /* function called when cmd_baudrate is parsed successfully */
1368 static void cmd_baudrate_parsed(void * parsed_result, __attribute__((unused)) void *data)
1370 struct cmd_baudrate_result *res = parsed_result;
1371 struct uart_config c;
1373 uart_getconf(XBEE_UART, &c);
1374 c.baudrate = res->arg1;
1375 uart_setconf(XBEE_UART, &c);
1378 const char PROGMEM str_baudrate_arg0[] = "baudrate";
1379 const parse_token_string_t PROGMEM cmd_baudrate_arg0 =
1380 TOKEN_STRING_INITIALIZER(struct cmd_baudrate_result, arg0,
1382 const parse_token_num_t PROGMEM cmd_baudrate_arg1 =
1383 TOKEN_NUM_INITIALIZER(struct cmd_baudrate_result, arg1,
1386 const char PROGMEM help_baudrate[] = "Change xbee baudrate";
1387 const parse_inst_t PROGMEM cmd_baudrate = {
1388 .f = cmd_baudrate_parsed, /* function to call */
1389 .data = NULL, /* 2nd arg of func */
1390 .help_str = help_baudrate,
1391 .tokens = { /* token list, NULL terminated */
1392 (PGM_P)&cmd_baudrate_arg0,
1393 (PGM_P)&cmd_baudrate_arg1,
1399 /**********************************************************/
1401 /* this structure is filled when cmd_beep is parsed successfully */
1402 struct cmd_beep_result {
1403 fixed_string_t beep;
1406 /* function called when cmd_beep is parsed successfully */
1407 static void cmd_beep_parsed(void *parsed_result, void *data)
1409 (void)parsed_result;
1420 const char PROGMEM str_beep[] = "beep";
1421 const parse_token_string_t PROGMEM cmd_beep_beep =
1422 TOKEN_STRING_INITIALIZER(struct cmd_beep_result, beep,
1425 const char PROGMEM help_beep[] = "Send a beep";
1427 const parse_inst_t PROGMEM cmd_beep = {
1428 .f = cmd_beep_parsed, /* function to call */
1429 .data = NULL, /* 2nd arg of func */
1430 .help_str = help_beep,
1431 .tokens = { /* token list, NULL terminated */
1432 (PGM_P)&cmd_beep_beep,
1437 /**********************************************************/
1439 /* this structure is filled when cmd_servo is parsed successfully */
1440 struct cmd_servo_result {
1441 fixed_string_t arg0;
1442 fixed_string_t arg1;
1447 /* function called when cmd_servo is parsed successfully */
1448 static void cmd_servo_parsed(void * parsed_result, void *data)
1450 struct cmd_servo_result *res = parsed_result;
1454 if (!strcmp_P(res->arg1, PSTR("set"))) {
1455 if (res->num >= N_SERVO) {
1456 printf_P(PSTR("bad servo num\n"));
1459 if (res->val >= 1024) {
1460 printf_P(PSTR("bad servo val\n"));
1463 spi_servo_set(res->num, res->val);
1465 else if (!strcmp_P(res->arg1, PSTR("bypass"))) {
1466 spi_servo_set_bypass(!!res->val);
1468 else if (!strcmp_P(res->arg1, PSTR("ppm"))) {
1469 spi_servo_set_ppm(!!res->val);
1471 else if (!strcmp_P(res->arg1, PSTR("show"))) {
1476 const char PROGMEM str_servo_arg0[] = "servo";
1477 const parse_token_string_t PROGMEM cmd_servo_arg0 =
1478 TOKEN_STRING_INITIALIZER(struct cmd_servo_result, arg0,
1480 const char PROGMEM str_servo_arg1_set[] = "set";
1481 const parse_token_string_t PROGMEM cmd_servo_arg1_set =
1482 TOKEN_STRING_INITIALIZER(struct cmd_servo_result, arg1,
1483 str_servo_arg1_set);
1484 const parse_token_num_t PROGMEM cmd_servo_num =
1485 TOKEN_NUM_INITIALIZER(struct cmd_servo_result, num,
1487 const parse_token_num_t PROGMEM cmd_servo_val =
1488 TOKEN_NUM_INITIALIZER(struct cmd_servo_result, val,
1491 const char PROGMEM help_servo_set[] = "set servo value";
1492 const parse_inst_t PROGMEM cmd_servo_set = {
1493 .f = cmd_servo_parsed, /* function to call */
1494 .data = NULL, /* 2nd arg of func */
1495 .help_str = help_servo_set,
1496 .tokens = { /* token list, NULL terminated */
1497 (PGM_P)&cmd_servo_arg0,
1498 (PGM_P)&cmd_servo_arg1_set,
1499 (PGM_P)&cmd_servo_num,
1500 (PGM_P)&cmd_servo_val,
1505 const char PROGMEM str_servo_arg1_show[] = "show";
1506 const parse_token_string_t PROGMEM cmd_servo_arg1_show =
1507 TOKEN_STRING_INITIALIZER(struct cmd_servo_result, arg1,
1508 str_servo_arg1_show);
1510 const char PROGMEM help_servo_show[] = "read servo and config";
1511 const parse_inst_t PROGMEM cmd_servo_show = {
1512 .f = cmd_servo_parsed, /* function to call */
1513 .data = NULL, /* 2nd arg of func */
1514 .help_str = help_servo_show,
1515 .tokens = { /* token list, NULL terminated */
1516 (PGM_P)&cmd_servo_arg0,
1517 (PGM_P)&cmd_servo_arg1_show,
1522 const char PROGMEM str_servo_arg1_bypassppm[] = "bypass#ppm";
1523 const parse_token_string_t PROGMEM cmd_servo_arg1_bypassppm =
1524 TOKEN_STRING_INITIALIZER(struct cmd_servo_result, arg1,
1525 str_servo_arg1_bypassppm);
1527 const char PROGMEM help_servo_bypassppm[] = "change bypass/ppm";
1528 const parse_inst_t PROGMEM cmd_servo_bypassppm = {
1529 .f = cmd_servo_parsed, /* function to call */
1530 .data = NULL, /* 2nd arg of func */
1531 .help_str = help_servo_bypassppm,
1532 .tokens = { /* token list, NULL terminated */
1533 (PGM_P)&cmd_servo_arg0,
1534 (PGM_P)&cmd_servo_arg1_bypassppm,
1535 (PGM_P)&cmd_servo_val,
1540 /**********************************************************/
1542 /* this structure is filled when cmd_test_spi is parsed successfully */
1543 struct cmd_test_spi_result {
1544 fixed_string_t arg0;
1547 static void cmd_test_spi_parsed(void * parsed_result, void *data)
1549 uint8_t i, flags, wait_time = 0;
1552 (void)parsed_result;
1555 spi_servo_set_bypass(0);
1556 spi_servo_set_ppm(0);
1558 /* stress test: send many commands, no wait between each servo
1559 * of a series, and a variable delay between series */
1560 printf_P(PSTR("stress test\r\n"));
1561 while (!cmdline_keypressed()) {
1573 for (i = 0; i < 6; i++)
1574 spi_servo_set(i, val);
1577 printf_P(PSTR("%4.4d %4.4d %4.4d %4.4d %4.4d %4.4d\r\n"),
1578 spi_servo_get(0), spi_servo_get(1), spi_servo_get(2),
1579 spi_servo_get(3), spi_servo_get(4), spi_servo_get(5));
1582 printf_P(PSTR("bypass mode, with spi commands in background\r\n"));
1583 spi_servo_set_bypass(1);
1585 /* test bypass mode */
1586 while (!cmdline_keypressed()) {
1598 for (i = 0; i < 6; i++)
1599 spi_servo_set(i, val);
1602 printf_P(PSTR("%4.4d %4.4d %4.4d %4.4d %4.4d %4.4d\r\n"),
1603 spi_servo_get(0), spi_servo_get(1), spi_servo_get(2),
1604 spi_servo_get(3), spi_servo_get(4), spi_servo_get(5));
1607 printf_P(PSTR("PPM to servo\r\n"));
1608 spi_servo_set_bypass(0);
1609 spi_servo_set_ppm(0);
1611 /* test PPM to servo (bypass) mode */
1612 while (!cmdline_keypressed()) {
1613 for (i = 0; i < 6; i++) {
1614 val = spi_servo_get(i);
1615 spi_servo_set(i, val);
1619 printf_P(PSTR("PPM to (servo + PPM)\r\n"));
1620 spi_servo_set_bypass(0);
1621 spi_servo_set_ppm(1);
1623 /* test PPM to servo (bypass) mode */
1624 while (!cmdline_keypressed()) {
1625 for (i = 0; i < 6; i++) {
1626 val = spi_servo_get(i);
1627 spi_servo_set(i, val);
1632 const char PROGMEM str_test_spi_arg0[] = "test_spi";
1633 const parse_token_string_t PROGMEM cmd_test_spi_arg0 =
1634 TOKEN_STRING_INITIALIZER(struct cmd_test_spi_result, arg0,
1637 const char PROGMEM help_test_spi[] = "Test the spi";
1638 const parse_inst_t PROGMEM cmd_test_spi = {
1639 .f = cmd_test_spi_parsed, /* function to call */
1640 .data = NULL, /* 2nd arg of func */
1641 .help_str = help_test_spi,
1642 .tokens = { /* token list, NULL terminated */
1643 (PGM_P)&cmd_test_spi_arg0,
1648 /**********************************************************/
1650 /* this structure is filled when cmd_dump_xbee_stats is parsed successfully */
1651 struct cmd_dump_xbee_stats_result {
1652 fixed_string_t arg0;
1655 static void cmd_dump_xbee_stats_parsed(void *parsed_result, void *data)
1657 (void)parsed_result;
1660 xbee_dump_stats(xbee_dev);
1663 const char PROGMEM str_dump_xbee_stats_arg0[] = "dump_xbee_stats";
1664 const parse_token_string_t PROGMEM cmd_dump_xbee_stats_arg0 =
1665 TOKEN_STRING_INITIALIZER(struct cmd_dump_xbee_stats_result, arg0,
1666 str_dump_xbee_stats_arg0);
1668 const char PROGMEM help_dump_xbee_stats[] = "Test the spi";
1669 const parse_inst_t PROGMEM cmd_dump_xbee_stats = {
1670 .f = cmd_dump_xbee_stats_parsed, /* function to call */
1671 .data = NULL, /* 2nd arg of func */
1672 .help_str = help_dump_xbee_stats,
1673 .tokens = { /* token list, NULL terminated */
1674 (PGM_P)&cmd_dump_xbee_stats_arg0,
1679 /**********************************************************/
1681 /* this structure is filled when cmd_test_eeprom_config is parsed successfully */
1682 struct cmd_test_eeprom_config_result {
1683 fixed_string_t arg0;
1686 static void cmd_test_eeprom_config_parsed(void *parsed_result, void *data)
1688 (void)parsed_result;
1692 eeprom_append_cmd("salut1\n");
1694 eeprom_append_cmd("salut2\n");
1695 eeprom_append_cmd("salut3\n");
1696 eeprom_append_cmd("salut4\n");
1698 eeprom_insert_cmd_before("coin\n", 0);
1699 eeprom_insert_cmd_before("coin2\n", 2);
1701 eeprom_delete_cmd(2);
1702 eeprom_delete_cmd(0);
1706 const char PROGMEM str_test_eeprom_config_arg0[] = "test_eeprom_config";
1707 const parse_token_string_t PROGMEM cmd_test_eeprom_config_arg0 =
1708 TOKEN_STRING_INITIALIZER(struct cmd_test_eeprom_config_result, arg0,
1709 str_test_eeprom_config_arg0);
1711 const char PROGMEM help_test_eeprom_config[] = "Test the eeprom configuration";
1712 const parse_inst_t PROGMEM cmd_test_eeprom_config = {
1713 .f = cmd_test_eeprom_config_parsed, /* function to call */
1714 .data = NULL, /* 2nd arg of func */
1715 .help_str = help_test_eeprom_config,
1716 .tokens = { /* token list, NULL terminated */
1717 (PGM_P)&cmd_test_eeprom_config_arg0,
1724 struct cmd_eeprom_del_result {
1726 fixed_string_t action;
1730 static void cmd_eeprom_del_parsed(void *parsed_result,
1733 struct cmd_eeprom_del_result *res = parsed_result;
1736 if (eeprom_delete_cmd(res->n) < 0)
1737 printf_P(PSTR("cannot delete command\n"));
1741 const char PROGMEM str_eeprom_del_eeprom[] = "eeprom";
1742 const parse_token_string_t PROGMEM cmd_eeprom_del_cmd =
1743 TOKEN_STRING_INITIALIZER(struct cmd_eeprom_del_result, cmd,
1744 str_eeprom_del_eeprom);
1745 const char PROGMEM str_eeprom_del_del[] = "del";
1746 const parse_token_string_t PROGMEM cmd_eeprom_del_action =
1747 TOKEN_STRING_INITIALIZER(struct cmd_eeprom_del_result, action,
1748 str_eeprom_del_del);
1749 const parse_token_num_t PROGMEM cmd_eeprom_del_num =
1750 TOKEN_NUM_INITIALIZER(struct cmd_eeprom_del_result, n,
1753 const char PROGMEM help_eeprom_del[] = "delete an eeprom init command";
1754 const parse_inst_t PROGMEM cmd_eeprom_del = {
1755 .f = cmd_eeprom_del_parsed, /* function to call */
1756 .data = NULL, /* 2nd arg of func */
1757 .help_str = help_eeprom_del,
1758 .tokens = { /* token list, NULL terminated */
1759 (PGM_P)&cmd_eeprom_del_cmd,
1760 (PGM_P)&cmd_eeprom_del_action,
1761 (PGM_P)&cmd_eeprom_del_num,
1768 struct cmd_eeprom_add_result {
1770 fixed_string_t action;
1774 static void cmd_eeprom_add_parsed(void *parsed_result,
1777 struct cmd_eeprom_add_result *res = parsed_result;
1783 rdline_init(&rdl, cmdline_write_char, NULL, NULL);
1784 rdline_newline(&rdl, "> ");
1786 /* XXX bad: we should not block as we do not serve callout */
1788 c = cmdline_dev_recv(NULL);
1792 ret = rdline_char_in(&rdl, c);
1794 printf_P(PSTR("abort\n"));
1801 buffer = rdline_get_buffer(&rdl);
1803 eeprom_insert_cmd_before(buffer, res->n);
1805 eeprom_append_cmd(buffer);
1809 const char PROGMEM str_eeprom_add_eeprom[] = "eeprom";
1810 const parse_token_string_t PROGMEM cmd_eeprom_add_cmd =
1811 TOKEN_STRING_INITIALIZER(struct cmd_eeprom_add_result, cmd,
1812 str_eeprom_add_eeprom);
1813 const char PROGMEM str_eeprom_add_add[] = "add";
1814 const parse_token_string_t PROGMEM cmd_eeprom_add_action =
1815 TOKEN_STRING_INITIALIZER(struct cmd_eeprom_add_result, action,
1816 str_eeprom_add_add);
1817 const parse_token_num_t PROGMEM cmd_eeprom_add_num =
1818 TOKEN_NUM_INITIALIZER(struct cmd_eeprom_add_result, n,
1821 const char PROGMEM help_eeprom_add[] = "insert an eeprom init command";
1822 const parse_inst_t PROGMEM cmd_eeprom_add = {
1823 .f = cmd_eeprom_add_parsed, /* function to call */
1824 .data = NULL, /* 2nd arg of func */
1825 .help_str = help_eeprom_add,
1826 .tokens = { /* token list, NULL terminated */
1827 (PGM_P)&cmd_eeprom_add_cmd,
1828 (PGM_P)&cmd_eeprom_add_action,
1829 (PGM_P)&cmd_eeprom_add_num,
1834 const char PROGMEM help_eeprom_add2[] = "append an eeprom init command";
1835 const parse_inst_t PROGMEM cmd_eeprom_add2 = {
1836 .f = cmd_eeprom_add_parsed, /* function to call */
1837 .data = (void *)1, /* 2nd arg of func */
1838 .help_str = help_eeprom_add2,
1839 .tokens = { /* token list, NULL terminated */
1840 (PGM_P)&cmd_eeprom_add_cmd,
1841 (PGM_P)&cmd_eeprom_add_action,
1848 struct cmd_eeprom_list_result {
1850 fixed_string_t action;
1853 static void cmd_eeprom_list_parsed(void *parsed_result,
1856 (void)parsed_result;
1861 const char PROGMEM str_eeprom_list_eeprom[] = "eeprom";
1862 const parse_token_string_t PROGMEM cmd_eeprom_list_cmd =
1863 TOKEN_STRING_INITIALIZER(struct cmd_eeprom_list_result, cmd,
1864 str_eeprom_list_eeprom);
1865 const char PROGMEM str_eeprom_list_list[] = "list";
1866 const parse_token_string_t PROGMEM cmd_eeprom_list_action =
1867 TOKEN_STRING_INITIALIZER(struct cmd_eeprom_list_result, action,
1868 str_eeprom_list_list);
1870 const char PROGMEM help_eeprom_list[] = "list all eeprom init commands";
1871 const parse_inst_t PROGMEM cmd_eeprom_list = {
1872 .f = cmd_eeprom_list_parsed, /* function to call */
1873 .data = NULL, /* 2nd arg of func */
1874 .help_str = help_eeprom_list,
1875 .tokens = { /* token list, NULL terminated */
1876 (PGM_P)&cmd_eeprom_list_cmd,
1877 (PGM_P)&cmd_eeprom_list_action,
1886 const parse_ctx_t PROGMEM main_ctx[] = {
1888 /* commands_gen.c */
1907 &cmd_send_hello_name,
1912 &cmd_range_powermask,
1915 &cmd_monitor_period,
1925 &cmd_servo_bypassppm,
1928 &cmd_dump_xbee_stats,
1929 &cmd_test_eeprom_config,