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"
47 #include "xbee_user.h"
51 #include "../fpv-common/i2c_commands.h"
52 #include "i2c_protocol.h"
53 #include "eeprom_config.h"
56 extern const parse_inst_t PROGMEM cmd_reset;
57 extern const parse_inst_t PROGMEM cmd_bootloader;
58 extern const parse_inst_t PROGMEM cmd_log;
59 extern const parse_inst_t PROGMEM cmd_log_show;
60 extern const parse_inst_t PROGMEM cmd_log_type;
61 extern const parse_inst_t PROGMEM cmd_stack_space;
62 extern const parse_inst_t PROGMEM cmd_callout;
64 static int monitor_period_ms = 1000;
65 static int monitor_running = 0;
66 static int monitor_count = 0;
67 static struct callout monitor_event;
68 struct monitor_reg *monitor_current;
70 static int range_period_ms = 1000;
71 static int range_powermask = 0x1F;
72 static uint8_t range_power = 0;
73 static int range_running = 0;
74 static uint64_t range_dstaddr = 0xFFFF; /* broadcast by default */
75 static struct callout range_event;
76 static int range_count = 100;
77 static int range_cur_count = 0;
79 static void monitor_cb(struct callout_mgr *cm,
80 struct callout *clt, void *dummy)
85 if (monitor_current == NULL)
86 monitor_current = LIST_FIRST(&xbee_monitor_list);
88 /* no rx_cb given: the user must check the monitored values in logs */
89 xbeeapp_send_atcmd(monitor_current->atcmd, NULL, 0, NULL, NULL);
90 monitor_current = LIST_NEXT(monitor_current, next);
91 callout_reschedule(cm, clt, monitor_period_ms / monitor_count);
94 static void range_cb(struct callout_mgr *cm,
95 struct callout *clt, void *dummy)
97 struct rc_proto_power_probe power_probe;
106 /* get new xmit power */
107 for (i = 1; i <= 8; i++) {
108 mask = 1 << ((range_power + i) & 0x7);
109 if (mask & range_powermask)
112 range_power = ((range_power + i) & 0x7);
114 xbeeapp_send_atcmd("PL", &range_power, sizeof(range_power), NULL, NULL);
116 power_probe.type = RC_PROTO_POWER_PROBE;
117 power_probe.power_level = range_power;
120 msg.iov[0].buf = &power_probe;
121 msg.iov[0].len = sizeof(power_probe);
123 xbeeapp_send_msg(range_dstaddr, &msg, NULL, NULL);
125 if (range_cur_count == 0) {
127 callout_stop(cm, clt);
131 callout_reschedule(cm, clt, range_period_ms);
134 /* callback invoked when a xbee_send is done */
135 static int8_t send_msg_cb(int8_t retcode, void *frame, unsigned len,
138 struct xbee_xmit_status_hdr *recvframe = frame;
142 if (retcode == XBEE_USER_RETCODE_TIMEOUT) {
143 printf_P(PSTR("timeout\r\n"));
146 if (retcode == XBEE_USER_RETCODE_BAD_FRAME ||
147 len != sizeof(*recvframe)) {
148 printf_P(PSTR("invalid frame\r\n"));
149 return XBEE_USER_RETCODE_BAD_FRAME;
152 printf_P(PSTR("ok\r\n"));
153 return XBEE_USER_RETCODE_OK;
156 /* callback invoked to dump the response to AT command */
157 static int8_t dump_xbee_atresp_cb(int8_t retcode, void *frame, unsigned len,
160 struct xbee_atresp_hdr *recvframe = frame;
166 if (retcode == XBEE_USER_RETCODE_TIMEOUT) {
167 printf_P(PSTR("timeout\r\n"));
170 if (retcode == XBEE_USER_RETCODE_BAD_FRAME ||
171 len < sizeof(*recvframe)) {
172 printf_P(PSTR("invalid frame\r\n"));
173 return XBEE_USER_RETCODE_BAD_FRAME;
176 /* get AT command from frame */
177 memcpy(atcmd_str, &recvframe->cmd, 2);
180 atresp_to_str(buf, sizeof(buf), frame, len);
181 len -= sizeof(*recvframe);
182 printf_P(PSTR("status ok, len=%d, %s\n"), len, buf);
183 return XBEE_USER_RETCODE_OK;
186 /* this structure is filled when cmd_help is parsed successfully */
187 struct cmd_help_result {
189 struct xbee_atcmd *cmd;
192 /* function called when cmd_help is parsed successfully */
193 static void cmd_help_parsed(void *parsed_result, void *data)
195 struct cmd_help_result *res = parsed_result;
196 struct xbee_atcmd cmdcopy;
201 memcpy_P(&cmdcopy, res->cmd, sizeof(cmdcopy));
202 type = (cmdcopy.flags & (XBEE_ATCMD_F_READ | XBEE_ATCMD_F_WRITE));
204 case XBEE_ATCMD_F_READ:
205 printf_P(PSTR("Read-only\r\n"));
207 case XBEE_ATCMD_F_WRITE:
208 printf_P(PSTR("Write-only\r\n"));
211 printf_P(PSTR("Read-write\r\n"));
214 if (cmdcopy.flags & XBEE_ATCMD_F_PARAM_NONE)
215 printf_P(PSTR("No argument\r\n"));
216 else if (cmdcopy.flags & XBEE_ATCMD_F_PARAM_U8)
217 printf_P(PSTR("Register is unsigned 8 bits\r\n"));
218 else if (cmdcopy.flags & XBEE_ATCMD_F_PARAM_U16)
219 printf_P(PSTR("Register is unsigned 16 bits\r\n"));
220 else if (cmdcopy.flags & XBEE_ATCMD_F_PARAM_U32)
221 printf_P(PSTR("Register is unsigned 32 bits\r\n"));
222 else if (cmdcopy.flags & XBEE_ATCMD_F_PARAM_S16)
223 printf_P(PSTR("Register is signed 16 bits\r\n"));
224 else if (cmdcopy.flags & XBEE_ATCMD_F_PARAM_STRING_20B)
225 printf_P(PSTR("Register is a 20 bytes string\r\n"));
227 printf_P(PSTR("Unknown argument\r\n"));
229 printf_P(PSTR("%S\r\n"), cmdcopy.help);
231 const char PROGMEM str_help_help[] = "help";
233 const parse_token_string_t PROGMEM cmd_help_help =
234 TOKEN_STRING_INITIALIZER(struct cmd_help_result, help, str_help_help);
236 const parse_token_atcmd_t PROGMEM cmd_help_atcmd =
237 TOKEN_ATCMD_INITIALIZER(struct cmd_help_result, cmd, &xbee_dev,
240 const char PROGMEM help_help[] = "Help a register using an AT command";
241 const parse_inst_t PROGMEM cmd_help = {
242 .f = cmd_help_parsed, /* function to call */
243 .data = NULL, /* 2nd arg of func */
244 .help_str = help_help,
245 .tokens = { /* token list, NULL terminated */
246 (PGM_P)&cmd_help_help,
247 (PGM_P)&cmd_help_atcmd,
254 struct cmd_neigh_del_result {
256 fixed_string_t action;
257 struct xbee_neigh *neigh;
260 static void cmd_neigh_del_parsed(void *parsed_result,
263 struct cmd_neigh_del_result *res = parsed_result;
266 xbee_neigh_del(xbee_dev, res->neigh);
269 const char PROGMEM str_neigh_del_neigh[] = "neigh";
270 const parse_token_string_t PROGMEM cmd_neigh_del_cmd =
271 TOKEN_STRING_INITIALIZER(struct cmd_neigh_del_result, cmd,
272 str_neigh_del_neigh);
273 const char PROGMEM str_neigh_del_del[] = "del";
274 const parse_token_string_t PROGMEM cmd_neigh_del_action =
275 TOKEN_STRING_INITIALIZER(struct cmd_neigh_del_result, action,
277 const parse_token_neighbor_t PROGMEM cmd_neigh_del_neigh =
278 TOKEN_NEIGHBOR_INITIALIZER(struct cmd_neigh_del_result, neigh,
281 const char PROGMEM help_neigh_del[] = "delete a neighbor";
282 const parse_inst_t PROGMEM cmd_neigh_del = {
283 .f = cmd_neigh_del_parsed, /* function to call */
284 .data = NULL, /* 2nd arg of func */
285 .help_str = help_neigh_del,
286 .tokens = { /* token list, NULL terminated */
287 (PGM_P)&cmd_neigh_del_cmd,
288 (PGM_P)&cmd_neigh_del_action,
289 (PGM_P)&cmd_neigh_del_neigh,
296 struct cmd_neigh_add_result {
298 fixed_string_t action;
303 static void cmd_neigh_add_parsed(void *parsed_result,
306 struct cmd_neigh_add_result *res = parsed_result;
309 if (xbee_neigh_add(xbee_dev, res->name, res->addr) == NULL)
310 printf_P(PSTR("name or addr already exist\r\n"));
313 const char PROGMEM str_neigh_add_neigh[] = "neigh";
314 const parse_token_string_t PROGMEM cmd_neigh_add_cmd =
315 TOKEN_STRING_INITIALIZER(struct cmd_neigh_add_result, cmd,
316 str_neigh_add_neigh);
317 const char PROGMEM str_neigh_add_add[] = "add";
318 const parse_token_string_t PROGMEM cmd_neigh_add_action =
319 TOKEN_STRING_INITIALIZER(struct cmd_neigh_add_result, action,
321 const parse_token_string_t PROGMEM cmd_neigh_add_name =
322 TOKEN_STRING_INITIALIZER(struct cmd_neigh_add_result, name, NULL);
323 const parse_token_num_t PROGMEM cmd_neigh_add_addr =
324 TOKEN_NUM_INITIALIZER(struct cmd_neigh_add_result, addr, UINT64);
326 const char PROGMEM help_neigh_add[] = "add a neighbor";
327 const parse_inst_t PROGMEM cmd_neigh_add = {
328 .f = cmd_neigh_add_parsed, /* function to call */
329 .data = NULL, /* 2nd arg of func */
330 .help_str = help_neigh_add,
331 .tokens = { /* token list, NULL terminated */
332 (PGM_P)&cmd_neigh_add_cmd,
333 (PGM_P)&cmd_neigh_add_action,
334 (PGM_P)&cmd_neigh_add_name,
335 (PGM_P)&cmd_neigh_add_addr,
342 struct cmd_neigh_list_result {
344 fixed_string_t action;
347 static void cmd_neigh_list_parsed(void *parsed_result,
350 struct xbee_neigh *neigh;
354 LIST_FOREACH(neigh, &xbee_dev->neigh_list, next) {
355 printf_P(PSTR(" %s: 0x%.8"PRIx32"%.8"PRIx32"\r\n"),
357 (uint32_t)(neigh->addr >> 32ULL),
358 (uint32_t)(neigh->addr & 0xFFFFFFFF));
362 const char PROGMEM str_neigh_list_neigh[] = "neigh";
363 const parse_token_string_t PROGMEM cmd_neigh_list_cmd =
364 TOKEN_STRING_INITIALIZER(struct cmd_neigh_list_result, cmd,
365 str_neigh_list_neigh);
366 const char PROGMEM str_neigh_list_list[] = "list";
367 const parse_token_string_t PROGMEM cmd_neigh_list_action =
368 TOKEN_STRING_INITIALIZER(struct cmd_neigh_list_result, action,
369 str_neigh_list_list);
371 const char PROGMEM help_neigh_list[] = "list all knwon neighbors";
372 const parse_inst_t PROGMEM cmd_neigh_list = {
373 .f = cmd_neigh_list_parsed, /* function to call */
374 .data = NULL, /* 2nd arg of func */
375 .help_str = help_neigh_list,
376 .tokens = { /* token list, NULL terminated */
377 (PGM_P)&cmd_neigh_list_cmd,
378 (PGM_P)&cmd_neigh_list_action,
385 /* this structure is filled when cmd_read is parsed successfully */
386 struct cmd_read_result {
388 struct xbee_atcmd *cmd;
391 /* function called when cmd_read is parsed successfully */
392 static void cmd_read_parsed(void *parsed_result,
395 struct cmd_read_result *res = parsed_result;
396 struct xbee_atcmd copy;
398 volatile uint8_t done = 0;
401 memcpy_P(©, res->cmd, sizeof(copy));
402 memcpy_P(&cmd, copy.name, 2);
404 xbeeapp_send_atcmd(cmd, NULL, 0, dump_xbee_atresp_cb, (void *)&done);
408 const char PROGMEM str_read_read[] = "read";
410 const parse_token_string_t PROGMEM cmd_read_read =
411 TOKEN_STRING_INITIALIZER(struct cmd_read_result, read,
414 const parse_token_atcmd_t PROGMEM cmd_read_atcmd =
415 TOKEN_ATCMD_INITIALIZER(struct cmd_read_result, cmd, &xbee_dev,
416 XBEE_ATCMD_F_READ, XBEE_ATCMD_F_READ);
418 const char PROGMEM help_read[] = "Read a register using an AT command";
419 const parse_inst_t PROGMEM cmd_read = {
420 .f = cmd_read_parsed, /* function to call */
421 .data = NULL, /* 2nd arg of func */
422 .help_str = help_read,
423 .tokens = { /* token list, NULL terminated */
424 (PGM_P)&cmd_read_read,
425 (PGM_P)&cmd_read_atcmd,
433 /* this structure is filled when cmd_write is parsed successfully */
434 struct cmd_write_result {
435 fixed_string_t write;
436 struct xbee_atcmd *cmd;
444 /* function called when cmd_write is parsed successfully */
445 static void cmd_write_parsed(void *parsed_result, void *data)
447 struct cmd_write_result *res = parsed_result;
448 struct xbee_atcmd copy;
452 volatile uint8_t done = 0;
455 memcpy_P(©, res->cmd, sizeof(copy));
457 if (copy.flags & XBEE_ATCMD_F_PARAM_NONE) {
461 else if (copy.flags & XBEE_ATCMD_F_PARAM_U8) {
462 len = sizeof(res->u8);
465 else if (copy.flags & XBEE_ATCMD_F_PARAM_U16) {
466 len = sizeof(res->u16);
467 res->u16 = htons(res->u16);
470 else if (copy.flags & XBEE_ATCMD_F_PARAM_U32) {
471 len = sizeof(res->u32);
472 res->u32 = htonl(res->u32);
476 printf_P(PSTR("Unknown argument type\r\n"));
479 memcpy_P(&cmd, copy.name, 2);
481 xbeeapp_send_atcmd(cmd, param, len, dump_xbee_atresp_cb, (void *)&done);
485 const char PROGMEM str_write_none[] = "write";
487 const parse_token_string_t PROGMEM cmd_write_write =
488 TOKEN_STRING_INITIALIZER(struct cmd_write_result, write,
491 const parse_token_atcmd_t PROGMEM cmd_write_none_atcmd =
492 TOKEN_ATCMD_INITIALIZER(struct cmd_write_result, cmd,
494 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_NONE,
495 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_NONE);
497 const char PROGMEM help_write_none[] = "Send an AT command (no argument)";
499 const parse_inst_t PROGMEM cmd_write_none = {
500 .f = cmd_write_parsed, /* function to call */
501 .data = NULL, /* 2nd arg of func */
502 .help_str = help_write_none,
503 .tokens = { /* token list, NULL terminated */
504 (PGM_P)&cmd_write_write,
505 (PGM_P)&cmd_write_none_atcmd,
510 const parse_token_atcmd_t PROGMEM cmd_write_u8_atcmd =
511 TOKEN_ATCMD_INITIALIZER(struct cmd_write_result, cmd,
513 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_U8,
514 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_U8);
516 const parse_token_num_t PROGMEM cmd_write_u8_u8 =
517 TOKEN_NUM_INITIALIZER(struct cmd_write_result, u8, UINT8);
519 const char PROGMEM help_write_u8[] = "Write a 8 bits register using an AT command";
521 const parse_inst_t PROGMEM cmd_write_u8 = {
522 .f = cmd_write_parsed, /* function to call */
523 .data = NULL, /* 2nd arg of func */
524 .help_str = help_write_u8,
525 .tokens = { /* token list, NULL terminated */
526 (PGM_P)&cmd_write_write,
527 (PGM_P)&cmd_write_u8_atcmd,
528 (PGM_P)&cmd_write_u8_u8,
533 const parse_token_atcmd_t PROGMEM cmd_write_u16_atcmd =
534 TOKEN_ATCMD_INITIALIZER(struct cmd_write_result, cmd,
536 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_U16,
537 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_U16);
539 const parse_token_num_t PROGMEM cmd_write_u16_u16 =
540 TOKEN_NUM_INITIALIZER(struct cmd_write_result, u16, UINT16);
542 const char PROGMEM help_write_u16[] = "Write a 16 bits register using an AT command";
544 const parse_inst_t PROGMEM cmd_write_u16 = {
545 .f = cmd_write_parsed, /* function to call */
546 .data = NULL, /* 2nd arg of func */
547 .help_str = help_write_u16,
548 .tokens = { /* token list, NULL terminated */
549 (PGM_P)&cmd_write_write,
550 (PGM_P)&cmd_write_u16_atcmd,
551 (PGM_P)&cmd_write_u16_u16,
556 const parse_token_atcmd_t PROGMEM cmd_write_u32_atcmd =
557 TOKEN_ATCMD_INITIALIZER(struct cmd_write_result, cmd,
559 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_U32,
560 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_U32);
562 const parse_token_num_t PROGMEM cmd_write_u32_u32 =
563 TOKEN_NUM_INITIALIZER(struct cmd_write_result, u32, UINT32);
565 const char PROGMEM help_write_u32[] = "Write a 32 bits register using an AT command";
567 const parse_inst_t PROGMEM cmd_write_u32 = {
568 .f = cmd_write_parsed, /* function to call */
569 .data = NULL, /* 2nd arg of func */
570 .help_str = help_write_u32,
571 .tokens = { /* token list, NULL terminated */
572 (PGM_P)&cmd_write_write,
573 (PGM_P)&cmd_write_u32_atcmd,
574 (PGM_P)&cmd_write_u32_u32,
582 /* this structure is filled when cmd_sendmsg is parsed successfully */
583 struct cmd_sendmsg_result {
584 fixed_string_t sendmsg;
589 /* function called when cmd_sendmsg is parsed successfully */
590 static void cmd_sendmsg_parsed(void *parsed_result, void *data)
592 struct cmd_sendmsg_result *res = parsed_result;
594 volatile uint8_t done = 0;
599 msg.iov[0].buf = res->data;
600 msg.iov[0].len = strlen(res->data);
602 xbeeapp_send_msg(res->addr, &msg, send_msg_cb, (void *)&done);
606 const char PROGMEM str_sendmsg[] = "sendmsg";
608 const parse_token_string_t PROGMEM cmd_sendmsg_sendmsg =
609 TOKEN_STRING_INITIALIZER(struct cmd_sendmsg_result, sendmsg,
612 const parse_token_num_t PROGMEM cmd_sendmsg_addr =
613 TOKEN_NUM_INITIALIZER(struct cmd_sendmsg_result, addr, UINT64);
615 const parse_token_string_t PROGMEM cmd_sendmsg_data =
616 TOKEN_STRING_INITIALIZER(struct cmd_sendmsg_result, data, NULL);
618 const char PROGMEM help_sendmsg[] = "Send data to a node using its address";
620 const parse_inst_t PROGMEM cmd_sendmsg = {
621 .f = cmd_sendmsg_parsed, /* function to call */
622 .data = NULL, /* 2nd arg of func */
623 .help_str = help_sendmsg,
624 .tokens = { /* token list, NULL terminated */
625 (PGM_P)&cmd_sendmsg_sendmsg,
626 (PGM_P)&cmd_sendmsg_addr,
627 (PGM_P)&cmd_sendmsg_data,
634 /* this structure is filled when cmd_sendmsg_name is parsed successfully */
635 struct cmd_sendmsg_name_result {
636 fixed_string_t sendmsg_name;
637 struct xbee_neigh *neigh;
641 /* function called when cmd_sendmsg_name is parsed successfully */
642 static void cmd_sendmsg_name_parsed(void *parsed_result, void *data)
644 struct cmd_sendmsg_name_result *res = parsed_result;
646 volatile uint8_t done = 0;
651 msg.iov[0].buf = res->data;
652 msg.iov[0].len = strlen(res->data);
654 xbeeapp_send_msg(res->neigh->addr, &msg, send_msg_cb, (void *)&done);
658 const parse_token_string_t PROGMEM cmd_sendmsg_name_sendmsg_name =
659 TOKEN_STRING_INITIALIZER(struct cmd_sendmsg_name_result, sendmsg_name,
662 const parse_token_neighbor_t PROGMEM cmd_sendmsg_name_neigh =
663 TOKEN_NEIGHBOR_INITIALIZER(struct cmd_sendmsg_name_result, neigh,
666 const parse_token_string_t PROGMEM cmd_sendmsg_name_data =
667 TOKEN_STRING_INITIALIZER(struct cmd_sendmsg_name_result, data, NULL);
669 const char PROGMEM help_sendmsg_name[] = "Send data to a node using its name";
671 const parse_inst_t PROGMEM cmd_sendmsg_name = {
672 .f = cmd_sendmsg_name_parsed, /* function to call */
673 .data = NULL, /* 2nd arg of func */
674 .help_str = help_sendmsg_name,
675 .tokens = { /* token list, NULL terminated */
676 (PGM_P)&cmd_sendmsg_name_sendmsg_name,
677 (PGM_P)&cmd_sendmsg_name_neigh,
678 (PGM_P)&cmd_sendmsg_name_data,
686 /* this structure is filled when cmd_range is parsed successfully */
687 struct cmd_range_result {
688 fixed_string_t range;
689 fixed_string_t action;
692 /* function called when cmd_range is parsed successfully */
693 static void cmd_range_parsed(void *parsed_result, void *data)
695 struct cmd_range_result *res = parsed_result;
698 if (!strcmp_P(res->action, PSTR("show"))) {
699 printf_P(PSTR("range infos:\r\n"));
700 printf_P(PSTR(" range period %d\r\n"), range_period_ms);
701 printf_P(PSTR(" range count %d\r\n"), range_count);
702 printf_P(PSTR(" range powermask 0x%x\r\n"), range_powermask);
703 printf_P(PSTR(" range dstaddr 0x%.8"PRIx32"%.8"PRIx32"\r\n"),
704 (uint32_t)(range_dstaddr >> 32ULL),
705 (uint32_t)(range_dstaddr & 0xFFFFFFFF));
708 printf_P(PSTR(" range test is running\r\n"));
710 printf_P(PSTR(" range test is not running\r\n"));
712 else if (!strcmp(res->action, "start")) {
714 printf_P(PSTR("already running\r\n"));
717 range_cur_count = range_count;
718 callout_init(&range_event, range_cb, NULL, LOW_PRIO);
720 callout_schedule(&xbeeboard.intr_cm,
721 &range_event, 0); /* immediate */
723 else if (!strcmp(res->action, "end")) {
724 if (range_running == 0) {
725 printf_P(PSTR("not running\r\n"));
728 callout_stop(&xbeeboard.intr_cm, &range_event);
733 const char PROGMEM str_range[] = "range";
734 const char PROGMEM str_range_tokens[] = "show#start#end";
736 const parse_token_string_t PROGMEM cmd_range_range =
737 TOKEN_STRING_INITIALIZER(struct cmd_range_result, range,
739 const parse_token_string_t PROGMEM cmd_range_action =
740 TOKEN_STRING_INITIALIZER(struct cmd_range_result, action,
743 const char PROGMEM help_range[] = "start/stop/show current rangeing";
745 const parse_inst_t PROGMEM cmd_range = {
746 .f = cmd_range_parsed, /* function to call */
747 .data = NULL, /* 2nd arg of func */
748 .help_str = help_range,
749 .tokens = { /* token list, NULL terminated */
750 (PGM_P)&cmd_range_range,
751 (PGM_P)&cmd_range_action,
758 /* this structure is filled when cmd_range_period is parsed successfully */
759 struct cmd_range_period_result {
760 fixed_string_t range;
761 fixed_string_t action;
765 /* function called when cmd_range_period is parsed successfully */
766 static void cmd_range_period_parsed(void *parsed_result, void *data)
768 struct cmd_range_period_result *res = parsed_result;
771 if (res->period < 10) {
772 printf_P(PSTR("error, minimum period is 10 ms\r\n"));
776 range_period_ms = res->period;
779 const char PROGMEM str_period[] = "period";
781 const parse_token_string_t PROGMEM cmd_range_period_range_period =
782 TOKEN_STRING_INITIALIZER(struct cmd_range_period_result, range,
784 const parse_token_string_t PROGMEM cmd_range_period_action =
785 TOKEN_STRING_INITIALIZER(struct cmd_range_period_result, action,
787 const parse_token_num_t PROGMEM cmd_range_period_period =
788 TOKEN_NUM_INITIALIZER(struct cmd_range_period_result, period, UINT32);
790 const char PROGMEM help_range_period[] = "set range test period";
792 const parse_inst_t PROGMEM cmd_range_period = {
793 .f = cmd_range_period_parsed, /* function to call */
794 .data = NULL, /* 2nd arg of func */
795 .help_str = help_range_period,
796 .tokens = { /* token list, NULL terminated */
797 (PGM_P)&cmd_range_period_range_period,
798 (PGM_P)&cmd_range_period_action,
799 (PGM_P)&cmd_range_period_period,
806 /* this structure is filled when cmd_range_count is parsed successfully */
807 struct cmd_range_count_result {
808 fixed_string_t range;
809 fixed_string_t action;
813 /* function called when cmd_range_count is parsed successfully */
814 static void cmd_range_count_parsed(void *parsed_result, void *data)
816 struct cmd_range_count_result *res = parsed_result;
819 range_count = res->count;
822 const char PROGMEM str_count[] = "count";
824 const parse_token_string_t PROGMEM cmd_range_count_range_count =
825 TOKEN_STRING_INITIALIZER(struct cmd_range_count_result, range,
827 const parse_token_string_t PROGMEM cmd_range_count_action =
828 TOKEN_STRING_INITIALIZER(struct cmd_range_count_result, action,
830 const parse_token_num_t PROGMEM cmd_range_count_count =
831 TOKEN_NUM_INITIALIZER(struct cmd_range_count_result, count, UINT32);
834 const char PROGMEM help_range_count[] = "set range test count";
836 const parse_inst_t PROGMEM cmd_range_count = {
837 .f = cmd_range_count_parsed, /* function to call */
838 .data = NULL, /* 2nd arg of func */
839 .help_str = help_range_count,
840 .tokens = { /* token list, NULL terminated */
841 (PGM_P)&cmd_range_count_range_count,
842 (PGM_P)&cmd_range_count_action,
843 (PGM_P)&cmd_range_count_count,
850 /* this structure is filled when cmd_range_powermask is parsed successfully */
851 struct cmd_range_powermask_result {
852 fixed_string_t range;
853 fixed_string_t action;
857 /* function called when cmd_range_powermask is parsed successfully */
858 static void cmd_range_powermask_parsed(void *parsed_result, void *data)
860 struct cmd_range_powermask_result *res = parsed_result;
863 range_powermask = res->powermask;
866 const char PROGMEM str_powermask[] = "powermask";
868 const parse_token_string_t PROGMEM cmd_range_powermask_range_powermask =
869 TOKEN_STRING_INITIALIZER(struct cmd_range_powermask_result, range,
871 const parse_token_string_t PROGMEM cmd_range_powermask_action =
872 TOKEN_STRING_INITIALIZER(struct cmd_range_powermask_result, action,
874 const parse_token_num_t PROGMEM cmd_range_powermask_powermask =
875 TOKEN_NUM_INITIALIZER(struct cmd_range_powermask_result, powermask,
879 const char PROGMEM help_range_powermask[] = "set range test powermask";
881 const parse_inst_t PROGMEM cmd_range_powermask = {
882 .f = cmd_range_powermask_parsed, /* function to call */
883 .data = NULL, /* 2nd arg of func */
884 .help_str = help_range_powermask,
885 .tokens = { /* token list, NULL terminated */
886 (PGM_P)&cmd_range_powermask_range_powermask,
887 (PGM_P)&cmd_range_powermask_action,
888 (PGM_P)&cmd_range_powermask_powermask,
895 /* this structure is filled when cmd_range_dstaddr is parsed successfully */
896 struct cmd_range_dstaddr_result {
897 fixed_string_t range;
898 fixed_string_t action;
902 /* function called when cmd_range_dstaddr is parsed successfully */
903 static void cmd_range_dstaddr_parsed(void *parsed_result, void *data)
905 struct cmd_range_dstaddr_result *res = parsed_result;
908 range_dstaddr = res->dstaddr;
911 const char PROGMEM str_dstaddr[] = "dstaddr";
913 const parse_token_string_t PROGMEM cmd_range_dstaddr_range_dstaddr =
914 TOKEN_STRING_INITIALIZER(struct cmd_range_dstaddr_result, range,
916 const parse_token_string_t PROGMEM cmd_range_dstaddr_action =
917 TOKEN_STRING_INITIALIZER(struct cmd_range_dstaddr_result, action,
919 const parse_token_num_t PROGMEM cmd_range_dstaddr_dstaddr =
920 TOKEN_NUM_INITIALIZER(struct cmd_range_dstaddr_result, dstaddr, UINT64);
923 const char PROGMEM help_range_dstaddr[] = "set register rangeing dstaddr";
925 const parse_inst_t PROGMEM cmd_range_dstaddr = {
926 .f = cmd_range_dstaddr_parsed, /* function to call */
927 .data = NULL, /* 2nd arg of func */
928 .help_str = help_range_dstaddr,
929 .tokens = { /* token list, NULL terminated */
930 (PGM_P)&cmd_range_dstaddr_range_dstaddr,
931 (PGM_P)&cmd_range_dstaddr_action,
932 (PGM_P)&cmd_range_dstaddr_dstaddr,
940 /* this structure is filled when cmd_monitor is parsed successfully */
941 struct cmd_monitor_result {
942 fixed_string_t monitor;
943 fixed_string_t action;
946 /* function called when cmd_monitor is parsed successfully */
947 static void cmd_monitor_parsed(void *parsed_result, void *data)
949 struct cmd_monitor_result *res = parsed_result;
950 struct monitor_reg *m;
953 if (!strcmp_P(res->action, PSTR("show"))) {
954 printf_P(PSTR("monitor period is %d ms, %d regs in list\r\n"),
955 monitor_period_ms, monitor_count);
956 LIST_FOREACH(m, &xbee_monitor_list, next)
957 printf_P(PSTR(" %S\r\n"), m->desc);
959 else if (!strcmp_P(res->action, PSTR("start"))) {
960 if (monitor_running) {
961 printf_P(PSTR("already running\r\n"));
964 if (monitor_count == 0) {
965 printf_P(PSTR("no regs to be monitored\r\n"));
968 callout_init(&monitor_event, monitor_cb, NULL, 1);
970 monitor_current = LIST_FIRST(&xbee_monitor_list);
971 callout_schedule(&xbeeboard.intr_cm,
972 &monitor_event, 0); /* immediate */
973 printf_P(PSTR("monitor cb: %S %s\r\n"),
974 monitor_current->desc,
975 monitor_current->atcmd);
978 else if (!strcmp_P(res->action, PSTR("end"))) {
979 if (monitor_running == 0) {
980 printf_P(PSTR("not running\r\n"));
983 callout_stop(&xbeeboard.intr_cm, &monitor_event);
988 const char PROGMEM str_monitor[] = "monitor";
989 const char PROGMEM str_monitor_tokens[] = "show#start#end";
991 const parse_token_string_t PROGMEM cmd_monitor_monitor =
992 TOKEN_STRING_INITIALIZER(struct cmd_monitor_result, monitor,
994 const parse_token_string_t PROGMEM cmd_monitor_action =
995 TOKEN_STRING_INITIALIZER(struct cmd_monitor_result, action,
998 const char PROGMEM help_monitor[] = "start/stop/show current monitoring";
1000 const parse_inst_t PROGMEM cmd_monitor = {
1001 .f = cmd_monitor_parsed, /* function to call */
1002 .data = NULL, /* 2nd arg of func */
1003 .help_str = help_monitor,
1004 .tokens = { /* token list, NULL terminated */
1005 (PGM_P)&cmd_monitor_monitor,
1006 (PGM_P)&cmd_monitor_action,
1013 /* this structure is filled when cmd_monitor_add is parsed successfully */
1014 struct cmd_monitor_add_result {
1015 fixed_string_t monitor;
1016 fixed_string_t action;
1017 struct xbee_atcmd *cmd;
1020 /* function called when cmd_monitor_add is parsed successfully */
1021 static void cmd_monitor_add_parsed(void *parsed_result, void *data)
1023 struct cmd_monitor_add_result *res = parsed_result;
1024 struct monitor_reg *m;
1025 struct xbee_atcmd copy;
1028 memcpy_P(©, res->cmd, sizeof(copy));
1029 LIST_FOREACH(m, &xbee_monitor_list, next) {
1030 if (!strcmp_P(m->atcmd, copy.name))
1035 printf_P(PSTR("already exist\r\n"));
1039 m = malloc(sizeof(*m));
1041 printf_P(PSTR("no mem\r\n"));
1044 m->desc = copy.desc;
1045 strcpy_P(m->atcmd, copy.name);
1046 LIST_INSERT_HEAD(&xbee_monitor_list, m, next);
1050 const char PROGMEM str_monitor_add[] = "add";
1052 const parse_token_string_t PROGMEM cmd_monitor_add_monitor_add =
1053 TOKEN_STRING_INITIALIZER(struct cmd_monitor_add_result, monitor,
1055 const parse_token_string_t PROGMEM cmd_monitor_add_action =
1056 TOKEN_STRING_INITIALIZER(struct cmd_monitor_add_result, action,
1058 const parse_token_atcmd_t PROGMEM cmd_monitor_add_atcmd =
1059 TOKEN_ATCMD_INITIALIZER(struct cmd_monitor_add_result, cmd, &xbee_dev,
1060 XBEE_ATCMD_F_READ, XBEE_ATCMD_F_READ);
1063 const char PROGMEM help_monitor_add[] = "add a register in monitor list";
1065 const parse_inst_t PROGMEM cmd_monitor_add = {
1066 .f = cmd_monitor_add_parsed, /* function to call */
1067 .data = NULL, /* 2nd arg of func */
1068 .help_str = help_monitor_add,
1069 .tokens = { /* token list, NULL terminated */
1070 (PGM_P)&cmd_monitor_add_monitor_add,
1071 (PGM_P)&cmd_monitor_add_action,
1072 (PGM_P)&cmd_monitor_add_atcmd,
1079 /* this structure is filled when cmd_monitor_period is parsed successfully */
1080 struct cmd_monitor_period_result {
1081 fixed_string_t monitor;
1082 fixed_string_t action;
1086 /* function called when cmd_monitor_period is parsed successfully */
1087 static void cmd_monitor_period_parsed(void *parsed_result, void *data)
1089 struct cmd_monitor_period_result *res = parsed_result;
1092 if (res->period < 100) {
1093 printf_P(PSTR("error, minimum period is 100 ms\r\n"));
1097 monitor_period_ms = res->period;
1100 const char PROGMEM str_monitor_period[] = "period";
1102 const parse_token_string_t PROGMEM cmd_monitor_period_monitor_period =
1103 TOKEN_STRING_INITIALIZER(struct cmd_monitor_period_result, monitor,
1105 const parse_token_string_t PROGMEM cmd_monitor_period_action =
1106 TOKEN_STRING_INITIALIZER(struct cmd_monitor_period_result, action,
1107 str_monitor_period);
1108 const parse_token_num_t PROGMEM cmd_monitor_period_period =
1109 TOKEN_NUM_INITIALIZER(struct cmd_monitor_period_result, period, UINT32);
1112 const char PROGMEM help_monitor_period[] = "set register monitoring period";
1114 const parse_inst_t PROGMEM cmd_monitor_period = {
1115 .f = cmd_monitor_period_parsed, /* function to call */
1116 .data = NULL, /* 2nd arg of func */
1117 .help_str = help_monitor_period,
1118 .tokens = { /* token list, NULL terminated */
1119 (PGM_P)&cmd_monitor_period_monitor_period,
1120 (PGM_P)&cmd_monitor_period_action,
1121 (PGM_P)&cmd_monitor_period_period,
1128 /* this structure is filled when cmd_monitor_del is parsed successfully */
1129 struct cmd_monitor_del_result {
1130 fixed_string_t monitor;
1131 fixed_string_t action;
1132 struct monitor_reg *m;
1135 /* function called when cmd_monitor_del is parsed successfully */
1136 static void cmd_monitor_del_parsed(void *parsed_result, void *data)
1138 struct cmd_monitor_del_result *res = parsed_result;
1141 monitor_current = LIST_NEXT(res->m, next);
1142 LIST_REMOVE(res->m, next);
1145 if (monitor_count == 0) {
1146 printf_P(PSTR("Disable monitoring, no more event\r\n"));
1147 callout_stop(&xbeeboard.intr_cm, &monitor_event);
1148 monitor_running = 0;
1153 const char PROGMEM str_monitor_del[] = "del";
1155 const parse_token_string_t PROGMEM cmd_monitor_del_monitor_del =
1156 TOKEN_STRING_INITIALIZER(struct cmd_monitor_del_result, monitor,
1158 const parse_token_string_t PROGMEM cmd_monitor_del_action =
1159 TOKEN_STRING_INITIALIZER(struct cmd_monitor_del_result, action,
1161 const parse_token_monitor_t PROGMEM cmd_monitor_del_atcmd =
1162 TOKEN_MONITOR_INITIALIZER(struct cmd_monitor_del_result, m);
1165 const char PROGMEM help_monitor_del[] = "del a register in monitor list";
1167 const parse_inst_t PROGMEM cmd_monitor_del = {
1168 .f = cmd_monitor_del_parsed, /* function to call */
1169 .data = NULL, /* 2nd arg of func */
1170 .help_str = help_monitor_del,
1171 .tokens = { /* token list, NULL terminated */
1172 (PGM_P)&cmd_monitor_del_monitor_del,
1173 (PGM_P)&cmd_monitor_del_action,
1174 (PGM_P)&cmd_monitor_del_atcmd,
1182 /* this structure is filled when cmd_ping is parsed successfully */
1183 struct cmd_ping_result {
1184 fixed_string_t ping;
1187 /* function called when cmd_ping is parsed successfully */
1188 static void cmd_ping_parsed(void *parsed_result, void *data)
1190 volatile uint8_t done = 0;
1192 (void)parsed_result;
1194 xbeeapp_send_atcmd("VL", NULL, 0, dump_xbee_atresp_cb, (void *)&done);
1198 const char PROGMEM str_ping[] = "ping";
1200 const parse_token_string_t PROGMEM cmd_ping_ping =
1201 TOKEN_STRING_INITIALIZER(struct cmd_ping_result, ping,
1204 const char PROGMEM help_ping[] = "Send a ping to the xbee device";
1206 const parse_inst_t PROGMEM cmd_ping = {
1207 .f = cmd_ping_parsed, /* function to call */
1208 .data = NULL, /* 2nd arg of func */
1209 .help_str = help_ping,
1210 .tokens = { /* token list, NULL terminated */
1211 (PGM_P)&cmd_ping_ping,
1218 /* this structure is filled when cmd_raw is parsed successfully */
1219 struct cmd_raw_result {
1223 /* function called when cmd_raw is parsed successfully */
1224 static void cmd_raw_parsed(void *parsed_result, void *data)
1226 (void)parsed_result;
1229 if (range_running || monitor_running) {
1230 printf_P(PSTR("stop running range or monitor first\r\n"));
1233 printf_P(PSTR("switched to raw mode, CTRL-D to exit\r\n"));
1234 rdline_stop(&xbeeboard.rdl); /* don't display prompt when return */
1238 const char PROGMEM str_raw[] = "raw";
1240 const parse_token_string_t PROGMEM cmd_raw_raw =
1241 TOKEN_STRING_INITIALIZER(struct cmd_raw_result, raw,
1244 const char PROGMEM help_raw[] = "Switch to raw mode";
1246 const parse_inst_t PROGMEM cmd_raw = {
1247 .f = cmd_raw_parsed, /* function to call */
1248 .data = NULL, /* 2nd arg of func */
1249 .help_str = help_raw,
1250 .tokens = { /* token list, NULL terminated */
1251 (PGM_P)&cmd_raw_raw,
1256 /**********************************************************/
1258 /* this structure is filled when cmd_baudrate is parsed successfully */
1259 struct cmd_baudrate_result {
1260 fixed_string_t arg0;
1264 /* function called when cmd_baudrate is parsed successfully */
1265 static void cmd_baudrate_parsed(void * parsed_result, __attribute__((unused)) void *data)
1267 struct cmd_baudrate_result *res = parsed_result;
1268 struct uart_config c;
1270 uart_getconf(XBEE_UART, &c);
1271 c.baudrate = res->arg1;
1272 uart_setconf(XBEE_UART, &c);
1275 const char PROGMEM str_baudrate_arg0[] = "baudrate";
1276 const parse_token_string_t PROGMEM cmd_baudrate_arg0 =
1277 TOKEN_STRING_INITIALIZER(struct cmd_baudrate_result, arg0,
1279 const parse_token_num_t PROGMEM cmd_baudrate_arg1 =
1280 TOKEN_NUM_INITIALIZER(struct cmd_baudrate_result, arg1,
1283 const char PROGMEM help_baudrate[] = "Change xbee baudrate";
1284 const parse_inst_t PROGMEM cmd_baudrate = {
1285 .f = cmd_baudrate_parsed, /* function to call */
1286 .data = NULL, /* 2nd arg of func */
1287 .help_str = help_baudrate,
1288 .tokens = { /* token list, NULL terminated */
1289 (PGM_P)&cmd_baudrate_arg0,
1290 (PGM_P)&cmd_baudrate_arg1,
1296 /**********************************************************/
1298 /* this structure is filled when cmd_beep is parsed successfully */
1299 struct cmd_beep_result {
1300 fixed_string_t beep;
1303 /* function called when cmd_beep is parsed successfully */
1304 static void cmd_beep_parsed(void *parsed_result, void *data)
1306 (void)parsed_result;
1317 const char PROGMEM str_beep[] = "beep";
1318 const parse_token_string_t PROGMEM cmd_beep_beep =
1319 TOKEN_STRING_INITIALIZER(struct cmd_beep_result, beep,
1322 const char PROGMEM help_beep[] = "Send a beep";
1324 const parse_inst_t PROGMEM cmd_beep = {
1325 .f = cmd_beep_parsed, /* function to call */
1326 .data = NULL, /* 2nd arg of func */
1327 .help_str = help_beep,
1328 .tokens = { /* token list, NULL terminated */
1329 (PGM_P)&cmd_beep_beep,
1334 /**********************************************************/
1336 /* this structure is filled when cmd_servo is parsed successfully */
1337 struct cmd_servo_result {
1338 fixed_string_t arg0;
1339 fixed_string_t arg1;
1344 /* function called when cmd_servo is parsed successfully */
1345 static void cmd_servo_parsed(void * parsed_result, void *data)
1347 struct cmd_servo_result *res = parsed_result;
1351 if (!strcmp_P(res->arg1, PSTR("set"))) {
1352 if (res->num >= N_SERVO) {
1353 printf_P(PSTR("bad servo num\n"));
1356 if (res->val >= 1024) {
1357 printf_P(PSTR("bad servo val\n"));
1360 spi_servo_set(res->num, res->val);
1362 else if (!strcmp_P(res->arg1, PSTR("bypass"))) {
1363 spi_servo_set_bypass(!!res->val);
1365 else if (!strcmp_P(res->arg1, PSTR("ppm"))) {
1366 spi_servo_set_ppm(!!res->val);
1368 else if (!strcmp_P(res->arg1, PSTR("show"))) {
1373 const char PROGMEM str_servo_arg0[] = "servo";
1374 const parse_token_string_t PROGMEM cmd_servo_arg0 =
1375 TOKEN_STRING_INITIALIZER(struct cmd_servo_result, arg0,
1377 const char PROGMEM str_servo_arg1_set[] = "set";
1378 const parse_token_string_t PROGMEM cmd_servo_arg1_set =
1379 TOKEN_STRING_INITIALIZER(struct cmd_servo_result, arg1,
1380 str_servo_arg1_set);
1381 const parse_token_num_t PROGMEM cmd_servo_num =
1382 TOKEN_NUM_INITIALIZER(struct cmd_servo_result, num,
1384 const parse_token_num_t PROGMEM cmd_servo_val =
1385 TOKEN_NUM_INITIALIZER(struct cmd_servo_result, val,
1388 const char PROGMEM help_servo_set[] = "set servo value";
1389 const parse_inst_t PROGMEM cmd_servo_set = {
1390 .f = cmd_servo_parsed, /* function to call */
1391 .data = NULL, /* 2nd arg of func */
1392 .help_str = help_servo_set,
1393 .tokens = { /* token list, NULL terminated */
1394 (PGM_P)&cmd_servo_arg0,
1395 (PGM_P)&cmd_servo_arg1_set,
1396 (PGM_P)&cmd_servo_num,
1397 (PGM_P)&cmd_servo_val,
1402 const char PROGMEM str_servo_arg1_show[] = "show";
1403 const parse_token_string_t PROGMEM cmd_servo_arg1_show =
1404 TOKEN_STRING_INITIALIZER(struct cmd_servo_result, arg1,
1405 str_servo_arg1_show);
1407 const char PROGMEM help_servo_show[] = "read servo and config";
1408 const parse_inst_t PROGMEM cmd_servo_show = {
1409 .f = cmd_servo_parsed, /* function to call */
1410 .data = NULL, /* 2nd arg of func */
1411 .help_str = help_servo_show,
1412 .tokens = { /* token list, NULL terminated */
1413 (PGM_P)&cmd_servo_arg0,
1414 (PGM_P)&cmd_servo_arg1_show,
1419 const char PROGMEM str_servo_arg1_bypassppm[] = "bypass#ppm";
1420 const parse_token_string_t PROGMEM cmd_servo_arg1_bypassppm =
1421 TOKEN_STRING_INITIALIZER(struct cmd_servo_result, arg1,
1422 str_servo_arg1_bypassppm);
1424 const char PROGMEM help_servo_bypassppm[] = "change bypass/ppm";
1425 const parse_inst_t PROGMEM cmd_servo_bypassppm = {
1426 .f = cmd_servo_parsed, /* function to call */
1427 .data = NULL, /* 2nd arg of func */
1428 .help_str = help_servo_bypassppm,
1429 .tokens = { /* token list, NULL terminated */
1430 (PGM_P)&cmd_servo_arg0,
1431 (PGM_P)&cmd_servo_arg1_bypassppm,
1432 (PGM_P)&cmd_servo_val,
1437 /**********************************************************/
1439 /* this structure is filled when cmd_test_spi is parsed successfully */
1440 struct cmd_test_spi_result {
1441 fixed_string_t arg0;
1444 static void cmd_test_spi_parsed(void * parsed_result, void *data)
1446 uint8_t i, flags, wait_time = 0;
1449 (void)parsed_result;
1452 spi_servo_set_bypass(0);
1453 spi_servo_set_ppm(0);
1455 /* stress test: send many commands, no wait between each servo
1456 * of a series, and a variable delay between series */
1457 printf_P(PSTR("stress test\r\n"));
1458 while (!cmdline_keypressed()) {
1470 for (i = 0; i < 6; i++)
1471 spi_servo_set(i, val);
1474 printf_P(PSTR("%4.4d %4.4d %4.4d %4.4d %4.4d %4.4d\r\n"),
1475 spi_servo_get(0), spi_servo_get(1), spi_servo_get(2),
1476 spi_servo_get(3), spi_servo_get(4), spi_servo_get(5));
1479 printf_P(PSTR("bypass mode, with spi commands in background\r\n"));
1480 spi_servo_set_bypass(1);
1482 /* test bypass mode */
1483 while (!cmdline_keypressed()) {
1495 for (i = 0; i < 6; i++)
1496 spi_servo_set(i, val);
1499 printf_P(PSTR("%4.4d %4.4d %4.4d %4.4d %4.4d %4.4d\r\n"),
1500 spi_servo_get(0), spi_servo_get(1), spi_servo_get(2),
1501 spi_servo_get(3), spi_servo_get(4), spi_servo_get(5));
1504 printf_P(PSTR("PPM to servo\r\n"));
1505 spi_servo_set_bypass(0);
1506 spi_servo_set_ppm(0);
1508 /* test PPM to servo (bypass) mode */
1509 while (!cmdline_keypressed()) {
1510 for (i = 0; i < 6; i++) {
1511 val = spi_servo_get(i);
1512 spi_servo_set(i, val);
1516 printf_P(PSTR("PPM to (servo + PPM)\r\n"));
1517 spi_servo_set_bypass(0);
1518 spi_servo_set_ppm(1);
1520 /* test PPM to servo (bypass) mode */
1521 while (!cmdline_keypressed()) {
1522 for (i = 0; i < 6; i++) {
1523 val = spi_servo_get(i);
1524 spi_servo_set(i, val);
1529 const char PROGMEM str_test_spi_arg0[] = "test_spi";
1530 const parse_token_string_t PROGMEM cmd_test_spi_arg0 =
1531 TOKEN_STRING_INITIALIZER(struct cmd_test_spi_result, arg0,
1534 const char PROGMEM help_test_spi[] = "Test the spi";
1535 const parse_inst_t PROGMEM cmd_test_spi = {
1536 .f = cmd_test_spi_parsed, /* function to call */
1537 .data = NULL, /* 2nd arg of func */
1538 .help_str = help_test_spi,
1539 .tokens = { /* token list, NULL terminated */
1540 (PGM_P)&cmd_test_spi_arg0,
1545 /**********************************************************/
1547 /* this structure is filled when cmd_dump_xbee_stats is parsed successfully */
1548 struct cmd_dump_xbee_stats_result {
1549 fixed_string_t arg0;
1552 static void cmd_dump_xbee_stats_parsed(void *parsed_result, void *data)
1554 (void)parsed_result;
1557 xbee_dump_stats(xbee_dev);
1560 const char PROGMEM str_dump_xbee_stats_arg0[] = "dump_xbee_stats";
1561 const parse_token_string_t PROGMEM cmd_dump_xbee_stats_arg0 =
1562 TOKEN_STRING_INITIALIZER(struct cmd_dump_xbee_stats_result, arg0,
1563 str_dump_xbee_stats_arg0);
1565 const char PROGMEM help_dump_xbee_stats[] = "Test the spi";
1566 const parse_inst_t PROGMEM cmd_dump_xbee_stats = {
1567 .f = cmd_dump_xbee_stats_parsed, /* function to call */
1568 .data = NULL, /* 2nd arg of func */
1569 .help_str = help_dump_xbee_stats,
1570 .tokens = { /* token list, NULL terminated */
1571 (PGM_P)&cmd_dump_xbee_stats_arg0,
1576 /**********************************************************/
1578 /* this structure is filled when cmd_rc_proto_stats is parsed successfully */
1579 struct cmd_rc_proto_stats_result {
1580 fixed_string_t arg0;
1581 fixed_string_t arg1;
1584 static void cmd_rc_proto_stats_parsed(void *parsed_result, void *data)
1586 struct cmd_rc_proto_stats_result *res = parsed_result;
1589 if (!strcmp(res->arg1, "show"))
1590 rc_proto_dump_stats();
1592 rc_proto_reset_stats();
1595 const char PROGMEM str_rc_proto_stats_arg0[] = "rc_proto_stats";
1596 const parse_token_string_t PROGMEM cmd_rc_proto_stats_arg0 =
1597 TOKEN_STRING_INITIALIZER(struct cmd_rc_proto_stats_result, arg0,
1598 str_rc_proto_stats_arg0);
1599 const char PROGMEM str_rc_proto_stats_arg1[] = "show#reset";
1600 const parse_token_string_t PROGMEM cmd_rc_proto_stats_arg1 =
1601 TOKEN_STRING_INITIALIZER(struct cmd_rc_proto_stats_result, arg1,
1602 str_rc_proto_stats_arg1);
1604 const char PROGMEM help_rc_proto_stats[] = "dump rc_proto stats";
1605 const parse_inst_t PROGMEM cmd_rc_proto_stats = {
1606 .f = cmd_rc_proto_stats_parsed, /* function to call */
1607 .data = NULL, /* 2nd arg of func */
1608 .help_str = help_rc_proto_stats,
1609 .tokens = { /* token list, NULL terminated */
1610 (PGM_P)&cmd_rc_proto_stats_arg0,
1611 (PGM_P)&cmd_rc_proto_stats_arg1,
1616 /**********************************************************/
1618 /* this structure is filled when cmd_rc_proto_timers is parsed successfully */
1619 struct cmd_rc_proto_timers_result {
1620 fixed_string_t arg0;
1621 fixed_string_t arg1;
1624 uint16_t power_probe;
1625 uint16_t autobypass;
1628 static void cmd_rc_proto_timers_parsed(void *parsed_result, void *data)
1630 struct cmd_rc_proto_timers_result *res = parsed_result;
1633 if (!strcmp_P(res->arg1, PSTR("set"))) {
1634 rc_proto_timers.send_servo_min_ms = res->servo_min;
1635 rc_proto_timers.send_servo_max_ms = res->servo_max;
1636 rc_proto_timers.send_power_probe_ms = res->power_probe;
1637 rc_proto_timers.autobypass_ms = res->autobypass;
1640 printf_P(PSTR("rc_proto_timers: min=%d, max=%d, "
1641 "power_probe=%d autobypass=%d\n"),
1642 rc_proto_timers.send_servo_min_ms,
1643 rc_proto_timers.send_servo_max_ms,
1644 rc_proto_timers.send_power_probe_ms,
1645 rc_proto_timers.autobypass_ms);
1648 const char PROGMEM str_rc_proto_timers_arg0[] = "rc_proto_timers";
1649 const parse_token_string_t PROGMEM cmd_rc_proto_timers_arg0 =
1650 TOKEN_STRING_INITIALIZER(struct cmd_rc_proto_timers_result, arg0,
1651 str_rc_proto_timers_arg0);
1652 const char PROGMEM str_rc_proto_timers_arg1[] = "set";
1653 const parse_token_string_t PROGMEM cmd_rc_proto_timers_arg1 =
1654 TOKEN_STRING_INITIALIZER(struct cmd_rc_proto_timers_result, arg1,
1655 str_rc_proto_timers_arg1);
1656 const parse_token_num_t PROGMEM cmd_rc_proto_timers_servo_min =
1657 TOKEN_NUM_INITIALIZER(struct cmd_rc_proto_timers_result, servo_min,
1659 const parse_token_num_t PROGMEM cmd_rc_proto_timers_servo_max =
1660 TOKEN_NUM_INITIALIZER(struct cmd_rc_proto_timers_result, servo_max,
1662 const parse_token_num_t PROGMEM cmd_rc_proto_timers_power_probe =
1663 TOKEN_NUM_INITIALIZER(struct cmd_rc_proto_timers_result, power_probe,
1665 const parse_token_num_t PROGMEM cmd_rc_proto_timers_autobypass =
1666 TOKEN_NUM_INITIALIZER(struct cmd_rc_proto_timers_result, autobypass,
1669 const char PROGMEM help_rc_proto_timers[] = "set rc_proto_timers (servo_min, "
1670 "servo_max, pow_probe, autobypass)";
1671 const parse_inst_t PROGMEM cmd_rc_proto_timers = {
1672 .f = cmd_rc_proto_timers_parsed, /* function to call */
1673 .data = NULL, /* 2nd arg of func */
1674 .help_str = help_rc_proto_timers,
1675 .tokens = { /* token list, NULL terminated */
1676 (PGM_P)&cmd_rc_proto_timers_arg0,
1677 (PGM_P)&cmd_rc_proto_timers_arg1,
1678 (PGM_P)&cmd_rc_proto_timers_servo_min,
1679 (PGM_P)&cmd_rc_proto_timers_servo_max,
1680 (PGM_P)&cmd_rc_proto_timers_power_probe,
1681 (PGM_P)&cmd_rc_proto_timers_autobypass,
1686 const char PROGMEM str_rc_proto_timers_show_arg1[] = "show";
1687 const parse_token_string_t PROGMEM cmd_rc_proto_timers_show_arg1 =
1688 TOKEN_STRING_INITIALIZER(struct cmd_rc_proto_timers_result, arg1,
1689 str_rc_proto_timers_show_arg1);
1691 const char PROGMEM help_rc_proto_timers_show[] = "show rc_proto timers value";
1692 const parse_inst_t PROGMEM cmd_rc_proto_timers_show = {
1693 .f = cmd_rc_proto_timers_parsed, /* function to call */
1694 .data = NULL, /* 2nd arg of func */
1695 .help_str = help_rc_proto_timers_show,
1696 .tokens = { /* token list, NULL terminated */
1697 (PGM_P)&cmd_rc_proto_timers_arg0,
1698 (PGM_P)&cmd_rc_proto_timers_show_arg1,
1703 /**********************************************************/
1705 /* this structure is filled when cmd_rc_proto_mode is parsed successfully */
1706 struct cmd_rc_proto_mode_result {
1707 fixed_string_t arg0;
1712 static void cmd_rc_proto_mode_parsed(void *parsed_result, void *data)
1714 struct cmd_rc_proto_mode_result *res = parsed_result;
1719 flags = rc_proto_get_mode();
1720 if (!strcmp_P(res->val, PSTR("on")))
1723 if (!strcmp_P(res->cmd, PSTR("rx_copy_spi"))) {
1725 flags |= RC_PROTO_FLAGS_RX_COPY_SPI;
1727 flags &= ~RC_PROTO_FLAGS_RX_COPY_SPI;
1729 else if (!strcmp_P(res->cmd, PSTR("rx_autobypass"))) {
1731 flags |= RC_PROTO_FLAGS_RX_AUTOBYPASS;
1733 flags &= ~RC_PROTO_FLAGS_RX_AUTOBYPASS;
1735 else if (!strcmp_P(res->cmd, PSTR("tx_stats"))) {
1737 flags |= RC_PROTO_FLAGS_TX_STATS;
1739 flags &= ~RC_PROTO_FLAGS_TX_STATS;
1741 else if (!strcmp_P(res->cmd, PSTR("tx_power_probe"))) {
1743 flags |= RC_PROTO_FLAGS_TX_POW_PROBE;
1745 flags &= ~RC_PROTO_FLAGS_TX_POW_PROBE;
1747 else if (!strcmp_P(res->cmd, PSTR("compute_best_pow"))) {
1749 flags |= RC_PROTO_FLAGS_COMPUTE_BEST_POW;
1751 flags &= ~RC_PROTO_FLAGS_COMPUTE_BEST_POW;
1753 else if (!strcmp_P(res->cmd, PSTR("tx"))) {
1754 flags &= ~RC_PROTO_FLAGS_TX_MASK;
1755 if (!strcmp_P(res->val, PSTR("bypass")))
1756 flags |= RC_PROTO_FLAGS_TX_BYPASS;
1757 else if (!strcmp_P(res->val, PSTR("copy_spi")))
1758 flags |= RC_PROTO_FLAGS_TX_COPY_SPI;
1760 rc_proto_set_mode(flags);
1763 if ((flags & RC_PROTO_FLAGS_TX_MASK) == RC_PROTO_FLAGS_TX_OFF)
1764 printf_P(PSTR("rc_proto_mode tx off\n"));
1765 else if ((flags & RC_PROTO_FLAGS_TX_MASK) == RC_PROTO_FLAGS_TX_BYPASS)
1766 printf_P(PSTR("rc_proto_mode tx bypass\n"));
1767 else if ((flags & RC_PROTO_FLAGS_TX_MASK) == RC_PROTO_FLAGS_TX_COPY_SPI)
1768 printf_P(PSTR("rc_proto_mode tx copy_spi\n"));
1769 printf_P(PSTR("rc_proto_mode rx_copy_spi %s\n"),
1770 (flags & RC_PROTO_FLAGS_RX_COPY_SPI) ? "on" : "off");
1771 printf_P(PSTR("rc_proto_mode rx_autobypass %s\n"),
1772 (flags & RC_PROTO_FLAGS_RX_AUTOBYPASS) ? "on" : "off");
1773 printf_P(PSTR("rc_proto_mode tx_stats %s\n"),
1774 (flags & RC_PROTO_FLAGS_TX_STATS) ? "on" : "off");
1775 printf_P(PSTR("rc_proto_mode tx_power_probe %s\n"),
1776 (flags & RC_PROTO_FLAGS_TX_POW_PROBE) ? "on" : "off");
1777 printf_P(PSTR("rc_proto_mode compute_best_pow %s\n"),
1778 (flags & RC_PROTO_FLAGS_COMPUTE_BEST_POW) ? "on" : "off");
1781 const char PROGMEM str_rc_proto_mode_arg0[] = "rc_proto_mode";
1782 const parse_token_string_t PROGMEM cmd_rc_proto_mode_arg0 =
1783 TOKEN_STRING_INITIALIZER(struct cmd_rc_proto_mode_result, arg0,
1784 str_rc_proto_mode_arg0);
1786 const char PROGMEM str_rc_proto_mode_cmd[] =
1787 "rx_copy_spi#rx_autobypass#tx_stats#tx_power_probe#compute_best_pow";
1788 const parse_token_string_t PROGMEM cmd_rc_proto_mode_cmd =
1789 TOKEN_STRING_INITIALIZER(struct cmd_rc_proto_mode_result, cmd,
1790 str_rc_proto_mode_cmd);
1792 const char PROGMEM str_rc_proto_mode_onoff[] = "on#off";
1793 const parse_token_string_t PROGMEM cmd_rc_proto_mode_onoff =
1794 TOKEN_STRING_INITIALIZER(struct cmd_rc_proto_mode_result, val,
1795 str_rc_proto_mode_onoff);
1797 const char PROGMEM help_rc_proto_mode[] = "Set rc proto behavior";
1798 const parse_inst_t PROGMEM cmd_rc_proto_mode = {
1799 .f = cmd_rc_proto_mode_parsed, /* function to call */
1800 .data = NULL, /* 2nd arg of func */
1801 .help_str = help_rc_proto_mode,
1802 .tokens = { /* token list, NULL terminated */
1803 (PGM_P)&cmd_rc_proto_mode_arg0,
1804 (PGM_P)&cmd_rc_proto_mode_cmd,
1805 (PGM_P)&cmd_rc_proto_mode_onoff,
1810 const char PROGMEM str_rc_proto_mode_cmd2[] = "tx";
1811 const parse_token_string_t PROGMEM cmd_rc_proto_mode_cmd2 =
1812 TOKEN_STRING_INITIALIZER(struct cmd_rc_proto_mode_result, cmd,
1813 str_rc_proto_mode_cmd2);
1815 const char PROGMEM str_rc_proto_mode_val[] = "off#bypass#copy_spi";
1816 const parse_token_string_t PROGMEM cmd_rc_proto_mode_val =
1817 TOKEN_STRING_INITIALIZER(struct cmd_rc_proto_mode_result, val,
1818 str_rc_proto_mode_val);
1820 const parse_inst_t PROGMEM cmd_rc_proto_mode2 = {
1821 .f = cmd_rc_proto_mode_parsed, /* function to call */
1822 .data = NULL, /* 2nd arg of func */
1823 .help_str = help_rc_proto_mode,
1824 .tokens = { /* token list, NULL terminated */
1825 (PGM_P)&cmd_rc_proto_mode_arg0,
1826 (PGM_P)&cmd_rc_proto_mode_cmd2,
1827 (PGM_P)&cmd_rc_proto_mode_val,
1832 const char PROGMEM str_rc_proto_mode_cmd3[] = "show";
1833 const parse_token_string_t PROGMEM cmd_rc_proto_mode_cmd3 =
1834 TOKEN_STRING_INITIALIZER(struct cmd_rc_proto_mode_result, cmd,
1835 str_rc_proto_mode_cmd3);
1837 const parse_inst_t PROGMEM cmd_rc_proto_mode3 = {
1838 .f = cmd_rc_proto_mode_parsed, /* function to call */
1839 .data = NULL, /* 2nd arg of func */
1840 .help_str = help_rc_proto_mode,
1841 .tokens = { /* token list, NULL terminated */
1842 (PGM_P)&cmd_rc_proto_mode_arg0,
1843 (PGM_P)&cmd_rc_proto_mode_cmd3,
1848 /**********************************************************/
1850 /* this structure is filled when cmd_rc_proto_hello is parsed successfully */
1851 struct cmd_rc_proto_hello_result {
1852 fixed_string_t rc_proto_hello;
1854 struct xbee_neigh *neigh;
1857 fixed_string_t data;
1860 /* function called when cmd_rc_proto_hello is parsed successfully */
1861 static void cmd_rc_proto_hello_parsed(void *parsed_result, void *use_neigh)
1863 struct cmd_rc_proto_hello_result *res = parsed_result;
1864 uint16_t now, next, diff;
1869 addr = res->neigh->addr;
1879 while (!cmdline_keypressed() && res->count != 0) {
1885 if (diff < res->period)
1888 rc_proto_send_hello(addr, res->data, strlen(res->data), -1);
1889 next += res->period;
1894 const char PROGMEM str_rc_proto_hello[] = "rc_proto_hello";
1896 const parse_token_string_t PROGMEM cmd_rc_proto_hello_rc_proto_hello =
1897 TOKEN_STRING_INITIALIZER(struct cmd_rc_proto_hello_result, rc_proto_hello,
1898 str_rc_proto_hello);
1900 const parse_token_num_t PROGMEM cmd_rc_proto_hello_addr =
1901 TOKEN_NUM_INITIALIZER(struct cmd_rc_proto_hello_result, addr, UINT64);
1903 const parse_token_num_t PROGMEM cmd_rc_proto_hello_period =
1904 TOKEN_NUM_INITIALIZER(struct cmd_rc_proto_hello_result, period, UINT16);
1906 const parse_token_num_t PROGMEM cmd_rc_proto_hello_count =
1907 TOKEN_NUM_INITIALIZER(struct cmd_rc_proto_hello_result, count, UINT16);
1909 const parse_token_string_t PROGMEM cmd_rc_proto_hello_data =
1910 TOKEN_STRING_INITIALIZER(struct cmd_rc_proto_hello_result, data, NULL);
1912 const char PROGMEM help_rc_proto_hello[] =
1913 "Send hello msg to a node: addr, period_ms, count, str";
1915 const parse_inst_t PROGMEM cmd_rc_proto_hello = {
1916 .f = cmd_rc_proto_hello_parsed, /* function to call */
1917 .data = NULL, /* 2nd arg of func */
1918 .help_str = help_rc_proto_hello,
1919 .tokens = { /* token list, NULL terminated */
1920 (PGM_P)&cmd_rc_proto_hello_rc_proto_hello,
1921 (PGM_P)&cmd_rc_proto_hello_addr,
1922 (PGM_P)&cmd_rc_proto_hello_period,
1923 (PGM_P)&cmd_rc_proto_hello_count,
1924 (PGM_P)&cmd_rc_proto_hello_data,
1929 const parse_token_neighbor_t PROGMEM cmd_rc_proto_hello_neigh =
1930 TOKEN_NEIGHBOR_INITIALIZER(struct cmd_rc_proto_hello_result, neigh,
1933 const parse_inst_t PROGMEM cmd_rc_proto_hello_name = {
1934 .f = cmd_rc_proto_hello_parsed, /* function to call */
1935 .data = (void *)1, /* 2nd arg of func */
1936 .help_str = help_rc_proto_hello,
1937 .tokens = { /* token list, NULL terminated */
1938 (PGM_P)&cmd_rc_proto_hello_rc_proto_hello,
1939 (PGM_P)&cmd_rc_proto_hello_neigh,
1940 (PGM_P)&cmd_rc_proto_hello_period,
1941 (PGM_P)&cmd_rc_proto_hello_count,
1942 (PGM_P)&cmd_rc_proto_hello_data,
1947 /**********************************************************/
1949 /* this structure is filled when cmd_rc_proto_echo is parsed successfully */
1950 struct cmd_rc_proto_echo_result {
1951 fixed_string_t rc_proto_echo;
1953 struct xbee_neigh *neigh;
1956 fixed_string_t data;
1959 /* function called when cmd_rc_proto_echo is parsed successfully */
1960 static void cmd_rc_proto_echo_parsed(void *parsed_result, void *use_neigh)
1962 struct cmd_rc_proto_echo_result *res = parsed_result;
1963 uint16_t now, next, diff;
1968 addr = res->neigh->addr;
1978 while (!cmdline_keypressed() && res->count != 0) {
1984 if (diff < res->period)
1987 rc_proto_send_echo_req(addr, res->data, strlen(res->data), -1);
1988 next += res->period;
1993 const char PROGMEM str_rc_proto_echo[] = "rc_proto_echo";
1995 const parse_token_string_t PROGMEM cmd_rc_proto_echo_rc_proto_echo =
1996 TOKEN_STRING_INITIALIZER(struct cmd_rc_proto_echo_result, rc_proto_echo,
1999 const parse_token_num_t PROGMEM cmd_rc_proto_echo_addr =
2000 TOKEN_NUM_INITIALIZER(struct cmd_rc_proto_echo_result, addr, UINT64);
2002 const parse_token_num_t PROGMEM cmd_rc_proto_echo_period =
2003 TOKEN_NUM_INITIALIZER(struct cmd_rc_proto_echo_result, period, UINT16);
2005 const parse_token_num_t PROGMEM cmd_rc_proto_echo_count =
2006 TOKEN_NUM_INITIALIZER(struct cmd_rc_proto_echo_result, count, UINT16);
2008 const parse_token_string_t PROGMEM cmd_rc_proto_echo_data =
2009 TOKEN_STRING_INITIALIZER(struct cmd_rc_proto_echo_result, data, NULL);
2011 const char PROGMEM help_rc_proto_echo[] =
2012 "Send echo msg to a node: addr, period_ms, count, str";
2014 const parse_inst_t PROGMEM cmd_rc_proto_echo = {
2015 .f = cmd_rc_proto_echo_parsed, /* function to call */
2016 .data = NULL, /* 2nd arg of func */
2017 .help_str = help_rc_proto_echo,
2018 .tokens = { /* token list, NULL terminated */
2019 (PGM_P)&cmd_rc_proto_echo_rc_proto_echo,
2020 (PGM_P)&cmd_rc_proto_echo_addr,
2021 (PGM_P)&cmd_rc_proto_echo_period,
2022 (PGM_P)&cmd_rc_proto_echo_count,
2023 (PGM_P)&cmd_rc_proto_echo_data,
2028 const parse_token_neighbor_t PROGMEM cmd_rc_proto_echo_neigh =
2029 TOKEN_NEIGHBOR_INITIALIZER(struct cmd_rc_proto_echo_result, neigh,
2032 const parse_inst_t PROGMEM cmd_rc_proto_echo_name = {
2033 .f = cmd_rc_proto_echo_parsed, /* function to call */
2034 .data = (void *)1, /* 2nd arg of func */
2035 .help_str = help_rc_proto_echo,
2036 .tokens = { /* token list, NULL terminated */
2037 (PGM_P)&cmd_rc_proto_echo_rc_proto_echo,
2038 (PGM_P)&cmd_rc_proto_echo_neigh,
2039 (PGM_P)&cmd_rc_proto_echo_period,
2040 (PGM_P)&cmd_rc_proto_echo_count,
2041 (PGM_P)&cmd_rc_proto_echo_data,
2046 /**********************************************************/
2048 /* this structure is filled when cmd_test_eeprom_config is parsed successfully */
2049 struct cmd_test_eeprom_config_result {
2050 fixed_string_t arg0;
2053 static void cmd_test_eeprom_config_parsed(void *parsed_result, void *data)
2055 (void)parsed_result;
2059 eeprom_append_cmd("salut1\n");
2061 eeprom_append_cmd("salut2\n");
2062 eeprom_append_cmd("salut3\n");
2063 eeprom_append_cmd("salut4\n");
2065 eeprom_insert_cmd_before("coin\n", 0);
2066 eeprom_insert_cmd_before("coin2\n", 2);
2068 eeprom_delete_cmd(2);
2069 eeprom_delete_cmd(0);
2073 const char PROGMEM str_test_eeprom_config_arg0[] = "test_eeprom_config";
2074 const parse_token_string_t PROGMEM cmd_test_eeprom_config_arg0 =
2075 TOKEN_STRING_INITIALIZER(struct cmd_test_eeprom_config_result, arg0,
2076 str_test_eeprom_config_arg0);
2078 const char PROGMEM help_test_eeprom_config[] = "Test the eeprom configuration";
2079 const parse_inst_t PROGMEM cmd_test_eeprom_config = {
2080 .f = cmd_test_eeprom_config_parsed, /* function to call */
2081 .data = NULL, /* 2nd arg of func */
2082 .help_str = help_test_eeprom_config,
2083 .tokens = { /* token list, NULL terminated */
2084 (PGM_P)&cmd_test_eeprom_config_arg0,
2091 struct cmd_eeprom_del_result {
2093 fixed_string_t action;
2097 static void cmd_eeprom_del_parsed(void *parsed_result,
2100 struct cmd_eeprom_del_result *res = parsed_result;
2103 if (eeprom_delete_cmd(res->n) < 0)
2104 printf_P(PSTR("cannot delete command\n"));
2108 const char PROGMEM str_eeprom_del_eeprom[] = "eeprom";
2109 const parse_token_string_t PROGMEM cmd_eeprom_del_cmd =
2110 TOKEN_STRING_INITIALIZER(struct cmd_eeprom_del_result, cmd,
2111 str_eeprom_del_eeprom);
2112 const char PROGMEM str_eeprom_del_del[] = "del";
2113 const parse_token_string_t PROGMEM cmd_eeprom_del_action =
2114 TOKEN_STRING_INITIALIZER(struct cmd_eeprom_del_result, action,
2115 str_eeprom_del_del);
2116 const parse_token_num_t PROGMEM cmd_eeprom_del_num =
2117 TOKEN_NUM_INITIALIZER(struct cmd_eeprom_del_result, n,
2120 const char PROGMEM help_eeprom_del[] = "delete an eeprom init command";
2121 const parse_inst_t PROGMEM cmd_eeprom_del = {
2122 .f = cmd_eeprom_del_parsed, /* function to call */
2123 .data = NULL, /* 2nd arg of func */
2124 .help_str = help_eeprom_del,
2125 .tokens = { /* token list, NULL terminated */
2126 (PGM_P)&cmd_eeprom_del_cmd,
2127 (PGM_P)&cmd_eeprom_del_action,
2128 (PGM_P)&cmd_eeprom_del_num,
2135 struct cmd_eeprom_add_result {
2137 fixed_string_t action;
2141 static void cmd_eeprom_add_parsed(void *parsed_result,
2144 struct cmd_eeprom_add_result *res = parsed_result;
2150 rdline_init(&rdl, cmdline_write_char, NULL, NULL);
2151 rdline_newline(&rdl, "> ");
2154 c = cmdline_dev_recv(NULL);
2158 ret = rdline_char_in(&rdl, c);
2160 printf_P(PSTR("abort\n"));
2167 buffer = rdline_get_buffer(&rdl);
2169 eeprom_insert_cmd_before(buffer, res->n);
2171 eeprom_append_cmd(buffer);
2175 const char PROGMEM str_eeprom_add_eeprom[] = "eeprom";
2176 const parse_token_string_t PROGMEM cmd_eeprom_add_cmd =
2177 TOKEN_STRING_INITIALIZER(struct cmd_eeprom_add_result, cmd,
2178 str_eeprom_add_eeprom);
2179 const char PROGMEM str_eeprom_add_add[] = "add";
2180 const parse_token_string_t PROGMEM cmd_eeprom_add_action =
2181 TOKEN_STRING_INITIALIZER(struct cmd_eeprom_add_result, action,
2182 str_eeprom_add_add);
2183 const parse_token_num_t PROGMEM cmd_eeprom_add_num =
2184 TOKEN_NUM_INITIALIZER(struct cmd_eeprom_add_result, n,
2187 const char PROGMEM help_eeprom_add[] = "insert an eeprom init command";
2188 const parse_inst_t PROGMEM cmd_eeprom_add = {
2189 .f = cmd_eeprom_add_parsed, /* function to call */
2190 .data = NULL, /* 2nd arg of func */
2191 .help_str = help_eeprom_add,
2192 .tokens = { /* token list, NULL terminated */
2193 (PGM_P)&cmd_eeprom_add_cmd,
2194 (PGM_P)&cmd_eeprom_add_action,
2195 (PGM_P)&cmd_eeprom_add_num,
2200 const char PROGMEM help_eeprom_add2[] = "append an eeprom init command";
2201 const parse_inst_t PROGMEM cmd_eeprom_add2 = {
2202 .f = cmd_eeprom_add_parsed, /* function to call */
2203 .data = (void *)1, /* 2nd arg of func */
2204 .help_str = help_eeprom_add2,
2205 .tokens = { /* token list, NULL terminated */
2206 (PGM_P)&cmd_eeprom_add_cmd,
2207 (PGM_P)&cmd_eeprom_add_action,
2214 struct cmd_eeprom_list_result {
2216 fixed_string_t action;
2219 static void cmd_eeprom_list_parsed(void *parsed_result,
2222 (void)parsed_result;
2227 const char PROGMEM str_eeprom_list_eeprom[] = "eeprom";
2228 const parse_token_string_t PROGMEM cmd_eeprom_list_cmd =
2229 TOKEN_STRING_INITIALIZER(struct cmd_eeprom_list_result, cmd,
2230 str_eeprom_list_eeprom);
2231 const char PROGMEM str_eeprom_list_list[] = "list";
2232 const parse_token_string_t PROGMEM cmd_eeprom_list_action =
2233 TOKEN_STRING_INITIALIZER(struct cmd_eeprom_list_result, action,
2234 str_eeprom_list_list);
2236 const char PROGMEM help_eeprom_list[] = "list all eeprom init commands";
2237 const parse_inst_t PROGMEM cmd_eeprom_list = {
2238 .f = cmd_eeprom_list_parsed, /* function to call */
2239 .data = NULL, /* 2nd arg of func */
2240 .help_str = help_eeprom_list,
2241 .tokens = { /* token list, NULL terminated */
2242 (PGM_P)&cmd_eeprom_list_cmd,
2243 (PGM_P)&cmd_eeprom_list_action,
2251 struct cmd_dump_i2c_result {
2255 static void cmd_dump_i2c_parsed(void *parsed_result, void *data)
2257 struct i2c_ans_imuboard_status imu;
2260 (void)parsed_result;
2263 while (!cmdline_keypressed()) {
2264 IRQ_LOCK(irq_flags);
2265 memcpy(&imu, &imuboard_status, sizeof(imu));
2266 IRQ_UNLOCK(irq_flags);
2268 if (imu.flags & IMUBOARD_STATUS_GPS_OK) {
2269 printf_P(PSTR("GPS lat=%"PRIi32" long=%"PRIi32
2270 " alt=%"PRIi32"\n"),
2271 imu.latitude, imu.longitude, imu.altitude);
2274 printf_P(PSTR("GPS unavailable"));
2275 i2c_protocol_debug();
2280 const char PROGMEM str_dump_i2c[] = "dump_i2c";
2281 const parse_token_string_t PROGMEM cmd_dump_i2c_cmd =
2282 TOKEN_STRING_INITIALIZER(struct cmd_dump_i2c_result, cmd,
2285 const char PROGMEM help_dump_i2c[] = "dump_i2c";
2286 const parse_inst_t PROGMEM cmd_dump_i2c = {
2287 .f = cmd_dump_i2c_parsed, /* function to call */
2288 .data = NULL, /* 2nd arg of func */
2289 .help_str = help_dump_i2c,
2290 .tokens = { /* token list, NULL terminated */
2291 (PGM_P)&cmd_dump_i2c_cmd,
2300 const parse_ctx_t PROGMEM main_ctx[] = {
2302 /* commands_gen.c */
2324 &cmd_range_powermask,
2327 &cmd_monitor_period,
2335 &cmd_servo_bypassppm,
2338 &cmd_dump_xbee_stats,
2339 &cmd_rc_proto_stats,
2340 &cmd_rc_proto_timers,
2341 &cmd_rc_proto_timers_show,
2343 &cmd_rc_proto_mode2,
2344 &cmd_rc_proto_mode3,
2345 &cmd_rc_proto_hello,
2346 &cmd_rc_proto_hello_name,
2348 &cmd_rc_proto_echo_name,
2349 &cmd_test_eeprom_config,