altos: Add ao_boot_chain to telemega v0.3
[fw/altos] / src / stm-flash / ao_stm_flash.c
index 2988a9375345c947665cc8972b87083da28e004e..f85807350763628f596958f401dba528951e3bfc 100644 (file)
@@ -26,16 +26,115 @@ 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)
 {
        ao_boot_reboot(AO_BOOT_APPLICATION_BASE);
 }
 
-__code struct ao_cmds ao_flash_cmds[] = {
-       { ao_application, "A\0Switch to application" },
-       { 0, NULL },
-};
+static uint32_t
+ao_get_hex32(void)
+{
+       int8_t  n;
+       uint32_t v = 0;
+
+       for (;;) {
+               n = ao_usb_getchar();
+               if (n != ' ')
+                       break;
+       }
+       for(;;) {
+               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;
+               n = ao_usb_getchar();
+       }
+       return v;
+}
+
+void
+ao_block_erase(void)
+{
+       uint32_t        addr = ao_get_hex32();
+       uint32_t        *p = (uint32_t *) addr;
+
+       ao_flash_erase_page(p);
+}
+
+void
+ao_block_write(void)
+{
+       uint32_t        addr = ao_get_hex32();
+       uint32_t        *p = (uint32_t *) addr;
+       union {
+               uint8_t         data8[256];
+               uint32_t        data32[64];
+       } u;
+       uint16_t        i;
+
+       if (addr < (uint32_t) AO_BOOT_APPLICATION_BASE) {
+               ao_put_string("Invalid address\n");
+               return;
+       }
+       for (i = 0; i < 256; i++)
+               u.data8[i] = ao_usb_getchar();
+       ao_flash_page(p, u.data32);
+}
+
+void
+ao_block_read(void)
+{
+       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++;
+               ao_usb_putchar(c);
+       }
+}
+
+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
@@ -43,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;
 }