altos: Add ao_boot_chain to telemega v0.3
[fw/altos] / src / stm-flash / ao_stm_flash.c
index 51856b469fb0b423a255b14b4dacd52405f21679..f85807350763628f596958f401dba528951e3bfc 100644 (file)
@@ -26,6 +26,17 @@ ao_panic(uint8_t reason)
        for (;;);
 }
 
+void
+ao_put_string(__code char *s)
+{
+       char    c;
+       while ((c = *s++)) {
+               if (c == '\n')
+                       ao_usb_putchar('\r');
+               ao_usb_putchar(c);
+       }
+}
+
 void
 ao_application(void)
 {
@@ -33,30 +44,35 @@ ao_application(void)
 }
 
 static uint32_t
-ao_cmd_hex32(void)
+ao_get_hex32(void)
 {
-       __pdata uint8_t r = ao_cmd_lex_error;
        int8_t  n;
        uint32_t v = 0;
 
-       ao_cmd_white();
+       for (;;) {
+               n = ao_usb_getchar();
+               if (n != ' ')
+                       break;
+       }
        for(;;) {
-               n = ao_cmd_hexchar(ao_cmd_lex_c);
-               if (n < 0)
+               if ('0' <= n && n <= '9')
+                       n = n - '0';
+               else if ('a' <= n && n <= 'f')
+                       n = n - ('a' - 10);
+               else if ('A' <= n && n <= 'F')
+                       n = n - ('A' - 10);
+               else
                        break;
                v = (v << 4) | n;
-               r = ao_cmd_success;
-               ao_cmd_lex();
+               n = ao_usb_getchar();
        }
-       if (r != ao_cmd_success)
-               ao_cmd_status = r;
        return v;
 }
 
 void
 ao_block_erase(void)
 {
-       uint32_t        addr = ao_cmd_hex32();
+       uint32_t        addr = ao_get_hex32();
        uint32_t        *p = (uint32_t *) addr;
 
        ao_flash_erase_page(p);
@@ -65,7 +81,7 @@ ao_block_erase(void)
 void
 ao_block_write(void)
 {
-       uint32_t        addr = ao_cmd_hex32();
+       uint32_t        addr = ao_get_hex32();
        uint32_t        *p = (uint32_t *) addr;
        union {
                uint8_t         data8[256];
@@ -73,50 +89,52 @@ ao_block_write(void)
        } u;
        uint16_t        i;
 
-       if (addr < 0x08002000 || 0x08200000 <= addr) {
-               puts("Invalid address");
+       if (addr < (uint32_t) AO_BOOT_APPLICATION_BASE) {
+               ao_put_string("Invalid address\n");
                return;
        }
        for (i = 0; i < 256; i++)
-               u.data8[i] = i;
+               u.data8[i] = ao_usb_getchar();
        ao_flash_page(p, u.data32);
 }
 
-static void
-puthex(uint8_t c)
-{
-       c &= 0xf;
-       if (c < 10)
-               c += '0';
-       else
-               c += 'a' - 10;
-       putchar (c);
-}
-
 void
 ao_block_read(void)
 {
-       uint32_t        addr = ao_cmd_hex32();
+       uint32_t        addr = ao_get_hex32();
        uint8_t         *p = (uint8_t *) addr;
        uint16_t        i;
        uint8_t         c;
 
        for (i = 0; i < 256; i++) {
                c = *p++;
-               puthex(c);
-               puthex(c>>4);
-               if ((i & 0xf) == 0xf)
-                       putchar('\n');
+               ao_usb_putchar(c);
        }
 }
 
-__code struct ao_cmds ao_flash_cmds[] = {
-       { ao_application, "a\0Switch to application" },
-       { ao_block_erase, "e <addr>\0Erase block." },
-       { ao_block_write, "W <addr>\0Write block. 256 binary bytes follow newline" },
-       { ao_block_read, "R <addr>\0Read block. Returns 256 bytes" },
-       { 0, NULL },
-};
+static void
+ao_show_version(void)
+{
+       ao_put_string("altos-loader");
+       ao_put_string("\nmanufacturer     "); ao_put_string(ao_manufacturer);
+       ao_put_string("\nproduct          "); ao_put_string(ao_product);
+       ao_put_string("\nsoftware-version "); ao_put_string(ao_version);
+       ao_put_string("\n");
+}
+
+static void
+ao_flash_task(void) {
+       for (;;) {
+               ao_usb_flush();
+               switch (ao_usb_getchar()) {
+               case 'v': ao_show_version(); break;
+               case 'a': ao_application(); break;
+               case 'X': ao_block_erase(); break;
+               case 'W': ao_block_write(); break;
+               case 'R': ao_block_read(); break;
+               }
+       }
+}
 
 
 int
@@ -124,15 +142,11 @@ main(void)
 {
        ao_clock_init();
 
-       ao_task_init();
-
-       ao_timer_init();
+//     ao_timer_init();
 //     ao_dma_init();
-       ao_cmd_init();
 //     ao_exti_init();
        ao_usb_init();
 
-       ao_cmd_register(&ao_flash_cmds[0]);
-       ao_start_scheduler();
+       ao_flash_task();
        return 0;
 }