*
* 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
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_7;
+package org.altusmetrum.altoslib_13;
import java.io.*;
+import java.util.concurrent.*;
-public class AltosRomconfig {
+public class AltosRomconfig implements AltosUnitInfoListener {
public boolean valid;
+ public boolean radio_calibration_broken;
public int version;
public int check;
public int serial_number;
public int radio_calibration;
+ public AltosUsbId usb_id;
+ public String usb_product;
- static private int find_offset(AltosHexfile hexfile, String name, int len) throws AltosNoSymbol {
+ static private long find_address(AltosHexfile hexfile, String name, int len) throws AltosNoSymbol {
AltosHexsym symbol = hexfile.lookup_symbol(name);
- if (symbol == null)
- throw new AltosNoSymbol(name);
- int offset = (int) symbol.address - hexfile.address;
- if (offset < 0 || hexfile.data.length < offset + len)
+ if (symbol == null) {
throw new AltosNoSymbol(name);
- return offset;
+ }
+ if (hexfile.address <= symbol.address && symbol.address + len <= hexfile.max_address) {
+ return symbol.address;
+ }
+ throw new AltosNoSymbol(name);
+ }
+
+ static private int find_offset(AltosHexfile hexfile, String name, int len) throws AltosNoSymbol {
+ return (int) (find_address(hexfile, name, len) - hexfile.address);
}
static int get_int(AltosHexfile hexfile, String name, int len) throws AltosNoSymbol {
byte[] bytes = hexfile.data;
- int start = find_offset(hexfile, name, len);
+ int start = (int) find_offset(hexfile, name, len);
int v = 0;
int o = 0;
final static String ao_radio_cal = "ao_radio_cal";
final static String ao_usb_descriptors = "ao_usb_descriptors";
+ Semaphore unit_info_done;
+
+ public void notify_unit_info(AltosUnitInfo unit_info) {
+ unit_info_done.release();
+ }
+
+ private void fetch_radio_cal() {
+ unit_info_done = new Semaphore(0);
+ AltosUnitInfo info = new AltosUnitInfo(serial_number, this);
+
+ /* Block waiting for the rf calibration data */
+ radio_calibration_broken = true;
+ try {
+ unit_info_done.acquire();
+ int new_cal = info.rfcal();
+ if (new_cal != AltosLib.MISSING) {
+ radio_calibration = new_cal;
+ radio_calibration_broken = false;
+ }
+ } catch (InterruptedException ie) {
+ }
+ }
+
public AltosRomconfig(AltosHexfile hexfile) {
try {
version = get_int(hexfile, ao_romconfig_version, 2);
} 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;
}
}
+ usb_id = hexfile.find_usb_id();
+ usb_product = hexfile.find_usb_product();
+
} catch (AltosNoSymbol missing) {
valid = false;
}
ao_romconfig_version,
ao_romconfig_check,
ao_serial_number,
- ao_radio_cal
+ ao_radio_cal,
+ ao_usb_descriptors,
};
+ private static int fetch_len(String name) {
+ if (name.equals(ao_usb_descriptors))
+ return 256;
+ return 2;
+ }
+
private final static String[] required_names = {
ao_romconfig_version,
ao_romconfig_check,
return false;
}
- public static int fetch_base(AltosHexfile hexfile) throws AltosNoSymbol {
- int base = 0x7fffffff;
+ public static long fetch_base(AltosHexfile hexfile) throws AltosNoSymbol {
+ long base = 0xffffffffL;
for (String name : fetch_names) {
try {
- int addr = find_offset(hexfile, name, 2) + hexfile.address;
+ int len = fetch_len(name);
+ long addr = find_address(hexfile, name, len);
+
if (addr < base)
base = addr;
} catch (AltosNoSymbol ns) {
return base;
}
- public static int fetch_bounds(AltosHexfile hexfile) throws AltosNoSymbol {
- int bounds = 0;
+ public static long fetch_bounds(AltosHexfile hexfile) throws AltosNoSymbol {
+ long bounds = 0;
for (String name : fetch_names) {
try {
- int addr = find_offset(hexfile, name, 2) + hexfile.address;
+ int len = fetch_len(name);
+ long addr = find_address(hexfile, name, len) + len;
if (addr > bounds)
bounds = addr;
} catch (AltosNoSymbol ns) {
throw (ns);
}
}
- return bounds + 2;
+
+ return bounds;
}
public void write (AltosHexfile hexfile) throws IOException {