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_callout;
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) {
122 callout_stop(cm, clt);
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(&xbeeboard.mainloop_cm,
745 &range_event, 0); /* immediate */
748 else if (!strcmp(res->action, "end")) {
749 if (range_running == 0) {
750 printf_P(PSTR("not running\r\n"));
754 callout_stop(&xbeeboard.mainloop_cm, &range_event);
758 const char PROGMEM str_range[] = "range";
759 const char PROGMEM str_range_tokens[] = "show#start#end";
761 const parse_token_string_t PROGMEM cmd_range_range =
762 TOKEN_STRING_INITIALIZER(struct cmd_range_result, range,
764 const parse_token_string_t PROGMEM cmd_range_action =
765 TOKEN_STRING_INITIALIZER(struct cmd_range_result, action,
768 const char PROGMEM help_range[] = "start/stop/show current rangeing";
770 const parse_inst_t PROGMEM cmd_range = {
771 .f = cmd_range_parsed, /* function to call */
772 .data = NULL, /* 2nd arg of func */
773 .help_str = help_range,
774 .tokens = { /* token list, NULL terminated */
775 (PGM_P)&cmd_range_range,
776 (PGM_P)&cmd_range_action,
783 /* this structure is filled when cmd_range_period is parsed successfully */
784 struct cmd_range_period_result {
785 fixed_string_t range;
786 fixed_string_t action;
790 /* function called when cmd_range_period is parsed successfully */
791 static void cmd_range_period_parsed(void *parsed_result, void *data)
793 struct cmd_range_period_result *res = parsed_result;
796 if (res->period < 10) {
797 printf_P(PSTR("error, minimum period is 10 ms\r\n"));
801 range_period_ms = res->period;
804 const char PROGMEM str_period[] = "period";
806 const parse_token_string_t PROGMEM cmd_range_period_range_period =
807 TOKEN_STRING_INITIALIZER(struct cmd_range_period_result, range,
809 const parse_token_string_t PROGMEM cmd_range_period_action =
810 TOKEN_STRING_INITIALIZER(struct cmd_range_period_result, action,
812 const parse_token_num_t PROGMEM cmd_range_period_period =
813 TOKEN_NUM_INITIALIZER(struct cmd_range_period_result, period, UINT32);
815 const char PROGMEM help_range_period[] = "set range test period";
817 const parse_inst_t PROGMEM cmd_range_period = {
818 .f = cmd_range_period_parsed, /* function to call */
819 .data = NULL, /* 2nd arg of func */
820 .help_str = help_range_period,
821 .tokens = { /* token list, NULL terminated */
822 (PGM_P)&cmd_range_period_range_period,
823 (PGM_P)&cmd_range_period_action,
824 (PGM_P)&cmd_range_period_period,
831 /* this structure is filled when cmd_range_count is parsed successfully */
832 struct cmd_range_count_result {
833 fixed_string_t range;
834 fixed_string_t action;
838 /* function called when cmd_range_count is parsed successfully */
839 static void cmd_range_count_parsed(void *parsed_result, void *data)
841 struct cmd_range_count_result *res = parsed_result;
844 range_count = res->count;
847 const char PROGMEM str_count[] = "count";
849 const parse_token_string_t PROGMEM cmd_range_count_range_count =
850 TOKEN_STRING_INITIALIZER(struct cmd_range_count_result, range,
852 const parse_token_string_t PROGMEM cmd_range_count_action =
853 TOKEN_STRING_INITIALIZER(struct cmd_range_count_result, action,
855 const parse_token_num_t PROGMEM cmd_range_count_count =
856 TOKEN_NUM_INITIALIZER(struct cmd_range_count_result, count, UINT32);
859 const char PROGMEM help_range_count[] = "set range test count";
861 const parse_inst_t PROGMEM cmd_range_count = {
862 .f = cmd_range_count_parsed, /* function to call */
863 .data = NULL, /* 2nd arg of func */
864 .help_str = help_range_count,
865 .tokens = { /* token list, NULL terminated */
866 (PGM_P)&cmd_range_count_range_count,
867 (PGM_P)&cmd_range_count_action,
868 (PGM_P)&cmd_range_count_count,
875 /* this structure is filled when cmd_range_powermask is parsed successfully */
876 struct cmd_range_powermask_result {
877 fixed_string_t range;
878 fixed_string_t action;
882 /* function called when cmd_range_powermask is parsed successfully */
883 static void cmd_range_powermask_parsed(void *parsed_result, void *data)
885 struct cmd_range_powermask_result *res = parsed_result;
888 range_powermask = res->powermask;
891 const char PROGMEM str_powermask[] = "powermask";
893 const parse_token_string_t PROGMEM cmd_range_powermask_range_powermask =
894 TOKEN_STRING_INITIALIZER(struct cmd_range_powermask_result, range,
896 const parse_token_string_t PROGMEM cmd_range_powermask_action =
897 TOKEN_STRING_INITIALIZER(struct cmd_range_powermask_result, action,
899 const parse_token_num_t PROGMEM cmd_range_powermask_powermask =
900 TOKEN_NUM_INITIALIZER(struct cmd_range_powermask_result, powermask,
904 const char PROGMEM help_range_powermask[] = "set range test powermask";
906 const parse_inst_t PROGMEM cmd_range_powermask = {
907 .f = cmd_range_powermask_parsed, /* function to call */
908 .data = NULL, /* 2nd arg of func */
909 .help_str = help_range_powermask,
910 .tokens = { /* token list, NULL terminated */
911 (PGM_P)&cmd_range_powermask_range_powermask,
912 (PGM_P)&cmd_range_powermask_action,
913 (PGM_P)&cmd_range_powermask_powermask,
920 /* this structure is filled when cmd_range_dstaddr is parsed successfully */
921 struct cmd_range_dstaddr_result {
922 fixed_string_t range;
923 fixed_string_t action;
927 /* function called when cmd_range_dstaddr is parsed successfully */
928 static void cmd_range_dstaddr_parsed(void *parsed_result, void *data)
930 struct cmd_range_dstaddr_result *res = parsed_result;
933 range_dstaddr = res->dstaddr;
936 const char PROGMEM str_dstaddr[] = "dstaddr";
938 const parse_token_string_t PROGMEM cmd_range_dstaddr_range_dstaddr =
939 TOKEN_STRING_INITIALIZER(struct cmd_range_dstaddr_result, range,
941 const parse_token_string_t PROGMEM cmd_range_dstaddr_action =
942 TOKEN_STRING_INITIALIZER(struct cmd_range_dstaddr_result, action,
944 const parse_token_num_t PROGMEM cmd_range_dstaddr_dstaddr =
945 TOKEN_NUM_INITIALIZER(struct cmd_range_dstaddr_result, dstaddr, UINT64);
948 const char PROGMEM help_range_dstaddr[] = "set register rangeing dstaddr";
950 const parse_inst_t PROGMEM cmd_range_dstaddr = {
951 .f = cmd_range_dstaddr_parsed, /* function to call */
952 .data = NULL, /* 2nd arg of func */
953 .help_str = help_range_dstaddr,
954 .tokens = { /* token list, NULL terminated */
955 (PGM_P)&cmd_range_dstaddr_range_dstaddr,
956 (PGM_P)&cmd_range_dstaddr_action,
957 (PGM_P)&cmd_range_dstaddr_dstaddr,
965 /* this structure is filled when cmd_monitor is parsed successfully */
966 struct cmd_monitor_result {
967 fixed_string_t monitor;
968 fixed_string_t action;
971 /* function called when cmd_monitor is parsed successfully */
972 static void cmd_monitor_parsed(void *parsed_result, void *data)
974 struct cmd_monitor_result *res = parsed_result;
975 struct monitor_reg *m;
978 if (!strcmp_P(res->action, PSTR("show"))) {
979 printf_P(PSTR("monitor period is %d ms, %d regs in list\r\n"),
980 monitor_period_ms, monitor_count);
981 LIST_FOREACH(m, &xbee_monitor_list, next)
982 printf_P(PSTR(" %S\r\n"), m->desc);
984 else if (!strcmp_P(res->action, PSTR("start"))) {
985 if (monitor_running) {
986 printf_P(PSTR("already running\r\n"));
989 if (monitor_count == 0) {
990 printf_P(PSTR("no regs to be monitored\r\n"));
993 callout_init(&monitor_event, monitor_cb, NULL, 0);
994 callout_schedule(&xbeeboard.mainloop_cm,
995 &monitor_event, 0); /* immediate */
997 monitor_current = LIST_FIRST(&xbee_monitor_list);
998 printf_P(PSTR("monitor cb: %S %s\r\n"),
999 monitor_current->desc,
1000 monitor_current->atcmd);
1003 else if (!strcmp_P(res->action, PSTR("end"))) {
1004 if (monitor_running == 0) {
1005 printf_P(PSTR("not running\r\n"));
1008 monitor_running = 0;
1009 callout_stop(&xbeeboard.mainloop_cm, &monitor_event);
1013 const char PROGMEM str_monitor[] = "monitor";
1014 const char PROGMEM str_monitor_tokens[] = "show#start#end";
1016 const parse_token_string_t PROGMEM cmd_monitor_monitor =
1017 TOKEN_STRING_INITIALIZER(struct cmd_monitor_result, monitor,
1019 const parse_token_string_t PROGMEM cmd_monitor_action =
1020 TOKEN_STRING_INITIALIZER(struct cmd_monitor_result, action,
1021 str_monitor_tokens);
1023 const char PROGMEM help_monitor[] = "start/stop/show current monitoring";
1025 const parse_inst_t PROGMEM cmd_monitor = {
1026 .f = cmd_monitor_parsed, /* function to call */
1027 .data = NULL, /* 2nd arg of func */
1028 .help_str = help_monitor,
1029 .tokens = { /* token list, NULL terminated */
1030 (PGM_P)&cmd_monitor_monitor,
1031 (PGM_P)&cmd_monitor_action,
1038 /* this structure is filled when cmd_monitor_add is parsed successfully */
1039 struct cmd_monitor_add_result {
1040 fixed_string_t monitor;
1041 fixed_string_t action;
1042 struct xbee_atcmd *cmd;
1045 /* function called when cmd_monitor_add is parsed successfully */
1046 static void cmd_monitor_add_parsed(void *parsed_result, void *data)
1048 struct cmd_monitor_add_result *res = parsed_result;
1049 struct monitor_reg *m;
1050 struct xbee_atcmd copy;
1053 memcpy_P(©, res->cmd, sizeof(copy));
1054 LIST_FOREACH(m, &xbee_monitor_list, next) {
1055 if (!strcmp_P(m->atcmd, copy.name))
1060 printf_P(PSTR("already exist\r\n"));
1064 m = malloc(sizeof(*m));
1066 printf_P(PSTR("no mem\r\n"));
1069 m->desc = copy.desc;
1070 strcpy_P(m->atcmd, copy.name);
1071 LIST_INSERT_HEAD(&xbee_monitor_list, m, next);
1075 const char PROGMEM str_monitor_add[] = "add";
1077 const parse_token_string_t PROGMEM cmd_monitor_add_monitor_add =
1078 TOKEN_STRING_INITIALIZER(struct cmd_monitor_add_result, monitor,
1080 const parse_token_string_t PROGMEM cmd_monitor_add_action =
1081 TOKEN_STRING_INITIALIZER(struct cmd_monitor_add_result, action,
1083 const parse_token_atcmd_t PROGMEM cmd_monitor_add_atcmd =
1084 TOKEN_ATCMD_INITIALIZER(struct cmd_monitor_add_result, cmd, &xbee_dev,
1085 XBEE_ATCMD_F_READ, XBEE_ATCMD_F_READ);
1088 const char PROGMEM help_monitor_add[] = "add a register in monitor list";
1090 const parse_inst_t PROGMEM cmd_monitor_add = {
1091 .f = cmd_monitor_add_parsed, /* function to call */
1092 .data = NULL, /* 2nd arg of func */
1093 .help_str = help_monitor_add,
1094 .tokens = { /* token list, NULL terminated */
1095 (PGM_P)&cmd_monitor_add_monitor_add,
1096 (PGM_P)&cmd_monitor_add_action,
1097 (PGM_P)&cmd_monitor_add_atcmd,
1104 /* this structure is filled when cmd_monitor_period is parsed successfully */
1105 struct cmd_monitor_period_result {
1106 fixed_string_t monitor;
1107 fixed_string_t action;
1111 /* function called when cmd_monitor_period is parsed successfully */
1112 static void cmd_monitor_period_parsed(void *parsed_result, void *data)
1114 struct cmd_monitor_period_result *res = parsed_result;
1117 if (res->period < 100) {
1118 printf_P(PSTR("error, minimum period is 100 ms\r\n"));
1122 monitor_period_ms = res->period;
1125 const char PROGMEM str_monitor_period[] = "period";
1127 const parse_token_string_t PROGMEM cmd_monitor_period_monitor_period =
1128 TOKEN_STRING_INITIALIZER(struct cmd_monitor_period_result, monitor,
1130 const parse_token_string_t PROGMEM cmd_monitor_period_action =
1131 TOKEN_STRING_INITIALIZER(struct cmd_monitor_period_result, action,
1132 str_monitor_period);
1133 const parse_token_num_t PROGMEM cmd_monitor_period_period =
1134 TOKEN_NUM_INITIALIZER(struct cmd_monitor_period_result, period, UINT32);
1137 const char PROGMEM help_monitor_period[] = "set register monitoring period";
1139 const parse_inst_t PROGMEM cmd_monitor_period = {
1140 .f = cmd_monitor_period_parsed, /* function to call */
1141 .data = NULL, /* 2nd arg of func */
1142 .help_str = help_monitor_period,
1143 .tokens = { /* token list, NULL terminated */
1144 (PGM_P)&cmd_monitor_period_monitor_period,
1145 (PGM_P)&cmd_monitor_period_action,
1146 (PGM_P)&cmd_monitor_period_period,
1153 /* this structure is filled when cmd_monitor_del is parsed successfully */
1154 struct cmd_monitor_del_result {
1155 fixed_string_t monitor;
1156 fixed_string_t action;
1157 struct monitor_reg *m;
1160 /* function called when cmd_monitor_del is parsed successfully */
1161 static void cmd_monitor_del_parsed(void *parsed_result, void *data)
1163 struct cmd_monitor_del_result *res = parsed_result;
1166 monitor_current = LIST_NEXT(res->m, next);
1167 LIST_REMOVE(res->m, next);
1170 if (monitor_count == 0) {
1171 printf_P(PSTR("Disable monitoring, no more event\r\n"));
1172 callout_stop(&xbeeboard.mainloop_cm, &monitor_event);
1173 monitor_running = 0;
1178 const char PROGMEM str_monitor_del[] = "del";
1180 const parse_token_string_t PROGMEM cmd_monitor_del_monitor_del =
1181 TOKEN_STRING_INITIALIZER(struct cmd_monitor_del_result, monitor,
1183 const parse_token_string_t PROGMEM cmd_monitor_del_action =
1184 TOKEN_STRING_INITIALIZER(struct cmd_monitor_del_result, action,
1186 const parse_token_monitor_t PROGMEM cmd_monitor_del_atcmd =
1187 TOKEN_MONITOR_INITIALIZER(struct cmd_monitor_del_result, m);
1190 const char PROGMEM help_monitor_del[] = "del a register in monitor list";
1192 const parse_inst_t PROGMEM cmd_monitor_del = {
1193 .f = cmd_monitor_del_parsed, /* function to call */
1194 .data = NULL, /* 2nd arg of func */
1195 .help_str = help_monitor_del,
1196 .tokens = { /* token list, NULL terminated */
1197 (PGM_P)&cmd_monitor_del_monitor_del,
1198 (PGM_P)&cmd_monitor_del_action,
1199 (PGM_P)&cmd_monitor_del_atcmd,
1207 /* this structure is filled when cmd_ping is parsed successfully */
1208 struct cmd_ping_result {
1209 fixed_string_t ping;
1212 /* function called when cmd_ping is parsed successfully */
1213 static void cmd_ping_parsed(void *parsed_result, void *data)
1215 (void)parsed_result;
1217 xbeeapp_send_atcmd("VL", NULL, 0, 1, NULL, NULL);
1220 const char PROGMEM str_ping[] = "ping";
1222 const parse_token_string_t PROGMEM cmd_ping_ping =
1223 TOKEN_STRING_INITIALIZER(struct cmd_ping_result, ping,
1226 const char PROGMEM help_ping[] = "Send a ping to the xbee device";
1228 const parse_inst_t PROGMEM cmd_ping = {
1229 .f = cmd_ping_parsed, /* function to call */
1230 .data = NULL, /* 2nd arg of func */
1231 .help_str = help_ping,
1232 .tokens = { /* token list, NULL terminated */
1233 (PGM_P)&cmd_ping_ping,
1240 /* this structure is filled when cmd_raw is parsed successfully */
1241 struct cmd_raw_result {
1245 /* function called when cmd_raw is parsed successfully */
1246 static void cmd_raw_parsed(void *parsed_result, void *data)
1248 (void)parsed_result;
1250 printf_P(PSTR("switched to raw mode, CTRL-D to exit\r\n"));
1251 rdline_stop(&xbeeboard.rdl); /* don't display prompt when return */
1255 const char PROGMEM str_raw[] = "raw";
1257 const parse_token_string_t PROGMEM cmd_raw_raw =
1258 TOKEN_STRING_INITIALIZER(struct cmd_raw_result, raw,
1261 const char PROGMEM help_raw[] = "Switch to raw mode";
1263 const parse_inst_t PROGMEM cmd_raw = {
1264 .f = cmd_raw_parsed, /* function to call */
1265 .data = NULL, /* 2nd arg of func */
1266 .help_str = help_raw,
1267 .tokens = { /* token list, NULL terminated */
1268 (PGM_P)&cmd_raw_raw,
1275 /* this structure is filled when cmd_dump is parsed successfully */
1276 struct cmd_dump_result {
1277 fixed_string_t dump;
1278 fixed_string_t onoff;
1281 /* function called when cmd_dump is parsed successfully */
1282 static void cmd_dump_parsed(void *parsed_result, void *data)
1284 struct cmd_dump_result *res = parsed_result;
1287 if (!strcmp(res->onoff, "on"))
1293 const char PROGMEM str_dump[] = "dump";
1294 const char PROGMEM str_dump_onoff[] = "on#off";
1296 const parse_token_string_t PROGMEM cmd_dump_dump =
1297 TOKEN_STRING_INITIALIZER(struct cmd_dump_result, dump,
1300 const parse_token_string_t PROGMEM cmd_dump_onoff =
1301 TOKEN_STRING_INITIALIZER(struct cmd_dump_result, onoff,
1304 const char PROGMEM help_dump[] = "enable/disable hexdump of received packets";
1306 const parse_inst_t PROGMEM cmd_dump = {
1307 .f = cmd_dump_parsed, /* function to call */
1308 .data = NULL, /* 2nd arg of func */
1309 .help_str = help_dump,
1310 .tokens = { /* token list, NULL terminated */
1311 (PGM_P)&cmd_dump_dump,
1312 (PGM_P)&cmd_dump_onoff,
1319 /* this structure is filled when cmd_debug is parsed successfully */
1320 struct cmd_debug_result {
1321 fixed_string_t debug;
1322 fixed_string_t onoff;
1325 /* function called when cmd_debug is parsed successfully */
1326 static void cmd_debug_parsed(void *parsed_result, void *data)
1328 struct cmd_debug_result *res = parsed_result;
1331 if (!strcmp(res->onoff, "on"))
1337 const char PROGMEM str_debug[] = "debug";
1338 const char PROGMEM str_debug_onoff[] = "on#off";
1340 const parse_token_string_t PROGMEM cmd_debug_debug =
1341 TOKEN_STRING_INITIALIZER(struct cmd_debug_result, debug,
1344 const parse_token_string_t PROGMEM cmd_debug_onoff =
1345 TOKEN_STRING_INITIALIZER(struct cmd_debug_result, onoff,
1348 const char PROGMEM help_debug[] = "enable/disable additionnal debug";
1350 const parse_inst_t PROGMEM cmd_debug = {
1351 .f = cmd_debug_parsed, /* function to call */
1352 .data = NULL, /* 2nd arg of func */
1353 .help_str = help_debug,
1354 .tokens = { /* token list, NULL terminated */
1355 (PGM_P)&cmd_debug_debug,
1356 (PGM_P)&cmd_debug_onoff,
1361 /**********************************************************/
1363 /* this structure is filled when cmd_baudrate is parsed successfully */
1364 struct cmd_baudrate_result {
1365 fixed_string_t arg0;
1369 /* function called when cmd_baudrate is parsed successfully */
1370 static void cmd_baudrate_parsed(void * parsed_result, __attribute__((unused)) void *data)
1372 struct cmd_baudrate_result *res = parsed_result;
1373 struct uart_config c;
1375 uart_getconf(XBEE_UART, &c);
1376 c.baudrate = res->arg1;
1377 uart_setconf(XBEE_UART, &c);
1380 const char PROGMEM str_baudrate_arg0[] = "baudrate";
1381 const parse_token_string_t PROGMEM cmd_baudrate_arg0 =
1382 TOKEN_STRING_INITIALIZER(struct cmd_baudrate_result, arg0,
1384 const parse_token_num_t PROGMEM cmd_baudrate_arg1 =
1385 TOKEN_NUM_INITIALIZER(struct cmd_baudrate_result, arg1,
1388 const char PROGMEM help_baudrate[] = "Change xbee baudrate";
1389 const parse_inst_t PROGMEM cmd_baudrate = {
1390 .f = cmd_baudrate_parsed, /* function to call */
1391 .data = NULL, /* 2nd arg of func */
1392 .help_str = help_baudrate,
1393 .tokens = { /* token list, NULL terminated */
1394 (PGM_P)&cmd_baudrate_arg0,
1395 (PGM_P)&cmd_baudrate_arg1,
1401 /**********************************************************/
1403 /* this structure is filled when cmd_beep is parsed successfully */
1404 struct cmd_beep_result {
1405 fixed_string_t beep;
1408 /* function called when cmd_beep is parsed successfully */
1409 static void cmd_beep_parsed(void *parsed_result, void *data)
1411 (void)parsed_result;
1422 const char PROGMEM str_beep[] = "beep";
1423 const parse_token_string_t PROGMEM cmd_beep_beep =
1424 TOKEN_STRING_INITIALIZER(struct cmd_beep_result, beep,
1427 const char PROGMEM help_beep[] = "Send a beep";
1429 const parse_inst_t PROGMEM cmd_beep = {
1430 .f = cmd_beep_parsed, /* function to call */
1431 .data = NULL, /* 2nd arg of func */
1432 .help_str = help_beep,
1433 .tokens = { /* token list, NULL terminated */
1434 (PGM_P)&cmd_beep_beep,
1439 /**********************************************************/
1441 /* this structure is filled when cmd_servo is parsed successfully */
1442 struct cmd_servo_result {
1443 fixed_string_t arg0;
1444 fixed_string_t arg1;
1449 /* function called when cmd_servo is parsed successfully */
1450 static void cmd_servo_parsed(void * parsed_result, void *data)
1452 struct cmd_servo_result *res = parsed_result;
1456 if (!strcmp_P(res->arg1, PSTR("set"))) {
1457 if (res->num >= N_SERVO) {
1458 printf_P(PSTR("bad servo num\n"));
1461 if (res->val >= 1024) {
1462 printf_P(PSTR("bad servo val\n"));
1465 spi_servo_set(res->num, res->val);
1467 else if (!strcmp_P(res->arg1, PSTR("bypass"))) {
1468 spi_servo_set_bypass(!!res->val);
1470 else if (!strcmp_P(res->arg1, PSTR("ppm"))) {
1471 spi_servo_set_ppm(!!res->val);
1473 else if (!strcmp_P(res->arg1, PSTR("show"))) {
1478 const char PROGMEM str_servo_arg0[] = "servo";
1479 const parse_token_string_t PROGMEM cmd_servo_arg0 =
1480 TOKEN_STRING_INITIALIZER(struct cmd_servo_result, arg0,
1482 const char PROGMEM str_servo_arg1_set[] = "set";
1483 const parse_token_string_t PROGMEM cmd_servo_arg1_set =
1484 TOKEN_STRING_INITIALIZER(struct cmd_servo_result, arg1,
1485 str_servo_arg1_set);
1486 const parse_token_num_t PROGMEM cmd_servo_num =
1487 TOKEN_NUM_INITIALIZER(struct cmd_servo_result, num,
1489 const parse_token_num_t PROGMEM cmd_servo_val =
1490 TOKEN_NUM_INITIALIZER(struct cmd_servo_result, val,
1493 const char PROGMEM help_servo_set[] = "set servo value";
1494 const parse_inst_t PROGMEM cmd_servo_set = {
1495 .f = cmd_servo_parsed, /* function to call */
1496 .data = NULL, /* 2nd arg of func */
1497 .help_str = help_servo_set,
1498 .tokens = { /* token list, NULL terminated */
1499 (PGM_P)&cmd_servo_arg0,
1500 (PGM_P)&cmd_servo_arg1_set,
1501 (PGM_P)&cmd_servo_num,
1502 (PGM_P)&cmd_servo_val,
1507 const char PROGMEM str_servo_arg1_show[] = "show";
1508 const parse_token_string_t PROGMEM cmd_servo_arg1_show =
1509 TOKEN_STRING_INITIALIZER(struct cmd_servo_result, arg1,
1510 str_servo_arg1_show);
1512 const char PROGMEM help_servo_show[] = "read servo and config";
1513 const parse_inst_t PROGMEM cmd_servo_show = {
1514 .f = cmd_servo_parsed, /* function to call */
1515 .data = NULL, /* 2nd arg of func */
1516 .help_str = help_servo_show,
1517 .tokens = { /* token list, NULL terminated */
1518 (PGM_P)&cmd_servo_arg0,
1519 (PGM_P)&cmd_servo_arg1_show,
1524 const char PROGMEM str_servo_arg1_bypassppm[] = "bypass#ppm";
1525 const parse_token_string_t PROGMEM cmd_servo_arg1_bypassppm =
1526 TOKEN_STRING_INITIALIZER(struct cmd_servo_result, arg1,
1527 str_servo_arg1_bypassppm);
1529 const char PROGMEM help_servo_bypassppm[] = "change bypass/ppm";
1530 const parse_inst_t PROGMEM cmd_servo_bypassppm = {
1531 .f = cmd_servo_parsed, /* function to call */
1532 .data = NULL, /* 2nd arg of func */
1533 .help_str = help_servo_bypassppm,
1534 .tokens = { /* token list, NULL terminated */
1535 (PGM_P)&cmd_servo_arg0,
1536 (PGM_P)&cmd_servo_arg1_bypassppm,
1537 (PGM_P)&cmd_servo_val,
1542 /**********************************************************/
1544 /* this structure is filled when cmd_test_spi is parsed successfully */
1545 struct cmd_test_spi_result {
1546 fixed_string_t arg0;
1549 static void cmd_test_spi_parsed(void * parsed_result, void *data)
1551 uint8_t i, flags, wait_time = 0;
1554 (void)parsed_result;
1557 spi_servo_set_bypass(0);
1558 spi_servo_set_ppm(0);
1560 /* stress test: send many commands, no wait between each servo
1561 * of a series, and a variable delay between series */
1562 printf_P(PSTR("stress test\r\n"));
1563 while (!cmdline_keypressed()) {
1575 for (i = 0; i < 6; i++)
1576 spi_servo_set(i, val);
1579 printf_P(PSTR("%4.4d %4.4d %4.4d %4.4d %4.4d %4.4d\r\n"),
1580 spi_servo_get(0), spi_servo_get(1), spi_servo_get(2),
1581 spi_servo_get(3), spi_servo_get(4), spi_servo_get(5));
1584 printf_P(PSTR("bypass mode, with spi commands in background\r\n"));
1585 spi_servo_set_bypass(1);
1587 /* test bypass mode */
1588 while (!cmdline_keypressed()) {
1600 for (i = 0; i < 6; i++)
1601 spi_servo_set(i, val);
1604 printf_P(PSTR("%4.4d %4.4d %4.4d %4.4d %4.4d %4.4d\r\n"),
1605 spi_servo_get(0), spi_servo_get(1), spi_servo_get(2),
1606 spi_servo_get(3), spi_servo_get(4), spi_servo_get(5));
1609 printf_P(PSTR("PPM to servo\r\n"));
1610 spi_servo_set_bypass(0);
1611 spi_servo_set_ppm(0);
1613 /* test PPM to servo (bypass) mode */
1614 while (!cmdline_keypressed()) {
1615 for (i = 0; i < 6; i++) {
1616 val = spi_servo_get(i);
1617 spi_servo_set(i, val);
1621 printf_P(PSTR("PPM to (servo + PPM)\r\n"));
1622 spi_servo_set_bypass(0);
1623 spi_servo_set_ppm(1);
1625 /* test PPM to servo (bypass) mode */
1626 while (!cmdline_keypressed()) {
1627 for (i = 0; i < 6; i++) {
1628 val = spi_servo_get(i);
1629 spi_servo_set(i, val);
1634 const char PROGMEM str_test_spi_arg0[] = "test_spi";
1635 const parse_token_string_t PROGMEM cmd_test_spi_arg0 =
1636 TOKEN_STRING_INITIALIZER(struct cmd_test_spi_result, arg0,
1639 const char PROGMEM help_test_spi[] = "Test the spi";
1640 const parse_inst_t PROGMEM cmd_test_spi = {
1641 .f = cmd_test_spi_parsed, /* function to call */
1642 .data = NULL, /* 2nd arg of func */
1643 .help_str = help_test_spi,
1644 .tokens = { /* token list, NULL terminated */
1645 (PGM_P)&cmd_test_spi_arg0,
1650 /**********************************************************/
1652 /* this structure is filled when cmd_dump_xbee_stats is parsed successfully */
1653 struct cmd_dump_xbee_stats_result {
1654 fixed_string_t arg0;
1657 static void cmd_dump_xbee_stats_parsed(void *parsed_result, void *data)
1659 (void)parsed_result;
1662 xbee_dump_stats(xbee_dev);
1665 const char PROGMEM str_dump_xbee_stats_arg0[] = "dump_xbee_stats";
1666 const parse_token_string_t PROGMEM cmd_dump_xbee_stats_arg0 =
1667 TOKEN_STRING_INITIALIZER(struct cmd_dump_xbee_stats_result, arg0,
1668 str_dump_xbee_stats_arg0);
1670 const char PROGMEM help_dump_xbee_stats[] = "Test the spi";
1671 const parse_inst_t PROGMEM cmd_dump_xbee_stats = {
1672 .f = cmd_dump_xbee_stats_parsed, /* function to call */
1673 .data = NULL, /* 2nd arg of func */
1674 .help_str = help_dump_xbee_stats,
1675 .tokens = { /* token list, NULL terminated */
1676 (PGM_P)&cmd_dump_xbee_stats_arg0,
1681 /**********************************************************/
1683 /* this structure is filled when cmd_test_eeprom_config is parsed successfully */
1684 struct cmd_test_eeprom_config_result {
1685 fixed_string_t arg0;
1688 static void cmd_test_eeprom_config_parsed(void *parsed_result, void *data)
1690 (void)parsed_result;
1694 eeprom_append_cmd("salut1\n");
1696 eeprom_append_cmd("salut2\n");
1697 eeprom_append_cmd("salut3\n");
1698 eeprom_append_cmd("salut4\n");
1700 eeprom_insert_cmd_before("coin\n", 0);
1701 eeprom_insert_cmd_before("coin2\n", 2);
1703 eeprom_delete_cmd(2);
1704 eeprom_delete_cmd(0);
1708 const char PROGMEM str_test_eeprom_config_arg0[] = "test_eeprom_config";
1709 const parse_token_string_t PROGMEM cmd_test_eeprom_config_arg0 =
1710 TOKEN_STRING_INITIALIZER(struct cmd_test_eeprom_config_result, arg0,
1711 str_test_eeprom_config_arg0);
1713 const char PROGMEM help_test_eeprom_config[] = "Test the eeprom configuration";
1714 const parse_inst_t PROGMEM cmd_test_eeprom_config = {
1715 .f = cmd_test_eeprom_config_parsed, /* function to call */
1716 .data = NULL, /* 2nd arg of func */
1717 .help_str = help_test_eeprom_config,
1718 .tokens = { /* token list, NULL terminated */
1719 (PGM_P)&cmd_test_eeprom_config_arg0,
1726 struct cmd_eeprom_del_result {
1728 fixed_string_t action;
1732 static void cmd_eeprom_del_parsed(void *parsed_result,
1735 struct cmd_eeprom_del_result *res = parsed_result;
1738 if (eeprom_delete_cmd(res->n) < 0)
1739 printf_P(PSTR("cannot delete command\n"));
1743 const char PROGMEM str_eeprom_del_eeprom[] = "eeprom";
1744 const parse_token_string_t PROGMEM cmd_eeprom_del_cmd =
1745 TOKEN_STRING_INITIALIZER(struct cmd_eeprom_del_result, cmd,
1746 str_eeprom_del_eeprom);
1747 const char PROGMEM str_eeprom_del_del[] = "del";
1748 const parse_token_string_t PROGMEM cmd_eeprom_del_action =
1749 TOKEN_STRING_INITIALIZER(struct cmd_eeprom_del_result, action,
1750 str_eeprom_del_del);
1751 const parse_token_num_t PROGMEM cmd_eeprom_del_num =
1752 TOKEN_NUM_INITIALIZER(struct cmd_eeprom_del_result, n,
1755 const char PROGMEM help_eeprom_del[] = "delete an eeprom init command";
1756 const parse_inst_t PROGMEM cmd_eeprom_del = {
1757 .f = cmd_eeprom_del_parsed, /* function to call */
1758 .data = NULL, /* 2nd arg of func */
1759 .help_str = help_eeprom_del,
1760 .tokens = { /* token list, NULL terminated */
1761 (PGM_P)&cmd_eeprom_del_cmd,
1762 (PGM_P)&cmd_eeprom_del_action,
1763 (PGM_P)&cmd_eeprom_del_num,
1770 struct cmd_eeprom_add_result {
1772 fixed_string_t action;
1776 static void cmd_eeprom_add_parsed(void *parsed_result,
1779 struct cmd_eeprom_add_result *res = parsed_result;
1785 rdline_init(&rdl, cmdline_write_char, NULL, NULL);
1786 rdline_newline(&rdl, "> ");
1788 /* XXX bad: we should not block as we do not serve callout */
1790 c = cmdline_dev_recv(NULL);
1794 ret = rdline_char_in(&rdl, c);
1796 printf_P(PSTR("abort\n"));
1803 buffer = rdline_get_buffer(&rdl);
1805 eeprom_insert_cmd_before(buffer, res->n);
1807 eeprom_append_cmd(buffer);
1811 const char PROGMEM str_eeprom_add_eeprom[] = "eeprom";
1812 const parse_token_string_t PROGMEM cmd_eeprom_add_cmd =
1813 TOKEN_STRING_INITIALIZER(struct cmd_eeprom_add_result, cmd,
1814 str_eeprom_add_eeprom);
1815 const char PROGMEM str_eeprom_add_add[] = "add";
1816 const parse_token_string_t PROGMEM cmd_eeprom_add_action =
1817 TOKEN_STRING_INITIALIZER(struct cmd_eeprom_add_result, action,
1818 str_eeprom_add_add);
1819 const parse_token_num_t PROGMEM cmd_eeprom_add_num =
1820 TOKEN_NUM_INITIALIZER(struct cmd_eeprom_add_result, n,
1823 const char PROGMEM help_eeprom_add[] = "insert an eeprom init command";
1824 const parse_inst_t PROGMEM cmd_eeprom_add = {
1825 .f = cmd_eeprom_add_parsed, /* function to call */
1826 .data = NULL, /* 2nd arg of func */
1827 .help_str = help_eeprom_add,
1828 .tokens = { /* token list, NULL terminated */
1829 (PGM_P)&cmd_eeprom_add_cmd,
1830 (PGM_P)&cmd_eeprom_add_action,
1831 (PGM_P)&cmd_eeprom_add_num,
1836 const char PROGMEM help_eeprom_add2[] = "append an eeprom init command";
1837 const parse_inst_t PROGMEM cmd_eeprom_add2 = {
1838 .f = cmd_eeprom_add_parsed, /* function to call */
1839 .data = (void *)1, /* 2nd arg of func */
1840 .help_str = help_eeprom_add2,
1841 .tokens = { /* token list, NULL terminated */
1842 (PGM_P)&cmd_eeprom_add_cmd,
1843 (PGM_P)&cmd_eeprom_add_action,
1850 struct cmd_eeprom_list_result {
1852 fixed_string_t action;
1855 static void cmd_eeprom_list_parsed(void *parsed_result,
1858 (void)parsed_result;
1863 const char PROGMEM str_eeprom_list_eeprom[] = "eeprom";
1864 const parse_token_string_t PROGMEM cmd_eeprom_list_cmd =
1865 TOKEN_STRING_INITIALIZER(struct cmd_eeprom_list_result, cmd,
1866 str_eeprom_list_eeprom);
1867 const char PROGMEM str_eeprom_list_list[] = "list";
1868 const parse_token_string_t PROGMEM cmd_eeprom_list_action =
1869 TOKEN_STRING_INITIALIZER(struct cmd_eeprom_list_result, action,
1870 str_eeprom_list_list);
1872 const char PROGMEM help_eeprom_list[] = "list all eeprom init commands";
1873 const parse_inst_t PROGMEM cmd_eeprom_list = {
1874 .f = cmd_eeprom_list_parsed, /* function to call */
1875 .data = NULL, /* 2nd arg of func */
1876 .help_str = help_eeprom_list,
1877 .tokens = { /* token list, NULL terminated */
1878 (PGM_P)&cmd_eeprom_list_cmd,
1879 (PGM_P)&cmd_eeprom_list_action,
1888 const parse_ctx_t PROGMEM main_ctx[] = {
1890 /* commands_gen.c */
1909 &cmd_send_hello_name,
1914 &cmd_range_powermask,
1917 &cmd_monitor_period,
1927 &cmd_servo_bypassppm,
1930 &cmd_dump_xbee_stats,
1931 &cmd_test_eeprom_config,