+ (PGM_P)&cmd_beep_beep,
+ NULL,
+ },
+};
+
+/**********************************************************/
+
+/* this structure is filled when cmd_servo is parsed successfully */
+struct cmd_servo_result {
+ fixed_string_t arg0;
+ fixed_string_t arg1;
+ uint16_t num;
+ uint16_t val;
+};
+
+/* function called when cmd_servo is parsed successfully */
+static void cmd_servo_parsed(void * parsed_result, void *data)
+{
+ struct cmd_servo_result *res = parsed_result;
+
+ (void)data;
+
+ if (!strcmp_P(res->arg1, PSTR("set"))) {
+ if (res->num >= N_SERVO) {
+ printf_P(PSTR("bad servo num\n"));
+ return;
+ }
+ if (res->val >= 1024) {
+ printf_P(PSTR("bad servo val\n"));
+ return;
+ }
+ spi_servo_set(res->num, res->val);
+ }
+ else if (!strcmp_P(res->arg1, PSTR("bypass"))) {
+ spi_servo_set_bypass(!!res->val);
+ }
+ else if (!strcmp_P(res->arg1, PSTR("ppm"))) {
+ spi_servo_set_ppm(!!res->val);
+ }
+ else if (!strcmp_P(res->arg1, PSTR("show"))) {
+ spi_servo_dump();
+ }
+}
+
+const char PROGMEM str_servo_arg0[] = "servo";
+const parse_token_string_t PROGMEM cmd_servo_arg0 =
+ TOKEN_STRING_INITIALIZER(struct cmd_servo_result, arg0,
+ str_servo_arg0);
+const char PROGMEM str_servo_arg1_set[] = "set";
+const parse_token_string_t PROGMEM cmd_servo_arg1_set =
+ TOKEN_STRING_INITIALIZER(struct cmd_servo_result, arg1,
+ str_servo_arg1_set);
+const parse_token_num_t PROGMEM cmd_servo_num =
+ TOKEN_NUM_INITIALIZER(struct cmd_servo_result, num,
+ UINT16);
+const parse_token_num_t PROGMEM cmd_servo_val =
+ TOKEN_NUM_INITIALIZER(struct cmd_servo_result, val,
+ UINT16);
+
+const char PROGMEM help_servo_set[] = "set servo value";
+const parse_inst_t PROGMEM cmd_servo_set = {
+ .f = cmd_servo_parsed, /* function to call */
+ .data = NULL, /* 2nd arg of func */
+ .help_str = help_servo_set,
+ .tokens = { /* token list, NULL terminated */
+ (PGM_P)&cmd_servo_arg0,
+ (PGM_P)&cmd_servo_arg1_set,
+ (PGM_P)&cmd_servo_num,
+ (PGM_P)&cmd_servo_val,
+ NULL,
+ },
+};
+
+const char PROGMEM str_servo_arg1_show[] = "show";
+const parse_token_string_t PROGMEM cmd_servo_arg1_show =
+ TOKEN_STRING_INITIALIZER(struct cmd_servo_result, arg1,
+ str_servo_arg1_show);
+
+const char PROGMEM help_servo_show[] = "read servo and config";
+const parse_inst_t PROGMEM cmd_servo_show = {
+ .f = cmd_servo_parsed, /* function to call */
+ .data = NULL, /* 2nd arg of func */
+ .help_str = help_servo_show,
+ .tokens = { /* token list, NULL terminated */
+ (PGM_P)&cmd_servo_arg0,
+ (PGM_P)&cmd_servo_arg1_show,
+ NULL,
+ },
+};
+
+const char PROGMEM str_servo_arg1_bypassppm[] = "bypass#ppm";
+const parse_token_string_t PROGMEM cmd_servo_arg1_bypassppm =
+ TOKEN_STRING_INITIALIZER(struct cmd_servo_result, arg1,
+ str_servo_arg1_bypassppm);
+
+const char PROGMEM help_servo_bypassppm[] = "change bypass/ppm";
+const parse_inst_t PROGMEM cmd_servo_bypassppm = {
+ .f = cmd_servo_parsed, /* function to call */
+ .data = NULL, /* 2nd arg of func */
+ .help_str = help_servo_bypassppm,
+ .tokens = { /* token list, NULL terminated */
+ (PGM_P)&cmd_servo_arg0,
+ (PGM_P)&cmd_servo_arg1_bypassppm,
+ (PGM_P)&cmd_servo_val,
+ NULL,
+ },
+};
+
+/**********************************************************/
+
+/* this structure is filled when cmd_test_spi is parsed successfully */
+struct cmd_test_spi_result {
+ fixed_string_t arg0;
+};
+
+static void cmd_test_spi_parsed(void * parsed_result, void *data)
+{
+ uint8_t i, flags, wait_time = 0;
+ uint16_t val = 0;
+
+ (void)parsed_result;
+ (void)data;
+
+ spi_servo_set_bypass(0);
+ spi_servo_set_ppm(0);
+
+ /* stress test: send many commands, no wait between each servo
+ * of a series, and a variable delay between series */
+ printf_P(PSTR("stress test\r\n"));
+ while (!cmdline_keypressed()) {
+
+ wait_time++;
+ if (wait_time > 20)
+ wait_time = 0;
+
+ IRQ_LOCK(flags);
+ val = global_ms;
+ IRQ_UNLOCK(flags);
+ val >>= 3;
+ val &= 1023;
+
+ for (i = 0; i < 6; i++)
+ spi_servo_set(i, val);
+
+ wait_ms(wait_time);
+ printf_P(PSTR("%4.4d %4.4d %4.4d %4.4d %4.4d %4.4d\r\n"),
+ spi_servo_get(0), spi_servo_get(1), spi_servo_get(2),
+ spi_servo_get(3), spi_servo_get(4), spi_servo_get(5));
+ }
+
+ printf_P(PSTR("bypass mode, with spi commands in background\r\n"));
+ spi_servo_set_bypass(1);
+
+ /* test bypass mode */
+ while (!cmdline_keypressed()) {
+
+ wait_time++;
+ if (wait_time > 20)
+ wait_time = 0;
+
+ IRQ_LOCK(flags);
+ val = global_ms;
+ IRQ_UNLOCK(flags);
+ val >>= 3;
+ val &= 1023;
+
+ for (i = 0; i < 6; i++)
+ spi_servo_set(i, val);
+
+ wait_ms(wait_time);
+ printf_P(PSTR("%4.4d %4.4d %4.4d %4.4d %4.4d %4.4d\r\n"),
+ spi_servo_get(0), spi_servo_get(1), spi_servo_get(2),
+ spi_servo_get(3), spi_servo_get(4), spi_servo_get(5));
+ }
+
+ printf_P(PSTR("PPM to servo\r\n"));
+ spi_servo_set_bypass(0);
+ spi_servo_set_ppm(0);
+
+ /* test PPM to servo (bypass) mode */
+ while (!cmdline_keypressed()) {
+ for (i = 0; i < 6; i++) {
+ val = spi_servo_get(i);
+ spi_servo_set(i, val);
+ }
+ }
+
+ printf_P(PSTR("PPM to (servo + PPM)\r\n"));
+ spi_servo_set_bypass(0);
+ spi_servo_set_ppm(1);
+
+ /* test PPM to servo (bypass) mode */
+ while (!cmdline_keypressed()) {
+ for (i = 0; i < 6; i++) {
+ val = spi_servo_get(i);
+ spi_servo_set(i, val);
+ }
+ }
+}
+
+const char PROGMEM str_test_spi_arg0[] = "test_spi";
+const parse_token_string_t PROGMEM cmd_test_spi_arg0 =
+ TOKEN_STRING_INITIALIZER(struct cmd_test_spi_result, arg0,
+ str_test_spi_arg0);
+
+const char PROGMEM help_test_spi[] = "Test the spi";
+const parse_inst_t PROGMEM cmd_test_spi = {
+ .f = cmd_test_spi_parsed, /* function to call */
+ .data = NULL, /* 2nd arg of func */
+ .help_str = help_test_spi,
+ .tokens = { /* token list, NULL terminated */
+ (PGM_P)&cmd_test_spi_arg0,
+ NULL,
+ },
+};
+
+/**********************************************************/
+
+/* this structure is filled when cmd_dump_xbee_stats is parsed successfully */
+struct cmd_dump_xbee_stats_result {
+ fixed_string_t arg0;
+};
+
+static void cmd_dump_xbee_stats_parsed(void *parsed_result, void *data)
+{
+ (void)parsed_result;
+ (void)data;
+
+ xbee_dump_stats(xbee_dev);
+}
+
+const char PROGMEM str_dump_xbee_stats_arg0[] = "dump_xbee_stats";
+const parse_token_string_t PROGMEM cmd_dump_xbee_stats_arg0 =
+ TOKEN_STRING_INITIALIZER(struct cmd_dump_xbee_stats_result, arg0,
+ str_dump_xbee_stats_arg0);
+
+const char PROGMEM help_dump_xbee_stats[] = "Test the spi";
+const parse_inst_t PROGMEM cmd_dump_xbee_stats = {
+ .f = cmd_dump_xbee_stats_parsed, /* function to call */
+ .data = NULL, /* 2nd arg of func */
+ .help_str = help_dump_xbee_stats,
+ .tokens = { /* token list, NULL terminated */
+ (PGM_P)&cmd_dump_xbee_stats_arg0,
+ NULL,
+ },
+};
+
+/**********************************************************/
+
+/* this structure is filled when cmd_test_eeprom_config is parsed successfully */
+struct cmd_test_eeprom_config_result {
+ fixed_string_t arg0;
+};
+
+static void cmd_test_eeprom_config_parsed(void *parsed_result, void *data)
+{
+ (void)parsed_result;
+ (void)data;
+
+ eeprom_dump_cmds();
+ eeprom_append_cmd("salut1\n");
+ eeprom_dump_cmds();
+ eeprom_append_cmd("salut2\n");
+ eeprom_append_cmd("salut3\n");
+ eeprom_append_cmd("salut4\n");
+ eeprom_dump_cmds();
+ eeprom_insert_cmd_before("coin\n", 0);
+ eeprom_insert_cmd_before("coin2\n", 2);
+ eeprom_dump_cmds();
+ eeprom_delete_cmd(2);
+ eeprom_delete_cmd(0);
+ eeprom_dump_cmds();
+}
+
+const char PROGMEM str_test_eeprom_config_arg0[] = "test_eeprom_config";
+const parse_token_string_t PROGMEM cmd_test_eeprom_config_arg0 =
+ TOKEN_STRING_INITIALIZER(struct cmd_test_eeprom_config_result, arg0,
+ str_test_eeprom_config_arg0);
+
+const char PROGMEM help_test_eeprom_config[] = "Test the eeprom configuration";
+const parse_inst_t PROGMEM cmd_test_eeprom_config = {
+ .f = cmd_test_eeprom_config_parsed, /* function to call */
+ .data = NULL, /* 2nd arg of func */
+ .help_str = help_test_eeprom_config,
+ .tokens = { /* token list, NULL terminated */
+ (PGM_P)&cmd_test_eeprom_config_arg0,