From 2289fd36f7ba76692fe07d2ebc8d7eda33750180 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 23 Aug 2020 15:32:57 -0700 Subject: [PATCH] altoslib: Deal with reflashing EasyMega boards with ancient firmware 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 --- altoslib/AltosHexfile.java | 32 +++++++++--------- altoslib/AltosRomconfig.java | 64 +++++++++++++++++++++--------------- 2 files changed, 54 insertions(+), 42 deletions(-) diff --git a/altoslib/AltosHexfile.java b/altoslib/AltosHexfile.java index 14f660a0..71882600 100644 --- a/altoslib/AltosHexfile.java +++ b/altoslib/AltosHexfile.java @@ -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() { diff --git a/altoslib/AltosRomconfig.java b/altoslib/AltosRomconfig.java index d868b9aa..8ef1848d 100644 --- a/altoslib/AltosRomconfig.java +++ b/altoslib/AltosRomconfig.java @@ -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(); -- 2.30.2