2 * Copyright Droids Corporation (2011)
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 * Revision : $Id: commands.c,v 1.9 2009-11-08 17:24:33 zer0 Exp $
20 * Olivier MATZ <zer0@droids-corp.org>
28 #include <aversive/pgmspace.h>
29 #include <aversive/queue.h>
30 #include <aversive/endian.h>
31 #include <aversive/error.h>
32 #include <aversive/wait.h>
35 #include <parse_string.h>
36 #include <parse_num.h>
39 #include "xbee_atcmd.h"
40 #include "xbee_neighbor.h"
41 #include "xbee_stats.h"
42 #include "xbee_proto.h"
46 #include "parse_atcmd.h"
47 #include "parse_neighbor.h"
48 #include "parse_monitor.h"
50 #include "spi_servo.h"
57 extern const parse_inst_t PROGMEM cmd_reset;
58 extern const parse_inst_t PROGMEM cmd_bootloader;
59 extern const parse_inst_t PROGMEM cmd_log;
60 extern const parse_inst_t PROGMEM cmd_log_show;
61 extern const parse_inst_t PROGMEM cmd_log_type;
62 extern const parse_inst_t PROGMEM cmd_stack_space;
63 extern const parse_inst_t PROGMEM cmd_scheduler;
65 static int monitor_period_ms = 1000;
66 static int monitor_running = 0;
67 static int monitor_count = 0;
68 static struct callout monitor_event;
69 struct monitor_reg *monitor_current;
71 static int range_period_ms = 1000;
72 static int range_powermask = 0x1F;
73 static uint8_t range_power = 0;
74 static int range_running = 0;
75 static uint64_t range_dstaddr = 0xFFFF; /* broadcast by default */
76 static struct callout range_event;
77 static int range_count = 100;
78 static int range_cur_count = 0;
80 static void monitor_cb(struct callout_manager *cm,
81 struct callout *clt, void *dummy)
86 if (monitor_current == NULL)
87 monitor_current = LIST_FIRST(&xbee_monitor_list);
89 xbeeapp_send_atcmd(monitor_current->atcmd, NULL, 0, 0, NULL, NULL);
90 monitor_current = LIST_NEXT(monitor_current, next);
91 callout_reset(cm, &monitor_event,
92 monitor_period_ms / monitor_count,
93 SINGLE, monitor_cb, NULL);
96 static void range_cb(struct callout_manager *cm,
97 struct callout *clt, void *dummy)
100 struct rc_proto_range rangepkt;
107 /* get new xmit power */
108 for (i = 1; i <= 8; i++) {
109 mask = 1 << ((range_power + i) & 0x7);
110 if (mask & range_powermask)
113 range_power = ((range_power + i) & 0x7);
115 xbeeapp_send_atcmd("PL", &range_power, sizeof(range_power), 0, NULL, NULL);
117 rangepkt.type = RC_PROTO_TYPE_RANGE;
118 rangepkt.power_level = range_power;
120 xbeeapp_send_msg(range_dstaddr, &rangepkt, sizeof(rangepkt), 0);
122 if (range_cur_count == 0) {
127 callout_reset(cm, &range_event,
129 SINGLE, range_cb, NULL);
132 /* this structure is filled when cmd_help is parsed successfully */
133 struct cmd_help_result {
135 struct xbee_atcmd *cmd;
138 /* function called when cmd_help is parsed successfully */
139 static void cmd_help_parsed(void *parsed_result, void *data)
141 struct cmd_help_result *res = parsed_result;
142 struct xbee_atcmd cmdcopy;
147 memcpy_P(&cmdcopy, res->cmd, sizeof(cmdcopy));
148 type = (cmdcopy.flags & (XBEE_ATCMD_F_READ | XBEE_ATCMD_F_WRITE));
150 case XBEE_ATCMD_F_READ:
151 printf_P(PSTR("Read-only\r\n"));
153 case XBEE_ATCMD_F_WRITE:
154 printf_P(PSTR("Write-only\r\n"));
157 printf_P(PSTR("Read-write\r\n"));
160 if (cmdcopy.flags & XBEE_ATCMD_F_PARAM_NONE)
161 printf_P(PSTR("No argument\r\n"));
162 else if (cmdcopy.flags & XBEE_ATCMD_F_PARAM_U8)
163 printf_P(PSTR("Register is unsigned 8 bits\r\n"));
164 else if (cmdcopy.flags & XBEE_ATCMD_F_PARAM_U16)
165 printf_P(PSTR("Register is unsigned 16 bits\r\n"));
166 else if (cmdcopy.flags & XBEE_ATCMD_F_PARAM_U32)
167 printf_P(PSTR("Register is unsigned 32 bits\r\n"));
168 else if (cmdcopy.flags & XBEE_ATCMD_F_PARAM_S16)
169 printf_P(PSTR("Register is signed 16 bits\r\n"));
170 else if (cmdcopy.flags & XBEE_ATCMD_F_PARAM_STRING_20B)
171 printf_P(PSTR("Register is a 20 bytes string\r\n"));
173 printf_P(PSTR("Unknown argument\r\n"));
175 printf_P(PSTR("%S\r\n"), cmdcopy.help);
177 const char PROGMEM str_help_help[] = "help";
179 const parse_token_string_t PROGMEM cmd_help_help =
180 TOKEN_STRING_INITIALIZER(struct cmd_help_result, help, str_help_help);
182 const parse_token_atcmd_t PROGMEM cmd_help_atcmd =
183 TOKEN_ATCMD_INITIALIZER(struct cmd_help_result, cmd, &xbee_dev,
186 const char PROGMEM help_help[] = "Help a register using an AT command";
187 const parse_inst_t PROGMEM cmd_help = {
188 .f = cmd_help_parsed, /* function to call */
189 .data = NULL, /* 2nd arg of func */
190 .help_str = help_help,
191 .tokens = { /* token list, NULL terminated */
192 (PGM_P)&cmd_help_help,
193 (PGM_P)&cmd_help_atcmd,
200 struct cmd_neigh_del_result {
202 fixed_string_t action;
203 struct xbee_neigh *neigh;
206 static void cmd_neigh_del_parsed(void *parsed_result,
209 struct cmd_neigh_del_result *res = parsed_result;
212 xbee_neigh_del(xbee_dev, res->neigh);
215 const char PROGMEM str_neigh_del_neigh[] = "neigh";
216 const parse_token_string_t PROGMEM cmd_neigh_del_cmd =
217 TOKEN_STRING_INITIALIZER(struct cmd_neigh_del_result, cmd,
218 str_neigh_del_neigh);
219 const char PROGMEM str_neigh_del_del[] = "del";
220 const parse_token_string_t PROGMEM cmd_neigh_del_action =
221 TOKEN_STRING_INITIALIZER(struct cmd_neigh_del_result, action,
223 const parse_token_neighbor_t PROGMEM cmd_neigh_del_neigh =
224 TOKEN_NEIGHBOR_INITIALIZER(struct cmd_neigh_del_result, neigh,
227 const char PROGMEM help_neigh_del[] = "delete a neighbor";
228 const parse_inst_t PROGMEM cmd_neigh_del = {
229 .f = cmd_neigh_del_parsed, /* function to call */
230 .data = NULL, /* 2nd arg of func */
231 .help_str = help_neigh_del,
232 .tokens = { /* token list, NULL terminated */
233 (PGM_P)&cmd_neigh_del_cmd,
234 (PGM_P)&cmd_neigh_del_action,
235 (PGM_P)&cmd_neigh_del_neigh,
242 struct cmd_neigh_add_result {
244 fixed_string_t action;
249 static void cmd_neigh_add_parsed(void *parsed_result,
252 struct cmd_neigh_add_result *res = parsed_result;
255 if (xbee_neigh_add(xbee_dev, res->name, res->addr) == NULL)
256 printf_P(PSTR("name or addr already exist\r\n"));
259 const char PROGMEM str_neigh_add_neigh[] = "neigh";
260 const parse_token_string_t PROGMEM cmd_neigh_add_cmd =
261 TOKEN_STRING_INITIALIZER(struct cmd_neigh_add_result, cmd,
262 str_neigh_add_neigh);
263 const char PROGMEM str_neigh_add_add[] = "add";
264 const parse_token_string_t PROGMEM cmd_neigh_add_action =
265 TOKEN_STRING_INITIALIZER(struct cmd_neigh_add_result, action,
267 const parse_token_string_t PROGMEM cmd_neigh_add_name =
268 TOKEN_STRING_INITIALIZER(struct cmd_neigh_add_result, name, NULL);
269 const parse_token_num_t PROGMEM cmd_neigh_add_addr =
270 TOKEN_NUM_INITIALIZER(struct cmd_neigh_add_result, addr, UINT64);
272 const char PROGMEM help_neigh_add[] = "add a neighbor";
273 const parse_inst_t PROGMEM cmd_neigh_add = {
274 .f = cmd_neigh_add_parsed, /* function to call */
275 .data = NULL, /* 2nd arg of func */
276 .help_str = help_neigh_add,
277 .tokens = { /* token list, NULL terminated */
278 (PGM_P)&cmd_neigh_add_cmd,
279 (PGM_P)&cmd_neigh_add_action,
280 (PGM_P)&cmd_neigh_add_name,
281 (PGM_P)&cmd_neigh_add_addr,
288 struct cmd_neigh_list_result {
290 fixed_string_t action;
293 static void cmd_neigh_list_parsed(void *parsed_result,
296 struct xbee_neigh *neigh;
300 LIST_FOREACH(neigh, &xbee_dev->neigh_list, next) {
301 printf_P(PSTR(" %s: 0x%.8"PRIx32"%.8"PRIx32"\r\n"),
303 (uint32_t)(neigh->addr >> 32ULL),
304 (uint32_t)(neigh->addr & 0xFFFFFFFF));
308 const char PROGMEM str_neigh_list_neigh[] = "neigh";
309 const parse_token_string_t PROGMEM cmd_neigh_list_cmd =
310 TOKEN_STRING_INITIALIZER(struct cmd_neigh_list_result, cmd,
311 str_neigh_list_neigh);
312 const char PROGMEM str_neigh_list_list[] = "list";
313 const parse_token_string_t PROGMEM cmd_neigh_list_action =
314 TOKEN_STRING_INITIALIZER(struct cmd_neigh_list_result, action,
315 str_neigh_list_list);
317 const char PROGMEM help_neigh_list[] = "list all knwon neighbors";
318 const parse_inst_t PROGMEM cmd_neigh_list = {
319 .f = cmd_neigh_list_parsed, /* function to call */
320 .data = NULL, /* 2nd arg of func */
321 .help_str = help_neigh_list,
322 .tokens = { /* token list, NULL terminated */
323 (PGM_P)&cmd_neigh_list_cmd,
324 (PGM_P)&cmd_neigh_list_action,
334 /* this structure is filled when cmd_read is parsed successfully */
335 struct cmd_read_result {
337 struct xbee_atcmd *cmd;
340 /* function called when cmd_read is parsed successfully */
341 static void cmd_read_parsed(void *parsed_result,
344 struct cmd_read_result *res = parsed_result;
345 struct xbee_atcmd copy;
349 memcpy_P(©, res->cmd, sizeof(copy));
350 memcpy_P(&cmd, copy.name, 2);
352 xbeeapp_send_atcmd(cmd, NULL, 0, 1, NULL, NULL);
355 const char PROGMEM str_read_read[] = "read";
357 const parse_token_string_t PROGMEM cmd_read_read =
358 TOKEN_STRING_INITIALIZER(struct cmd_read_result, read,
361 const parse_token_atcmd_t PROGMEM cmd_read_atcmd =
362 TOKEN_ATCMD_INITIALIZER(struct cmd_read_result, cmd, &xbee_dev,
363 XBEE_ATCMD_F_READ, XBEE_ATCMD_F_READ);
365 const char PROGMEM help_read[] = "Read a register using an AT command";
366 const parse_inst_t PROGMEM cmd_read = {
367 .f = cmd_read_parsed, /* function to call */
368 .data = NULL, /* 2nd arg of func */
369 .help_str = help_read,
370 .tokens = { /* token list, NULL terminated */
371 (PGM_P)&cmd_read_read,
372 (PGM_P)&cmd_read_atcmd,
380 /* this structure is filled when cmd_write is parsed successfully */
381 struct cmd_write_result {
382 fixed_string_t write;
383 struct xbee_atcmd *cmd;
391 /* function called when cmd_write is parsed successfully */
392 static void cmd_write_parsed(void *parsed_result, void *data)
394 struct cmd_write_result *res = parsed_result;
395 struct xbee_atcmd copy;
401 memcpy_P(©, res->cmd, sizeof(copy));
403 if (copy.flags & XBEE_ATCMD_F_PARAM_NONE) {
407 else if (copy.flags & XBEE_ATCMD_F_PARAM_U8) {
408 len = sizeof(res->u8);
411 else if (copy.flags & XBEE_ATCMD_F_PARAM_U16) {
412 len = sizeof(res->u16);
413 res->u16 = htons(res->u16);
416 else if (copy.flags & XBEE_ATCMD_F_PARAM_U32) {
417 len = sizeof(res->u32);
418 res->u32 = htonl(res->u32);
422 printf_P(PSTR("Unknown argument type\r\n"));
425 memcpy_P(&cmd, copy.name, 2);
427 xbeeapp_send_atcmd(cmd, param, len, 1, NULL, NULL);
430 const char PROGMEM str_write_none[] = "write";
432 const parse_token_string_t PROGMEM cmd_write_write =
433 TOKEN_STRING_INITIALIZER(struct cmd_write_result, write,
436 const parse_token_atcmd_t PROGMEM cmd_write_none_atcmd =
437 TOKEN_ATCMD_INITIALIZER(struct cmd_write_result, cmd,
439 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_NONE,
440 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_NONE);
442 const char PROGMEM help_write_none[] = "Send an AT command (no argument)";
444 const parse_inst_t PROGMEM cmd_write_none = {
445 .f = cmd_write_parsed, /* function to call */
446 .data = NULL, /* 2nd arg of func */
447 .help_str = help_write_none,
448 .tokens = { /* token list, NULL terminated */
449 (PGM_P)&cmd_write_write,
450 (PGM_P)&cmd_write_none_atcmd,
455 const parse_token_atcmd_t PROGMEM cmd_write_u8_atcmd =
456 TOKEN_ATCMD_INITIALIZER(struct cmd_write_result, cmd,
458 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_U8,
459 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_U8);
461 const parse_token_num_t PROGMEM cmd_write_u8_u8 =
462 TOKEN_NUM_INITIALIZER(struct cmd_write_result, u8, UINT8);
464 const char PROGMEM help_write_u8[] = "Write a 8 bits register using an AT command";
466 const parse_inst_t PROGMEM cmd_write_u8 = {
467 .f = cmd_write_parsed, /* function to call */
468 .data = NULL, /* 2nd arg of func */
469 .help_str = help_write_u8,
470 .tokens = { /* token list, NULL terminated */
471 (PGM_P)&cmd_write_write,
472 (PGM_P)&cmd_write_u8_atcmd,
473 (PGM_P)&cmd_write_u8_u8,
478 const parse_token_atcmd_t PROGMEM cmd_write_u16_atcmd =
479 TOKEN_ATCMD_INITIALIZER(struct cmd_write_result, cmd,
481 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_U16,
482 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_U16);
484 const parse_token_num_t PROGMEM cmd_write_u16_u16 =
485 TOKEN_NUM_INITIALIZER(struct cmd_write_result, u16, UINT16);
487 const char PROGMEM help_write_u16[] = "Write a 16 bits register using an AT command";
489 const parse_inst_t PROGMEM cmd_write_u16 = {
490 .f = cmd_write_parsed, /* function to call */
491 .data = NULL, /* 2nd arg of func */
492 .help_str = help_write_u16,
493 .tokens = { /* token list, NULL terminated */
494 (PGM_P)&cmd_write_write,
495 (PGM_P)&cmd_write_u16_atcmd,
496 (PGM_P)&cmd_write_u16_u16,
501 const parse_token_atcmd_t PROGMEM cmd_write_u32_atcmd =
502 TOKEN_ATCMD_INITIALIZER(struct cmd_write_result, cmd,
504 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_U32,
505 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_U32);
507 const parse_token_num_t PROGMEM cmd_write_u32_u32 =
508 TOKEN_NUM_INITIALIZER(struct cmd_write_result, u32, UINT32);
510 const char PROGMEM help_write_u32[] = "Write a 32 bits register using an AT command";
512 const parse_inst_t PROGMEM cmd_write_u32 = {
513 .f = cmd_write_parsed, /* function to call */
514 .data = NULL, /* 2nd arg of func */
515 .help_str = help_write_u32,
516 .tokens = { /* token list, NULL terminated */
517 (PGM_P)&cmd_write_write,
518 (PGM_P)&cmd_write_u32_atcmd,
519 (PGM_P)&cmd_write_u32_u32,
527 /* this structure is filled when cmd_sendmsg is parsed successfully */
528 struct cmd_sendmsg_result {
529 fixed_string_t sendmsg;
534 /* function called when cmd_sendmsg is parsed successfully */
535 static void cmd_sendmsg_parsed(void *parsed_result, void *data)
537 struct cmd_sendmsg_result *res = parsed_result;
540 xbeeapp_send_msg(res->addr, res->data, strlen(res->data), 1);
543 const char PROGMEM str_sendmsg[] = "sendmsg";
545 const parse_token_string_t PROGMEM cmd_sendmsg_sendmsg =
546 TOKEN_STRING_INITIALIZER(struct cmd_sendmsg_result, sendmsg,
549 const parse_token_num_t PROGMEM cmd_sendmsg_addr =
550 TOKEN_NUM_INITIALIZER(struct cmd_sendmsg_result, addr, UINT64);
552 const parse_token_string_t PROGMEM cmd_sendmsg_data =
553 TOKEN_STRING_INITIALIZER(struct cmd_sendmsg_result, data, NULL);
555 const char PROGMEM help_sendmsg[] = "Send data to a node using its address";
557 const parse_inst_t PROGMEM cmd_sendmsg = {
558 .f = cmd_sendmsg_parsed, /* function to call */
559 .data = NULL, /* 2nd arg of func */
560 .help_str = help_sendmsg,
561 .tokens = { /* token list, NULL terminated */
562 (PGM_P)&cmd_sendmsg_sendmsg,
563 (PGM_P)&cmd_sendmsg_addr,
564 (PGM_P)&cmd_sendmsg_data,
571 /* this structure is filled when cmd_sendmsg_name is parsed successfully */
572 struct cmd_sendmsg_name_result {
573 fixed_string_t sendmsg_name;
574 struct xbee_neigh *neigh;
578 /* function called when cmd_sendmsg_name is parsed successfully */
579 static void cmd_sendmsg_name_parsed(void *parsed_result, void *data)
581 struct cmd_sendmsg_name_result *res = parsed_result;
584 xbeeapp_send_msg(res->neigh->addr, res->data, strlen(res->data), 1);
587 const parse_token_string_t PROGMEM cmd_sendmsg_name_sendmsg_name =
588 TOKEN_STRING_INITIALIZER(struct cmd_sendmsg_name_result, sendmsg_name,
591 const parse_token_neighbor_t PROGMEM cmd_sendmsg_name_neigh =
592 TOKEN_NEIGHBOR_INITIALIZER(struct cmd_sendmsg_name_result, neigh,
595 const parse_token_string_t PROGMEM cmd_sendmsg_name_data =
596 TOKEN_STRING_INITIALIZER(struct cmd_sendmsg_name_result, data, NULL);
598 const char PROGMEM help_sendmsg_name[] = "Send data to a node using its name";
600 const parse_inst_t PROGMEM cmd_sendmsg_name = {
601 .f = cmd_sendmsg_name_parsed, /* function to call */
602 .data = NULL, /* 2nd arg of func */
603 .help_str = help_sendmsg_name,
604 .tokens = { /* token list, NULL terminated */
605 (PGM_P)&cmd_sendmsg_name_sendmsg_name,
606 (PGM_P)&cmd_sendmsg_name_neigh,
607 (PGM_P)&cmd_sendmsg_name_data,
615 /* this structure is filled when cmd_range is parsed successfully */
616 struct cmd_range_result {
617 fixed_string_t range;
618 fixed_string_t action;
621 /* function called when cmd_range is parsed successfully */
622 static void cmd_range_parsed(void *parsed_result, void *data)
624 struct cmd_range_result *res = parsed_result;
627 if (!strcmp_P(res->action, PSTR("show"))) {
628 printf_P(PSTR("range infos:\r\n"));
629 printf_P(PSTR(" range period %d\r\n"), range_period_ms);
630 printf_P(PSTR(" range count %d\r\n"), range_count);
631 printf_P(PSTR(" range powermask 0x%x\r\n"), range_powermask);
632 printf_P(PSTR(" range dstaddr 0x%.8"PRIx32"%.8"PRIx32"\r\n"),
633 (uint32_t)(range_dstaddr >> 32ULL),
634 (uint32_t)(range_dstaddr & 0xFFFFFFFF));
637 printf_P(PSTR(" range test is running\r\n"));
639 printf_P(PSTR(" range test is not running\r\n"));
641 else if (!strcmp(res->action, "start")) {
643 printf_P(PSTR("already running\r\n"));
646 range_cur_count = range_count;
647 callout_init(&range_event);
648 callout_reset(&cm, &range_event, 0,
649 SINGLE, range_cb, NULL);
652 else if (!strcmp(res->action, "end")) {
653 if (range_running == 0) {
654 printf_P(PSTR("not running\r\n"));
658 callout_stop(&cm, &range_event);
662 const char PROGMEM str_range[] = "range";
663 const char PROGMEM str_range_tokens[] = "show#start#end";
665 const parse_token_string_t PROGMEM cmd_range_range =
666 TOKEN_STRING_INITIALIZER(struct cmd_range_result, range,
668 const parse_token_string_t PROGMEM cmd_range_action =
669 TOKEN_STRING_INITIALIZER(struct cmd_range_result, action,
672 const char PROGMEM help_range[] = "start/stop/show current rangeing";
674 const parse_inst_t PROGMEM cmd_range = {
675 .f = cmd_range_parsed, /* function to call */
676 .data = NULL, /* 2nd arg of func */
677 .help_str = help_range,
678 .tokens = { /* token list, NULL terminated */
679 (PGM_P)&cmd_range_range,
680 (PGM_P)&cmd_range_action,
687 /* this structure is filled when cmd_range_period is parsed successfully */
688 struct cmd_range_period_result {
689 fixed_string_t range;
690 fixed_string_t action;
694 /* function called when cmd_range_period is parsed successfully */
695 static void cmd_range_period_parsed(void *parsed_result, void *data)
697 struct cmd_range_period_result *res = parsed_result;
700 if (res->period < 10) {
701 printf_P(PSTR("error, minimum period is 10 ms\r\n"));
705 range_period_ms = res->period;
708 const char PROGMEM str_period[] = "period";
710 const parse_token_string_t PROGMEM cmd_range_period_range_period =
711 TOKEN_STRING_INITIALIZER(struct cmd_range_period_result, range,
713 const parse_token_string_t PROGMEM cmd_range_period_action =
714 TOKEN_STRING_INITIALIZER(struct cmd_range_period_result, action,
716 const parse_token_num_t PROGMEM cmd_range_period_period =
717 TOKEN_NUM_INITIALIZER(struct cmd_range_period_result, period, UINT32);
719 const char PROGMEM help_range_period[] = "set range test period";
721 const parse_inst_t PROGMEM cmd_range_period = {
722 .f = cmd_range_period_parsed, /* function to call */
723 .data = NULL, /* 2nd arg of func */
724 .help_str = help_range_period,
725 .tokens = { /* token list, NULL terminated */
726 (PGM_P)&cmd_range_period_range_period,
727 (PGM_P)&cmd_range_period_action,
728 (PGM_P)&cmd_range_period_period,
735 /* this structure is filled when cmd_range_count is parsed successfully */
736 struct cmd_range_count_result {
737 fixed_string_t range;
738 fixed_string_t action;
742 /* function called when cmd_range_count is parsed successfully */
743 static void cmd_range_count_parsed(void *parsed_result, void *data)
745 struct cmd_range_count_result *res = parsed_result;
748 range_count = res->count;
751 const char PROGMEM str_count[] = "count";
753 const parse_token_string_t PROGMEM cmd_range_count_range_count =
754 TOKEN_STRING_INITIALIZER(struct cmd_range_count_result, range,
756 const parse_token_string_t PROGMEM cmd_range_count_action =
757 TOKEN_STRING_INITIALIZER(struct cmd_range_count_result, action,
759 const parse_token_num_t PROGMEM cmd_range_count_count =
760 TOKEN_NUM_INITIALIZER(struct cmd_range_count_result, count, UINT32);
763 const char PROGMEM help_range_count[] = "set range test count";
765 const parse_inst_t PROGMEM cmd_range_count = {
766 .f = cmd_range_count_parsed, /* function to call */
767 .data = NULL, /* 2nd arg of func */
768 .help_str = help_range_count,
769 .tokens = { /* token list, NULL terminated */
770 (PGM_P)&cmd_range_count_range_count,
771 (PGM_P)&cmd_range_count_action,
772 (PGM_P)&cmd_range_count_count,
779 /* this structure is filled when cmd_range_powermask is parsed successfully */
780 struct cmd_range_powermask_result {
781 fixed_string_t range;
782 fixed_string_t action;
786 /* function called when cmd_range_powermask is parsed successfully */
787 static void cmd_range_powermask_parsed(void *parsed_result, void *data)
789 struct cmd_range_powermask_result *res = parsed_result;
792 range_powermask = res->powermask;
795 const char PROGMEM str_powermask[] = "powermask";
797 const parse_token_string_t PROGMEM cmd_range_powermask_range_powermask =
798 TOKEN_STRING_INITIALIZER(struct cmd_range_powermask_result, range,
800 const parse_token_string_t PROGMEM cmd_range_powermask_action =
801 TOKEN_STRING_INITIALIZER(struct cmd_range_powermask_result, action,
803 const parse_token_num_t PROGMEM cmd_range_powermask_powermask =
804 TOKEN_NUM_INITIALIZER(struct cmd_range_powermask_result, powermask,
808 const char PROGMEM help_range_powermask[] = "set range test powermask";
810 const parse_inst_t PROGMEM cmd_range_powermask = {
811 .f = cmd_range_powermask_parsed, /* function to call */
812 .data = NULL, /* 2nd arg of func */
813 .help_str = help_range_powermask,
814 .tokens = { /* token list, NULL terminated */
815 (PGM_P)&cmd_range_powermask_range_powermask,
816 (PGM_P)&cmd_range_powermask_action,
817 (PGM_P)&cmd_range_powermask_powermask,
824 /* this structure is filled when cmd_range_dstaddr is parsed successfully */
825 struct cmd_range_dstaddr_result {
826 fixed_string_t range;
827 fixed_string_t action;
831 /* function called when cmd_range_dstaddr is parsed successfully */
832 static void cmd_range_dstaddr_parsed(void *parsed_result, void *data)
834 struct cmd_range_dstaddr_result *res = parsed_result;
837 range_dstaddr = res->dstaddr;
840 const char PROGMEM str_dstaddr[] = "dstaddr";
842 const parse_token_string_t PROGMEM cmd_range_dstaddr_range_dstaddr =
843 TOKEN_STRING_INITIALIZER(struct cmd_range_dstaddr_result, range,
845 const parse_token_string_t PROGMEM cmd_range_dstaddr_action =
846 TOKEN_STRING_INITIALIZER(struct cmd_range_dstaddr_result, action,
848 const parse_token_num_t PROGMEM cmd_range_dstaddr_dstaddr =
849 TOKEN_NUM_INITIALIZER(struct cmd_range_dstaddr_result, dstaddr, UINT64);
852 const char PROGMEM help_range_dstaddr[] = "set register rangeing dstaddr";
854 const parse_inst_t PROGMEM cmd_range_dstaddr = {
855 .f = cmd_range_dstaddr_parsed, /* function to call */
856 .data = NULL, /* 2nd arg of func */
857 .help_str = help_range_dstaddr,
858 .tokens = { /* token list, NULL terminated */
859 (PGM_P)&cmd_range_dstaddr_range_dstaddr,
860 (PGM_P)&cmd_range_dstaddr_action,
861 (PGM_P)&cmd_range_dstaddr_dstaddr,
869 /* this structure is filled when cmd_monitor is parsed successfully */
870 struct cmd_monitor_result {
871 fixed_string_t monitor;
872 fixed_string_t action;
875 /* function called when cmd_monitor is parsed successfully */
876 static void cmd_monitor_parsed(void *parsed_result, void *data)
878 struct cmd_monitor_result *res = parsed_result;
879 struct monitor_reg *m;
882 if (!strcmp_P(res->action, PSTR("show"))) {
883 printf_P(PSTR("monitor period is %d ms, %d regs in list\r\n"),
884 monitor_period_ms, monitor_count);
885 LIST_FOREACH(m, &xbee_monitor_list, next)
886 printf_P(PSTR(" %S\r\n"), m->desc);
888 else if (!strcmp_P(res->action, PSTR("start"))) {
889 if (monitor_running) {
890 printf_P(PSTR("already running\r\n"));
893 if (monitor_count == 0) {
894 printf_P(PSTR("no regs to be monitored\r\n"));
897 callout_init(&monitor_event);
898 callout_reset(&cm, &monitor_event, 0, SINGLE, monitor_cb, NULL);
900 monitor_current = LIST_FIRST(&xbee_monitor_list);
901 printf_P(PSTR("monitor cb: %S %s\r\n"),
902 monitor_current->desc,
903 monitor_current->atcmd);
906 else if (!strcmp_P(res->action, PSTR("end"))) {
907 if (monitor_running == 0) {
908 printf_P(PSTR("not running\r\n"));
912 callout_stop(&cm, &monitor_event);
916 const char PROGMEM str_monitor[] = "monitor";
917 const char PROGMEM str_monitor_tokens[] = "show#start#end";
919 const parse_token_string_t PROGMEM cmd_monitor_monitor =
920 TOKEN_STRING_INITIALIZER(struct cmd_monitor_result, monitor,
922 const parse_token_string_t PROGMEM cmd_monitor_action =
923 TOKEN_STRING_INITIALIZER(struct cmd_monitor_result, action,
926 const char PROGMEM help_monitor[] = "start/stop/show current monitoring";
928 const parse_inst_t PROGMEM cmd_monitor = {
929 .f = cmd_monitor_parsed, /* function to call */
930 .data = NULL, /* 2nd arg of func */
931 .help_str = help_monitor,
932 .tokens = { /* token list, NULL terminated */
933 (PGM_P)&cmd_monitor_monitor,
934 (PGM_P)&cmd_monitor_action,
941 /* this structure is filled when cmd_monitor_add is parsed successfully */
942 struct cmd_monitor_add_result {
943 fixed_string_t monitor;
944 fixed_string_t action;
945 struct xbee_atcmd *cmd;
948 /* function called when cmd_monitor_add is parsed successfully */
949 static void cmd_monitor_add_parsed(void *parsed_result, void *data)
951 struct cmd_monitor_add_result *res = parsed_result;
952 struct monitor_reg *m;
953 struct xbee_atcmd copy;
956 memcpy_P(©, res->cmd, sizeof(copy));
957 LIST_FOREACH(m, &xbee_monitor_list, next) {
958 if (!strcmp_P(m->atcmd, copy.name))
963 printf_P(PSTR("already exist\r\n"));
967 m = malloc(sizeof(*m));
969 printf_P(PSTR("no mem\r\n"));
973 strcpy_P(m->atcmd, copy.name);
974 LIST_INSERT_HEAD(&xbee_monitor_list, m, next);
978 const char PROGMEM str_monitor_add[] = "add";
980 const parse_token_string_t PROGMEM cmd_monitor_add_monitor_add =
981 TOKEN_STRING_INITIALIZER(struct cmd_monitor_add_result, monitor,
983 const parse_token_string_t PROGMEM cmd_monitor_add_action =
984 TOKEN_STRING_INITIALIZER(struct cmd_monitor_add_result, action,
986 const parse_token_atcmd_t PROGMEM cmd_monitor_add_atcmd =
987 TOKEN_ATCMD_INITIALIZER(struct cmd_monitor_add_result, cmd, &xbee_dev,
988 XBEE_ATCMD_F_READ, XBEE_ATCMD_F_READ);
991 const char PROGMEM help_monitor_add[] = "add a register in monitor list";
993 const parse_inst_t PROGMEM cmd_monitor_add = {
994 .f = cmd_monitor_add_parsed, /* function to call */
995 .data = NULL, /* 2nd arg of func */
996 .help_str = help_monitor_add,
997 .tokens = { /* token list, NULL terminated */
998 (PGM_P)&cmd_monitor_add_monitor_add,
999 (PGM_P)&cmd_monitor_add_action,
1000 (PGM_P)&cmd_monitor_add_atcmd,
1007 /* this structure is filled when cmd_monitor_period is parsed successfully */
1008 struct cmd_monitor_period_result {
1009 fixed_string_t monitor;
1010 fixed_string_t action;
1014 /* function called when cmd_monitor_period is parsed successfully */
1015 static void cmd_monitor_period_parsed(void *parsed_result, void *data)
1017 struct cmd_monitor_period_result *res = parsed_result;
1020 if (res->period < 100) {
1021 printf_P(PSTR("error, minimum period is 100 ms\r\n"));
1025 monitor_period_ms = res->period;
1028 const char PROGMEM str_monitor_period[] = "period";
1030 const parse_token_string_t PROGMEM cmd_monitor_period_monitor_period =
1031 TOKEN_STRING_INITIALIZER(struct cmd_monitor_period_result, monitor,
1033 const parse_token_string_t PROGMEM cmd_monitor_period_action =
1034 TOKEN_STRING_INITIALIZER(struct cmd_monitor_period_result, action,
1035 str_monitor_period);
1036 const parse_token_num_t PROGMEM cmd_monitor_period_period =
1037 TOKEN_NUM_INITIALIZER(struct cmd_monitor_period_result, period, UINT32);
1040 const char PROGMEM help_monitor_period[] = "set register monitoring period";
1042 const parse_inst_t PROGMEM cmd_monitor_period = {
1043 .f = cmd_monitor_period_parsed, /* function to call */
1044 .data = NULL, /* 2nd arg of func */
1045 .help_str = help_monitor_period,
1046 .tokens = { /* token list, NULL terminated */
1047 (PGM_P)&cmd_monitor_period_monitor_period,
1048 (PGM_P)&cmd_monitor_period_action,
1049 (PGM_P)&cmd_monitor_period_period,
1056 /* this structure is filled when cmd_monitor_del is parsed successfully */
1057 struct cmd_monitor_del_result {
1058 fixed_string_t monitor;
1059 fixed_string_t action;
1060 struct monitor_reg *m;
1063 /* function called when cmd_monitor_del is parsed successfully */
1064 static void cmd_monitor_del_parsed(void *parsed_result, void *data)
1066 struct cmd_monitor_del_result *res = parsed_result;
1069 monitor_current = LIST_NEXT(res->m, next);
1070 LIST_REMOVE(res->m, next);
1073 if (monitor_count == 0) {
1074 printf_P(PSTR("Disable monitoring, no more event\r\n"));
1075 callout_stop(&cm, &monitor_event);
1076 monitor_running = 0;
1081 const char PROGMEM str_monitor_del[] = "del";
1083 const parse_token_string_t PROGMEM cmd_monitor_del_monitor_del =
1084 TOKEN_STRING_INITIALIZER(struct cmd_monitor_del_result, monitor,
1086 const parse_token_string_t PROGMEM cmd_monitor_del_action =
1087 TOKEN_STRING_INITIALIZER(struct cmd_monitor_del_result, action,
1089 const parse_token_monitor_t PROGMEM cmd_monitor_del_atcmd =
1090 TOKEN_MONITOR_INITIALIZER(struct cmd_monitor_del_result, m);
1093 const char PROGMEM help_monitor_del[] = "del a register in monitor list";
1095 const parse_inst_t PROGMEM cmd_monitor_del = {
1096 .f = cmd_monitor_del_parsed, /* function to call */
1097 .data = NULL, /* 2nd arg of func */
1098 .help_str = help_monitor_del,
1099 .tokens = { /* token list, NULL terminated */
1100 (PGM_P)&cmd_monitor_del_monitor_del,
1101 (PGM_P)&cmd_monitor_del_action,
1102 (PGM_P)&cmd_monitor_del_atcmd,
1110 /* this structure is filled when cmd_ping is parsed successfully */
1111 struct cmd_ping_result {
1112 fixed_string_t ping;
1115 /* function called when cmd_ping is parsed successfully */
1116 static void cmd_ping_parsed(void *parsed_result, void *data)
1118 (void)parsed_result;
1120 xbeeapp_send_atcmd("VL", NULL, 0, 1, NULL, NULL);
1123 const char PROGMEM str_ping[] = "ping";
1125 const parse_token_string_t PROGMEM cmd_ping_ping =
1126 TOKEN_STRING_INITIALIZER(struct cmd_ping_result, ping,
1129 const char PROGMEM help_ping[] = "Send a ping to the xbee device";
1131 const parse_inst_t PROGMEM cmd_ping = {
1132 .f = cmd_ping_parsed, /* function to call */
1133 .data = NULL, /* 2nd arg of func */
1134 .help_str = help_ping,
1135 .tokens = { /* token list, NULL terminated */
1136 (PGM_P)&cmd_ping_ping,
1143 /* this structure is filled when cmd_raw is parsed successfully */
1144 struct cmd_raw_result {
1148 /* function called when cmd_raw is parsed successfully */
1149 static void cmd_raw_parsed(void *parsed_result, void *data)
1151 (void)parsed_result;
1153 printf_P(PSTR("switched to raw mode, CTRL-D to exit\r\n"));
1154 rdline_stop(&xbeeboard.rdl); /* don't display prompt when return */
1158 const char PROGMEM str_raw[] = "raw";
1160 const parse_token_string_t PROGMEM cmd_raw_raw =
1161 TOKEN_STRING_INITIALIZER(struct cmd_raw_result, raw,
1164 const char PROGMEM help_raw[] = "Switch to raw mode";
1166 const parse_inst_t PROGMEM cmd_raw = {
1167 .f = cmd_raw_parsed, /* function to call */
1168 .data = NULL, /* 2nd arg of func */
1169 .help_str = help_raw,
1170 .tokens = { /* token list, NULL terminated */
1171 (PGM_P)&cmd_raw_raw,
1178 /* this structure is filled when cmd_dump is parsed successfully */
1179 struct cmd_dump_result {
1180 fixed_string_t dump;
1181 fixed_string_t onoff;
1184 /* function called when cmd_dump is parsed successfully */
1185 static void cmd_dump_parsed(void *parsed_result, void *data)
1187 struct cmd_dump_result *res = parsed_result;
1190 if (!strcmp(res->onoff, "on"))
1196 const char PROGMEM str_dump[] = "dump";
1197 const char PROGMEM str_dump_onoff[] = "on#off";
1199 const parse_token_string_t PROGMEM cmd_dump_dump =
1200 TOKEN_STRING_INITIALIZER(struct cmd_dump_result, dump,
1203 const parse_token_string_t PROGMEM cmd_dump_onoff =
1204 TOKEN_STRING_INITIALIZER(struct cmd_dump_result, onoff,
1207 const char PROGMEM help_dump[] = "enable/disable hexdump of received packets";
1209 const parse_inst_t PROGMEM cmd_dump = {
1210 .f = cmd_dump_parsed, /* function to call */
1211 .data = NULL, /* 2nd arg of func */
1212 .help_str = help_dump,
1213 .tokens = { /* token list, NULL terminated */
1214 (PGM_P)&cmd_dump_dump,
1215 (PGM_P)&cmd_dump_onoff,
1222 /* this structure is filled when cmd_debug is parsed successfully */
1223 struct cmd_debug_result {
1224 fixed_string_t debug;
1225 fixed_string_t onoff;
1228 /* function called when cmd_debug is parsed successfully */
1229 static void cmd_debug_parsed(void *parsed_result, void *data)
1231 struct cmd_debug_result *res = parsed_result;
1234 if (!strcmp(res->onoff, "on"))
1240 const char PROGMEM str_debug[] = "debug";
1241 const char PROGMEM str_debug_onoff[] = "on#off";
1243 const parse_token_string_t PROGMEM cmd_debug_debug =
1244 TOKEN_STRING_INITIALIZER(struct cmd_debug_result, debug,
1247 const parse_token_string_t PROGMEM cmd_debug_onoff =
1248 TOKEN_STRING_INITIALIZER(struct cmd_debug_result, onoff,
1251 const char PROGMEM help_debug[] = "enable/disable additionnal debug";
1253 const parse_inst_t PROGMEM cmd_debug = {
1254 .f = cmd_debug_parsed, /* function to call */
1255 .data = NULL, /* 2nd arg of func */
1256 .help_str = help_debug,
1257 .tokens = { /* token list, NULL terminated */
1258 (PGM_P)&cmd_debug_debug,
1259 (PGM_P)&cmd_debug_onoff,
1264 /**********************************************************/
1266 /* this structure is filled when cmd_baudrate is parsed successfully */
1267 struct cmd_baudrate_result {
1268 fixed_string_t arg0;
1272 /* function called when cmd_baudrate is parsed successfully */
1273 static void cmd_baudrate_parsed(void * parsed_result, __attribute__((unused)) void *data)
1275 struct cmd_baudrate_result *res = parsed_result;
1276 struct uart_config c;
1278 uart_getconf(XBEE_UART, &c);
1279 c.baudrate = res->arg1;
1280 uart_setconf(XBEE_UART, &c);
1283 const char PROGMEM str_baudrate_arg0[] = "baudrate";
1284 const parse_token_string_t PROGMEM cmd_baudrate_arg0 =
1285 TOKEN_STRING_INITIALIZER(struct cmd_baudrate_result, arg0,
1287 const parse_token_num_t PROGMEM cmd_baudrate_arg1 =
1288 TOKEN_NUM_INITIALIZER(struct cmd_baudrate_result, arg1,
1291 const char PROGMEM help_baudrate[] = "Change xbee baudrate";
1292 const parse_inst_t PROGMEM cmd_baudrate = {
1293 .f = cmd_baudrate_parsed, /* function to call */
1294 .data = NULL, /* 2nd arg of func */
1295 .help_str = help_baudrate,
1296 .tokens = { /* token list, NULL terminated */
1297 (PGM_P)&cmd_baudrate_arg0,
1298 (PGM_P)&cmd_baudrate_arg1,
1304 /**********************************************************/
1306 /* this structure is filled when cmd_beep is parsed successfully */
1307 struct cmd_beep_result {
1308 fixed_string_t beep;
1311 /* function called when cmd_beep is parsed successfully */
1312 static void cmd_beep_parsed(void *parsed_result, void *data)
1314 (void)parsed_result;
1325 const char PROGMEM str_beep[] = "beep";
1326 const parse_token_string_t PROGMEM cmd_beep_beep =
1327 TOKEN_STRING_INITIALIZER(struct cmd_beep_result, beep,
1330 const char PROGMEM help_beep[] = "Send a beep";
1332 const parse_inst_t PROGMEM cmd_beep = {
1333 .f = cmd_beep_parsed, /* function to call */
1334 .data = NULL, /* 2nd arg of func */
1335 .help_str = help_beep,
1336 .tokens = { /* token list, NULL terminated */
1337 (PGM_P)&cmd_beep_beep,
1342 /**********************************************************/
1344 /* this structure is filled when cmd_servo is parsed successfully */
1345 struct cmd_servo_result {
1346 fixed_string_t arg0;
1347 fixed_string_t arg1;
1352 /* function called when cmd_servo is parsed successfully */
1353 static void cmd_servo_parsed(void * parsed_result, void *data)
1355 struct cmd_servo_result *res = parsed_result;
1359 if (!strcmp_P(res->arg1, PSTR("set"))) {
1360 if (res->num >= N_SERVO) {
1361 printf_P(PSTR("bad servo num\n"));
1364 if (res->val >= 1024) {
1365 printf_P(PSTR("bad servo val\n"));
1368 spi_servo_set(res->num, res->val);
1370 else if (!strcmp_P(res->arg1, PSTR("bypass"))) {
1371 spi_servo_set_bypass(!!res->val);
1373 else if (!strcmp_P(res->arg1, PSTR("ppm"))) {
1374 spi_servo_set_ppm(!!res->val);
1376 else if (!strcmp_P(res->arg1, PSTR("show"))) {
1381 const char PROGMEM str_servo_arg0[] = "servo";
1382 const parse_token_string_t PROGMEM cmd_servo_arg0 =
1383 TOKEN_STRING_INITIALIZER(struct cmd_servo_result, arg0,
1385 const char PROGMEM str_servo_arg1_set[] = "set";
1386 const parse_token_string_t PROGMEM cmd_servo_arg1_set =
1387 TOKEN_STRING_INITIALIZER(struct cmd_servo_result, arg1,
1388 str_servo_arg1_set);
1389 const parse_token_num_t PROGMEM cmd_servo_num =
1390 TOKEN_NUM_INITIALIZER(struct cmd_servo_result, num,
1392 const parse_token_num_t PROGMEM cmd_servo_val =
1393 TOKEN_NUM_INITIALIZER(struct cmd_servo_result, val,
1396 const char PROGMEM help_servo_set[] = "set servo value";
1397 const parse_inst_t PROGMEM cmd_servo_set = {
1398 .f = cmd_servo_parsed, /* function to call */
1399 .data = NULL, /* 2nd arg of func */
1400 .help_str = help_servo_set,
1401 .tokens = { /* token list, NULL terminated */
1402 (PGM_P)&cmd_servo_arg0,
1403 (PGM_P)&cmd_servo_arg1_set,
1404 (PGM_P)&cmd_servo_num,
1405 (PGM_P)&cmd_servo_val,
1410 const char PROGMEM str_servo_arg1_show[] = "show";
1411 const parse_token_string_t PROGMEM cmd_servo_arg1_show =
1412 TOKEN_STRING_INITIALIZER(struct cmd_servo_result, arg1,
1413 str_servo_arg1_show);
1415 const char PROGMEM help_servo_show[] = "read servo and config";
1416 const parse_inst_t PROGMEM cmd_servo_show = {
1417 .f = cmd_servo_parsed, /* function to call */
1418 .data = NULL, /* 2nd arg of func */
1419 .help_str = help_servo_show,
1420 .tokens = { /* token list, NULL terminated */
1421 (PGM_P)&cmd_servo_arg0,
1422 (PGM_P)&cmd_servo_arg1_show,
1427 const char PROGMEM str_servo_arg1_bypassppm[] = "bypass#ppm";
1428 const parse_token_string_t PROGMEM cmd_servo_arg1_bypassppm =
1429 TOKEN_STRING_INITIALIZER(struct cmd_servo_result, arg1,
1430 str_servo_arg1_bypassppm);
1432 const char PROGMEM help_servo_bypassppm[] = "change bypass/ppm";
1433 const parse_inst_t PROGMEM cmd_servo_bypassppm = {
1434 .f = cmd_servo_parsed, /* function to call */
1435 .data = NULL, /* 2nd arg of func */
1436 .help_str = help_servo_bypassppm,
1437 .tokens = { /* token list, NULL terminated */
1438 (PGM_P)&cmd_servo_arg0,
1439 (PGM_P)&cmd_servo_arg1_bypassppm,
1440 (PGM_P)&cmd_servo_val,
1445 /**********************************************************/
1447 /* this structure is filled when cmd_test_spi is parsed successfully */
1448 struct cmd_test_spi_result {
1449 fixed_string_t arg0;
1452 static void cmd_test_spi_parsed(void * parsed_result, void *data)
1454 uint8_t i, flags, wait_time = 0;
1457 (void)parsed_result;
1460 spi_servo_set_bypass(0);
1461 spi_servo_set_ppm(0);
1463 /* stress test: send many commands, no wait between each servo
1464 * of a series, and a variable delay between series */
1465 printf_P(PSTR("stress test\r\n"));
1466 while (!cmdline_keypressed()) {
1478 for (i = 0; i < 6; i++)
1479 spi_servo_set(i, val);
1482 printf_P(PSTR("%4.4d %4.4d %4.4d %4.4d %4.4d %4.4d\r\n"),
1483 spi_servo_get(0), spi_servo_get(1), spi_servo_get(2),
1484 spi_servo_get(3), spi_servo_get(4), spi_servo_get(5));
1487 printf_P(PSTR("bypass mode, with spi commands in background\r\n"));
1488 spi_servo_set_bypass(1);
1490 /* test bypass mode */
1491 while (!cmdline_keypressed()) {
1503 for (i = 0; i < 6; i++)
1504 spi_servo_set(i, val);
1507 printf_P(PSTR("%4.4d %4.4d %4.4d %4.4d %4.4d %4.4d\r\n"),
1508 spi_servo_get(0), spi_servo_get(1), spi_servo_get(2),
1509 spi_servo_get(3), spi_servo_get(4), spi_servo_get(5));
1512 printf_P(PSTR("PPM to servo\r\n"));
1513 spi_servo_set_bypass(0);
1514 spi_servo_set_ppm(0);
1516 /* test PPM to servo (bypass) mode */
1517 while (!cmdline_keypressed()) {
1518 for (i = 0; i < 6; i++) {
1519 val = spi_servo_get(i);
1520 spi_servo_set(i, val);
1524 printf_P(PSTR("PPM to (servo + PPM)\r\n"));
1525 spi_servo_set_bypass(0);
1526 spi_servo_set_ppm(1);
1528 /* test PPM to servo (bypass) mode */
1529 while (!cmdline_keypressed()) {
1530 for (i = 0; i < 6; i++) {
1531 val = spi_servo_get(i);
1532 spi_servo_set(i, val);
1537 const char PROGMEM str_test_spi_arg0[] = "test_spi";
1538 const parse_token_string_t PROGMEM cmd_test_spi_arg0 =
1539 TOKEN_STRING_INITIALIZER(struct cmd_test_spi_result, arg0,
1542 const char PROGMEM help_test_spi[] = "Test the spi";
1543 const parse_inst_t PROGMEM cmd_test_spi = {
1544 .f = cmd_test_spi_parsed, /* function to call */
1545 .data = NULL, /* 2nd arg of func */
1546 .help_str = help_test_spi,
1547 .tokens = { /* token list, NULL terminated */
1548 (PGM_P)&cmd_test_spi_arg0,
1554 const parse_ctx_t PROGMEM main_ctx[] = {
1556 /* commands_gen.c */
1578 &cmd_range_powermask,
1581 &cmd_monitor_period,
1591 &cmd_servo_bypassppm,