altos: Shrink ao_cmd_put16, ao_cmd_hex and ao_cmd
[fw/altos] / src / ao_cmd.c
index 33619b245086b8f8ad8a6de1f4cada00d542b64d..60f1071631d180cccf6f16741a0f022c5701fa3b 100644 (file)
@@ -18,9 +18,9 @@
 #include "ao.h"
 
 __xdata uint16_t ao_cmd_lex_i;
+__xdata uint32_t ao_cmd_lex_u32;
 __xdata char   ao_cmd_lex_c;
 __xdata enum ao_cmd_status ao_cmd_status;
-static __xdata uint8_t lex_echo;
 
 #define CMD_LEN        32
 
@@ -40,7 +40,7 @@ static void
 readline(void)
 {
        __xdata char c;
-       if (lex_echo)
+       if (ao_echo())
                put_string("> ");
        cmd_len = 0;
        for (;;) {
@@ -49,7 +49,7 @@ readline(void)
                /* backspace/delete */
                if (c == '\010' || c == '\177') {
                        if (cmd_len != 0) {
-                               if (lex_echo)
+                               if (ao_echo())
                                        put_string("\010 \010");
                                --cmd_len;
                        }
@@ -59,7 +59,7 @@ readline(void)
                /* ^U */
                if (c == '\025') {
                        while (cmd_len != 0) {
-                               if (lex_echo)
+                               if (ao_echo())
                                        put_string("\010 \010");
                                --cmd_len;
                        }
@@ -71,18 +71,18 @@ readline(void)
                        c = '\n';
 
                if (c == '\n') {
-                       if (lex_echo)
+                       if (ao_echo())
                                putchar('\n');
                        break;
                }
 
                if (cmd_len >= CMD_LEN - 2) {
-                       if (lex_echo)
+                       if (ao_echo())
                                putchar('\007');
                        continue;
                }
                cmd_line[cmd_len++] = c;
-               if (lex_echo)
+               if (ao_echo())
                        putchar(c);
        }
        cmd_line[cmd_len++] = '\n';
@@ -110,9 +110,8 @@ putnibble(uint8_t v)
 void
 ao_cmd_put16(uint16_t v)
 {
-       int8_t i;
-       for (i = 3; i >= 0; i--)
-               putnibble((v >> (i << 2)) & 0xf);
+       ao_cmd_put8(v >> 8);
+       ao_cmd_put8(v);
 }
 
 void
@@ -133,18 +132,20 @@ void
 ao_cmd_hex(void)
 {
        __xdata uint8_t r = ao_cmd_lex_error;
+       uint8_t n;
 
        ao_cmd_lex_i = 0;
        ao_cmd_white();
        for(;;) {
                if ('0' <= ao_cmd_lex_c && ao_cmd_lex_c <= '9')
-                       ao_cmd_lex_i = (ao_cmd_lex_i << 4) | (ao_cmd_lex_c - '0');
+                       n = (ao_cmd_lex_c - '0');
                else if ('a' <= ao_cmd_lex_c && ao_cmd_lex_c <= 'f')
-                       ao_cmd_lex_i = (ao_cmd_lex_i << 4) | (ao_cmd_lex_c - 'a' + 10);
+                       n = (ao_cmd_lex_c - 'a' + 10);
                else if ('A' <= ao_cmd_lex_c && ao_cmd_lex_c <= 'F')
-                       ao_cmd_lex_i = (ao_cmd_lex_i << 4) | (ao_cmd_lex_c - 'A' + 10);
+                       n = (ao_cmd_lex_c - 'A' + 10);
                else
                        break;
+               ao_cmd_lex_i = (ao_cmd_lex_i << 4) | n;
                r = ao_cmd_success;
                ao_cmd_lex();
        }
@@ -157,11 +158,11 @@ ao_cmd_decimal(void)
 {
        __xdata uint8_t r = ao_cmd_lex_error;
 
-       ao_cmd_lex_i = 0;
+       ao_cmd_lex_u32 = 0;
        ao_cmd_white();
        for(;;) {
                if ('0' <= ao_cmd_lex_c && ao_cmd_lex_c <= '9')
-                       ao_cmd_lex_i = (ao_cmd_lex_i * 10) + (ao_cmd_lex_c - '0');
+                       ao_cmd_lex_u32 = (ao_cmd_lex_u32 * 10) + (ao_cmd_lex_c - '0');
                else
                        break;
                r = ao_cmd_success;
@@ -169,6 +170,21 @@ ao_cmd_decimal(void)
        }
        if (r != ao_cmd_success)
                ao_cmd_status = r;
+       ao_cmd_lex_i = (uint16_t) ao_cmd_lex_u32;
+}
+
+uint8_t
+ao_match_word(__code char *word)
+{
+       while (*word) {
+               if (ao_cmd_lex_c != *word) {
+                       ao_cmd_status = ao_cmd_syntax_error;
+                       return 0;
+               }
+               word++;
+               ao_cmd_lex();
+       }
+       return 1;
 }
 
 static void
@@ -179,37 +195,22 @@ eol(void)
 }
 
 static void
-dump(void)
+echo(void)
 {
-       __xdata uint16_t c;
-       __xdata uint8_t * __xdata start, * __xdata end;
-
-       ao_cmd_hex();
-       start = (uint8_t __xdata *) ao_cmd_lex_i;
        ao_cmd_hex();
-       end = (uint8_t __xdata *) ao_cmd_lex_i;
-       if (ao_cmd_status != ao_cmd_success)
-               return;
-       c = 0;
-       while (start <= end) {
-               if ((c & 7) == 0) {
-                       if (c)
-                               putchar('\n');
-                       ao_cmd_put16((uint16_t) start);
-               }
-               putchar(' ');
-               ao_cmd_put8(*start);
-               ++c;
-               start++;
-       }
-       putchar('\n');
+       if (ao_cmd_status == ao_cmd_success)
+               ao_stdios[ao_cur_stdio].echo = ao_cmd_lex_i != 0;
 }
 
 static void
-echo(void)
+ao_reboot(void)
 {
-       ao_cmd_hex();
-       lex_echo = ao_cmd_lex_i != 0;
+       ao_cmd_white();
+       if (!ao_match_word("eboot"))
+               return;
+       WDCTL = WDCTL_EN | WDCTL_MODE_WATCHDOG | WDCTL_INT_64;
+       ao_delay(AO_SEC_TO_TICKS(2));
+       ao_panic(AO_PANIC_REBOOT);
 }
 
 static void
@@ -221,8 +222,6 @@ version(void)
        printf("software-version %s\n", ao_version);
 }
 
-static const char help_txt[] = "All numbers are in hex";
-
 #define NUM_CMDS       11
 
 static __code struct ao_cmds   *__xdata (ao_cmds[NUM_CMDS]);
@@ -234,11 +233,13 @@ help(void)
        __xdata uint8_t cmds;
        __xdata uint8_t cmd;
        __code struct ao_cmds * __xdata cs;
-       puts(help_txt);
+
        for (cmds = 0; cmds < ao_ncmds; cmds++) {
                cs = ao_cmds[cmds];
-               for (cmd = 0; cs[cmd].cmd != '\0'; cmd++)
-                       puts(cs[cmd].help);
+               for (cmd = 0; cs[cmd].func; cmd++)
+                       printf("%-45s %s\n",
+                               cs[cmd].help,
+                               cs[cmd].help+1+strlen(cs[cmd].help));
        }
 }
 
@@ -263,15 +264,13 @@ ao_cmd_register(__code struct ao_cmds *cmds)
 }
 
 void
