Switch from GPLv2 to GPLv2+
[fw/altos] / ao-tools / ao-usbload / ao-usbload.c
index 0c8a23dfc60115786aa0be0c57c243cc6d0c159a..2f121cfe4fccf558d70f2e3c11bc0c7f05b2516a 100644 (file)
@@ -3,7 +3,8 @@
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
  *
  * This program is distributed in the hope that it will be useful, but
  * WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -86,12 +87,13 @@ static const struct option options[] = {
        { .name = "cal", .has_arg = 1, .val = 'c' },
        { .name = "serial", .has_arg = 1, .val = 's' },
        { .name = "verbose", .has_arg = 1, .val = 'v' },
+       { .name = "wait", .has_arg = 0, .val = 'w' },
        { 0, 0, 0, 0},
 };
 
 static void usage(char *program)
 {
-       fprintf(stderr, "usage: %s [--raw] [--verbose=<verbose>] [--device=<device>] [-tty=<tty>] [--cal=<radio-cal>] [--serial=<serial>] file.{elf,ihx}\n", program);
+       fprintf(stderr, "usage: %s [--raw] [--verbose=<verbose>] [--device=<device>] [-tty=<tty>] [--cal=<radio-cal>] [--serial=<serial>] [--wait] file.{elf,ihx}\n", program);
        exit(1);
 }
 
@@ -142,8 +144,10 @@ main (int argc, char **argv)
        int                     verbose = 0;
        struct ao_sym           *file_symbols;
        int                     num_file_symbols;
+       uint32_t                flash_base, flash_bound;
+       int                     has_flash_size = 0;
 
-       while ((c = getopt_long(argc, argv, "rT:D:c:s:v:", options, NULL)) != -1) {
+       while ((c = getopt_long(argc, argv, "wrT:D:c:s:v:", options, NULL)) != -1) {
                switch (c) {
                case 'T':
                        tty = optarg;
@@ -154,6 +158,9 @@ main (int argc, char **argv)
                case 'r':
                        raw = 1;
                        break;
+               case 'w':
+                       cc_default_timeout = -1;
+                       break;
                case 'c':
                        cal = strtoul(optarg, &cal_end, 10);
                        if (cal_end == optarg || *cal_end != '\0')
@@ -206,6 +213,10 @@ main (int argc, char **argv)
                                this_tty = cc_usbdevs_find_by_arg(device, "AltosFlash");
                        if (!this_tty)
                                this_tty = cc_usbdevs_find_by_arg(device, "TeleMega");
+                       if (!this_tty)
+                               this_tty = cc_usbdevs_find_by_arg(device, "TeleMetrum");
+                       if (!this_tty)
+                               this_tty = cc_usbdevs_find_by_arg(device, "TeleGPS");
                        if (!this_tty)
                                this_tty = getenv("ALTOS_TTY");
                        if (!this_tty)
@@ -222,6 +233,14 @@ main (int argc, char **argv)
                                cc_usb_getline(cc, line, sizeof(line));
                                if (!strncmp(line, "altos-loader", 12))
                                        is_loader = 1;
+                               if (!strncmp(line, "flash-range", 11)) {
+                                       int i;
+                                       for (i = 11; i < strlen(line); i++)
+                                               if (line[i] != ' ')
+                                                       break;
+                                       if (sscanf(line + i, "%x %x", &flash_base, &flash_bound) == 2)
+                                               has_flash_size = 1;
+                               }
                                if (!strncmp(line, "software-version", 16))
                                        break;
                        }
@@ -262,6 +281,22 @@ main (int argc, char **argv)
 #endif
        }
 
+       /* If the device can tell us the size of flash, make sure
+        * the image fits in that
+        */
+       if (has_flash_size) {
+               if (load->address < flash_base ||
+                   load->address + load->length > flash_bound)
+               {
+                       fprintf(stderr, "Image does not fit on device.\n");
+                       fprintf(stderr, "  Image base:  %08x bounds %08x\n",
+                               load->address, load->address + load->length);
+                       fprintf(stderr, "  Device base: %08x bounds %08x\n",
+                               flash_base, flash_bound);
+                       done(cc, 1);
+               }
+       }
+
        if (!raw) {
                /* Go fetch existing config values
                 * if available
@@ -295,7 +330,7 @@ main (int argc, char **argv)
        /* And flash the resulting image to the device
         */
        success = ao_self_write(cc, load);
-               
+
        if (!success) {
                fprintf (stderr, "\"%s\": Write failed\n", filename);
                done(cc, 1);