altoslib: Deal with reflashing EasyMega boards with ancient firmware
authorKeith Packard <keithp@keithp.com>
Sun, 23 Aug 2020 22:32:57 +0000 (15:32 -0700)
committerKeith Packard <keithp@keithp.com>
Sun, 23 Aug 2020 22:32:57 +0000 (15:32 -0700)
Ancient EasyMega firmware included radio calibration data in the
romconfig bits, which has since been removed. That means the config
data from those boards will be at a different location than current
firmware. Deal with that by poking around in firmware looking for
valid bits.

Signed-off-by: Keith Packard <keithp@keithp.com>
altoslib/AltosHexfile.java
altoslib/AltosRomconfig.java

index 14f660a0bbcb0c4d38f406d31d2029d3fea3c711..718826001755a0dedf1a1b9725b94a30e3fcf7f4 100644 (file)
@@ -287,6 +287,8 @@ public class AltosHexfile {
                return null;
        }
 
+       private static final int look_around[] = { 0, -2, 2, -4, 4 };
+
        private long find_usb_descriptors() {
                AltosHexsym     usb_descriptors = lookup_symbol("ao_usb_descriptors");
                long            a;
@@ -294,24 +296,22 @@ public class AltosHexfile {
                if (usb_descriptors == null)
                        return -1;
 
-               try {
-                       /* The address of this has moved depending on
-                        * padding in the linker script. Look forward
-                        * and backwards two bytes to see if we can find it
-                        */
-                       a = usb_descriptors.address;
-
-                       if (get_u8(a) == 0x12 && get_u8(a+1) == AO_USB_DESC_DEVICE)
-                               return a;
-                       else if (get_u8(a+1) == 0x12 && get_u8(a+3) == AO_USB_DESC_DEVICE)
-                               return a + 2;
-                       else if (get_u8(a-2) == 0x12 && get_u8(a-1) == AO_USB_DESC_DEVICE)
-                               return a - 2;
+               /* The address of this has moved depending on padding
+                * in the linker script and romconfig symbols. Look
+                * forward and backwards two and four bytes to see if
+                * we can find it
+                */
+               a = usb_descriptors.address;
 
-                       return -1;
-               } catch (ArrayIndexOutOfBoundsException ae) {
-                       return -1;
+               for (int look : look_around) {
+                       try {
+                               if (get_u8(a + look) == 0x12 && get_u8(a + look + 1) == AO_USB_DESC_DEVICE)
+                                       return a;
+                       } catch (ArrayIndexOutOfBoundsException ae) {
+                               continue;
+                       }
                }
+               return -1;
        }
 
        public AltosUsbId find_usb_id() {
index d868b9aa444cfc488476ea7b244de71e24053691..8ef1848d0f3c5c8e690113458cea23a170afd4dc 100644 (file)
@@ -28,6 +28,7 @@ public class AltosRomconfig implements AltosUnitInfoListener {
        public int      check;
        public int      serial_number;
        public int      radio_calibration;
+       public int      address_offset;
        public AltosUsbId       usb_id;
        public String           usb_product;
 
@@ -46,9 +47,9 @@ public class AltosRomconfig implements AltosUnitInfoListener {
                return (int) (find_address(hexfile, name, len) - hexfile.address);
        }
 
-       static int get_int(AltosHexfile hexfile, String name, int len) throws AltosNoSymbol {
+       static private int get_int(AltosHexfile hexfile, String name, int len, int adjust) throws AltosNoSymbol {
                byte[] bytes = hexfile.data;
-               int start = (int) find_offset(hexfile, name, len);
+               int start = (int) find_offset(hexfile, name, len) + adjust;
 
                int     v = 0;
                int     o = 0;
@@ -142,33 +143,44 @@ public class AltosRomconfig implements AltosUnitInfoListener {
                }
        }
 
+       static final int adjust_rom[] = { 0, -4, 4 };
+
        public AltosRomconfig(AltosHexfile hexfile) {
                try {
-                       version = get_int(hexfile, ao_romconfig_version, 2);
-                       check = get_int(hexfile, ao_romconfig_check, 2);
-                       if (check == (~version & 0xffff)) {
-                               switch (version) {
-                               case 2:
-                               case 1:
-                                       serial_number = get_int(hexfile, ao_serial_number, 2);
-                                       try {
-                                               radio_calibration = get_int(hexfile, ao_radio_cal, 4);
-                                       } catch (AltosNoSymbol missing) {
-                                               radio_calibration = 0;
-                                       }
-
-                                       valid = true;
-
-                                       /* XXX TeleBT v4.0 units originally shipped without RF calibration programmed. Go fetch
-                                        * the correct value from the web site
-                                        */
-                                       if (serial_number == 2584 ||
-                                           (3686 <= serial_number && serial_number <= 3938 && radio_calibration == 5695485))
-                                       {
-                                               fetch_radio_cal();
+                       for (int adjust : adjust_rom) {
+                               try {
+                                       version = get_int(hexfile, ao_romconfig_version, 2, adjust);
+                                       check = get_int(hexfile, ao_romconfig_check, 2, adjust);
+                                       System.out.printf("adjust %d version %x check %x\n", adjust, version, check);
+                                       if (check == (~version & 0xffff)) {
+                                               switch (version) {
+                                               case 2:
+                                               case 1:
+                                                       serial_number = get_int(hexfile, ao_serial_number, 2, adjust);
+                                                       try {
+                                                               radio_calibration = get_int(hexfile, ao_radio_cal, 4, adjust);
+                                                       } catch (AltosNoSymbol missing) {
+                                                               radio_calibration = 0;
+                                                       }
+
+                                                       valid = true;
+
+                                                       /* XXX TeleBT v4.0 units originally shipped without RF calibration programmed. Go fetch
+                                                        * the correct value from the web site
+                                                        */
+                                                       if (serial_number == 2584 ||
+                                                           (3686 <= serial_number && serial_number <= 3938 && radio_calibration == 5695485))
+                                                       {
+                                                               fetch_radio_cal();
+                                                       }
+
+                                                       break;
+                                               }
+                                               break;
                                        }
-
-                                       break;
+                               } catch (ArrayIndexOutOfBoundsException aie) {
+                                       System.out.printf("adjust %d failed\n", adjust);
+                                       continue;
                                }
                        }
                        usb_id = hexfile.find_usb_id();