-ao_cmd(void *parameters)
+ao_cmd(void)
 {
-       __xdata char    c;
-       __xdata uint8_t cmd, cmds;
+       char    c;
+       uint8_t cmd, cmds;
        __code struct ao_cmds * __xdata cs;
        void (*__xdata func)(void);
-       (void) parameters;
 
-       lex_echo = 1;
        for (;;) {
                readline();
                ao_cmd_lex();
@@ -283,8 +282,8 @@ ao_cmd(void *parameters)
                func = (void (*)(void)) NULL;
                for (cmds = 0; cmds < ao_ncmds; cmds++) {
                        cs = ao_cmds[cmds];
-                       for (cmd = 0; cs[cmd].cmd != '\0'; cmd++)
-                               if (cs[cmd].cmd == c) {
+                       for (cmd = 0; cs[cmd].func; cmd++)
+                               if (cs[cmd].help[0] == c) {
                                        func = cs[cmd].func;
                                        break;
                                }
@@ -302,12 +301,12 @@ ao_cmd(void *parameters)
 __xdata struct ao_task ao_cmd_task;
 
 __code struct ao_cmds  ao_base_cmds[] = {
-       { '?', help,            "?                                  Print this message" },
-       { 'T', ao_task_info,    "T                                  Show task states" },
-       { 'E', echo,            "E <0 off, 1 on>                    Set command echo mode" },
-       { 'd', dump,            "d <start> <end>                    Dump memory" },
-       { 'v', version,         "v                                  Show version" },
-       { 0,    help,   NULL },
+       { help,         "?\0Help" },
+       { ao_task_info, "T\0Show tasks" },
+       { echo,         "E <0 off, 1 on>\0Set echo mode" },
+       { ao_reboot,    "r eboot\0Reboot" },
+       { version,      "v\0Version" },
+       { 0,    NULL },
 };
 
 void